同步FIFO设计

1. 同步FIFO原理

        请看《硬件架构的艺术》笔记(三)3.7 同步FIFO

2. Verilog 设计

module sync_fifo
(
    fifo_wr     ,
    fifo_rd     ,
    fifo_din    ,
    fifo_dout   ,
    fifo_full   ,
    fifo_empty  ,
    clk         ,
    rstn
); 

parameter FIFO_WIDTH = 16,
          FIFO_DEPTH = 8,
          FIFO_ADDR_BIT = 3;
       
input   wire    fifo_wr;
input   wire    fifo_rd;
input   wire    [FIFO_WIDTH-1:0]    fifo_din;
output  reg     [FIFO_WIDTH-1:0]    fifo_dout ;
output  wire    fifo_full;
output  wire    fifo_empty;

input   wire    clk;
input   wire    rstn;

integer i;

reg [FIFO_WIDTH-1:0] mem [0:FIFO_DEPTH-1];

//---读写指针扩展一位---//
reg [FIFO_ADDR_BIT:0]rd_ptr;
reg [FIFO_ADDR_BIT:0]wr_ptr;

always@(posedge clk or negedge rstn)begin 
    if(~rstn)begin 
        wr_ptr <= 'b0;
    end else if(fifo_wr && !fifo_full)begin 
        wr_ptr <= wr_ptr + 1'b1;
    end 
end 

always@(posedge clk or negedge rstn)begin 
    if(~rstn)begin 
        rd_ptr <= 'b0;
    end else if(fifo_rd && !fifo_empty)begin 
        rd_ptr <= rd_ptr + 1'b1;
    end 
end 

//--- write in ---//
always@(posedge clk or negedge rstn)begin 
    if(~rstn)begin 
        for(i=0; i<FIFO_DEPTH; i=i+1)begin
            mem[i] <= 'd0;
        end 
    end else if (fifo_wr && !fifo_full)begin
        mem[wr_ptr[FIFO_ADDR_BIT-1:0]] <= fifo_din;
    end 
end 
    
assign fifo_full = (wr_ptr[FIFO_ADDR_BIT] != rd_ptr[FIFO_ADDR_BIT])
                    & (wr_ptr[FIFO_ADDR_BIT-1:0] == rd_ptr[FIFO_ADDR_BIT-1:0]);

//--- read out ---//

always@(posedge clk or negedge rstn)begin 
    if(~rstn)begin
        fifo_dout <= 'd0;
    end 
    else if(fifo_rd && !fifo_empty)begin
        fifo_dout = mem[rd_ptr[FIFO_ADDR_BIT-1:0]];    
    end 
end 

assign fifo_empty = (wr_ptr == rd_ptr)? 1'b1 : 1'b0;

endmodule 

3. 测试用例(testbench)

`timescale 1ns/1ns 

module tb();

parameter FIFO_WIDTH = 16,
          FIFO_DEPTH = 8,
          FIFO_ADDR_BIT = 3;

reg clk,rstn,fifo_wr,fifo_rd;
reg [FIFO_WIDTH-1:0] fifo_din;

wire    fifo_empty,fifo_full;
wire    [FIFO_WIDTH-1:0] fifo_dout;

always begin 
    #10 clk = ~clk;
end 

initial begin 
    rstn = 0;
    clk  = 0; 
    repeat(5) @(posedge clk);
    rstn = 1;
end 

initial begin 
    fifo_wr = 0;
    repeat(3) @(posedge clk);
    fifo_wr = 1;
end 

initial begin   
    fifo_rd = 0;
    repeat(100) @(posedge clk);
    fifo_rd = 1;
    fifo_wr = 0;
end 

initial begin 
    fifo_din = 16'h0;
    #20 fifo_din = 16'h1;
    #20 fifo_din = 16'h2;
    #20 fifo_din = 16'h3;
    #20 fifo_din = 16'h4;
    #20 fifo_din = 16'h5;
    #20 fifo_din = 16'h6;
    #20 fifo_din = 16'h7;
    #20 fifo_din = 16'h8;
    #20 fifo_din = 16'h9;
    #20 fifo_din = 16'ha;
    #20 fifo_din = 16'hb;
    #20 fifo_din = 16'hc;   
    #20 fifo_din = 16'hd;
    #20 fifo_din = 16'he;
    #20 fifo_din = 16'hf;   

    repeat(200) @(posedge clk);
    $finish();
    
end 

sync_fifo sync_fifo_inst
(
    .fifo_wr     (fifo_wr   ),
    .fifo_rd     (fifo_rd   ),
    .fifo_din    (fifo_din  ),
    .fifo_dout   (fifo_dout ),
    .fifo_full   (fifo_full ),
    .fifo_empty  (fifo_empty),
    .clk         (clk       ),
    .rstn        (rstn      )
); 

endmodule 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值