If you are still optimizing timing at a single PVT corner and hoping signoff will be clean, stop. That approach died somewhere around 16nm and is absolutely untenable at 7nm and below. Process variation, voltage droop, thermal gradients, and multiple operating modes mean your design lives in a multi-dimensional space. Multi-Corner Multi-Mode (MCMM) is not optional — it is the only way to close timing on modern SoCs.
This post captures what we have learned across multiple tapeouts at 7nm and 5nm nodes. These are not textbook strategies — they are hard-won lessons from blocks that refused to close and the techniques that finally brought them home.
Why Single-Corner Optimization Is Dead
At 180nm, you could optimize at worst-case slow and your design would work everywhere. The process window was wide, voltage variation was manageable, and temperature effects were predictable. At 7nm and below, that world no longer exists.
- Intra-die variation dominates — two gates 50um apart can have 15-20% performance difference due to local process variation
- Voltage droop is path-dependent — IR drop creates localized slow corners that differ from chip-level worst-case
- Multiple power domains — your design operates in functional, scan, MBIST, and low-power modes simultaneously across different voltage islands
- Temperature inversion — at sub-28nm, cell delay can actually increase at lower temperatures for certain Vt flavors, breaking the traditional hot=slow assumption
- Crosstalk coupling — dense routing at advanced nodes means coupling capacitance can be 2-3x grounded capacitance, making timing fundamentally neighbor-dependent
The result: you need to simultaneously satisfy timing across 20-40+ scenarios. Welcome to MCMM.
Setting Up MCMM Scenarios: Corners and Modes
Which Corners Matter
Your foundry will provide a dizzying array of PVT corners. Not all are created equal for timing closure. Here is what we typically run for a 7nm tapeout:
| Corner | Voltage | Temp | Primary Use |
|---|---|---|---|
| ss_0p72v_125c | 0.72V | 125C | Setup (worst slow) |
| ss_0p72v_m40c | 0.72V | -40C | Setup (temp inversion check) |
| ff_0p88v_m40c | 0.88V | -40C | Hold (worst fast) |
| ff_0p88v_125c | 0.88V | 125C | Hold (hot fast) |
| tt_0p80v_25c | 0.80V | 25C | Functional validation |
| ss_0p65v_125c | 0.65V | 125C | Low-power mode setup |
| ff_0p88v_0c | 0.88V | 0C | Hold (emerging critical) |
The key insight: at advanced nodes, your worst setup corner might not be the traditional ss/hot. Temperature inversion means ss_cold can be worse for high-Vt cells. Always validate both temperature extremes at slow process.
Which Modes to Analyze
- Functional mode — normal operation, all clocks active, nominal frequency target
- Scan/DFT mode — shift and capture, typically at reduced frequency but with different clock relationships
- Low-power mode — retention with voltage scaling, often the hardest to close because margins are razor-thin
- MBIST mode — memory test with specific clock configurations
- Boot/reset mode — power-on with uncertain clock states
For ICC2, you define these as scenarios. Each scenario is a corner + mode combination:
# ICC2: Define MCMM scenarios
create_scenario -name func_ss_125c \
-corner ss_0p72v_125c -mode functional
create_scenario -name func_ss_m40c \
-corner ss_0p72v_m40c -mode functional
create_scenario -name func_ff_m40c \
-corner ff_0p88v_m40c -mode functional
create_scenario -name scan_ss_125c \
-corner ss_0p72v_125c -mode scan_shift
create_scenario -name lp_ss_0p65v \
-corner ss_0p65v_125c -mode low_power
# Set scenario activity
set_scenario_status func_ss_125c \
-setup true -hold false -leakage false
set_scenario_status func_ff_m40c \
-setup false -hold true -leakage false
set_scenario_status lp_ss_0p65v \
-setup true -hold false -leakage true
The MCMM Flow: Stage by Stage
MCMM is not something you bolt on at the end. It must be integrated from synthesis through signoff. Here is the flow we run:
1. Synthesis Constraints
Start with multi-corner constraints in Design Compiler or Genus. Your SDC must reflect the worst-case scenario for each path:
# SDC: Multi-mode clock definitions
# Functional mode
create_clock -name clk_func -period 0.833 [get_ports clk]
# Scan mode (reduced frequency)
create_clock -name clk_scan -period 10.0 [get_ports clk]
# Mode-dependent constraints
if {[get_mode] == "functional"} {
set_multicycle_path -setup 2 -from [get_cells mem_ctrl/*] \
-to [get_cells wb_stage/*]
}
# Set operating conditions per corner
set_operating_conditions -max ss_0p72v_125c -min ff_0p88v_m40c
2. Placement Optimization
During placement, ICC2 considers all active scenarios simultaneously. The key is weighting them correctly:
# ICC2: Scenario weighting for placement
set_scenario_status func_ss_125c -active true -setup true \
-hold false -weight 1.0
set_scenario_status func_ss_m40c -active true -setup true \
-hold false -weight 0.8
set_scenario_status func_ff_m40c -active true -setup false \
-hold true -weight 0.6
# Run placement with MCMM awareness
place_opt -effort high
Do not give equal weight to all scenarios during placement. Your primary setup corner (typically ss_125c for functional mode) should dominate. Hold fixing is cheaper post-CTS.
3. Clock Tree Synthesis — The Cross-Corner Challenge
CTS at advanced nodes is where MCMM gets painful. You need the clock tree balanced across all corners simultaneously. A tree that is perfectly balanced at ss_125c might have 80ps of skew at ff_m40c because buffer delays scale differently across PVT.
# ICC2: Multi-corner CTS
set_app_options -name cts.compile.enable_global_route -value true
set_app_options -name cts.common.max_skew -value 0.060
# Enable cross-corner balancing
clock_opt -from build_clock -to route_clock
# Verify skew across all corners
foreach scenario [get_scenarios -filter "active==true"] {
current_scenario $scenario
report_clock_timing -type skew -clock [get_clocks clk_func]
}
Critical lesson: if your CTS target skew is 60ps at the primary corner, expect 80-100ps at off-corners. Budget for this in your timing margin. We have seen tapeouts fail because the team assumed cross-corner CTS skew would be the same as single-corner skew.
4. Post-Route Optimization
After routing, you have real parasitics. This is where most of the MCMM closure work happens:
# ICC2: Post-route MCMM optimization
route_opt -effort high -xtalk_reduction true
# Incremental optimization targeting worst scenarios
set_app_options -name route_opt.flow.enable_ccd -value true
route_opt -incremental true
5. STA Signoff
PrimeTime signoff is where truth meets the road. Run all scenarios with extracted parasitics from StarRC:
# PrimeTime: MCMM signoff analysis
set_multi_cpu_usage -local_cpu_count 16
read_parasitics -format spef -corner ss_0p72v_125c \
./parastics/ss_125c.spef.gz
read_parasitics -format spef -corner ff_0p88v_m40c \
./parasitics/ff_m40c.spef.gz
# Run timing with all corners
update_timing -full
# Report worst across all scenarios
report_timing -slack_lesser_than 0 -max_paths 500 \
-significant_digits 4 -input_pins \
-corner [all_corners]
Common Timing Closure Failures and Fixes
Setup Violations at ss_0p72v_125c
This is your bread-and-butter worst corner. Typical causes and solutions:
- Long combinational paths — restructure logic, add pipeline stages, or use size_cell to upsize critical gates
- High-Vt cells on critical paths — swap to SVT or LVT selectively (watch leakage budget)
- Clock reconvergence pessimism — enable CPPR (common path pessimism removal) in PrimeTime
- Routing detours — use ECO routing to straighten critical net paths
# PrimeTime: Identify and fix setup-critical paths
report_timing -delay max -corner ss_0p72v_125c \
-max_paths 50 -path_type full_clock_expanded
# ICC2: Targeted cell swapping
size_cell [get_cells path/critical_buf_*] LVT_BUF_X4
set_dont_touch [get_cells path/critical_buf_*] false
Real numbers from a recent 7nm block: initial WNS was -180ps at ss_125c after place_opt. After route_opt with CCD (concurrent clock and data optimization), WNS improved to -45ps. Final ECO closure brought it to +12ps positive slack.
Hold Violations at ff_0p88v_m40c
Hold violations are the silent killer. They appear late in the flow and require buffer insertion that can disturb setup timing. The trick is fixing hold without destroying setup margin:
# ICC2: Hold fixing with setup awareness
set_app_options -name opt.hold.effort -value high
set_app_options -name opt.hold.allow_setup_degrade -value false
# Fix hold across all fast corners simultaneously
optimize_design -hold -scenarios {func_ff_m40c func_ff_125c}
# Verify no setup degradation
report_timing -delay max -corner ss_0p72v_125c \
-slack_lesser_than 0.020
Typical TNS improvement: we often see 20,000-50,000ps of hold TNS after routing on a 5M-gate block. Dedicated hold fixing passes bring this to zero, but it requires 3-5 iterations with intermittent setup checks.
Cross-Corner CTS Balancing Issues
When your clock tree is balanced at one corner but skewed at another, the root cause is usually buffer delay tracking. At advanced nodes, different buffer architectures (standard cells vs. clock buffers) track PVT differently.
- Use dedicated CTS cells — these are designed for consistent delay tracking across PVT
- Limit buffer variety — restrict CTS to 2-3 buffer types max to improve cross-corner correlation
- Insert useful skew — intentionally skew the clock to help both setup and hold simultaneously (see next section)
- Check OCV impact on clock — clock path OCV derating can amplify skew differences across corners
Crosstalk-Induced Delta Delays
At 7nm with M1 pitch of 28nm, coupling capacitance dominates. A net switching opposite to its neighbor sees a significant delay increase (setup aggressor) or decrease (hold aggressor).
# PrimeTime: Enable SI analysis
set_si_mode -enable_delay_analysis true
set_si_mode -enable_glitch_analysis true
# Report paths with significant crosstalk delta
report_timing -crosstalk_delta -max_paths 100 \
-slack_lesser_than 0
# StarRC: Extract with coupling
star_cmd -coupling_cap_threshold 0.005 \
-coupling_report detailed
Fix strategies: NDR (non-default rules) for critical nets providing 2x spacing, shield insertion for clock nets, or layer promotion to wider-pitch metal layers.
OCV/AOCV/POCV Derating Strategies
On-Chip Variation derating is where advanced node timing gets nuanced. The progression from flat OCV to POCV represents increasingly accurate (and less pessimistic) modeling:
- OCV (flat derating) — apply a fixed percentage (e.g., +/-8%) to all cells. Simple but overly pessimistic. You leave performance on the table.
- AOCV (Advanced OCV) — derating varies by path depth and distance. Longer paths have better statistical averaging, so they get less derating. Typically recovers 30-50ps of margin versus flat OCV.
- POCV (Parametric OCV) — per-cell sigma-based variation using Liberty Variation Format (LVF). The most accurate. Each cell has its own statistical delay distribution. Recovers an additional 20-40ps versus AOCV on critical paths.
# PrimeTime: POCV setup
set_app_var timing_pocvm_enable_analysis true
read_lvf ./lib/ss_0p72v_125c.lvf
# AOCV table-based derating
read_aocvm ./lib/aocv_ss_0p72v_125c.aocvm
# Compare flat OCV vs POCV on critical path
set_timing_derate -early 0.92 -late 1.08 ;# flat OCV
report_timing -path_type full_clock_expanded
# Then switch to POCV
reset_timing_derate
set_app_var timing_pocvm_enable_analysis true
report_timing -path_type full_clock_expanded
# Typical recovery: 40-80ps on long paths
Our recommendation: use POCV for signoff whenever the foundry provides LVF libraries. The margin recovery is real and can be the difference between closing timing and adding a pipeline stage.
Useful Skew and Clock Scheduling
When conventional optimization hits a wall, useful skew is your next tool. The idea: intentionally shift the clock arrival at specific registers to borrow time from adjacent stages.
# ICC2: Enable useful skew / CCD
set_app_options -name clock_opt.flow.enable_ccd -value true
set_app_options -name cts.compile.enable_local_skew -value true
# Constrain maximum allowable useful skew
set_app_options -name ccd.max_skew -value 0.100
# PrimeTime: Analyze schedule potential
report_clock_timing -type skew -verbose \
-clock [get_clocks clk_func]
# Check paths that benefit from useful skew
report_timing -path_type full_clock_expanded \
-through [get_pins reg_A/CK]
Rules of thumb for useful skew:
- Never borrow more than 30% of the clock period — diminishing returns and hold risk
- Verify hold after applying skew — what helps setup at ss will hurt hold at ff
- Limit useful skew to localized clusters — global skew is a nightmare to maintain across ECOs
- Document which paths use useful skew — future ECOs must respect these constraints
ECO Strategies: Minimal Disruption Timing Fixes
Post-route ECOs are inevitable. The goal is to fix timing without disturbing converged paths. Here is the flow we use:
# PrimeTime: Generate ECO guidance
fix_eco_timing -type setup -methods size_cell \
-corner ss_0p72v_125c -max_paths 100
write_changes -format icc2 -output eco_setup_fix.tcl
# ICC2: Apply ECO with minimal disturbance
source eco_setup_fix.tcl
set_app_options -name route_opt.eco_route.search_repair_loop -value 5
# Legalize and re-route only affected cells
place_eco_cells -eco_changed_cells -legalize_only
route_eco
# Re-extract and verify
# (Run StarRC extraction on modified region only)
update_timing -full
report_timing -slack_lesser_than 0
ECO best practices from our tapeouts:
- Size before insert — try cell sizing first. It preserves placement and routing topology.
- Batch ECOs by region — group fixes in the same physical area to minimize routing disturbance
- Freeze clean paths — use dont_touch on paths that are already closed
- ECO iteration limit — set a hard cap (we use 5 major ECO iterations). If you are not converging, something architectural is wrong.
- Track WNS/TNS per iteration — if TNS is not improving by at least 30% per ECO pass, change strategy
Tool Tips: ICC2, PrimeTime, and StarRC
ICC2 Practical Tips
- Enable
route_opt.flow.enable_ccdearly — CCD is most effective when it has routing freedom - Use
check_design -checks timingbefore optimization to catch constraint issues - Set
place_opt.flow.optimize_icgsfor ICG-heavy designs — clock gating cell placement affects both timing and power - Multi-threading: use
set_host_options -max_cores 16— MCMM scales well with core count
PrimeTime Practical Tips
- Always run
check_timing -verbosefirst — unconstrained paths will silently ruin your signoff - Use
report_bottleneckto find the real timing limiters, not just the worst path - Enable
timing_report_unconstrained_paths— missing constraints are the number one signoff surprise - For crosstalk, set
si_filter_per_aggressor_noise_peakto reduce runtime without losing accuracy
StarRC Practical Tips
- Use coupled extraction (not decoupled) for signoff — coupling is too significant to ignore at advanced nodes
- Set
COUPLE_TO_GROUNDthreshold carefully — too high loses accuracy, too low explodes SPEF size - Run
REDUCTIONfor in-design optimization, full extraction for signoff - Validate extraction correlation to silicon — if your first tapeout does not match, calibrate immediately
Real Numbers: WNS/TNS Improvement by Stage
Here is a representative trajectory from a recent 5nm, 8M-gate subsystem tapeout at 1.2GHz:
| Stage | WNS (ps) | TNS (ns) | Hold TNS (ns) |
|---|---|---|---|
| Post-synthesis | -320 | -48.2 | N/A |
| Post-place_opt | -145 | -12.8 | -85.4 |
| Post-CTS | -95 | -6.2 | -42.1 |
| Post-route_opt | -38 | -1.4 | -8.6 |
| Post-route_opt (CCD) | -12 | -0.3 | -2.1 |
| Post-ECO (iteration 1) | +5 | 0 | -0.4 |
| Post-ECO (iteration 2) | +18 | 0 | 0 |
| PrimeTime signoff (POCV) | +22 | 0 | 0 |
Key observations from this trajectory:
- Placement alone recovers ~55% of post-synthesis WNS — invest in placement quality
- CCD (concurrent clock-data) is worth 25-40ps of WNS recovery — do not skip it
- ECO iterations have diminishing returns — if ECO 1 does not get you close, re-evaluate the approach
- POCV signoff recovered 10ps versus AOCV on the same design — free margin from better modeling
Closing Thoughts
MCMM timing closure at advanced nodes is a discipline, not a step. It requires consistent methodology from synthesis constraints through signoff, deliberate scenario management, and a willingness to invest in better variation modeling (POCV over flat OCV). The tools are mature — ICC2 and PrimeTime handle MCMM well — but they need correct input: clean constraints, appropriate corner selection, and realistic derating.
The teams that close timing on schedule are the ones who set up MCMM correctly from day one, track WNS/TNS convergence at every stage, and know when to stop optimizing and start the ECO flow. If your TNS is not converging by route_opt, no amount of ECO iterations will save you — go back and fix the root cause at the architecture or floorplan level.
Physical design at advanced nodes is unforgiving, but the methodology is well-established. Apply it rigorously and your design will close.