Module 518 min

Clock Tree Synthesis (CTS)

How CTS builds a real, balanced clock network: topologies (H-tree, spine, mesh), skew, latency, useful skew and the hold it exposes.

Pro Tip

Your chip has one clock root (usually a PLL output) but hundreds of thousands, even millions, of flip-flops that all need that clock. You cannot run a single wire to all of them: the capacitance would be enormous, the edge would turn into a slow ramp, and flip-flops in different corners of the die would see the edge at wildly different times. Clock tree synthesis (CTS) solves both problems by building a balanced network of clock buffers that fans the clock out level by level, so every flip-flop gets a fast, clean edge at almost the same instant.

What clock tree synthesis does

Before CTS, static timing analysis uses an ideal clock: the tool pretends the clock reaches every flip-flop at exactly the same time with zero delay. That is fine for early analysis, but it is not real silicon. CTS replaces that ideal clock with a physical network of buffers, inverters and wires, and from then on timing is checked with the propagated (real) clock.

CTS runs after placement and before (or interleaved with) routing. It has one job stated two ways: deliver the clock to every sink with a controlled arrival time, and do it with a clean enough edge that setup and hold can be met everywhere. Everything else about CTS is a trade-off around those two goals.

The clock tree: buffers that fan the clock out

A clock tree starts at the clock root and branches outward. Each level of buffers takes the incoming clock and drives a manageable number of loads at the next level, until the last level drives the individual flip-flop clock pins. A real block typically has four to eight levels of buffering. Buffers are what keep the transition (slew) sharp: without them, one net driving tens of thousands of pins would have a rise time measured in nanoseconds and the clock would barely toggle.

A buffered clock tree: violet = clock source, cyan = buffers, amber = flip-flop sinks — click to enlarge
Note

Buffer vs inverter, CTS cells come in both flavours. Many tools build the tree from inverters in balanced pairs, because a matched inverter pair keeps rise and fall delays close and cancels duty-cycle drift better than a plain buffer. Whichever is used, the cells are special, well-characterised clock cells, not ordinary logic.

Clock tree topologies

How the tree is shaped is the topology. The tool picks (or you constrain) a topology based on how the sinks are laid out, how tight the skew target is, and how much power and routing you can spend. These are the shapes you will hear named in reviews and interviews.

H-tree

The H-tree is the textbook balanced tree. The clock splits into an H shape, each arm splits into a smaller H, and so on, so that the wire distance from the root to every leaf is identical. Equal length means equal delay, which means skew is near zero by construction rather than by tool effort. The cost is dedicated routing and area, and it works best when sinks are spread out fairly regularly. The X-tree is the same idea rotated onto diagonal segments.

H-tree, recursive H shapes give every leaf the same path length from the root — click to enlarge

X-tree

An X-tree is an H-tree that routes along diagonals instead of only horizontal and vertical segments. It can shorten total wire length and latency versus a strict H-tree, but diagonal clock routing is awkward on standard preferred-direction metal layers, so it is rare in normal cell-based flows and shows up mostly in custom or full-custom clocking.

Spine / fishbone

A spine (or fishbone) drives one strong central wire and taps ribs off it to reach the sinks. It is compact and cheap in area and power and is a natural fit for regular structures like datapaths and memory arrays. The weakness is balance: sinks near the driver see the clock earlier than sinks at the far end, so skew grows along the spine and has to be watched.

Spine / fishbone, a central spine with ribs; simple and compact, less inherently balanced — click to enlarge

Clock mesh (grid)

A mesh (grid) shorts many drivers onto a single grid of wires that blankets the block. Because dozens of drivers hold the same grid, the arrival time is averaged and skew is extremely low, even under on-chip variation. The price is high power (a large always-switching capacitance) and area, so meshes are reserved for the top-level clock of high-performance CPUs and GPUs where skew matters more than power.

Clock mesh, many drivers short one grid together for the lowest skew, at high power — click to enlarge

Hybrid trees

Real SoCs almost never use one pure topology. The common pattern is hybrid: a mesh or a balanced H-tree distributes the clock at the top level across the die, and a conventional buffered tree grows locally inside each block from that distribution. You get low top-level skew where it is expensive to fix and cheap local trees everywhere else.

TopologySkew controlPowerArea / routingTypical use
H-tree / X-treeExcellent (balanced by construction)ModerateHigh (dedicated tracks)Top-level distribution, regular sinks
Conventional buffered treeGood (tool-balanced)Low to moderateLowThe default inside standard-cell blocks
Spine / fishboneModerate (grows along spine)LowLowDatapaths, memory arrays, simple blocks
Mesh / gridBest (drivers averaged)Very highHighTop clock of high-performance CPUs/GPUs
Hybrid (mesh + local trees)ExcellentHighHighLarge SoCs: mesh at top, trees per block

The three numbers CTS cares about

Clock skew

Skew is the difference in clock arrival time between two flip-flops. If the launch flop sees the edge at 1.00 ns and the capture flop at 1.04 ns, the skew on that pair is 40 ps. Local skew is measured between related (launch/capture) flops; global skew is the spread across the whole design. Skew is not purely bad: positive skew toward the capture flop relaxes setup but tightens hold, and negative skew does the reverse. A typical post-CTS target keeps global skew under roughly 5% of the clock period.

Insertion delay is source to sink; skew is the difference in arrival between two sinks — click to enlarge

Insertion delay (latency)

Insertion delay, or clock latency, is the time from the clock source to a flip-flop clock pin through all the buffers and wires. It splits into source latency (before the clock root, e.g. inside the PLL and the top-level route) and network latency (the tree the CTS tool builds). Latency on its own does not break timing; it is the difference in latency between flops, which is skew, that does. Still, lower and more balanced latency means less absolute variation, so tools try to keep the tree shallow.

Clock uncertainty

Uncertainty is the guard-band you subtract from every clock edge in STA. Before CTS it stands in for the skew you have not built yet plus jitter; you set it with set_clock_uncertainty in the SDC. After CTS, the propagated clock carries the real skew directly, so you drop the skew portion and leave only jitter (cycle-to-cycle variation from the PLL, typically tens of picoseconds) and a small modelling margin.

Useful skew, turning skew into margin

Instead of driving skew to zero everywhere, modern CTS deliberately spends it. If a path is tight on setup, delaying the capture clock a little (useful skew) gives that path extra time. The catch is that the capture flop is the launch flop for the next stage, so the borrowed time has to be paid back downstream. Concurrent clock and data optimisation lets the tool push skew onto exactly the launch/capture pairs where it buys the most slack without breaking their neighbours.

Note

Useful skew in one line, zero skew is a starting point, not the goal. The goal is the best worst-slack across the whole design, and a well-placed few picoseconds of skew often beats a perfectly balanced tree.

The CTS flow, step by step

1
Cluster the sinks

Group flip-flop clock pins by location so physically close sinks share a branch. Good clustering is what makes a shallow, low-skew tree possible.

2
Build the tree and insert buffers

Grow the network from the clock root, adding balanced buffers or inverter pairs at each level to drive the next fan-out cleanly.

3
Balance skew

Size and reposition cells so every sink sees the edge at nearly the same time, or hit the target useful-skew schedule instead of pure balance.

4
Concurrent clock + data optimisation

Optimise the data paths and the clock together, spending skew where it buys the most margin (ccopt in Innovus, clock_opt in ICC2 / Fusion Compiler).

5
Route the clock with NDR and shielding

Commit the clock nets on non-default rules (wider, more spacing, sometimes shielded) so they are low-resistance and immune to neighbour crosstalk.

6
Analyse and fix hold

With real latency in place, re-time the design and add hold buffers on the short paths CTS just exposed.

Clock tree cells, NDR and shielding

The clock network gets special treatment because a picosecond of variation here hits every path. A few things distinguish it from ordinary logic:

  • Clock buffers and inverters are dedicated, well-characterised cells; balanced inverter pairs are preferred so rise and fall delays match.
  • After the tree is balanced its cells are marked don’t-touch, so later timing optimisation cannot resize them and unbalance the tree.
  • Non-default routing rules (NDR) give clock nets extra width and spacing to cut resistance, electromigration and crosstalk-induced skew.
  • Shielding runs grounded or power wires alongside sensitive clock nets so neighbouring switching cannot jitter the edge.
  • Integrated clock-gating cells (ICG) live inside the tree, so even gated branches stay balanced with the rest of the clock.

Why CTS creates hold violations

Before CTS the clock was ideal, so hold almost always passed. The moment CTS inserts real latency and skew, short paths between physically close flip-flops can fail hold: the data races through the tiny bit of logic and arrives before the previous value is safely captured, and any positive skew toward the capture flop makes it worse.

Watch out

Hundreds of hold violations right after CTS are normal, not a bug. They are fixed by adding delay (hold or delay buffers) on the short paths, never by speeding the clock up. Watch that the added delay does not eat the setup margin on the same path.

Reading a CTS / clock report

After CTS you check the tree the same way in every tool: skew, insertion delay, transition, buffer count and clock power. A healthy tree hits the skew target with the fewest levels and buffers, and with clean transitions at the leaves.

text
report_clock_timing -type skew -clock clk

Clock: clk
  Rise Skew ............ 0.041 ns
  Max Insertion Delay .. 0.312 ns   (u_mem/.../CK)
  Min Insertion Delay .. 0.271 ns   (u_alu/.../CK)
  Global Skew .......... 0.041 ns
  Sinks ................ 12480
  Clock Buffers ........ 214
  Tree Levels .......... 6
MetricWhat it tells youHealthy target
Global skewSpread of clock arrival across all sinksUnder ~5% of the clock period
Max insertion delayLongest source-to-sink latencyLow, and balanced against min insertion delay
Clock transition (slew)Edge rate at the sink pinsUnder ~100 ps (node dependent)
Buffer / inverter countSize and power of the treeMinimised for the skew target
Clock powerDynamic power of the networkOften 20-40% of chip dynamic power
Tree levelsDepth of the treeFewer levels means less latency and variation

Key CTS commands

Command / propertyToolPurpose
ccopt_designInnovusBuild the tree with concurrent clock + data optimisation
set_ccopt_propertyInnovusSet target skew, max latency, buffer/inverter lists, NDR
clock_optICC2 / Fusion CompilerRun clock tree synthesis and optimisation
set_clock_tree_optionsICC2Configure CTS references, targets and routing rules
report_clock_timing -type skewPrimeTime / InnovusReport skew between launch and capture sinks
report_clock_tree / report_clock_tree_powerBothSkew, insertion delay, buffer count and clock power
Note

Recap: CTS turns the ideal clock into a real, buffered network. Pick a topology for your skew and power budget (tree, H-tree, spine or mesh), balance skew or spend it usefully, route the clock on its own rules, then clean up the hold violations that real latency exposes.