Home Knowledge Base Clock tree synthesis (CTS)

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:

TopologyStructureSkewPowerUse case
H-treeSymmetric binary branching (fractal H-shape)Very low (inherently balanced)ModerateSmall, regular arrays (SRAM, register file)
Fishbone / spineCentral trunk with lateral branchesLow (trunk balanced, branches short)Low (fewer buffers)Datapaths with regular placement
Buffer tree (CTS engine)Irregular tree of buffers/inverters built by toolTool-optimizedOptimizedGeneral logic (primary method)
Mesh + treeGlobal mesh for low-skew distribution, local trees from mesh tapsVery lowHigh (short-circuit current in mesh)High-performance CPUs, GPUs
Hybrid mesh-treeMesh at top level, trees belowLowModerate-highAI 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) &lt; 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: &lt;10–15 ps (within a domain)</text>
  <text x="420" y="390" fill="#e8d44d" font-size="10">Global skew: &lt;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.

clock tree synthesisdesign & verification

Explore 500+ Semiconductor & AI Topics

From EUV lithography to CUDA optimization — search the full knowledge base or chat with our AI assistant.