使用软件: Vivado
参考文档:FIFO Generator v13.2
FIFIO介绍及IP核的使用
基础知识
FIFO(Fist In Fist Out),即为先进先出,常被用于数据的缓存或高速异步数据的交互,与普通存储器区别是没有外部读写地址线,使用简单,缺点是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样由地址线决定读取或写入某个指定的地址。
1. FIFO 结构
FIFO从读写时钟上看,分为两类:
(1)单时钟FIFO(同步FIFO)
读写共用一个时钟,即所有输入输出信号的变化都是由一个时钟信号控制。
(2)双时钟FIFO(异步FIFO)
读写各由一个时钟信号控制,写时钟:wr_clk,读时钟:rd_clk。
双时钟FIFO的整体框图和内部结构如下所示:
2. 应用场景
场景一
需求:
FPGA内部有个16位计数器,以50MHz频率计数,此时,希望随机截取计数器连续256个计数周期的值发到电脑上进行分析处理。
用串口发送到电脑上。(数据产生速率大于数据消费速率)
解决:
需要用存储器先将256个数据存储起来,再由串口慢慢发送到电脑。
对于FIFO来说,写入的数据是16位,读出的数据可能是16位或者8位
场景二
需求:
任意脉冲信号发生器:由电脑通过串口发送256个14位(16)的数据到FPGA,FPGA再把这256个数据,以50MHz的输出速率送给DAC,产生脉冲信号
问题:数据的产生速率小于数据消费速率
解决:
电脑发送速率最大为115200,小于FPGA发送的速率,需要FPGA将256个数据完全接收到并存储后,再一次性送给DAC输出
对于FIFO来说,写入的数据可能是16位(UART收到2个8位数据后,拼接起来一起写入)或者8位,读出的数据是16位
3. FIFO 常见参数
FIFO 的宽度:即 FIFO一次读写操作的数据位;
FIFO 的深度:指的是 FIFO可以存储多少个 N 位的数据(如果宽度为 N)。
满标志:FIFO已满或将要满时由 FIFO的状态电路送出的一个信号,以阻止FIFO的写操作继续向FIFO 中写数据而造成溢出。
空标志:FIFO 已空或将要空时由 FIFO 的状态电路送出的一个信号,以阻止FIFO的读操作继续从 FIFO 中读出数据而造成无效数据的读出。
读时钟:读操作所遵循的时钟,在每个时钟沿来临时读数据。
FIFO IP核的使用及仿真
双时钟 FIFO IP的配置
在Vivado软件的左侧项目管理栏下找到[IP Catalog],鼠标单击,在右边搜索框输入fifo搜索,选择[Memories&Storage Elements]下的[FIFO Generator],双击进入FIFO设置界面。
在Basic栏下进行配置
修改IP名字,为fifo,如下图所示
- 接口类型分为3种,一般选择Native类型
(1)Native:能够配置时钟域,用于写入和读取操作。
(2)AXI Memory Mapped:AXI指定写入通道和读取通道。
(3)AXI Stream:适合非基于地址的点对点应用,与使用此接口的其他IP进行连接。(如AXI4版本的DSP功能、FFT、DDS和FIR编译器等)
具体介绍看官方文档:FIFO Generator v13.2 - 创建一个独立的读写时钟,使用嵌入式Block RAM资源的FIFO,选择Independent Clocks Block RAM
对引脚进行配置
1. Read Mode选择Standard FIFO
对于Standard FIFO,在给了读数据使能后,数据才出来
对于First Word Fall Through,当前数据提前到了数据读数据线还是那个,在读使能到来后,下一个数据汇到数据线上,可以结合下面时序图来看:
Standard FIFO时序图:
First Word Fall Through时序图:
2. 读写数据位宽均设置为 8bits(实际根据需要可以设置读写数据位宽不一样),数据深度为 256words。
这里修改数据位宽及深度。需要注意的是设置数据后面有实际深度,这里虽然我们配置的是 256,但实际 FIFO 只有 255 的深度,这个是需要注意的,最终配置深度以后面实际深度为准,这个可能和 FIFO IP 内部设计有关,在仿真的时候可以看出来。
从下图中可以看到,在蓝线的位置,rd_clk为上升沿,检测到rd_en为1,隔了一个时钟周期,在黄线的位置,dout有了第一个有效输出值:01
3. 勾选[Output Register]
后面选择[Embedded Register]会使输出多一个寄存器,输出就会多延迟一个时钟周期出来,如果选择[Embedded Reg AND Fabric Reg]的话,输出会延迟2个时钟周期,从后面仿真图中可以看出。
4. 初始化设置
(1)这里可以保持默认的勾选复位管脚、复位同步和使能 Safety Circuit,这里的复位是对数据输出以及内部读写指针计数等进行复位,复位后,读写指针清零。
这里的复位同步功能是对异步输入的复位信号分别在读写时钟域内先进行同步后再进行读写的各自复位。
使用Safety Circuit 可以认为是一种更加可靠模式,内部通过额外的逻辑电路让 FIFO 复位的更加可靠,勾选 Enable Safety Circuit 后 fifo 模块的管脚会多出 wr_rst_busy 和 rd_rst_busy 两个信号输出,这两个信号分别表示的是写/读时钟域复位忙信号(为 1 表示忙,处于复位中,为0表示复位完),所以每次给一个异步复位信号对 FIFO 进行复位时,需要等到 wr_rst_busy 从1 变为 0 后才能对 FIFO 进行写数据操作(在 FIFO 非满情况下,这个是任何写操作时候都需要满足的),在 wr_rst_busy 为 1 时进行写是不允许的;
同样的要等到 rd_rst_busy 从 1 变为 0 后才能对 FIFO 进行读操作,在rd_rst_busy 为 1 时进行读是不允许的,这些是我们在使用 IP 过程需要注意的地方,有关具体时序波形可以到