3. 跨域时序告警分类

跨域时序告警并不是一种单一错误,而是多种结构缺陷在静态时序分析、CDC 检查工具或形式验证中表现出的不同症状。定位跨域问题的第一步,不是立刻改 RTL,而是把告警归入正确的类别。类别判断正确,修复方向、约束写法和验证手段才会正确;类别判断错误,往往会出现“改了同步器但告警仍在”“加了约束却掩盖了真实风险”的情况。

核心思路:先看告警指向的结构对象(单比特、多比特、总线、握手信号、FIFO 指针、复位网络),再看跨域方向(快采慢、慢采快、异步复位释放),最后看工具给出的特征(无同步器、多比特汇聚、协议不完整、指针比较错误、复位释放未同步)。

一、五类典型告警的结构与特征

在 CDC 检查报告中,最常见的告警可以归纳为五类。它们分别对应不同的硬件结构,也对应不同的修复策略。

告警类型 典型结构 工具特征 风险后果 修复方向
同步器缺失 单比特信号直接跨域 No synchronizer / CDC-1 亚稳态传播、随机采样错误 插入两级触发器同步器
多比特跨域 总线、计数器、状态码并行跨域 Multi-bit CDC / convergence 各比特到达时间不一致,采样到非法组合 格雷码、握手、异步 FIFO
握手协议错误 req/ack 跨域但缺少完整握手 Handshake incomplete / protocol 数据丢失、重复采样、死锁 补齐 req/ack 时序与数据保持
异步 FIFO 误用 读写指针、空满判断跨域 FIFO pointer / gray code violation 空满误判、读写冲突、数据覆盖 使用标准异步 FIFO,指针格雷码化
复位跨域 异步复位释放未同步 Reset CDC / recovery-removal 不同触发器退出复位时刻不一致 复位同步器、异步置位同步释放

二、同步器缺失:最基础也最容易被忽略

同步器缺失通常发生在单比特控制信号从源时钟域直接进入目的时钟域,目的域没有两级触发器。工具会报告“no synchronizer”或“CDC-1”。它的特征是:源信号在目的域被直接采样,采样时刻与源信号变化沿无关,因此可能采到亚稳态。

// 错误示例:单比特信号直接跨域
always @(posedge clk_dst) begin
    flag_dst <= flag_src;   // 缺少同步器
end

// 正确示例:两级同步器
reg flag_meta, flag_sync;
always @(posedge clk_dst) begin
    flag_meta <= flag_src;
    flag_sync <= flag_meta;
end

需要注意的是,同步器只能降低亚稳态传播概率,不能保证数据一致性。如果跨域信号是多比特总线,即使每比特都加了同步器,仍然属于多比特跨域问题。

三、多比特跨域:并行采样导致非法组合

多比特跨域的核心风险不是亚稳态本身,而是各比特到达目的域的时间不一致。例如一个 4 位计数器从 0111 变为 1000,四个比特同时变化,但目的域采样时可能采到 0111、1000 之间的中间态,如 1111 或 0000。工具会报告“multi-bit CDC”或“convergence”告警。

常见修复方式有三种:格雷码、握手同步、异步 FIFO。格雷码适合连续变化的计数器,因为相邻值只有一位变化;握手适合低频控制参数;异步 FIFO 适合数据流跨域。

多比特跨域采样风险示意 源时钟域 clk_src data_src[3:0] 0111 → 1000 4 位同时变化 目的时钟域 clk_dst 采样时刻不确定 可能采到 1111 / 0000 非法中间态 修复方案 格雷码 / 握手 / 异步FIFO 保证采样一致性 消除非法组合 采样时刻对比 源数据变化沿: 0111 ──────┐ 1000 目的采样沿: ──┬──────┬──┬────── 若采样沿落在变化窗口内,可能得到 1111 或 0000,导致状态机跳变错误。

四、握手协议错误与异步 FIFO 误用

握手协议错误通常表现为 req/ack 不完整、数据在 req 有效前变化、ack 未同步回源域等。工具会报告“handshake incomplete”或“protocol violation”。典型场景是:源域发出 req 后立即改变数据,而目的域尚未采样;或者目的域返回 ack 后源域立刻撤销 req,导致目的域漏采。

异步 FIFO 误用则集中在读写指针和空满判断上。标准异步 FIFO 要求读写指针使用格雷码跨域,空满判断在各自时钟域完成。如果设计者自己用二进制指针跨域比较,工具会报告“FIFO pointer”或“gray code violation”。常见错误包括:读写指针直接跨域比较、空满标志未同步、FIFO 深度计算错误。

异步 FIFO 误用最危险的后果是“空满误判”:FIFO 实际已满但满标志未置起,导致写覆盖;或 FIFO 实际非空但空标志未撤销,导致读端提前读走无效数据。这类问题在仿真中不一定复现,但在硅后高低温、电压波动时容易暴露。

五、复位跨域:释放时刻不一致

复位跨域的核心问题是异步复位释放未同步。异步复位可以异步置位,但释放必须与目的时钟同步。如果复位释放信号直接跨域,不同触发器可能在不同时钟沿退出复位,导致状态机进入非法状态。工具会报告“reset CDC”或“recovery/removal”告警。

// 复位同步器:异步置位,同步释放
reg rst_meta, rst_sync_n;
always @(posedge clk_dst or negedge rst_n) begin
    if (!rst_n) begin
        rst_meta   <= 1'b0;
        rst_sync_n <= 1'b0;
    end else begin
        rst_meta   <= 1'b1;
        rst_sync_n <= rst_meta;
    end
end

六、案例与复盘:从告警到修复

某设计中,一个 8 位配置寄存器从慢速配置时钟域跨到快速工作时钟域,工具报告“multi-bit CDC”。最初工程师只在每位加了同步器,告警消失但功能仍偶发错误。复盘发现:8 位配置值在源域同时变化,目的域采样时仍可能采到中间组合。最终改为“配置有效标志 + 数据保持”的握手方式:源域先保持数据稳定,再拉高 valid;目的域用两级同步器同步 valid,再用 valid 同步后的上升沿采样数据。这样既消除了多比特跨域,也避免了数据在采样窗口内变化。

排障顺序建议:先看告警类型,再看跨域方向,最后看源域信号是否在目的域采样窗口内变化。对于多比特跨域,不要只加同步器;对于握手协议,不要只看 req 是否同步,还要看 ack 是否同步回源域、数据是否保持到 ack 返回。