同步FIFO和异步FIFO设计
同步FIFO
-
关键端口解读
- push—写入数据指令
- din—写入数据
- full—反馈—FIFO是否满了
- pop—读数据指令
- dout—读出数据
- empty—没有数据
- 其他为辅助信号
-
写波形
- 写波形相对比较稳定的方式—push和din是同步—需要自己维护数据地址,没有地址线
- 写波形相对比较稳定的方式—push和din是同步—需要自己维护数据地址,没有地址线
-
读波形
-
第一种
- pop和dout同步输出—需要用寄存器去搭建内部结构—如果采用sram会出现dout延迟现象
- pop和dout同步输出—需要用寄存器去搭建内部结构—如果采用sram会出现dout延迟现象
-
第二种
- pop和dout存在输出差异,不同步—可以使用sram搭建
- pop和dout存在输出差异,不同步—可以使用sram搭建
-
-
FIFO空满判断
- 在原有的深度对应bit上扩展一位,用于判断rptr和wptr的关系,如果低位相同通过比较最高位,如果最高位不同,则FIFO满而最高位相同则必然是没有满
- 在原有的深度对应bit上扩展一位,用于判断rptr和wptr的关系,如果低位相同通过比较最高位,如果最高位不同,则FIFO满而最高位相同则必然是没有满
-
同步FIFO的深度计算
- 找到写时钟周期在峰值带宽存入的数据个数,然后看在该时段内,读的数据个数为多少,两者相减为深度
- 例如
- clk=100MHZ,A模块每100个时钟周期随机往FIFO写入50个数据;B模块每2个时钟周期从FIFO读取一个数据,问不看到fifo full==1则fifo深度最小需要多少
- 分析
- 峰值为50-99连续输入50个数据
- 峰值写入周期内100个clk中读取25个
- deep = 50 - 25 = 25
- 也有可能出现FIFOdeep = 50
- 50-99输入50个数据,100-149输入50个数据
- 这就导致两个100周期内有100个数据,取出最多只有25+25
- deep = 100-50 = 50
异步FIFO
-
总体框架图—与同步时钟的区别—输入输出拥有不同的时钟
-
注意—这里的addr是二进制编码而wptr是gray码,为何要这样设计?
- 根本原因就在于,我们多bit跨时钟域电路,如果多位同时变化,会有新数据产生,导致跨时钟失败,因此,我们更希望每次变化,只变化一位,然后进行两级寄存(打两拍跨时钟域)。同时需要注意,wptr和rptr必须是寄存器的q端,保证其不是组合逻辑直接输出
-
设计要点—格雷码
-
异步FIFO深度的计算
-
wclk=100MHZ,在cycle 0-95做运算,96-99cycle连续输入4个数据,以后循环。rclk=25MHZ,只要FIFO不空,就可以从FIFO读取数据。问不看到fifo full=1则fifo的深度最小需要多少(假设wptr_gray/rptr_gray用两DFF同步,empty/full是组合逻辑输出)
-
因为存在两级跨时钟域,因此,需要先通过两个rclk进行格雷码同步wclk指针,然后再进行数据读取,如上图所示,其实一个Wclk中只能读取2个数据
-
-
设计关注点
- 异步FIFO主要是要设计格雷码在2N的范围内循环,保证1bit不同即可
- fifo_full是用wclk or rclk domain的信号产生的?
- wclk
- fifo_empty是用wclk or rclk domain的信号产生的?
- rclk
- fifo_empty和fifo_full有效时,是否意味着fifo一定空或满
- 不一定,存在跨时钟域两拍设计