由于平时我们工作中,FIFO都是直接调用IP核,对于FIFO深度选择并没有很在意,而在笔试面试过程中,经常被问及的问题之一就是如何计算FIFO深度。
当读数据的速率小于写数据的速率时,我们需要先将数据缓存下来,那么我们需要开多大的空间缓存这些数据呢?缓存开大了会浪费资源,开小了会丢失数据,如何去计算最小FIFO深度是本文的重点。
本文涵盖了FIFO最小深度计算所有情况:
假如模块A不间断的往FIFO中写数据,模块B同样不间断的从FIFO中读数据,不同的是模块A写数据的时钟频率要大于模块B读数据的时钟频率,那么在一段时间内总是有一些数据没来得及被读走,如果系统一直在工作,那么那些没有被读走的数据会越累积越多,那么FIFO的深度需要是无穷大的;
但是若写操作是连续的数据流,那么再大的FIFO都无法保证数据不溢出。因此可以认为这种情况下写数据的传输是“突发Burst”的,即写操作并不连续;
要确定FIFO的深度,关键在于计算出在突发读写这段时间内有多少个数据没有被读走。即FIFO的最小深度就等于没有被读走的数据个数。
Case1 fa>fb with no idle cycles in both write and read
即写时钟快于读时钟,写和读的过程中没有空闲周期;
假设:
那么:
Case2 fa>fb with two clock cycle delay between two successive read and write
即写时钟频率大于读时钟频率,但在读写的过程中存在空闲周期;
Case2在Case1的基础上增加了一个假设,即读比写慢两拍。这种假设是真正存在的,在异步FIFO设计中,我们需要去判断FIFO的空满来保证逻辑的正确性,判断空满标志需要去比较读写指针,而读指针与写指针处在不同的时钟域中,我们需要采用格雷码和两级同步寄存器去降低亚稳态的概率,而两级同步必然会导致空满标志位的判断至少延迟2个cycle。对于空标志位来说,将写指针同步到读时钟域至少需要花费2个时钟,而在同步这段时间内有可能还会写入新的数据,因此同步后的写指针一定小于或等于(当且仅有同步时间内没有新数据写入的情况下才会等于)当前的写指针,所以此时判断不一定是真空;同理,对于满标志位来说,将读指针同步到读时钟域至少需要花费2个时钟,而在同步这段时间内有可能还会读出新的数据,因此同步后的读指针一定小于或等于当前读指针,所以此时判断并不一定是真满。
通过上述讨论可以知道Case2的FIFO最小深度应该比场景1的FIFO最小深度45略大。
Case3 fa > fb with idle cycles in both write and read
即写时钟频率大于读时钟频率,但在读写的过程中存在空闲周期;
假设:
那么:
Case4 fa > fb with duty cycles given for wr_enb and rd_enb.
即写时钟频率大于读时钟频率,给定wr_enb和rd_enb的占空比;
假设:
那么:
此场景与前一个场景(场景3)没有任何不同,因为在本例中,一个数据项将在2个时钟周期内写入,而一个数据项将在4个时钟周期内读取。
因此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)
即写时钟频率小于读时钟频率,且读写过程中没有空闲周期;
假设:
那么:
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的占空比;
假设:
那么:
Case7 fA = fB with no idle cycles in both write and read ( the delay between two consecutive writes and reads is one clock cycle).
即写时钟频率等于读时钟频率,且读写过程中没有空闲周期;
假设:
那么:
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的占空比;
假设:
那么:
Case9 如果数据速率如下所示
在前面几种场景中,我们给的条件都是每隔几个时钟读写一次,这种周期性读写在实际中很常见。但是在工程设计中还存在这样一种情形,只给出数据在一段时间内的读写速率,怎么读写完全随机,这种情况我们需要考虑最坏的一种情况避免数据丢失。
对于最坏的情况,读写之间的数据速率差异应该是最大的。因此,对于写操作,应该考虑最大数据速率,对于读操作,应该考虑最小数据速率。
以下是一些可能性:
下面是从上图中观察到的情况:
写操作的最大数据速率在上表格中case - 4。(写操作在最小的时间内完成)。因此,考虑case - 4来进行进一步的计算。
首先这里没有给出数据的突发长度,从假设中可以得出每100个周期就有80个数据写入FIFO,这里可能就有人会说突发长度就是80个数据,其实不是这样的,因为数据是随机写入FIFO的,我们需要考虑做坏的情形,即写速率最大的情形,只有如下图背靠背的情形才是写速率最高的情形,burst length为160;
因此FIFO的最小深度=160 - 128 = 32
总结
从上面分析来看,求FIFO的最小深度主要有以下要点:
下面我们来推导一下FIFO深度的求解公式,假设:
由上得到:FIFO的最小深度为 B - B * (clkr/clkw) * (y/x)
参考文献
https://hardwaregeeksblog.files.wordpress.com/2016/12/fifodepthcalculationmadeeasy2.pdf