3. 跨时钟域信号分类与风险建模

在Lattice FPGA多时钟系统里,CDC问题很少以“一个信号跨时钟域”这么简单的形式出现。真正决定风险等级的是信号的语义类型:它承载的是持续电平、一次性事件、并行数值、复位状态,还是带顺序约束的数据流。同一根跨域路径,如果语义不同,失效模式、同步结构和验证方法都会完全不同。因此,在写第一行同步器代码之前,先把跨时钟域信号做分类,并针对每一类建立风险模型,是CDC验证中最省成本的一步。

六类跨时钟域信号的语义与风险画像

按工程实践,可把跨域信号归为六类:单比特控制、多比特数据、脉冲、复位、总线、流式接口。它们的核心区别在于“信息是否依赖多个比特之间的相对关系”以及“事件是否依赖边沿或顺序”。

  • 单比特控制:如使能、模式选择、旁路开关。电平语义,变化缓慢,风险是亚稳态传播和采样时刻不一致,通常用两级触发器同步即可,但必须确认它在目的域只被当作电平使用。
  • 多比特数据:如配置字、阈值、系数。风险是各比特到达目的域的时间不同,采样瞬间可能得到“半新半旧”的混合值,即数据一致性破坏。必须用保持握手、格雷码或异步FIFO保证整体一致。
  • 脉冲:如中断、触发、单次启动。风险是脉冲宽度小于目的时钟周期时被完全漏采,或宽度处于临界时被重复采样。需要脉冲展宽、脉冲同步器或握手转换。
  • 复位:如全局复位、模块软复位。风险是复位释放沿在不同时钟域异步到达,导致部分逻辑先退出复位、部分仍在复位,形成不确定状态。必须做复位同步与释放顺序控制。
  • 总线:如寄存器读写、地址数据复用总线。风险是地址、数据、使能之间的相对时序在跨域后错位,导致写错寄存器或读到无效数据。需要握手或异步桥。
  • 流式接口:如带valid/ready的采样流、视频行数据。风险是背压跨域后握手死锁、数据丢失或重复,以及吞吐不匹配导致的溢出。需要异步FIFO并严格约束满空标志。

风险建模:从失效模式反推同步结构

风险建模的关键不是给信号贴标签,而是回答三个问题:信息以什么形式存在、目的域在什么时刻读取它、读错时系统会怎样。以多比特数据为例,若源域在clk_a下更新cfg[7:0],目的域clk_b直接采样,即使每个比特都经过两级同步,仍可能在cfg从0x0F变为0x10时采到0x1F或0x00这类非法中间值。这类失效不会报错,却会让状态机进入未定义分支,属于最隐蔽的一类CDC缺陷。

再以脉冲为例,源域clk_a为100MHz,产生一个10ns宽的单周期脉冲,目的域clk_b为25MHz、周期40ns。若直接两级同步,该脉冲在clk_b的采样窗口内可能完全不被捕获,事件永久丢失。正确做法是先把脉冲展宽到至少两个clk_b周期,或改用握手:源域置起请求,目的域同步后回确认,源域收到确认再撤销请求。这样事件既不丢失也不重复。

风险建模必须区分“功能失效”和“时序失效”。功能失效是逻辑语义被破坏,如多比特撕裂、脉冲丢失;时序失效是建立/保持违例导致的亚稳态。前者靠协议和结构解决,后者靠同步器和约束解决,二者不能互相替代。

分类到结构的映射关系

下面的SVG把六类信号、典型失效模式与推荐同步结构放在同一张关系图中,便于在设计中快速对照。图中箭头表示“该类信号应优先考虑的转换路径”,而不是唯一实现。

跨时钟域信号分类 → 失效模式 → 同步结构映射 信号分类 单比特控制 使能 / 模式 / 旁路 多比特数据 配置字 / 阈值 / 系数 脉冲 中断 / 触发 / 启动 复位 全局 / 软复位 总线 寄存器 / 地址数据 流式接口 valid/ready 数据流 典型失效模式 亚稳态传播、采样时刻不一致 目的域误判电平跳变 多比特撕裂:半新半旧混合值 状态机进入非法分支 脉冲漏采或重复采样 事件丢失 / 重复触发 复位释放沿异步到达 部分逻辑先退出复位 地址/数据/使能错位 写错寄存器、读到无效值 背压跨域死锁、溢出/丢数 吞吐不匹配、重复数据 推荐同步结构 两级触发器同步 仅限电平语义 保持握手 / 格雷码 或异步FIFO整体搬运 脉冲展宽 / 脉冲同步器 或请求-确认握手 复位同步器 + 释放顺序 异步置位、同步释放 握手桥 / 异步总线桥 地址数据打包传输 异步FIFO + 格雷码指针 满空标志跨域约束

教学示例:多比特配置字的撕裂风险量化

假设源域clk_a为50MHz,目的域clk_b为33MHz,配置字cfg[7:0]在clk_a下由0x0F切换到0x10,两个值只有bit4不同。若直接跨域采样,目的域在切换窗口附近采到0x1F或0x00的概率取决于两个时钟的相位关系。虽然单次概率不高,但在长时间运行中必然出现。更危险的是,这类错误不会触发任何断言,只会让下游状态机偶发进入非法状态。

用保持握手可以彻底消除该风险:源域更新cfg后拉高req,目的域用两级同步器采样req,确认后一次性锁存cfg并回ack,源域收到ack后才允许下一次更新。这样cfg在目的域始终是完整值。若数据更新频繁且允许短暂延迟,异步FIFO是更自然的选择,但必须保证写指针和读指针都用格雷码跨域,且满空判断留出足够余量。

复位与流式接口的专项风险

复位常被误认为“低风险”,实际上异步复位释放是典型CDC问题。若复位在clk_a域撤销、在clk_b域直接使用,clk_b域触发器可能在释放沿附近进入亚稳态。标准做法是每个时钟域各放一个复位同步器:异步置位、同步释放,保证复位撤销与本地时钟对齐。对于多域系统,还应规定复位释放顺序,例如先释放时钟管理单元,再释放数据通路。

流式接口的风险集中在背压。valid/ready握手跨域时,若ready信号直接跨域组合返回,可能形成跨域组合环,既难约束又易死锁。正确结构是两侧各用异步FIFO,FIFO的满标志在写侧、空标志在读侧,跨域的只有格雷码指针。验证时要重点检查:FIFO深度是否覆盖两个时钟频率差带来的累积偏差、满空标志是否在跨域后仍满足建立保持、以及复位时FIFO指针是否被正确清零。

分类不是目的,而是为了在代码评审和约束文件中形成可检查的条目。建议为每个跨域信号记录:源时钟、目的时钟、语义类型、同步结构、是否允许丢失、是否允许重复、验证用例编号。这张表比任何事后调试都更有价值。

可执行的CDC信号分类检查表

下表可直接用于设计评审,字段按本节分类模型组织。填写时要求每个跨域信号至少占一行,不允许合并。

信号名源时钟目的时钟语义类型同步结构允许丢失允许重复验证用例
cfg_word[7:0]clk_aclk_b多比特数据保持握手否否CDC-01
start_pulseclk_aclk_b脉冲脉冲展宽+同步否否CDC-02
soft_rst_nclk_aclk_b复位复位同步器否否CDC-03
sample_data[15:0]clk_bclk_c流式接口异步FIFO否否CDC-04
mode_selclk_aclk_c单比特控制两级同步否是CDC-05

完成分类后,风险建模的下一步是把每类信号的失效模式转成可观测的验证目标。例如多比特数据要检查“是否出现非法中间值”,脉冲要检查“事件计数是否守恒”,流式接口要检查“写入数量是否等于读出数量”。这些目标可以直接写成断言或记分板规则,使CDC验证从“看波形”升级为“可判定”。