A latch is level-sensitive: while enable is true it is transparent, while enable is false it holds. Most FPGA/ASIC RTL should be flip-flops, not latches.
flowchart LR d[D] --> lat[latch] en[enable] --> lat lat --> q[Q]
Accidental inference
Incomplete assignments in always_comb create latches:
always_comb begin
if (en) q = d; // no else → latch
end
Wrong vs right
Wrong — implied latch in combo decode:
always_comb begin
if (sel == 2'd1) y = a;
else if (sel == 2'd2) y = b;
end
Right — default first, or cover every branch:
always_comb begin
y = '0;
if (sel == 2'd1) y = a;
else if (sel == 2'd2) y = b;
end
Intentional latches
Rare: clock-gating cells, some async interfaces, or a library latch primitive. Write them on purpose, name them, and keep them out of the normal datapath.
Lint in RTL Studio flags the accidental case — treat a latch warning as a bug until you can explain the cell.