FPGA之FIFO设计(二)

时间:2021-11-20 23:36:20

异步FIFO在ISE下有两种生成方法:

         法一:使用CORE Generator生成的DPRAM和自己设计的FIFO控制逻辑,将两者连在一起就构成了FIFO。

         法二:直接使用FIFO的IP核。

现在我们来做一件事情:异步时钟域的芯片A和B,假设A的频率是48MHZ,B的频率是100MHZ。设计一个异步FIFO,使得B发送的数据可以被A正确接收。A和B的数据宽度均为16。

         使用ISE的FIFO IP核:

FPGA之FIFO设计(二)

选择这个IP核接着进入设置:Native类型就是之前的,可用于block ram,distributed ram等;AXI4就是支持AXI4总线标准的FIFO,在系统设计的时候用得到。这里我们选择Native就可以了。

FPGA之FIFO设计(二)

Step 2:如果我们选择Common Clock的话就会生成同步FIFO,选择Independent Clocks就变成了异步FIFO。后面的Features就是支持不同读写数据位宽,支持ECC数据校验,首字直通等等。具体地去看Datasheet!

FPGA之FIFO设计(二)

Step 3:选择First-Word-Fall-Through。这就可以没有延时读出数据。另外一个就会有一个周期延时。下面就可以设置位宽。

FPGA之FIFO设计(二)

Step 4:这里选择标志位,几乎满,几乎空。

FPGA之FIFO设计(二)

Step 5:选择复位设置复位后的值为0。

FPGA之FIFO设计(二)

Step 6:这里设置Count记录的是读或者写的数据的数量。

FPGA之FIFO设计(二)

Step 7:例化

FPGA之FIFO设计(二)

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