I am trying to code a controller/data-path implementation in Verilog, and I am confused on what will cause an unwanted latch. Essentially, I have a state machine updating on the negedge clock. This state machine sends 5 control signals (loadSquare, loadDelta, addDelta, etc.) to the data-path based on what state the machine is in. The code for the data-path and controller is shown below.
Data-path
//Control lines
reg addSquare, addDelta, decDelta;
reg loadSquare, loadDelta;
//Input lines
reg [8:0] square, delta;
//Output register
reg [7:0] outReg;
always @(posedge clk) begin
if (loadSquare)
square = 9'h1; //used on initialization
if (loadDelta)
delta = 9'h3; //used on initialization
if (addSquare)
square = square + delta;
if (addDelta)
delta = delta + 2'h2;
if (decDelta)
outReg = (delta>>1) - 1; //used for output
else
outReg = Input;
end
Controller
//Output of module
assign Output = outReg;
//Finite State Machine
always @(currentState) begin
case(currentState)
2'h0: begin //initialize values, wait for start
{loadSquare, loadDelta} = 2'b11;
{addSquare, addDelta, decDelta} = 3'h0;
end
2'h1: begin
{loadSquare, loadDelta} = 2'b00;
{addSquare, addDelta, decDelta} = 3'b110; //add square and delta
end
2'h2: begin
{loadSquare, loadDelta} = 2'b00;
{addSquare, addDelta, decDelta} = 3'b001; //decrement delta, wait for reset
end
default: ; // unused
endcase
//Next state logic implemented on negedge clk (not shown)
This code generates the following warnings in Xilinx:
WARNING:Xst:737 - Found 1-bit latch for signal <addDelta>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 1-bit latch for signal <decDelta>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 1-bit latch for signal <loadDelta>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:1294 - Latch <loadDelta> is equivalent to a wire in block <ModuleName>.
WARNING:Xst:1294 - Latch <decDelta> is equivalent to a wire in block <ModuleName>.
WARNING:Xst:1294 - Latch <addDelta> is equivalent to a wire in block <ModuleName>.
I understand that incomplete if statements cause latches. In order to try to account for this, I have tried 2 different implementations but they do not remove the warnings. I am especially confused for the "decDelta" case because I don't understand what I am not accounting for in this conditional statement.
Try #1
always @(posedge clk) begin
if (loadSquare)
square = 9'h1;
else
square = square;
if (loadDelta)
delta = 9'h3;
else
delta = delta;
//... and so on
Try #2
always @(posedge clk) begin
square = square;
delta = delta;
if (loadSquare)
square = 9'h1;
if (loadDelta)
delta = 9'h3;
//... and so on
The code works as expected when I run a simulation, but I wanted to learn a little more about what causes these warnings.
A latch is inferred when a variable within a combinational block is not assigned a value within all possible permutation of the blocks functionality.
Doing something like
addSquare = addSquare;
is still an inferred latch.addSquare
(and all the other variables) needs to be assigned to a constant, a flop (edge sensitive flip-flop), or combinational function terms of constants and flop values.If you truly do not need
addSquare
(and all the other variables), then just assign them to a constant in thedefault
condition.If you do need to keep the value, then you need to add a flop that is synchrously assigned to the variable. In the
default
condition, the variable needs to be assigned to the flop. Example:A latch is a basic memory element, it is open or closed ie it is level sensitive. A flip-flop is basically two latches with one operating on the invert of the enable signal, this makes it edge sensitive.
When using
always @(posedge clk)
you have implied a flip-flop that loads data values on the rising edge ofclk
. Latches do not get implied inside this process (always @(posedge clk)
).As Sharvil111 has described latches are implied when you have left undefined states in combinatorial sections ie
always @*
processes. If some thing is undefined in part of a conditional then it retains its value. Value retention is state, and since combinatorial sections are not edge sensitive you have forced the tool to insert a latch.To avoid this fully define the conditional output:
Latches are inferred when a variable will have to retain its previous value, if it is not assigned a value in an always block. A latch must be created to store this present value.
Latches can cause various race conditions. Unwanted latches create a feedback in a combinational circuit, i.e. it routes the output back to the input - which can be unpredictable causing unstable circuit behavior.
An incomplete
if-else
statement will generate unwanted latches. An if-else statement is considered "incomplete" if the one of the condition is not defined for all possible input conditions. Similarly, an incompletecase
statement, that does not have adefault
statement can also infer to latch.A complete
if-else
statement refers to the following Mux:While and incomplete
if-else
refers to a feedback path from output to input, in order to hold the previous value. Similar applies tocase
statement.As a rule, combinational loops must be avoided:
As a contradiction, verilog standard specifies that a variable must retain/hold its previous value if it is not assigned a value in an always block. This is the root cause of latch creation.
To avoid the latches, following points must be kept in mind:
if
orcase
statement.Here, to avoid latch creation, either you can else branch and explicitly assign all output variables, such that other input is grounded.
Another alternative is to assign a default value at every clock tick.
Side Note : I've used non-blocking assignments statements here, for proper flip-flop synthesis.
For detailed synthesis information, refer to FPGA prototyping by Verilog examples by Pong P. Chu pdf. Also, this and this links about latch creation may be useful.
Image courtesy doulous.com.
The latches are cause by the state machine logic. The following always block is sensitive to
currentState
and not to a clock. This is not bad, but needs some extra precautions to hinder latch creation:default
case ORHere is your code with my additions using default assignments:
For further information on latch creation have a look at @sharvil111's answer. He addresses this topic in a more general way.