` 立即学习—60天FPGA工程师入门就业项目实战特训营(3月16日开班)
谈谈FIFO阈值的阈值设置及深度计算
1.什么是FIFO 2.什么情况下使用FIFO
3.什么FIFO的阈值
4.FIFO的阈值如何设置
5.FIFO的深度如何计算
6.其他角度了解FIFO深度
1.什么是FIFO
FIFO是First in First out 的缩写,一般是由寄存器reg或者ram搭起来的,相对于普通存储器而言,FIFO没有地址可操作的地址总线,因而使用比较方便,但是数据只能像水流一样排队进排队出。
2.什么情况下使用FIFO
FIFO一般发生在不同时钟域下数据的交互或者同一时钟域下写快读慢的情况下,就像“蓄水池“一样,让下游来不及处理的数据暂存起来,不会因此而发生数据丢失。当然写时钟侧数据不能一直是持续的写入,否则再大的fifo迟早也会溢出。写时钟侧数据应是突发写入,在某一段时间内写数据是大于读数据的,此时FIFO的深度要保证这段时间内数据不会溢出。从长时间轴来看写口和读口流量必定是均衡的。从带宽角度来看写带宽是大于读带宽的,FIFO的作用就是完成大带宽到小带宽的转变。
3.什么FIFO的阈值
FIFO的接口信号一般会有将满prog_full和prog_empty信号,对应afull_cnt将满阈值和aempty_cnt 将空阈值;当FIFO的数据data_count大于afull_cnt 时,将满afull 将会拉高,由于路径上有一定延时(Nxclk)因此必须要提前通知上游模块,不要再给下游模块发数据了,否则FIFO会溢出,不会使用full满信号作为通知上游的反压信号。Prog_empty 信号一般不会使用,使用empty,FIFO非空即读。
4.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)
5.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;afull_cnt >=15
Afull_cnt <64-15=49; 这个区间内都是合理的。
6.其他角度了解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被填满时间} > {数据包传送时间}= {写入数据量 / 写入速率}
即:保对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
了解更多关注微信公众号:
参考博客:
https://blog.csdn.net/icxiaoge/article/details/80555683
https://www.cnblogs.com/aliFPGA/p/9684653.html
https://blog.csdn.net/u011412586/article/details/10241585
`
|