# **异步FIFO的设计与总结**
关于处理跨时钟域的方法有几种,少量数据时用边沿检测电路,脉冲检测电路,电平检测电路,两级触发器,数据较多时用异步FIFO。本文主要讨论异步FIFO,由于读写时钟的不同,实际的设计中很容易出现问题,有以下两点:
**难点:**
1、首先是读写指针的产生,读写指针要被同步到对方的时钟域以产生空满信号。
2、然后是当读写地址相同时,怎样判断写空还是读满。
**解决方法:**
1、我们可以将读写指针通过两级触发器同步的方法同步到对方时钟域,但是由于读写地址不止1bit,同时进行处理会增大错误的概率,不能将多位二进制直接同步到另一时钟域中,所以最常见的是先将数据转化成Gray码,Gray码相邻数据之间只有一个bit在变化,然后进行同步,这样会减少错误的概率。
2、读写地址相同时,需要判断是读地址追上了写地址(读空),还是写地址追上了读地址(写满)。我们可以将读写指针加上一位冗余位,因此读写指针要比地址多一位标志位。复位时,读写地址都是0,此时产生空标志。当写地址写完一个循环开始写新的一轮时,写指针标志位换为1,若再次读写地址相同而标志位不同时,产生满标志。显然,当读写地址相同而标志位也相等时,产生空标志。利用格雷码同步时,即使发生错误也不会产生overflow和underflow的情况。拿满标志产生为例,当写指针追上读指针时满标志能立刻准确的产生,而满标志的移除需要时间,因为当异步读指针增加时,FIFO不再为满,此时满标志产生逻辑不会立即检测到变化,因为要经过写时钟同步,等待两个写时钟后才会撤销满标志位,不过没关系,当FIFO产生满标志而实际不为满时我们不写数据就是了,不会造成overflow。
这种方法中,由指针产生读写地址时需要将格雷码转换为二进制码(地址),需要额外的组合逻辑。还有一种由读写指针直接产生地址的方法,即直接利用读写指针的高两位进行判断。若读写指针的高两位不等且其他位读写指针相等,则可判定为写满,完全相等时则产生空标志。
如图所示:
![Alt text](./1444806972261.png)
这种方法设计的FIFO完整的结构如下:
![Alt text](./1444807224374.png)
还有一种方法是异曲同工的,先将读写指针同步到一个组合逻辑电路之中直接比较空满,再将空满信号同步到各自的模块中。这种电路也会产生撤销空/满标志动作延迟的不好影响,但不会出现overflow和underflow的现象。
![Alt text](./1444809224709.png)
此种方法设计的FIFO深度必须为2^n,如果不是呢?当FIFO深度与2^n差距太大时,我们可以使用一种Gray码的一种改进方法来编码。如果深度为6,可以采用4位编码,码的总长度是12,分为上下两部分,分别作为地址奇偶循环编码,这种方法去掉了格雷码中数值为6,7的两个值0101,0100,使上下两部分成对称反射码。最高位为0时,低3为直接作为读地址,为1时,低3位取反再作为写地址。这种编码缺点是生成地址复杂,硬件开销较大。
![Alt text](./1444808376747.png)
几种方法各有优劣,在实际情况中应综合考虑。
文章评论(0条评论)
登录后参与讨论