通过仿真认识xilinx fifo 内核

一 介绍

通过仿真FIFO IP,进一步理解FIFO工作机制以及各信号变化情况。

二 fifo配置

1 first word fall through类型

配置一个FIFO,配置参数如下图,关键参数,read mode选择first word fall through,数据宽度8,深度2048,设置prog full阈值为1279,勾选输出count标识。

通过仿真认识xilinx fifo 内核_第1张图片

 通过仿真认识xilinx fifo 内核_第2张图片

2 standard fifo类型

与first类型的区别如下:

通过仿真认识xilinx fifo 内核_第3张图片

 三 仿真代码功能描述

复位后,向fifo中写数据,写满后,再依次读出来,fifo为空后再次写数据,按此无限循环。

四 仿真结果

1 first word fall through类型

仿真图形如下

通过仿真认识xilinx fifo 内核_第4张图片

上图,系统复位后开始往fifo中写数据,可以发现:

  1. wr_en有效,则往fifo写入din的数据,同时count计数增加1。
  2. fifo存了2个数据,empty信号才有效。
  3. empty有效后,dout引脚出现fifo中的第一个数据。

通过仿真认识xilinx fifo 内核_第5张图片

上图,fifo写入prog full设置的阈值1279个数据后,prog full信号有效。

通过仿真认识xilinx fifo 内核_第6张图片上图,fifo写满,可以发现:

  1. fifo设置的深度为2048,但是full信号在fifo存了2049个数据后才有效,并且full有效时还能写入1个数据,fifo能够存放2050个数据。
  2. rd_en有效,从fifo读出数据,同时count计数减1。

通过仿真认识xilinx fifo 内核_第7张图片

上图,fifo数据读完,fifo没有数据时empty有效。

2 standard fifo类型

仿真图如下:

通过仿真认识xilinx fifo 内核_第8张图片

上图,系统复位后开始往fifo中写数据,可以发现:

  1. wr_en有效,向fifo写数据,count计数加1;
  2. fifo有数据后,empty信号立马有效;
  3. dout引脚一直为0;

通过仿真认识xilinx fifo 内核_第9张图片

上图,fifo内存有1279个数据后,prog_full有效。

通过仿真认识xilinx fifo 内核_第10张图片

上图,fifo写满,可以发现:

  1. fifo存满2048个数据后再向fifo中写数据,full会有效,同时count溢出,从下图可以看出差异(下图是修改了testbench代码,修改wr_en拉低时刻),实际fifo可以存放2049个数据,之后无法向fifo中写入数据;
  2. 通过仿真认识xilinx fifo 内核_第11张图片
  3. full有效期间,count计数器溢出,标明fifo中有2049个数据,之后wr_en有效但不会写入数据,这个在下图读出fifo数据仿真图中是可以看到。
  4. rd_en有效,同时count开始减1,从溢出状态变为2047。
  5. dout从rd_en有效2个时钟后开始输出数据。

通过仿真认识xilinx fifo 内核_第12张图片 

上图,fifo读空,可以发现:

  1. dout数据相较rd_en延迟2个时钟才输出。
  2. empty有效期间,rd_en没有意义,不会从fifo中读出数据。
  3. empty上升沿到来时,实际fifo还有2个数据没有输出。

五 结论

对比fifo的两种read mode模式,如下:

stardard mode

first  word fall through

dout输出fifo数据的时刻

(相较于rd_en信号延迟时钟数)

0

2

fifo容量

2049

2050

full有效时刻

fifo存满2049

fifo存满2050

full无效时刻

rd_en有效

rd_en有效

empty有效时刻

count =0

count=0

empty无效时刻

count=0

count = 2

prog_flag有效时刻

count=1279

count=1279

仿真代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 09/21/2022 02:08:52 PM
// Design Name: 
// Module Name: tb_fifo
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_fifo(

    );
    reg         clk;
    reg         srst;
    reg [7:0]   din;
    reg         wr_en;
    reg         rd_en;
    wire  [7:0]      dout;
    wire        full;
    wire        empty;
    wire  [10:0]          data_count;
    wire            prog_full;
    wire            wr_rst_busy;
    wire            rd_rst_busy;
    
    
    initial begin
        clk = 0;
        srst = 1;
        din =0;
        wr_en = 0;
        rd_en = 0;
        #100;
        srst    =0;
        
    end
    always  #5  clk = ~clk;
    
    reg [1:0]   st;
    always @(posedge clk)begin
        if(~srst)begin
            case(st)
            2'd0:begin//wr
                wr_en <= 1'b1;
                din <= din + 1'b1;
                if(data_count == 11'd2046)begin//full
                    st <= 2'd1;
                    wr_en <= 1'b0;
                    din <= 8'd0;
                end
            end
            2'd1:begin
                rd_en <= 1'b1;
                if(empty)begin
                    rd_en <= 1'b0;
                    st  <= 1'b0;
                end
            end
           
            default:begin
                st  <= 1'b0;
            end
            endcase
            
        end
        else begin
           din      <=  0;
           wr_en    <=  0;
           rd_en    <=  0; 
           st       <=  0;
        end
    end
    
//    fifo_generator_0 your_instance_name (  //first 
//      .clk(clk),                  // input wire clk
//      .srst(srst),                // input wire srst
//      .din(din),                  // input wire [7 : 0] din
//      .wr_en(wr_en),              // input wire wr_en
//      .rd_en(rd_en),              // input wire rd_en
//      .dout(dout),                // output wire [7 : 0] dout
//      .full(full),                // output wire full
//      .empty(empty),              // output wire empty
//      .data_count(data_count),    // output wire [11 : 0] data_count
//      .prog_full(prog_full),      // output wire prog_full
//      .wr_rst_busy(wr_rst_busy),  // output wire wr_rst_busy
//      .rd_rst_busy(rd_rst_busy)  // output wire rd_rst_busy
//    );
    fifo_generator_0 your_instance_name (//stardard fifo
  .clk(clk),                  // input wire clk
  .srst(srst),                // input wire srst
  .din(din),                  // input wire [7 : 0] din
  .wr_en(wr_en),              // input wire wr_en
  .rd_en(rd_en),              // input wire rd_en
  .dout(dout),                // output wire [7 : 0] dout
  .full(full),                // output wire full
  .empty(empty),              // output wire empty
  .data_count(data_count),    // output wire [10 : 0] data_count
  .prog_full(prog_full),      // output wire prog_full
  .wr_rst_busy(wr_rst_busy),  // output wire wr_rst_busy
  .rd_rst_busy(rd_rst_busy)  // output wire rd_rst_busy
);
endmodule

你可能感兴趣的:(fpga开发)