跨时钟域搬数据时,只按位宽和速率比算 FIFO 深度是最常见的翻车点。最近调一个 200MHz 写、100MHz 读的采集链路,深度算少了,突发一来就丢数,复盘后把计算方法固定了下来,分享一下。
第一,深度先看突发,不看平均速率。公式我用:深度 = 单次突发长度 + 写读速率差 × 突发持续时间 + 安全裕量。平均速率再低,突发窗口内写侧快于读侧的那部分数据必须全部能装下,裕量我一般留 25%以上。
第二,满空标志必须同步,不能直接跨时钟域用。写侧满标志用格雷码同步到读侧判断空,读侧空标志反向同步,格雷码每次只变一位,亚稳态风险可控。直接传二进制计数器,跳变时采样到中间态,满空判断会错乱。
第三,背压要提前,不要等满才停。almost_full 提前一个突发长度触发,写侧停发;等真正满了再停,流水线里在途的数据已经没地方放。读侧同理,almost_empty 提前唤醒,避免读空后重同步。
第四,实测验证别只看仿真。仿真里时钟理想,板上还要用 ILA 抓满标志抖动和突发间隔,连续跑半小时压力流量,确认无溢出计数再算过关。我那次就是仿真全过、板上突发间隔一缩就丢数。
大家算异步 FIFO 深度时,安全裕量一般留多少?有没有遇到过仿真通过、板上突发就溢出的情况?