Verifying, Recording & Reverting ECOs
Chapter 12 — Verifying, Recording & Reverting ECOs (+ Quick
Reference)
An Engineering Change Order is only as trustworthy as the proof that backs it. The edit itself may take seconds; the discipline of recording what you did, verifying that it actually helped, and being able to walk it back cleanly is what separates a controlled late-stage change from a tape-out risk. This final chapter closes the loop. We treat the ECO not as a one-shot patch but as a transaction: it is logged, it is checked against a verification gate, it is signed off, and — if it misbehaves — it is reverted with the same rigor it was applied. By the end you will have a mental model of the change record, an undo discipline, a complete sign-off checklist, a pitfalls table, and a consolidated command quick-reference for the entire workflow introduced across this book.
12.1 Recording the Change: The ECO Journal
Every physical edit you make in an ECO must be reconstructible by someone who was not in the room. The mechanism for that is the change record (often called an ECO journal or change log): an ordered, human-readable and machine-replayable list of every atomic edit. If your scripts cannot answer "what changed, why, when, and by whom," the change is not finished.
A good change record captures intent, not just mechanics. Knowing that inst_U42 was upsized is useful; knowing it was upsized to fix a 38 ps setup violation on path_grp_core2mem is gold during the next review.

A change record entry typically contains:
| Field | Purpose | Example value |
|---|---|---|
| Sequence ID | Strict ordering for replay/undo | ECO-0007-step-03 |
| Edit type | Class of operation | size_cell |
| Target object | Instance / net / region affected | inst_U42 |
| Before state | What it was | BUFX2 |
| After state | What it became | BUFX8 |
| Rationale | Why the edit was made | setup fix, slack -38 ps |
| Author / timestamp | Auditability | pd_eng / 2026-06-13T14:02 |
| Verification tag | Result that justified keeping it | slack +6 ps post-fix |
The journal should be append-only during the session. You never silently rewrite history; if an edit is undone, that undo is itself a logged entry. This gives you a faithful timeline and lets two engineers diff two ECO attempts.
# Record each atomic edit with intent so it can be reviewed and replayed
record_eco -id "ECO-0007-step-03" \
-op size_cell -target inst_U42 \
-before BUFX2 -after BUFX8 \
-reason "setup fix path_grp_core2mem, slack -38ps" \
-author $env(USER)
# At the end of the session, freeze the journal for handoff
record_eco -finalize -out ./eco/eco0007_journal.tcl
The finalized journal should be a self-contained, replayable script. A reviewer or the next shift must be able to load a clean database, source the journal, and arrive at exactly your post-ECO state. If sourcing the journal does not reproduce your result bit-for-bit, the record is incomplete and the ECO is not handoff-ready. Two flavors of ECO change record show up in practice, and a strong candidate can name both. A pre- mask (logical) ECO record describes changes at the netlist level — cells added, sized, or rewired — and is the artifact that flows back to the synthesis and verification teams so the golden netlist can be kept in lockstep with the layout. A post-mask (metal-only) ECO record is more constrained: it must describe only edits achievable on metal and via masks using pre-placed spare cells, because base layers are frozen. The journal format is the same, but the post-mask record additionally tracks which spare instances were consumed and which metal layers were touched, since those drive mask cost. Confusing the two is a classic interview trap: proposing a base-layer edit during a metal-only ECO is an immediate red flag. A subtle but important habit is to record the baseline fingerprint alongside the journal — a hash or summary of the starting database, the library set, the constraints, and the corner/mode definitions in force. A journal is only replayable against the exact inputs it was built on. If a reviewer sources your journal on a different timing snapshot or a refreshed library, the edits may apply but the verification result will not match, and you will chase a phantom discrepancy. Pinning the baseline removes that ambiguity.
12.2 Identifying and Reverting Nonoptimal Changes
Not every edit you try is a good edit. ECO loops are exploratory: you size a cell, you insert a buffer, you reroute — and sometimes the metric you were chasing improves while another quietly degrades. The skill is detecting the bad edits early and removing them without leaving residue. Detecting a nonoptimal change. Compare metrics immediately before and after each edit (or each small batch). A change is suspect when any of the following is true:
- The targeted slack improved by less than the cost it imposed elsewhere (you fixed −38 ps on one path but created −20 ps on three others).
- Total negative slack (TNS) or violation count went up across any mode/corner.
- Area, leakage, or dynamic power rose without a justifying timing gain.
- A buffer insertion fixed setup but opened a hold violation, or moved congestion past a threshold. The cleanest way to support this is to checkpoint before each batch and compute a delta report afterward. If the delta is negative on the whole, revert.
# Snapshot, attempt, measure, decide
record_eco -checkpoint cp_before_buf
insert_buffer -net net_clk_skewfix -lib_cell BUFX4 -at {120.4 88.0}
legalize_placement -region {110 80 135 100}
report_timing -delta_against cp_before_buf -modes {func test} -corners {ss_125
ff_m40}
# If the delta worsens TNS or violators, undo this batch
revert_eco -to cp_before_buf
Undo discipline. Reverting is a first-class operation, not a panic button. Three rules keep it clean:
- 1. Revert in reverse sequence order. Undo the last edit first. Reverting out of order can leave
dangling nets or unlegalized cells.
- 2. Revert the side effects, not just the primary edit. If a buffer insertion also created a spare-cell
mapping and a placement nudge, all three must come out together. Treat the batch as the unit of undo.
- 3. Log the revert. The undo is a journal entry with its own rationale ("reverted: created 3 new hold
violators"). The audit trail must show the dead end, not hide it.
| Bad-change symptom | Likely cause | Clean revert action |
|---|---|---|
| New hold violations after | Upsize/buffer sped a path feeding a | revert_eco the size/buffer, retry with |
| setup fix | short path | smaller drive |
| Congestion hotspot | ECO cells clustered in a tight region appears | revert placement + insertion, spread targets |
| Leakage up, timing flat | Upsized cells on already-met paths | revert to original size_cell state |
| LVS mismatch after edit | Manual edit_netlist left a floating pin | revert netlist edit, reapply with full connectivity |
A practical question is how big should a batch be? Too small, and you drown in checkpoints and delta reports; too large, and a regression cannot be localized. A good rule of thumb is to scope a batch to a single intent — one path group, one violating endpoint cluster, or one congestion region. All the edits needed to satisfy that intent (size, buffer, place, legalize, supply-fix) belong to one batch, and the batch is the unit you keep or revert. This way every checkpoint maps to a question you can answer cleanly: "did fixing this endpoint help, on the whole, or not?" Reverting also interacts with spare-cell accounting. When a metal-only edit that mapped logic onto spares turns out to be nonoptimal, the revert must return those spare instances to the free pool, not just disconnect them. A spare that is logically freed but still marked consumed silently shrinks your budget for later ECOs — a leak that only surfaces when a future ECO unexpectedly runs out of spares. The cleanest discipline is to let revert_eco own the rollback of the entire map_to_spares operation rather than hand-editing the netlist back, so the spare bookkeeping stays consistent with the connectivity.
12.3 The Post-ECO Verification Gate
No ECO is accepted on the strength of one timing report. After the edits settle, the design must pass a verification gate — a fixed battery of checks that proves the change is safe across every dimension it could have disturbed. Run these incrementally where possible (only re-analyze the affected fan-in/fanout cones) but never skip a category just because the edit "looked local." Late-stage edits have a habit of breaking distant things.

| Check | What it confirms | Scope after ECO |
|---|---|---|
| Incremental STA — | No new/worse setup violations | All affected modes & corners |
setup
| Incremental STA — hold | No new hold violations (the #1 ECO regression) | All corners, esp. fast/min |
|---|---|---|
| DRC | Edits introduced no geometry/spacing/via | Edited regions + neighbors |
violations
LVS Layout still matches the (post-ECO) netlist Whole block if netlist
| Equivalence check | Logical function unchanged vs golden reference | Full functional equivalence |
|---|---|---|
| Power / IR / EM | No new IR droop or EM hotspots from added cells | Local rails + affected domains |
| Antenna | Rerouting did not create antenna violations | Edited nets |
A few points interviewers love to probe:
- Hold is the silent killer. Setup-driven ECOs (upsizing, buffering) accelerate paths, which is exactly how you manufacture hold violations. Always re-run hold at the fast corner after any speed- improving edit.
- Equivalence checking is non-negotiable for functional ECOs. Sizing and buffering preserve logic, so a structural-only check may suffice; but any
edit_netlistthat adds/removes gates or
remaps spares must pass full functional equivalence against the golden netlist. A passing timing report on a logically wrong netlist is worse than useless.
- Multi-corner / multi-mode is the default, not an option. An edit that helps the slow corner can hurt the fast one, and a fix in functional mode can break test mode. The gate runs the full corner/ mode set the block signs off on.
- Incremental does not mean local-only. Running STA incrementally saves runtime by re-timing affected cones, but the pass criterion is still global: you check that no endpoint anywhere regressed, not just endpoints near the edit. Coupling, clock reconvergence, and shared buffers can carry a disturbance well beyond the edited region. Why physical re-checks cannot be skipped. It is tempting to believe that a logically equivalent edit is physically safe, but every added or moved cell occupies area, draws current, and may force a detour route. A buffer dropped into a dense region can violate spacing rules with a neighbor it never touched logically; a cluster of upsized cells can pull enough current to create a local IR droop that pushes a nearby path out of spec at the operating voltage. Antenna violations are the canonical surprise: rerouting a single net to make room for an ECO cell can leave a long metal segment connected to a gate during fabrication, requiring a diode fix. None of these are visible in a timing report, which is exactly why DRC, LVS, power/IR/EM, and antenna are gate members in their own right. A disciplined team also treats the gate as ordered. Run the fast, cheap checks first (incremental STA, equivalence) so an obviously broken edit is caught before you spend runtime on full LVS or power analysis. A failure at any stage routes straight back to the revert path; there is no value in completing the remaining checks on an edit you already know is being rolled back.
# Full post-ECO verification gatereport_timing -check setup -modes {func test scan} -corners {ss_125 ss_m40 tt_25} -slack_lesser_than 0report_timing -check hold -modes {func test scan} -corners {ff_m40ff_125} -slack_lesser_than 0equivalence_check -golden ./ref/golden.v -revised ./eco/post_eco.v -report ./eco/eq.rpt# Physical re-checks confined to touched area where possiblerun_drc -incremental -regions $eco_regionsrun_lvs -netlist ./eco/post_eco.vcheck_power -ir -em -domains $affected_domainscheck_antenna -nets $eco_nets
12.4 ECO Sign-Off Checklist
An ECO is "accepted" only when every item below is demonstrably true. Treat unchecked boxes as blockers, not warnings.
- [ ] Change recorded — every edit is in the journal with rationale; finalized journal replays to the exact post-ECO state.
- [ ] Setup clean — no new or worsened setup violators in any signed-off mode/corner; TNS not regressed.
- [ ] Hold clean — no new hold violators at fast/min corners (verified, not assumed).
- [ ] Logic verified — functional equivalence passes against the golden reference; spare/cell remapping confirmed.
- [ ] DRC clean — edited regions and neighbors are violation-free.
- [ ] LVS clean — layout matches the post-ECO netlist (re-run if netlist changed).
- [ ] Power/IR/EM ok — no new droop or EM hotspot from added cells; domain supplies intact.
- [ ] Antenna ok — rerouted nets pass antenna rules.
- [ ] Placement legal — all ECO cells legalized; no overlaps, on-grid, in legal rows/sites.
- [ ] Spares accounted — spare cells consumed are documented; remaining spare budget known.
- [ ] Nonoptimal edits removed — every dead-end edit reverted and the revert logged.
- [ ] Metrics net-positive — area/power/timing trade clearly favorable vs pre-ECO baseline.
- [ ] Handoff ready — journal, reports, and post-ECO database packaged for the next stage.
12.5 Common ECO Pitfalls and How to Avoid Them
| Pitfall | Why it bites | Prevention |
|---|---|---|
| Fixing setup, creating | Speeding a path shortens margin on | Re-run hold at fast corner after every |
| hold | coupled short paths | speed edit |
| Skipping multi-corner/ | Edit helps one corner, breaks another | Always verify across the full sign-off set |
mode
| Unlegalized ECO | Placed off-grid or overlapping; DRC/ | legalize_placement after every |
|---|---|---|
| cells | LVS fail | placement edit |
| Floating pins after | Manual edit forgot a connection; LVS | Use guarded edit_netlist ; re-run LVS |
| netlist edit | mismatch | immediately |
| No change record | Edit can't be reviewed, replayed, or undone | record_eco every atomic edit, finalize for handoff |
| Reverting out of order | Leaves dangling nets / unlegalized | Undo last-in-first-out; revert whole batches |
cells
| Disturbing the clock | Buffering near clock alters skew | Treat clock edits as a separate, gated |
|---|---|---|
| tree | silently | category |
| Consuming all spares | No spare cells left for later mask ECOs early | Track spare budget; prefer min-impact mapping |
| Trusting timing alone | Logically wrong netlist can still "meet timing" | Equivalence check is mandatory for functional ECOs |
| Big-bang batches | Hard to localize which edit caused regression | Small batches + checkpoints + delta reports |
The connective tissue across this table is small, logged, immediately-verified steps. Engineers who get burned by ECOs almost always made many edits, then verified once at the end, and could not tell which change introduced the regression. One more pitfall deserves a paragraph of its own because it is so easy to rationalize: closing setup at the cost of an unverified hold corner. Under deadline pressure it is tempting to run hold at only the corner you "expect" to be worst and call it done. But hold margins are tiny and corner-sensitive; the corner that bites is often not the one intuition picks, especially once on-chip variation and clock skew are folded in. The safe posture is mechanical, not intuitive: any edit that improves a data path's speed triggers a hold re-check at every min/fast corner in the sign-off set, no exceptions. The cost of one extra incremental hold run is trivial next to the cost of a silicon hold failure discovered after tape-out.
12.6 Consolidated Command Quick-Reference
The generic command names used throughout this book, grouped by phase. Names are deliberately vendor-neutral; map them to your environment's equivalents.
| Phase | Command | What it does |
|---|---|---|
| Orchestration | apply_eco | Drive an ECO directive set onto the design |
| Logical edit | edit_netlist | Add/remove/reconnect gates and nets |
| Logical edit | size_cell | Change a cell's drive strength / variant |
| Logical edit | insert_buffer | Add a buffer/inverter pair on a net |
| Spares | map_to_spares | Bind new logic onto pre-placed spare cells |
| Physical | place_eco_cells | Place newly added ECO instances |
| Physical | legalize_placement | Snap ECO cells to legal rows/sites |
| Power | update_supply_nets | Reconnect power/ground for new/moved cells |
| Verify | report_timing | Incremental STA across modes/corners |
| Verify | equivalence_check | Confirm logic vs golden reference |
| Record | record_eco | Log/checkpoint/finalize the change journal |
| Revert | revert_eco | Roll back to a checkpoint or undo a batch |
A canonical end-to-end skeleton tying them together:
# 1. Begin: snapshot a known-good baseline
record_eco -checkpoint cp_baseline
# 2. Apply the change set (logical + physical)
apply_eco -directives ./eco/eco0007.dir
edit_netlist -add_buffer -net net_data_q -lib_cell BUFX4 ;# or size/insert as
needed
size_cell inst_U42 -to BUFX8
insert_buffer -net net_long_haul -lib_cell BUFX6 -at {120 88}
map_to_spares -logic added_cells -strategy nearest
# 3. Realize physically and fix power
place_eco_cells -instances $added_cells
legalize_placement -region $eco_regions
update_supply_nets -instances $added_cells
# 4. Verify the gate
report_timing -check setup -modes {func test} -corners {ss_125 tt_25}
report_timing -check hold -modes {func test} -corners {ff_m40}
equivalence_check -golden ./ref/golden.v -revised ./eco/post_eco.v
# 5. Decide: keep (record) or roll back (revert)
record_eco -finalize -out ./eco/eco0007_journal.tcl
# revert_eco -to cp_baseline ;# uncomment if the gate fails
12.7 Interview Q&A — Rapid Fire
buffering) speed up data paths. A faster path arriving at a capture flop can violate hold on coupled short paths, so any speed-improving edit must be re-checked for hold at the fast/min corner.
atomic, ordered, self-contained operation so that sourcing the finalized journal on a clean baseline reproduces the post-ECO state exactly. It matters for review, handoff, debug, and clean reverts.
buffering, which preserve logic (a structural check may suffice). Mandatory for any functional ECO that adds, removes, or remaps logic — including spare-cell mapping — because timing reports say nothing about logical correctness.
Treat the batch as the unit of undo: revert the placement nudge, the spare mapping, and the insertion together, in reverse order, then log the revert with its rationale. Never undo only the primary edit.
the delta against the pre-edit checkpoint, confirm the net regression, revert_eco the batch, and retry with a lower-impact fix (smaller upsize, better-placed buffer, or a different path target).
Key Takeaways
- An ECO is a transaction: record it, verify it against a fixed gate, sign it off, or revert it cleanly — never a casual edit.
- The change record must be append-only and replayable; if sourcing the journal doesn't reproduce your result, the ECO isn't done.
- Undo discipline means reverting whole batches in reverse order, removing side effects, and logging the revert itself.
- The verification gate is multi-corner, multi-mode, and covers setup, hold, DRC, LVS, equivalence, power/IR/EM, and antenna — hold and equivalence are the two most-skipped, highest-risk checks.
- Work in small, logged, immediately-verified batches so any regression is instantly traceable to the edit that caused it.
- The sign-off checklist is a gate of blockers, not suggestions — every box must be demonstrably true before acceptance and handoff.
ChipBuddy
← Home
Comments
Leave a Reply