Back to Interview Prep

Tcl Reference Guide: Part 5 — Clock Tree Synthesis Commands

May 28, 2026 HDL2Chips Team Tcl Reference

Part 5 of the Tcl command reference covering Clock Tree Synthesis (CTS) commands used to define clock constraints, synthesize clock trees, balance skew, and optimize timing. CTS distributes the clock signal from the clock source to all sequential elements with minimal skew and latency.

The complete physical design flow follows this order:

  • Design & Database Setup
  • Floorplanning
  • Power Planning
  • Placement
  • Clock Tree Synthesis
  • Routing
  • Optimization
  • Signoff & Reports

Quick Reference: Clock Tree Synthesis Commands for EDA Tools

CTS builds a physical clock network using buffers and inverters to deliver the clock from the source to every flip-flop, latch, and memory clock pin. The goal is to minimize clock skew, meet transition and latency targets, and preserve timing margins across all PVT corners.

CommandDescription
create_clockCreates a clock definition
create_generated_clockCreates a generated clock (derived from master clock)
set_clock_latencySets clock latency (source or network)
set_clock_uncertaintySets clock uncertainty (jitter + margin)
set_clock_transitionSets clock transition (slew) limits
set_propagated_clockSets propagated clock mode for realistic latency
set_clock_tree_exceptionsSets clock tree exceptions (exclude pins, stop pins)
set_clock_groupsSets clock groups for asynchronous or exclusive clocks
set_clock_gating_checkSets clock gating setup and hold checks
set_cts_strategySets CTS strategy (effort, target skew, target latency)
synthesize_clock_treeSynthesizes the clock tree
optimize_clock_treeOptimizes the clock tree for skew and timing
balance_clock_treeBalances clock tree between domains
report_clock_treeReports clock tree structure and statistics
report_clockReports clock definitions and properties
check_timing -clock_treeChecks CTS timing violations

Typical CTS Flow Script

# === Typical CTS Flow ===
# Define clocks
create_clock -name clk -period 10.0 [get_ports clk]

# Set clock constraints
set_clock_uncertainty 0.2 [get_clocks clk]
set_clock_transition 0.15 [get_clocks clk]

# Set CTS strategy
set_cts_strategy -target_skew 0.05 -target_latency 1.0

# Synthesize clock tree
synthesize_clock_tree

# Balance and optimize
balance_clock_tree
optimize_clock_tree

# Report results
report_clock_tree > reports/cts.rpt
check_timing -clock_tree > reports/cts_checks.rpt

Command Deep-Dive: Understanding Each Command

create_clock Creates a clock definition

What it is: create_clock defines a clock in the design with a specified period, waveform, and source pin or port. This is the fundamental timing constraint that drives all static timing analysis. Every sequential element is timed relative to its clock.

Where we use it: Applied at the top-level clock input ports or at generated clock sources. The clock period defines the available time for logic between flip-flops. You also specify the waveform (rising and falling edges) for non-50% duty cycles. Multiple clocks can be created for multi-frequency designs.

Syntax: create_clock -name <name> -period <value> [-waveform {rise fall}] <source>

# Create a 100MHz clock with 50% duty cycle
create_clock -name clk -period 10.0 [get_ports clk]

# Create a clock with custom waveform
create_clock -name clk -period 10.0 -waveform {0 5} [get_ports clk]

# Create a clock at an internal pin
create_clock -name vco_clk -period 2.5 [get_pins pll/clk_out]
create_generated_clock Creates a generated clock

What it is: create_generated_clock defines a clock that is derived from a master clock through frequency division, multiplication, or phase shifting. Generated clocks exist at internal pins like divider outputs or PLL outputs.

Where we use it: For clocks generated by clock dividers, PLLs, or MMCMs. The generated clock relationship to the master clock is defined using -divide_by, -multiply_by, or -master_clock and -source pins.

Syntax: create_generated_clock -name <name> -source <pin> [-divide_by <n>] [-multiply_by <n>] <target>

# Divide master clock by 2
create_generated_clock -name clk_div2 -divide_by 2 \
  -source [get_ports clk] [get_pins divider/out]

# Multiply clock (PLL output)
create_generated_clock -name clk_2x -multiply_by 2 \
  -source [get_ports clk] [get_pins pll/clk_out]
set_clock_uncertainty Sets clock uncertainty

What it is: set_clock_uncertainty models clock jitter, margin, and derating by subtracting time from the available clock period. It accounts for PLL jitter, power supply noise, and on-chip variation (OCV) effects that are not modeled during CTS.

Where we use it: Applied to each clock before CTS and STA. Setup uncertainty reduces the available data path time. Hold uncertainty is set separately. Typical values range from 50ps to 300ps depending on the technology node and jitter characteristics.

Syntax: set_clock_uncertainty [-setup <value>] [-hold <value>] <clock_list>

# Set setup uncertainty
set_clock_uncertainty -setup 0.2 [get_clocks clk]

# Set hold uncertainty
set_clock_uncertainty -hold 0.05 [get_clocks clk]

# Set different uncertainty for rising/falling
set_clock_uncertainty 0.15 [get_clocks clk]
set_propagated_clock Sets propagated clock mode

What it is: set_propagated_clock enables propagated clock mode which uses the actual clock tree delay (calculated from the synthesized buffers and wires) instead of an ideal or estimated latency. After CTS the clock network has real physical delays.

Where we use it: Before CTS you use ideal clocks. After CTS you switch to propagated clocks so STA uses the actual clock arrival times at each flip-flop. This gives accurate setup and hold analysis with real clock skew.

Syntax: set_propagated_clock <clock_list>

# Enable propagated clock for all clocks
set_propagated_clock [all_clocks]

# Enable for specific clock only
set_propagated_clock [get_clocks clk]
set_clock_groups Sets clock groups

What it is: set_clock_groups defines relationships between clock domains. Clocks can be asynchronous (no timing relationship), exclusive (only one active at a time), or physically exclusive (mutually exclusive in hardware).

Where we use it: For designs with multiple clock domains. Asynchronous clock groups disable timing paths between unrelated clocks (e.g., USB and DDR clocks). Exclusive groups are used for clocks that never operate simultaneously like functional and test modes.

Syntax: set_clock_groups [-asynchronous] [-exclusive] -group <clock_list> -group <clock_list>

# Define asynchronous clock groups
set_clock_groups -asynchronous \
  -group [get_clocks clk_a] \
  -group [get_clocks clk_b]

# Define exclusive groups for mode muxing
set_clock_groups -exclusive \
  -group [get_clocks {func_clk scan_clk}]
synthesize_clock_tree Synthesizes the clock tree

What it is: synthesize_clock_tree builds the physical clock tree by inserting clock buffers and inverters to distribute the clock from the source to all sequential elements. The tool builds a balanced tree structure to minimize skew.

Where we use it: After placement is complete. The tool reads the clock constraints, identifies all clock sinks (flip-flop clock pins), and builds a buffer tree. CTS uses H-tree, X-tree, or balanced binary tree topologies depending on the strategy.

Syntax: synthesize_clock_tree [-target_skew <value>] [-gate_clock]

# Synthesize clock tree with default settings
synthesize_clock_tree

# Synthesize with specific target
synthesize_clock_tree -target_skew 0.05

# Synthesize with clock gating integration
synthesize_clock_tree -gate_clock
balance_clock_tree Balances clock tree between domains

What it is: balance_clock_tree adjusts the clock tree delays to balance skew between different clock domains or between different branches of the same clock. This is used when cross-domain timing paths need matching clock delays.

Where we use it: After initial CTS to fine-tune the balance. For example if a clock domain interface has tight timing the tool can add delay to the faster clock path to match the slower one. Also used for clock domain crossing (CDC) synchronization paths.

Syntax: balance_clock_tree [-from <clock>] [-to <clock>]

# Balance all clock trees
balance_clock_tree

# Balance specific clock domains
balance_clock_tree -from [get_clocks clk_a] -to [get_clocks clk_b]
report_clock_tree Reports clock tree structure

What it is: report_clock_tree prints detailed information about the synthesized clock tree including skew, latency, levels of buffering, total buffer count, and clock gating details. It is the primary verification command after CTS.

Where we use it: After synthesize_clock_tree to verify the clock tree quality. Check that skew is within target, latency is acceptable, and no clock tree DRC violations exist. Also use report_clock to verify clock definitions and check_timing -clock_tree for timing checks.

Syntax: report_clock_tree [-skew] [-latency] [-output <file>]

# Basic clock tree report
report_clock_tree > reports/cts.rpt

# Report with skew details
report_clock_tree -skew > reports/cts_skew.rpt

# Report clock properties
report_clock > reports/clocks.rpt

# CTS timing check
check_timing -clock_tree > reports/cts_check.rpt

Mastering these CTS commands is critical for building a balanced clock network with minimal skew and reliable timing margins. A well-synthesized clock tree ensures that all sequential elements receive the clock with predictable delay. Continue to Part 6: Routing & Signoff →