前言
FIFO 的英文全称是 First In First Out,即先进先出。FPGA 使用的 FIFO 一般指的是对数据的存储具有先进先出特性的一个缓存器,常被用于数据的缓存,或者高速异步数据的交互也即所谓的跨时钟域信号传递。
它与 FPGA 内部的 RAM 和 ROM 的区别是没有外部读写地址线,采取顺序写入数据,顺序读出数据的方式,使用起来简单方便,由此带来的缺点就是不能像 RAM 和 ROM 那样可以由地址线决定读取或写入某个指定的地址。
本章我们将对 Vivado 软件生成的 FIFO IP 核进行读写测试,来向大家介绍 Xilinx FIFO IP 核的使用方法。
提示:以下是本篇文章正文内容,下面案例可供参考
一、简介各端口含义
FIFO 各端口含义:
输入端口:
wr_clk 写时钟
rd_clk 读时钟
din 输入数据
wr_en 写使能
rd_en 读使能
输出端口:
dout 输出数据
full 满标记
wr_ack 写应答
empty 空标记
valid 输出有效标记
rd_data_count 读计数
wr_data_count 写计数
almost_full 快满标记
overflow 写溢出标记
almost_empty 快空标记
underflow 读溢出标记
具体使用FIFO 的配置中会说明。
————————————————
二、创建同步FIFO IP核
1.1创建IP
1.2 设置同步FIFO IP核相关参数
数字1处为IP核的名称,可以根据自己需求修改。
数字2处为IP核总线类型,Native类型用于非SOC逻辑设计,其它两种用于SOC逻辑设计,通常选择Native类型。
数字3处为FIFO的时钟组成和存储结构,从上到下依次为单时钟块RAM、单时钟分布式RAM、单时钟移位寄存器、单时钟内建FIFO、双时钟块RAM、双时钟分布式RAM、双时钟内建FIFO。其中的单时钟即同步FIFO,双时钟即异步FIFO。同步FIFO 是指读时钟和写时钟为同一个时钟,异步FIFO 是指读写时钟不一致,读写时钟是互相独立的。
————————————————
1.3 Native Ports选项卡
上图中Read Mode处用于设置读FIFO时的读模式。当FIFO配置为单时钟块RAM时,选择Standard FIFO时当读使能信号rd_en拉高时,下一个时钟周期才会输出数据,而选择First Word Fall Through时,当读使能信号rd_en拉高时,数据就会输出,不用等待一个时钟周期。
上图中Data Port Parameters处用于设置读写端口的数据总线的宽度以及FIFO的深度。从上到下依次是写数据宽度、写数据深度、读数据宽度 、读数据深度(自动生成)。
上图中Reset Pin处为是否采用复位引脚。注意复位信号为高电平有效。
上图中Reset Type处为是否为异步复位。
上图中Full Flags Reset Value处为复位时Full Flags的状态为0还是为1。
上图中Dout Reset Value处为复位时Dout数据线的状态。
————————————————
1.4 Status Flags选项卡
1.5 Data Counts选项卡
“Data Counts”选项卡用于设置FIFO 内数据计数的输出信号,此信号表示当前在FIFO 内存在多少个有效数据。
1.6 Summary选项卡
该选项卡为FIFO最终的配置以及资源占用情况
1.7 生成FIFO
三、FIFO IP核TB测试
`timescale 1ns / 1ps
//
// Create Date: 2022/12/22 15:59:39
// Module Name: fifo_tb
// Name: 小王在努力...
// Revision:Vivado 2018.3
// Revision 0.01 - File Created
//
module fifo_tb();
reg clk;
reg rst;
reg [15:0]din;
reg wr_en;
reg rd_en;
wire [15:0]dout;
wire full;
wire empty;
wire wr_rst_busy;
wire rd_rst_busy;
fifo fifo (
.clk(clk), // input wire clk
.rst(rst), // input wire rst
.din(din), // input wire [15 : 0] din
.wr_en(wr_en), // input wire wr_en
.rd_en(rd_en), // input wire rd_en
.dout(dout), // output wire [7 : 0] dout
.full(full), // output wire full
.empty(empty), // output wire empty
.wr_rst_busy(wr_rst_busy), // output wire wr_rst_busy
.rd_rst_busy(rd_rst_busy) // output wire rd_rst_busy
);
initial clk = 1;
always #10 clk = ~clk;
initial begin
rst = 1;
din = 0;
wr_en = 0;
rd_en = 0;
#201;
rst = 0; //低电平有效
#200;
repeat(500) begin
wr_en = 1;
#20;
din = din + 1;
end
wr_en = 0;
#199;
repeat(500) begin
rd_en = 1;
#20;
end
rd_en = 0;
#200000;
$stop;
end
endmodule
四、FIFO IP核仿真结果
五、同步复位和异步复位比较
【Verilog】 同步复位和异步复位比较