VHDL · Chapter 7.8 · Sequential Logic Design
Gated Clocks and Why to Avoid Them
It is tempting to disable a register by ANDing an enable with the clock, so the flip-flop only sees clock pulses when enabled. In hand-written RTL this is a classic mistake. A glitch on the enable near a clock edge becomes a spurious clock edge that captures garbage, the gated clock is a new unbalanced clock that wrecks skew and timing analysis, and hold relationships become hazardous. The right tool is the clock enable from the previous lessons, which gates the data rather than the clock and keeps one clean free-running clock net. This lesson explains exactly why gated clocks are dangerous, when clock gating is actually legitimate through purpose-built glitch-free cells the tool inserts, and how to spot and remove the hand-gated anti-pattern in real designs.
Foundation13 min readVHDLGated ClockClock EnableGlitchTimingRTL
1. Engineering intuition — do not put logic on the clock
A clock is special: every flip-flop depends on it arriving cleanly, at a predictable time, with sharp edges. The moment you put combinational logic on the clock path — like ANDing it with an enable — you make the clock depend on data, and data has glitches and delay. A brief glitch on the enable can create an extra clock pulse, clocking your registers when you did not intend; the delay through the AND gate shifts the clock in time, breaking the careful balancing the tools rely on. The rule is simple: keep the clock a clean, free-running net, and control when registers update with a data-path enable instead.
2. Formal explanation — why the gate is dangerous
library ieee; use ieee.std_logic_1164.all;
-- ANTI-PATTERN: gating the clock with an enable.
gated_clk <= clk and en; -- combinational logic on the clock path
bad : process (gated_clk)
begin
if rising_edge(gated_clk) then
q <= d; -- clocked by a glitchy, skewed, hard-to-time clock
end if;
end process;Three concrete problems: (1) glitches — if en changes near a clock edge, the AND output can
produce a sliver pulse that the flip-flop sees as a real edge, capturing wrong data; (2) skew and
balancing — gated_clk is a separate clock net delayed by the gate, so it no longer aligns with the
main clock, breaking skew budgets and clock-tree balancing; (3) timing analysis — static timing
tools treat each clock specially, and a hand-made gated clock is hard or impossible to constrain
correctly, hiding setup/hold violations.
3. The correct alternative — a clock enable
library ieee; use ieee.std_logic_1164.all;
-- CORRECT: free-running clock, enable gates the DATA (lesson 7.5).
good : process (clk)
begin
if rising_edge(clk) then
if en = '1' then q <= d; end if; -- update only when enabled; clock never gated
end if;
end process;What hardware does this become? A flip-flop on the normal clock with a feedback mux selecting d
or its own output q under en (lesson 7.5). The clock stays clean and balanced; the enable is ordinary
data-path logic that timing tools handle easily. This achieves the same goal — update only when enabled —
with none of the gated-clock hazards.
4. Hardware interpretation — glitch hazard vs clean enable
5. Simulation interpretation — the spurious edge
A glitch on the enable creates a spurious gated-clock edge; the enable register is clean
8 cycles6. Debugging example — registers clocking on garbage
Expected: a register updates only when enabled. Observed: the register occasionally captures wrong
data, or behaves nondeterministically across runs/temperature, and timing reports show an unconstrained or
problematic clock. Root cause: the design gated the clock (clk and en), so a glitch or late
transition on en produced a spurious clock edge, and the gated clock net broke skew/timing. Fix:
replace the gated clock with a clock enable — free-running clock, if en = '1' inside the edge guard — or,
for power gating, use the synthesis tool's integrated clock-gating (ICG) cells, which are glitch-free by
construction. Engineering takeaway: never hand-gate a clock with logic; use a clock enable for control
and tool-inserted ICG cells for power gating.
-- BUG: hand-gated clock → spurious edges, skew, untimeable.
-- gated_clk <= clk and en; process(gated_clk) ... q <= d; ...
-- FIX: clock enable on a free-running clock.
process (clk) begin
if rising_edge(clk) then
if en = '1' then q <= d; end if;
end if;
end process;7. Common mistakes & what to watch for
- Hand-ANDing the clock with an enable. Creates glitch, skew, and timing hazards; use a clock enable.
- Putting any combinational logic on the clock path. Inverters/gates/muxes on the clock break timing analysis; keep the clock clean.
- Confusing clock gating with clock enable. The enable gates data; legitimate clock gating uses ICG cells inserted by the tool, not RTL AND gates.
- Assuming RTL clock gating saves power safely. Only tool-inserted, glitch-free gating is safe; hand-rolled gating risks function and timing.
- Multiple derived clocks from logic. Generating clocks with logic (dividers via toggling a signal as a clock) has the same hazards; prefer enables/strobes off one clock, or proper clocking resources.
8. Engineering insight & continuity
Gated clocks are the canonical "do not put logic on the clock" lesson: the clock must stay a clean, balanced, timeable net, so control belongs on the data path as a clock enable, never on the clock itself. Reserve actual clock gating for the synthesis tool's purpose-built, glitch-free cells. This completes the core toolkit of sequential structures. The module's final lesson revisits a subtlety that threads through all of them — Signals versus Variables in Clocked Processes — clarifying how each behaves when registered, before the curriculum turns to Reset Design, which gives all this state a defined starting point.