今天看别人的博客研究了一天的异步FIFO,中遇到了很多问题。很多人可能有过这样的经历,当你研究一个东西,可能你当时很清楚你是怎么想的,但是过后就忘记了当时的思路了。因此我写博客的主要目的就是为了回头查阅方便。IC基础可能会写很多篇,本篇异步FIFO就是此系列的第一篇。
一、FIFIO简介
FIFO是一种现先进先出的数据缓冲器,特点是没有外部的读写地址。由于没有外部的地址信号,所以只能顺序的读写,而不能跳读。FIFO的读写是根据满和空信号设计写使能和读使能来写/读FIFO,当FIFO满的时候不可以往里面写、当FIFO空的时候不能读数据。读FIFO时,内部的读指针自动的加一,当写FIFO时写指针自动的加一。
什么是异步FIFO,什么又是同步FIFO?
异步FIFO简单的来说就是读写时钟不相同,同步FIFO就是读写的时钟相同。
二、异步FIFO的用途
1、使用异步FIFO可以在两个不同的时钟域之间快速而方便的传输数据,起到跨时钟域处理的作用。经常用于处理跨时钟域的问题。
2、对于不同宽度的数据接口也可以采用FIFO进行缓冲,如8位输入,16位输出。(注:本文只简介输入输出位宽相同的情况)
三、FIFO的常见参数
- wfull: 满标志, 表示FIFO已经满,不能再写入数据。
- rempty:空标志,表示FIFO已经空,不能再读取数据。
- wclk: 写时钟
- rclk: 读时钟
- winc: 写使能
- rinc: 读使能
- wdata:写数据
- rdata: 读数据
- wrst_n: 写复位
10.rrst_n:读复位
四、读写指针的工作原理
- 读指针:总是指向下一个将要被写入的单元,复位时指向第一个单元。
- 写指针:总是指向当前要被读出的数据,复位时指向第一个单元。
也就是说,复位时读写指针都指向第一个单元。并且向FIFO写入一个数据,写指针加1。从FIFO中读出一个数据,都指针加1。
五、FIFO满空标志的产生
FIFO设计的关键是如何产生可靠的读写指针和满空信号。FIFO读写指针的工作原理如上第四点所述。
那么剩下的就是要讨论如何产生FIFO的满空信号了。FIFO什么时候为空呢?我们来思考一下,假设我从第一个单元写入数据,那么写指针从地址0—>1,读指针不变,此时FIFO中有一个数据。接着我把这个数据读出来,读指针从0—>1。此时写指针为1,读指针也为1,FIFO中没有数据了,因此FIFO为空。从中可以发现,判断FIFO为空很简单,只要读写指针相等就是空。但是事情好像也没那么简单,再想一下,假设一开始就复位,读写指针都在0地址,然后一直王FIFO中写入数据,当写满FIFO的时候,写指针刚好转了一圈回到了0地址,此时读写指针也相等,但是这时候FIFO是满的。因此得到下面的判空和判满条件。
判空:读指针追上写指针的时候,两者相等,为空。
判满:写指针追上读指针的时候,两者相等,为满。
突然发现两者相等的话不是空就是满,区别就是谁追上谁而已了。那么如何来区别是谁追上谁呢?
六、如何判断读写指针相等时,为空还是为满呢?
答案就是在表示读写指针的数据位宽上再加1位来区分是满还是空。比如FIFO的深度位8,那么需要3位二进制数来表地址,则需要再最高之前再加一位,变成4位。一开始读写都是0000,FIFO为空。当写指针增加并越过最后一个存储单元的时候,就将这个最高位取反,变成1000。这时是写地址追上了读地址,FIFO为满。同理,当读地址越过最后一个存储单元的时候把读地址的最高位也取反。可以看到,当最高位相同,并且剩下的位也相同的时候FIFO为空;当最高位不同,并且剩下的位相同时,为满。
七、异步时钟域下如何判断时空还