(By Zakk_XLW,verision2)
当异步FIFO读写两端的through-put不同时(平均意义上,clk-domain-crossing,写快于读),会遇到FIFO depth的问题。即FIFO至少深度是多少时才能保证读写流畅不卡顿。尤其同时需要严格保证performance和area,并且缓冲FIFO/buffer在chip中分布较为密集的架构,此问题会很关键甚至成为瓶颈。
当然,如果FIFO在chip里不是critical path,gate count什么的在架构上也不关注,这问题实际上无关紧要,depth合理即可。比如通常的选取值为: D = write_burst_len X (Wclk/Rclk), 其中选择比D大且最接近D值的一个2^N数值即可, 或者直接把(Wclk/Rclk)向上取整,等等。
来看下网上比较完备的一个问题模型
写时钟Wclk, throughput 为平均B个Wclk写入A个数据
读时钟Rclk,throughput为平均Y个Rclk读出X个数据
读写的burst_len同为 BST_LEN
求FIFO的DEPTH?
上述问题所谓corner case实际上是:burst write最大长度连续写(每cycle写一数据)的同时burst read尽可能长地保持0读出,则写和读的差即是fifo depth.
为了便于分析,下面的模型采用趋于一般情况的case:burst write有平均也有集中, burst read始终保持平均throughput。数学模型如下:
蓝线是write,T1时间段内平均写BST_LEN,但从T1到T2间集中再写BST_LEN。此即write path上所谓背靠背(back2back)。其中:
tanA = Wclk*A/B. 此处因子A/B是因为Wclk在T1内并不是100%的有效写,只有A/B是有效的。
tanA1 = Wclk, T1~T2是100%写,没有写间隔。
红线是read, 这个case里面从原点到T2一直保持平均读,所以tanB = Rclk*X/Y
可以得到: T1 = BST_LEN / (tanA) = (BST_len * B)/(Wclk * A)
T2 = BST_LEN / (tanA1) = BST_LEN/Wclk
因此经过写了2个burst_len之后,读出的数据为:
(T1+T2) * tanB = (1+ B/A) *(BST_len/Wclk)*Rclk*(X/Y)
所以此种较为一般的情况下,对于任意1个burst而言,FIFO Depth一个相对一般的表达式为:
1/2 * (2*BST_LEN - (1+ B/A) *(BST_len/Wclk)*Rclk*(X/Y))
= BST_LEN – 1/2 *(1+ B/A) *(BST_LEN/Wclk)*Rclk*(X/Y)
NOTE : (1+ B/A) 为write-factor,(X/Y)为read-factor
回归到前面的最corner case,此时异步FIFO 需要的Depth最大。即2A个clk写2A个数据,且同时2A个clk中读空白最大。此时变化的实际上是上面的write-factor和read-factor:
Write-factor 为:1+ A/A = 2,
Read-factor 严格依赖于具体 case中2A个clk时间段中的最小读数据率,根据实际情况选取即可,此处不深入讨论,直接以一般情况下的X/Y代替
此时FIFO Depth简化为:BST_LEN *(1-(Rclk /Wclk) *(X/Y))
如果读写两边的burst_len不一样,直接在上述计算流程中用各自的burst_len即可。