开源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 
复制代码 
 
 |