A large gap between two tools is a symptom. The cause is found by comparing the pieces of a path, not the total. The pieces are few: cell delay, net delay, clock latency and skew, setup or hold time, and uncertainty.
# Path components in ns for one endpoint (illustrative)
impl = {"cell": 0.52, "net": 0.18, "skew_credit": 0.05}
signoff = {"cell": 0.53, "net": 0.27, "skew_credit": 0.05}
period, setup = 1.00, 0.06
def slack(c):
return round(period - setup - (c["cell"] + c["net"]) + c["skew_credit"], 3)
assert slack(impl) == 0.29 and slack(signoff) == 0.19
diff = {k: round(signoff[k] - impl[k], 3) for k in impl}
assert diff == {"cell": 0.01, "net": 0.09, "skew_credit": 0.0}
biggest = max(diff, key=lambda k: abs(diff[k]))
assert biggest == "net"
assert round(slack(signoff) - slack(impl), 3) == round(-(diff["cell"] + diff["net"]) + diff["skew_credit"], 3)
print("PASS: slack impl", slack(impl), "signoff", slack(signoff), "; largest difference:", biggest, diff[biggest])The slack gap is 0.10 ns. Cell delay differs by 0.01 ns and skew credit is unchanged, so 0.09 ns comes from net delay: the signature of different parasitics, for example estimated wire load in one tool and extracted routing in the other. The decomposition turned a vague 'tools disagree' into a specific question about extraction.
Component that moved | Likely cause |
|---|---|
Net delay | Different parasitics or extraction corner; estimated versus routed |
Cell delay | Different library version, delay model, or slew propagation |
Clock latency or skew credit | Ideal versus propagated clock; different common-path pessimism handling |
Setup or hold time | Different library or slew at the capture pin |
Uncertainty | Different margins or derates applied |
The same endpoint is compared with the same startpoint, clocks and path in both tools.
The comparison covers a sample of endpoints, so a cause is confirmed by several, not one.
The fix is in the setup (matching parasitics, libraries, margins), not in a per-endpoint waiver.
The library or delay-model setup: different library versions, a different model, or different slew handling are the likely causes.