Verilog99题-FIFO设计

前言

不忘出芯veriloig99题的58-61题是关于FIFO设计,包括同步FIFO,异步FIFO和FIFO最小深度计算等问题。

同步FIFO设计

因为同步 FIFO 的读写速率是相同的,所以 FIFO 的大小设置不必考虑读写速率差和跨时钟域等问题,要简单很多。

在 FIFO 内部,一般使用 dual port RAM 存储数据。双端口 RAM 有两套独立的读写地址,读地址和写地址分别由读指针和写指针来产生:写指针指向下一个数据被写入的地址,读指针指向下一个被读出的数据的地址,通过判断读写指针的相对大小,就可以得到 FIFO 的状态(full / empty)。

还有另外一种方法来产生 full / empty 信号:FIFO 内部维护一个计数器,每次写入一个数据 cnt++,每次读出一个数据 cnt--。这种方法产生 full / empty 很简单:当 cnt == 0,表示 FIFO empty;当 cnt == max,表示 FIFO full。虽然这种方法产生 full / empty 很简单,但是需要额外的计数器,而且计数器的位宽随着 FIFO 的深度增加,不仅占用的资源更多,而且会降低 FIFO 最终可以达到的速度。

所以这里采用第一种方法实现。

思路

调用34题的dual port SRAM来实现。

深度为2n2^n的FIFO,为读、写地址指针多添加一个额外的位。当写指针超过最后的FIFO地址时,写指针将使未使用的MSB(Most Significant Bit的缩写,指最高有效位)递增,同时将其余的位设置为零,如下图所示(FIFO已经回环并翻转指针的MSB位)。

空满状态判别

读指针的操作与此类似,如果两个指针的MSB不同,则意味着写指针已经发生了回环。如果两个指针的MSB相同,则意味着两个指针都回环了相同的次数。

对于深度为2n2^n的FIFO,使用n位指针,其中(n-1)bit是访问整个FIFO存储器缓冲区所需的地址位数,当两个指针(包括MSB)相等时,FIFO为空;当两个指针(MSB除外)相等时,FIFO就会满。

FIFO的深度为8,需要用宽度为4的指针

读写指针的关系就好比A,B两个田径运动员在一环形跑道上赛跑一样,当B运动员领先A并整整超前一圈时,A,B两人的地点相同,此种情况对应于读写指针指向了同一地址,但写指针超前整整一圈,FIFO被写满。和读空标志产生一样,写满标志也是读写指针相同时产生。但是如果地址的宽度和FIFO实际深度所需的宽度相等,某一时刻读写地址相同了,那FIFO是空还是满就难以判断了。所以读写指针需要增加一位来标记写地址是否超前读地址(在系统正确工作的前提下,读地址不可能超前于写地址),比如FIFO的深度为8,如上图所示需要用宽度为4的指针。

Verilog描述&testbench

verilog

testbench

verilog_refrence

参考链接

FIFO 设计笔记

异步FIFO设计

异步FIFO设计

。。。。。。

即将入行的数字IC设计工程师