zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    HDU 4034 Graph:反向floyd
    POJ 2728 Desert King:最优比率生成树
    求树的最大独立集,最小点覆盖,最小支配集 贪心and树形dp
    AtCoder ARC061E Snuke's Subway Trip 最短路
    hdu4126_hdu4756_求最小生成树的最佳替换边_Kruskal and Prim
    洛谷 P2633 Count on a tree
    POJ3241 最小曼哈顿距离生成树
    HDU6315 Naive Operations 线段树
    ACM-ICPC 2018 沈阳赛区网络预赛-B,F,G
    LCA
  • 原文地址:https://www.cnblogs.com/wt-seu/p/12355764.html
Copyright © 2011-2022 走看看