4. 时钟与复位约束编写
CDC/RDC形式验证工具本身不会“猜”时钟和复位。它依赖SDC约束来建立时钟域模型、复位域模型以及跨域路径的判定边界。约束写得不准,工具要么把真实跨域路径当成同步路径放过,要么把同域路径误判为跨域而制造大量伪违例。因此,时钟与复位约束是CDC/RDC验证的第一道地基。
一、create_clock:定义时钟域的原点
create_clock用于在指定源对象上建立时钟波形,是划分时钟域的依据。CDC验证中,时钟的名字、周期和源点决定了工具如何给每个触发器打“时钟域标签”。
create_clock -name clk_core -period 5.0 [get_ports clk_core]
create_clock -name clk_uart -period 20.0 [get_ports clk_uart]
create_clock -name clk_ddr -period 2.5 -waveform {0 1.25} [get_ports clk_ddr]
要点有三:其一,时钟名必须唯一且语义清晰,建议与RTL中的时钟网络名一致,便于跨域报告定位;其二,周期单位要与工具的时间单位一致,通常为ns;其三,源点应尽量选在时钟进入设计的端口或PLL输出端,而不是随意选一个内部缓冲器,否则时钟域边界会偏移。对于同一物理时钟经不同路径到达的多个点,不要重复创建同名时钟,应通过create_generated_clock描述其派生关系。
二、create_reset:复位域与复位同步的判定基础
RDC验证关注复位信号从一个复位域进入另一个复位域时是否经过同步处理。标准SDC并没有create_reset命令,工程中通常用create_clock为复位建立“伪时钟”约束,或使用工具提供的复位约束命令。常见做法是:
create_clock -name rst_sys_n -period 100 [get_ports rst_sys_n]
create_clock -name rst_aux_n -period 100 [get_ports rst_aux_n]
set_false_path -from [get_ports rst_sys_n] -to [get_ports rst_aux_n]
这里把复位当作周期很长的时钟来建模,目的是让工具识别复位域。周期值本身不参与时序计算,但会影响某些工具对复位脉冲宽度的推断,建议统一设为足够大的值(如100ns)。同时要明确复位的有效极性:低有效复位在约束中应保持信号名带_n后缀,并在工具配置中声明极性,否则复位同步器的判定会反向。
三、时钟分组与频率、相位关系
时钟分组告诉工具哪些时钟之间是同步的、哪些是异步的。CDC验证中,异步时钟组之间的路径才是真正的跨域路径。常用命令是set_clock_groups:
set_clock_groups -asynchronous \
-group {clk_core clk_ddr} \
-group {clk_uart} \
-group {clk_usb}
同一group内的时钟被视为同步,组间为异步。对于同源但频率不同的时钟,如clk_core与clk_ddr由同一PLL分出,应放在同一group,并通过create_generated_clock描述分频/倍频关系,而不是简单设为异步。频率与相位关系直接影响跨域判定:若两个时钟频率成整数倍且相位固定,工具可能将其识别为同步关系,此时跨域路径需要额外的同步器约束才能被正确标记。
-waveform描述。例如-waveform {0 2.5}表示上升沿在0ns、下降沿在2.5ns。若两个时钟上升沿对齐但周期不同,仍属同步关系,不能随意设为异步组。四、生成时钟:PLL与分频器的正确建模
生成时钟用于描述由主时钟派生出的时钟,如PLL输出、分频器输出、时钟门控输出。CDC验证中,生成时钟的源点决定了时钟域的传播路径。
create_generated_clock -name clk_core_div2 \
-source [get_pins u_pll/CLKOUT] \
-divide_by 2 [get_pins u_div/Q]
关键点:-source必须指向生成时钟的驱动源,通常是PLL输出引脚或分频器输入;-divide_by或-multiply_by描述频率关系;若存在相位偏移,用-phase或-edges补充。生成时钟若未正确声明,工具会把分频后的时钟当作独立主时钟,导致跨域路径漏报或误报。
五、虚拟时钟:为外部接口建立参照
虚拟时钟没有物理源点,用于描述外部器件时钟或输入输出延迟的参照。在CDC验证中,虚拟时钟常用于约束芯片边界上的跨域路径:
create_clock -name vclk_ext -period 10.0
set_input_delay -clock vclk_ext 2.0 [get_ports data_in*]
set_output_delay -clock vclk_ext 2.0 [get_ports data_out*]
虚拟时钟本身不驱动内部触发器,但它参与跨域判定:当外部信号进入内部时钟域时,工具会依据虚拟时钟与内部时钟的关系判断是否需要同步器。若虚拟时钟缺失,边界路径可能被当作无时钟路径而跳过检查。
六、约束编写中的常见陷阱
第一,时钟名重复或源点选错。若两个不同物理时钟被赋予同名,工具会合并时钟域,跨域路径被隐藏。第二,生成时钟未声明-source,导致工具把分频时钟当作独立主时钟,跨域判定错误。第三,异步组划分过粗,把本应同步的时钟设为异步,会漏掉真实的同步路径检查;划分过细,则把同步时钟设为异步,产生大量伪跨域违例。第四,复位约束缺失或极性错误,RDC检查会完全失效。第五,虚拟时钟遗漏,芯片边界上的跨域路径不会被识别。
七、验证前的约束自检清单
| 检查项 | 预期结果 | 判断依据 |
|---|---|---|
| 时钟数量 | 与RTL时钟网络数一致 | 工具报告clock list |
| 生成时钟源 | 每个生成时钟有-source | 约束文件审查 |
| 异步组划分 | 组间为真实异步关系 | 时钟树与PLL配置 |
| 复位域 | 每个复位有对应约束 | RDC报告复位域列表 |
| 虚拟时钟 | 外部接口均有参照 | 边界路径检查报告 |
完成上述约束后,CDC/RDC工具才能建立正确的时钟域与复位域模型。后续的跨域路径识别、同步器结构检查、复位同步检查,都建立在这一步的准确性之上。约束越贴近真实时钟结构,验证结果的可信度越高。