单比特脉冲怎么跨时钟域传递?
更新时间:2026-09-21。问题驱动短答页。脉冲同步电路见 脉冲同步,CDC 总论见 跨时钟域处理,亚稳态见 metastability。
一句话回答
两触发器同步器只解决“亚稳态收敛”,不解决“被漏采”:源域一个只有一个快时钟周期宽的脉冲,到了更慢的目的域可能正好落在采样间隙被完全错过。标准做法是脉冲同步器(toggle/pulse synchronizer)——源域每来一个脉冲就把一个 toggle 信号翻转一次,把这个电平送两触发器同步到目的域,再在目的域对同步后的信号做边沿检测,每个翻转还原出一个目的域脉冲。更可靠或要求确认的场景用 req/ack 握手;多比特数据则要靠异步 FIFO 或握手,不能逐位打拍。
toggle 法结构
verilog
// 源域:脉冲 -> 翻转电平
always @(posedge src_clk or negedge src_rst_n)
if (!src_rst_n_t) tgl <= 1'b0;
else if (pulse) tgl <= ~tgl;
// 目的域:两级同步 + 边沿检测
always @(posedge dst_clk or negedge dst_rst_n) begin
if (!dst_rst_n) begin s1<=0; s2<=0; s3<=0; end
else begin s1<=tgl; s2<=s1; s3<=s2; end
end
assign dst_pulse = s2 ^ s3; // 检测到翻转 -> 一个目的域脉冲关键约束
- 脉冲间隔要够大:两次源脉冲之间,toggle 电平必须至少稳定到被目的域采到两次边沿,否则会合并丢失。通常要求源脉冲间隔 ≥ 2 个目的时钟周期(加上亚稳余量),快→慢尤其要注意。
- 只能传“有一个事件”,传电平含义或多比特不适用。
- 复位释放要做同步,避免复位本身跨域,见 异步复位同步释放。
三种单比特方法对比
| 方法 | 适用 | 说明 |
|---|---|---|
| 两拍电平同步 | 稳定电平/控制位 | 只防亚稳,宽电平才不漏 |
| toggle 脉冲同步 | 单周期事件脉冲 | 翻转+同步+边沿检测,注意最小间隔 |
| req/ack 握手 | 要确认/较可靠 | 跨域来回,延迟大但不丢 |
多比特(数据、地址、指针)请用 异步 FIFO(指针走格雷码)或使能 + 握手,切勿逐位打两拍。
常见坑
- 拿两触发器直接同步单周期脉冲,慢域漏脉冲。
- 脉冲来得过密,toggle 来不及被采到,事件被合并。
- 复位跨域未同步,偶发不恢复。
- 用同一套单比特电路传多位总线,各位 skew 导致采到中间值。
总结
两拍同步只保证亚稳态收敛、保证慢域不漏,单比特事件脉冲必须用 toggle 脉冲同步器:源域把脉冲转成电平翻转,经两级同步后在目的域边沿检测还原脉冲,并保证源脉冲间隔足够被慢域采到;需要确认用 req/ack,多比特数据则必须走异步 FIFO 或握手而不是逐位打拍。