FIFO预读取模式实现

FIFO标准读模式:rd_en有效后,数据在下一周期输出。

FFIO预读取模式:提前将下一数据输出到总线上(无需等待rd_en触发),使得读操作零延迟,下游模块可以立即获取数据。 

FIFO 预读取模式的优势

(1)减少流水线气泡:下游模块无需等待数据就绪。

(2)简化控制逻辑:读数据总线始终有效,可直接连接组合逻辑。

(3)提高吞吐量:每个时钟周期均可发起新读操作。

 FIFO代码


module fifo_prefetch #(
    parameter DATA_WIDTH = 8,   
    parameter ADDR_WIDTH = 4   
)(
    input  wire clk,           
    input  wire rst_n,        
    
    input  wire wr_en,        
    input  wire [DATA_WIDTH-1:0] wr_data,  
    output wire full,          
    //  
    input  wire rd_en,         
    output wire [DATA_WIDTH-1:0] rd_data,  
    output wire empty          
);
 
//  
reg [DATA_WIDTH-1:0] mem [0:(1<<ADDR_WIDTH)-1];

//  
reg [ADDR_WIDTH:0] wr_ptr;  
reg [ADDR_WIDTH:0] rd_ptr;  

//  
assign full  = (wr_ptr[ADDR_WIDTH-1:0] == rd_ptr[ADDR_WIDTH-1:0]) 
                && (wr_ptr[ADDR_WIDTH] != rd_ptr[ADDR_WIDTH]);
assign empty = (wr_ptr == rd_ptr);

//  
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        wr_ptr <= 0;
    end else if (wr_en && !full) begin
        wr_ptr <= wr_ptr + 1;
        mem[wr_ptr[ADDR_WIDTH-1:0]] <= wr_data;  
    end
end

//  
wire [ADDR_WIDTH:0] rd_ptr_next = rd_ptr + 1;
//  
wire [DATA_WIDTH-1:0] rd_data_prefetch = 
    (empty) ? {DATA_WIDTH{1'b0}} : mem[rd_ptr[ADDR_WIDTH-1:0]];

//  
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        rd_ptr <= 0;
    end else if (rd_en && !empty) begin
        rd_ptr <= rd_ptr_next; //  
    end
end

//  
assign rd_data = rd_data_prefetch;

endmodule





测试程序

module tb_fifo_prefetch;
    reg clk; 
    reg rst_n;
    reg wr_en; 
    reg rd_en;
    reg [7:0] wr_data;
    wire [7:0] rd_data;
    wire full;
    wire empty; 
    
    localparam CLK_PERIOD = 20;

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

    integer i;
     
    initial begin
        rst_n = 0;
        wr_en = 0;
        rd_en = 0;
        wr_data = 0;

        #(10*CLK_PERIOD) rst_n = 1;
        //  
        for (i=0; i < 16; i = i + 1) 
        begin
            @(posedge clk)
            begin 
                wr_en <= 1;
                wr_data <= i + 8'hA0;
            end
        end
            
        for (i=0; i < 2; i = i + 1) 
        begin
            @(posedge clk); 
              wr_en <= 0;
        end
        //
        for (i=0; i < 5; i = i + 1) 
        begin
            @(posedge clk) 
               rd_en <= 1;
        end
        
        for (i=0; i < 2; i = i + 1) 
        begin
        @(posedge clk) 
           rd_en <= 0;
        end

        for (i=0; i < 3; i = i + 1) 
        begin
            @(posedge clk) 
               rd_en <= 1;
        end

        for (i=0; i < 8; i = i + 1) 
        begin
        @(posedge clk) 
           rd_en <= 0;
        end

        $finish;
 
    end 
  
    fifo_prefetch #(
        .DATA_WIDTH(8),
        .ADDR_WIDTH(4)
    )uut(
        .clk(clk),
        .rst_n(rst_n),
        .wr_en(wr_en),
        .wr_data(wr_data),
        .full(full),
        .rd_en(rd_en),
        .rd_data(rd_data),
        .empty(empty)
    );
 
endmodule 

仿真

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值