A latch holds the old value while its enable is low. A synthesis tool infers one exactly when some path through a combinational block skips an output.
The script below reads that shape: an if with no else. It pins exactly one $dlatch with no $dff.
read_verilog <<EOV
module latch_top (
input wire d,
input wire en,
output reg q
);
always @* begin
if (en)
q = d;
end
endmodule
EOV
hierarchy -check -top latch_top
proc
select -assert-count 1 t:$dlatch
select -assert-none t:$dff
log PASS: missing else branch infers one latch with no flopCode shape | Skipped path | Cell |
|---|---|---|
| Condition low |
|
| Uncovered values |
|
Default assigned before the branch | None |
|
Each fix makes every path assign the output. The latch disappears and a multiplexer takes its place.
Assign a default value before the if or case.
Add the missing else branch.
Add a default item to the case.
The testbench below drives a latch and a mux with the same inputs. The latch holds its value when the enable drops, while the mux follows its input.
module latch_demo (
input wire d,
input wire en,
output reg q
);
always @* begin
if (en)
q = d;
end
endmodule
module mux_ref (
input wire d,
input wire en,
output reg y
);
always @* begin
if (en)
y = d;
else
y = 1'b0;
end
endmodule
module tb_latch_hold;
reg d;
reg en;
wire q_latch;
wire y_mux;
integer errors;
latch_demo l (.d(d), .en(en), .q(q_latch));
mux_ref m (.d(d), .en(en), .y(y_mux));
initial begin
errors = 0;
d = 1; en = 1; #1;
if (q_latch !== 1'b1) errors = errors + 1;
if (y_mux !== 1'b1) errors = errors + 1;
d = 0; en = 0; #1;
if (q_latch !== 1'b1) errors = errors + 1;
if (y_mux !== 1'b0) errors = errors + 1;
if (errors == 0) $display("PASS: latch holds last value while mux follows input");
else $display("FAIL: %0d mismatches", errors);
$finish;
end
endmoduleif without an else drives an 8-bit bus in a combinational block. How many latches does the tool infer?Eight, one $dlatch per bit. Each bit holds its own old value on the skipped path.
q = 0 before the if. What changes in the netlist?Every path now assigns the output. The latches disappear and a multiplexer takes their place.