异步 FIFO 解决两个不同时钟域之间的数据传递:写侧用写时钟、读侧用读时钟,通过格雷码指针同步到对方时钟域来判断空满;关键是指针同步避免亚稳态,不能直接用二进制指针打两拍。
本文概述
跨时钟域(CDC)是 FPGA 高频考点,单 bit 用打两拍/握手,多 bit 数据用异步 FIFO 或 DMUX。面试常考:异步 FIFO 结构、格雷码为什么、空满判断、亚稳态。回答要画出结构并讲清指针同步。
核心要点
跨时钟域三方法:单 bit 打两拍、多 bit 握手、数据帧用异步 FIFO
异步 FIFO 核心是写指针/读指针各自用本地时钟计数,转格雷码后同步到对方时钟域
格雷码每次只变一位,跨时钟域打两拍不会多 bit 同时翻转导致错误判断
空满判断:读指针同步到写时钟域判满,写指针同步到读时钟域判空
亚稳态无法消除,只能用同步器降低概率;复位也要异步复位、同步释放

面试官考察点
这是 CDC 核心题。面试官看你是否理解亚稳态、多 bit 同时翻转的风险,而不是背「用格雷码」三个字。
回答思路
先讲问题本质(多 bit 同时变 + 亚稳态),再讲格雷码怎么解决,最后讲空满判断逻辑。
参考回答
先讲问题本质。跨时钟域传多 bit 信号有两个风险:
亚稳态:信号在对方时钟建立/保持时间内翻转,触发器输出会进入亚稳态,要等一段时间才稳定;
多 bit 同时翻转:二进制指针从 3(011)→4(100),三位同时变。跨时钟域采样时,打两拍后可能采到 000/001/010/100 任意组合——因为每一位在亚稳态窗口内被采样的时机不同,拼出一个不存在的指针值,空满判断就错了。
格雷码为什么解决。格雷码相邻两个数只有 1 bit 变化:
| 十进制 | 二进制 | 格雷码 |
|---|---|---|
| 0 | 000 | 000 |
| 1 | 001 | 001 |
| 2 | 010 | 011 |
| 3 | 011 | 010 |
| 4 | 100 | 110 |
无论哪一位进入亚稳态,打两拍后要么采到旧值、要么采到新值,不会出现「拼错的中间值」。最坏情况是空满判断晚一个周期,不会出错。
异步 FIFO 结构。
写侧:写时钟 wclk 下,写指针 wptr 加一,写数据到双端口 RAM;
读侧:读时钟 rclk 下,读指针 rptr 加一,从 RAM 读数据;
跨时钟域:wptr 转格雷码后,在 rclk 域打两拍同步给读侧判空;rptr 转格雷码后,在 wclk 域打两拍同步给写侧判满;
空满判断:读指针等于写指针=空;写指针比读指针多绕一圈(最高位相反、其余位相同)=满。
几个工程要点。
复位:异步复位、同步释放(asynchronous assert, synchronous deassert),避免复位释放时亚稳态;
RAM 用双端口:写口和读口独立时钟,可以用块 RAM 或分布式 RAM;
深度选 2 的幂:格雷码方便,地址译码也简单;
不是所有 CDC 都要 FIFO:单 bit 控制信号用打两拍,多 bit 但偶发用握手,连续数据流才用 FIFO。

扫码关注





























