The Complete CTS Options Reference
Topic 9: Complete CTS Options Reference Clock Tree Synthesis is rarely a one-shot, push-button step. In real production flows, the difference between a clock tree that closes timing on the first ECO pass and one that drags a block through weeks of churn usually comes down to how the engineer dialed in the CTS engine. The tool exposes dozens of knobs — some control how aggressively it chases skew, others trade runtime for quality, and a few quietly reshape power, congestion, or the physical structure of the tree itself. Knowing what each switch actually does, and more importantly when it earns its keep, is exactly the kind of depth interviewers probe for. This topic is the full reference. We walk through six families of options, explain every individual switch in plain engineering terms, and give you a usable command snippet for each. Treat the defaults as your baseline contract with the tool, and treat every override as a deliberate trade you are making with eyes open.

9.1 Timing Optimization Options
This family is the heart of CTS. These switches govern the engine's primary objective: delivering balanced, low-skew, controlled-transition clocks to every sequential element. Most timing problems you will ever debug in CTS trace back to one of these five settings being either too loose or too aggressive for the block in hand.
enable_high_effort_timing_mode
Purpose. Tells the engine to spend significantly more compute exploring buffer placement, sizing, and balancing decisions in pursuit of tighter skew and cleaner transitions. It is the "try harder" master switch for timing quality. Type. Boolean. Default. false . Key impact. The headline cost is runtime — expect roughly an 7x to 9x increase versus the default effort level. In exchange you typically recover skew and slew margin that the standard effort leaves on the table, which can translate into fewer hold buffers downstream and a smoother timing-closure ramp. When to use. Reach for it on timing-critical blocks late in the flow, when you have already converged on a floorplan and you need the last few picoseconds of skew. It is also the right tool for highfrequency designs where the clock period is unforgiving. Do not enable it during early exploratory iterations — you will burn hours waiting for results you are about to throw away.
Trade-offs. Runtime is the obvious one, but there is a subtler cost: high effort can insert more buffers chasing marginal skew gains, which nudges clock power and area upward. On a block that is already meeting skew comfortably, the extra effort buys you little and costs you a lot.
set_clock_tree_options -enable_high_effort_timing_mode true
target_skew
Purpose. Sets the skew budget the engine tries to hit across the clock tree — the maximum accept‐ able difference in clock arrival time between balanced sinks. This is the single most consequential timing number you give to CTS. Type. Float, in nanoseconds. Default. Auto — the tool derives a target from the clock period and design constraints if you do not specify one. Range and typical values. Practical range runs from about 0.012 ns to 0.95 ns. Common production targets are 0.045 ns for aggressive, high-frequency blocks, 0.09 ns as a balanced everyday choice, and 0.18 ns for relaxed or low-power designs where loose skew is acceptable. Key impact. A tighter target forces the engine to balance more carefully, which means more buffers, more area, more clock power, and longer runtime. A looser target relaxes all of those but leaves less margin for setup and hold closure. When to use. Set it explicitly whenever you know your timing requirements — never lean on auto for a block whose period you understand. Tighten it for blocks where useful skew has little room to maneuver; loosen it for power-sensitive blocks that can tolerate skew slack. Trade-offs. Over-tightening is a classic rookie mistake: you spend buffers and power chasing a skew number far below what the design actually needs, inflating clock power for no real timing benefit. Always size the target to the timing requirement, not to vanity.

target_max_slew
Purpose. Caps the maximum transition (slew) time allowed on clock nets. Slow clock edges are a reliability and timing hazard — they widen the uncertainty window and make the clock more susceptible to noise — so CTS sizes and places buffers to keep every edge crisp. Type. Float, in nanoseconds. Default. 0.5 ns. Key impact. A tighter slew target makes the engine drive nets harder — bigger buffers, shorter net segments, more repeaters — improving edge quality but raising power and area. It works hand in hand with the set_max_transition design constraint; CTS honors whichever is the binding limit. When to use. Tighten it on advanced nodes and high-frequency clocks where edge rate directly affects jitter and the duty-cycle budget. Keep it relaxed on low-speed or power-sensitive clocks where a softer edge is harmless. Trade-offs. Aggressive slew control is one of the quieter contributors to clock power, because fast edges mean larger drivers switching more current. Set it to what the design needs for reliability and timing, not tighter.
set_clock_tree_options -target_max_slew 0.36
set_max_transition 0.36 [get_clocks CLK]
skew_only
Purpose. Directs the engine to optimize purely for skew, de-emphasizing insertion delay. The result is typically a shallower tree built to equalize arrival times rather than to minimize total latency. Type. Boolean. Default. false . Key impact. You usually get tighter skew and a simpler tree structure, but at the cost of higher insertion delay — the absolute latency from clock root to sinks grows. Higher insertion delay means more exposure to on-chip variation (OCV), which can hurt you on long timing paths. When to use. It fits designs where relative balance between sinks matters far more than absolute latency, or where you are deliberately accepting latency to simplify the tree. It can also be a useful experimental mode to understand how much insertion delay your skew target is costing. Trade-offs. The insertion-delay penalty is the catch. On variation-sensitive nodes, a deeper-but-lowerlatency tree sometimes closes timing more reliably than a shallow, high-latency, perfectly-skewed one. Use this knob knowing you are trading latency for balance.
set_clock_tree_options -skew_only true
enable_local_skew_optimization
Purpose. Enables skew optimization at the level of local subtrees rather than treating the whole clock as one global balancing problem. The engine targets skew between sinks that share register-toregister timing paths, which is what actually matters for timing closure. Type. Boolean. Default. false . Key impact. Because it focuses effort where skew genuinely affects path timing — between launch and capture flops that talk to each other — it can deliver better timing results without paying for global balancing everywhere. It tends to be more efficient than brute-force global skew minimization. When to use. Turn it on for designs with many independent timing groups or clustered logic, where global skew is a poor proxy for what the paths need. It pairs naturally with useful-skew flows. Trade-offs. Local optimization can leave global skew numbers looking worse on a report even when path timing is better, which can confuse a reviewer reading raw skew metrics. Make sure your downstream timing analysis is set up to credit the local balancing.
set_clock_tree_options -enable_local_skew_optimization true
Timing Optimization summary
De‐
Option Type Primary effect Main cost
| en‐ | bool | false | Better skew/slew via | +7–9x runtime, more |
|---|---|---|---|---|
| able_high_effort_timing_mode | more search | buffers | ||
| target_skew | float | auto | Sets skew budget (ns) | Tighter = more power/area |
| target_max_slew | float | 0.45 | Caps clock transition (ns) | Tighter = more clock power |
| skew_only | bool | false | Shallower, skew-first tree | Higher insertion delay |
| en‐ | bool | false | Subtree-level skew able_local_skew_optimization | Worse-looking glob‐ al skew |
9.2 Power Optimization Options
Clock networks are one of the largest dynamic-power consumers on a chip — the clock toggles every single cycle by definition, feeding thousands of buffers and flop clock pins. This family lets you steer CTS toward power-conscious decisions, almost always at some cost to skew, runtime, or both.
enable_power_reduction
Purpose. A general power-saving mode that biases buffer selection, placement, and tree structure toward lower clock-network power. Type. Boolean. Default. false . Key impact. Typically yields a 9–14% reduction in clock power. The trade is roughly 5–8 ps of addi‐ tional skew, because the engine is no longer free to spend buffers purely on balancing. When to use. Excellent default for power-sensitive products — mobile, IoT, battery-driven, or any block where clock power dominates the budget — provided you have a few picoseconds of skew slack to give back. Trade-offs. The skew penalty is small but real. On a block with zero skew margin, those extra pico‐ seconds can be the difference between closing and not closing, so confirm you have the headroom first.
set_clock_tree_options -enable_power_reduction true
enable_dynamic_power_optimization
Purpose. Specifically attacks switching (dynamic) power in the clock network — the active power burned every cycle as buffers and nets charge and discharge. Type. Boolean. Default. false . Key impact. A more aggressive lever than the general mode, delivering roughly 13–18% dynamicpower savings. The cost is a substantial 28–46% runtime increase, since the engine evaluates powerversus-timing trade-offs much more exhaustively. When to use. Choose it for designs where dynamic power is the binding constraint and you can absorb the runtime hit — typically late in the flow on a power-critical block, not during fast iteration. Trade-offs. Runtime is the headline cost. Like all power modes, it also competes with skew for the engine's attention, so verify timing stays within budget after enabling it.
set_clock_tree_options -enable_dynamic_power_optimization true
enable_leakage_power_optimization
Purpose. Targets static leakage power, primarily by favoring higher-threshold-voltage (HVT) cells and avoiding leaky structures in the clock tree. Type. Boolean. Default. false . Key impact. Delivers roughly 4–9% leakage reduction. It is most meaningful on older, larger nodes — 28 nm and similar — where leakage is a comparatively larger slice of total power. On the most advanced nodes, dynamic power usually dominates and this knob matters less. When to use. Best suited to mature-node designs, always-on or standby-heavy blocks, and any con‐ text where static power is a real budget line item. Less impactful on bleeding-edge nodes. Trade-offs. HVT cells are slower, so leaning on them in the clock path can cost you speed and force timing recovery elsewhere. The leakage win is modest, so weigh it against any timing give-back.
set_clock_tree_options -enable_leakage_power_optimization true
enable_wire_length_aware_power_driven_relocation
Purpose. Lets CTS relocate clock buffers and adjust the tree to shorten clock wires, directly cutting the wire capacitance that the clock has to switch every cycle. Type. Boolean. Default. false . Key impact. Since dynamic power scales with switched capacitance, trimming wire length is one of the cleanest ways to cut clock power — and unlike cell-based tricks, it does not slow down the path. Savings depend heavily on how routing-inefficient the baseline tree was. When to use. Valuable on spread-out floorplans, designs with long clock routes, or any block where wire capacitance is a large fraction of clock load. It complements the other power modes rather than replacing them. Trade-offs. Relocation can interact with placement legality and congestion — moving buffers to shorten wires may push them into already-crowded regions. Watch congestion and DRC after enabling it.
set_clock_tree_options -enable_wire_length_aware_power_driven_relocation true
Power Optimization summary
| De‐ | Power bene‐ | ||
|---|---|---|---|
| Option | Main cost / note | ||
| fault | fit | ||
| enable_power_reduction | false | 9–14% clock | +5–8 ps skew |
power
enable_dynamic_power_optimization false 13–18% dy‐ +28–46% runtime
| enable_leakage_power_optimization | false | 4–9% leak‐ | Best on 28 nm+ |
|---|---|---|---|
| age | older nodes; slower |
HVT cells

9.3 Area & Placement Options
This smaller family controls how CTS physically places and consolidates clock cells. The defaults are auto-tuned and usually fine, but on congested or unusually structured blocks these knobs give you direct control over the spatial behavior of the engine.
enable_advanced_legalization_algorithms
Purpose. Switches the buffer legalizer — the step that snaps inserted clock cells onto legal placement sites — to a more sophisticated algorithm that resolves overlaps and density problems more intelli‐ gently. Type. Boolean. Default. false .
Key impact. Produces cleaner, denser, more DRC-friendly clock-cell placement, which pays off on congested blocks where naive legalization scatters buffers or creates density hotspots. The cost is a 18–28% runtime increase for the legalization phase. When to use. Enable it on high-utilization or congestion-prone designs where standard legalization leaves a messy clock-cell placement that complicates routing. Trade-offs. Pure runtime for placement quality. On a low-utilization, roomy floorplan the advanced legalizer has little to fix, so you pay the runtime without seeing the benefit.
set_clock_tree_options -enable_advanced_legalization_algorithms true
placement_window_size
Purpose. Sets the size of the local region the engine searches when deciding where to drop a clock buffer. A larger window gives the placer more freedom to find a good spot; a smaller one constrains it to stay near the ideal location. Type. Float, in microns. Default. Auto — derived from design size and density. Key impact. Bigger windows can find better-balanced placements and avoid local congestion, but enlarge the search and slow the engine. Smaller windows keep buffers tightly placed and run faster but may force the placer into congested spots it cannot escape. When to use. Tune it manually only when the auto value clearly misbehaves — for example, enlarge it when buffers are getting stuck in congested pockets, or shrink it when you want tighter, more predictable placement on a clean floorplan. Trade-offs. It is a search-effort-versus-runtime dial. Most flows leave it on auto; treat manual tuning as a targeted fix, not a default action.
set_clock_tree_options -placement_window_size 28.0
buffer_merge_distance
Purpose. Defines how close two clock buffers must be before the engine considers merging them into a single, often larger, cell. Merging cuts buffer count and can reduce both area and power. Type. Float, in microns. Default. Auto. Key impact. A larger merge distance is more aggressive — it consolidates more buffers, shrinking cell count and area, but a merged buffer drives a larger fanout, which can degrade slew and skew. A smaller distance is conservative, preserving balance at the cost of more cells.
When to use. Increase it when you want to thin out an over-buffered tree for area or power; decrease it when merging is hurting your transition or skew numbers. Trade-offs. Over-merging is the risk — consolidate too eagerly and you trade away the edge quality and balance that the buffers were providing. Tune in small steps and re-check slew and skew.
set_clock_tree_options -buffer_merge_distance 4.0
Area & Placement summary
De‐
Option Type Effect Main cost
| en‐ | bool | false | Cleaner, denser cell | +18–28% runtime |
|---|---|---|---|---|
| able_ad‐ | placement |
vanced_legalization_algorithms
| placement_window_size | float | auto | Buffer search region | Larger = slower |
|---|---|---|---|---|
| (µm) | size | |||
| buffer_merge_distance | float | auto (µm) | Buffer consolidation threshold | Over-merge hurts slew/skew |
9.4 Advanced Algorithm Options
This family unlocks the engine's smarter, more physically-aware optimization modes. The common theme is that these switches make CTS reason about realities it would otherwise approximate — actual routing layers, route-based delay, per-buffer drive strength, and congestion. They generally improve correlation with the post-route world at the price of runtime.
enable_grbl_preroute_optimization
Purpose. Makes the pre-route clock optimization aware of the global routing layers — the metal layers and their differing resistance and capacitance characteristics — rather than assuming an idealized routing environment. Type. Boolean. Default. false . Key impact. Because the engine factors in which layers the clock will actually run on, its pre-route delay and slew estimates correlate far better with the final routed result. That means fewer surprises and less post-route ECO churn.
When to use. Valuable on advanced nodes where layer-dependent RC effects are pronounced and the gap between idealized and real routing is large. It is part of building a clock tree that survives the route step intact. Trade-offs. More physical awareness means more computation and longer runtime. The accuracy gain is most worthwhile when layer effects genuinely dominate; on simple nodes the benefit shrinks.
set_clock_tree_options -enable_grbl_preroute_optimization true
enable_rde_preroute_optimization
Purpose. Enables route-driven estimation (RDE) — the engine estimates clock-net delay using a realistic routing model instead of crude Manhattan (point-to-point rectilinear) distance. Type. Boolean. Default. false . Key impact. Manhattan estimates ignore detours around blockages and congestion, so they system‐ atically under-predict real wire length and delay. RDE produces estimates that track the actual router much more closely, improving the fidelity of every timing-driven decision CTS makes. When to use. Use it on congested designs or blocks with significant routing blockages, where Man‐ hattan distance and routed length diverge sharply. It pairs well with the GRBL option for a fully routeaware pre-route flow. Trade-offs. The richer estimation model costs runtime. On an open, lightly-congested floorplan, Manhattan distance is already a decent approximation and RDE buys less.
set_clock_tree_options -enable_rde_preroute_optimization true
enable_dynamic_power_shaping
Purpose. Lets the engine tune drive strength on a per-buffer basis, shaping each buffer's powerversus-performance point to its local load instead of applying a uniform sizing policy. Type. Boolean. Default. false . Key impact. Fine-grained sizing means each buffer is no larger than it needs to be for its actual fanout and slew target, trimming clock power while still meeting transition requirements. It is a more surgical alternative to blanket power modes. When to use. Effective on power-sensitive designs where you want savings without globally relaxing slew or skew targets. It works well alongside the wire-length-aware relocation option for a comprehensive power strategy.
Trade-offs. Per-buffer analysis adds runtime, and aggressive downsizing can erode slew margin if the engine cuts too close. Validate transition after enabling.
set_clock_tree_options -enable_dynamic_power_shaping true
enable_global_routing_based_optimization
Purpose. Drives CTS using global routing information so the engine proactively avoids congested regions when placing and routing clock cells, rather than discovering congestion problems only after the fact. Type. Boolean. Default. false . Key impact. Proactive congestion avoidance produces clock trees that route cleanly the first time, reducing detours, DRC violations, and the timing degradation that comes from clock nets being forced around hotspots. It improves both routability and timing correlation. When to use. A strong choice for congestion-limited designs and high-utilization blocks where clock routing competes hard with signal routing for tracks. Trade-offs. Running global routing analysis inside CTS adds runtime, and the engine may place clock cells slightly sub-optimally for skew in order to dodge congestion — a deliberate trade of a little balance for a lot of routability.
set_clock_tree_options -enable_global_routing_based_optimization true
Advanced Algorithm summary
De‐
Option What it adds Best for
| enable_grbl_preroute_optimization | false | Routing-layer-aware | Advanced nodes, layer- |
|---|---|---|---|
| estimates | RC effects | ||
| enable_rde_preroute_optimization | false | Route-driven vs Man‐ hattan delay | Congested / blockage- heavy blocks |
| enable_dynamic_power_shaping | false | Per-buffer drive- strength tuning | Power-sensitive, slew- constrained |
| en‐ | false able_glob‐ | Proactive congestion avoidance | Congestion-limited, high-utilization |
al_routing_based_optimization

9.5 Clock Domain Isolation Options
Modern SoCs carry many clocks — functional, test, divided, gated — and they must not be allowed to interfere with one another during CTS. This family controls which clocks the engine builds, and whether it is permitted to share buffers and tree structure across clock domains. Sharing saves area and power; isolation guarantees independence. These knobs let you choose deliberately.
prevent_specific_clocks
Purpose. Excludes a named list of clocks from CTS so the engine leaves them untouched — no buffering, no balancing, no restructuring. Type. Clock list. Default. Empty (all clocks are processed). Key impact. Listed clocks are skipped entirely, preserving whatever structure they already have. This is essential for clocks that must keep a hand-crafted or pre-built tree, or that are managed by a different methodology. When to use. Use it for test/scan clocks built separately, hard-macro clocks you do not own, clocks already synthesized in an earlier step, or any clock whose tree must remain exactly as-is. Trade-offs. An excluded clock gets none of CTS's balancing or transition fixing, so you are fully responsible for its quality. Exclude only clocks you are sure should be left alone.
set_clock_tree_options -prevent_specific_clocks {scan_clk test_clk}
prevent_tree_sharing_with_clocks
Purpose. Forbids a specified set of clocks from sharing tree structure — buffers and nets — with other clocks, forcing each listed clock to be built on its own dedicated resources. Type. Clock list. Default. Empty (sharing allowed where beneficial). Key impact. Guarantees electrical and structural independence for the listed clocks, preventing one domain's behavior from coupling into another. The cost is lost sharing efficiency: dedicated trees mean more buffers, more area, and more power than a shared structure would use. When to use. Apply it to asynchronous clocks that must stay independent, clocks with very different frequencies, or any domain where cross-coupling through shared buffers would create timing or integrity risk. Trade-offs. You pay area and power for the isolation. Reserve it for the clocks that genuinely require independence rather than blanketing the whole design.
set_clock_tree_options -prevent_tree_sharing_with_clocks {clk_a clk_b}
disable_tree_sharing
Purpose. A global switch that turns off all clock-tree sharing across the design — every clock gets its own dedicated tree. Type. Boolean. Default. false (sharing enabled). Key impact. Maximum isolation: no two clocks share a buffer or net anywhere. This makes per-clock behavior fully predictable and independent, at the highest possible cost in area and power because no consolidation is allowed. When to use. Choose it when isolation is a hard requirement across the whole block — for example, certain safety-critical or high-integrity designs — or when shared trees have caused debugging headaches you want to eliminate outright. Trade-offs. This is the most resource-expensive isolation option. For most designs, targeting specific clocks with prevent_tree_sharing_with_clocks is the smarter move; reserve the global disable for cases where nothing may share.
set_clock_tree_options -disable_tree_sharing true
Clock Domain Isolation summary
De‐
Option Type Scope Cost of using
| prevent_specific_clocks | clock | empty | Skip named clocks | No CTS quality on |
|---|---|---|---|---|
| list | entirely | those clocks | ||
| pre‐ | clock vent_tree_sharing_with_clocks | empty list | Dedicated trees for named clocks | More area/power for those clocks |
| disable_tree_sharing | bool | false | Dedicated trees for all clocks | Maximum area/ power |

9.6 Mode & Scenario Options
Real designs operate under multiple corners and operating modes — functional, test, low-power — each captured as a scenario in a multi-mode multi-corner (MMMC) setup. This family controls how CTS treats those modes and which timing direction it optimizes for. Getting these right is what keeps your clock tree consistent and closeable across every scenario, not just the one you happened to look at.
setup_only / hold_only
Purpose. Restricts CTS optimization to a single timing direction — setup_only focuses the engine on setup (max-delay) timing, while hold_only focuses it on hold (min-delay) timing. By default the engine balances both.
Type. Boolean (each is its own switch). Default. false for both — meaning setup and hold are optimized together. Key impact. Narrowing the objective lets the engine pour all its effort into one timing type, which can produce a better result for that direction. The danger is the other direction: optimizing setup-only can leave hold violations, and hold-only can erode setup margin. When to use. These are targeted tools, not everyday settings. Use hold_only in a dedicated holdfixing pass after setup has converged, or setup_only when you are deliberately deferring hold to a later stage. They are useful for staged closure flows where you tackle one timing type at a time. Trade-offs. You must own the consequences for the un-optimized direction. The standard, balanced default is correct for most CTS runs; reach for these only when you have a clear staged plan.
# Setup-focused pass
set_clock_tree_options -setup_only true
# Dedicated hold-fixing pass
set_clock_tree_options -hold_only true
copy_exceptions_across_modes
Purpose. Propagates timing exceptions — false paths, multicycle paths, and similar constraints — from one mode to the others, so the engine applies a consistent set of exceptions everywhere instead of treating each mode in isolation. Type. Boolean. Default. false . Key impact. Ensures exceptions defined in one mode are honored across all modes, which prevents the engine from over-optimizing a path that is actually a false or multicycle path in another scenario. It improves consistency and avoids wasted effort on paths that do not need it. When to use. Enable it in multi-mode designs where the same structural exceptions logically apply across modes and you want uniform constraint handling. It saves you from redundantly redefining exceptions per mode. Trade-offs. Copying exceptions is only correct when they genuinely apply everywhere — blindly propagating a mode-specific exception can mask a real path in a mode where it should be timed. Confirm the exceptions are truly mode-independent before turning this on.
set_clock_tree_options -copy_exceptions_across_modes true
mode_selection
Purpose. Tells CTS which mode (or modes) to optimize for, selecting the relevant scenario from a multi-mode setup. It scopes the engine's optimization to the operating condition that matters most for the run. Type. Mode name. Default. Tool-dependent — typically all defined modes are considered together. Key impact. Directing the engine at a specific mode concentrates effort where it counts and can speed up the run by not balancing modes that are not the current priority. The risk is neglecting the modes you did not select. When to use. Use it when one mode dominates the design's importance — say, functional mode for a consumer SoC — or in a staged flow where you optimize modes in a deliberate order. It is also handy for debugging a single mode's clock behavior in isolation. Trade-offs. Focusing on one mode can leave others under-optimized, so a final all-mode pass is usually wise before sign-off. Treat single-mode runs as a targeting tool, not a substitute for full MMMC coverage.
set_clock_tree_options -mode_selection func_mode
Mode & Scenario summary
| Option | Type | Default | Effect | Watch out for |
|---|---|---|---|---|
| setup_only | bool | false | Optimize setup timing only | Possible hold viola‐ tions |
| hold_only | bool | false | Optimize hold timing only | Possible setup de‐ gradation |
| copy_excep‐ | bool | false tions_across_modes | Share exceptions across modes | Masking real paths if misused |
| mode_selection | mode | all name | Target a specific mode modes | Other modes under- optimized |

Putting the Options Together
No production CTS run flips every switch on. The art is composing a small, deliberate set of overrides that matches the block in front of you. A power-sensitive mobile block might combine en‐ able_power_reduction , enable_wire_length_aware_power_driven_relocation , and en‐ able_dynamic_power_shaping while keeping target_skew deliberately loose at 0.18 ns. A high-fre‐ quency, congestion-limited block might instead pair enable_high_effort_timing_mode , a tight tar‐
get_skew of 0.045 ns, enable_rde_preroute_optimization , and en‐
able_global_routing_based_optimization — accepting the runtime hit because the timing and routability payoff is worth it. The recurring trade across all six families is the same: quality, runtime, power, and area pull against each other, and every switch moves you along one of those axes at the expense of another. Strong CTS engineers do not memorize a single "best" recipe; they read the block's binding constraint — is it timing, power, congestion, or schedule? — and reach for the two or three options that address it dir‐ ectly.

Interview Q&A
that cost justified? High-effort mode makes the engine search a much larger space of buffer place‐ ment, sizing, and balancing options instead of taking the first acceptable solution. That exhaustive exploration is where the runtime goes. It is justified late in the flow on timing-critical or high-frequency blocks where you need the last few picoseconds of skew margin and the floorplan is already stable — never during early iterations you are going to discard.
with that? A skew target far below what the design actually needs forces the engine to insert extra buffers and burn clock power and area chasing balance the timing paths never required. Tighter skew is not free — it costs power, area, and runtime. The target should be sized to the real timing require‐ ment: 0.045 ns for aggressive blocks, 0.09 ns as a balanced default, 0.18 ns for relaxed or low-power blocks. Over-tightening is pure waste.
skew_only is a global posture — it tells the engine to chase skew while de-emphasizing insertion delay, typically producing a shallow, high-latency tree. enable_local_skew_optimization is more surgical: it balances skew within subtrees, focusing on sinks that share register-to-register paths, which is what actually affects path timing. The local option often gives better real timing even if the global skew number on a report looks worse, whereas skew_only can hurt you through elevated insertion delay and OCV exposure.
Sharing lets clocks reuse buffers and nets, which is efficient but couples the domains structurally. For asynchronous clocks, clocks at very different frequencies, or high-integrity and safety-critical designs,
that coupling is a risk — one domain's behavior can bleed into another. Disabling sharing (globally with disable_tree_sharing , or selectively with prevent_tree_sharing_with_clocks ) guarantees inde‐ pendence at the cost of more area and power. The selective option is usually smarter; the global disable is reserved for when nothing may share.
design? Both replace idealized assumptions with physical reality. RDE estimates clock-net delay using a route-driven model instead of crude Manhattan distance, so it captures the detours around blockages and congestion that Manhattan ignores. GRBL makes the optimizer aware of the actual global routing layers and their differing RC characteristics. Together they make CTS's pre-route delay and slew estimates track the final routed result far more closely, which means fewer post-route surprises and less ECO churn — at the price of additional runtime, most worthwhile on advanced nodes and congested blocks.
Key Takeaways
- CTS options cluster into six families — timing, power, area/placement, advanced algorithm, clock domain isolation, and mode/scenario — and almost every switch trades quality, runtime, power, or area against one another.
target_skewis the single most consequential knob: size it to the real timing requirement (0.05 /
0.10 / 0.18 ns are the common targets), because over-tightening wastes power and area for no be‐ nefit.
- High-effort and power-optimization modes deliver real gains but at steep runtime cost (7–9x for high-effort timing, +28–46% for dynamic power), so reserve them for late-flow, constraint-binding situations.
- Advanced algorithm options (RDE, GRBL, global-routing-based optimization) buy you better correl‐ ation with the routed design and are most valuable on advanced nodes and congested blocks.
- Clock domain isolation is about deliberate choice: sharing saves area and power, isolation guaran‐ tees independence — prefer per-clock isolation over a blanket global disable.
- Mode/scenario controls keep the tree consistent across MMMC;
setup_only/hold_onlyand single-mode runs are staged-closure tools, not everyday defaults, and usually need a final all-mode pass. - There is no universal best recipe — identify the block's binding constraint first, then enable the two or three options that address it directly.
ChipBuddy
← Home
Comments
Leave a Reply