Beyond Synthesis: Verifying Your Design Actually Works
You've synthesized your design into gates, optimized for area and power, and analyzed the results. But there's one critical question remaining: Will it work at the target clock frequency? Synthesis tools provide estimates, but accurate timing verification requires dedicated static timing analysis (STA). This is where hope becomes certainty—or where you discover timing violations that must be fixed before tape-out.
Static timing analysis is the industry-standard method for verifying timing in digital designs. Unlike simulation (which only checks specific input vectors), STA mathematically analyzes all possible paths through your circuit, ensuring timing requirements are met across all operating conditions. Understanding STA fundamentals—setup and hold constraints, clock definitions, delays, and exceptions—is essential for any digital designer working on real hardware.
This module introduces the foundational concepts of timing analysis that apply across all STA tools, though we'll use OpenSTA for concrete examples.
Setup and Hold Constraints: The Fundamental Requirements
Understanding Setup Time
Setup time is the minimum time data must be stable before the clock edge captures it.
Physical Reason
Inside a flip-flop, data must propagate through internal transistors and gates to reach the master latch. If data changes too close to the clock edge, the internal circuitry doesn't have time to resolve the correct value, potentially capturing the wrong data or entering a metastable state.
Setup Time Specification
Data must be stable at least T_setup before the clock edge
From Liberty File
timing () {
related_pin : "D";
timing_type : setup_rising;
rise_constraint (setup_template_5x5) {
values (...); // Setup time values
}
}
Setup Check Equation
T_data_arrival + T_setup ≤ T_clock_arrival + T_period
Or equivalently:
T_data_arrival ≤ T_clock_arrival + T_period - T_setup
Where:
T_data_arrival = Time when data arrives at capture flip-flop
T_setup = Setup time requirement (from Liberty)
T_clock_arrival = Time when clock arrives at capture flip-flop
T_period = Clock period
Setup Slack
Slack = Required_time - Arrival_time
= (T_clock + T_period - T_setup) - T_data_arrival
Positive slack: Timing met (data arrives early enough)
Negative slack: Timing violation (data arrives too late)
Zero slack: Exactly meeting timing (no margin)
Understanding Hold Time
Hold time is the minimum time data must remain stable after the clock edge.
Physical Reason
After the clock edge triggers capture, the flip-flop's internal master latch needs time to completely latch the data. If data changes too soon after the clock edge, the latch might not have fully captured the value, leading to incorrect operation.
Hold Time Specification
Data must remain stable for at least T_hold after the clock edge
Hold Check Equation
T_data_arrival ≥ T_clock_arrival + T_hold
Or equivalently:
T_data_arrival - T_clock_arrival ≥ T_hold
Where:
T_data_arrival = Time when data arrives at capture flip-flop
T_clock_arrival = Time when clock arrives at capture flip-flop
T_hold = Hold time requirement (from Liberty)
Hold Slack
Slack = Arrival_time - Required_time
= T_data_arrival - (T_clock + T_hold)
Positive slack: Hold timing met (data stays stable long enough)
Negative slack: Hold violation (data changes too soon)
Key Differences: Setup vs. Hold
Setup Timing:
- Checks maximum delay (data arrives before deadline)
- Related to clock period (higher frequency = harder to meet)
- Fixed by: Speeding up logic, pipelining, lowering frequency
- Analysis corner: Slow corner (SS - worst-case delays)
Hold Timing:
- Checks minimum delay (data doesn't arrive too soon)
- Independent of clock period (same requirement at any frequency)
- Fixed by: Adding delay (buffers, routing detours)
- Analysis corner: Fast corner (FF - minimum delays)
Critical Insight
Setup violations can be fixed by reducing clock frequency. Hold violations cannot be fixed by changing frequency—they require physical design changes (adding delay). This makes hold violations more serious in many ways.
Example: Timing Analysis of a Simple Path
Circuit
Launch_FF → INV → AND → NAND → Capture_FF
Setup Analysis (Slow Corner, 2.0ns clock period)
Launch FF clock-to-Q: 0.180ns
INV delay: 0.065ns
AND delay: 0.078ns
NAND delay: 0.082ns
Wire delays: 0.045ns
────────────────────────────────
Data arrival time: 0.450ns
Clock period: 2.000ns
Capture FF setup time: -0.095ns
────────────────────────────────
Required time: 1.905ns
Setup slack = 1.905 - 0.450 = 1.455ns (PASS)
Hold Analysis (Fast Corner, same path)
Launch FF clock-to-Q: 0.095ns
INV delay: 0.032ns
AND delay: 0.038ns
NAND delay: 0.040ns
Wire delays: 0.020ns
────────────────────────────────
Data arrival time: 0.225ns
Capture FF hold time: 0.045ns
────────────────────────────────
Required time: 0.045ns
Hold slack = 0.225 - 0.045 = 0.180ns (PASS)
Both setup and hold are satisfied with positive slack.
Clock Definitions and Specifications
Why Clock Definition Matters
Clocks are the reference for all timing checks. Every setup and hold calculation depends on accurate clock definition. Incorrect clock specifications lead to incorrect timing analysis—potentially passing bad designs or failing good ones.
Basic Clock Definition (SDC Format)
Simple Clock
create_clock -name sys_clk -period 10.0 [get_ports clk]
This defines:
- Clock name:
sys_clk - Period: 10.0ns (100 MHz)
- Source: Port named
clk
Equivalent Specifications
# Using frequency instead of period
create_clock -name sys_clk -period 10.0 -waveform {0 5} [get_ports clk]
Where waveform:
First edge (rise) at 0ns
Second edge (fall) at 5ns
Creates 50% duty cycle
Non-50% Duty Cycle
# 40% duty cycle (4ns high, 6ns low)
create_clock -name sys_clk -period 10.0 -waveform {0 4} [get_ports clk]
Multiple Clocks
Independent Clocks
create_clock -name fast_clk -period 5.0 [get_ports clk_fast]
create_clock -name slow_clk -period 20.0 [get_ports clk_slow]
# Declare them unrelated (asynchronous)
set_clock_groups -asynchronous -group {fast_clk} -group {slow_clk}
Related Clocks
create_clock -name main_clk -period 10.0 [get_ports clk]
# Derived clock (divided by 2)
create_generated_clock -name div2_clk \
-source [get_ports clk] \
-divide_by 2 \
[get_pins div/Q]
The STA tool understands div2_clk is synchronous to main_clk and analyzes paths between them correctly.
Clock Characteristics
Clock Period
Defines the fundamental timing window:
create_clock -period 5.0 ...
# Launch edge at 0ns, capture edge at 5ns
Clock Latency
Time for clock to reach sequential elements:
# Source latency (before clock tree)
set_clock_latency -source 0.5 [get_clocks sys_clk]
# Network latency (clock tree delay)
set_clock_latency 1.2 [get_clocks sys_clk]
# Total clock arrival time = source + network latency
Clock Transition
Clock edge slew rate:
set_clock_transition 0.1 [get_clocks sys_clk]
Affects flip-flop setup/hold times (from Liberty characterization).
Virtual Clocks
Purpose: For I/O timing when external clock isn't visible in design
# External system clock (not in design)
create_clock -name ext_clk -period 10.0
# Reference for input/output delays
set_input_delay -clock ext_clk -max 2.0 [get_ports data_in]
set_output_delay -clock ext_clk -max 1.5 [get_ports data_out]
Virtual clocks define timing relationships without an actual clock signal in the design.
Input and Output Delays
Why I/O Delays Matter
Your design doesn't exist in isolation—it interfaces with external devices (other chips, memories, sensors). I/O delays model the timing relationship between your internal clock and external signals.
Input Delays
Concept: External device launches data relative to its clock; your chip captures it relative to your clock.
Input Delay Specification
set_input_delay -clock sys_clk -max 3.0 [get_ports data_in]
set_input_delay -clock sys_clk -min 1.0 [get_ports data_in]
Interpretation:
-max 3.0: In worst case, data arrives 3.0ns after the clock edge-min 1.0: In best case, data arrives 1.0ns after the clock edge
Setup Check with Input Delay
Available time = Clock_period - Input_delay_max - Setup_time
Example:
Period: 10.0ns
Input delay max: 3.0ns
Setup time: 0.1ns
Available for internal logic: 10.0 - 3.0 - 0.1 = 6.9ns
Hold Check with Input Delay
Required delay = Input_delay_min + Hold_time
Example:
Input delay min: 1.0ns
Hold time: 0.05ns
Internal path must be at least: 1.0 + 0.05 = 1.05ns
Output Delays
Concept: Your chip launches data; external device must capture it within its timing budget.
Output Delay Specification
set_output_delay -clock sys_clk -max 2.5 [get_ports data_out]
set_output_delay -clock sys_clk -min 0.5 [get_ports data_out]
Interpretation:
-max 2.5: External device needs data stable 2.5ns before its clock edge-min 0.5: External device needs data stable 0.5ns after its clock edge
Setup Check with Output Delay
Available time = Clock_period - Output_delay_max
Example:
Period: 10.0ns
Output delay max: 2.5ns
Internal logic budget: 10.0 - 2.5 = 7.5ns
Practical I/O Timing Example
System Architecture
External Chip → [data_in] → Your Chip → [data_out] → External Memory
(Tco=2ns) (Tsu=1.5ns)
Constraints
# Input from external chip
# Worst case: External Tco = 2ns, board trace = 1ns
set_input_delay -clock sys_clk -max 3.0 [get_ports data_in]
# Best case: Tco = 1ns, trace = 0.5ns
set_input_delay -clock sys_clk -min 1.5 [get_ports data_in]
# Output to external memory
# Memory setup requirement = 1.5ns, board trace = 1ns
set_output_delay -clock sys_clk -max 2.5 [get_ports data_out]
# Memory hold requirement = 0.5ns, trace = 0.2ns
set_output_delay -clock sys_clk -min 0.7 [get_ports data_out]
This ensures your chip's internal timing accounts for external system requirements.
False Paths: Intentionally Ignoring Timing
What Are False Paths?
False paths are signal paths that exist structurally but will never actually propagate data in real operation. Analyzing them wastes time and creates false timing violations.
Common False Path Scenarios
Scenario 1: Asynchronous Clock Domain Crossing
// Data crosses from clk_a domain to clk_b domain
always @(posedge clk_a) begin
data_a <= input_signal;
end
// Synchronizer in clk_b domain
always @(posedge clk_b) begin
sync1 <= data_a; // Metastable
sync2 <= sync1; // Stable
end
Path from clk_a domain to clk_b domain is asynchronous—timing doesn't matter (synchronizer handles metastability).
False Path Declaration
set_false_path -from [get_clocks clk_a] -to [get_clocks clk_b]
Scenario 2: Configuration Registers
// Configuration written once at startup, never during operation
always @(posedge cfg_clk) begin
config_reg <= config_data;
end
// Design uses config_reg, but it's static during operation
always @(posedge sys_clk) begin
result <= data & config_reg;
end
Path from cfg_clk domain to sys_clk domain is false (config_reg doesn't change).
False Path Declaration
set_false_path -from [get_clocks cfg_clk] -to [get_clocks sys_clk]
Scenario 3: Test/Debug Paths
// Debug multiplexer
assign output = debug_mode ? debug_data : normal_data;
If debug_mode is never high in production, the path through debug_data is false.
False Path Declaration
set_false_path -through [get_pins debug_mux/debug_data]
False Path Cautions
Warning: False paths eliminate timing analysis. Use carefully:
- Document why each false path is truly false
- Verify the path won't be used in operation
- Reconsider if design changes might enable the path
Common Mistake: Using false paths to "fix" real timing violations
# BAD: Hiding real timing problem
set_false_path -from launch_ff -to capture_ff
If the path is functionally real, this creates a chip that won't work!
Multicycle Paths: Relaxing Timing Requirements
What Are Multicycle Paths?
Multicycle paths are paths where data intentionally takes multiple clock cycles to propagate. The default single-cycle setup check is too pessimistic.
Multicycle Path Scenarios
Scenario 1: Slow Divider
// 32-bit divider takes 32 cycles
always @(posedge clk) begin
if (start)
busy <= 1;
if (busy) begin
// Division logic (many cycles)
counter <= counter + 1;
if (counter == 31) begin
busy <= 0;
result <= quotient;
end
end
end
always @(posedge clk) begin
if (!busy)
output_reg <= result; // Only captured after 32 cycles
end
Path from divider to output_reg can take 32 cycles.
Multicycle Constraint
set_multicycle_path 32 -setup -from [get_pins divider/*] -to [get_pins output_reg]
set_multicycle_path 31 -hold -from [get_pins divider/*] -to [get_pins output_reg]
Why hold is 31?
Setup checks at cycle N+32, hold checks at cycle N+31 (one cycle before).
Scenario 2: Pipelined Multiplier with Enable
// 3-stage multiplier, only updates every 3 cycles
always @(posedge clk) begin
if (enable) begin
stage1 <= a * b;
stage2 <= stage1;
stage3 <= stage2;
end
end
If enable pulses every 3 cycles, paths can be multicycle.
Multicycle Path Equations
Setup Check
Default: Check at N+1 cycles
Multicycle K: Check at N+K cycles
Available time = K × T_period - T_setup
Hold Check
Default: Check at same edge (N cycles)
Multicycle K: Check at N+(K-1) cycles
This prevents hold check from being too relaxed
Multicycle Path Cautions
Verify Functionality
Ensure the design truly operates over multiple cycles:
- Control logic enforces multicycle operation
- Data stability guaranteed
- No glitches or intermediate updates
Document Thoroughly
Multicycle paths are non-obvious; document:
- Why the path is multicycle
- What control logic enforces it
- Cycle count and reasoning
Clock Uncertainty and Skew
Clock Uncertainty
Clock uncertainty accounts for variations in clock arrival time:
- Jitter: Random cycle-to-cycle variation
- Duty cycle distortion: Non-50% duty cycle errors
- Modeling inaccuracy: Pessimism in clock tree analysis
Specification
set_clock_uncertainty -setup 0.5 [get_clocks sys_clk]
set_clock_uncertainty -hold 0.2 [get_clocks sys_clk]
Impact on Timing
Setup check: Tightens requirement by uncertainty amount
Available time = T_period - T_setup - T_uncertainty
Hold check: Tightens requirement by uncertainty amount
Required time = T_hold + T_uncertainty
Typical Values:
- Low-quality oscillator: 100-500ps uncertainty
- High-quality PLL: 20-100ps uncertainty
- On-chip generated clock: 50-200ps uncertainty
Clock Skew
Clock skew is the difference in clock arrival time between launch and capture flip-flops.
Positive Skew (capture clock arrives later):
Launch FF clock arrives at 1.0ns
Capture FF clock arrives at 1.2ns
Skew = +0.2ns (positive)
Impact:
- Setup: Helps (more time for data)
- Hold: Hurts (less time before next edge)
Negative Skew (capture clock arrives earlier):
Launch FF clock arrives at 1.0ns
Capture FF clock arrives at 0.8ns
Skew = -0.2ns (negative)
Impact:
- Setup: Hurts (less time for data)
- Hold: Helps (more time before next edge)
Common-Path Pessimism Removal (CPPR)
Modern STA tools remove pessimism from using worst-case delays for both launch and capture paths when they share common clock tree segments.
Without CPPR (overly pessimistic):
Launch path: Worst-case delay
Capture path: Worst-case delay
Total pessimism: Sum of two worst cases
With CPPR (realistic):
Common path: Use same delay for both
Unique paths: Use appropriate corner
Result: Less pessimistic, more accurate
Most modern tools enable CPPR by default.
Practical Uncertainty Guidelines
Conservative Approach
# External clock (board-level)
set_clock_uncertainty -setup 0.5 [get_clocks ext_clk]
set_clock_uncertainty -hold 0.3 [get_clocks ext_clk]
# On-chip PLL
set_clock_uncertainty -setup 0.2 [get_clocks pll_clk]
set_clock_uncertainty -hold 0.1 [get_clocks pll_clk]
# Internal generated (divider)
set_clock_uncertainty -setup 0.1 [get_clocks div_clk]
set_clock_uncertainty -hold 0.05 [get_clocks div_clk]
Uncertainty vs. Margin:
- Uncertainty models real variation
- Design margin is separate (target slack)
- Both contribute to robust design
Summary
Static timing analysis fundamentals provide the foundation for timing closure:
- Setup constraints verify data arrives before the clock edge deadline
- Hold constraints ensure data remains stable after the clock edge
- Clock definitions establish the reference for all timing checks
- Input/output delays model external system timing requirements
- False paths eliminate analysis of structurally impossible paths
- Multicycle paths relax timing for intentionally slow operations
- Clock uncertainty and skew account for real-world clock variations
Key concepts you've mastered:
- Setup checks maximum delay (slow corner)
- Hold checks minimum delay (fast corner)
- Setup violations can be fixed by slowing clock; hold violations cannot
- Proper clock definition is critical for accurate analysis
- I/O delays bridge your chip to the external system
- Timing exceptions (false paths, multicycle) must be used carefully
With these fundamentals, you're ready to perform actual timing analysis using OpenSTA in the next module. Understanding these concepts deeply—not just the commands—enables effective timing closure, intelligent optimization, and confident tape-out. Every timing check you'll encounter builds on these foundations.