E
Member
CDC 问题综合器不会报错、仿真也看不出来,一出问题就是偶发死机,排查成本极高。总结下常用处理:
1. 单 bit 慢到快/快到慢:两级寄存器同步器是最常用的。注意打拍的寄存器要加 ASYNC_REG 属性,防止综合器优化掉;两级之间不要插组合逻辑。
2. 多 bit 数据:不要直接打两拍!用异步 FIFO,或者握手加格雷码。直接多 bit 打拍会出现数据错位,这是 CDC 里最常见的低级错误。
3. 复位信号:异步复位、同步释放是标准做法,复位释放也要过同步器,不然复位域交叉一样出亚稳态。
4. 约束写法:同步器路径加 set_max_delay -datapath_only,告诉时序引擎这条路径按最大延迟分析而不是按时钟关系;同时 set_false_path 容易掩盖真问题,慎用。
5. 检查工具:Vivado 的 report_cdc / Questa CDC 跑一遍,能抓出漏网的结构性问题,但工具只能查结构,协议层面的握手错误还得靠 review。
经验:CDC 路径在代码里集中标注,review 时一眼能看到所有跨时钟的地方,比事后补约束靠谱得多。
你们项目里 CDC 是怎么管理的?有没有被亚稳态坑过的案例?
1. 单 bit 慢到快/快到慢:两级寄存器同步器是最常用的。注意打拍的寄存器要加 ASYNC_REG 属性,防止综合器优化掉;两级之间不要插组合逻辑。
2. 多 bit 数据:不要直接打两拍!用异步 FIFO,或者握手加格雷码。直接多 bit 打拍会出现数据错位,这是 CDC 里最常见的低级错误。
3. 复位信号:异步复位、同步释放是标准做法,复位释放也要过同步器,不然复位域交叉一样出亚稳态。
4. 约束写法:同步器路径加 set_max_delay -datapath_only,告诉时序引擎这条路径按最大延迟分析而不是按时钟关系;同时 set_false_path 容易掩盖真问题,慎用。
5. 检查工具:Vivado 的 report_cdc / Questa CDC 跑一遍,能抓出漏网的结构性问题,但工具只能查结构,协议层面的握手错误还得靠 review。
经验:CDC 路径在代码里集中标注,review 时一眼能看到所有跨时钟的地方,比事后补约束靠谱得多。
你们项目里 CDC 是怎么管理的?有没有被亚稳态坑过的案例?
