同步FIFO代码

sync_fifo.v

module sync_fifo #
(
DATA_WIDTH = 8,
DATA_DEPTH = 128
)
(
input  wire                  i_sys_clk   ,
input  wire                  i_sys_rst_n , 
input  wire                  i_wren      ,
input  wire [DATA_WIDTH-1:0] i_wdata     ,
input  wire                  i_rden      ,
output wire [DATA_WIDTH-1:0] o_rdata     ,
output wire                  o_full      ,
output wire                  o_empty
);

reg [DATA_WIDTH-1:0] mem_ram [0:DATA_DEPTH-1];

reg [clogb2(DATA_DEPTH-1)-1:0] r_wr_ptr;
reg [clogb2(DATA_DEPTH-1)-1:0] r_rd_ptr;

reg [clogb2(DATA_DEPTH-1)  :0] r_fifo_number;

//r_wr_ptr
always @(posedge i_sys_clk or negedge i_sys_rst_n)
begin
    if(!i_sys_rst_n)
        r_wr_ptr <= 0;
    else if(i_wren && !o_full)
        r_wr_ptr <= r_wr_ptr + 1;
    else
        r_wr_ptr <= r_wr_ptr;
end

//r_rd_ptr
always @(posedge i_sys_clk or negedge i_sys_rst_n)
begin
    if(!i_sys_rst_n)
        r_rd_ptr <= 0;
    else if(i_rden && !o_empty)
        r_rd_ptr <= r_rd_ptr + 1;
    else
        r_rd_ptr <= r_rd_ptr;
end

//write data
integer i;
always @(posedge i_sys_clk or negedge i_sys_rst_n)
begin
    if(!i_sys_rst_n)
    begin
        for(i = 0; i < DATA_DEPTH; i = i + 1)
            mem_ram[i] <= 0;
    end
    else if(i_wren && !o_full)
        mem_ram[r_wr_ptr] <= i_wdata;
end

//read data
reg [DATA_WIDTH-1:0] r_rdata;
always @(posedge i_sys_clk or negedge i_sys_rst_n)
begin
    if(!i_sys_rst_n)
        r_rdata <= 0;
    else if(i_rden && !o_empty)
        r_rdata <= mem_ram[r_rd_ptr];
end

//r_fifo_number
always @(posedge i_sys_clk or negedge i_sys_rst_n)
begin
    if(!i_sys_rst_n)
        r_fifo_number <= 0;
    else if(i_wren && !o_full && i_rden && !o_empty)
        r_fifo_number <= r_fifo_number;
    else if(i_wren && !o_full && !i_rden)
        r_fifo_number <= r_fifo_number + 1;
    else if(i_rden && !o_empty && !i_wren)
        r_fifo_number <= r_fifo_number - 1;
    else
        r_fifo_number <= r_fifo_number;
end

assign o_rdata = r_rdata;
assign o_full  = (r_fifo_number == DATA_DEPTH);
assign o_empty = (r_fifo_number == 0);

function integer clogb2(input number);
    for(clogb2 = 0; number > 0; clogb2 = clogb2 +1)
        number = number >> 1;
endfunction

endmodule

tb_sync_fifo.v

`timescale 1ns/1ps
`define CLK_PERILOD 20

module tb_sync_fifo;

parameter DATA_WIDTH = 8;
parameter DATA_DEPTH = 128;

reg                   clk;
reg                   rst_n;
reg                   wren;
reg                   rden;
wire [DATA_WIDTH-1:0] rdata;
reg  [DATA_WIDTH-1:0] wdata;
wire                  full;
wire                  empty;


sync_fifo u_synv_fifo(
    .i_sys_clk(clk)    ,
    .i_sys_rst_n(rst_n),
    .i_wren(wren)      ,
    .i_rden(rden)      ,
    .i_wdata(wdata)    ,
    .o_rdata(rdata)    ,
    .o_full(full)      ,
    .o_empty(empty)
);

initial begin
    clk = 0;
    forever
        #(`CLK_PERILOD/2) clk = ~clk;
end

initial begin
    rst_n = 0;
    repeat(20) @(posedge clk);
    rst_n = 1;
end

initial begin
    wren = 0;
    wdata = 0;
    repeat(30) @(posedge clk);
    wren = 1;
    repeat(300) @(posedge clk) wdata = wdata + 1;
    $stop;
end

initial begin
    rden = 0;
    repeat(130) @(posedge clk);
    rden = 1;
end

initial begin
    $fsdbDumpfile("sync_fifo.fsdb");
    $fsdbDumpvars(0);
end


endmodule

具体代码可以参考代码仓 sync_fifo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值