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*]

虚拟时钟本身不驱动内部触发器,但它参与跨域判定:当外部信号进入内部时钟域时,工具会依据虚拟时钟与内部时钟的关系判断是否需要同步器。若虚拟时钟缺失,边界路径可能被当作无时钟路径而跳过检查。

CDC/RDC 时钟与复位约束关系图 主时钟 clk_core 5.0ns clk_uart 20.0ns 生成时钟 clk_core_div2 PLL / 分频器输出 虚拟时钟 vclk_ext 10.0ns 外部接口参照 复位域 rst_sys_n / rst_aux_n 时钟分组 set_clock_groups Group A: clk_core, clk_ddr Group B: clk_uart Group C: clk_usb 跨域路径判定 组间 → 异步跨域 需同步器检查 组内 → 同步路径 按同步时序检查 复位跨域 → RDC检查 约束编写检查要点 1. 每个时钟源点唯一,命名与RTL一致 2. 生成时钟必须声明 -source 与分频/倍频关系 3. 异步时钟组用 set_clock_groups -asynchronous 明确划分 4. 复位域用伪时钟建模,并声明有效极性 5. 虚拟时钟覆盖外部接口,避免边界路径漏检

六、约束编写中的常见陷阱

第一,时钟名重复或源点选错。若两个不同物理时钟被赋予同名,工具会合并时钟域,跨域路径被隐藏。第二,生成时钟未声明-source,导致工具把分频时钟当作独立主时钟,跨域判定错误。第三,异步组划分过粗,把本应同步的时钟设为异步,会漏掉真实的同步路径检查;划分过细,则把同步时钟设为异步,产生大量伪跨域违例。第四,复位约束缺失或极性错误,RDC检查会完全失效。第五,虚拟时钟遗漏,芯片边界上的跨域路径不会被识别。

约束文件应作为CDC/RDC验证的输入版本管理。每次RTL时钟结构变更后,必须同步更新SDC,并重新运行约束一致性检查,确认工具报告的时钟域数量与设计预期一致。

七、验证前的约束自检清单

检查项预期结果判断依据
时钟数量与RTL时钟网络数一致工具报告clock list
生成时钟源每个生成时钟有-source约束文件审查
异步组划分组间为真实异步关系时钟树与PLL配置
复位域每个复位有对应约束RDC报告复位域列表
虚拟时钟外部接口均有参照边界路径检查报告

完成上述约束后,CDC/RDC工具才能建立正确的时钟域与复位域模型。后续的跨域路径识别、同步器结构检查、复位同步检查,都建立在这一步的准确性之上。约束越贴近真实时钟结构,验证结果的可信度越高。