Removing a gate level shortened the minimum paths into a group of flops and left a wider gap between their shortest and longest paths in that cone. For most of those endpoints there is enough setup slack to buy back hold with delay cells. For a minority the gap itself is the problem. The 31 setup violations are separate: they sit in the deeper cone, where the added gate level lengthened the maximum paths.
Step | Endpoints | Method | Rung of the ECO ladder |
|---|---|---|---|
1 | 196 | Insert delay at the endpoints, within setup slack | Buffer insertion (rung 3) |
2 | 12 of the 18 | Insert delay on the short branch only, ahead of the point where short and long paths merge (a per-path fix, not at the endpoint) | Buffer insertion (rung 3) |
3 | 6 of the 18 | Restructure the logic to narrow the spread between longest and shortest paths without re-adding the removed gate (function unchanged, equivalence checked) | Logic change (rung 5) |
4 | — | Verification: fast loop after each batch, two full runs | Union of all rungs used |
counts = {"delay": 196, "short_branch": 12, "logic": 6}
assert sum(counts.values()) == 214 - 0
batches = [("delay", 196), ("short_branch", 12), ("logic", 6)]
hours = 0
for name, n in batches:
hours += 5 # fast loop after each batch
hours += 2 * 18 # two full runs
assert hours == 51
waived = 214 - sum(counts.values())
assert waived == 0
print("PASS: all 214 hold endpoints have a fix:", counts, "; schedule", hours, "h of 60; waivers", waived)Every endpoint has a fix: 196 by delay at the endpoints, 12 by delay on the short branch only, ahead of the point where short and long paths merge, and 6 by restructuring the logic to narrow the spread; no waiver is needed. The schedule takes 51 of the 60 hours: three batches each followed by a five-hour fast loop, then two 18-hour full runs. The nine spare hours are the buffer for the batch that goes wrong. The 31 setup violations are handled in the same batches: the slow-corner violations are mostly shared segments of paths touching the added gate level in the deeper cone, so one sizing change covers many of them.
Do not waive hold in the fast corner: hold failures are not fixed by lowering the clock frequency.
Do not apply all changes in one batch: a failure leaves no time to find the cause.
Do not skip the equivalence check on the logic rebalancing: it is the only proof that the functional fix survived.
Delay insertion does not change function; restructuring logic can, so equivalence has to confirm that the functional ECO is intact.