See it move
Enables
A flop that should sometimes hold its value needs an enable.
always_ff @(posedge clk)
if (en) q <= d;In hardware, this is a mux in front of D, feeding Q back when en is low. It works well, but the flop still receives its clock, so its clock pin keeps burning power, plus a mux per bit.
Clock gating
Rather than holding the value with a mux, stop the clock from reaching a group of flops. They keep their values, since no edge arrives. For a 32-bit register, one gate replaces 32 muxes and removes the clock-pin activity.
Why a plain AND doesn't work
assign gclk = clk & en; looks right. But if en changes while clk is high, the output changes partway through a pulse, creating a runt pulse or a false edge. The animation above shows exactly this. Flops treat these glitches as real clock edges.
The integrated clock gate
An ICG cell adds a that is transparent while the clock is low:
// A model of the behaviour; real designs use the library's ICG cell
always_latch
if (!clk) en_lat = en;
assign gclk = clk & en_lat;The latch can change only during the low phase, and the AND output is then held low anyway. Once the clock rises, en_lat is frozen, so every pulse is whole.
Common mistake
Writing your own gate out of a latch and an AND in production RTL. Use the library's ICG, which is characterised and understood by clock-tree tools, or let synthesis insert gating automatically. Remember that a gated domain also needs its enable to meet timing against the clock edge.
Key ideas
- An enable is a mux feeding back Q.
- Gating stops the clock so the flops don't toggle.
- Use an integrated clock gate; a raw AND can glitch.
Your exercise
Find the bug
This code has one deliberate bug. Read the symptom, then click the line you think is wrong.
The fix
// no else: a flop with no assignment holds its value
Why it failed
An enable register keeps its value when disabled. Leaving out the else already gives this, since a clocked block with no assignment keeps the old value. The added else clears the register on every idle cycle, so it behaves like a pulse instead of storage.
Interview questions
coreWhy not gate a clock with plain AND?
An enable changing while the clock is high creates glitches; an ICG latches the enable.
basicWhat hardware does if (en) q <= d; inside a clocked block describe?
A flop with a 2-to-1 mux in front of its D input. When en is 1 the mux selects d, and when en is 0 it selects q itself, so the flop reloads its own value and appears to hold. The flop still receives every clock edge either way.
basicWhy does clock gating save power compared with an enable mux?
With an enable mux, every flop still sees every clock edge, so its clock pin and internal clock circuitry keep switching even while it holds. Clock gating stops edges from reaching the group of flops, so that clock activity stops while they hold. One gate can also replace a mux per bit, for example 32 muxes for a 32-bit register.
coreSomeone gates a clock with a plain AND gate. The enable comes from logic that can change while the clock is high. What goes wrong?
assign gclk = clk & en;
If en rises while clk is high, the gated clock rises at that moment, creating a false rising edge in the middle of a pulse. If en falls while clk is high, the pulse is cut short into a runt. Flops treat these as real edges, or may respond unreliably to a runt. In a simulation with en rising partway through a high phase, the AND output gave an extra rising edge compared with a proper clock gate.
coreExplain how this clock gate model avoids glitches, and why its latch is open while the clock is low rather than high.
always @(*) if (!clk) en_lat = en; assign gclk = clk & en_lat;
The latch passes en only while clk is low, and during that time the AND output is held low by clk anyway, so changes on en cannot reach gclk. When clk rises, the latch closes and en_lat is frozen for the whole high phase, so every pulse is either whole or absent. A latch open while the clock is high would let en changes through exactly when the AND passes them, which brings the glitches back.
coreA 32-bit register is loaded on one cycle in every ten. Over 100 clock cycles, how many rising clock edges reach its flops with an enable mux, and with clock gating?
With an enable, all 32 flops see every edge: 32 x 100 = 3,200. With gating, only the 10 load cycles pass a clock edge, so 32 x 10 = 320. That is a tenfold drop in clock-pin activity, minus the small cost of the gate itself, which still sees every edge.
coreIs it always worth gating the clock of a register that has an enable?
No. A gate has its own area and power, and its clock input toggles all the time, so for a register of one or two bits it can cost more than it saves. Gating pays off for wide registers that hold their value for most cycles. Synthesis tools that insert gating automatically typically apply a minimum register width for this reason.
advancedIn a clock-gated domain, by when must the enable be stable, and why is that timing path often tighter than a normal flop-to-flop path?
The enable must meet setup at the gate's latch before the rising clock edge, because that edge closes the latch and fixes which pulse passes. The gate sits near the root of the clock tree feeding its group of flops, so its clock arrives earlier than the clocks at those flops. The enable logic, launched by flops at the leaves, therefore has less than a full cycle to reach it.
advancedThis hand-written clock gate still produces false edges in simulation. What is the bug?
always @(*) if (clk) en_lat = en; assign gclk = clk & en_lat;
The latch is open while clk is high, which is exactly the phase in which the AND passes its other input to the output. An enable change during the high phase goes straight through the latch and the AND, giving a false edge or a runt pulse, just like a plain AND gate. The latch must be open while clk is low. In production, use the library's clock gate cell rather than hand-built logic.