3. 时钟域交叉与同步机制
多时钟SoC中,只要一个信号从时钟域A进入时钟域B,就构成一次时钟域交叉(CDC)。CDC路径的时序验证与普通同步路径有本质区别:普通路径关心建立/保持时间是否满足,而CDC路径关心的是亚稳态是否被充分抑制、数据是否被正确传递、多比特信号是否保持一致性。因此,验证的第一步不是急着跑STA,而是先把所有CDC路径识别出来,判断每条路径属于哪一类同步机制,再针对不同机制施加不同的约束与检查策略。
一、CDC路径的分类与识别
从数据传递方式看,CDC路径可分为三类:单比特控制信号跨域、多比特数据总线跨域、以及需要保证吞吐率的批量数据跨域。单比特信号常用两级触发器同步器;多比特数据若各比特独立同步,会因到达时间不同而产生数据错位,因此必须用异步FIFO或握手协议;而握手协议本身又依赖单比特请求/应答信号的同步。识别CDC路径时,应重点关注:跨域信号是否直接来自组合逻辑、是否经过多路选择、是否存在多位同时变化、以及源端与目的端时钟是否存在相位或频率关系。
二、两级同步器的时序验证要点
两级触发器同步器是最基础的CDC结构。其原理是:第一级触发器采样异步输入时可能进入亚稳态,但在一个目的时钟周期内未能稳定到合法电平的概率随等待时间指数下降,第二级触发器在下一个时钟沿采样时,第一级输出已大概率稳定。验证时需确认三点:同步器链确实存在且级数不少于2;同步器第一级之前没有组合逻辑(否则毛刺会被采样);同步器输出扇出到目的域逻辑时不再经过组合跨域。
在Synopsys工具链中,通常用SpyGlass CDC或VC SpyGlass进行结构检查,用PrimeTime进行CDC约束下的时序分析。典型约束写法如下:
set_clock_groups -asynchronous \
-group {clk_a} \
-group {clk_b}
set_false_path -from [get_clocks clk_a] -to [get_clocks clk_b]
set_false_path -from [get_clocks clk_b] -to [get_clocks clk_a]
# 对同步器第一级设置最大延迟约束,防止亚稳态窗口过大
set_max_delay 0.5 -from [get_pins sync_ff1/D] -to [get_pins sync_ff1/Q]
这里set_clock_groups -asynchronous告诉STA工具两个时钟无固定相位关系,不做跨域建立/保持检查;set_false_path进一步切断跨域路径的时序分析;而set_max_delay则用于约束同步器内部路径,防止第一级触发器D端到Q端的延迟过大导致亚稳态传播窗口变宽。需要注意的是,set_false_path与set_max_delay不能同时作用于同一路径,否则约束冲突。
三、异步FIFO的验证重点
异步FIFO用于多比特数据跨域且需要一定吞吐率的场景。其核心设计是读写指针各自在本地时钟域递增,指针跨域比较时先转换为格雷码,保证每次只有1比特变化,再经两级同步器同步到对方域。验证异步FIFO时,应重点检查:
- 指针编码:读写指针是否采用格雷码,二进制指针直接跨域会导致多位同时变化,同步后产生错误空满判断。
- 空满标志生成:空标志在读时钟域生成,满标志在写时钟域生成,且必须使用同步后的对方指针。若直接用异步指针比较,会产生毛刺和误判。
- 深度与余量:FIFO深度需覆盖写端突发长度与读端响应延迟之和。例如写端以100 MHz突发写入16拍,读端以80 MHz读出,则最坏情况下FIFO中积压数据约为16 - 16×(80/100) = 3.2拍,加上同步器2~3拍延迟,深度至少需6~8拍。
- 复位与指针初始化:读写指针复位值必须一致,否则上电后空满标志错误。
四、握手协议的验证要点
握手协议适用于低频、非连续的数据传递。源端置起req,目的端同步req后采集数据并置起ack,源端同步ack后撤销req,目的端再撤销ack,完成一次完整握手。验证时需关注:
- req/ack必须单比特:多比特握手信号无法用两级同步器安全传递。
- 数据保持时间:数据必须在req有效期间保持稳定,直到ack同步回源端后才能改变。若数据提前变化,目的端可能采到中间态。
- 握手完成检测:验证平台需监测req与ack的完整翻转序列,确认没有死锁或提前撤销。
- 跨域延迟:每次握手至少需要2个目的时钟周期同步req,再加2个源时钟周期同步ack,总延迟约为2×T_b + 2×T_a。若系统对延迟敏感,需评估是否改用异步FIFO。
set_clock_groups -asynchronous约束下确认无意外跨域时序路径;第三步用带CDC检查的仿真或形式验证工具,注入亚稳态模型,确认同步器输出不会导致功能错误。三步缺一不可,仅靠仿真无法覆盖所有亚稳态场景,仅靠静态检查也无法验证功能正确性。
五、三类机制的对比与选择依据
| 机制 | 适用信号 | 吞吐率 | 延迟 | 验证重点 |
|---|---|---|---|---|
| 两级同步器 | 单比特控制/状态 | 低(每2周期1次) | 2个目的时钟周期 | 级数、无组合前级、扇出约束 |
| 异步FIFO | 多比特数据流 | 高(接近满带宽) | 2~3个时钟周期 | 格雷码指针、空满生成、深度余量 |
| 握手协议 | 多比特非连续数据 | 低(每次握手4周期以上) | 2×T_b + 2×T_a | req/ack单比特、数据保持、死锁检测 |
选择依据可归纳为:若信号为单比特且变化不频繁,用两级同步器;若为多比特且需要连续传输,用异步FIFO;若为多比特但传输间隔大、对延迟不敏感,用握手协议。无论哪种机制,验证的核心都是确认亚稳态不会传播到功能逻辑,以及数据在跨域后保持语义正确。在Synopsys流程中,这分别对应结构检查与功能验证两个层面,二者结合才能形成完整的CDC验证闭环。