Verilog & SystemVerilog DISCUSSION

Why does my combinational always block infer a latch in Verilog, and how do I prevent it?

Started by vothanhdat Verilog inferred latchincomplete assignmentcombinational logicalways_combdefault assignment
4 replies 248 views 5 participants
Latest activity · 30 Sep 2026

Why does my combinational always block infer a latch in Verilog, and how do I prevent it?

vothanhdat Verilog & SystemVerilog Forum
#1

Synthesis of my decoder reports an inferred latch on y. The block is always @* begin if (en) y = d; end. A second block uses a case on a 2-bit sel with items for 2'b00, 2'b01 and 2'b10 and no default, and it produces latches on two more outputs. I intended pure combinational logic in both.

Why does leaving out an else or a case item create storage, why are tools so unhappy about latches in an FPGA design, and what coding habits avoid them reliably?

Community replies 4

Re: Why does my combinational always block infer a latch in Verilog, and how do I prevent it?

#2

A variable keeps its value until it is assigned again; that is the language rule. In your block, when en is 0 no assignment to y executes, so y must hold its previous value. Hardware that passes d while en is high and holds otherwise is a level-sensitive latch, so the synthesiser builds one to match what the code says. The case is the same: when sel is 2'b11 none of the three items matches, the outputs are not assigned, and they have to be remembered.

Combinational logic requires that every output is assigned on every possible path through the block.

Re: Why does my combinational always block infer a latch in Verilog, and how do I prevent it?

#3

The most reliable habit is to assign a default to every output at the top of the block and let later statements override it: always @* begin y = 1'b0; if (en) y = d; end. With blocking assignments the last one executed wins, so no path is left without a value, however many branches you add later. For the output block of a state machine, list all outputs with their idle values first and then write the case.

The alternatives are an else for every if and a default item in every case, but those must be repeated for every output in every branch. An output assigned in three branches out of four still latches.

Re: Why does my combinational always block infer a latch in Verilog, and how do I prevent it?

#4

Latches are legal hardware, but they are a poor fit for clocked FPGA design. They are transparent for the whole time the enable is active, so any glitch on the data or enable logic passes straight through, and timing analysis is more complicated than for edge-triggered registers. Above all, an unintended latch means the circuit is not what you thought you described, so treat the message as an error and search the synthesis log for the word latch after every build.

Note that a missing else in a clocked block is fine: always @(posedge clk) if (en) q <= d; is a flip-flop with a clock enable, not a latch.

Re: Why does my combinational always block infer a latch in Verilog, and how do I prevent it?

#5

In SystemVerilog, write always_comb instead of always @*. It infers its own sensitivity list, runs once at time zero so that outputs start consistent with inputs, and states your intent, so tools report a latch inferred from it as a violation rather than a note buried in the log. always_latch exists for the rare case where you do want one.

Two things that look similar are different problems. An incomplete sensitivity list such as always @(a) for logic that also reads b does not create a latch; it makes simulation disagree with the synthesised gates. And assigning y = 1'bx in a default branch avoids the latch and lets the tool optimise, at the cost of different behaviour between simulation and hardware for that input.

TEP COMMUNITY