主要是参考这篇博客linkl,从头到尾做了一遍,对部分代码不懂的地方做了注释
1 FIFO是什么
FIFO(first in first out)本质上就是个RAM,可以用作数据缓存,解决数据发送模块和接收模块速度不一致的问题。
2 FIFO设计注意事项
2.1 读空和写满信号如何产生?
读空信号:读地址和写地址相等
写满信号:读地址和写地址相等,但是读地址会比写地址落后一个周期
2.2 如何区分读空和写满信号?
拓展地址位:比如原始地址是3位,则将地址拓展到4位,最高位为判断位。读地址和写地址最高位相同,其余位相同,则为读空;最高位不同,其余位相同,则为写满。
2.3 异步时钟同步问题(亚稳态问题):由于读写时钟属于不同时钟域,需进行同步后才能对地址进行直接比较。
2.3.1 什么是亚稳态?
触发器工作过程中存在数据的建立(setup)和数据的保持(hold)时间,对于使用上升沿触发的触发器来说,建立时间就是在时钟上升沿到来之前,触发器数据端保持稳定的最小时间。而保持时间则是时钟沿到来之后,触发器数据端继续保持稳定的最小时间。统称为setup-hold时间(如图所示)。在这个时间内,输入信号是不允许变化的,否则会导致输出结构不可知,即亚稳态(Metastability)。
2.3.2 异步时钟同步易产生亚稳态
一个信号过渡到另一个时钟域时,如果仅用一个触发器将其锁存,那么采样结果可能是亚稳态。如图2所示
通过双锁存器即打两拍可以缓解时钟同步造成的亚稳态
2.3.3 二进制编码易产生亚稳态
(1)举个例子:假设读地址(假设4位地址,拓展后的)从0111到下一位1000,4位全部发生变化,总共可能出现2^4种情况(0000到1111之间的可能任意值),无判断读空和写满状态。
(2)格雷码解决:由于格雷码仅仅只有一位可以发生变化,因此结果是可以预知的,同时结果也是保守的。保守含义:假设读地址0000,下一位读地址则只有两种情况:正确0001,错