FPGA

Clock gating in FPGA

By CourseTron Team ·  4 min read ·  Updated Oct 2026 💬 𝕏 in f
Table of Contents
    ? Print / Save as PDF

    In short: On an FPGA you gate a clock by routing the enable through a dedicated clock buffer such as a Xilinx BUFGCE, not by ANDing a signal with the clock in the fabric, because a LUT-gated clock injects skew and glitches that break timing closure — and in most cases a simple clock-enable (CE) on the flip-flop is better still.

    Why you even want to gate a clock

    Clock gating stops the clock to a block of logic when that block has no useful work to do. Every rising edge a flip-flop sees costs dynamic power — roughly P = α·C·V²·f — even if the captured value never changes. On a datapath that is idle 80% of the time, suppressing those edges can cut that block's dynamic power by a similar fraction. In ASIC design this is routine: synthesis tools like Synopsys Design Compiler and Cadence Genus automatically insert integrated clock-gating (ICG) cells. On an FPGA the economics and the silicon are different, and that difference is exactly what interview panels probe.

    Key fact: An FPGA's clock trees are pre-built, balanced global networks fed by a fixed number of clock buffers (e.g. 32 BUFGCEs per clock region on many 7-series devices). You cannot synthesize an arbitrary gating cell into that tree — you can only use the enable pin the vendor already put there.

    The naive approach: gating in the fabric (don't)

    The tempting beginner move is gated_clk = clk & enable; and then clocking flops on gated_clk. This "LUT-gated clock" is almost always wrong on an FPGA for three reasons:

    • Skew. The AND gate sits in a LUT in the general fabric, so the gated clock leaves the balanced global tree and travels on ordinary routing. It arrives late and with uncontrolled, placement-dependent delay relative to the ungated clock — tens to hundreds of picoseconds of skew that the timing engine cannot easily balance.
    • Glitches. If enable changes while clk is high, the AND output can produce a runt pulse. A glitch on a clock net is a spurious edge: flops capture garbage or go metastable.
    • Analysis pain. A fabric-generated clock becomes a new timing clock that the tool must characterize and that fights clock-domain analysis in Vivado or Quartus.
    LUT-gated clock vs BUFGCE Bad: AND gate in a LUT (skew + glitches) clken LUT AND fabric FF late, uneven delayrunt pulses possible Good: BUFGCE on the global clock tree clkce BUFGCE global FF balanced, glitch-freegating inside the tree CourseTron · coursetron.com
    Gating in the LUT fabric leaves the balanced tree and risks glitches; a BUFGCE gates the clock inside the dedicated global network.

    The right primitive: BUFGCE and friends

    Xilinx (now AMD) provides global clock buffers with a built-in enable. A BUFGCE is a global buffer whose output is suppressed by a CE input inside the dedicated clock network, with glitch-free switching: the primitive only lets a clean, full-width pulse through and blocks partial edges. Intel/Altera offers the equivalent through clkctrl blocks (the "clock control" / gated-clock-enable path). Because the gating happens in the clock column, downstream skew stays balanced and the tool treats the result as the same clock, simply with missing edges.

    You rarely instantiate it by hand. Both Vivado and Quartus will infer a BUFGCE or clkctrl when you code a clean clock-enable and let the tool do fine-grained clock gating (in Vivado, the -gated_clock_conversion / BUFGCE inference flows). You can also instantiate BUFGCE explicitly for a coarse, block-level shutdown.

    Usually you don't need to gate the clock at all

    The cleanest FPGA pattern is the enable flip-flop (clock-enable, CE): keep one free-running clock and feed the enable to the flop's dedicated CE pin. Every FPGA flip-flop has one.

    always @(posedge clk)
        if (en)          // uses the FF's dedicated CE pin
            q <= d;      // NOT: always @(posedge (clk & en))

    This gives you the functional result of a gated clock — the register holds its value when en is low — with zero added skew and no new clock to analyze. The clock keeps toggling, so it saves less dynamic power on the clock tree itself than a true BUFGCE gate, but for small register banks it is the correct, portable, timing-safe default.

    Clock-enable flop: hold without gating Flip-flop dedicated CE pin d en clk, never gated q enq after rising clk 0holds old q 1loads d Zero added skew, no new clock to analyze CourseTron · coursetron.com
    A clock-enable flop holds its value when en is low while the clock keeps running, so no gated clock is created.

    When to reach for each

    TechniqueSkew riskClock-tree power savedUse when
    LUT-gated clock (clk & en)High (glitches)SomeNever, on FPGA
    Clock-enable (CE) flopNoneNone (clock still toggles)Small banks, default choice
    BUFGCE / clkctrlNone (handled in tree)Large, whole regionsBig idle blocks, DSP/BRAM clusters

    Key fact: A BUFGCE saves the dynamic power of the entire gated clock branch (buffers, routing and the toggling of thousands of flops). A CE pin only stops the flop from updating — the clock net keeps switching — so CE saves far less tree power but costs nothing in timing.

    Clock skew and the timing-closure angle

    Skew is the real reason interviewers hammer this topic. Setup slack is T_period − T_cq − T_logic − T_setup + T_skew; hold slack is T_cq + T_logic − T_hold − T_skew. A positive launch-to-capture skew helps setup but hurts hold. A fabric-gated clock adds an unpredictable, placement-dependent skew term to every path crossing between gated and ungated flops, so the static timing analyzer (in Vivado, Quartus, or a sign-off tool) cannot guarantee hold closure. Keeping the gate inside the dedicated tree — BUFGCE — keeps that skew term small and characterized. If the gated and ungated domains must exchange data, treat the boundary with the same care you would a clock-domain crossing: synchronize or use proper handshaking rather than assuming the edges line up.

    A practical checklist

    • Default to a CE flop; only escalate to BUFGCE when a large block is idle often and power matters.
    • Let the synthesis tool infer the buffer from clean enable logic; register the enable so it is glitch-free.
    • Never build a clock in a LUT. If you see @(posedge (clk & en)) in a review, flag it.
    • Check the clock-region BUFGCE budget early — you can exhaust global buffers on a design with many gated domains.
    • For deeper RTL discipline, see our note on reset strategy in FPGA, which interacts directly with enable logic.

    Teams building production FPGA and ASIC flows — and the Avecas VLSI design-services group we work with — treat this as a first-pass lint rule precisely because a single hand-rolled gated clock can sink an otherwise clean timing closure.

    BUFGCE blanks whole pulses clkengated en = 0 suppressed CourseTron · coursetron.com
    When the enable goes low the buffer blanks whole clock pulses — no runt edges — then resumes cleanly. That glitch-free masking is what the fabric AND gate cannot guarantee.

    Want to design timing-clean FPGA datapaths end to end? Our FPGA & VLSI courses at CourseTron cover clock gating, CDC and timing closure with hands-on Vivado and Quartus labs.

    Frequently asked questions

    Is clock gating the same as a clock-enable?

    No. A true gated clock (BUFGCE) actually stops clock edges from propagating, saving the clock tree's dynamic power. A clock-enable keeps the clock running and simply holds the flop's value via its CE pin. The functional result at the register is similar; the power and timing implications differ.

    Why not just write clk & enable in Verilog?

    That synthesizes a clock inside the LUT fabric, off the balanced global tree, adding uncontrolled skew and risking glitches on a clock net. Both Vivado and Quartus warn against it; use a CE pin or let the tool infer a BUFGCE/clkctrl instead.

    How much power does a BUFGCE really save?

    It depends on duty cycle and fan-out, but for a block idle most of the time it can remove the majority of that branch's dynamic clock power — the buffers, routing, and the switching of every flop on the branch. A CE pin saves only the flop-internal update energy, not the clock net.

    Can I gate a clock feeding a BRAM or DSP block?

    Prefer the dedicated enable pins those hard blocks already expose (BRAM EN, DSP CE). For a whole cluster, a BUFGCE on the shared clock is appropriate, but never a fabric AND gate.

    Advertisement