A latch is inferred within a combinatorial block where the net is not assigned to a known value. Assign a net to itself will still infer a latch. Latches can also be inferred by missing signals form a sensitivity list and feedback loops.
The proper way of inferring a intended latch in Verilog/SystemVerilog are:
/* Verilog */ //// /* SystemVerilog */
always @* //// always_latch
begin //// begin
if (en) q = d; //// if (en) q = d;
end //// end
Ways latches are accidentally inferred:
Signal(s) missing for the sensitivity list (this is why @*
should be used):
always @(a or b) // inferred latch :: "c" missing for the sensitivity list.
begin
out = a + b + c;
end
Missing Condition:
always @*
begin
case(in[1:0])
2'b00: out = 1'b0;
2'b01: out = 1'b1;
2'b10: out = 1'b1;
// inferred latch "out" :: missing condition 2'b11/default
endcase
end
always @*
begin
next0 = flop0;
next1 = flop1;
// inferred latch "next2" :: missing initial condition
next3 = flop3;
case(a[2:0])
3'b001: next0 = in;
3'b010: if(b) next1 = in;
3'b100: if(c) next2 = in;
default: if(!b&&!c) next3 = in;
endcase
end
Feedback Loop:
assign out = en ? in : out; // inferred latch "out" :: feedback to mux
assign a = en ? z : c;
// ... any amount of code between ...
assign z = en ? a : y; // inferred latch "a" :: feedback chain
- Feedback loops can traverse through the hierarchy and design.
How to mitigate the risk of unintended latches:
- Make intended latches simple and identifiable:
- Put intended latches in their own always blocks with as little combinatorial logic as possible; ideally put the latches' combinatorial logic in its own separate always block. Be as explicit and identify intended latches. Use comments, labels, and if possible use the SystemVerilog
always_latch
.
- All combinatorial logic blocks need to be defined with
always @*
or SystemVerilog's always_comb
.
- Make sure all variables assigned in a combinatorial logic blocks have an initial or default assignment.
case
statements should have a default
condition.
if
statements should have a corresponding else
.
- When the combinatorial logic blocks is assigning many variables, giving each variable an initial value at the start of the block (before any
case
or if
).
- Know where the inputs are coming from and where the outputs are going to.
- The inputs of combinatorial logic should be flops or the outputs combinatorial logic should be flops.
- Do code reviews, use linting tools and logical-equivalency-checking tools.
- Code review requires the reviewer(s) to know where latches could hide.
- Using SystemVerilog's
always_comb
can help identify inferred latches with linting and logical-equivalency-checking tools.
Worst case scenario, put all logic inside synchronous blocks. All inferred latches become inferred flip-flops. This is usually a bad idea because it can unnecessarily increases the gate count, create more routing, and impact timing.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…