Clock tree synthesis (CTS) is the physical-design step that builds a balanced distribution network to deliver the clock signal from a single source (PLL output) to thousands or millions of sequential elements (flip-flops, latches, SRAMs) across the die — with minimum skew (difference in arrival time between any two endpoints), controlled insertion delay, and bounded transition time. A modern AI accelerator at 1–2 GHz may have 10–50 million flip-flops grouped into hundreds of clock domains; the clock tree that drives them consumes 30–40% of total chip dynamic power and is the single largest contributor to signal integrity and timing closure difficulty.
Why clock skew matters. Every flip-flop in a synchronous design samples data on the clock edge. If two flip-flops on the same combinational path see different clock arrival times, the effective setup or hold margin shifts:
$$T_{\text{setup,eff}} = T_{\text{clk}} - t_{\text{comb}} - t_{\text{setup}} - (t_{\text{clk,launch}} - t_{\text{clk,capture}})$$
$$T_{\text{hold,eff}} = t_{\text{comb}} - t_{\text{hold}} + (t_{\text{clk,launch}} - t_{\text{clk,capture}})$$
Positive skew (launch arrives before capture) helps setup but hurts hold; negative skew does the opposite. Uncontrolled skew of even 20–30 ps at a 1 GHz clock (1000 ps period) can violate hundreds of timing paths, requiring expensive ECO fixes or frequency derating.
CTS algorithms — H-tree, fishbone, and buffer tree. The fundamental goal is to equalize wire delay from source to every sink:
| Topology | Structure | Skew | Power | Use case |
|---|---|---|---|---|
| H-tree | Symmetric binary branching (fractal H-shape) | Very low (inherently balanced) | Moderate | Small, regular arrays (SRAM, register file) |
| Fishbone / spine | Central trunk with lateral branches | Low (trunk balanced, branches short) | Low (fewer buffers) | Datapaths with regular placement |
| Buffer tree (CTS engine) | Irregular tree of buffers/inverters built by tool | Tool-optimized | Optimized | General logic (primary method) |
| Mesh + tree | Global mesh for low-skew distribution, local trees from mesh taps | Very low | High (short-circuit current in mesh) | High-performance CPUs, GPUs |
| Hybrid mesh-tree | Mesh at top level, trees below | Low | Moderate-high | AI accelerators |
The CTS flow — what the EDA tool does. After placement, the CTS engine (Innovus CCOpt, ICC2 CTS):
1. Clustering — groups flip-flops by physical proximity and clock domain into balanced clusters (~32–256 sinks per leaf buffer). 2. Tree construction — builds a multi-level buffer tree from source to clusters, inserting clock buffers (CK-BUF) or inverters (CK-INV) to drive the capacitive load at each branch point. Buffer sizing is chosen to meet transition-time constraints (typically <50 ps slew at each stage). 3. Skew balancing — adjusts wire detours (snaking) and buffer delays to equalize path lengths. Target: local skew <10–15 ps; global skew <30–50 ps. 4. Useful skew (intentional skew) — CTS can deliberately skew certain endpoints to help setup-critical paths (borrow time from the next cycle) — a controlled trade-off that synthesis tools exploit during optimization. 5. OCV / AOCV derating — after CTS, timing analysis accounts for on-chip variation (voltage/temperature gradients, process mismatch) that adds random skew on top of the tree's systematic skew.
Power — the clock tree's dominant cost. The clock net toggles every cycle at full frequency. Its dynamic power:
$$P_{\text{clock}} = \alpha \cdot C_{\text{tree}} \cdot V_{\text{DD}}^2 \cdot f$$
where $\alpha$ = 1 (full activity), $C_{\text{tree}}$ is the total capacitance of all clock wires + buffer input caps + flip-flop clock pins. In a 5 nm GPU, $C_{\text{tree}}$ can exceed 10 nF, giving >5 W of clock-tree power at 1.5 GHz and 0.75 V — motivating clock gating (shutting off branches to idle blocks, reducing effective $\alpha$ to 0.3–0.5).
Clock gating — the primary power optimization. An integrated clock gating (ICG) cell (latch + AND/OR gate) gates the clock to a group of flip-flops: when the enable signal is low, the downstream clock stops toggling and those flops hold state with zero dynamic power. A well-gated design achieves 40–70% clock-tree power reduction. CTS must build the tree considering gating cells as intermediate nodes — each ICG is both a sink (from the parent tree) and a source (for the gated subtree).
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 440" font-family="system-ui,sans-serif">
<rect width="760" height="440" fill="#1a1a17" rx="12"/>
<text x="380" y="28" fill="#c9c3f2" font-size="15" text-anchor="middle" font-weight="600">Clock tree synthesis — buffer tree with skew balancing</text>
<!-- PLL source -->
<rect x="340" y="50" width="80" height="30" fill="#4a3a6a" stroke="#9a8adf" stroke-width="1.5" rx="5"/>
<text x="380" y="69" fill="#d4c8ff" font-size="10" text-anchor="middle">PLL (source)</text>
<!-- Root buffer -->
<line x1="380" y1="80" x2="380" y2="100" stroke="#e0913a" stroke-width="2"/>
<rect x="365" y="100" width="30" height="18" fill="#3a3a28" stroke="#e8d44d" stroke-width="1.2" rx="3"/>
<text x="380" y="113" fill="#e8d44d" font-size="8" text-anchor="middle">BUF</text>
<!-- Level 1 branches -->
<line x1="380" y1="118" x2="380" y2="130" stroke="#e0913a" stroke-width="1.5"/>
<line x1="380" y1="130" x2="200" y2="130" stroke="#e0913a" stroke-width="1.5"/>
<line x1="380" y1="130" x2="560" y2="130" stroke="#e0913a" stroke-width="1.5"/>
<!-- Level 1 buffers -->
<rect x="185" y="135" width="30" height="18" fill="#3a3a28" stroke="#e8d44d" stroke-width="1.2" rx="3"/>
<text x="200" y="148" fill="#e8d44d" font-size="8" text-anchor="middle">BUF</text>
<rect x="545" y="135" width="30" height="18" fill="#3a3a28" stroke="#e8d44d" stroke-width="1.2" rx="3"/>
<text x="560" y="148" fill="#e8d44d" font-size="8" text-anchor="middle">BUF</text>
<!-- Level 2 branches (left) -->
<line x1="200" y1="153" x2="200" y2="170" stroke="#e0913a" stroke-width="1.2"/>
<line x1="200" y1="170" x2="120" y2="170" stroke="#e0913a" stroke-width="1.2"/>
<line x1="200" y1="170" x2="280" y2="170" stroke="#e0913a" stroke-width="1.2"/>
<!-- Level 2 buffers (left) -->
<rect x="105" y="175" width="30" height="18" fill="#3a3a28" stroke="#e8d44d" stroke-width="1" rx="3"/>
<text x="120" y="188" fill="#e8d44d" font-size="7" text-anchor="middle">BUF</text>
<rect x="265" y="175" width="30" height="18" fill="#3a3a28" stroke="#e8d44d" stroke-width="1" rx="3"/>
<text x="280" y="188" fill="#e8d44d" font-size="7" text-anchor="middle">BUF</text>
<!-- Level 2 branches (right) -->
<line x1="560" y1="153" x2="560" y2="170" stroke="#e0913a" stroke-width="1.2"/>
<line x1="560" y1="170" x2="480" y2="170" stroke="#e0913a" stroke-width="1.2"/>
<line x1="560" y1="170" x2="640" y2="170" stroke="#e0913a" stroke-width="1.2"/>
<rect x="465" y="175" width="30" height="18" fill="#3a3a28" stroke="#e8d44d" stroke-width="1" rx="3"/>
<text x="480" y="188" fill="#e8d44d" font-size="7" text-anchor="middle">BUF</text>
<rect x="625" y="175" width="30" height="18" fill="#3a3a28" stroke="#e8d44d" stroke-width="1" rx="3"/>
<text x="640" y="188" fill="#e8d44d" font-size="7" text-anchor="middle">BUF</text>
<!-- ICG (clock gating cell) on one branch -->
<line x1="120" y1="193" x2="120" y2="210" stroke="#e0913a" stroke-width="1"/>
<rect x="100" y="210" width="40" height="20" fill="#3a2a3a" stroke="#bf6faf" stroke-width="1.3" rx="3"/>
<text x="120" y="224" fill="#dfafdf" font-size="7" text-anchor="middle">ICG</text>
<text x="148" y="218" fill="#8a8a86" font-size="7">gate</text>
<!-- Flip-flop sinks -->
<line x1="120" y1="230" x2="120" y2="250" stroke="#6fbf6f" stroke-width="1"/>
<line x1="120" y1="250" x2="80" y2="250" stroke="#6fbf6f" stroke-width="0.8"/>
<line x1="120" y1="250" x2="160" y2="250" stroke="#6fbf6f" stroke-width="0.8"/>
<rect x="68" y="255" width="24" height="16" fill="#2a3a2a" stroke="#6fbf6f" stroke-width="1" rx="2"/>
<text x="80" y="266" fill="#bff0bf" font-size="7" text-anchor="middle">FF</text>
<rect x="148" y="255" width="24" height="16" fill="#2a3a2a" stroke="#6fbf6f" stroke-width="1" rx="2"/>
<text x="160" y="266" fill="#bff0bf" font-size="7" text-anchor="middle">FF</text>
<!-- More FF sinks for other branches -->
<line x1="280" y1="193" x2="280" y2="250" stroke="#6fbf6f" stroke-width="0.8"/>
<line x1="280" y1="250" x2="250" y2="250" stroke="#6fbf6f" stroke-width="0.8"/>
<line x1="280" y1="250" x2="310" y2="250" stroke="#6fbf6f" stroke-width="0.8"/>
<rect x="238" y="255" width="24" height="16" fill="#2a3a2a" stroke="#6fbf6f" stroke-width="1" rx="2"/>
<text x="250" y="266" fill="#bff0bf" font-size="7" text-anchor="middle">FF</text>
<rect x="298" y="255" width="24" height="16" fill="#2a3a2a" stroke="#6fbf6f" stroke-width="1" rx="2"/>
<text x="310" y="266" fill="#bff0bf" font-size="7" text-anchor="middle">FF</text>
<line x1="480" y1="193" x2="480" y2="250" stroke="#6fbf6f" stroke-width="0.8"/>
<line x1="480" y1="250" x2="450" y2="250" stroke="#6fbf6f" stroke-width="0.8"/>
<line x1="480" y1="250" x2="510" y2="250" stroke="#6fbf6f" stroke-width="0.8"/>
<rect x="438" y="255" width="24" height="16" fill="#2a3a2a" stroke="#6fbf6f" stroke-width="1" rx="2"/>
<text x="450" y="266" fill="#bff0bf" font-size="7" text-anchor="middle">FF</text>
<rect x="498" y="255" width="24" height="16" fill="#2a3a2a" stroke="#6fbf6f" stroke-width="1" rx="2"/>
<text x="510" y="266" fill="#bff0bf" font-size="7" text-anchor="middle">FF</text>
<line x1="640" y1="193" x2="640" y2="250" stroke="#6fbf6f" stroke-width="0.8"/>
<line x1="640" y1="250" x2="610" y2="250" stroke="#6fbf6f" stroke-width="0.8"/>
<line x1="640" y1="250" x2="670" y2="250" stroke="#6fbf6f" stroke-width="0.8"/>
<rect x="598" y="255" width="24" height="16" fill="#2a3a2a" stroke="#6fbf6f" stroke-width="1" rx="2"/>
<text x="610" y="266" fill="#bff0bf" font-size="7" text-anchor="middle">FF</text>
<rect x="658" y="255" width="24" height="16" fill="#2a3a2a" stroke="#6fbf6f" stroke-width="1" rx="2"/>
<text x="670" y="266" fill="#bff0bf" font-size="7" text-anchor="middle">FF</text>
<!-- Skew annotation -->
<line x1="80" y1="280" x2="80" y2="295" stroke="#c9c3f2" stroke-width="0.8"/>
<line x1="670" y1="280" x2="670" y2="295" stroke="#c9c3f2" stroke-width="0.8"/>
<line x1="80" y1="290" x2="670" y2="290" stroke="#c9c3f2" stroke-width="1" stroke-dasharray="4,2"/>
<text x="380" y="305" fill="#c9c3f2" font-size="9" text-anchor="middle">skew = max(t_arrive) − min(t_arrive) < 30 ps target</text>
<!-- Bottom: power + metrics -->
<rect x="40" y="320" width="340" height="105" fill="#1f1f1c" stroke="#3a3a37" stroke-width="1" rx="8"/>
<text x="210" y="345" fill="#c9c3f2" font-size="11" text-anchor="middle" font-weight="500">Clock power breakdown (typical 5nm GPU)</text>
<text x="60" y="370" fill="#d4d4d0" font-size="10">Clock tree wire + buffer: 30–40% of total dynamic P</text>
<text x="60" y="390" fill="#d4d4d0" font-size="10">Clock gating saves: 40–70% of clock power</text>
<text x="60" y="410" fill="#8a8a86" font-size="9">P_clk = C_tree · V²DD · f (α=1, toggles every cycle)</text>
<rect x="400" y="320" width="330" height="105" fill="#1f1f1c" stroke="#3a3a37" stroke-width="1" rx="8"/>
<text x="565" y="345" fill="#c9c3f2" font-size="11" text-anchor="middle" font-weight="500">CTS quality metrics</text>
<text x="420" y="370" fill="#e8d44d" font-size="10">Local skew: <10–15 ps (within a domain)</text>
<text x="420" y="390" fill="#e8d44d" font-size="10">Global skew: <30–50 ps (across die)</text>
<text x="420" y="410" fill="#8a8a86" font-size="9">Insertion delay: 200–500 ps (PLL → leaf FF)</text>
</svg>
Multi-domain CTS in AI accelerators. A GPU or TPU has dozens of independent clock domains — the shader cores run at one frequency, the memory controller at another, the NoC at a third. Each domain gets its own tree, and crossings between domains use synchronizers (2-flop or FIFO). The CTS tool must respect domain boundaries, insert proper buffers at each domain root (often driven by a separate PLL or clock divider), and verify that no clock signal leaks across domains. At 50+ million flip-flops and 30+ domains, CTS runtime is one of the longest single steps in the physical-design flow (hours to days on a high-end server).
CTS and the CFS ecosystem. Clock tree performance ties directly to multiple CFS simulators: the Transistor Simulator at /transistor determines buffer drive strength and leakage; the Interconnect Simulator at /interconnect models wire RC delay in the clock nets; and the Thermal Simulator at /thermal captures the self-heating from clock-tree power dissipation across the die.
Explore 500+ Semiconductor & AI Topics
From EUV lithography to CUDA optimization — search the full knowledge base or chat with our AI assistant.