FIFO深度计算

FIFO深度学习

格雷码的轴对称问题。这个我在学格雷码的时候还真没想到。
2,为何用格雷码而非二进制码做CDC。
3,异步FIFO的大致框图。
4,满空信号产生。尤其是满。
5,RDCLK和WRCLK差距较大时,是否会造成multi-bit的问题。
6,接5,是否会造成跳过了full而full+1的状态漏过满。
7,Verilog Coding。

SRAM用于数据的暂时存储,读写地址都由Controller控制,可以随机访问任意地址。FIFO是First in First out的缩写,其读写是有特定顺序的:先进先出。基于“先进先出”这个数据访问顺序的限制,FIFO的功能与控制时序跟SRAM相比是不同的。但是两者均具有缓存的功能。

异步FIFO要点:

  • 读写指针采用格雷码,消除亚稳态
  • 空满标志的生成的方法

给系统中的异步FIFO设定适当的深度,既可以满足系统的性能需求,又可以优化系统的面积和功耗。

异步FIFO的动态参数包括FIFO的饱和度、读写速度、和溢出情况等。他们反映了FIFO运行状态并且对确定FIFO深度具有指导意义。设计者可以根据这些动态参数,分析FIFO深度对性能的影响。

饱和度

  • 某一时刻FIFO中已存储数据的个数相对于FIFO深度的百分比;
  • FIFO的饱和度是瞬时值,反映了当前FIFO中存储单元的使用率;
  • 其值为0表示FIFO中没有数据,值为100表示FIFO已满,存储单元的使用达到饱和;
  • 在FIFO运行过程当中,如果其饱和度一直很低,则表明FIFO的深度值过大,很多存储单元被浪费了;如果频繁出现饱和状态,则表明FIFO的深度值过小,存储单元使用紧张。

写入端和读出端的传输速率
单位时间内向FIFO中写入数据的字节数和从FIFO中读出数据的字节数。

上溢频率和下溢频率
当FIFO已满时,若发送端仍然向FIFO写入数据,则FIFO发生上;反之,当FIFO为空时,接收端从FIFO中读出数据,则发生下溢。

假设FIFO写入端执行32字节的burst写操作,相邻两次burst操作的时间间隔服从泊松分布

FIFO之后的处理模块将FIFO中的数据读出,并通过总线存储到SRAM中供总线上其他模块处理。处理模块的的占用率由总线仲裁器控制控制,采用分时复用策略。

FIFO深度计算
在这里插入图片描述

FIFO常用于缓冲块数据,一般用在写快读慢的情况下,遵循如下规则:
{FIFO深度/(写速率-读出速率)}> {写入数据量/写入速率}。
本质就是:
FIFO被填满的时间 > 数据包传送时间(猝发发送的时间)

假如读写FIFO是同时进行的
构造一模型:
写时钟:wr_clk;且写时钟周期里,每B个时钟周期会有A个数据写入FIFO;
读时钟:r_clk;且读时钟周期里,每Y个时钟周期里会有X个数据读出FIFO。

读写的Busrt_len: 相同,都为Burst_len。

那么FIFO要求的最小深度为?
答:首先,这一题目并不一定是有解的,有解的前提是要求一定时间内(T),写入的数据量要等于读出的数据量,即A/Bwr_clk =X/Yr_clk。

然后,要算出写数据的最大猝发长度burst_length,考虑最坏的情况。比如若题目给出的是每100个时钟有80个数据写入FIFO,那么在背靠背(前20clk不发送数据,80clk发送数据,80clk发送数据,20clk不发送数据)的情况下,burst_length=2*80=160。假如题目中明显给出了数据包的传输方式,比如一个package与另一个package相隔很远,也就是互不影响,不会出现这种背靠背的情况。

最后FIFO的最小深度:fif o_depth =Burst_length - Burst_len * X/Y * r_clk/w_clk
BTW:通常,为了安全起见,都会多留一些depth的余度。
可计算FIFO深度:
fifo_deepth = 160-160*80%=160-128=32。

FIFO的最小深度计算公式:
FiFo_depth =Burst_length - Burst_length * X/Y * r_clk/w_clk
如何在2次幂和非2次幂深度下设计相应的读写指针
为什么需要格雷码做读写指针?

由于异步FIFO是工作在两个不同的时钟域中,如果读写地址在某一时刻从0111到1000转变,恰好写时钟要在这时刻采样读地址,那么得到的只有可能是0000至1111中的任一个值。这个不确定的读地址会导致空满状态判断错误,这就是亚稳态。

亚稳态的出现是不可避免的,如果把二进制地址计数器转换成格雷码然后再采样,而不是直接采样二进制计数器出来的值,那么就能很好的减少亚稳态的发生。

引用格雷码后,相邻数值只有1位发生翻转,1位翻转所引起的亚稳态的概率远远小于几位同时翻转所引起的概率。因此,格雷码能很好的降低亚稳态出现的概率。

注意:
假设FIFO深度为6,如果读写指针继续使用格雷码,那么当前首尾指针所有比特位都不相同。此时,如果从尾部返回首部,则无法实现消除亚稳态的目的。
解决办法:可将地址为5的指针设定为100,此时其与首地址“000”相差一个bit位。与地址为4的指针“110”也相差一个bit位,满足消除亚稳态要求。

并不是一定要用格雷码做读写指针,而是当前深度为2次幂的时候,刚好格雷码满足消除亚稳态的需求;
非2次幂深度情况下,格雷码不再适用,此时的解决方法通常有:
若深度为偶数,可采用最接近的2次幂的格雷码编码,在此基础上修改;
深度为一般数值是,可自行设计一种逻辑电路或查找表,以实现指针每次只跳变一次的功能;
以上方法通常在设计层面较为复杂,若无特定需求,可将FIFO深度设置为2次幂,浪费一些存储空间,来简化控制电路的复杂度。

FIFO中亚稳态的消除
亚稳态不能从根本上消除,但可以采取一定的措施使其对电路造成的影响降低。通常我们用故障间隔平均时间(MTBF,mean time between failures)来衡量亚稳态的影响。MTBF越大则说明亚稳态对电路产生的影响越小,反之亦然。 如当MTBF等于几十年或上百年时,我们就认为它对电路的影响基本上可以忽略。实验结果表明:对于输入为异步信号的电路,其MTBF与从亚稳态状态下恢复的时间长度有着指数的关系:

MTBF = ( e^(Tmet/C2) ) / (C1 × Fclk × Fdata)
Tmet:寄存器从时钟上升沿触发后的时序余量时间;
Fclk:接收时钟域的时钟频率;
Fdata:数据的变化频率
C1/C2:与器件有关的参数,对于用户来说是固定值。

异步FIFO读时钟是写时钟的100倍,或者写是读的100倍会出现什么问题?
分析
该问题主要考察内容为FIFO读写时钟差异过大,而深度又没有足够深的情况下极其容易同时出现满标志和空标志。导致异步FIFO出现问题。
为此XILINX官方FIFO ip核给出如下说明
在这里插入图片描述
当然也会存在很多同学认为的一些问题:

  • 可能会产生虚空和虚满,比如写地址同步到读时钟频率,判断此时读空与否,可能会判断已经读空,但是由于写时钟频率快,此时又写了很多,所以非空,但是只要深度大于200,因为在读时钟域打了2拍,这个就不会对数据安全性产生影响。
  • 格雷码转换是相邻写地址,尽管读时钟2次采样时看到的不是相邻地址,但这个不影响写时钟频率下的格雷码,不会增大亚稳态发生的概率。设计存在的问题可能是,对于FPGA来说,同时产生相差100倍的时钟频率比较困难,一般PLL锁相环输出时钟频率最大最小差值不到一百倍,这样可能最小的频率需要自己进行分频处理,时钟扇出质量不好,有timing问题。
  • 具体内容可以参考这个链接:http://bbs.eetop.cn/thread-613258-2-1.html

异步FIFO的难点在于2个指示信号,即读空和写满。对于空满判断,如果写地址比读地址多了1个FIFO的深度,那么就是写满;如果读地址赶上了写地址(即相等),那么就是读空。在具体设计过程中,会将地址位扩充1位,高位不等其余位相等则为写满,所有位都相等则为读空。但是,在读写地址是否相等判断时,需要转换到同一时钟域,比如写满full信号判断需要转换到写时钟域,读空empty信号判断需要转换到读时钟域,那么就会引出跨时钟域问题。

读写地址属于多比特数据,那么可以提出面试常问问题:跨时钟域的常用方法有哪些?对于单比特数据可以打两拍,降低亚稳态发生概率。对于多比特数据跨时钟域有两种方法,一种是可以通过握手的方式,本质上相当于跨时钟的是单比特的握手指示信号,而握手成功后即可将数据发出;另一种方法是将多比特数据转换成格雷码,然后跨时钟域之后打两拍,因为格雷码的特性是在连续数据上一次只变换1bit,那么在跨时钟域时相当于单比特传输。但是,值得注意的是,应用格雷码跨时钟域时,要求数据连续变化,即连续递增或连续递减,否则在跨时钟域时就不是只有1bit不同了。


版权声明:本文为little_ox原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。