集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 976|回复: 1

同步FIFO代码

[复制链接]
fpga_feixiang 发表于 2020-10-13 14:31:42 | 显示全部楼层 |阅读模式
`define BUF_WIDTH   4     //地址宽度为3+1,
`define BUF_SIZE    8    //数据个数,FIFO深度

module fifo_counter( clk,rst_n,buf_in,buf_out,wr_en,rd_en,buf_empty,buf_full,fifo_cnt);
        input clk,rst_n;
        input wr_en,rd_en;
        input [7:0] buf_in;             // data input to be pushed to buffer
        output reg [7:0] buf_out;       // port to output the data using pop.
        output wire buf_empty,buf_full;  // buffer empty and full indication
        output reg [`BUF_WIDTH-1:0] fifo_cnt;  // number of data pushed in to buffer  
                                               //写入数据等于8时,满
       
        reg [`BUF_WIDTH-2:0] rd_ptr,wr_ptr;  //这个很重要,数据指针3位宽度,0-7索引,8个数据深度,循环指针0-7-0-7
        reg [7:0] buf_mem[0:`BUF_SIZE-1];
       
        //判断空满
        assign buf_empty = (fifo_cnt == 0);  //buf_empty若是reg类型则错,不能使用assign持续赋值
        assign buf_full  = (fifo_cnt == `BUF_SIZE);
       
        always @(posedge clk or negedge rst_n)begin
                if(!rst_n)
                        fifo_cnt <= 0;
                else if((!buf_full&&wr_en)&&(!buf_empty&&rd_en)) //同时读写,数量不变
                        fifo_cnt <= fifo_cnt;
                else if(!buf_full && wr_en)          //写数据
                        fifo_cnt <= fifo_cnt + 1;
                else if(!buf_empty && rd_en)         //读数据
                        fifo_cnt <= fifo_cnt-1;
                else
                        fifo_cnt <= fifo_cnt;
        end
       
        always @(posedge clk or negedge rst_n) begin   //读数据
                if(!rst_n)
                        buf_out <= 0;
                if(rd_en && !buf_empty)
                        buf_out <= buf_mem[rd_ptr];
        end
       
        always @(posedge clk) begin
                if(wr_en && !buf_full)
                        buf_mem[wr_ptr] <= buf_in;
        end
       
        always @(posedge clk or negedge rst_n) begin
                if(!rst_n) begin
                        wr_ptr <= 0;
                        rd_ptr <= 0;
                end
                else begin
                        if(!buf_full && wr_en)
                                wr_ptr <= wr_ptr + 1;
                        if(!buf_empty && rd_en)
                                rd_ptr <= rd_ptr + 1;
                end
        end
       
endmodule

使用Modelsim仿真的程序:
`define BUF_WIDTH   4     //地址宽度为3+1,
`define BUF_SIZE    (8)    //数据个数,FIFO深度

module tb_fifo_counter;
        reg clk,rst_n;
        reg wr_en,rd_en;
        reg [7:0] buf_in;             // data input to be pushed to buffer
        wire [7:0] buf_out;       // port to output the data using pop.
    wire buf_empty,buf_full;  // buffer empty and full indication
        wire [`BUF_WIDTH-1:0] fifo_cnt;  // number of data pushed in to buffer
       
        fifo_counter dut(clk,rst_n,buf_in,buf_out,wr_en,rd_en,buf_empty,buf_full,fifo_cnt);
       
        always #10 clk = ~clk;
       
        reg [7:0] tempdata = 0;
        initial begin
                clk = 0;
                rst_n = 0;
                wr_en = 0;
                rd_en = 0;
                buf_in = 0;
                #15;
                rst_n = 1;
               
                push(1);
        fork
           push(2);
           pop(tempdata);
        join              //push and pop together   
        push(10);
        push(20);
        push(30);
        push(40);
        push(50);
        push(60);
        push(70);
        push(80);
        push(90);
        push(100);
        push(110);
        push(120);
        push(130);

        pop(tempdata);
        push(tempdata);
        pop(tempdata);
        pop(tempdata);
        pop(tempdata);
        pop(tempdata);
                push(140);
        pop(tempdata);
        push(tempdata);//
        pop(tempdata);
        pop(tempdata);
        pop(tempdata);
        pop(tempdata);
        pop(tempdata);
        pop(tempdata);
        pop(tempdata);
        pop(tempdata);
        pop(tempdata);
        pop(tempdata);
        pop(tempdata);
        push(5);
        pop(tempdata);
               
        end
       
        task push (input [7:0] data);
                if(buf_full)
                        $display("---Cannot push %d: Buffer Full---",data);
                else begin
                        $display("Push",,data);
                        buf_in = data;
                        wr_en = 1;
                        @(posedge clk);
                        #5 wr_en = 0;
                end
        endtask
       
        task pop(output[7:0] data);
                if(buf_empty)
                        $display("---Cannot Pop: Buffer Empty---");
                else begin
                        rd_en = 1;
                        @(posedge clk);
                        #3 rd_en = 0;
                        data = buf_out;
                        $display("------Poped:",,data);
                end               
        endtask
       
       
endmodule

程序仿真打印结果:
# 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
zxopenhl 发表于 2020-10-13 18:42:01 | 显示全部楼层
同步FIFO代码
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2025-4-20 03:36 , Processed in 0.056897 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表