查看: 1238|回复: 0
打印 上一主题 下一主题

开源Verilog HDL原创FIFO模块

[复制链接]
跳转到指定楼层
沙发
发表于 2015-4-1 12:38:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
开源Verilog HDL原创FIFO模块,包含测试文件,请勿用于商业用途,用于出版或教程请联系本人。

module fifo(rst,iclk,ien,oclk,oen,idat,odat,full,empty);
        parameter datbits = 8, addrbits = 4;
        parameter low = 1'b0, hi = 1'b1, true = low, false = hi;
        input rst,iclk,oclk,ien,oen; //复位,输入时钟、输出时钟,输入使能,输出使能
        input [datbits-1:0]idat; //输入数据
        output [datbits-1:0]odat; //输出数据
        output full,empty; //fifo满,空
        reg [datbits-1:0]mem[0:2**addrbits-1]; //2^addrbits字节RAM块
        reg [addrbits-1:0]rdaddr = {addrbits{1'b1}}; //fifo读地址
        reg [addrbits-1:0]wraddr = {addrbits{1'b0}}; //fifo写地址
        wire [addrbits-1:0]delt = wraddr - rdaddr; //有效数据数+1
        assign full = delt == 1'b0 ? true : false; //fifo满信号
        assign empty = delt == 1'b1 ? true : false; //fifo空信号
        assign odat = oen == true ? mem[rdaddr] : {datbits{1'bz}}; //输出控制
        initial begin //初始化
                wraddr = {addrbits{1'b0}}; //写地址复位
                rdaddr = {addrbits{1'b1}}; //读地址复位
                end //初始化
        always @(negedge iclk or negedge rst) begin //push
                if(rst == low) begin //复位
                        wraddr <= {addrbits{1'b0}}; //写地址复位
                        end
                else begin //进栈
                        if(ien == true) begin //输入使能
                                mem[wraddr] <= idat; //进栈
                                wraddr <= wraddr + 1'b1; //写地址调整
                                end
                        end //进栈
                end //push
        always @(negedge oclk or negedge rst) begin //pop
                if(rst == low) begin //复位
                        rdaddr <= {addrbits{1'b1}}; //读地址复位
                        end
                else begin //出栈
                        if(oen == true) begin //输出使能
                                rdaddr <= rdaddr + 1'b1; //读地址调整
                                end
                        end //出栈
                end //pop        
endmodule

`timescale 1ps/1ps
module testbench();
        parameter low = 1'b0, hi = 1'b1, true = low, false = hi;
        wire [7:0]odat;
        wire ick,ock;
        reg iclk,oclk;
        assign ick = iclk;
        assign ock = oclk;
        wire iena,oena;
        reg ien,oen;
        assign iena = ien;
        assign oena = oen;
        wire full,empty;
        wire [7:0]idat;
        reg [7:0]dat;
        assign idat = dat;
        always #1 iclk <= ~iclk;
        always #3 oclk <= ~oclk;
        initial begin
                iclk = hi;
                oclk = hi;
                dat = 8'd0;
                end
        always @(posedge iclk) begin
                if(full == true) ien <= false;
                else begin
                        ien <= true;
                        dat <= dat + 1'b1;
                        end
                end
        always @(posedge oclk) begin
                if(empty == true) oen <= false;
                else oen <= true;
                end
        fifo #(8,3) f1(hi,ick,iena,ock,oena,idat,odat,full,empty);
endmodule
复制代码

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

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