F
Member
FPGA 设计里,只要信号从一个时钟域进入另一个不相关的时钟域,就存在亚稳态风险。CDC 问题往往在仿真中不出现,却在板上偶发,排查成本很高。
一、单比特控制信号:双(多)级同步器。 用两个或以上串联的触发器打拍,给亚稳态留出恢复时间,大幅降低故障概率。注意同步器前不能有组合逻辑,源端信号应先寄存;同步器触发器应在约束或属性中标注(如 Xilinx 的 ASYNC_REG),让工具将其放在一起。
二、脉冲信号: 快时钟域的单周期脉冲,慢时钟域可能采不到。常用做法是在源端把脉冲转换为电平翻转(toggle),同步后在目的端通过边沿检测还原脉冲。
三、多比特数据:不能逐位同步。 各位到达时间不同,会采到错误组合。常见方法有:
1. 握手协议(req/ack):数据保持稳定,只同步控制信号,适合低速率传输。
2. 异步 FIFO:读写指针转换为格雷码后跨域同步,因为格雷码相邻值只变化一位。适合连续数据流。
3. 多比特数据配合同步使能:数据先稳定,再同步一个有效信号。
四、复位也要考虑 CDC。 常用“异步复位、同步释放”,避免复位释放时引起亚稳态。
五、工具支持。 对异步时钟组设置正确的时序约束(如 set_clock_groups),并使用 CDC 检查工具(如 Vivado 的 report_cdc)辅助排查。
讨论问题:
1. 异步 FIFO 的深度应如何根据突发长度和读写时钟比例计算?
2. 你们是否在项目中使用 CDC 静态检查工具?误报多吗?
3. 跨域格雷码指针为什么一般要求 FIFO 深度为 2 的幂?
一、单比特控制信号:双(多)级同步器。 用两个或以上串联的触发器打拍,给亚稳态留出恢复时间,大幅降低故障概率。注意同步器前不能有组合逻辑,源端信号应先寄存;同步器触发器应在约束或属性中标注(如 Xilinx 的 ASYNC_REG),让工具将其放在一起。
二、脉冲信号: 快时钟域的单周期脉冲,慢时钟域可能采不到。常用做法是在源端把脉冲转换为电平翻转(toggle),同步后在目的端通过边沿检测还原脉冲。
三、多比特数据:不能逐位同步。 各位到达时间不同,会采到错误组合。常见方法有:
1. 握手协议(req/ack):数据保持稳定,只同步控制信号,适合低速率传输。
2. 异步 FIFO:读写指针转换为格雷码后跨域同步,因为格雷码相邻值只变化一位。适合连续数据流。
3. 多比特数据配合同步使能:数据先稳定,再同步一个有效信号。
四、复位也要考虑 CDC。 常用“异步复位、同步释放”,避免复位释放时引起亚稳态。
五、工具支持。 对异步时钟组设置正确的时序约束(如 set_clock_groups),并使用 CDC 检查工具(如 Vivado 的 report_cdc)辅助排查。
讨论问题:
1. 异步 FIFO 的深度应如何根据突发长度和读写时钟比例计算?
2. 你们是否在项目中使用 CDC 静态检查工具?误报多吗?
3. 跨域格雷码指针为什么一般要求 FIFO 深度为 2 的幂?
