设计FIFO的时候其深度的计算至关重要,深度设置小了有丢数据的风险,太大了又浪费资源。

其实FIFO的深度主要取决于传输时的极端情况。那么我们先了解跟极端情况相关的一个概念:突发传输。

突发传输(burst)

突发(burst)传输是这样定义的:In telecommunication, a burst transmission or data burst is the broadcast of a relatively high-bandwidth transmission over a short period。某个短时间内相对高带宽的数据传输。

 其实突发传输也就是一个又一个的数据包,每一个数据包之间是有时间间隔的。假如模块A不间断地往FIFO中写数据,模块B同样不间断地从FIFO中读数据,不同的是模块A写数据的时钟频率要大于模块B读数据的时钟频率,那么在一段时间内总是有一些数据没来得及被读走,如果系统一直在工作,那么那些没有被读走的数据会越累积越多,那么FIFO的深度需要是无穷大的,因此只有在突发数据传输过程中讨论FIFO深度才是有意义的。

突发长度

一次传递一包数据完成后再去传递下一包数据,一段时间内传递的数据个数称为burst length。比如每100个写周期内写入80个数据,如果输入数据的模式是固定的,那么这里burst length就是80个数据。如果传输模式不是固定的,那就要考了极端情况,也就是所谓的“背靠背”。

背靠背

假设一个异步FIFO,每100个cycle可以写入80个数据,输入数据模式不固定,那么这就意味着这80个数据可以在100个cycle的周期的任意时间写进FIFO里面。极端情况下可以是连续的200个cycle中,两个80个数据是“背靠背”接着输入的:

 

 

 那么这种场景下的burst length就是160个数据了。

FIFO深度计算公式

FIFO的最小深度与突发长度(burst length), 读出率(rd_rate),读写时钟(rd_clk和wr_clk)等因素有关。

在读写时钟相同或者读比写快时,理论上FIFO的最小深度是1即可,但在实际应用中,还需要考虑时钟相位差异、数据位宽、传输效率等因素,并在计算出的最小深度基础上增加适当的余量。一般会选择接近该值的2的幂次方。

 写比读快举例

写数据时钟wr_clk=80MHz,读数据时钟rd_clk=50MHz

每100个写时钟周期就有80个数据写入FIFO

每10个读时钟周期可以有6个数据读出FIFO

分析:这里可能会出现极端情况,即背靠背时burst length为160,rd_rate就是6/10也就是0.6。根据上面的公式计算可得出FIFO深度:

160-160*(50/80)*(6/10)=100

因此FIFO的最小深度为100。

写比读慢举例

写数据时钟wr_clk=80MHz,读数据时钟rd_clk=100MHz

写侧连续写入100个数据包,数据包EOP与SOP之间可能存在Gap气泡,问:为保证数据包SOP/EOP输出连续不间断,存够多少数据后才能开始发送?
分析:此场景为写入一定数据后开始读取FIFO并保证输出连续“不拉断“,则必须满足:读取100个数据期间写入的数据+已缓存数据 ≥100

在读完t = 100*(1/rd_clk)这段时间里, 写入数据个数为:t*wr_clk, 

100 - 100*(1/rd_clk)*wr_clk = 20

即FIFO深度最小应是20,在FIFO写满20个数据后启动读,完整读取SOP/EOP的同时也写入了80数据,保证了读侧不出现”拉断”现象。如此,深度既满足了数据不丢失,也最大化节省了资源。由于FIFO深度只能取2的整数次幂,因此最小深度为:2^5 = 32。