← Home Routing & Postroute Optimization
14 Routing & Postroute Optimization

Performing Postroute Optimization

Global routing, track assignment, detail routing, DRC convergence, SI and postroute optimization

Performing Postroute Optimization

By the time the router has finished laying down every signal net, your design has crossed an important threshold: it now carries real metal, real vias, and real geometry. Up to this point, every timing number you trusted was built on an estimate. Global routing gave you topology guesses, virtual-route gave you length-based capacitance, and even your best preroute optimization leaned on a Steiner-tree approximation of where the wires would eventually go. Postroute optimization is the stage where the tool stops guessing and starts working with the truth — the extracted resistance and capacitance of the actual interconnect that now exists in the layout. This chapter walks through why that distinction matters so much, what the postroute_opt and advanced_postroute_opt engines actually do with those parasitics, and how to read the results so you know when the design has genuinely converged versus when you are just burning runtime.

Why Postroute Optimization Exists

The single most important idea behind this stage is that parasitics change everything. Before detail routing, the placement-based parasitic estimation (often called virtual route or VR extraction) treats a net as a clean point-to-point connection scaled by distance. After detail routing, that same net might zig-zag across four metal layers, jog around a macro, climb a via stack three times, and pick up

coupling capacitance from a dozen aggressor wires running alongside it. The delay of that net can swing dramatically — sometimes a path that looked comfortably positive in preroute timing turns negative once the real RC lands.

Technical diagram

Three categories of problems surface only after routing:

  • Setup and hold degradation from accurate cell and net delays. Long detour routes add delay (hurting setup), while short well-buffered paths can become too fast relative to the clock (hurting hold).
  • Signal integrity (SI) effects — crosstalk delay and crosstalk noise — which simply cannot be computed without knowing which nets are physically adjacent. Coupling capacitance is a property of geometry, not topology.
  • Physical and electrical DRC violations introduced by the routing itself: max transition, max capacitance, max fanout, and the "soft" design rules the router could not fully resolve during the detail route pass. Postroute optimization exists to recover all of this in a single, RC-aware loop. The optimizer is allowed to resize cells, insert buffers, swap to different drive strengths or threshold-voltage flavors, restructure small pieces of logic, and — crucially — rip up and reroute the affected nets so that any cell change is immediately reflected in real metal. That last point is what separates postroute opt from a logic-only ECO: routing is in the loop. There is also a subtler reason this stage is indispensable: it is the first place where your timing picture is consistent with the database you will eventually hand to signoff. A static timing analysis tool reading your routed DEF with extracted SPEF will compute delays from the same physical reality postroute_opt optimized against. If you skip or shortchange postroute optimization, the gap between your in-tool timing and your signoff timing widens, and you end up discovering closure problems late — in signoff ECO — where every fix is far more expensive and far more constrained. Doing the work here, with the router still free to reroute aggressively, is dramatically cheaper than doing it after the design is frozen.

The postroute_opt Engine

postroute_opt is the workhorse command for postroute optimization in a the routing tool / the routerstyle flow. When you invoke it, it performs detail routing (if not already done) and then runs an integrated optimization loop that interleaves timing/DRC/SI fixing with incremental rerouting. Because it operates on extracted RC, every fix it makes is validated against the actual interconnect rather than an estimate. A clean first invocation usually looks like this:

# Make sure extraction and analysis modes are set up before opt
set_tool_option -name time.si_enable_analysis -value true
set_tool_option -name extract.starrc_decks -value $rc_corner_decks
# Run the integrated postroute optimization
postroute_opt
# Report where we landed
report_qor
report_timing -delay_type max -nworst 10
report_timing -delay_type min -nworst 10

What postroute_opt fixes, and the levers it pulls to fix it, can be summarized cleanly:

Problem classWhat postroute_opt does about it
Setup (maxUpsizes cells, inserts/relocates buffers, restructures critical logic, reroutes for shorter
delay)paths
Hold (min delay)Inserts hold buffers/delay cells, downsizes overly fast drivers, uses real RC to size

margin precisely

Max transitionUpsizes drivers, splits high-fanout nets, reroutes to reduce wire RC
Max capacitanceBuffers or resizes, moves nets to lower-cap layers where helpful
SI / crosstalkReroutes to reduce coupling, increases spacing (NDR), resizes aggressor/victim drivers

delay

SI / crosstalk Buffer insertion, layer reassignment, victim driver strengthening The key behavioral point for an interview: postroute_opt does not trust preroute timing. It re-extracts and re-times against routed parasitics, which is precisely why a design can look clean before postroute_opt and suddenly show new violations the moment you enter the stage. Those violations were always there — they were just invisible to the estimate. A practical sequencing note: order matters inside the stage. postroute_opt will generally attack setup, transition, and capacitance first, because those define the bulk of the slack picture, and only

then converge hold. The reason is that hold fixes (delay buffers, downsizing) depend on the final setup-driven topology; if you close hold before setup is stable, the setup work that follows can reopen the hold paths you just fixed and you waste two passes. Letting the engine resolve the larger setup/SI problems first and then clean hold against a settled path structure is both faster and more stable. When you drive the stage manually with incremental ECOs, mirror that order rather than fighting it. You can scope and tune postroute_opt for the situation you are in:

# Setup-focused recovery pass, skip the initial detail route
postroute_opt -from_initial_drc false
# A timing-only incremental pass after a manual ECO
postroute_opt -optimize_timing_only true
# Power-aware postroute opt: let it recover leakage/dynamic without hurting timing
set_tool_option -name opt.common.power_effort -value high
postroute_opt

advanced_postroute_opt for Advanced Nodes and Large Designs

On advanced process nodes (think FinFET geometries with dense multi-patterning rules) and on very large blocks, the classic interleaved postroute_opt flow can become a runtime bottleneck. Each time the optimizer touches a cell, it must reroute, re-extract, and re-time the affected region, and the cost of those incremental steps grows quickly with design size and rule complexity. advanced_postroute_opt is the engine built to address this — it performs concurrent optimization, attacking timing, DRC, and SI together across the whole design rather than walking through them in a more serialized fashion. The mental model is the difference between solving problems one neighborhood at a time versus solving the whole city's traffic at once. advanced_postroute_opt exploits multithreading and distributed compute more aggressively, makes globally coordinated decisions about where to spend optimization budget, and tends to give better quality-of-results at large scale with less wall-clock time.

# Concurrent postroute optimization for an advanced-node block
set_host_options -max_cores 16
set_tool_option -name postroute_opt.flow.enable_ccd -value true
advanced_postroute_opt
report_qor -summary

When should you reach for which engine? Use this as a practical guide:

SituationPreferred engineRationale
Small to mid block, maturepostroute_opt nodePredictable, well-understood, lower setup overhead
Large block, advancedadvanced_postroute_opt FinFET nodeConcurrent engine scales better, handles complex DRC
Heavy SI + dense routingadvanced_postroute_opt congestionGlobally coordinated SI/DRC tradeoffs
Quick incremental after apostroute_opt - tiny ECOMinimal disturbance, fast turnaround optimize_timing_only
Final signoff-qualityEither, with high effort convergenceEffort level matters more than engine choice here

A common gotcha: advanced_postroute_opt benefits enormously from correct host setup. If you run it on too few cores, you lose most of the advantage that justifies choosing it over postroute_opt in the first place. The concurrent engine is also more memory-hungry per pass, since it holds a larger working view of the design in flight; provisioning compute for it is a real planning decision, not an afterthought. On a properly sized farm, the payoff is that a block which would take many serial hours under postroute_opt can converge in a fraction of the wall-clock time with comparable or better QoR — which on a large advanced-node design is often the difference between making and missing a tapeout window.

Postroute Logic Optimization with Routing in the Loop

It is worth dwelling on what "logic optimization with routing in the loop" actually means, because it is the conceptual heart of the stage and a favorite interview probe. In a preroute logic optimization, when the tool resizes a gate or inserts a buffer, the effect on the net is modeled. The new wire delay is estimated from placement. Postroute, the tool cannot get away with that — the net already physically exists. So every transform follows a tight cycle:

Technical diagram
  1. 1. The optimizer proposes a change: upsize this driver, drop in a buffer here, restructure this cone.
  2. 2. The affected nets are ripped up and incrementally rerouted in real metal.
  3. 3. The new routing is extracted for accurate RC.
  4. 4. The path is re-timed against that RC.
  5. 5. The transform is kept only if it genuinely improves the cost function.

This is why postroute logic optimization is trustworthy in a way preroute optimization can never be: there is no estimation gap between the decision and the validation. The downside, of course, is cost — each transform is far more expensive than a preroute resize because it drags routing and extraction along with it. That is exactly the cost that advanced_postroute_opt is engineered to amortize through concurrency. A few practical controls govern how aggressively this loop reshapes the design:

# Allow logic restructuring during postroute opt (more aggressive)
set_tool_option -name opt.common.enable_postroute_logic_restruct -value true
# Bound how much area the optimizer may add chasing timing
set_tool_option -name opt.common.max_area_growth_ratio -value 0.05
# Preserve specific instances from being touched
set_dont_touch [get_cells u_critical_analog_iso/*] true
postroute_opt

The set_dont_touch guardrail matters more than people expect. Postroute optimization will happily resize or buffer anything it is allowed to, including hand-crafted structures you intended to leave alone. Protect them explicitly before you run.

Fixing Soft DRC Violations

Detail routing distinguishes between hard and soft design rules. Hard rules are non-negotiable manufacturability constraints — shorts, spacing minimums, via rules — and the router will not knowingly leave them open. Soft rules are preferences: optional spacing for yield, preferred-layer usage, recommended via configurations, color-balance hints on multi-patterned layers. During the primary detail route, the router may leave soft violations behind in order to close the harder, more important rules first. Cleaning them up is a deliberate postroute step. The dedicated control is the soft-violation fixing option, run as part of the post-detail-route flow:

# Enable cleanup of soft (optional/recommended) DRC violations
set_tool_option -name common.post_detail_route_fix_soft_violations -value setup
# Tune detail-route behavior that feeds soft-rule cleanup
set_tool_option -name detail.optimize_wire_via_effort_level -value high
set_tool_option -name detail.diode_insertion_mode -value fix_max_antenna
# Run a detail-route pass that includes the soft-fix step
detail_route
# Confirm both hard and soft DRC status
check_routes
report_design_violations

The post_detail_route_fix_soft_violations value of setup tells the flow to attempt soft-rule recovery as part of detail routing rather than skipping it. Be aware of the tradeoff: chasing soft violations too hard can perturb a clean route, sometimes reintroducing congestion or timing wiggle. On a design that is timing-critical and DRC-clean on hard rules, you may deliberately leave a handful of soft violations alone — they do not threaten manufacturability, and the disturbance of fixing them may not be worth it. Knowing which battles to skip is part of the craft.

Convergence Effort and Iteration Control

Postroute optimization is fundamentally iterative. The tool exposes effort levels and iteration controls so you can dial the cost/quality tradeoff to match where you are in the schedule. Early in the flow you want fast, coarse passes; near signoff you want exhaustive convergence.

# High-effort convergence pass for signoff-quality closure
set_tool_option -name postroute_opt.flow.effort -value high
set_tool_option -name detail.timing_driven -value true
set_tool_option -name detail.force_max_number_iterations -value 40
postroute_opt
# A lighter, faster pass for an early-stage sanity check
set_tool_option -name postroute_opt.flow.effort -value low
postroute_opt -optimize_timing_only true

The relationship between effort and outcome is not linear. The first pass clears the bulk of the violations; each subsequent iteration recovers progressively less. This is the classic diminishingreturns curve, and recognizing it is the single most valuable skill in this stage.

EffortRuntime
Typical useWhat to expect
levelcost
lowEarly sanity checks, quickLowestClears gross violations, leaves the long tail

ECO

mediumDefault working passesModerateSolid timing/DRC closure on most blocks
highFinal convergence beforeHigh signoffSqueezes the last picoseconds and stubborn DRCs
Technical diagram

For iteration control specifically, resist the temptation to crank force_max_number_iterations to a huge number "just to be safe." Beyond a point, additional iterations either oscillate (fixing one violation reopens another) or do nothing. If TNS and DRC counts are flat across two consecutive passes, more iterations will not save you — the design has converged to whatever the current constraints, floorplan, and library allow.

Postroute Shielding (Cross-Reference)

For especially sensitive nets — clocks, analog references, high-speed differential pairs — postroute optimization is often paired with postroute shielding, where ground or power wires are routed alongside the victim net to absorb coupling and stabilize delay against SI. Shielding is a sibling step to optimization: it changes the routing environment, which changes parasitics, which means you typically run an incremental postroute_opt afterward to re-time against the new RC. The mechanics of shield net creation, spacing rules, and shield assignment are covered in the dedicated shielding chapter; for the purposes of this chapter, simply remember the ordering: shield the sensitive nets, then re- optimize, never the reverse, because shielding alters the very parasitics the optimizer is trying to close against.

Reading Results and Knowing When to Stop

The hardest judgment call in postroute optimization is not how to run it — it is knowing when you are done. The tools will let you iterate forever; the discipline is yours to supply. Lean on report_qor as your primary dashboard. The numbers that matter are WNS (worst negative slack), TNS (total negative slack), the number of failing endpoints, and the DRC violation count broken out by category. Track them pass over pass:

# Snapshot QoR after each major opt pass
report_qor -summary > qor_pass1.rpt
postroute_opt
report_qor -summary > qor_pass2.rpt
# Detailed accounting of what remains
report_constraint -all_violators
report_design_violations -all
check_routes

When reading the trend, look for these signals that the design has converged:

  • WNS and TNS are flat or improving by negligible amounts between consecutive passes (e.g., TNS moves by less than a percent).
  • Failing endpoint count has stabilized — the same endpoints fail each time and the optimizer cannot close them without changing constraints or floorplan.
  • DRC count is at zero on hard rules and stable on whatever soft rules you have chosen to accept.
  • No oscillation — you are not in a loop where setup fixes break hold and hold fixes break setup. Conversely, these are signs to stop and rethink rather than iterate:
  • A small cluster of endpoints stays deeply negative no matter the effort level. That is almost always a structural problem — a badly placed macro, a missing pipeline stage, an over-constrained path — and no amount of postroute_opt will fix architecture. Kick it back to placement or RTL.
  • TNS improves but DRC explodes, or vice versa. The constraints are fighting each other; loosen something or adjust NDRs.
  • Runtime per pass keeps climbing while gains shrink to nothing. You have hit the diminishing-returns tail; ship it. The professional habit is to define your closure criteria before you start iterating — for example, "WNS within margin, TNS under a defined threshold, zero hard DRC, hold clean across all corners" — and then stop the moment you hit them. Chasing the last fractional picosecond on an already-passing design wastes machine time and risks perturbing a clean result into a dirty one. Convergence is a target to reach, not a horizon to chase indefinitely.

Interview Q&A

Q
Why can't preroute optimization catch the violations that postroute optimization fixes?

Preroute optimization works on estimated parasitics derived from placement and Steiner-tree topology. It has no knowledge of the actual metal layers, via stacks, detours, or physical neighbors the router will eventually create. Crosstalk delay and noise in particular depend on which nets are physically adjacent, which is purely a function of routed geometry. Postroute optimization re-extracts real RC from the finished routing and re-times against it, so it sees — and can fix — the delay, transition, capacitance, and SI effects that simply did not exist as data before detail routing.

Q
What does "routing in the loop" mean during postroute logic optimization, and why does it

matter? It means that whenever the optimizer resizes a cell, inserts a buffer, or restructures logic, the affected nets are immediately ripped up and incrementally rerouted in real metal, then re-extracted and re-timed before the transform is accepted. It matters because there is no estimation gap between the decision and its validation — the tool is always optimizing against ground truth. The price is runtime, since every transform drags routing and extraction along with it, which is precisely the cost that concurrent engines like advanced_postroute_opt are designed to amortize.

Q
When would you choose advanced_postroute_opt over postroute_opt? On large blocks and

advanced FinFET nodes where the serialized resize-reroute-retime loop becomes a runtime and quality bottleneck. advanced_postroute_opt optimizes timing, DRC, and SI concurrently across the whole design and exploits multicore and distributed compute more aggressively, giving better QoR at scale with less wall-clock time. For small blocks on mature nodes, plain postroute_opt is fine and has lower overhead. Critically, advanced_postroute_opt only pays off if you give it enough host cores — under-provision it and you lose the advantage.

Q
What is the difference between hard and soft DRC violations, and how do you handle soft

ones? Hard DRC rules are manufacturability constraints — shorts, minimum spacing, via rules — that the router will never knowingly leave open. Soft rules are preferences for yield and quality: optional spacing, preferred-layer usage, recommended via configs, color hints. The router may defer soft fixes during the primary detail route to close hard rules first. You clean them up afterward with common.post_detail_route_fix_soft_violations , but it's a judgment call: on a timing-critical, hardclean design, aggressively fixing soft violations can perturb the route and reintroduce congestion or timing wiggle, so sometimes you deliberately accept a few.

Q
How do you know when postroute optimization has converged and it's time to stop? Track

WNS, TNS, failing endpoint count, and DRC counts across consecutive passes via report_qor . Convergence shows up as flat or negligibly-improving WNS/TNS, a stable set of failing endpoints, zero hard DRC, and no setup-hold oscillation. If a small cluster of endpoints stays deeply negative regardless of effort, that's a structural problem — bad macro placement, missing pipelining, overconstraint — and no further iteration will fix it; escalate to placement or RTL. Define closure criteria up front and stop when you hit them, because chasing the last picosecond risks turning a clean result dirty.

Key Takeaways

  • Postroute optimization exists because real metal-and-via parasitics differ sharply from preroute estimates, exposing setup, hold, transition, capacitance, and SI problems that were always latent but invisible.
  • postroute_opt is the integrated RC-aware engine: it resizes, buffers, restructures, and reroutes, validating every change against extracted parasitics rather than estimates.
  • advanced_postroute_opt performs concurrent timing/DRC/SI optimization and is the right choice for large, advanced-node designs — provided you give it enough host cores.
  • "Routing in the loop" is the defining trait of the stage: every logic transform is immediately rerouted, re-extracted, and re-timed, eliminating the estimation gap at the cost of runtime.
  • Soft DRC violations are quality preferences, not manufacturability blockers; clean them with post_detail_route_fix_soft_violations but accept some when fixing them would disturb a clean, timing-critical route.
  • Effort levels and iteration limits exist to manage diminishing returns — the first pass clears most violations and each subsequent one recovers less.
  • Shield sensitive nets first, then re-optimize, because shielding changes the parasitics the optimizer closes against.
  • Define convergence criteria before you start, watch WNS/TNS/endpoints/DRC trend flat, and stop deliberately — structural problems belong to placement and RTL, not to more postroute_opt iterations.

Comments

Leave a Reply

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

Replying to