目錄
一、"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個數據后拉高;