1.简介缓存
定义:异步
FIFO(First In First Out)一种先入先出(读写数据是只能顺序写入顺序读出)的数据缓存器,读写数据时,其内部读写指针自动加1,所以没有外部地址线,使用简单。ide
分类:spa
FIFO能够分为同步FIFO和异步FIFO。同步FIFO的写入时钟和读取时钟彻底同样,内核时一个简单双口RAM(Simple Dual Port RAM);异步FIFO写入时钟和读取时钟不一样,不只须要真双口RAM(True Dual Port RAM),还须要专门的握手信号进行跨时钟域的数据传递。设计
用途:指针
1)使用异步FIFO进行跨时钟域交互数据;2)进行不一样数据宽度的读写匹配;3)对高速突发数据进行平均处理,下降瞬时处理速率。code
使用场景:blog
1)AXI总线工做在1GHz以上,而USB2.0工做在480MHz时,就须要内嵌异步FIFO;2)AD采样为24位,而传输协议为8位时,可使用FIFO进行不一样数据宽度的读写匹配...接口
2.空满原理同步
空或满时应知足:读写指针相等。当复位后,或者读指针读出FIFO中最后的数据后追上了写指针则说明FIFO为空;当写指针写满一圈后又追上读指针则说明满。可是随之而来又有一个问题,当读写指针相等时,究竟是空仍是满呢?对此,目前采用的方法有两种:1)指针中增长一个额外的位用于肯定满或空。2)采用格雷码完成FIFO空/满判断。
法1)在异步FIFO中容易出现问题(将一个二进制的计数值从一个时钟域同步到另外一个时钟域时容易出现问题),例如1111在下一刻变成0000,但在实际电路中这个过程可能会持续较长时间,实际须要4个状态才能实现(例如1111=>1011=>1001=>1000=>0000),若写时钟而在这个期间采样,得出的指针就会是错误的。
法2)则能解决这个问题,由于格雷码每次变换只有一位发生改变。
3.建立
通常来讲,如今使用FIFO时,能够直接使用公司自带的IP核实现,此处以ISE为例(新建项目就不说了,直接新建文件)。
(1)New Source
(2)选择IP 并填写文件名
(3)在Memories&Storage Elements中找到FIFOs
(4)接下来程序会自动打开FIFO Generator
(5)此处选择读写公用时钟仍是独立时钟,采用块RAM仍是分布RAM,(我选择的是独立时钟,Block RAM)
(6)接下来选择写宽度,写深度,读深度,读宽度。(由于本文举例的FIFO实在实际工程中,所以根据实际要求作了选择)
(7)接下来还有一些可选项,能够依照本身的需求选择。
(8)在生成以后点击View HDL Instantiation Template即可以查看接口信息,方便实例化;同时在
(9)同时在自定义的目录下会生成相关的文件与文件夹,以下图;其中simulation包含仿真信息。
4.使用(无具体代码,介绍方法)
fifo_da U2_0_2_F0(
.rst(!rst_n), // FIFO复位信号,高电平有效
.wr_clk(wr_clk), // 写FIFO时钟
.wr_en(u_rd_en), // 写FIFO使能
.din(din), // 写入FIFO的数据
//写入:wr_en为高电平时wr_clk的上升沿会把din写入fifo中;(同步写入)
.rd_clk(rd_clk), // 读FIFO时钟
.rd_en(rd_en), // 读FIFO使能
.dout(dout), // 读出FIFO的数据
.full(full), // output full
.empty(empty) // output empty
//读出:rd_en为高电平时,会在下一个rd_clk的上升沿会把fifo的数据读出;(下一个时钟数据读出)
);
5.相关
1)二进制码转格雷码
binarycode = graycode^(graycode>>1);
2)格雷码转二进制码
1 always@(geraycode)begin 2 3 for(i=0;i<n-1;i=i+1) 4 5 binarycode[i]=^(geraycode>>i); 6 7 end
5.参考资料
1)《通讯IC设计》李庆华著