XILINX原语之——xpm_fifo_async(异步FIFO灵活设置位宽、深度)
目录
一、"fwft"模式(First-Word-Fall-Through read mode)
1、写FIFO
2、读FIFO
二、"std"模式(standard read mode)
1、写FIFO
2、读FIFO
调用方式和xpm_fifo_sync基本一致:
XILINX原语之——xpm_fifo_sync(灵活设置位宽、深度)_xpm fifo-CSDN博客
将引脚设置成和调用FIFO IP一致,例化后:
`timescale 1ns / 1psmodule ASYNC_FIFO#(parameter READ_MODE = "fwft", //"std"- standard read mode;"fwft"- First-Word-Fall-Through read modeparameter integer DATA_WIDTH = 32, //1 to 4096parameter integer DATA_DEPTH = 2048, //16 to 4194304parameter integer READ_LATENCY= 0 //0 to 100 "fwft":0; "std":1
)(input wire rst ,input wire wr_clk ,input wire rd_clk ,input wire [DATA_WIDTH-1 : 0] din ,input wire wr_en ,input wire rd_en ,output wire [DATA_WIDTH-1 : 0] dout ,output wire full ,output wire empty ,output wire [$clog2(DATA_DEPTH) : 0] rd_data_count ,output wire [$clog2(DATA_DEPTH) : 0] wr_data_count );wire sync_rst;xpm_cdc_sync_rst #(.DEST_SYNC_FF (3 ), .INIT (1 ), .INIT_SYNC_FF (0 ), .SIM_ASSERT_CHK (0 ) )u_sync_rst(.dest_rst (sync_rst ), .dest_clk (wr_clk ),.src_rst (rst ) );xpm_fifo_async #(.CDC_SYNC_STAGES(2), // DECIMAL 2 to 8.DOUT_RESET_VALUE("0"), // String.ECC_MODE("no_ecc"), // String.FIFO_MEMORY_TYPE("block"), // String "auto", "block","distributed".FIFO_READ_LATENCY(READ_LATENCY),// DECIMAL 0 to 10.FIFO_WRITE_DEPTH(DATA_DEPTH), // DECIMAL 16 to 4194304.FULL_RESET_VALUE(0), // DECIMAL.PROG_EMPTY_THRESH(10), // DECIMAL.PROG_FULL_THRESH(10), // DECIMAL.RD_DATA_COUNT_WIDTH($clog2(DATA_DEPTH)+1), // DECIMAL 1 to 23.READ_DATA_WIDTH(DATA_WIDTH), // DECIMAL 1 to 4096.READ_MODE(READ_MODE), // String "std", "fwft".RELATED_CLOCKS(0), // DECIMAL.SIM_ASSERT_CHK(0), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages.USE_ADV_FEATURES("0707"), // String.WAKEUP_TIME(0), // DECIMAL.WRITE_DATA_WIDTH(DATA_WIDTH), // DECIMAL 1 to 4096.WR_DATA_COUNT_WIDTH($clog2(DATA_DEPTH)+1) // DECIMAL 1 to 23)u_xpm_fifo_async(// output .almost_empty (), .almost_full (), .data_valid (), .dbiterr (), .dout (dout ), .empty (empty ), .full (full ), .overflow (), .prog_empty (), .prog_full (), .rd_data_count (rd_data_count), .rd_rst_busy (), .sbiterr (), .underflow (), .wr_ack (), .wr_data_count (wr_data_count), .wr_rst_busy (), // input .din (din ), .injectdbiterr (0), .injectsbiterr (0), .rd_clk (rd_clk ), .rd_en (rd_en ), .rst (sync_rst ), .sleep (0), .wr_clk (wr_clk ), .wr_en (wr_en ) );endmodule
同样使用IP生成一个FIFO进行仿真对比。
一、"fwft"模式(First-Word-Fall-Through read mode)
生成的FIFO IP同样设置为fwft模式,仿真代码如下:
`timescale 1ns / 1psmodule tb_async_fifo();parameter READ_MODE = "fwft";//"std"- standard read mode;"fwft"- First-Word-Fall-Through read modeparameter integer DATA_WIDTH = 32;parameter integer DATA_DEPTH = 2048;reg rst ;reg wr_clk ;reg rd_clk ;reg [DATA_WIDTH-1 : 0] din ;reg wr_en ;wire rd_en ;wire [DATA_WIDTH-1 : 0] dout ;wire full ;wire empty ;wire [$clog2(DATA_DEPTH) : 0] rd_data_count ;wire [$clog2(DATA_DEPTH) : 0] wr_data_count ;wire [31 : 0] dout_IP;wire full_IP;wire empty_IP;wire [11 : 0] rd_data_count_IP; wire [11 : 0] wr_data_count_IP; ASYNC_FIFO#(.READ_MODE (READ_MODE),.DATA_WIDTH (DATA_WIDTH),.DATA_DEPTH (DATA_DEPTH),.READ_LATENCY (0 ))u_ascfifo(.rst (rst ), .wr_clk (wr_clk ), .rd_clk (rd_clk ), .din (din ), .wr_en (wr_en ), .rd_en (rd_en ), .dout (dout ), .full (full ), .empty (empty ), .rd_data_count (rd_data_count), .wr_data_count (wr_data_count));wire sync_rst;xpm_cdc_sync_rst #(.DEST_SYNC_FF (3 ), .INIT (1 ), .INIT_SYNC_FF (0 ), .SIM_ASSERT_CHK (0 ) )u_sync_rst(.dest_rst (sync_rst ), .dest_clk (wr_clk ),.src_rst (rst ) );DCFIFO_32W_2048D u_IP_fifo (.rst (sync_rst), // input wire rst.wr_clk (wr_clk), // input wire wr_clk.rd_clk (rd_clk), // input wire rd_clk.din (din), // input wire [31 : 0] din.wr_en (wr_en), // input wire wr_en.rd_en (rd_en), // input wire rd_en.dout (dout_IP), // output wire [31 : 0] dout.full (full_IP), // output wire full.empty (empty_IP), // output wire empty.rd_data_count(rd_data_count_IP), // output wire [11 : 0] rd_data_count.wr_data_count(wr_data_count_IP) // output wire [11 : 0] wr_data_count);initial beginwr_clk<=0;rd_clk<=0;rst<=1;
#2000rst<=0;
endalways #5 wr_clk<=!wr_clk;always #10 rd_clk<=!rd_clk;reg [31:0] cnt;always @(posedge wr_clk or posedge rst)beginif (rst) begincnt <= 0;end else beginif(cnt>=10000)cnt<=0;elsecnt<=cnt+1;endendalways @(*)beginif (rst) beginwr_en <= 0;end else beginif(cnt>200&&cnt<3000 && full==0)beginwr_en <= 1;end elsewr_en <= 0;endendalways @(posedge wr_clk or posedge rst)beginif (rst) begindin<=0;end else beginif(cnt>200&&cnt<3000 && full==0)begindin <=din+1;endendendreg rd_en_1;always @(posedge rd_clk or posedge rst)beginif (rst) beginrd_en_1 <= 0;end else beginif(cnt>3000 && empty==0)beginrd_en_1 <= 1;end elserd_en_1 <= 0;endendassign rd_en=rd_en_1 && (empty==0);
endmodule
仿真波形如下:
1、写FIFO
FIFO空信号(empty):调用XPM原语和使用IP核一致;
FIFO满信号(full):调用XPM原语和使用IP核一致,都在写入2048+1个数据后拉高;
FIFO计数信号(wr_data_count):调用XPM原语和使用IP核一致,计数延迟2个wr_clk周期。
2、读FIFO
FIFO满信号(full):调用XPM原语和使用IP核一致;
FIFO计数信号(rd_data_count):调用XPM原语和使用IP核一致,计数延迟2个rd_clk周期。
FIFO输出信号(dout): 调用XPM原语和使用IP核一致,rd_en使能时输出数据,无时钟延迟。
FIFO空信号(empty):调用XPM原语和使用IP核一致,都在读完数据后1个周期拉高;
二、"std"模式(standard read mode)
生成的FIFO IP同样设置为STD模式,仿真代码如下:
`timescale 1ns / 1psmodule tb_Async_fifo_std();parameter READ_MODE = "std";//"std"- standard read mode;"fwft"- First-Word-Fall-Through read modeparameter integer DATA_WIDTH = 32;parameter integer DATA_DEPTH = 2048;reg rst ;reg wr_clk ;reg rd_clk ;reg [DATA_WIDTH-1 : 0] din ;reg wr_en ;wire rd_en ;wire [DATA_WIDTH-1 : 0] dout ;wire full ;wire empty ;wire [$clog2(DATA_DEPTH) : 0] rd_data_count ;wire [$clog2(DATA_DEPTH) : 0] wr_data_count ;wire [31 : 0] dout_IP;wire full_IP;wire empty_IP;wire [10 : 0] rd_data_count_IP; wire [10 : 0] wr_data_count_IP; ASYNC_FIFO#(.READ_MODE (READ_MODE),.DATA_WIDTH (DATA_WIDTH),.DATA_DEPTH (DATA_DEPTH),.READ_LATENCY (1 ))u_ascfifo(.rst (rst ), .wr_clk (wr_clk ), .rd_clk (rd_clk ), .din (din ), .wr_en (wr_en ), .rd_en (rd_en ), .dout (dout ), .full (full ), .empty (empty ), .rd_data_count (rd_data_count), .wr_data_count (wr_data_count));wire sync_rst;xpm_cdc_sync_rst #(.DEST_SYNC_FF (3 ), .INIT (1 ), .INIT_SYNC_FF (0 ), .SIM_ASSERT_CHK (0 ) )u_sync_rst(.dest_rst (sync_rst ), .dest_clk (wr_clk ),.src_rst (rst ) );DCFIFO_32W_2048D_STD u_IP_fifo (.rst (sync_rst), // input wire rst.wr_clk (wr_clk), // input wire wr_clk.rd_clk (rd_clk), // input wire rd_clk.din (din), // input wire [31 : 0] din.wr_en (wr_en), // input wire wr_en.rd_en (rd_en), // input wire rd_en.dout (dout_IP), // output wire [31 : 0] dout.full (full_IP), // output wire full.empty (empty_IP), // output wire empty.rd_data_count(rd_data_count_IP), // output wire [11 : 0] rd_data_count.wr_data_count(wr_data_count_IP) // output wire [11 : 0] wr_data_count);initial beginwr_clk<=0;rd_clk<=0;rst<=1;
#2000rst<=0;
endalways #5 wr_clk<=!wr_clk;always #10 rd_clk<=!rd_clk;reg [31:0] cnt;always @(posedge wr_clk or posedge rst)beginif (rst) begincnt <= 0;end else beginif(cnt>=10000)cnt<=0;elsecnt<=cnt+1;endendalways @(*)beginif (rst) beginwr_en <= 0;end else beginif(cnt>200&&cnt<3000 && full==0)beginwr_en <= 1;end elsewr_en <= 0;endendalways @(posedge wr_clk or posedge rst)beginif (rst) begindin<=0;end else beginif(cnt>200&&cnt<3000 && full==0)begindin <=din+1;endendendreg rd_en_1;always @(posedge rd_clk or posedge rst)beginif (rst) beginrd_en_1 <= 0;end else beginif(cnt>3000 && empty==0)beginrd_en_1 <= 1;end elserd_en_1 <= 0;endendassign rd_en=rd_en_1 && (empty==0);endmodule
1、写FIFO
FIFO空信号(empty):调用XPM原语和使用IP核一致;
FIFO计数信号(wr_data_count):调用XPM原语和使用IP核一致,计数延迟2个周期。
FIFO满信号(full):调用XPM原语和使用IP核一致,都在写入2048-1个数据后拉高;
2、读FIFO
FIFO满信号(full):调用XPM原语和使用IP核一致,都在读取数据后1个时钟周期后拉低;
FIFO计数信号(rd_data_count):调用XPM原语和使用IP核一致,计数延迟2个rd_clk周期。
FIFO输出信号(dout): 调用XPM原语和使用IP核一致,rd_en使能后下一个时钟周期输出数据,1个时钟周期延迟。
FIFO空信号(empty):调用XPM原语和使用IP核一致,都在读完2048-1个数据后拉高;