FPGA FIFO深度计算

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

首先,一定要理解清楚FIFO的应用场景,这个会直接关系到FIFO深度的计算,如果是面试官抛出的问题,那么有不清楚的地方,就应该进行询问。如果是笔试或者工程中需要计算FIFO深度的话,那么就需要自己考虑清楚。

其次,异步FIFO,读写时钟不同频,那么FIFO主要用于数据缓存,我们选择的FIFO深度应该能够保证在最极端的情况下,仍然不会溢出。因此考虑的前提一般都是写时钟频率大于读时钟频率,但是若写操作是连续的数据流,那么再大的FIFO都无法保证数据不溢出。因此可以认为这种情况下写数据的传输是“突发Burst”的,即写操作并不连续,设计者需要根据满标志控制或者自己来控制写操作的起止。

宏观地,从整个时间域上看,"写数据=读数据",这个条件必须要满足,如果这个大条件不满足的话,用FIFO是没有效果的。但是在发送方"突发"发送数据的时间T内,是很有可能写数据>读数据的,因此FIFO的深度要能够保证,在这段时间T内,如果接收方未能将发送方发送的数据接收完毕的话,剩下的数据都是可以存储在FIFO内部而且不会溢出的,那么在发送方停止发送数据的"空闲时隙"内,接收方可以从容地接收剩下来的数据。

红字部分就是个人认为在FIFO深度计算中,最重要的部分了。接着来看一个例子,这是我看一个网友写时,是他当时遇到的一道笔试题。

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

因为这位网友可能只是简述,因此信息并不完整,我的个人理解是这样的场景,一个异步FIFO,读写频率不同,读写位宽相同。发送发一次Burst突发的数据量为4Kbit,即500Word,在两次Burst突发之间有足够的时间,因此我们只用考虑在发送方Burst发送数据的时间T内,如果接受方没法将数据全部接受,其余数据均可存在FIFO内且不溢出,那么在发送方停止Burst发送数据的时间段内,接收方就可以从容的从FIFO内读取数据。首先发送方Burst发送数据的时间段为 T = 500/100MHz,发送的数据量为 B_send = 500word,而在T这段时间内,接收方能够接受的数据量为B_rec =  T*95MHz = 500 * 95 / 100 word = 475word,因此 B_remain = B_send - B_rec = 500 - 475 = 25 。那么FIFO的深度至少要大于等于25才行。

再看另外一个例子,还是从网上找到的,

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

首先,我们可以认为写操作是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 中去,应该是是可以解决的。

原文地址:https://www.cnblogs.com/yangjun1219/p/5598982.html