Hold fixes insert delay, and delay on a path is delay on every check through it. If the setup slack at that endpoint is smaller than the delay needed, the fix trades a hold violation for a setup one. Checking each fix against the available setup slack prevents that.
margin = 0.005
endpoints = [("e1", -0.030, 0.200), ("e2", -0.010, 0.020), ("e3", -0.050, 0.040), ("e4", 0.004, 0.500)] # (name, hold slack, setup slack) in ns
rows = {}
for name, hold, setup in endpoints:
need = max(0.0, margin - hold) # delay to add so hold slack reaches the margin
left = setup - need
rows[name] = (round(need, 3), round(left, 3), left >= -1e-12)
assert rows == {"e1": (0.035, 0.165, True), "e2": (0.015, 0.005, True), "e3": (0.055, -0.015, False), "e4": (0.001, 0.499, True)}
fits = [n for n, r in rows.items() if r[2]]
assert fits == ["e1", "e2", "e4"]
print("PASS: fixes that fit", fits, "; needs another method:", [n for n, r in rows.items() if not r[2]])Endpoint | Hold slack (ns) | Delay needed (ns) | Setup slack (ns) | Setup left after fix | Fits? |
|---|---|---|---|---|---|
e1 | -0.030 | 0.035 | 0.200 | 0.165 | Yes |
e2 | -0.010 | 0.015 | 0.020 | 0.005 | Yes, barely |
e3 | -0.050 | 0.055 | 0.040 | -0.015 | No |
e4 | +0.004 | 0.001 | 0.500 | 0.499 | Yes |
e1 and e4 have plenty of setup slack to spend. e2 fits with 5 ps left, so it is safe but it must be marked as having used its slack. e3 needs 55 ps and has only 40 ps: inserting the delay would turn a hold violation of 50 ps into a setup violation of 15 ps. e3 needs a different approach (see order of operations), such as reducing the spread between its longest and shortest paths. A hold fix at the endpoint adds the same delay to every path that reaches it, so the check uses the worst setup slack of those paths.
Insert near | Effect |
|---|---|
The endpoint (flop D pin) | Affects only paths into that endpoint; safest for setup elsewhere |
The middle of the fan-in | May fix several endpoints at once but costs setup on all of them |
The launch point | Affects every path from it, and clock-to-Q timing |
Each hold ECO lists the delay added and the setup slack left; slack left near zero is flagged.
Delay is inserted as close to the endpoint as possible unless there is a reason to share it.
Hold fixes are done in all hold scenarios together; a fix verified in one corner can still fail in another.
The slow corner: the inserted delay is larger there, so the real setup slack left may be negative.