同步FIFO设计(代码篇)

//同步FIFO设计

//深度16 位宽16
module top
#(
    parameter   depth = 16  ,
    parameter   width = 16

)
(
    input                   clk         ,
    input                   rst_n       ,
    input                   wr_en       ,
    input   [width-1:0]     data_in     ,
            
    input                   rd_en       ,
    output  [width-1:0]     data_out    ,
    
    output                  full        ,
    output                  empty       
);

reg     [width-1:0]     mem [depth:0]   ;
reg     [4:0]           waddr           ;
reg     [4:0]           raddr           ;
reg     [width-1:0]     temp_rdata      ;

//写指针
always@(posedge clk or negedge rst_n)
begin
    if (!rst_n)
        waddr <= 5'b0_0000;
    else if (wr_en ==1'b1)
        waddr <= waddr + 1'b1;
    else 
        waddr <= waddr ;
end 

//读指针
always@(posedge clk or negedge rst_n)
begin
    if (!rst_n)
        raddr <= 5'b0_0000;
    else if (rd_en ==1'b1)
        raddr <= raddr + 1'b1;
    else 
        raddr <= raddr ;
end 

//写数据
always@(posedge clk)
begin
    mem[waddr] <= data_in;
end

//读数据 1 latency
assign  data_out = temp_rdata;

always@(posedge clk or negedge rst_n)
begin 
    if (!rst_n)
        temp_rdata <= {width{1'b0}};
    else 
        temp_rdata <= mem[raddr];
end 

//空信号判断
assign  empty = (waddr == raddr) ? 1'b1 : 1'b0;

//满信号判断
assign  full = ({~waddr[4],waddr[3:0]} == raddr) ? 1'b1 : 1'b0;

endmodule

//testbench
`timescale 1ns/1ns
module top_test();

reg             clk     ;
reg             rst_n   ;
reg             wr_en   ;
reg     [15:0]  data_in ;
reg             rd_en   ;
wire            full    ;
wire            empty   ;
wire    [15:0]  data_out;

top top_inst1(
    .clk         (clk     ),
    .rst_n       (rst_n   ),
    .wr_en       (wr_en   ),
    .data_in     (data_in ),

    .rd_en       (rd_en   ),

    .data_out    (data_out),
    .full        (full    ),
    .empty       (empty   )
);    

initial
begin 
    clk = 1'b0;
    rst_n  = 1'b0;
    wr_en = 1'b0;
    rd_en = 1'b0;
    data_in = 16'h0000;
    
    repeat(5)@(posedge clk);
    rst_n = 1'b1;
    repeat(5)@(posedge clk);
    drive_w();
    repeat(5)@(posedge clk);
    drive_r();
end 

task    drive_w;
    integer i;
    begin
        for (i=0;i<16;i=i+1)
        begin 
            wr_en   <= 1'b1;
            data_in <= i[15:0];
            @(posedge clk);
            wr_en   <= 0;
        end 
    end 
endtask

task    drive_r;
    integer i;
    begin 
        for (i=0;i<16;i=i+1)
        begin 
            rd_en   <= 1'b1;
            @(posedge clk);
            rd_en   <= 1'b0;
        end
    end 
endtask

always # 10 clk = ~clk;

endmodule

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值