未经本人允许,禁止任何形式转载!!!
FIFO在FPGA工程中常被用做数据缓存和跨时钟域处理,和RAM相比,FIFO没有地址线(数据先入先出)操作简单,因此在FPGA工程中被广泛使用。XINLINX公司提供了两种FIFO IP核,一种是standard fifo模式,另外一种是First Word Fall Through fifo模式。这两种模式的fifo具体有什么区别呢?话不多说,上干货!!!
下面对两种FIFO编写测试代码(部分代码见附件一)及仿真代码(见附件二),通过仿真波形对比两种fifo区别。测试代码对两种FIFO一次性写入128字节数据之后控制FIFO读出。由图1-1所示的波形图来看,standard模式的fifo在读使能拉高之后,第一个数据会在下一个时钟读出,而First Word Fall Through 模式的fifo在读使能拉高后,第一个数据会立刻被读出。那么最后一个数据在输出端口又有什么区别呢?点赞加关注会加更哦!
图1-1
未经本人允许,禁止任何形式转载!!!
附件一
module xilinx_fifo_test(
input sys_clk,
input i_rst
);
parameter rd_wr_num = 'd128;
reg [7:0] din_standard;
reg wr_en_standard;
reg rd_en_standard;
wire [7:0] dout_standard;
wire full_standard;
wire almost_full_standard;
wire empty_standard;
wire almost_empty_standard;
wire [8:0] rd_data_count_standard;
wire [8:0] wr_data_count_standard;
wire wr_rst_busy_standard;
wire rd_rst_busy_standard;
reg [7:0] din_fwft;
reg wr_en_fwft;
reg rd_en_fwft;
wire [7:0] dout_fwft;
wire full_fwft;
wire almost_full_fwft;
wire empty_fwft;
wire almost_empty_fwft;
wire [8:0] rd_data_count_fwft;
wire [8:0] wr_data_count_fwft;
wire wr_rst_busy_fwft;
wire rd_rst_busy_fwft;
wire fifo_work_flag;
fifo_standard u1_fifo_standard (
.rst(i_rst), // input wire rst
.wr_clk(sys_clk), // input wire wr_clk
.rd_clk(sys_clk), // input wire rd_clk
.din(din_standard), // input wire [7 : 0] din
.wr_en(wr_en_standard), // input wire wr_en
.rd_en(rd_en_standard), // input wire rd_en
.dout(dout_standard), // output wire [7 : 0] dout
.full(full_standard), // output wire full
.almost_full(almost_full_standard), // output wire almost_full
.empty(empty_standard), // output wire empty
.almost_empty(almost_empty_standard), // output wire almost_empty
.rd_data_count(rd_data_count_standard), // output wire [8 : 0] rd_data_count
.wr_data_count(wr_data_count_standard), // output wire [8 : 0] wr_data_count
.wr_rst_busy(wr_rst_busy_standard), // output wire wr_rst_busy
.rd_rst_busy(rd_rst_busy_standard) // output wire rd_rst_busy
);
fifo_fwft u2_fifo_fwft (
.rst(i_rst), // input wire rst
.wr_clk(sys_clk), // input wire wr_clk
.rd_clk(sys_clk), // input wire rd_clk
.din(din_fwft), // input wire [7 : 0] din
.wr_en(wr_en_fwft), // input wire wr_en
.rd_en(rd_en_fwft), // input wire rd_en
.dout(dout_fwft), // output wire [7 : 0] dout
.full(full_fwft), // output wire full
.almost_full(almost_full_fwft), // output wire almost_full
.empty(empty_fwft), // output wire empty
.almost_empty(almost_empty_fwft), // output wire almost_empty
.rd_data_count(rd_data_count_fwft), // output wire [8 : 0] rd_data_count
.wr_data_count(wr_data_count_fwft), // output wire [8 : 0] wr_data_count
.wr_rst_busy(wr_rst_busy_fwft), // output wire wr_rst_busy
.rd_rst_busy(rd_rst_busy_fwft) // output wire rd_rst_busy
);
assign fifo_work_flag = (!wr_rst_busy_standard) && (!rd_rst_busy_standard) && (!wr_rst_busy_fwft) && (!rd_rst_busy_fwft);
always @(posedge sys_clk)begin
if(i_rst)begin
din_standard <= 'd0;
wr_en_standard <= 'd0;
din_fwft <= 'd0;
wr_en_fwft <= 'd0;
end
else if(fifo_work_flag)begin
附件二
`timescale 1ns / 1ps
module xilinx_fifo_test_tb;
parameter sys_clk_val = 'd10;
reg sys_clk;
reg i_rst;
xilinx_fifo_test u_xilinx_fifo_test(
.sys_clk(sys_clk),
.i_rst(i_rst)
);
initial begin
sys_clk = 'd0;
i_rst = 'd1;
#('d1000*sys_clk_val) i_rst = 'd0;
end
always #(sys_clk_val/'d2) sys_clk = ~sys_clk;
endmodule