4. SDC约束基础
SDC(Synopsys Design Constraints)是STA(静态时序分析)的核心输入语言,它描述了设计者期望的时序意图。在PrimeTime中,SDC约束的质量直接决定了签核结果的准确性与可信度。本章将围绕STA中最核心的约束语法展开,涵盖时钟定义、时钟分组、输入/输出延迟、伪路径与多周期路径,并结合工程案例说明如何从“跑通流程”走向“精准签核”。
4.1 时钟定义:STA的“时间基准”
时钟是STA中所有时序计算的基准。一个不准确的时钟定义会导致所有路径的时序报告失真。时钟定义的核心在于明确时钟源、周期、波形、以及时钟树上的延迟与不确定性。
核心原理
在PrimeTime中,时钟通过 create_clock 命令定义。该命令指定时钟端口或引脚、周期和波形。时钟对象一旦创建,STA工具会自动计算从时钟源到每个触发器的时钟路径延迟(clock latency),并据此计算数据到达时间(data arrival time)与数据要求时间(data required time)。
# 定义主时钟,周期10ns,占空比50%
create_clock -name clk_sys -period 10 -waveform {0 5} [get_ports clk_sys]
# 定义虚拟时钟(用于I/O约束)
create_clock -name vclk -period 5 -waveform {0 2.5}
对于派生时钟(如分频时钟、门控时钟),使用 create_generated_clock 定义其与主时钟的相位关系。派生时钟的源点可以是寄存器输出或单元引脚。
判断方法或操作流程
- 识别时钟源:检查RTL或网表中所有时钟端口、PLL输出、分频器输出。
- 定义主时钟:在时钟源端口创建主时钟,周期与波形必须与芯片规格一致。
- 定义派生时钟:对分频、倍频、门控时钟使用
create_generated_clock,并指定-divide_by、-multiply_by或-edges。 - 设置时钟不确定性:
set_clock_uncertainty用于建模时钟抖动、PLL相位噪声和时钟树偏差(skew)。 - 设置时钟延迟:
set_clock_latency用于预布局阶段估计时钟树延迟,或后布局阶段覆盖实际延迟。
案例拆解
某SoC芯片工作频率为1GHz,PLL输出时钟为1GHz,同时产生一个250MHz的派生时钟用于低速外设。初始约束仅定义了主时钟,未定义派生时钟,导致STA报告中外设路径的时序完全错误。
分析过程:通过 report_clocks 发现只有主时钟存在,外设路径的捕获时钟为“理想时钟”(ideal clock),未建模分频关系。进一步检查RTL,发现分频器为寄存器输出。
修正操作:
create_clock -name clk_pll -period 1 [get_pins pll/clk_out]
create_generated_clock -name clk_periph -source [get_pins pll/clk_out] -divide_by 4 [get_pins div_reg/Q]
结果对比:修正后,外设路径的setup/hold报告恢复正常,且与后仿真结果一致。
4.2 时钟分组:管理异步与互斥时钟
现代SoC包含多个时钟域,不同时钟域之间的路径可能是异步的、互斥的或同步的。时钟分组约束用于告诉STA工具哪些时钟域之间的路径不需要进行时序检查。
核心原理
set_clock_groups 命令定义时钟组之间的关系。主要选项包括:
-asynchronous:时钟之间没有确定的相位关系,路径不需要检查setup/hold。-exclusive:时钟在功能上互斥,不会同时活跃(如MUX选择的不同时钟)。-logically_exclusive:时钟在逻辑上互斥,但物理上可能同时存在。
判断方法或操作流程
- 分析时钟拓扑:识别所有时钟域及其交叉路径。
- 判断时钟关系:通过时钟源、PLL配置、时钟MUX选择信号确定关系。
- 编写分组约束:将异步或互斥时钟放入不同组。
- 验证分组效果:使用
report_clock_groups检查分组结果,并确认交叉路径不再报告violation。
案例拆解
某芯片包含USB 2.0 PHY(480MHz)和DDR控制器(800MHz),两者时钟来自不同PLL,且无同步机制。初始约束未设置时钟分组,导致STA报告大量跨时钟域violation。
分析判断:通过查看时钟树和PLL配置,确认两个时钟源独立,且无相位关系。进一步检查RTL,发现跨时钟域信号均通过异步FIFO或同步器处理。
操作步骤:
set_clock_groups -asynchronous -group {clk_usb} -group {clk_ddr}
结果对比:设置后,跨时钟域violation消失,STA报告仅保留同步路径的检查,运行时间减少约30%。
-exclusive 时钟,务必确认MUX选择信号在功能上确实互斥。若选择信号可能同时有效,应使用 -logically_exclusive 并配合 set_case_analysis 进行验证。
4.3 输入/输出延迟约束:定义边界时序
输入/输出延迟约束描述了芯片外部信号相对于时钟边沿的时序关系。这些约束是STA进行边界路径检查的基础。
核心原理
set_input_delay 定义外部信号到达芯片输入引脚的时间(相对于时钟边沿)。set_output_delay 定义芯片输出信号被外部捕获的时间要求。延迟值可以为正或负,取决于外部器件的时序特性。
# 输入延迟:数据在时钟上升沿前2ns到达
set_input_delay -clock clk_sys -max 2.0 [get_ports data_in]
set_input_delay -clock clk_sys -min 0.5 [get_ports data_in]
# 输出延迟:外部器件在时钟沿后3ns捕获数据
set_output_delay -clock clk_sys -max 3.0 [get_ports data_out]
set_output_delay -clock clk_sys -min 1.0 [get_ports data_out]
判断方法或操作流程
- 获取外部时序参数:从芯片数据手册或接口规范中提取外部器件的setup/hold时间、时钟到输出延迟。
- 计算输入延迟:输入延迟 = 外部时钟到芯片引脚的延迟 + 外部器件时钟到输出延迟 + PCB走线延迟。
- 计算输出延迟:输出延迟 = 外部器件setup时间 + PCB走线延迟(或外部时钟偏移)。
- 区分max/min:max用于setup检查,min用于hold检查。
案例拆解
某芯片与外部ADC接口,ADC时钟频率为100MHz,ADC输出数据在时钟上升沿后5ns有效,且数据保持时间为2ns。PCB走线延迟为0.5ns。
计算过程:
- 输入延迟max = 5 + 0.5 = 5.5ns(数据最晚到达)
- 输入延迟min = 2 + 0.5 = 2.5ns(数据最早到达)
set_input_delay -clock clk_adc -max 5.5 [get_ports adc_data]
set_input_delay -clock clk_adc -min 2.5 [get_ports adc_data]
结果验证:STA报告显示边界路径的setup slack为0.2ns,hold slack为0.1ns,满足签核要求。
4.4 伪路径与多周期路径:时序例外
时序例外用于覆盖默认的单周期setup/hold检查规则,以匹配设计的真实功能需求。
核心原理
set_false_path 指示STA工具完全忽略指定路径的时序检查。适用于:
- 跨时钟域路径(已通过异步FIFO处理)
- 测试逻辑路径(如扫描链)
- 静态配置信号路径
set_multicycle_path 指定路径需要多个时钟周期才能完成数据传输。适用于:
- 慢速外设接口(如SPI、I2C)
- 流水线寄存器之间的长组合逻辑
- 使能信号控制的路径
判断方法或操作流程
- 识别伪路径:检查跨时钟域路径是否已同步,测试逻辑是否仅在测试模式激活。
- 设置伪路径:使用
set_false_path -from [get_clocks clk_a] -to [get_clocks clk_b]或指定具体引脚。 - 识别多周期路径:分析数据通路的逻辑级数和时钟周期,判断是否能在单周期内完成。
- 设置多周期路径:
set_multicycle_path -setup 2 -hold 1 -from [get_pins reg_a/Q] -to [get_pins reg_b/D]。
案例拆解
某芯片的SPI接口时钟为10MHz,数据从SPI接收寄存器到内部AHB总线需要经过多级同步和协议解析逻辑,组合逻辑延迟为85ns,而SPI时钟周期为100ns。
分析判断:默认单周期检查要求数据在100ns内到达,但实际逻辑延迟为85ns,加上时钟偏移和抖动,setup可能违例。
操作步骤:
set_multicycle_path -setup 2 -hold 1 -from [get_clocks clk_spi] -to [get_clocks clk_ahb]
结果对比:设置后,setup检查放宽到200ns,hold检查提前到100ns,路径满足时序要求。
report_timing -exceptions 审查所有例外路径。
4.5 约束验证与签核检查清单
| 检查项 | 命令/方法 | 通过标准 |
|---|---|---|
| 时钟完整性 | report_clocks | 所有时钟源已定义,周期/波形正确 |
| 时钟分组 | report_clock_groups | 异步/互斥时钟已分组 |
| I/O延迟 | report_port -verbose | 所有输入/输出端口已约束 |
| 时序例外 | report_timing -exceptions | 例外路径数量合理,无冗余 |
| 约束冲突 | check_timing | 无未约束路径、无时钟冲突 |
签核前必须运行 check_timing 命令,它会报告所有未约束的路径、悬空时钟、以及不一致的约束。任何warning都需要人工确认,不能直接忽略。
source 命令统一加载,便于维护和复用。