• Verilog-同步FIFO


    参考博客:https://blog.csdn.net/hengzo/article/details/49683707

    1、基本框图

      1)双端口RAM加两个读写指针

      2)写数据、写使能、写满;读数据、读使能、读满

     2、代码思路

      

      1)Full和Empty的产生:使用fifo_counter记录FIFO RAM中的数据个数,等于0时,给出empty信号,等于BUF_LENGTH时,给出full信号

      2)fifo_counter的更新:发生有效写操作时+1,发生有效读操作时-1,同时发生读写操作时不变

      3)读写指针的控制:读写指针宽度与地址宽度相当,地址增加而溢出后,自动变成0。循环指针。初始时刻都指到0,发生有效写时写指针+1,写指针指向将要写的地址;发生有效读时读指针-1,读指针指向将要读的地址。

    3、代码

    `timescale 1ns / 1ps
    
    module synchronous_fifo
     #(parameter BUF_WIDTH=3,  //地址宽度为3,
        parameter BUF_SIZE=8)   //数据个数,FIFO深度 
    (
        input clk,
        input rst_n,
        input wr_en,
        input rd_en,
        input [7:0] buf_in,
        output [7:0] buf_out,
        output buf_full,
        output buf_empty,
        output [BUF_WIDTH:0] fifo_cnt
        );
       
    
    reg [7:0] buf_mem [0:BUF_SIZE-1];  // 双端口RAM
    reg [BUF_WIDTH-1:0] rd_ptr,wr_ptr; // 读写指针
    reg [7:0] buf_out_reg;
    reg [BUF_WIDTH:0] fifo_cnt_reg; // 存入数据的计数,0-8,位宽要比地址位宽大1
    
    //========= 写入 ============
    always @(posedge clk) begin
        if(wr_en&&!buf_full) begin
            buf_mem[wr_ptr] <= buf_in;
        end
    end
    
    //========= 读出 ============
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            buf_out_reg <= 8'd0;
        end
        else begin
            if(rd_en&&!buf_empty) begin
                buf_out_reg <= buf_mem[rd_ptr];
            end
            else buf_out_reg <= buf_out_reg;
        end
    end
    
    assign buf_out = buf_out_reg;
    
    //========= 数据计数 ============
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            fifo_cnt_reg <= {(BUF_WIDTH+1){1'b0}};
        end
        else begin
            if((wr_en&&!buf_full)&&((rd_en&&!buf_empty))) 
                fifo_cnt_reg <= fifo_cnt_reg;
            else if(wr_en&&!buf_full)
                fifo_cnt_reg <= fifo_cnt_reg+1'b1;
            else if(rd_en&&!buf_empty)
                fifo_cnt_reg <= fifo_cnt_reg-1'b1;
            else fifo_cnt_reg <= fifo_cnt_reg;
        end
    end
    assign fifo_cnt = fifo_cnt_reg;
    
    //========= 读写指针控制 ============
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            rd_ptr <= {BUF_WIDTH{1'b0}};
        end
        else begin
            if(rd_en&&!buf_empty) rd_ptr <= rd_ptr + 1'b1;
            else rd_ptr <= rd_ptr;
        end
    end
    
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            wr_ptr <= {BUF_WIDTH{1'b0}};
        end
        else begin
            if(wr_en&&!buf_full) wr_ptr <= wr_ptr + 1'b1;
            else wr_ptr <= wr_ptr;
        end
    end
    
    //========= 空满判断 ============
    assign buf_full = (fifo_cnt_reg == BUF_SIZE)?1'b1:1'b0;
    assign buf_empty = (fifo_cnt_reg == {(BUF_WIDTH+1){1'b0}})?1'b1:1'b0;
    
    endmodule

    his is a Full version of ISim.
    Time resolution is 1 ps
    Simulator is doing circuit initialization process.
    Finished circuit initialization process.
    Push   1
    Push   2
    ------Poped:   1
    Push  10
    Push  20
    Push  30
    Push  40
    Push  50
    Push  60
    Push  70
    ---Cannot push  80: Buffer Full---
    ---Cannot push  90: Buffer Full---
    ---Cannot push 100: Buffer Full---
    ---Cannot push 110: Buffer Full---
    ---Cannot push 120: Buffer Full---
    ---Cannot push 130: Buffer Full---
    ------Poped:   2
    Push   2
    ------Poped:  10
    ------Poped:  20
    ------Poped:  30
    ------Poped:  40
    Push 140
    ------Poped:  50
    Push  50
    ------Poped:  60
    ------Poped:  70
    ------Poped:   2
    ------Poped: 140
    ------Poped:  50
    ---Cannot Pop: Buffer Empty---
    ---Cannot Pop: Buffer Empty---
    ---Cannot Pop: Buffer Empty---
    ---Cannot Pop: Buffer Empty---
    ---Cannot Pop: Buffer Empty---
    ---Cannot Pop: Buffer Empty---
    Push   5
    ------Poped:   5
  • 相关阅读:
    边工作边刷题:70天一遍leetcode: day 25-2
    边工作边刷题:70天一遍leetcode: day 25-1
    边工作边刷题:70天一遍leetcode: day 25
    边工作边刷题:70天一遍leetcode: day 26-1
    边工作边刷题:70天一遍leetcode: day 26
    边工作边刷题:70天一遍leetcode: day 27-2
    边工作边刷题:70天一遍leetcode: day 27-1
    边工作边刷题:70天一遍leetcode: day 27
    边工作边刷题:70天一遍leetcode: day 28-2
    c#中sqlhelper类的编写(二)
  • 原文地址:https://www.cnblogs.com/wt-seu/p/12355764.html
Copyright © 2020-2023  润新知