Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
Skip to lesson

Course contents

  • Logic Synthesis Glossary
  • Logic Synthesis Cheatsheet
  • Synthesis Foundations14
  • Logic Optimisation and Mapping20
  • Constraints and Timing15
  • Sequential, FSM and Memory19
    • Flops, Resets and Enables
      • D Flop Inference
      • Enables: Mux or Clock Enable
      • Synchronous and Asynchronous Reset
      • Reset-less Flops and Initial Values
      • Mapping Flops to Library Cells
    • FSM Synthesis
    • Memory and Macro Inference
    • Retiming and Pipelining
  • Datapath Synthesis14
  • Area, Power and Test14
  • Verification, ECO and Handoff15
  • Flows and Debugging15
  • Interview and Judgment11
Loading lesson

←Flops, Resets and Enables
  1. Topics
  2. Logic Synthesis
  3. Sequential, FSM and Memory
  4. Flops, Resets and Enables
  5. Enables: Mux or Clock Enable
On this page

    Part 4 of 9, lesson 2 of 19Part 4 of 9/Sequential, FSM and Memory/Lesson 2 of 19Intermediate

    Enables: Mux or Clock Enable

    Enabled flops infer $dffe, which this library builds from a DFF plus a feedback mux.

    An enable looks like it should save power, but the recorded structure keeps every clock pin toggling. Knowing which structure saves what stops the enable from being sold as a clock gate.

    After this lesson you can: infer $dffe from the guard spelling, say what ANDing the data builds instead, read the DFF-plus-mux mapping, and price real clock gating with an activity model.

    The question

    Guarding a clocked load with if (en) keeps the old value on the cycles the enable is low. The question is what hardware that hold needs, and whether the enable saves any clock power by itself. This lesson infers a one-bit enabled flop, maps a 4-bit enabled register beside a 4-bit plain one, and breaks the hold with an AND-the-data variant. A short activity model then prices the one structure that does save clock power, labelled as a model throughout.

    The enabled flop idiom

    Guarding the load with if (en) infers an enabled flop: when the enable is low the flop keeps its value instead of loading new data. The first script pins the family on the if spelling: exactly one $dffe cell, with no plain, sync-reset, or async-reset variant.

    yosys
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    read_verilog <<EOV
    module en1(input clk, input en, input d, output reg q);
    always @(posedge clk) if (en) q <= d;
    endmodule
    EOV
    hierarchy -check -top en1
    proc
    opt
    select -assert-count 1 t:$dffe
    select -assert-none t:$dff
    select -assert-none t:$adff
    select -assert-none t:$sdff
    tee -o stat_en1_generic.txt stat
    write_json net_en1_generic.json
    log PASS: enabled flop infers one $dffe cell
    Predict first The enabled 4-bit register maps in a library with no clock-enable cell. What cells will the histogram hold, and will the clock pins toggle any less than the plain register?

    The histogram reads DFF x4, MUX2 x4: 4 DFFs for storage and 4 MUX2s recirculating the output when the enable is low. The clock still toggles every cycle, so the enable alone saves no clock power; it only stops new data from propagating.

    Spelling

    Generic cells (recorded)

    Reading

    if (en) q <= d

    1 $dffe

    One $dffe cell: enable plus data.

    q <= d & en

    1 $and, 1 $dff

    A $dff plus AND: clears instead of holding.

    Mux feedback or clock enable

    Two structures implement the hold. A mux recirculates the output when the enable is low: a plain flop plus one select mux per bit, working in every library, with the clock pin toggling on every cycle either way. A clock-enable cell instead blocks capture inside the flop while leaving the clock tree untouched. The teaching library offers no such cell, so the mapping below is the place to watch what the tool actually builds: the second script maps the 4-bit enabled register and a 4-bit plain twin through synth, dfflegalize, dfflibmap, abc, and stat, asserting 4 DFFs in each. The recorded histogram for the enabled form reads DFF x4, MUX2 x4.

    yosys
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    read_verilog <<EOV
    module enreg4(input clk, input en, input [3:0] d, output reg [3:0] q);
    always @(posedge clk) if (en) q <= d;
    endmodule
    EOV
    read_liberty -lib course.lib
    hierarchy -check -top enreg4
    synth -top enreg4 -flatten
    dfflegalize -cell $_DFF_P_ 01 -cell $_DFF_PN0_ 01
    dfflibmap -liberty course.lib
    tee -o abc_enreg4.txt abc -liberty course.lib -constr typical.constr -D 1000
    tee -o stat_enreg4.txt stat -liberty course.lib
    write_json net_enreg4.json
    select -assert-count 4 t:DFF
    design -reset
    read_verilog <<EOV
    module platter4(input clk, input [3:0] d, output reg [3:0] q);
    always @(posedge clk) q <= d;
    endmodule
    EOV
    read_liberty -lib course.lib
    hierarchy -check -top platter4
    synth -top platter4 -flatten
    dfflegalize -cell $_DFF_P_ 01 -cell $_DFF_PN0_ 01
    dfflibmap -liberty course.lib
    tee -o abc_plain4.txt abc -liberty course.lib -constr typical.constr -D 1000
    tee -o stat_plain4.txt stat -liberty course.lib
    write_json net_plain4.json
    select -assert-count 4 t:DFF
    log PASS: enabled register maps to DFF plus feedback logic beside a plain one

    4-bit register

    Mapped library cells (recorded)

    Chip area (stat -liberty)

    Enabled

    4 DFF + 4 MUX2

    52

    Plain

    4 DFF

    32

    Read the enabled row as the price of the hold: chip area 52 against 32 for the plain twin, so the four feedback muxes cost 20 units on top of storage. The clock pins toggle in both rows; the enable only selects which data reaches the flop. A library with a clock-enable cell would map the same $dffe to that cell instead, so the structure varies by library while the generic family stays put.

    Recorded total chip area from the stat reports for the enabled register and the plain twin. The gap is the four feedback muxes.
    The recorded mapped enabled register: 4 DFFs with 4 feedback MUX2s. Each bit recirculates its own output when the enable is low.

    Where the real clock-power saving comes from

    Neither row above saves clock power: in both, every clock pin toggles every cycle and the enable only steers data. The structure that does remove clock toggling is a clock gate, usually an integrated clock gater (ICG): a latch plus an AND placed in the clock path so the gated clock net stays still on idle cycles. That is the standard low-power technique, described here as background rather than as a run on this page: the teaching library has no gater cell and this flow inserts none, so there is no Yosys recording to quote. What stands in for the recording is a small activity model below, labelled as a model, counting clock-pin toggles for one 64-bit register with a shared enable at 10% activity over 1000 cycles.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    import sys
    
    # Clock-pin toggle model for one 64-bit register with a SHARED enable (model,
    # not a tool measurement). Each clock pin costs one toggle unit per cycle it
    # switches. Mux feedback keeps every clock pin toggling; a clock gate (ICG)
    # switches the shared gated net only on cycles the enable is high.
    N = 64
    P_ENABLE = 0.1
    CYCLES = 1000
    GATER_OVERHEAD = 2.0
    
    ungated = N * CYCLES
    mux_feedback = N * CYCLES
    gated = N * P_ENABLE * CYCLES + GATER_OVERHEAD * CYCLES
    saving = (mux_feedback - gated) / mux_feedback
    
    # Second operating point, worked by hand: at 50 percent enable activity the
    # gated net toggles 64 x 0.5 x 1000 + 2 x 1000 = 34000 units, saving
    # (64000 - 34000) / 64000 = 0.46875 of the pin toggles.
    gated_half = N * 0.5 * CYCLES + GATER_OVERHEAD * CYCLES
    saving_half = (mux_feedback - gated_half) / mux_feedback
    
    checks = [
        (mux_feedback == ungated, "enable alone toggles like the plain register"),
        (gated == 64000 * P_ENABLE + 2000, "gated total follows N p CYCLES plus overhead"),
        (gated < ungated, "the gate removes toggles at p 0.1"),
        (round(saving, 3) == 0.869, "saving at p 0.1 rounds to 87 percent"),
        (gated_half == 34000.0, "gated total at p 0.5"),
        (saving_half == 0.46875, "saving at p 0.5"),
    ]
    
    for ok, what in checks:
        if not ok:
            print("FAIL: " + what)
            sys.exit(1)
    
    print("PASS: a shared gate removes about 87 percent of clock-pin toggles at p 0.1")
    print("ungated " + str(ungated) + " gated " + str(gated) + " saving " + str(round(saving, 3)))
    Diagram
    activity model, shared enable at p = 0.1 over 1000 cycles (labelled model, not measured)
    ungated or mux-feedback clock toggles = 64 x 1000 = 64000
    gated clock toggles = 64 x 0.1 x 1000 + 2 x 1000 = 8400
    saving = (64000 - 8400) / 64000 = 0.869, about 87% fewer pin toggles

    Read the model against the recorded rows: the $dffe-as-mux this library builds sits at 64000 toggle units, exactly where the plain register sits, while the gated variant sits near 8400. The saving belongs to the gate, not to the enable idiom. In a commercial flow the gate is inserted by the low-power step, with its own enable-timing checks; here it stays a hand-counted model, which is why the page never quotes it beside the recorded areas without the label.

    Break it: AND the data instead of guarding the load

    The third script writes the one-bit flop as q <= d & en and records a different family: one $dff cell plus an AND gate, reading 1 $and, 1 $dff, with no $dffe anywhere. ANDing the data clears the flop whenever the enable is low instead of holding it, so the behaviour is not the same hold and the tool does not infer the enabled cell. The testbench below pins the difference: with the enable low across an edge the output clears to 0, while the guarded flop in the next section holds. Reach for data gating only when clearing is what the spec wants; keep the if (en) guard whenever the old value must survive.

    yosys
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    read_verilog <<EOV
    module enand1(input clk, input en, input d, output reg q);
    always @(posedge clk) q <= d & en;
    endmodule
    EOV
    hierarchy -check -top enand1
    proc
    opt
    select -assert-count 1 t:$dff
    select -assert-none t:$dffe
    select -assert-count 1 t:$and
    tee -o stat_enand1_generic.txt stat
    write_json net_enand1_generic.json
    log PASS: AND-the-data variant infers a plain flop plus gate
    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // engine: icarus
    module enand1_tb(input logic clk, input logic en, input logic d, output logic q);
      always @(posedge clk) q <= d & en;
    endmodule
    module tb_anden;
      logic clk = 0, en = 0, d = 1, q;
      enand1_tb dut (.*);
      always #5 clk = ~clk;
      int errors = 0;
      initial begin
        @(posedge clk); #1;
        if (q !== 1'b0) begin $display("FAIL: AND form held instead of clearing"); errors++; end
        en = 1;
        @(posedge clk); #1;
        if (q !== 1'b1) begin $display("FAIL: AND form did not load with en"); errors++; end
        if (errors == 0) $display("PASS: AND-the-data clears instead of holding");
        $finish;
      end
    endmodule

    Simulate the hold

    The testbench below exercises the behaviour the $dffe promises: without enable the flop holds across edges, with enable it loads. It runs on Icarus with four-state checks so a held value and a loaded value are distinguished exactly.

    en_hold.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // engine: icarus
    module en_hold (
      input logic clk, input logic en, input logic d, output logic q
    );
      always @(posedge clk) if (en) q <= d;
    endmodule
    
    module tb_en_hold;
      logic clk = 0, en = 0, d = 0, q;
      en_hold dut (.*);
      always #5 clk = ~clk;
      int errors = 0;
      initial begin
        d = 1;
        @(posedge clk); #1;
        if (q !== 1'bx) begin $display("FAIL: flop changed without enable"); errors++; end
        en = 1;
        @(posedge clk); #1;
        if (q !== 1'b1) begin $display("FAIL: flop did not load with enable"); errors++; end
        en = 0; d = 0;
        @(posedge clk); #1;
        if (q !== 1'b1) begin $display("FAIL: flop did not hold without enable"); errors++; end
        if (errors == 0) $display("PASS: enabled flop holds without enable and loads with it");
        $finish;
      end
    endmodule

    Common mistakes

    Calling the mux-feedback flop lower power. It saves data switching downstream, never clock toggling; only a gate in the clock path removes pin toggles, as the model quantifies.

    Gating the clock signal with logic (clk & en) is not an enable. When en changes while the clock is high the derived clock glitches, and the result needs its own clock tree and timing treatment instead of being timed as data. The safe gate is an integrated clock gater, which qualifies the enable through a latch that is transparent while the clock is low so the gated edge never glitches. Write if (en) inside the clocked block and let the tool pick the cell; never AND the clock net yourself.

    Likely probes: $dffe spelling, the mux-versus-cell choice, and where power is saved.

    Weak answer: an enable flop saves power because the clock stops when disabled.

    Strong answer: if (en) infers $dffe, which this library builds as 4 DFFs plus 4 MUX2s at chip area 52, and the clock pins still toggle every cycle. Real clock-power saving needs a gate in the clock path, which the model prices near 87% fewer toggles at 10% shared-enable activity.

    Follow-up: the enable fans out to thousands of flops. Answer: share one gate for the whole bank so the gated net sleeps together, and check the enable timing into the gater the way the flow requires.

    Check yourself An enabled flop sits in a library with no clock-enable cell. What does the tool build?

    A DFF plus per-bit feedback mux logic: the recorded 4-bit register reads DFF x4, MUX2 x4 at chip area 52. The $dffe behaviour stays identical; only the structure differs by library.

    Check yourself Why is if (en) q <= d preferred over ANDing the clock with en?

    The first is data timed like any synchronous input, with the clock tree untouched. The second can glitch when en moves near a high clock, builds a new clock needing its own tree, and synthesis cannot time it as data.

    • $dffe is DFF plus feedback mux in this library; the clock still toggles every cycle.

    • Real clock-power saving needs a gate in the clock path, priced by a labelled model.

    • Never build the enable by ANDing the clock net; write if (en) inside the block.

    Rule of thumb: ask what still toggles before calling anything lower power.

    How this was checked

    Generic families, mapped histograms, and chip areas on this page come from three Yosys 0.70 runs recorded by the course checker (scripts/tools/run-rtl-testbenches.mjs with COURSE=synth): a one-bit enabled flop through proc and opt, a 4-bit enabled register and a plain twin through synth, dfflegalize, dfflibmap -liberty course.lib, abc -liberty course.lib -constr typical.constr -D 1000 and stat -liberty course.lib, and an AND-the-data variant that infers a plain flop plus gate. The 87% toggle saving is a stdlib-only Python activity model with checks at two operating points, labelled so on the page. The ICG description is standard background, not a run. The hold and clear testbenches run on Icarus. The libraries are fictional, so absolute areas are teaching units.

    • Interview: run a mock interview on this topic

    Related topics

    • D Flop Inference

    • Synchronous and Asynchronous Reset

    • Clock Gating and Low Power

    Previous

    53 / 139

    Next: Synchronous and Asynchronous Reset

    Up next

    Up nextSynchronous and Asynchronous Reset

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Reset-less Flops and Initial Values
    • Mapping Flops to Library Cells