"Timing improved by about 60 picoseconds after a constraint refactor with no design change, which I treat as a flag: a constraint-only gain that large has to be explained. A semantic diff showed one high-risk addition, a false path between clk_a and clk_b, imported from an earlier project where they were asynchronous. Here clk_b is a divide-by-two of clk_a, so the clocks are related. The exception covers 1,120 paths, none truly asynchronous. Removing it brings back three violations, worst minus 50 picoseconds, matching the pre-refactor worst slack, and one of them is the path that fails in hot silicon. I would remove or scope the exception, fix the three with a shared-cell change, rerun the whole matrix, and run a lint that flags false paths between clocks that share a root. The process change is a coverage gate: any exception that covers many times the expected path count gets a mandatory review. The evidence is the before-and-after table on common endpoints and the lint output."
Step | Sentence |
|---|---|
Assumption | A constraint-only improvement is suspect until its coverage is counted |
Mechanism | An imported false path between related clocks removed 1,120 real paths |
Trade-off | Scoping costs review time; removing it costs fixing three real violations |
Evidence | Semantic diff, path count, rerun without the exception, related-clock lint |
# the story in numbers: the gain equals the hidden violation
hidden_worst, reported_gain = -0.050, 0.061
wns_before = -0.050
assert abs(hidden_worst - wns_before) < 0.002
assert round(wns_before + reported_gain, 3) == 0.011
print("PASS: hidden worst slack", hidden_worst, "ns matches the pre-refactor WNS", wns_before, "ns")Whether you notice that a green report can be a symptom.
Whether you know how to measure what an exception covers.
Whether you propose a process fix as well as a technical one.
The three violations that return when it is removed: the worst (-0.050 ns) matches the -0.050 ns WNS that vanished in the refactor.