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.
| Command | Description |
|---|---|
create_clock | Creates a clock definition |
create_generated_clock | Creates a generated clock (derived from master clock) |
set_clock_latency | Sets clock latency (source or network) |
set_clock_uncertainty | Sets clock uncertainty (jitter + margin) |
set_clock_transition | Sets clock transition (slew) limits |
set_propagated_clock | Sets propagated clock mode for realistic latency |
set_clock_tree_exceptions | Sets clock tree exceptions (exclude pins, stop pins) |
set_clock_groups | Sets clock groups for asynchronous or exclusive clocks |
set_clock_gating_check | Sets clock gating setup and hold checks |
set_cts_strategy | Sets CTS strategy (effort, target skew, target latency) |
synthesize_clock_tree | Synthesizes the clock tree |
optimize_clock_tree | Optimizes the clock tree for skew and timing |
balance_clock_tree | Balances clock tree between domains |
report_clock_tree | Reports clock tree structure and statistics |
report_clock | Reports clock definitions and properties |
check_timing -clock_tree | Checks 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
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]
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]
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]
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]
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}]
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
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]
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 →