搜档网
当前位置:搜档网 › FIFO的verilog语言代码(含测试代码)

FIFO的verilog语言代码(含测试代码)

FIFO存储器的设计(后面是测试程序的部分)
module fifo (clk, rstp, din, writep, readp, dout, emptyp, fullp);
input clk;
input rstp; //复位信号
input [15:0] din;
input readp; //读信号
input writep; //写信号
output [15:0] dout;
output emptyp; //空标志
output fullp; //满标志
parameter DEPTH = 2,
MAX_COUNT = 2‘b11; //定义地址最大值
reg emptyp;
reg fullp;
reg [15:0] dout;
reg [(DEPTH-1):0] tail; //定义读指针
reg [(DEPTH-1):0] head; //定义写指针
// 定义计数器
reg [(DEPTH-1):0] count;
reg [15:0] fifomem[0:MAX_COUNT]; //定义fifomem存储器有4个16位的存储器

// dout被赋给tail指向的值
always @(posedge clk) begin
if (rstp == 1) begin
dout <= 16‘h0000; //复位信号有效置0
end
else begin
dout <= fifomem[tail]; //将fifomem中第tail个单元赋给dout
end
end
always @(posedge clk) begin
if (rstp == 1'b0 && writep == 1'b1 && fullp == 1'b0) begin
fifomem[head] <= din; //写入
end
end
always @(posedge clk) begin
if (rstp == 1'b1) begin
head <= 2‘b00; //复位
end
else begin
if (writep == 1'b1 && fullp == 1'b0) begin
head <= head + 1;
end
end
end
always @(posedge clk) begin
if (rstp == 1'b1) begin
tail <= 2‘b00; //复位
end
else begin
if (readp == 1'b1 && emptyp == 1'b0) begin
tail <= tail + 1;
end
end
end
always @(posedge clk) begin
if (rstp == 1'b1) begin
count <= 2'b00;
end
else begin
case ({readp, writep})
2'b00: count <= count;
2'b01:
if (count != MAX_COUNT)
count <= count + 1; //为写状态时计数器进行加法计数
2'b10:
if (count != 2'b00)
count <= count - 1; //为读状态计数器进行减法计数
2'b11:
count <= count;
endcase
end
end


always @(count) begin
if (count == 2'b00)
emptyp <= 1‘b1; //count为0时emptyp赋为1
else
emptyp <= 1'b0;
end


always @(count) begin
if (count == MAX_COUNT)
fullp <= 1‘b1; //计数到最大时fullp赋为1
else
fullp <= 1'b0;
end

endmodule

/*******************************************************************************************/
测试程序:

module test_fifo;

reg clk;
reg rstp;
reg [15:0] din;
reg readp;
reg writep;
wire [15:0] dout;
wire emptyp;
wire fullp;

reg [15:0] value;
fifo U1 (.clk(clk),.rstp(rstp),.din(din),.readp(readp),.writep(writep),.dout(dout),
.emptyp(emptyp),.fullp(fullp));

task read_word;
begin
@(negedge clk);
readp = 1;
@(posedge clk) #5;
readp = 0;
end
endtask

task write_word;
input [15:0] value;
begin
@(negedge clk);
din = value;
writep = 1;


@(posedge clk);
#5;
din = 16'hzzzz;
writep = 0;
end
endtask
initial begin
clk = 0;
forever begin
#10 clk = 1;
#10 clk = 0;
end
end

initial begin
//test1;
test2; //调用测试模块2

end
task test1;
begin
din = 16'hzzzz;
writep = 0;
readp = 0;
rstp = 1;
#50 rstp = 0;
#50;
write_word (16'h1111);
write_word (16'h2222);
write_word (16‘h3333); //写入3个数据
read_word;
read_word; //读两个
write_word (16‘h4444); //在写一个数据
repeat (6) begin
read_word;
end


write_word (16'h0001);
write_word (16'h0002);
write_word (16'h0003);
write_word (16'h0004);
write_word (16'h0005);
write_word (16'h0006);
write_word (16'h0007);
write_word (16'h0008);
repeat (6) begin
read_word;
end
end
endtask

task test2;
reg [15:0] writer_counter;
begin
writer_counter = 16'h0001;
din = 16'hzzzz;
writep = 0;
readp = 0;
rstp = 1;
#50 rstp = 0;
#50;
fork
//写数据
begin
repeat (500) begin
@(negedge clk);
if (fullp == 1'b0) begin
write_word (writer_counter);
#5;
writer_counter = writer_counter + 1;
end
#50;
end
end


//读数据
begin
forever begin
@(negedge clk);
if (emptyp == 1'b0) begin
read_word;
end
#50;
end
end
join
end
endtask



endmodule



相关主题