Core capabilities
iCTS (Clock Tree Synthesis) builds the buffered tree network from clock sources (PLL/OSC) to all timing-register clock pins after standard-cell placement. Goals include keeping clock skew within constraints, minimizing insertion latency, and meeting transition/slew requirements. iCTS uses a DME (Deferred-Merge Embedding) plus Slew-Aware dual framework—bottom-up geometric merging and top-down timing propagation and correction.
Agents can upgrade iCTS from a one-click build tool to an interactive clock-tree debug platform. Use cases include: clock tree inspection—traverse topology, check fanout and load per buffer level, identify abnormally long branches or high-fanout nodes; local clock tree resynthesis—when STA finds skew violations on a path, rebuild only the problem subtree (adjust buffer types, add buffer levels, or change routing topology) instead of rerunning full CTS; skew target tuning—try different skew_target values (e.g. 0.02ns vs 0.05ns) and observe trade-offs in buffer count and total latency for PPA optimization.
In multi-clock-domain designs, iCTS builds independent trees per domain, then balances at the top level after cross-domain skew evaluation via iSTA. Agents can prioritize domains with strict skew constraints (e.g. source-synchronous interfaces) and relax async domains to save area and power.
iCTS supports extensible timing models: interconnect uses PERI for slew and Elmore for delay; buffer insertion delay uses LUT with bilinear interpolation. Agents can switch to ML models (XGBoost / CatBoost) for more accurate buffer delay prediction. For large designs (>3000 registers), iCTS auto-enables K-Means clustering to split clock nets into sub-regions, build local trees, and merge.
Agent calling patterns
# Agent calls iCTS for clock tree synthesis
from ieda_client import IEDAClient
client = IEDAClient()
# Basic clock tree build
result = client.call("iCTS.synthesize",
design_ref="snap_7f3a",
skew_target=0.05,
latency_target=1.0)
# Agent checks results; rebuild subtree if needed
if result['achieved_skew'] > 0.05:
# Rebuild violating subtree
repair = client.call("iCTS.rebuild_subtree",
clock_tree_ref=result['clock_tree_ref'],
subtree_root="clk_buf_42",
target_skew=0.03)
# Agent traverses clock paths and extracts AI features
for path in result['clock_paths']:
print(f"Path: {path['name']}, levels: {path['levels']}")
{
"tool": "iCTS.synthesize",
"arguments": {
"design_ref": "snap_7f3a",
"skew_target": 0.05,
"latency_target": 1.0
}
}
# Tcl interactive clock tree synthesis
iCTS::set_design snap_7f3a
iCTS::set_skew_target 0.05
iCTS::set_latency_target 1.0
iCTS::set_buffer_types {BUF_X1 BUF_X2 BUF_X4}
iCTS::synthesize
iCTS::report_clock_tree
iCTS::check_skew -threshold 0.05
iCTS::write_def -output snap_7f3a.cts.def
Input / output contract
| Field | Type | Required | Description |
|---|---|---|---|
design_ref | string | Yes | Design instance identifier (includes post-placement data) |
skew_target | float | Yes | Target clock skew (ns); typical 0.02–0.10 |
latency_target | float | Yes | Target insertion latency (ns) |
clock_ports | string[] | Yes | Clock ports to build trees for |
buffer_types | string[] | No | Available buffer types (auto-selected by default) |
| Return field | Type | Description |
|---|---|---|
clock_tree_ref | string | Clock tree reference ID in iDB |
achieved_skew | float | Achieved global skew (ns) |
achieved_latency | float | Achieved average insertion latency (ns) |
buffer_count | int | Total clock buffers inserted |
clock_paths | ClockPath[] | Per-path details (delay, levels, slew) |
Role in the flow
··· prior steps ···
│
┌─────────────┐
│ iPL │ standard-cell placement complete
│ Placement │
└──────┬──────┘
│ placed design
▼
┌─────────────┐
│ iCTS │ ← current tool: clock tree synthesis
│ Clock Tree │
└──────┬──────┘
│ clock_tree_ref
▼
┌─────────────┐
│ iTO │ timing optimization (hold/DRV repair)
│ Timing Opt │
└──────┬──────┘
│
▼
┌─────────────┐
│ iRT │ routing
│ Routing │
└──────┬──────┘
··· downstream steps ···