Thousands of failing endpoints are not thousands of problems. Endpoints that fail in the same set of views usually share a cause. Grouping them by failing-view signature reduces a list to a handful of work items.
from collections import defaultdict
views = ["func_ss", "func_ff", "scan_ss"]
slack = { # endpoint -> slack per view (ns), setup and hold together are not mixed here: setup slack only
"e1": [-0.04, 0.20, 0.10], "e2": [-0.06, 0.18, 0.12], "e3": [-0.03, -0.02, 0.05],
"e4": [0.10, 0.15, -0.07], "e5": [-0.05, 0.19, 0.11], "e6": [0.22, 0.30, 0.25],
}
groups = defaultdict(list)
for ep, s in slack.items():
sig = tuple(v for v, x in zip(views, s) if x < 0)
if sig:
groups[sig].append(ep)
assert dict(groups) == {("func_ss",): ["e1", "e2", "e5"], ("func_ss", "func_ff"): ["e3"], ("scan_ss",): ["e4"]}
sizes = sorted(((len(v), k) for k, v in groups.items()), reverse=True)
assert sizes[0] == (3, ("func_ss",))
print("PASS: groups", {k: v for k, v in groups.items()})Signature | Endpoints | Interpretation |
|---|---|---|
func_ss only | e1, e2, e5 | Slow-corner functional setup failures: the main closure work |
func_ss and func_ff | e3 | Fails setup in two corners of one mode: severe, likely a real structural problem; setup can still fail in the fast view where fixed external delays or dominating clock skew outweigh the faster cells |
scan_ss only | e4 | Scan-mode problem: constraints or scan logic, independent of the functional work |
Six endpoints become three groups and one clean one. The three that fail only in the slow functional view are one work item. The endpoint failing setup in two functional views needs separate attention because it is already failing in a second corner, which is physically plausible where fixed external delays or dominating clock skew outweigh the faster cells in the fast view. The scan failure has a different owner.
A triage table with signature, count, owner and next action, reviewed every day during closure.
Signatures with one endpoint are not ignored: a singleton can be the most severe.
Groups are reassigned when a fix changes the signature of its members.
The scan_ss only group (e4): it fails only in the scan scenario.