FIFO 简介 FIFO 是英文 First In First Out 的缩写,是一种先进先出的数据缓存器,它与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加 1 完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
用途 1:
异步 FIFO 读写分别采用相互异步的不同时钟。在现代集成电路芯片中,随着设计规模的不断扩大,一个系统中往往含有数个时钟,多时钟域带来的一个问题就是,如何设计异步时钟之间的接口电路。异步 FIFO 是这个问题的一种简便、快捷的解决方案,使用异步 FIFO 可以在两个不同时钟系统之间快速而方便地传输实时数据。
用途 2:
对于不同宽度的数据接口也可以用 FIFO,例如单片机位 8 位数据输出,而 DSP 可能是 16 位数据输入,在单片机与 DSP 连接时就可以使用 FIFO 来达到数据匹配的目的。
分类
同步 FIFO 是指读时钟和写时钟为同一个时钟,在时钟沿来临时同时发生读写操作;
异步 FIFO 是指读写时钟不一致,读写时钟是互相独立的。
FIFO 的常见参数
FIFO 的宽度:即 FIFO 一次读写操作的数据位;
FIFO 的深度:指的是 FIFO 可以存储多少个 N 位的数据(如果宽度为 N)。
满标志:FIFO 已满或将要满时由 FIFO 的状态电路送出的一个信号,以阻止 FIFO 的写操作继续向 FIFO 中写数据而造成溢出(overflow)。
空标志:FIFO 已空或将要空时由 FIFO 的状态电路送出的一个信号,以阻止 FIFO 的读操作继续从 FIFO 中读出数据而造成无效数据的读出(underflow)。
读时钟:读操作所遵循的时钟,在每个时钟沿来临时读数据。
写时钟:写操作所遵循的时钟,在每个时钟沿来临时写数据。
1. 读写指针的工作原理 读指针:总是指向下一个将要被写入的单元,复位时,指向第 1 个单元(编号为 0)。
写指针:总是指向当前要被读出的数据,复位时,指向第 1 个单元(编号为 0)
2.FIFO 的“空”/“满”检测 FIFO 设计的关键:产生可靠的 FIFO 读写指针和生成 FIFO“空”/“满”状态标志。
当读写指针相等时,表明 FIFO 为空,这种情况发生在复位操作时,或者当读指针读出 FIFO 中最后一个字后,追赶上了写指针时,如下图所示:
当读写指针再次相等时,表明 FIFO 为满,这种情况发生在,当写指针转了一圈,折回来(wrapped around)又追上了读指针,如下图:
为了区分到底是满状态还是空状态,可以采用以下方法:
方法 1:在指针中添加一个额外的位(extra bit),当写指针增加并越过最后一个 FIFO 地址时,就将写指针这个未用的 MSB 加 1,其它位回零。对读指针也进行同样的操作。此时,对于深度为 2n 的 FIFO,需要的读 / 写指针位宽为(n+1)位,如对于深度为 8 的 FIFO,需要采用 4bit 的计数器,0000~1000、1001~1111,MSB 作为折回标志位,而低 3 位作为地址指针。
如果两个指针的 MSB 不同,说明写指针比读指针多折回了一次;如 r_addr=0000,而 w_addr = 1000,为满。
如果两个指针的 MSB 相同,则说明两个指针折回的次数相等。其余位相等,说明 FIFO 为空;
3. 二进制 FIFO 指针的考虑
将一个二进制的计数值从一个时钟域同步到另一个时钟域的时候很容易出现问题,因为采用二进制计数器时所有位都可能同时变化,在同一个时钟沿同步多个信号的变化会产生亚稳态问题。而使用格雷码只有一位变化,因此在两个时钟域间同步多个位不会产生问题。所以需要一个二进制到 gray 码的转换电路,将地址值转换为相应的 gray 码,然后将该 gray 码同步到另一个时钟域进行对比,作为空满状态的检测。
4. 使用 gray 码进行对比,如何判断“空”与“满” 使用 gray 码解决了一个问题,但同时也带来另一个问题,即在格雷码域如何判断空与满。
对于“空”的判断依然依据二者完全相等(包括 MSB);
而对于“满”的判断,如下图,由于 gray 码除了 MSB 外,具有镜像对称的特点,当读指针指向 7,写指针指向 8 时,除了 MSB,其余位皆相同,不能说它为满。因此不能单纯的只检测最高位了,在 gray 码上判断为满必须同时满足以下 3 条:
wptr 和同步过来的 rptr 的 MSB 不相等,因为 wptr 必须比 rptr 多折回一次。
wptr 与 rptr 的次高位不相等,如上图位置 7 和位置 15,转化为二进制对应的是 0111 和 1111,MSB 不同说明多折回一次,111 相同代表同一位置。
剩下的其余位完全相等。
|