FIFO深度该怎么计算?

我们今天详细的聊一聊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

FIFO深度该怎么计算?_第1张图片

首先验证是否有解:即写入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)

你可能感兴趣的:(SOC设计)