时钟、复位与跨时钟域
按信号形态选择方案
跳转到“按信号形态选择方案”| 跨域对象 | 推荐结构 | 不能只做什么 |
|---|---|---|
| 慢变化单比特电平 | 目的域 2FF/多级同步器 | 直接采样 |
| 窄脉冲 | toggle、脉冲展宽或请求/应答握手 | 直接 2FF,脉冲可能漏掉 |
| 多比特配置值 | 握手并保持数据稳定 | 每一位各打两拍 |
| 连续数据流 | 异步 FIFO | 直接同步整个总线 |
| 计数/指针 | Gray 编码 + 同步 + 保守比较 | 直接传二进制多位计数 |
flowchart LR S["源时钟域"] -->|"写数据 + 写指针"| FIFO["双口存储<br/>Gray 指针同步"] -->|"读数据 + 读指针"| D["目的时钟域"]单比特同步
跳转到“单比特同步”(* ASYNC_REG = "TRUE" *) logic sync_ff1, sync_ff2;
always_ff @(posedge dst_clk) begin sync_ff1 <= async_level; sync_ff2 <= sync_ff1;end第一拍可能亚稳,功能逻辑只使用最后一级;两级之间不要插入组合逻辑或使用第一级去驱动其他功能。源信号应无组合毛刺,并稳定足够长以便目的域采样。该结构降低亚稳传播概率,不保证每次短脉冲都能被捕获,也不提供固定跨域延迟。级数取决于器件、时钟频率、输入变化率和目标 MTBF,不是“永远两拍”即可。
代码是模块内部片段,dst_clk 和 async_level 由所在模块声明。没有复位或初始化时,仿真开始的同步寄存器可为未知值;下游应等待有效采样建立,或使用符合需求的复位结构。RTL 仿真不会模拟真实模拟亚稳过程,仿真通过不能替代 CDC 结构、布局和 MTBF 评估。
脉冲与 Gray 总线的额外条件
跳转到“脉冲与 Gray 总线的额外条件”Toggle 把事件变成状态翻转,但两次事件若在目的域观察到中间状态前就完成翻转,仍会丢失。脉冲展宽也必须结合目的时钟周期与相位安排;不能把表中的结构名称当成“任意事件速率都安全”的保证。需要逐事件无损传输时,应有能限制发送速率的握手或队列。
例如 Vivado 2020.2 的 XPM_CDC_PULSE要求从前一源脉冲下降沿到下一源脉冲上升沿,至少间隔 2 × max(Tsrc, Tdst)。启用复位时还有两域复位同时有效的时长要求;复位期间不能把输出当作有效事件。这个数值属于该宏,不能直接套到所有 toggle 或脉冲同步器。
Gray 编码只有在源端相邻有效状态确实只改变一位、发送值已寄存、位间传播偏斜受控时,才具有预期的跨域性质。不能先将任意跳变的二进制计数变成 Gray,就假定所有位能独立同步;也不能忽略 FIFO 两侧的复位和 full/empty 协议。对应的最大延迟与偏斜约束见 XDC 约束与时序收敛。
复位策略
跳转到“复位策略”同步复位和异步复位都可以正确使用:
- 同步复位便于时序分析,但只有时钟运行时生效。
- 异步复位可立即置位,释放时必须同步到各自时钟域,避免不同寄存器在不同边沿退出复位。
- 不必复位每个数据流水寄存器;通常复位控制、状态和
valid,让无效数据由有效标志屏蔽。
异步置位、同步释放示意:
(* ASYNC_REG = "TRUE" *) logic [1:0] rst_pipe;
always_ff @(posedge clk or negedge arst_n) begin if (!arst_n) begin rst_pipe <= 2'b11; end else begin rst_pipe <= {rst_pipe[0], 1'b0}; endend
assign rst = rst_pipe[1];这也是模块内部片段,需声明 clk、低有效外部复位 arst_n 和高有效本域复位输出 rst。arst_n 置低后管线异步进入复位;撤销后,rst 在本域两个上升沿后才拉低。时钟停转时保持复位,每个时钟域应有自己的释放管线。外部脉冲还须满足器件异步控制最小脉宽;同步释放网络仍需满足下游时序要求。
CDC 完成标准
跳转到“CDC 完成标准”- 架构图标出所有时钟、频率、来源和跨域信号。
- 每条跨域信号按形态选择结构,而不是统一“打两拍”。
- 使用 XPM CDC/FIFO 或经过审查的等价实现,高风险异步 FIFO不从零临时编写。
- 运行结构化 CDC 报告,并逐项解释警告。
- Testbench 使用非整数倍频率、随机相位、背压和复位扰动验证边界。