A constraint change can remove endpoints from the analysis, a netlist change can add new ones. A run-to-run comparison of WNS and TNS then mixes design improvement with changes in what is being measured. Comparing on the endpoints both runs share isolates the real movement.
a = {"e1": -0.05, "e2": -0.02, "e3": 0.10, "e4": -0.08} # run A
b = {"e1": -0.03, "e2": -0.04, "e3": 0.12, "e5": -0.01} # run B: e4 disappeared, e5 is new
def stats(d):
neg = [v for v in d.values() if v < 0]
return round(min(d.values()), 3), round(sum(neg), 3), len(neg)
assert stats(a) == (-0.08, -0.15, 3) and stats(b) == (-0.04, -0.08, 3)
common = sorted(set(a) & set(b))
ca = {e: a[e] for e in common}
cb = {e: b[e] for e in common}
assert stats(ca) == (-0.05, -0.07, 2) and stats(cb) == (-0.04, -0.07, 2)
removed, added = sorted(set(a) - set(b)), sorted(set(b) - set(a))
assert (removed, added) == (["e4"], ["e5"])
moved = {e: round(cb[e] - ca[e], 3) for e in common}
assert moved == {"e1": 0.02, "e2": -0.02, "e3": 0.02}
print("PASS: all endpoints", stats(a), "->", stats(b), "; common endpoints", stats(ca), "->", stats(cb), "; removed", removed, "added", added)View | WNS (ns) | TNS (ns) | Violations |
|---|---|---|---|
Run A, all endpoints | -0.08 | -0.15 | 3 |
Run B, all endpoints | -0.04 | -0.08 | 3 |
Run A, common endpoints (e1, e2, e3) | -0.05 | -0.07 | 2 |
Run B, common endpoints (e1, e2, e3) | -0.04 | -0.07 | 2 |
Over all endpoints, B looks better than A: TNS improves from -0.15 to -0.08 ns. On the endpoints both runs share the TNS is unchanged at -0.07 ns: e1 improved by 0.02 ns and e2 worsened by 0.02 ns. The whole TNS 'improvement' is e4 (-0.08 ns) leaving the analysis, partly offset by e5 (-0.01 ns) joining it. Before accepting that gain, someone must find out why e4 disappeared: a legitimate fix, or a constraint that now hides it.
Run comparisons list endpoints added and removed, with reasons.
The comparison on common endpoints is the headline for progress.
A removed endpoint is explained before its slack is dropped from the totals.
Why e4 is no longer in run B: a netlist change, a constraint change (for example a new exception), or a legitimate fix. Only then is the TNS change meaningful.