異步FIFO在ISE下有兩種生成方法:
法一:使用CORE Generator生成的DPRAM和自己設計的FIFO控制邏輯,将兩者連在一起就構成了FIFO。
法二:直接使用FIFO的IP核。
現在我們來做一件事情:異步時鐘域的晶片A和B,假設A的頻率是48MHZ,B的頻率是100MHZ。設計一個異步FIFO,使得B發送的資料可以被A正确接收。A和B的資料寬度均為16。
使用ISE的FIFO IP核:

選擇這個IP核接着進入設定:Native類型就是之前的,可用于block ram,distributed ram等;AXI4就是支援AXI4總線标準的FIFO,在系統設計的時候用得到。這裡我們選擇Native就可以了。
Step 2:如果我們選擇Common Clock的話就會生成同步FIFO,選擇Independent Clocks就變成了異步FIFO。後面的Features就是支援不同讀寫資料位寬,支援ECC資料校驗,首字直通等等。具體地去看Datasheet!
Step 3:選擇First-Word-Fall-Through。這就可以沒有延時讀出資料。另外一個就會有一個周期延時。下面就可以設定位寬。
Step 4:這裡選擇标志位,幾乎滿,幾乎空。
Step 5:選擇複位設定複位後的值為0。
Step 6:這裡設定Count記錄的是讀或者寫的資料的數量。
Step 7:例化
fifo1 YourInstanceName (
.rst(rst), //複位
.wr_clk(wr_clk), //寫時鐘
.rd_clk(rd_clk), //讀時鐘
.din(din), // Bus [15 : 0] //讀入資料
.wr_en(wr_en), //寫使能
.rd_en(rd_en), //讀使能
.dout(dout), // Bus [15 : 0] //讀出資料
.full(full), //滿
.almost_full(almost_full), //幾乎滿
.overflow(overflow), //溢出
.empty(empty), //空
.almost_empty(almost_empty), //幾乎空
.underflow(underflow), //下溢
.rd_data_count(rd_data_count), // Bus [9 : 0] //記錄讀的資料數
.wr_data_count(wr_data_count)); // Bus [9 : 0] //記錄寫的資料數
仿真檔案部分:
`timescale 1ns / 100ps
module my_fifo_tb;
// Inputs
reg rst;
reg wr_clk;
reg rd_clk;
reg [15:0] din;
reg wr_en;
reg rd_en;
// Outputs
wire [15:0] dout;
wire full;
wire almost_full;
wire overflow;
wire empty;
wire almost_empty;
wire underflow;
wire [9:0] rd_data_count;
wire [9:0] wr_data_count;
// Instantiate the Unit Under Test (UUT)
My_fifo uut (
.rst(rst),
.wr_clk(wr_clk),
.rd_clk(rd_clk),
.din(din),
.wr_en(wr_en),
.rd_en(rd_en),
.dout(dout),
.full(full),
.almost_full(almost_full),
.overflow(overflow),
.empty(empty),
.almost_empty(almost_empty),
.underflow(underflow),
.rd_data_count(rd_data_count),
.wr_data_count(wr_data_count)
);
initial begin
wr_clk = 0;
forever #5 wr_clk = ~wr_clk; //f = 100MHZ
end
initial begin
rd_clk = 0;
forever #10.4 rd_clk = ~rd_clk; //48MHZ
end
//************************************************************
//該異步FIFO是高電平複位,是以給系統一個寫時鐘周期的複位信号,使FIFO複位。
//************************************************************
task reset;
begin
rst = 1;
@(posedge wr_clk);
rst = 0;
@(posedge wr_clk);
end
endtask
initial begin
// Initialize Inputs
rst = 0;
din = 0;
wr_en = 0;
rd_en = 0;
// Wait 100 ns for global reset to finish
#100;
reset;
// Add stimulus here
end
endmodule
參考資料:
http://www.cnblogs.com/BitArt/archive/2013/04/10/3010073.html