Real buffers do not delay rising and falling edges equally. Through a tree of many stages the difference accumulates, and the duty cycle at the leaf is not the duty cycle at the root. The narrower phase is the one that violates the pulse width check.
# 1 GHz clock, 50% duty at the source. 12 non-inverting buffer stages.
period = 1.00
rise_d, fall_d, stages = 0.060, 0.070, 12 # per-stage delays, ns (illustrative)
shift = stages * (fall_d - rise_d) # 0.12: how much later the falling edge arrives
high_leaf = 0.50 + shift
low_leaf = period - high_leaf
min_low = 0.42
slack_low = low_leaf - min_low
assert abs(shift - 0.12) < 1e-9
assert abs(high_leaf - 0.62) < 1e-9 and abs(low_leaf - 0.38) < 1e-9
assert abs(slack_low - (-0.04)) < 1e-9
# balanced with inverting stages in pairs: rise and fall delays swap each stage, so they cancel
pairs = stages // 2
rise_path = fall_d + rise_d # inverter 1 output falls, inverter 2 output rises
fall_path = rise_d + fall_d # inverter 1 output rises, inverter 2 output falls
assert pairs == 6 and abs(rise_path - fall_path) < 1e-12
print("PASS: leaf high", round(high_leaf, 2), "low", round(low_leaf, 2), "low slack", round(slack_low, 2))Each stage makes the falling edge 0.010 ns later than the rising edge, so after 12 stages the high phase is 0.12 ns longer: 0.62 ns instead of 0.50 ns. The low phase is the remainder of the period, 0.38 ns, and it misses a 0.42 ns limit by 0.04 ns. Nothing is wrong with any data path; the clock waveform itself is at fault.
Method | Why it helps |
|---|---|
Use inverting stages in pairs | A rising edge is slow through one stage and fast through the next, so the differences nominally cancel to first order if the pair is matched; residual mismatch remains and must be verified at the leaves. |
Use balanced rise/fall cells for clock trees | Rise and fall delays are closer by design |
Shorten the tree | Fewer stages accumulate less difference |
Check the corner with the largest rise/fall difference | The worst case is reported, not assumed |
Duty cycle at the leaves is reported in each corner, against the nominal at the source.
Distortion is checked in the corners where rise and fall delays diverge most; which corner that is depends on the cell library.
Both phases are checked, not only the one that looks weak at the source.
20 × 0.005 = 0.10 ns longer; the low phase is 0.10 ns shorter.