Guarding the load with if (en) infers an enabled flop. When the enable is low the flop keeps its value.
Spelling the same behaviour as q <= en ? d : q infers the same cell. The tool recognizes the feedback-mux pattern in both forms.
The script below infers a one-bit enabled flop and pins its family. It asserts one $dffe cell and no plain or reset variants.
read_verilog <<EOV
module top(input clk, input en, input d, output reg q);
always @(posedge clk) if (en) q <= d;
endmodule
EOV
hierarchy -check -top top
proc
opt
select -assert-count 1 t:$dffe
select -assert-none t:$dff
select -assert-none t:$adff
select -assert-none t:$sdff
log PASS: enabled flop infers one $dffe cellTwo structures implement the enable. A mux recirculates the output when disabled, while a clock-enable cell keeps the clock pin toggling but blocks internal capture when disabled, saving data switching rather than pin toggling.
Structure | Logic | Trade-off |
|---|---|---|
Mux feedback |
| Works in every library; the clock still toggles each cycle. |
Clock-enable cell | A flop with an enable pin | Less internal switching when idle; needs care in the clock tree. |
The teaching library offers no clock-enable cell, so an enabled flop maps to a DFF plus feedback logic here. Libraries with such a cell map $dffe to it instead, so the mapping varies.
course.lib EXAMPLE areas: DFF = 8 units, MUX2 = 5 units
mux-feedback enable, per bit: 8 + 5 = 13 units
8-bit enabled register here: 8 x 13 = 104 unitsGating the clock signal with logic (clk & en) is not an enable. It builds a skewed derived clock that static timing cannot treat as data.
A DFF plus per-bit feedback mux logic. The $dffe behaviour stays identical; only the structure differs.
if (en) q <= d preferred over ANDing the clock with en?The first is data timed like any synchronous input. The second builds a new clock that needs its own tree and timing treatment.
The testbench below checks hold-when-disabled and load-when-enabled across four clock edges.
module en_flop (
input logic clk, input logic rst, input logic en, input logic d, output logic q
);
always @(posedge clk) begin
if (rst) q <= 1'b0;
else if (en) q <= d;
end
endmodule
module tb_en_flop;
logic clk = 0, rst = 1, en = 0, d = 0;
logic q;
en_flop dut (.*);
always #5 clk = ~clk;
int errors = 0;
initial begin
#12; rst = 0; #1;
if (q !== 1'b0) errors++;
d = 1; en = 0; @(posedge clk); #1;
if (q !== 1'b0) errors++;
en = 1; @(posedge clk); #1;
if (q !== 1'b1) errors++;
en = 0; d = 0; @(posedge clk); #1;
if (q !== 1'b1) errors++;
if (errors == 0) $display("PASS: enabled flop holds without enable and loads with it");
$finish;
end
endmodule