跨时钟域(CDC)是不同时钟域信号传输,会亚稳态;单 bit 信号用两级触发器同步(打两拍),降低亚稳态概率;多 bit 信号不能直接打拍(会采到中间值),用握手(req/ack)、MUX 同步(控制信号同步后选通)、或异步 FIFO(批量数据);格雷码用于多 bit 计数器跨域(相邻 1 位变化);CDC 要做形式验证(如 Questa CDC)。
本文概述
CDC 是 FPGA 设计核心难点,面试常考:亚稳态、单bit同步、多bit方法、异步FIFO。回答要给原理和选型。
核心要点
亚稳态:触发器输入不满足建立保持时间,输出不确定,需一个时钟周期恢复
单 bit 跨域:两级触发器同步(打两拍),MTBF 足够大;慢到快时钟域直接打拍,快到慢要展宽
多 bit 跨域:不能直接打拍(多位同时变化采到错误值),用握手协议/异步FIFO/格雷码
握手:req(请求)+ ack(应答),慢但可靠,适合少量控制信号
异步 FIFO:批量数据跨域标准方案,写时钟域写,读时钟域读,格雷码指针

面试官考察点
FPGA CDC 核心题。面试官看你是否理解亚稳态和同步方法。重点听:单bit/多bit、异步FIFO、格雷码。
回答思路
讲亚稳态原理,单bit同步,多bit方法对比,异步FIFO,注意事项。
参考回答
亚稳态(Metastability)。
触发器输入数据在时钟沿附近变化(不满足建立/保持时间),输出会进入亚稳态(既非 0 也非 1);
亚稳态持续一段时间后会稳定到 0 或 1(不确定哪个);
亚稳态传播到后续逻辑会导致功能错误;
解决方法:同步器(打拍)给亚稳态足够恢复时间,MTBF(平均无故障时间)足够大。
两级同步器(打两拍):
always @(posedge clk_b) begin
q1 <= data_a; // 第一级,可能亚稳态
q2 <= q1; // 第二级,恢复后稳定
end
q2 是同步后的稳定信号
单 bit 信号同步。
慢时钟→快时钟:直接打两拍即可,快时钟一定能采到慢信号(持续多个快周期);
快时钟→慢时钟:快信号可能只有一个快周期,慢时钟采不到。要先展宽(快域里把脉冲展宽到 > 慢周期),再打两拍;或用握手;
单 bit 控制信号(如 start、enable、rst)用打两拍;
复位信号跨域用异步复位同步释放(不是简单打拍)。
多 bit 信号为什么不能直接打拍。
多 bit 信号各位变化时间不同(走线延迟、逻辑延迟不同);
打拍时可能采到部分位已变、部分位未变的中间状态(如 0111→1000 采到 0011);
这个中间值是错误的,会导致功能错误;
单 bit 只有 0/1 两种状态,打拍后要么是旧值要么是新值,不会出错。
多 bit 跨域方法。
| 方法 | 原理 | 适用 | 开销 |
|---|---|---|---|
| 握手(req/ack) | 请求+应答,确保数据稳定后才采样 | 少量控制/数据 | 中(几个周期延迟) |
| 异步 FIFO | 写域写、读域读,指针用格雷码 | 批量数据流 | 大(RAM+逻辑) |
| 格雷码 | 多 bit 计数器转格雷码(相邻1位变),打拍后不会错 | 计数器、地址 | 小 |
| MUX 同步 | 控制信号同步后选通数据(数据保持不变) | 寄存器配置、慢变数据 | 小 |
| DM 同步器 | 数据+使能,使能同步后采样数据 | 偶尔传输的数据 | 小 |
握手协议。
源时钟域:数据稳定后,拉高 req(请求);
目的时钟域:req 打两拍同步后,采样数据,拉高 ack(应答);
源时钟域:ack 打两拍同步后,拉低 req,可以更新数据;
目的时钟域:检测 req 拉低后,拉低 ack;
完成一次传输,延迟约 4~6 个周期(两个时钟域之和)。
异步 FIFO。
批量数据跨域标准方案,写时钟域写数据,读时钟域读数据;
写指针和读指针用格雷码编码,跨时钟域打两拍(异步 FIFO 就是用格雷码解决多 bit 指针跨域);
空满标志在各自时钟域判断(空在读域,满在写域);
适合连续数据流(如 ADC 采样→DSP 处理);
Xilinx FIFO Generator 可直接生成异步 FIFO。
注意事项。
所有跨时钟域信号都要识别并处理,不能遗漏(CDC 检查工具);
组合逻辑输出不要直接跨域(先寄存器打拍再跨域);
复位跨域用异步复位同步释放(每级时钟域各自同步);
不要在两个时钟域同时写同一个寄存器;
用 CDC 工具(Questa CDC、VC SpyGlass)做形式验证,确保没有未同步的跨域路径。

扫码关注



























