The check model decides which clock edges bracket the enable's change. Know it and every gating report is easy: the enable must settle before the clock edge that would otherwise pass it, and not move until the clock leaves the sensitive phase.
Gate type | Output follows the clock when... | Setup check (enable settled before) | Hold check (enable held until) |
|---|---|---|---|
AND (active-high clock) | Enable high | Clock rising edge | Clock falling edge |
OR (clock idles high when gated) | Enable low | Clock falling edge | Clock rising edge |
ICG (integrated clock gating cell) | Latched enable high | Clock rising edge at the cell | Clock rising edge at the cell |
For the AND gate the enable may only change while the clock is low. The setup check requires the enable to arrive before the next rising edge; the hold check requires it not to change before the falling edge. Together they confine changes to the low phase. In an integrated clock gating (ICG) cell the enable setup and hold are both checked against the rising clock edge at the cell (the cell's internal latch holds the enable through the high phase), so an enable launched by a rising-edge flop gets a full cycle.
# AND gate, period 10, 50% duty: rising at 0, falling at 5. Enable launched by a rising-edge flop at 0.
T, rise, fall = 10.0, 0.0, 5.0
def check(en_arrival_min, en_arrival_max, setup=0.1, hold=0.1):
setup_slack = (T + rise - setup) - en_arrival_max # before the NEXT rising edge
hold_slack = en_arrival_min - (fall + hold) # after the falling edge of the current cycle
return round(setup_slack, 2), round(hold_slack, 2)
# enable path delay between 5.5 and 8.0 ns after the launching edge
s, h = check(5.5, 8.0)
assert (s, h) == (1.9, 0.4)
# an enable that changes too early (min arrival 4.0) violates hold (still in the high phase)
s2, h2 = check(4.0, 8.0)
assert h2 < 0
print("PASS: setup", s, "hold", h, "; early enable hold slack", h2)With the enable arriving between 5.5 and 8.0 ns, setup slack against the next rising edge (10 ns) is 1.9 ns and hold slack against the falling edge (5 ns) is 0.4 ns: the enable changes only in the low phase. If the shortest enable path were 4.0 ns the enable could change while the clock is still high, giving a negative hold slack and a possible runt pulse.
The waveform below is simulation output of an AND-type gate with two enables. One lane slot is one tick of a sampling clock. The enable en_u changes just after each rising edge, while the clock is high; the enable en_s changes just after each falling edge, while the clock is low.
How to read it: the clock is high for four slots at a time, for example slots 3 to 6 and 11 to 14. en_u changes at slots 5, 13, 21 and 29, two slots after a rising edge. gclk_u is therefore high only at slots 5 to 6, 11 to 12, 21 to 22 and 27 to 28: every pulse is two slots instead of four, some starting late and some ending early. en_s changes at slots 9, 17, 25 and 33, in the low phase. gclk_s is high at slots 11 to 14 and 27 to 30, two complete four-slot pulses, and nothing else. The simulation has no timing checks; it shows what the checks exist to prevent.
Gating checks are enabled and inferred for every gate; the count of gates equals the count of gating checks.
The gating cell type is known (AND, OR, ICG) and the right edges are used.
Enable launch clock and gate clock are related correctly (same or related clocks).
The clock falling edge: the OR output follows the clock when the enable is low, so the enable must settle before the clock goes low and hold until it returns high.