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