FIFO深度计算学习记录(汇总)

前言

本来打算整理一下自己的学习笔记,但是前辈们的笔记已经很详细了,所以就直接摘录了,所有来源均已标注。

笔试面试考点:fifo最小深度计算

Source

对于异步FIFO而言,因为读写时钟和读写的位宽可能不一样,从而导致我们在设计异步fifo时需要考虑会不会出现一次写入太多数据,导致出现fifo写满但数据还向fifo输入数据这种情况(此时FIFO写满了数据是没法把数据写进fifo中的,但是数据仍继续输入过来就只能导致数据丢失了)。
当然,讨论fifo最小深度有两个隐含前提,
1)数据输入速率大于读数据速率,注意这里不是FIFO读写速率,而是数据输入与被读的速率,毕竟FIFO只是一个缓存,真正把控数据读写的还是工程师们。
2)FIFO写和读的数据吞吐量相同,即一段时间内FIFO写入与读出的数据要相同。假设FIFO写吞吐量更大一下, 那fifo迟早会有写满的时候,那时候数据仍在输入,就导致数据丢失。
笔试面试中有以下几个考察方式:

1)写时钟频率为100MHz,读时钟频率为200MHz。读写位宽一致。每100个时钟写入60个数据,每10个时钟读出3个数据。
首先,计算读写吞吐量,即单位时钟写入/读出数据量,写入带宽为(60/100)100MHz=60MHz;
读取带宽为(3/10)200MHz。两者相等则可以进行下一步计算,否则写吞吐量大于读则最小深度为无限大,读吞吐量大于写吞吐量,则最小深度为1即可。
何为最小深度?即为在最坏的读写情况下我FIFO都能保证数据不溢出的深度即为最小深度。
这种最坏的情况是“背对背写入”,即100个时钟最后的60个时钟连续写入,下一次的100个时钟前60个时钟连续写入,那这样会连续写入120个数据,而写入这120个数据需要的时间为:120
(1/100MHz)=1200ns。
这段时间读出了多少数据呢?
首先计算1200ns有多少个读时钟,平均每个读时钟读了多少个数据出去。
即1200ns
200MHz*(3/10)=72个数据,则此时FIFO种有120-72=48个数据,这是在最坏情况下的FIFO存留的数据个数,因此这种情况下FIFO的最小深度为48个数据,如果FIFO最小深度比48还小,则会导致读写失衡,FIFO写满了但数据还向FIFO输入。

2)上面针对的是读写位宽相同的情况,先假设写时钟频率为100MHz,读时钟频率为200MHz。写位宽为10bit,读位宽为5bit。每100个时钟写入60个10bit数据,每100个时钟读出x个数据。
2.1)问读写吞吐量一样的时候,x值为多少?
首先是写入带宽(6010/100)100MHz=600bitMHz
读取带宽=600bit
MHz=(x5/100)200MHz,解的x=60。即每100个时钟读出60个5bit数据才能保证读写吞吐量相同。
当然我们也可以认为每100个时钟写入600bit数据,每100个时钟读出300bit数据。同理,写入1200个数据要用120个写时钟,即1200ns。
则1200ns会读出1200ns
200MHz
(300/100)=720个1bit数据
这样FIFO最小深度=1200-720=480个1bit数据。
这样我们得出结论:对于读写不同位宽的,将其转换为1bit即可。

3)A/D采样率为100MHz,读A/D速率为80MHz,要将10万个单bit采样数据送入FPGA,至少需要在A/D和FPGA之间加多大深度的FIFO才能保证数据不丢失?
这里已经告诉我们总的数据量了,10W单bit数据,假设我们最坏的情况就是连续写入10W个数据,
则写一个数据所需时间为: 1/100MHz = 0.0110e-6 s (这里10e-6表示10的负6次方,下同)
写完10万个数据需要时间为: 10e5 * 0.01
10e-6=0.001 s
读一个数据需要时间为: 1/80MHz = 0.012510e-6 s
0.001s内读走的数据为: 0.001/(0.0125
10e-6)=80000;
则在写完10W个数据还有100000-80000 = 20000个数据没有没读走;
因此FIFO的最小深度为20000。

异步FIFO最小深度计算

Source

一、异步FIFO最小深度计算原理
如果数据流连续不断则FIFO深度无论多少,只要读写时钟不同源同频则都会丢数;
FIFO用于缓冲块数据流,一般用在写快读慢时,遵循的规则如下:
{FIFO深度 /(写入速率 - 读出速率)} = {FIFO被填满时间} > {数据包传送时间}= {写入数据量 / 写入速率}
即:确保对FIFO写数据时不存在overflow,从FIFO读出数据时不存在underflow.
例: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深度。
一种错误的算法(我也犯了同样的错误):
100,000 / 40MHZ= 1/400s = 2.50ms
(50M - 400M)1/400 =25K.那么这样进去的数据就不是100K了,而是100K+50M(0.0025-0.002)=125,000bit,错误在时间的计算。

错误的原因是,计算的是读取的时间。但是事实上,读取的最后的时候,没有进行写入,此时已经不需要担心溢出了,所以不能用读取时间来算容量。

求解的思路是构建等式
构建 写入时间等于FIFO写满时间的等式
构建 写入容量等于读取容量和FIFO容量的等式

假设写时钟频率是40MHz,读时钟为25Mhz,在写端最大突发写数据个数为100个数据。

此时,写入时间为T=100/40M。读取的数据量为Cr=25M*T。那么FIFO的最小最小深度为Cf=100-Cr=37.5
核心是 写入数据等于读取数据+FIFO深度

五、异步FIFO最小深度计算实例(2)
1、一个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=41024=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 。

FIFO深度计算

FIFO深度计算

Case3 fa > fb with idle cycles in both write and read
即写时钟频率大于读时钟频率,但在读写的过程中存在空闲周期;
假设:
写数据时钟频率fa=80MHz
读数据时钟频率fb=50MHz
突发长度= number of data to be transferred = 120
连续写入之间的空闲周期为1。
连续读取之间的空闲周期为3。
那么:
两个连续写之间的空闲周期为1个时钟周期。它的意思是,在写入一个数据后,模块A等待一个时钟周期,开始下一个写入。因此,可以理解为每两个时钟周期,一个数据被写入;
两个连续读取之间的空闲周期为3个时钟周期。即读取一个数据后,B模块等待3个时钟周期,开始下一次读取。因此,我们可以理解,每四个时钟周期,读取一个数据;
写一个数据所需要的时间 = 21/80MHz = 25ns
突发传输中,写完所有数据所需要的时间 = 120
25ns = 3000ns
读一个数据所需要的时间 = 4*1/50MHz = 80ns
所以写完所有的突发传输数据需要花费3000ns
在3000ns内能够读走的数据个数 = 3000ns/80ns = 37.5
所以在3000ns内还没有被读走的数据个数 = 120-37.5 = 82.5
因此FIFO的最小深度为83

Case5 fA < fB with no idle cycles in both write and read ( the delay between two consecutive writes and reads is one clock cycle)
即写时钟频率小于读时钟频率,且读写过程中没有空闲周期;
假设:
写数据时钟频率fa=30MHz
读数据时钟频率fb=50MHz
突发长度= number of data to be transferred = 120
在突发传输过程中,数据都是连续读写的
那么:
由于读数据比写数据要快,这种情况下永远也不会发生数据丢失的,因此FIFO只起到过时钟域的作用,FIFO的最小深度为1即可;

Case6 fa < fb with idle cycles in both write and read(duty cycles of wr_enb and rd_enb can also be given in these type of questions).
即写时钟频率小于读时钟频率,给定wr_enb和rd_enb的占空比;
假设:
写数据时钟频率fa=40MHz
读数据时钟频率fb=50MHz
突发长度= number of data to be transferred = 120
连续写入之间的空闲周期为1。
连续读取之间的空闲周期为3。
那么:
两个连续写之间的空闲周期为1个时钟周期。它的意思是,在写入一个数据后,模块A等待一个时钟周期,开始下一个写入。因此,可以理解为每两个时钟周期,一个数据被写入;
两个连续读取之间的空闲周期为3个时钟周期。即读取一个数据后,B模块等待3个时钟周期,开始下一次读取。因此,我们可以理解,每四个时钟周期,读取一个数据;
写一个数据所需要的时间 = 21/40MHz = 50ns
突发传输中,写完所有数据所需要的时间 = 120
50ns = 6000ns
读一个数据所需要的时间 = 4*1/50MHz = 80ns
所以写完所有的突发传输数据需要花费6000ns
在6000ns内能够读走的数据个数 = 6000ns/80ns = 75
所以在6000ns内还没有被读走的数据个数 = 120-75 = 45
因此FIFO的最小深度为45

Case7 fA = fB with no idle cycles in both write and read ( the delay between two consecutive writes and reads is one clock cycle).
即写时钟频率等于读时钟频率,且读写过程中没有空闲周期;
假设:
写数据时钟频率fa=50MHz
读数据时钟频率fb=50MHz
突发长度= number of data to be transferred = 120
读和写都没有空闲周期,这意味着突发中的所有项都将以连续的时钟周期写入和读取
那么:
如果clkA和clkB之间没有相位差,则不需要FIFO;
如果clkA和clkB之间存在相位差,深度“1”的FIFO就足够了。

Case8 fA = fB with idle cycles in both write and read (duty cycles of wr_enb and rd_enb can also be given in these type of questions).
即写时钟频率等于读时钟频率,给定wr_enb和rd_enb的占空比;
假设:
写数据时钟频率fa=50MHz
读数据时钟频率fb=50MHz
突发长度= number of data to be transferred = 120
连续写入之间的空闲周期为1。
连续读取之间的空闲周期为3。
那么:
两个连续写之间的空闲周期为1个时钟周期。它的意思是,在写入一个数据后,模块A等待一个时钟周期,开始下一个写入。因此,可以理解为每两个时钟周期,一个数据被写入;
两个连续读取之间的空闲周期为3个时钟周期。即读取一个数据后,B模块等待3个时钟周期,开始下一次读取。因此,我们可以理解,每四个时钟周期,读取一个数据;
写一个数据所需要的时间 = 21/50MHz = 40ns
突发传输中,写完所有数据所需要的时间 = 120
40ns = 4800ns
读一个数据所需要的时间 = 4*1/50MHz = 80ns
所以写完所有的突发传输数据需要花费4800ns
在4800ns内能够读走的数据个数 = 4800ns/80ns = 60
所以在4800ns内还没有被读走的数据个数 = 120-60 = 60
因此FIFO的最小深度为60

Case9 如果数据速率如下所示
在前面几种场景中,我们给的条件都是每隔几个时钟读写一次,这种周期性读写在实际中很常见。但是在工程设计中还存在这样一种情形,只给出数据在一段时间内的读写速率,怎么读写完全随机,这种情况我们需要考虑最坏的一种情况避免数据丢失。
对于最坏的情况,读写之间的数据速率差异应该是最大的。因此,对于写操作,应该考虑最大数据速率,对于读操作,应该考虑最小数据速率。
写数据时钟频率fa=读数据时钟频率fb
在写时钟周期内,每100个周期就有80个数据写入FIFO
在读时钟周期内,每10个周期可以有8个数据读出FIFO
首先这里没有给出数据的突发长度,从假设中可以得出每100个周期就有80个数据写入FIFO,这里可能就有人会说突发长度就是80个数据,其实不是这样的,因为数据是随机写入FIFO的,我们需要考虑做坏的情形,即写速率最大的情形,只有如下图背靠背的情形才是写速率最高的情形,burst length为160;
在读时钟周期内,每10个周期可以有8个数据读出FIFO;即一个周期可以写入 8/10 数据
所以160个时钟读了160*8/10 = 128个数据;
考虑背靠背(20个clk不发数据+80clk发数据+80clk发数据+20clk不发数据的共200个clk)
因此FIFO的最小深度=160 - 128 = 32

总结
从上面分析来看,求FIFO的最小深度主要有以下要点:
在求解之前需要验证一下在允许的最大时间长度内写入的数据量是否等于读出的数据量,保证有解;
求FIFO深度需要考虑最坏的情形,读写的速率应该相差最大,也就是说需要找出最大的写速率和最小的读速率;
不管什么场景,要确定FIFO的深度,关键在于计算出在突发读写这段时间内有多少个数据没有被读走;
由于FIFO空满标志位的判断延迟,在实际应用中需要预留一些余量。
下面我们来推导一下FIFO深度的求解公式,假设:
写时钟周期为clkw
读时钟周期为clkr
在读时钟周期内,每x个周期内可以有y个数据读出FIFO,即读数据的读数率
在写时钟周期内,每m个周期内就有n个数据写入FIFO
背靠背“的情形下是FIFO读写的最坏情形,burst长度 B = 2*n
由上得到:FIFO的最小深度为 B - B * (clkr/clkw) * (y/x)

上面的公式仅适用于背对背的最坏情况,不适用于周期性写入的情况,因为没有乘上,周期性读的相关系数

FIFO的深度计算

Source

写时钟频率w_clk,
读时钟频率r_clk,
写时钟周期里,每B个时钟周期会有A个数据写入FIFO
读时钟周期里,每Y个时钟周期会有X个数据读出FIFO
则,FIFO的最小深度是?
这里的背靠背,可以想象一下在发送端和接收端会有一定的处理之后,才会给FIFO读使能或写使能,所以可以出现平均100个周期写60个数据,也可以出现120个周期写120个数据的极端情况
首先,我们可以认为写操作是Burst突发的。其次,写操作的效率并不是100%的,而是A/B的,因此我们可以认为实际的F_wr = (A/B)*w_clk,同理,实际中F_rd = (X/Y)*r_clk。另外,和第一个例子不同的是,这个题目里面并没有约束Burst突发的场景,在正常情况下,应该是这样的空闲—Burst突发—空闲—Burst突发—空闲—Burst突发。但是我们在计算中,需要考虑最极端的情况,即空闲—Burst突发—Burst突发—空闲—Burst突发—空闲。即传输过程中,可能会出现"背靠背"的情况,那么我们设计的FIFO深度必须能够保正,在"背靠背"的时间段内,如果接收方没法接受所有数据,那么剩余的数据可以被存储在FIFO内部且不会溢出。那么就可以开始计算了。假设"背靠背"时发送的数据 = BL,那么"背靠背"的时间 = BL / w_clk ,注意,这段时间内 F_wr = w_clk 而不是之前提到的(A/B)*w_clk。在这段时间内,接收方可以接受的数据 = (BL / w_clk) * (X/Y)*r_clk ,
剩下的数据量 = BL - ( BL / w_clk ) * (X/Y)*r_clk,那么FIFO的深度至少就要为
" depth = BL - ( BL / w_clk ) * (X/Y)*r_clk "这样的深度了。
将上述公式变换下,得到 depth = BL - BL * (X/Y) * (r_clk/w_clk) 。这个公式就是网上流传的计算FIFO深度的公式,我想应该就是这个推理过程吧。
上述的讨论的一个前提就是FIFO的读写位宽一致,如果这个条件不满足的话,那么FIFO的深度的计算就更加复杂一些,但是我们还是可以把FIFO的读写位宽也折合成一定的因子,带入 实际的F_wr = (A/B)*w_clk 和 F_rd = (X/Y)*r_clk 中去,应该是是可以解决的。

这里对公式的得出介绍了详细的过程

但是在实际应用中,尤其是异步FIFO的应用中,需要使用格雷码计数,这就要求FIFO的深度为2的整数次幂,否则格雷码计数到最大值跳变为0时,将出现多位变化的情况,不符合设计。异步FIFO深度不是2的整数次幂情况下,则可能需要特殊处理,需要使用别的编码方式了。

笔试|面试|FPGA知识点大全系列(9)FIFO深度计算详解

Source

这篇文章中增加了情况10和笔试题,但是并没有说的很清楚,所以这里没有进行引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值