← Home Mixed (Concurrent) Placement
6 Mixed (Concurrent) Placement

Incremental Tuning & ECO Re-Placement

Concurrent macro and standard-cell placement with MSV awareness and incremental tuning

Chapter 6 — Incremental Tuning & ECO Re-Placement

Why You Almost Never Re-Place From Scratch

By the time a block reaches a stable mixed-placement state, an enormous amount of work has been amortized into that result. Macros have been positioned and pinned, channels have been sized, the standard-cell sea has settled into a low-wirelength configuration, and timing has been coaxed into a recognizable shape. That converged state is expensive — measured in both runtime and human judgment. When the netlist changes, the instinct of a novice is to throw it all away and run the full flow again. The instinct of an experienced engineer is the opposite: preserve everything that is still valid and touch only what changed. This matters because in real projects the design is never frozen. RTL re-spins arrive, functional ECOs land late, a clock-gating cell gets inserted, a buffer tree is restructured, a few thousand gates are added to fix a corner-case bug. Each of these is a perturbation, not a rewrite. The skill of incremental placement is knowing how to fold a perturbation into a good result without inducing a fresh, unpredictable convergence — because a fresh run will give you a different good answer, and "different" is the enemy of a closing block.

Technical diagram

Incremental Placement vs. a Fresh Run

Incremental placement takes an existing, legal (or near-legal) placement and refines it locally. It nudges cells, re-spreads small overflowing regions, and re-optimizes the immediate neighborhood of a change while leaving the global structure intact. A fresh run, by contrast, re-derives the entire cell distribution from connectivity alone and is free to land anywhere in the solution space. The decision hinges on how much of the existing solution is still trustworthy. If 98% of the netlist is unchanged and the floorplan is identical, the existing placement is almost entirely correct and you want to keep it. If the macro set changed, the die shrank, or the connectivity churned by more than roughly 15–20%, the old solution may be actively misleading and a fresh run is cleaner.

DimensionIncremental PlacementFresh (Full) Re-Place
Starting pointExisting converged placementConnectivity only
Scope of motionLocal, boundedGlobal, unbounded
RuntimeMinutes to low hoursHours
Result determinism vs. priorHigh — most cells stay putLow — new global optimum
Timing/ECO correlationPreservedBroken; re-correlate everything
Best whenSmall netlist/constraint deltaFloorplan or macro changes, large churn
RiskQoR drift over many passesThrowing away good work

The subtle trap is treating incremental as strictly inferior. It is not. For a closing block, stability is a feature. An incremental pass that holds 95% of cells fixed and fixes one congestion hotspot is worth more than a full run that improves average wirelength by 2% but moves every cell and forces a complete timing re-correlation.

The ECO Flow for a Revised Netlist

The most common incremental scenario is a netlist ECO: someone hands you a new netlist that is mostly the old one plus deletions, additions, and rewiring. The flow has a predictable shape.

  1. 1. Ingest the revised netlist and diff it. The tool compares the new netlist against the placed design

and classifies every instance: unchanged (same name, same master, same connectivity), modified (rewired or resized), added (brand new), and deleted (gone). This classification is the foundation of everything that follows.

  1. 2. Map unchanged cells to their existing locations. Every cell that survived the diff keeps its

coordinates. This is the heart of disturbance minimization — the vast majority of the design simply does not move.

  1. 3. Place only the new and changed cells. Added cells have no location yet; modified cells may want

to move slightly toward their new neighbors. The placer solves a small, constrained sub-problem: find good spots for the newcomers given that everything else is fixed.

  1. 4. Legalize locally. New cells dropped into the sea will overlap existing ones. Legalization shoves

them into legal rows, displacing neighbors as little as possible, propagating ripple only as far as needed to resolve overlaps.

  1. 5. Minimize timing disturbance. Because unchanged cells held position, paths that did not touch the

ECO retain their delays. You re-time only the affected cone and verify nothing regressed.

Technical diagram

Preserving Fixed Macros, Good Regions, and Constraints

The incremental pass must respect everything you already decided. Macros are the most important: they should be hard-fixed so the placer treats them as immovable obstacles, never candidates for motion. The same applies to any region you have manually tuned — a hand-placed datapath, a carefully spread clock spine, a power-critical cluster. Two mechanisms protect good work. First, fixing marks instances as non-movable. Second, bounding (region or guide constraints) keeps groups inside a defined area so the incremental engine cannot scatter them. A robust ECO setup re-asserts these constraints before the incremental pass, because a freshly ingested netlist may have lost placement status flags on re-read.

Object classRecommended status in ECO passRationale
MacrosFixedFloorplan decision; never auto-move
Hand-tuned region cellsFixed or tightly boundedPreserve manual effort
Unchanged std cellsPlaced, movable (low priority)Allow tiny relief moves only
Added cellsMovableNeed a home
Blockages / keep-outsRe-assertedOften dropped on netlist re-read

The same discipline applies to timing and physical constraints: re-apply the constraint set, confirm clock definitions survived, and verify keep-out and density rules are still active. An incremental pass that runs against a half-loaded constraint environment will happily produce a "legal" result that violates rules you forgot to re-assert.

Tuning Levers for a Specific Metric

Often there is no netlist change at all — you just need to fix one thing without re-churning the block. The art is applying a local lever. For a congestion hotspot, you do not re-place globally. You raise the placement density target only in the offending region (or add a soft density screen there), let local spreading push cells outward into adjacent slack, and re-legalize. The cells outside the hotspot barely move. For a timing-critical region, you can pull the endpoints of a failing path closer together with a pathbased attraction (a net weight bump or a region guide), then run a bounded incremental optimization that is allowed to move only the cells on that cone. Everything else stays frozen.

# Local congestion relief: tighten density only in a hotspot region,
# freeze the rest of the design, re-spread and legalize locally.
set_fixed_status -instances [all_placed_instances]
set_movable_status -region {1820 940 2060 1180} -instances *
set_placement_density -region {1820 940 2060 1180} -target 0.62
place_incremental -scope region -region {1820 940 2060 1180} -effort low
legalize -region {1820 940 2060 1180}

The principle is contain the blast radius. Freeze the design, open a small window, fix the metric inside that window, legalize the window, done. Global churn for a local problem is the most common selfinflicted wound in physical design.

Decision Table: Incremental vs. Full Re-Place

SituationActionWhy
< 5% netlist churn, same floorplanIncremental ECOExisting solution almost fully

valid

Buffer/clock-gate insertion only Incremental, bounded to affected Tiny localized delta

Single congestion hotspot, no Local density tuning Don't disturb a closing block

One critical region failing timing Bounded incremental opt Preserve the rest of the

15–25% churn, same die/macros Incremental with relaxed effort, then Borderline; measure drift

Floorplan or die size changed Full re-place Old coordinates no longer

Macro set added/removed/movedFull re-place (or re-floorplan)Global structure invalidated
QoR has drifted badly after manyFull re-place from clean netlist ECOsReset accumulated disturbance

ECO Step List (Generic)

  1. 1. Snapshot the current placement so you can roll back.
  2. 2. Re-assert macro fixes, region bounds, blockages, and constraints.
  3. 3. Ingest the revised netlist and generate the instance diff.
  4. 4. Map unchanged instances to their saved coordinates.
  5. 5. Place added/modified instances against the frozen background.
  6. 6. Legalize locally, bounding ripple to the changed neighborhoods.
  7. 7. Run a bounded incremental optimization on affected cones only.
  8. 8. Diff the placement against the snapshot; confirm disturbance is small.
  9. 9. Re-time the affected cones; verify no regression elsewhere.

Worked Example

Here is a representative end-to-end ECO using generic command names. The intent — not the exact syntax — is what transfers across tools.

# --- 1. Protect the converged result before touching anything ---
save_placement -name pre_eco_snapshot
set_fixed_status -instances [get_macros *]
set_fixed_status -instances [get_instances -filter {region == "datapath_tuned"}]
reassert_blockages
reassert_constraints -timing -physical
# --- 2. Ingest revised netlist and classify every instance ---
apply_eco_netlist -file rev_b.netlist -diff_report eco_diff.rpt
# eco_diff.rpt: unchanged=184210  modified=412  added=1380  deleted=905
# --- 3. Keep unchanged cells; place only the delta ---
restore_locations -instances [get_eco_instances -class unchanged]
place_incremental -instances [get_eco_instances -class {added modified}] \
-background_fixed true -effort medium

The placer here treats the 184k unchanged cells as a fixed backdrop and solves only for the ~1,800 cells that actually changed. Now legalize and check disturbance.

# --- 4. Legalize locally, then quantify how much the design moved ---
legalize -mode incremental -max_displacement 5
report_placement -diff pre_eco_snapshot -metric displacement
# moved_instances: 2114 of 185590  (1.1%)
# mean_displacement: 0.4 rows   max_displacement: 5 rows
# total_wirelength delta: +0.3%   congestion peak: unchanged

A 1.1% move count and sub-row mean displacement is the signature of a healthy ECO: the netlist changed, the placement barely did. Compare that to a full re-place, where the diff would show essentially 100% of cells moved and every timing path needing re-correlation. The report_placement -diff step is the single most valuable habit in incremental work — it turns "I think it's fine" into a measured disturbance budget.

Pitfalls

Over-disturbing the design. The most common failure is letting the incremental pass run at high effort with everything movable. It then "improves" wirelength by relocating thousands of innocent cells, and you have effectively done a full re-place while believing you did an ECO. Always freeze the background, bound the scope, and cap displacement. If the diff report shows double-digit move percentages after a small netlist change, stop and investigate — something was not fixed that should have been. QoR drift across many passes. Each incremental pass is locally optimal but globally a little worse than a from-scratch solution. One pass is invisible. Twenty stacked passes can accumulate into measurable wirelength bloat, congestion creep, and timing degradation, because legalization ripple and local re-spreading slowly erode the original clean structure. The defense is a drift budget: track wirelength, peak congestion, and worst slack across passes, and when cumulative degradation

crosses a threshold, do one clean full re-place from the current netlist to reset the baseline. Think of incremental passes as interest payments and the occasional full re-place as paying down the principal. Losing constraint state on netlist re-read. Ingesting a new netlist frequently clears placement-status flags, blockages, or region bounds. If you skip the re-assert step, the incremental engine runs against a permissive environment and quietly violates rules. Make re-assertion a non-negotiable first step. Trusting an unverified diff. If the netlist diff mis-classifies a rewired cell as unchanged, you preserve a stale location and stale timing. Always sanity-check the diff counts against what the ECO was supposed to do — if you expected 1,400 added cells and the report says 30, the ingest is wrong, not the design.

Interview Q&A

Q
When would you choose an incremental placement over a fresh run, and what is the single

most important signal in that decision? The decision is driven by how much of the existing solution is still valid. If the floorplan, die, and macro set are unchanged and the netlist delta is small (a few percent), incremental is correct because you preserve a converged result and its timing correlation. The single most important signal is the scope of change relative to the existing solution: small, local, connectivity-preserving changes favor incremental; floorplan or macro changes invalidate the old coordinates and force a fresh run.

Q
Walk me through how an ECO netlist change becomes a placement without re-running

global placement. You ingest the revised netlist and diff it against the placed design to classify every instance as unchanged, modified, added, or deleted. Unchanged instances keep their saved coordinates. Added and modified instances are placed against that frozen background as a small constrained sub-problem. You then legalize locally to resolve overlaps with bounded ripple, run a bounded incremental optimization on only the affected timing cones, and re-time those cones. The global structure never moves because the unchanged majority is held fixed.

Q
How do you prevent an incremental pass from disturbing the parts of the design that are

already good? Freeze them explicitly. Hard-fix macros and any hand-tuned regions, re-assert region bounds and blockages, and set the unchanged standard cells to low-priority or capped-displacement movable. Bound the placement and optimization scope to the changed neighborhood and cap maximum displacement during legalization. Then verify with a placement diff against a pre-ECO snapshot — if the move percentage is small, the good regions were genuinely protected.

Q
You have run two dozen ECOs on a block and timing is slowly getting worse even though

each ECO is tiny. What is happening and what do you do? That is QoR drift from accumulated incremental disturbance. Each pass is locally optimal but slightly degrades the global structure through legalization ripple and local re-spreading; stacked over many passes it compounds into wirelength bloat, congestion creep, and slack erosion. The fix is to maintain a drift budget — track wirelength, peak congestion, and worst slack across passes — and when cumulative degradation crosses a threshold, do one clean full re-place from the current netlist to reset the baseline, then resume incremental work.

Key Takeaways

  • A converged mixed placement is expensive and valuable; the default response to change is to preserve it, not rebuild it.
  • Incremental placement refines an existing result locally; a fresh run re-derives everything. Choose based on how much of the old solution is still valid.
  • The ECO flow is: diff the netlist, keep unchanged cells in place, place only added/modified cells, legalize locally, re-time affected cones.
  • Always re-assert macro fixes, region bounds, blockages, and constraints before an incremental pass — netlist re-read often drops them.
  • For a local problem (one hotspot, one critical region), freeze the design and open a small window; never use global churn for a local fix.
  • report_placement -diff against a pre-ECO snapshot turns disturbance into a measured budget — a small move percentage is the signature of a healthy ECO.
  • Watch for QoR drift across many passes; pay down accumulated disturbance with an occasional clean full re-place.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

Replying to