A flop sits between two stages. Delaying its clock by d gives the stage before it d more time to settle, and the stage after it d less. Hold moves the other way. Four constraints bound d, and the window they leave is the useful skew available.
Check | Effect of delaying the flop's clock by d | Constraint |
|---|---|---|
Setup into the flop (stage 1) | Gains d | s1 + d ≥ m |
Hold into the flop (stage 1) | Loses d | h1 - d ≥ m |
Setup out of the flop (stage 2) | Loses d | s2 - d ≥ m |
Hold out of the flop (stage 2) | Gains d | h2 + d ≥ m |
m = 0.005 # margin, ns
s1, h1 = -0.050, 0.080 # stage 1 (FF1 -> FF2): setup, hold
s2, h2 = 0.100, 0.030 # stage 2 (FF2 -> FF3): setup, hold
lo = max(m - s1, m - h2)
hi = min(h1 - m, s2 - m)
assert round(lo, 3) == 0.055 and round(hi, 3) == 0.075
d = round((lo + hi) / 2, 3)
assert d == 0.065
after = {"s1": round(s1 + d, 3), "h1": round(h1 - d, 3), "s2": round(s2 - d, 3), "h2": round(h2 + d, 3)}
assert after == {"s1": 0.015, "h1": 0.015, "s2": 0.035, "h2": 0.095}
assert all(v >= m for v in after.values())
print("PASS: feasible delay window", (round(lo, 3), round(hi, 3)), "ns; choose", d, "giving", after)Stage 1 needs at least 55 ps of help (50 ps of setup deficit plus the 5 ps margin). Stage 1's hold slack allows at most 75 ps, and stage 2's setup slack allows 95 ps. The window is 55 to 75 ps; choosing the middle, 65 ps, gives every check at least 15 ps. If the window were empty (lo greater than hi) the flop could not be fixed by skew alone, just as in the endpoint case of the order-of-operations lesson. Choosing the middle of the window leaves room for variation on both sides.
Each skewed flop has its window computed with all four checks and in every corner, not only the one that motivated it.
The chosen skew is near the middle of the window unless there is a reason to be asymmetric.
The stage after the skewed flop is checked after the fix: it paid for the gain.
hi = 0.040 - 0.005 = 0.035, which is below lo = 0.055: the window is empty, so skew alone cannot fix stage 1.