FIFO的阈值如何设置

描述

  什么是FIFO?

FIFO是First in First out 的缩写,一般是由寄存器reg或者ram搭起来的,相对于普通存储器而言,FIFO没有地址可操作的地址总线,因而使用比较方便,但是数据只能像水流一样排队进排队出。

  什么情况下使用FIFO?

FIFO一般发生在不同时钟域下数据的交互或者同一时钟域下写快读慢的情况下,就像“蓄水池“一样,让下游来不及处理的数据暂存起来,不会因此而发生数据丢失。当然写时钟数据不能一直是持续的写入,否则再大的fifo迟早也会溢出。写时钟侧数据应是突发写入,在某一段时间内写数据是大于读数据的,此时FIFO的深度要保证这段时间内数据不会溢出。从长时间轴来看写口和读口流量必定是均衡的。从带宽角度来看写带宽是大于读带宽的,FIFO的作用就是完成大带宽到小带宽的转变。

      什么是FIFO的阈值?

FIFO的接口信号一般会有将满prog_full和prog_empty信号,对应afull_cnt将满阈值和aempty_cnt 将空阈值;当FIFO的数据data_count大于afull_cnt 时,将满afull 将会拉高,由于路径上有一定延时(Nxclk)因此必须要提前通知上游模块,不要再给下游模块发数据了,否则FIFO会溢出,不会使用full满信号作为通知上游的反压信号。Prog_empty 信号一般不会使用,使用empty,FIFO非空即读。

寄存器

  FIFO的阈值如何设置?

 1.当FIFO的数据等于afull_cnt时,afull 开始拉高,反压    路径延时M拍到达上游模块Module A,此时FIFO中的数    据拍数为afull_cnt + M

 2.上游模块ModuleA 收到afull信号后开始响应,但是还    会给下游发送路径流水数据N拍

   此时FIFO中的数据为afull_cnt +M +N

 3.为了数据不会溢出,Fifo_depth >= afull_cnt +M        +N ;得到afull_cnt <=Fifo_depth –(M+N)

寄存器

  FIFO的深度如何计算?

  上述而得到的afull_cnt 最大值,没有得到下限值。在没有考虑反压期间下游Module B 需要读出的数据,为了保证FIFO不会被读空。

 这里考虑FIFO是异步(wclk快于rclk)的场景,(M+N)是写时钟wclk域下的时钟周期拍数,而在读时钟rclk域下时钟周期拍数(rclk/wclk)*(M+N);反压期间FIFO需要至少要存有M+N拍数据以防被下游模块读空,导致数据断流(极限情况下rclk=wclk) ;

  FIFO的深度一方面要要能缓存当起反压afull后上游的数据流水;另一方面也要使得当反压撤销后不会被下游读空,Afull_cnt应不小于(M+N)。从而得到fifo_depth >=(M+N)+ (M+N) =2*(M+N)。

  由于异步FIFO通过比较读写指针进行满空判断,但是读写指针属于不同的时钟域,所以在比较之前需要先将读写指针进行同步处理,这样在设计的时候读写指针用了至少两级寄存器同步,同步会消耗至少两个时钟周期,势必会使得判断空或满有所延迟。满判断时并不是真的满,有2个地址不会进行读写,因此在理论计算的fifo的深度上要多加2。通常FIFO深度会留有20%左右的裕量;而且对与异步FIFO而言FIFO的深度只能是2^n

 

如下图所示,如果afull_cnt设的过小假设为5  M+N=15 fifo将会被读空。导致数据断流T->T+15 是起反压期间,写多少,读走多少,data_count 不会变化维持在afull_cnt 上,当撤销反压之后(T+15->T+30) 这段时间不会有数据写入,因此必须使得afull_cnt 大于M+N.

此例,对于异步FIFO而言,fifo深度理论计算至少等于2*15+2 =32 正好是2^n,为了设计的可靠性,一般会预留一定裕量,异步FIFO的深度将会扩大一倍,depth=64;15<=Afull_cnt <64-15=49;这个区间内都是合理的。

寄存器

  FIFO的深度计算公式

1.如果从带宽的角度分析FIFO的深度,则FIFO的深度和写口和读口最大带宽差有关。

带宽计算公式:bw=freq*data_width

一般考虑的场景:空闲----bust-----空闲----bust

深度计算公式:T(bust)*bw(read)+fifo_depth >=T(bust)*bw(write)

且保证空闲时间内slave把FIFO读空:T(空间)*bw(read) >=fifo_dpeth

极端的场景:空闲---bust---bust----空--- (背靠背场景)

深度计算公式:T(bust)*bw(read)+fifo_depth >=2*T(bust)*bw(write)

且保证空闲时间内slave把FIFO读空:T(空闲时间)*bw(read) >=fifo_dpeth

2.FIFO用于缓冲块数据流,一般用在写快读慢时,遵循的规则如下:

{FIFO深度 /(写入速率 - 读出速率)} = {FIFO被填满时间} > {数据包传送时间}= {写入数据量 / 写入速率}

即:保对FIFO写数据时不存在overflow,从FIFO读出数据时不存在underflow

计算公式如下:

fifo_depth = burst_length - burst_length * X/Y * r_clk/w_clk

写时钟频率w_clk,

读时钟频率 r_clk,

写时钟周期里,每B个时钟周期会有A个数据写入FIFO

读时钟周期里,每Y个时钟周期会有X个数据读出FIFO  

      审核编辑:彭静
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分