你问我FIFO有多深?

你问我FIFO有多深?

搜索技术问题,还是得用英文 + Google搜索或Bing国际版搜索。
不是不相信国内老哥们写的博客,而是直接看人家原版文档是真的好。

我们通常需要异步FIFO用作两个不同时钟域的模块之间的数据缓冲,确保不会丢失数据,只有在读速率快,写速率慢的时候,需要使用FIFO才能缓存来不及读取的数据。反之??

通常因为读速率慢于写速率,慢的模块来不及读取的数据要被缓存下来,所以说,FIFO的工作模式应该是,数据突发写入的形式,Bursts。也就是隔一段时间突发的写一组数据。如果连续写入的话,因为读速率慢于写速率,FIFO肯定会写满,FIFO的深度就需要无穷大,才能确保数据不丢失。

我们需要知道,读写频率,突发速率,突发长度进而确定FIFO的最小深度。

上文的意思,已经明确,我们需要的FIFO深度是因为读取速率慢于写入速率而未能读取的数据量。明确了这一点原理,就可以不需要记任何公式,而直接计算任何情况下的传输问题。

image

Case-1:fA > fB 读写之间没有空闲周期

写速率fA = 80MHz

读速率fB = 50MHz

突发长度Burst Length = 120

读写之间没有空闲周期,是连续读写一个突发长度。

Sol:

写一个数据需要的时间 = 1 / 80MHz = 12.5ns

写一个突发需要的时间 = 120 * 12.5ns = 1500ns

读一个数据需要的时间 = 1 / 50MHz = 20ns

每1500ns,120个数据被写入FIFO,但读一个数据需要20ns的时间

可以计算出,1500ns内读出多少个数据,1500 / 20 = 75

剩下的没有读出,就存在FIFO中,则需要120 - 75 = 45

所以这种情况下,需要的FIFO最小深度为45

拿笔在纸上推导下更清楚。

Case-2:fA > fB 在两个连续读写之间有一个周期的延迟

Sol:

这个题目是制造了一些假象,这其实和Case-1的情况是一样的,因为两个连续的读写之间通常都会有延迟。解决方法,如同Case-1。

Case–3:fA > fB读写都有空闲周期(IDLE Cycles)

写速率fA = 80MHz

读速率fB = 50MHz

突发长度Burst Length = 120

两个连续写入之间的空闲周期为 = 1

两个连续读取之间的空闲周期为 = 3

Sol:

两个连续写入之间的空闲周期为1的意思是,每写入一个数据,要等待一个周期,再写入下一个数据。这也可以理解为每两个周期,写入一个数据。

两个连续读取之间的空闲周期为3的意思是,每读取一个数据,要等待三个周期,再读取下一个数据。这也可以理解为每四个周期,读取一个数据。

写一个数据需要的时间 = 2 * (1 / 80MHz) = 25ns

写一个突发需要的时间 = 120 * 25ns = 3000ns

读一个数据需要的时间 = 4 * (1 / 50MHz) = 80ns

每3000ns,120个数据被写入FIFO,但读一个数据需要80ns的时间

可以计算出,3000ns内读出可以多少个数据,3000 / 80 = 37.5

剩下的没有读出,就存在FIFO中,则需要120 - 37.5 = 82.5 约等于 83

所以这种情况下,需要的FIFO最小深度为83

Case-4:fA > fB并给出了读写使能的百分比

写速率fA = 80MHz

读速率fB = 50MHz

突发长度Burst Length = 120

写使能占得百分比为 = 50% = 1 / 2

读使能占得百分比为 = 25% = 1 / 4

Sol:

用你聪明的大脑想一想,这是不是和Case-3也是一模一样呢,写使能占得百分比为50%,即每两个周期写入一个数据。读使能占得百分比为25%,即每四个周期读取一个数据。

Case-5:fA < fB 读写操作无空闲周期(每两个连续读写之间有一个周期延迟)

Sol:

这类题目,因为读取速率大于写入速率,FIFO永远不会被写满,所以FIFO深度为1就够了。

Case-6:fA < fB 读写操作有空闲周期(读写使能占得百分比问题)

写速率fA = 30MHz

读速率fB = 50MHz

突发长度Burst Length = 120

两个连续写入之间的空闲周期为 = 1

两个连续读取之间的空闲周期为 = 3

Sol:

两个连续写入之间的空闲周期为1的意思是,每写入一个数据,要等待一个周期,再写入下一个数据。这也可以理解为每两个周期,写入一个数据。

两个连续读取之间的空闲周期为3的意思是,每读取一个数据,要等待三个周期,再读取下一个数据。这也可以理解为每四个周期,读取一个数据。

写一个数据需要的时间 = 2 * (1 / 30MHz) = 66.667ns

写一个突发需要的时间 = 120 * 66.667ns = 8000ns

读一个数据需要的时间 = 4 * (1 / 50MHz) = 80ns

每8000ns,120个数据被写入FIFO,但读一个数据需要80ns的时间

可以计算出,8000ns内读出可以多少个数据,8000 / 80 = 100

剩下的没有读出,就存在FIFO中,则需要120 - 100 = 20

所以这种情况下,需要的FIFO最小深度为20

Case-7:fA = fB 读写操作无空闲周期(每两个连续读写之间有一个周期延迟)

Sol:

很好理解。

如果读写时钟为同一个时钟,则可以不需要FIFO。

如果读写时钟存在相位差,FIFO深度为1,也是够了。

Case-8:fA = fB 读写操作有空闲周期(读写使能占得百分比问题)

写速率fA = 50MHz

读速率fB = 50MHz

突发长度Burst Length = 120

两个连续写入之间的空闲周期为 = 1

两个连续读取之间的空闲周期为 = 3

Sol:

同样的解题思路。

两个连续写入之间的空闲周期为1的意思是,每写入一个数据,要等待一个周期,再写入下一个数据。这也可以理解为每两个周期,写入一个数据。

两个连续读取之间的空闲周期为3的意思是,每读取一个数据,要等待三个周期,再读取下一个数据。这也可以理解为每四个周期,读取一个数据。

写一个数据需要的时间 = 2 * (1 / 50MHz) = 40ns

写一个突发需要的时间 = 120 * 40ns = 4800ns

读一个数据需要的时间 = 4 * (1 / 50MHz) = 80ns

每4800ns,120个数据被写入FIFO,但读一个数据需要80ns的时间

可以计算出,4800ns内读出可以多少个数据,4800 / 80 = 60

剩下的没有读出,就存在FIFO中,则需要120 - 60 = 60

所以这种情况下,需要的FIFO最小深度为60

Case-9 如果数据速率如下所示

读写速率相等

每100个时钟写入80个数据

每10个时钟读取8个数据

突发长度为160

Sol:

写速率的其他20个周期的位置是随机的。所以就有了下面几种情况。

image

image

为了保证数据的传输不丢失,我们考虑到最坏的情况。

考虑的最坏的情况,就是写数据速率和读数据速率之间的差别最大。即写数据速率最大,读数据速率最小。

写操作最坏得情况是Case-4 ,即两次连续的突发写入,又称“背靠背”的情况。

即为在160个周期内写入160个数据。

读数据速率读出每个数据的时间为 = 8 / 10

所以160个周期读出数据的个数为 160 * (8 * 10) = 128

剩下的没有读出,就存在FIFO中,则需要160 - 128 = 32

所以这种情况下,需要的FIFO最小深度为32。

Case-10:如下所示

写入时钟20MHz

读出时钟40MHz

每1000个时钟周期写入500个数据

每4个时钟周期读出1个数据

读写数据位宽一致。

Sol:

考虑到“背靠背”的情况突发长度则为500 * 2 = 1000

则为每1000个时钟周期写入1000个数据

每4个周期,读取一个数据。

写一个数据需要的时间 = 1 / 20MHz = 50ns

写一个突发需要的时间 = 1000 * 50ns = 50000ns

读一个数据需要的时间 = 4 * (1 / 40MHz) = 100ns

每50000ns,120个数据被写入FIFO,但读一个数据需要100ns的时间

可以计算出,50000ns内读出可以多少个数据,50000 /100 = 500

剩下的没有读出,就存在FIFO中,则需要1000- 500 = 500

所以这种情况下,需要的FIFO最小深度为500

Reference

CALCULATION OF FIFO DEPTH - MADE EASY —— Putta Satish

http://comm.chinaaet.com/adi/blogdetail/37555.html

https://blog.csdn.net/u011412586/article/details/10241585/

参考文献中诸多实例,可以参考点击查看。参考文献的文档关注硅农订阅号,后台回复FIFO Depth Cal即可获得。这份文档的写的太好了,解决所有FIFO深度计算类笔面试题都不再话下。

例子

FIFO深度 /(写入速率 - 读出速率)= FIFO被填满时间 > 数据包传送时间 = 写入数据量 / 写入速率

确保对FIFO写数据时不存在overflow,从FIFO读出数据时不存在underflow。

即:FIFO深度 = (写入速率 - 读出速率) * (写入数据量 / 写入速率)

例:A/D采样率50MHz,dsp读A/D读的速率40MHz,要不丢失地将10万个采样数据送入DSP,在A/D在和DSP之间至少加多大容量(深度)的FIFO才行?

100,000 / 50MHz = 1/500 s = 2ms
(50MHz - 40MHz) * 1/500 = 20k就是FIFO深度。

例子

FIFO深度计算: 写入时钟20MHz,读出时钟40MHz,每1000个时钟周期写入500个数据,每4个时钟周期读出1个数据,读写数据位宽一致。

写时钟频率w_clk,
读时钟频率 r_clk,
写时钟周期里,每B个时钟周期会有A个数据写入FIFO
读时钟周期里,每Y个时钟周期会有X个数据读出FIFO
则,FIFO的最小深度是?

fifo_depth = burst_length - burst_length * X / Y * r_clk / w_clk

首先认为写操作是Burst(突发)进行的,但是写操作的效率并不是100%,而是A/B,因此实际的写速率为Fwr = (A/B)*w_clk。同理,实际的读速率为Frd = (X/Y) * r_clk。

而且这类题也没有约束突发长度场景,正常情况下应该是这样的:

空闲——Burst——空闲——Burst——空闲——Burst

但是在计算时要考虑极端的情况,即“背靠背”的情况。

空闲——Burst——Burst——空闲——Burst——Burst——空闲

这就是”背靠背“的极端情况。

所以这里的burst_length = (A+A) / w_clk

此题得解。

fifo_depth = 1000-1000(1/4)*(40/20) = 500

例子

再来一个例子。

例:一个8bit宽的AFIFO,输入时钟为100MHz,输出时钟为95MHz,设一个package为4Kbit,且两个package之间的发送间距足够大。求AFIFO的深度?

公式:fifo_depth = burst_length - burst_length * (X / Y) * (r_clk/w_clk)

burst_length = 4Kbit/8bit ,有两种结果

其一,根据存储厂商的惯用算法,4Kbit=4000bit,burst_length=500;

其二,用一般二进制算法,4Kbit=4*1024=4096bit,burst_length=512。

因为X和Y的值没有给出,所以默认为1.

其一,fifo_depth = 500 - 500*(95/100)= 25 ,所以fifo_depth最小取值是25 。

其二,fifo_depth = 512 - 512*(95/100)= 25.6 ,所以fifo_depth最小取值是26 。

SDRAM中应用

在SDRAM的应用中,我们通常使用的读写FIFO是突发长度的2倍,比如突发长度为256,那FIFO的深度设置为512,使得FIFO始终保持半满的状态。可以保证数据的传输。

image

image