Violations are usually reported path by path, but paths overlap. Cells and nets that many failing paths share are where one fix can do the work of many. Fixing the worst path alone may leave all the others.
slack = {"p1": -0.015, "p2": -0.012, "p3": -0.019, "p4": -0.008, "p5": -0.018} # setup slack, ns
through_x = {"p1", "p2", "p3", "p5"} # paths that pass through shared cell X
speedup_x = 0.020
after_shared = {p: round(s + speedup_x, 3) if p in through_x else s for p, s in slack.items()}
assert after_shared == {"p1": 0.005, "p2": 0.008, "p3": 0.001, "p4": -0.008, "p5": 0.002}
remaining_shared = sorted(p for p, s in after_shared.items() if s < 0)
assert remaining_shared == ["p4"]
# fixing only the worst path (p3) with a private 20 ps gain
after_worst = {p: (round(s + 0.020, 3) if p == "p3" else s) for p, s in slack.items()}
remaining_worst = sorted(p for p, s in after_worst.items() if s < 0)
assert remaining_worst == ["p1", "p2", "p4", "p5"]
print("PASS: after speeding the shared cell, failing:", remaining_shared, "; after fixing only the worst path:", remaining_worst)Fix | Failing paths before | Failing paths after |
|---|---|---|
Speed up shared cell X by 20 ps | 5 (p1 to p5) | 1 (p4) |
Speed up a private cell on the worst path p3 by 20 ps | 5 | 4 (p1, p2, p4, p5) |
Four of the five failing paths pass through cell X. A 20 ps speed-up of X clears all four, leaving p4 (which does not use X). The same 20 ps spent on a cell only the worst path uses clears only that path. Finding shared segments is the main skill: group failing paths by common cells and nets, and rank the segments by how many failing paths they carry, weighted by the slack deficit.
Lever | What it does | Watch for |
|---|---|---|
Upsize a driver | Lowers its delay and the transition downstream | Input capacitance on the previous stage |
Swap to a faster threshold cell | Lowers cell delay | Leakage |
Buffer a long or high-fanout net | Isolates load | Added cell delay and area |
Restructure logic | Reduces depth | Needs equivalence checking |
Useful skew | Moves slack between stages | Hold, variation |
Failing paths are grouped by shared segments before any fix is chosen.
Every fix records the number of paths it was expected to clear and the number it actually cleared.
Fixes that clear fewer paths than predicted are examined: the shared segment may have been mis-identified.
Nothing: p4 would gain 20 ps and go from -0.008 to +0.012 ns.