二、FIFO的介绍
终于写到FIFO了,FIFO 是first in first out的缩写,也就是“先进先出”;从字面理解,就是说,数据先进来的,就先出去。前面说了当快时钟域传输数据到慢时钟域时,就推荐用FIFO了。FIFO无论是快到慢,还是慢到快,都可以使用它进行数据的缓冲,可谓是“快慢皆宜”啊。 FIFO的工作流程如下:
FIFO在写时钟和状态信号的控制下,根据写使能信号往FIFO里面写数据,当写到一定程度后,FIFO存不下新数据的了(或者要以牺牲丢弃旧数据为贷款),这时候就不能往FIFO里面写数据了;在读时钟和状态信号的控制下,根据读使能信号从FIFO里面读出数据,当读到一定程度后,FIFO里面没有数据了,就不能继续读了,不然就会读出错误的数据。根据读写时钟是否一致(同步),FIFO的种类又可以分成同步FIFO和异步FIFO。FIFO能够读写数据,肯定需要数据的存储单元,这里存储数据的单元往往是双口RAM。
FIFO的写过程:在复位的时候,FIFO(双口RAM)里面的数据被清零(也就是不存在数据)。复位之后,只能进行写操作,因为什么都没有,读数据会读出错误的值。这个时候,当外部给FIFO写使能信号了,在时钟的驱动下,数据就会被写入FIFO里面的RAM存储单元(存储单元的地址由写指针寄存器的内容确定,写指针寄存器中的内容称为写地址,复位的时候为0),写完数据之后(或者在允许写数据之后),这个写指针寄存器就会自动加一,指向下一个存储单元。当写到一定程度的时候(写指针寄存器到达一定的数值),旧数据还没有被读出的时候,再写入新数据就会把旧数据给覆盖,这个时候称为写满,需要产生写满的状态信号(full,简称满)。在写满的时候,需要禁止继续写数据。
三、在进行FIFO的RTL设计前的问题
根据FIFO的介绍内容,我们试着来推导一下FIFO大致由哪些部分构成。
首先,FIFO需要存储数据,因此就需要存储器;由于需要读,也需要写,于是乎就需要一个DPRAM(double port RAM,双端口RAM)。
然后,RAM需要读/写地址,它才知道在哪里读/写数据,因此需要读/写地址产生模块,也就是需要读/写地址寄存器。什么时候进行写,什么时候进行读,因此需要读/写控制逻辑和空满状态的信号产生逻辑。
最后,空满信号的产生需要通过对读地址和写地址的比较,由于读写地址在不同的时钟域,因此需要同步电路进行同步。
通过上面的简单介绍,我们就得到了FIFO的大致框图如下(主要是告诉大家为什么会有这么一个框图):