What is inferred latch and how it is created when it is missing else statement in if condition. Can anybody explain briefly?

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.

Leave a Comment