关于异步FIFO

参考http://blog.163.com/jinyun_xie/blog/static/12839081120123692259923/

异步FIFO 在产生写满读空信号的时候,可以有两种解决方式:一,格雷码两级同步触发器同步后地址比较

                                                                                                    二,异步地址比较

异步FIFO设计

FIFO设计的难点 是如何判断空/满标志

在涉及到触发器的电路中,亚稳态无法彻底消除,只能想办法将其发生的概率将到最低。其中的一个方法就是使用格雷码。格雷码在相邻的两个码元之间只由一位变换(二进制码在很多情况下是很多码元在同时变化)。这就会避免计数器与时钟同步的时候发生亚稳态现象。但是格雷码有个缺点就是只能定义2^n的深度,而不能像二进制码那样随意的定义FIFO的深度,因为格雷码必须循环一个2^n,否则就不能保证两个相邻码元之间相差一位的条件,因此也就不是真正的各雷码了。例如,读指针从011变化到100时,所有位都要变化,读指针的每一位在读时钟的作用下,跳变不一致,即产生毛刺。如果写时钟恰好在读指针的变化时刻采样,得到的采样信号可能是000~111中的任何一个,从而导致空/满信号判断错误。由实践可知,同步多个异步输入信号出现亚稳态的概率远远大于同步一个异步信号的概率[3]。解决这一问题的有效方法是采用格雷码。格雷码的主要特点是相邻的两个编码之间只有一位变化。图4是格雷码产生的逻辑框图。在读使能或写使能信号有效、并且空/满标志无效的情况下,读写指针开始累加,进行FIFO读或写操作。二进制码与格雷码的转换是一个“异或”运算:gnext=(bnext>>1)^bnext。格雷码gnext 经寄存器输出格雷码指针ptr。这种方法采用了两组寄存器,虽然面积较大,但是有助于提高系统的工作频率。

第二就是使用冗余的触发器,假设一个触发器发生亚稳态的概率为P,那么两个及联的触发器发生亚稳态的概率就为P的平方。但这回导致延时的增加。亚稳态的发生会使得FIFO出现错误,读/写时钟采样的地址指针会与真实的值之间不同,这就导致写入或读出的地址错误。由于考虑延时的作用,空/满标志的产生并不一定出现在FIFO真的空/满时才出现。可能FIFO还未空/满时就出现了空/满标志。这并没有什么不好,只要保证FIFO不出现overflow or underflow 就OK了。

很多关于FIFO的文章其实讨论的都是空/满标志的不同算法问题。

第一个算法:Clifford E. Cummings的文章中提到的STYLE #1,构造一个指针宽度为N+1,深度为2^N字节的FIFO(为便方比较将格雷码指针转换为二进制指针)。当指针的二进制码中最高位不一致而其它N位都相等时,FIFO为满(在Clifford E. Cummings的文章中以格雷码表示是前两位均不相同,而后两位LSB相同为满,这与换成二进制表示的MSB不同其他相同为满是一样的)。当指针完全相等时,FIFO为空。

这种方法思路非常明了,为了比较不同时钟产生的指针,需要把不同时钟域的信号同步到本时钟域中来,而使用Gray码的目的就是使这个异步同步化的过程发生亚稳态的机率最小,而为什么要构造一个N+1的指针,Clifford E. Cummings也阐述的很明白,有兴趣的读者可以看下作者原文是怎么论述的,Clifford E. Cummings的这篇文章有Rev1.1 \ Rev1.2两个版本,两者在比较Gray码指针时的方法略有不同,个Rev1.2版更为精简。

第二种算法:Clifford E. Cummings的文章中提到的STYLE #2。它将FIFO地址分成了4部分,每部分分别用高两位的MSB 00 、01、 11、 10决定FIFO是否为going full 或going empty (即将满或空)。如果写指针的高两位MSB小于读指针的高两位MSB则FIFO为“几乎满”,若写指针的高两位MSB大于读指针的高两位MSB则FIFO为“几乎空”。

它是利用将地址空间分成4个象限(也就是四个等大小的区域),然后观察两个指针的相对位置,如果写指针落后读指针一个象限(25%的距离,呵呵),则证明很可能要写满,反之则很可能要读空,这个时候分别设置两个标志位dirset和dirrst,然后在地址完全相等的情况下,如果dirset有效就是写满,如果dirrst有效就是读空。

这种方法对深度为2^N字节的FIFO只需N位的指针即可,处理的速度也较第一种方法快。

异步的多时钟设计应按以下几个原则进行设计:

1,尽可能的将多时钟的逻辑电路(非同步器)分割为多个单时钟的模块,这样有利于静态时序分析工具来进行时序验证。

2,同步器的实现应使得所有输入来自同一个时钟域,而使用另一个时钟域的异步时钟信号采样数据。

3,面向时钟信号的命名方式可以帮助我们确定那些在不同异步时钟域间需要处理的信号。

4,当存在多个跨时钟域的控制信号时,我们必须特别注意这些信号,保证这些控制信号到达新的时钟域仍然能够保持正确的顺序。

异步地址比较如下:地址空间被分为四个象限,通过比较最高两位来产生 将满 或 将空 信号,然后等地址一样时,相应的输出写满或读空信号。

猜你喜欢

转载自blog.csdn.net/fengxiaocheng/article/details/81571139