Why Does My Verilog always Block Infer a Latch?

Because some path through the block leaves an output unassigned. In a combinational always block, an output that is not given a value on every path has to keep its previous value, and keeping a value without a clock needs a storage element: a level-sensitive latch. The fix is to give every output a value on every path, most simply with a default assignment at the top of the block.

What you'll learn

  • The two shapes of code that infer latches: an incomplete case and an if without an else
  • What the latch does in simulation
  • The default-assignment fix, and why default in the case alone is not always enough
  • How Verilator and SystemVerilog's always_comb catch it

Conventions and assumptions

Verilog-2001 syntax. Examples simulated in Icarus Verilog 12 and linted with Verilator 5.036 with -Wall.

Shape 1: a case that doesn't cover every value

A 3-input mux selected by a 2-bit sel. Three of the four sel values are listed; nothing says what y is when sel is 2'b11.

Infers a latch on y
always @(*) begin
  case (sel)
    2'b00: y = a;
    2'b01: y = b;
    2'b10: y = c;
  endcase          // sel = 2'b11: y keeps its old value
end

In simulation, set a = 1 and sel = 2'b00, so y = 1, then change sel to 2'b11. The block runs, no branch matches, and y stays 1. Icarus Verilog shows exactly that: y is 1 for sel 00 and still 1 for sel 11. Hardware that behaves like this needs memory, so synthesis builds a latch. Verilator warns CASEINCOMPLETE, "Case values incompletely covered (example pattern 0x3)".

Shape 2: an if without an else

The same thing, written as an if:

Infers a latch on q
always @(*) begin
  if (en) q = d;   // no else: q holds when en is 0
end

When en is 0, q is not assigned, so it holds. Verilator warns LATCH: "Latch inferred for signal 'q' (not all control paths of combinational always assign a value)". Sometimes a latch is what you want; this is how you would write one deliberately. In synchronous designs it almost never is, because latches are transparent while enabled, which makes timing analysis harder, and many FPGA flows handle them poorly.

The fix: assign a default first

No latch: every path assigns y
always @(*) begin
  y = 1'b0;        // default first: every path now assigns y
  case (sel)
    2'b00: y = a;
    2'b01: y = b;
    2'b10: y = c;
    default: y = 1'b0;
  endcase
end

With y = 1'b0 as the first line, every path through the block gives y a value, whatever the case or if statements below do. Verilator reports no warnings, and in simulation y is now 0 when sel is 2'b11. A default branch in the case does the same job for that one case statement, but the line at the top also covers outputs assigned in only some branches, which is the usual way latches creep in when a block assigns several outputs.

Let the language check it

  • In SystemVerilog, write always_comb instead of always @(*). Tools are expected to warn when an always_comb block's behavior is not combinational, which includes an inferred latch (IEEE 1800-2023, clause 9.2.2.2).
  • Run Verilator with -Wall as a lint step: CASEINCOMPLETE and LATCH catch both shapes before synthesis does.
  • Read the synthesis report: latches are listed as their own cell type (an LD or LDCE primitive on AMD FPGAs, for example).

Common mistakes

  • Adding a default to the case but forgetting an output that is assigned in only some of the branches.
  • Assigning an output in one if branch and a different output in the else, so neither is complete.
  • Thinking a sensitivity list fixes it. always @(*) gets the inputs right but says nothing about whether every output is assigned.
  • Using a casez or casex with don't-cares and assuming it covers every value.

Check your understanding

  • Q1. A block assigns x in every branch of a full case, but assigns y only when sel is 2'b01. Which signal gets a latch? Answer: y.
  • Q2. Does always @(posedge clk) begin if (en) q <= d; end infer a latch? Answer: no. It is clocked, so holding the value is what a flip-flop with an enable does.
  • Q3. Why is a default assignment at the top safer than a default case branch? Answer: it covers every output in every branch, including ones added later.

Related

Sources

Last verified

Examples simulated in Icarus Verilog 12 and linted with Verilator 5.036 on 14 November 2026; the warning text above is copied from that run. always_comb rules checked against IEEE 1800-2023.

Keep going