Hold violations are the ones you cannot fix by slowing the clock: for same-edge paths on one clock, a chip with a hold failure fails at every frequency. They are also usually cheap to fix, but only if you know which side of the equation to change. The derivation is a mirror of setup with the roles of early and late swapped.
Hold is checked at the same clock edge, for same-edge paths on one clock: the data launched at edge k must not reach the capture flop before that flop has finished capturing the previous data at the same edge k. Use the earliest delays on the data path and the latest capture clock. With launch latency L, capture latency C, minimum clock-to-Q D_cq_min, minimum path delay D_min, hold time H and hold uncertainty U_h:
arrival = L + D_cq_min + D_min (earliest new data)
required = C + H + U_h (capture flop must have finished)
slack = arrival - required
hold met <=> slack >= 0L, C, Dcq_min, Dmin, H, Uh = 0.30, 0.35, 0.35, 0.20, 0.05, 0.05
arrival = L + Dcq_min + Dmin # 0.85
required = C + H + Uh # 0.45
slack = arrival - required # 0.40
assert abs(arrival - 0.85) < 1e-9 and abs(required - 0.45) < 1e-9 and abs(slack - 0.40) < 1e-9
# If the capture clock were 0.5 ns later (large skew), hold would fail:
assert arrival - (C + 0.5 + H + Uh) < 0
print("PASS: hold slack =", round(slack, 2), "ns; period does not appear for same-edge paths on one clock")Hold slack is +0.40 ns. For same-edge paths on one clock, the period T appears nowhere in the equation, which is why a hold failure persists at any frequency, and why delay padding rather than a slower clock is the fix. The danger sign is large skew: a later capture clock (large C) pushes the required time up and eats hold slack.
Setup | Hold | |
|---|---|---|
Delays used | Maximum (slow corner) | Minimum (fast corner) |
Capture clock used | Early | Late |
Period in the equation | Yes | No, for same-edge paths on one clock |
Typical fix | Speed up the path, shift skew, relax the clock | Add delay on the data path, adjust skew |
Fixable by changing frequency | Yes | No, for same-edge paths on one clock |
Hold is signed off in the corner where data is fastest and the capture clock is latest relative to launch, not the setup corner.
Hold fixes (delay cells) are checked against setup slack on the same path; a delay added to fix hold can create a setup violation.
Large positive hold slack is not a goal: it usually means unnecessary delay cells and area.
Hold is fixed by adding delay (buffers or delay cells) on short paths, which adds area and leakage. Setup is fixed by speeding up long paths (larger drive strength, parallelism), which costs power and sometimes area. Both are trade-offs the closure section revisits.