← Home CTS & Concurrent Optimization
7 CTS & Concurrent Optimization

Useful-Skew Optimization

Clock tree synthesis with simultaneous clock-and-data optimization for tighter timing closure

Of all the levers a physical-design engineer can pull during clock tree synthesis and concurrent clockdata optimization, useful skew is arguably the most surgical and the most powerful. It is the one technique that lets you create timing slack out of seemingly nothing, by redistributing the time budget you already have rather than spending more area, more buffering on the datapath, or a slower clock. This chapter explains what useful skew really is, how the optimization engine schedules it automatically, how to control its aggressiveness, how to cap it so it does not become a liability, and how it interacts with hold timing, on-chip variation, and signoff.

Recap: What Useful Skew Actually Buys You

In a naive clock tree, the design goal is zero skew: every register flip-flop receives its clock edge at exactly the same instant. That symmetry is comfortable to reason about, but it is rarely optimal. Real datapaths are uneven. One pipeline stage may have a long combinational cone that barely makes timing, while the very next stage is short and finishes with picoseconds to spare. A zero-skew clock forces both stages to live inside the same uniform clock period, so the tight stage limits the whole design even though slack is sitting idle one stage downstream. Useful skew breaks that symmetry on purpose. By intentionally delaying the clock arrival at the register that captures the tight path, you extend the time available for that path to settle. The capturing edge arrives later, so the data has more time to propagate. Of course, that same register is the launching register for the next stage, so delaying its clock steals time from the downstream path. The

trick is that the downstream path had slack to spare. You are, in effect, borrowing time from a loose stage and lending it to a tight one, register by register, across the whole sequential graph.

Technical diagram

The reason useful skew is such a strong lever is leverage in the literal sense: a single clock-arrival adjustment at one register simultaneously affects every path that launches from it and every path that captures into it. One offset can rebalance a whole neighborhood of timing. Compared with resizing dozens of datapath gates, inserting datapath buffers, or restructuring logic, a well-chosen clock offset is cheap and globally effective. This is precisely why modern flows fold useful skew into the concurrent clock-data optimization step rather than treating it as a manual afterthought.

How the Engine Schedules Useful Skew Automatically

In a concurrent clock-data optimization flow, the engine does not build a balanced tree first and then bolt on skew. Instead it reasons about clock arrival times and datapath delays together. Conceptually, it treats each register's clock latency as a tunable variable and solves for the set of per-register offsets that minimizes the design's negative slack. The mechanism is usually framed as a slack-driven scheduling problem on the sequential graph. Each register is a node; each timing path between two registers is an edge carrying a setup constraint (and a hold constraint in the opposite direction). Shifting a node's clock arrival relaxes the setup edges feeding into it and tightens the setup edges leaving it. The optimizer searches for the assignment of clock arrivals that pushes the worst negative slack (WNS) toward zero and reduces the total negative slack (TNS) summed across all violating endpoints. Importantly, this is a global optimization, not a per-path greedy fix. Borrowing time across one register boundary can cascade: relieving a violation here may create one two stages away, so the engine has to balance the whole chain. After it decides on the target offsets, it physically realizes them by adjusting the clock network, typically by adding or removing buffer delay along the branches feeding each register, so that the as-built clock latency matches the scheduled latency.

# Enable useful-skew scheduling inside concurrent clock-data optimization
set_clock_opt   -useful_skew true
set_cts_option  -concurrent_clock_data true
set_cts_option  -useful_skew_mode auto

Because the offsets are computed from timing, the quality of useful skew depends entirely on the quality of the timing picture the engine sees. Garbage constraints, missing clock definitions, or unrealistic datapath delays will produce useful skew that helps in the tool's model and hurts in reality. Clean constraints are a prerequisite, not a nicety.

Controlling Useful-Skew Effort

Useful skew is not free. Every picosecond of intentional offset is realized by real delay in the clock network, which means more buffers, more clock power, more routing, and a wider spread of clock arrival times that variation can act on. The flow therefore exposes an effort control that trades quality of results against these costs. At low effort, the engine applies useful skew conservatively. It only redistributes clock arrival where the payoff is large and the offset required is small, leaving most registers at their balanced latency. This keeps the clock tree close to zero-skew, minimizes added buffering, and is gentle on hold timing and variation margin. At high effort, the engine schedules aggressively. It will assign larger offsets to more registers, chase smaller slices of negative slack, and accept the added buffer count and power that come with it. High effort can recover timing that nothing else will, but it produces a clock tree with a wider arrival spread and more hold exposure.

Effort levelEngine behaviorCost / risk
LowSkews only a few critical registers; smallMinimal extra buffers/power; low hold risk;
(conservative)offsets; stays near zero-skewmodest WNS/TNS gain
MediumSkews moderate set of registers; offsetsModerate buffer/power overhead;
(balanced)sized to recover meaningful slackmanageable hold and variation impact
HighSkews many registers; large offsets;Significant extra buffers, clock power, hold
(aggressive)chases small slack incrementspressure, variation exposure

The right place to set effort depends on where you are in the flow and how tight the design is. A common practice is to start at low or medium effort during early CTS and placement-stage optimization, when the timing picture is still fluid and you do not want the tool over-fitting useful skew to numbers that will change. Reserve high effort for late post-route optimization on the specific corners and paths that genuinely refuse to close any other way. Globally cranking effort to maximum on every block is a classic way to win timing in the tool and lose it at signoff.

# Stage-appropriate effort settings
# Early optimization: stay conservative
set_clock_opt -useful_skew_effort low
# Late timing closure on a stubborn block: allow aggressive scheduling
set_clock_opt -useful_skew_effort high

Applying Useful-Skew Limits

Effort decides how hard the engine tries; limits decide how far it is allowed to go. A skew limit caps the magnitude of clock offset any single register may take, and it is the single most important guardrail in a useful-skew flow. Without a limit, an aggressive optimizer can hand a register a very large offset because, in its idealized timing model, that offset closes a path. In silicon, a large offset means the clock arrival at that register sits far from its neighbors, and that gap is exactly where hold violations, variation-induced failures, and manufacturing surprises live. Limits can be applied globally (one cap for every register), per register or per group (tighter caps on hold-sensitive or variation-sensitive registers), and even per clock domain. A typical strategy sets a moderate global cap and then tightens it further on registers known to be fragile, such as those near asynchronous boundaries, in low-voltage domains, or feeding short hold-critical paths.

# Global cap: no register may take more than this much useful skew
set_useful_skew_limit -global 0.120
# Tighter cap on a hold-sensitive register group
set_useful_skew_limit -group hold_critical_regs -max 0.040
# Per-register override on a known-fragile flop
set_useful_skew_limit -pin u_core/async_capture_reg/CK -max 0.030

The most common mistake here is setting limits in only one stage. Useful skew is scheduled and rescheduled across CTS, post-CTS optimization, and post-route optimization. If you cap skew during CTS but leave it unconstrained in post-route, a later stage can quietly hand back the aggressive offsets you fought to avoid. Limits must be applied consistently across the complete flow so every optimization step honors the same ceiling.

# Apply the same limit policy to every optimization stage
set_useful_skew_limit -global 0.120 -apply_to_all_stages true
# Re-assert before each optimization invocation as a safeguard
proc enforce_skew_policy {} {
set_useful_skew_limit -global 0.120
set_useful_skew_limit -group hold_critical_regs -max 0.040
}
enforce_skew_policy ; optimize_clock -post_route
Limit typeWhat it protects against
Global magnitude capRunaway offsets anywhere; bounds overall arrival spread and clock

power

Per-register / per-group capHold failures and variation sensitivity on known-fragile flops
Per-domain capCross-domain arrival skew that complicates synchronizer and CDC

margins

Cross-stage (flow-wide) Later stages silently re-introducing offsets a prior stage avoided

Hold-Time Risk and How Limits Plus Hold Fixing Manage It

Useful skew and hold timing are in direct tension. The same offset that relaxes a setup path also changes the hold relationship on the paths it touches. When you delay the capturing register's clock to win setup, you can make a hold path into that register tighter, because the data now races against a later capture edge on short paths. Aggressive useful skew, left unchecked, is one of the most reliable ways to manufacture a flood of hold violations. Two mechanisms keep this under control. First, the limits described above bound how bad any single offset can make the local hold picture, before any fixing is attempted. A bounded offset produces a bounded hold problem. Second, the flow fixes the remaining hold violations explicitly, by inserting delay (hold buffers or delay cells) on the short datapaths so the data arrives after the hold window. A good concurrent flow co-optimizes here: it weighs the setup gain of a proposed offset against the holdbuffer cost it will incur, and rejects offsets whose hold-fixing overhead outweighs their benefit.

# Co-optimize setup useful skew against hold cost, then clean up residual hold
set_clock_opt -useful_skew true -hold_aware true
set_optimization_target -setup true -hold true
optimize_timing -fix_hold -hold_margin 0.020

The practical workflow is: schedule useful skew with limits and hold-awareness on, then run a dedicated hold-fix pass, then re-check that the hold buffers did not erode the setup gains you booked. Treating hold as an afterthought to useful skew is how blocks end up trading a handful of setup violations for hundreds of hold violations.

Interaction with On-Chip Variation and Signoff

On-chip variation (OCV) is where optimistic useful skew gets punished. The premise of useful skew is that two clock edges arrive a precise distance apart. OCV says you cannot fully trust that distance: process, voltage, and temperature gradients, plus aging and clock-path uncertainty, make the launch and capture edges drift relative to each other. The longer and more divergent the two clock paths feeding a skewed register pair, the more variation can eat into the offset you scheduled. A useful-skew

offset that looks like clean margin in a single nominal corner can shrink or invert once variation derating is applied. This has direct implications. Useful skew should always be scheduled against a variation-aware timing model, ideally the same advanced OCV or path-based derating methodology used at signoff, so the offsets the engine books already account for the uncertainty silicon will impose. Scheduling useful skew on optimistic, non-derated timing and only discovering the problem at signoff is a painful and common failure mode. It also reinforces why limits matter: a tighter skew cap keeps clock paths from diverging so far that variation dominates, preserving correlation between launch and capture edges. At signoff, every useful-skew offset must hold up across all corners and modes, with full OCV applied, on both setup and hold. The closer the optimization corners, derates, and constraints track the signoff setup, the fewer surprises appear. The healthiest sign-off story for a useful-skew design is one where the offsets are modest, bounded by consistent flow-wide limits, hold-clean across corners, and computed under the same variation assumptions the signoff tool will enforce.

Technical diagram

Interview Q&A

Q
In one sentence, why does useful skew work, and what is the catch? Useful skew works

because delaying a register's clock simultaneously relaxes every setup path capturing into it while tightening the paths launching from it, so you can move idle slack from loose stages to tight ones; the catch is that the same offsets tighten hold timing and become fragile under on-chip variation, so they must be bounded by limits and validated with derated timing.

Q
Effort and limits both control useful skew. What is the difference, and why do you need

both? Effort controls how hard the engine tries to find and apply beneficial offsets, trading quality of results against buffers, power, hold pressure, and variation exposure. Limits cap how large any single offset may become regardless of effort. You need both because high effort with no limit produces runaway offsets that fail hold and variation, while a limit with no effort leaves achievable timing on the table. Effort is the throttle; limits are the guardrail.

Q
You enabled useful skew during CTS, capped it, and timing was clean, but post-route

signoff shows large unexpected skew and new hold violations. What likely went wrong? Almost certainly the skew limit was applied only at the CTS stage and not enforced across post-route

optimization, so a later stage re-scheduled aggressive offsets that the earlier cap had prevented. The fix is to apply the limit policy flow-wide so every optimization step honors the same ceiling, and to run hold fixing with the offsets already in place. A secondary cause is scheduling useful skew on nonderated timing, so OCV at signoff revealed offsets that were never robust.

Q
How do you keep useful skew from creating a hold-violation disaster? Three layers. First,

bound the offsets with global and per-group skew limits so each offset's hold impact is bounded before any fixing. Second, run useful skew in a hold-aware, concurrent mode so the engine weighs setup gain against hold-buffer cost and rejects bad trades. Third, run an explicit hold-fix pass after scheduling, then re-verify that the inserted delay did not erode the setup gains. Tightening limits on hold-sensitive registers near asynchronous or low-voltage boundaries is the targeted reinforcement.

Key Takeaways

  • Useful skew intentionally offsets a register's clock arrival to borrow idle slack from loose stages and lend it to tight ones; one offset rebalances every path through that register, making it the most leveraged timing lever available.
  • Concurrent clock-data optimization schedules useful skew automatically by treating per-register clock latency as a variable and solving for the offsets that minimize worst and total negative slack across the whole sequential graph.
  • Effort controls aggressiveness (conservative small offsets versus aggressive large ones) and trades QoR against buffers, power, hold, and variation; set it low/medium early and reserve high effort for stubborn late-stage paths.
  • Skew limits cap how much offset any register may take and are the primary guardrail; apply them globally, per group, and per domain, and enforce them across the complete flow so later stages cannot re-introduce aggressive offsets.
  • Useful skew directly tightens hold timing; manage it with bounded limits, hold-aware co- optimization, and an explicit hold-fix pass, then re-verify the setup gains survived.
  • Always schedule useful skew against a variation-aware (OCV/derated) timing model that matches signoff; modest, bounded, hold-clean offsets are the only ones that survive all corners and modes.

Comments

Leave a Reply

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

Replying to