Two ECOs on the same cell or net can undo each other, or produce a result neither author predicted. Applying every ECO at once and sorting out the damage afterwards wastes full runs. Grouping ECOs by the objects they touch lets the independent ones go together and the conflicting ones go in sequence.
ecos = {"e1": {"netA", "cellX"}, "e2": {"cellX", "netB"}, "e3": {"netC"}, "e4": {"netB", "netD"}, "e5": {"netE"}}
names = sorted(ecos)
batch_of = {}
for e in names: # greedy colouring in sorted order: first batch with no shared object
used = {batch_of[n] for n in names if n in batch_of and ecos[e] & ecos[n]}
b = 0
while b in used:
b += 1
batch_of[e] = b
nbatches = max(batch_of.values()) + 1
schedule = [[e for e in names if batch_of[e] == b] for b in range(nbatches)]
assert batch_of == {"e1": 0, "e2": 1, "e3": 0, "e4": 0, "e5": 0}
assert schedule == [["e1", "e3", "e4", "e5"], ["e2"]]
assert nbatches == 2 and len(ecos) == 5
for b in range(nbatches):
members = [e for e in names if batch_of[e] == b]
for i, a in enumerate(members):
for c in members[i + 1:]:
assert not ecos[a] & ecos[c]
print("PASS: batches", nbatches, "; schedule", schedule)Batch | ECOs applied | Why |
|---|---|---|
1 | e1, e3, e4, e5 | No two touch the same object (e1 and e4 share no object, so they share the batch) |
2 | e2 | Touches cellX (with e1) and netB (with e4) |
e1 and e2 both touch cellX; e2 and e4 both touch netB. But e1 and e4 share no object, so they can share a batch: colouring the conflict graph puts e1, e3, e4 and e5 together and e2 alone. A schedule of two batches applies e1, e3, e4 and e5 first, then e2: two verifications instead of five if each ECO were verified alone. A connected component is not a clique: only pairs that share an object conflict.
ECOs declare the cells and nets they touch, and the tooling checks for overlap before batching.
Interactions that are not about shared objects are tracked too: a hold fix and a setup fix on the same endpoint conflict through its slack.
After each batch the fix results are compared with the predictions; large differences mean an undeclared conflict.
Three: e5 would conflict with e1 and e2 only, so greedy colouring gives e.g. {e1, e3, e4}, {e2}, {e5}.