本文首先对异步 FIFO 设计的重点难点进行分析

最后给出详细代码


一、FIFO简单讲解

FIFO的本质是RAM, 先进先出

重要参数:fifo深度(简单来说就是需要存多少个数据)

              fifo位宽(每个数据的位宽)

FIFO有同步异步两种,同步即读写时钟相同,异步即读写时钟不相同

同步FIFO用的少,可以作为数据缓存

异步FIFO可以解决跨时钟域的问题,在应用时需根据实际情况考虑好fifo深度即可


本次要设计一个异步FIFO,深度为8,位宽也是8.

代码是学习Simulation and Synthesis Techniques for Asynchronous FIFO Design   Clifford E. Cummings, Sunburst Design, Inc.这篇文章的,

百度搜搜很容易找到,虽然是英文的但是写的确实值得研究。

下面我会对设计的要点进行分析,也是对自己学习过程的一个总结,希望能和大家交流共同进步。


二、设计要点解析

1、读空信号如何产生?写满信号如何产生?

读空信号:复位的时候,读指针和写指针相等,读空信号有效(这里所说的指针其实就是读地址、写地址)

              当读指针赶上写指针的时候,写指针等于读指针意味着最后一个数据被读完,此时读空信号有效

写满信号:当写指针比读指针多一圈时,写指针等于读指针意味着写满了,此时写满信号有效

我们会发现 读空的条件是写指针等于读指针,写满的条件也是写指针等于读指针,到底如何区分呢?

解决方法将指针的位宽多定义一位

举个例子说明:假设要设计深度为 8 的异步FIFO,此时定义读写指针只需要 3 位(2^3=8)就够用了,

但是我们在设计时将指针的位宽设计成 4 位,最高位的作用就是区分是读空还是写满,具体理论 1 如下

当最高位相同,其余位相同认为是读空

当最高位不同,其余位相同认为是写满

知道这个理论就万事大吉了吗?重点来啦

由于我们在设计中判断是读指针是否等于写指针的时候,用的是读写指针的格雷码形式(为什么用格雷码后面解释),此时若用上面的理论1就会出问题,

因为格雷码是镜像对称的,若只根据最高位是否相同来区分是读空还是写满是有问题的,详情我会慢慢说,请看图 1

绿色框起来的是0--15的格雷码,用红线将格雷码分为上下两部分

通过观察格雷码相邻位每次只有1位发生变化,且上下两部分,除了最高位相反,其余位全都关于红线镜像对称,

7 --> 8 ,格雷码从 0100 --> 1100 ,只有最高位发生变化其余位相同

6 --> 9  , 格雷码从 0101 --> 1101 , 只有最高位发生变化其余位相同

以此类推,为什么要说镜像对称呢?

试想如果读指针指向 8,写指针指向 7 ,我们可以知道此时此刻并不是读空状态也不是写满状态

但是如果在此刻套用理论 1 来判断,看会出现什么情况,我们来套一下

7的格雷码与8的格雷码的最高位不同,其余位相同,所以判断出为写满。这就出现误判了,同样套用在 6 和 9,5 和 10等也会出现误判。

网友评论