我们今天详细的聊一聊fifo深度该如何计算;
数据突发长度(burst_lenth):
在讲解如何去计算FIFO深度之前,我们来理解一个术语burst length,如果你已经了解了可以跳过,要理解数据的突发长度,首先我们来考虑一种场景,加入模块A不间断的往FIFO中写数据,模块B同样不间断的从FIFO中读数据,不同的是模块A写数据的时钟频率要大于模块B读数据的时钟频率,那么在一段时间内总是有一些数据没来得及被读走,如果系统一直在工作,那么哪些没有被读走的数据会累积越来越多,那么FIFO的深度需要是无穷大的,因此只有在突发数据传输过程中讨论FIFO深度才是有意义的,也就是说我们一次传递一包数据完成后再传递下一包数据,我们把一段时间内传递的数据个数称为burst length。
我们知道burst length后,通过上述讨论我们大概就知道FIFO的最小深度与burst rate,burst size,read and write frequency等因素有关,要确定FIFO的深度,关键在于计算处在突发读写这段时间内有多少个数据没有被读走,也就是说FIFO的最小深度就等于没有被读走的数据个数。
其实在一些ASIC论坛中,很多前辈就给出过FIFO深度计算公式,但是当时看到公式时不是太理解它是怎么来的,为了让大家更好的理解FIFO size的计算过程,这里在不套用计算公式的前提下来逐步计算不同场景FIFO深度,当然在本文的最后会给出FIFO深度的计算公式,只想套用公式的同学可以直接移步到本文末尾。
在讨论之前我们假定模块A向FIFO写数据的时钟频率为Fa,模块B从FIFO读数据的时钟频率为Fb
场景1:Fa > Fb with no idle cycle in both write and read
假设:
写数据频率Fa = 80Mhz
读数据频率Fb = 50Mhz
突发长度 number of data to be transferred =120
在突发传输过程中,数据都是连续读写的
那么:
写一个数据所需要的时间 = 1/80Mhz = 12.5ns
突发传输中,写完所有数据所需要的时间 = 120*12.5ns = 1500ns
读一个数据所需要的时间 = 1/50Mhz = 20ns
所以在1500ns时间内能够读走的数据个数 = 1500ns/20ns = 75个
即,在1500ns内还没有被读走的数据个数 = 120-75 = 45个
因此FIFO的最小深度为45
场景2:Fa > Fb with two clock cycle delay between two successive read and write
场景2在场景1的基础上增加了一个假设,即读比写慢两拍,这种假设是真正存在的,在异步FIFO的设计中,我们需要去判断FIFO的空/满来保证逻辑的正确性,判断空满标志需要去比较读写指针,而读指针与写指针处在不同的时钟域中,我们需要采用gray code和两级同步器去降低亚稳态的概率,而两级同步必然会导致空满标志位的判断延迟2个cycle,对于empty标志位来说,将写指针同步到读时钟域至少需要花费2个时钟,而在同步的过程中有可能还有新的数据写入,因此同步后的写指针一定小于或者等于当前真实的写指针,所以此时判断不一定是真的empty;同理,对于full 标志位来说,将读指针同步到读时钟域至少要花费2个时钟,而在同步这段时间内有可能还会读走新的数据,因此同步后的读指针一定小于或者等于当前真实的读指针,所以此时判断并不一定是真的full;
通过上述讨论可以知道场景2的FIFO最小深度应该比场景1的FIFO最小深度45略大。
场景3:Fa > Fb with idle cycles in both write and read
假设:
写数据时钟 Fa = 80Mhz
读数据时钟 Fb = 50Mhz
突发长度 = number of data to be transferred = 120
每隔1个cycle写一次
每隔3个cycle读一次
那么:
每隔一个cycle写一次,意味着2个cycle才能写一个数据
每隔3个cycle读一次,意味着每4个cycle才能读一个数据
写一个数据需要花费的时间 = 2 * 1/80Mhz = 25ns
突发传输写完所有数据需要的时间 = 120 * 25ns = 3000ns
读一个数据需要的时间为4*1/50Mhz = 80ns
所以在3000ns时间内能被读走的数据有3000/80=37.5个
因此还有120-37.5=82.5个数据没有被读走
故,FIFO的最小深度为83
场景4:Fa > Fb with duty cycle given for wr_enb and rd_enb
假设:
写数据时钟频率 Fa = 80Mhz
读数据时钟频率 Fb = 50Mhz
突发长度 - number of data to be transferred = 120
写使能信号占整个burst 时间比重为1/2
读使能信号占整个burst时间比重为1/4
那么:
虽然场景3和4描述不一致,但是情形是一样的,因此FIFO的最小深度也为83
场景5:Fa < Fb with no idle cycles in both write and read
假设:
写数据时钟 Fa = 40Mhz
读数据时钟 Fb = 50Mhz
突发长度 = number of data to be transferred = 120
那么:
由于读数据比写数据要快,因此FIFO只起到跨时钟域的作用,FIFO的最小深度为1即可
场景6:Fa < Fb with idle cycle in both write and read
假设:
写数据时钟频率 Fa = 40Mhz
读数据时钟频率 Fb = 50Mhz
突发长度 number of data to be transferred = 120
每隔一个cycle 写一次
每隔3个cycle读一次
那么:
每隔一个cycle写一次,意味着2个cycle才能写一个数据
每隔3个cycle读一次,意味着4个cycle才能读一个数据
写一个数据所需要的时间 = 2* 1/40Mhz = 50ns
突发传输120个数据所需要的时间为 120*50ns = 6000ns
读一个数据所需要的时间 = 4* 1/50Mhz = 80ns
所以在6000ns内能够读出的数据个数为 6000/80 = 75个
因此还有120-75=45个数据没有被读出
故FIFO的最小深度最小需要设置为45
场景7:Fa = Fb with no idle cycle in both write and read
假设:
写数据时钟频率 Fa = 50Mhz
读数据时钟频率 Fb = 50Mhz
突发数据长度 number of data to be transferred = 120
那么:
如果读写时钟同源且没有相位差,那么可以不需要FIFO;
如果读写时钟同源有相位差,FIFO的最小深度为1即可;
场景8:Fa = Fb with idle cycle in both write and read
假设:
写数据时钟频率Fa = 50Mhz
读数据时钟频率Fb = 50Mhz
突发数据长度 number of data to be transferred = 120
每隔1个cycle 写一次
每隔3个cycle读一次
那么:
每隔1个cycle写一次,意味着2个cycle才能写一个数据
每隔3个cycle读一次,意味着4个cycle才能读一个数据
写一个数据需要花费的时间 = 2*1/50Mhz = 40ns
写完突发传输所有数据需要的时间 = 120*40ns = 4800ns
读一个数据需要的时间 = 4*1/50Mhz = 80ns
所以4800ns时间内能读出的数据个数为 4800/80= 60个
因此还有120-60个数据没有被读走
故:FIFO的最小深度为60
场景9:Data rates are given ,read and write random
在前面几种场景中,我们给的条件是每隔几个时钟读写一次,这种周期性读写在实际中很常见,但是在工程中还存在这样一种情形,只给出数据在某一段时间内的读写速率,怎么读怎么写完全随机,这种情况我们需要考虑最坏的一种情况避免数据丢失,在最坏的情形中,读写的速率应该相差最大,也就是说需要找出最大的写速率和最小的读速率。
假设:
写数据时钟频率Fa = 80Mhz
读数据时钟频率Fb = 50Mhz
在写时钟周期内,每100个周期就有40个数据写入FIFO
在读时钟周期内,每10个周期可以有8个数据读出FIFO
首先这里没有直接给出burst 长度,从假设可以知道每100个周期就有40个数据写入FIFO,这里可能就有人会说突发长度就是40个数据,其实不是这样的,因为数据是随机写入FIFO的,我们需要考虑做最坏的情形,即写速率最大的情形,只有如下图背靠背的情形才是写速率最高的情形,burst number 为80
首先验证是否有解:即写入burst数据时间必须大于等于读出burst数据的时间,不然fifo深度必须要开到无穷大。
写入80个数据需要的时间= 1/80Mhz * (80*100/40) = 2500ns
读出80个数据需要的时间= 1/50Mhz * (80*10/8)= 2000ns
由于写入burst数据时间大于读出数据需要的时间,因此有解;
接下来看计算FIFO的最小深度,连续写入80个数据最快需要的时间=80*(1/80Mhz)= 1000ns
从FIFO中读出一个数据至少需要的时间1/50Mhz * ( 10/8) = 25ns
1000ns的时间段内能读出的数据个数= 1000ns/25ns = 40个
因此还有80-40=40个数据没有读出;
故:FIFO的最小深度需要开40
总结:
从上面的分析来看,求FIFO的最小深度主要有一下几点:
1:在求解之前需要验证在写入burst number的数据时间必须大于读出burst数据的时间
2:求FIFO深度要考虑最坏的情形,读写的速率应该相差最大,也就是说要找出最大的写速率和最小的读速率。
3:不管什么场景,要确定FIFO的深度,关键在于看突发写和读的这段时间内有多少个数据没有被读走。
4:由于FIFO空满标志同步器的延迟,在实际应用中需要预留一些余量。
知识的掌握重在理解,而不是去死记硬背公式,这里原文的公式就不贴出来了,感兴趣可以看原文
参考:FIFO的深度你会计算吗? - 知乎 (zhihu.com)