异步FIFO的Verilog代码

// *****************************************************************************
// Project Name     : *
// Target Device    : *
// Tool version     : *
// Module Name      : dcfifo
// Description      : Dual Clock First In First Out
// Function         : asynchronous FIFO
// Attention        : The FIFO must be reseted firstly before used
// Version History  : *
// *****************************************************************************
// Engineer         : zyhe
// Date             : 2016-01-01
// Modification     : 1) initial version
// *****************************************************************************
// Engineer         : zyhe
// Date             : 2016-05-01
// Modification     : 1) standard coding style
//                    i_ for input, o_ for output, w_ for wire, r_ for register
// *****************************************************************************
// All rights reserved.
// *****************************************************************************
 
`timescale 1ns / 1ps
 
module dcfifo # (
    parameter   DW      = 8                 , // Data Width
    parameter   AW      = 4                   // Address Width
    ) (
    input               i_wr_rst            , // write reset, active high
    input               i_wr_clk            , // write clock
    input               i_wr_ena            , // write enable
    input       [DW-1:0]i_wr_dat            , // write data
    output  reg         o_wr_ful            , // write full
    input               i_rd_rst            , // read reset, active high
    input               i_rd_clk            , // read clock
    input               i_rd_ena            , // read enable
    output      [DW-1:0]o_rd_dat            , // read data
    output  reg         o_rd_ept              // read empty
    );
 
    reg [DW-1:0]r_2d_mem[0:(1<> 1);
    assign  w_rd_adr = r_rd_adr + (i_rd_ena & ~o_rd_ept);
    assign  w_rd_gry = w_rd_adr ^ (w_rd_adr >> 1);
    assign  o_rd_dat = r_2d_mem[r_rd_adr[AW-1:0]];
 
    always @ (posedge i_wr_clk)
    begin
        if (i_wr_ena & ~o_wr_ful)
            r_2d_mem[r_wr_adr[AW-1:0]] <= i_wr_dat;
    end
 
    always @ (posedge i_wr_clk)
    begin
        if (i_wr_rst)
        begin
            r_wr_gry <= 0;
            r_wr_adr <= 0;
            r_rd_gry_d0 <= 0;
            r_rd_gry_d1 <= 0;
            o_wr_ful <= 0;
        end
        else
        begin
            r_wr_gry <= w_wr_gry;
            r_wr_adr <= w_wr_adr;
            r_rd_gry_d0 <= r_rd_gry;
            r_rd_gry_d1 <= r_rd_gry_d0;
            o_wr_ful <= (w_wr_gry == {~r_rd_gry_d1[AW:AW-1], r_rd_gry_d1[AW-2:0]});
        end
    end
 
    always @ (posedge i_rd_clk)
    begin
        if (i_rd_rst)
        begin
            r_rd_gry <= 0;
            r_rd_adr <= 0;
            r_wr_gry_d0 <= 0;
            r_wr_gry_d1 <= 0;
            o_rd_ept <= 1;
        end
        else
        begin
            r_rd_gry <= w_rd_gry;
            r_rd_adr <= w_rd_adr;
            r_wr_gry_d0 <= r_wr_gry;
            r_wr_gry_d1 <= r_wr_gry_d0;
            o_rd_ept <= (w_rd_gry == r_wr_gry_d1);
        end
    end
 
endmodule

 

你可能感兴趣的:(异步FIFO的Verilog代码)