非2次幂(也可2次幂)的异步fifo的verilog实现

原理参照这个第7部分:各种FIFO硬件设计(FIFO概念、异步、同步、非2次幂深度FIFO)_fifo设计-优快云博客

我发现大家的异步fifo或多或少存在一些问题,我在上面这个老哥的基础上修改了一些地方:

1.去除了判断时候的偏移

2.二进制计数器的范围大小,以及到ram的地址映射

3.bram修改为不是ip,方便移植

4.testbench的值的提供不用延时,采用always模块根据full和empty状态提供输入,而且我的是边写边读验证,一般人都是先写后读验证;

5.修改tb文件的 FIFO_DEPTH_COMPLE为0,可以实现2次幂整数的异步fifo,也就是这个代码是兼容的

代码如下:

顶层代码

module Asyn_no2power#(
        //BLOCK RAM address width 
        parameter   integer RAM_ADDR_WIDTH = 5,
        //FIFO true depth
        parameter   integer FIFO_DATA_DEPTH = 6,
        //FIFO compensate depth,(FIFO_DATA_DEPTH+FIFO_DEPTH_COMPLE) must be the data of power 2
        parameter   integer FIFO_DEPTH_COMPLE = 2,
        parameter   integer FIFO_ADDR_WIDTH = $clog2(FIFO_DATA_DEPTH+FIFO_DEPTH_COMPLE),
        parameter   integer FIFO_DATA_WIDTH = 8
    )(
        input   wire                              nrst,
        input   wire                             clk_w,
        input   wire                             wr_en,
        input   wire [FIFO_DATA_WIDTH-1:0]      wrdata,
        output  reg                         fifo_full,
 
        input   wire                             clk_r,
        input   wire                             rd_en,
        output  wire [FIFO_DATA_WIDTH-1:0]      rddata,
        output  reg                        fifo_empty
    );


/*
    w_ptr : the write data pointer (RAM Write address)
    r_ptr : the read data pointer (RAM Read address)
*/
    wire    fifo_full_wire;
    wire    fifo_empty_wire;
    reg   [FIFO_ADDR_WIDTH:0] w_ptr;
    reg   [FIFO_ADDR_WIDTH:0] r_ptr;
    wire [RAM_ADDR_WIDTH-1:0] ram_wr_addr;
    wire [RAM_ADDR_WIDTH-1:0] ram_rd_addr;
    wire [FIFO_ADDR_WIDTH:0] w_ptr_shift;
    wire [FIFO_ADDR_WIDTH:0] r_ptr_shift;

    assign w_ptr_shift  =   (w_ptr>=2**FIFO_ADDR_WIDTH)?w_ptr:w_ptr-FIFO_DEPTH_COMPLE;
    assign r_ptr_shift  =   (r_ptr>=2**FIFO_ADDR_WIDTH)?r_ptr:r_ptr-FIFO_DEPTH_COMPLE;
    
    assign ram_wr_addr  =   {
  {(RAM_ADDR_WIDTH-FIFO_ADDR_WIDTH){1'b0}},w_ptr_shift[FIFO_ADDR_WIDTH-1:0]};
    assign ram_rd_addr  =   {
  {(RAM_ADDR_WIDTH-FIFO_ADDR_WIDTH){1'b0}},r_ptr_shift[FIFO_ADDR_WIDTH-1:0]};

    wire   fifo_wr;
    wire   fifo_rd;


/*
    fifo_wr :  (RAM Write enable). valid only when fifo is not full and fifo data wr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值