212 lines
6.2 KiB
Verilog
212 lines
6.2 KiB
Verilog
//
|
|
// Copyright 2012-2013 Ettus Research LLC
|
|
//
|
|
|
|
|
|
module axi_fifo_tb();
|
|
|
|
reg clk, reset;
|
|
reg read_flag, write_flag;
|
|
|
|
reg error;
|
|
reg [7:0] i_tdata, o_tdata_ref;
|
|
wire [7:0] o_tdata;
|
|
reg i_tvalid, o_tready;
|
|
wire o_tvalid, i_tready;
|
|
wire [15:0] space, occupied;
|
|
|
|
always
|
|
#100 clk = ~clk;
|
|
|
|
initial clk = 0;
|
|
|
|
|
|
axi_fifo
|
|
#(
|
|
.WIDTH(8),
|
|
.SIZE(8)
|
|
)
|
|
dut
|
|
(.clk(clk),
|
|
.reset(reset),
|
|
.clear(1'b0),
|
|
.i_tdata(i_tdata),
|
|
.i_tvalid(i_tvalid),
|
|
.i_tready(i_tready),
|
|
.o_tdata(o_tdata),
|
|
.o_tvalid(o_tvalid),
|
|
.o_tready(o_tready),
|
|
.space(space),
|
|
.occupied(occupied)
|
|
);
|
|
|
|
|
|
task write;
|
|
begin
|
|
write_flag <= 1;
|
|
i_tvalid <= 1'b1;
|
|
#1;
|
|
while (i_tready != 1'b1)
|
|
@(posedge clk);
|
|
#1;
|
|
@(posedge clk);
|
|
write_flag <= 0;
|
|
i_tvalid <= 1'b0;
|
|
i_tdata <= i_tdata + 8'h1;
|
|
end
|
|
endtask // write
|
|
|
|
task read;
|
|
begin
|
|
read_flag <= 1;
|
|
o_tready <= 1'b1;
|
|
#1;
|
|
while (o_tvalid != 1'b1)
|
|
@(posedge clk);
|
|
#1;
|
|
@(posedge clk);
|
|
read_flag <= 0;
|
|
o_tready <= 1'b0;
|
|
if (o_tdata_ref != o_tdata) begin
|
|
$display("ERROR: Expected %d, got %d, at time %d",o_tdata_ref,o_tdata,$time);
|
|
error <= 1'b1;
|
|
end else
|
|
error <= 1'b0;
|
|
o_tdata_ref = o_tdata_ref + 8'h1;
|
|
end
|
|
endtask // read
|
|
|
|
initial
|
|
begin
|
|
reset <= 1'b0;
|
|
error <= 1'b0;
|
|
i_tdata <= 8'b00;
|
|
o_tdata_ref <= 8'b00;
|
|
i_tvalid <= 1'b0;
|
|
o_tready <= 1'b0;
|
|
read_flag <= 0;
|
|
write_flag <= 0;
|
|
|
|
repeat(10) @(posedge clk);
|
|
reset <= 1'b1;
|
|
repeat(10) @(posedge clk);
|
|
reset <= 1'b0;
|
|
@(posedge clk);
|
|
@(negedge clk);
|
|
|
|
// FIFO Should be empty now, check avail space
|
|
if (space != 16'd256)
|
|
begin $display("ERROR: FIFO is empty, space should read 256 not %d at time %d",space,$time); error <= 1; end
|
|
if (occupied != 16'd0)
|
|
begin $display("ERROR: FIFO is empty, occupied should read 0 not %d at time %d",occupied,$time); error <= 1; end
|
|
if (o_tvalid == 1'b1)
|
|
begin $display("ERROR: FIFO is empty, o_tvalid should be 0 at time %d",$time); error <= 1; end
|
|
@(posedge clk);
|
|
// Push 1 item onto FIFO, check fullness updates accordingly
|
|
write();
|
|
@(posedge clk);
|
|
@(negedge clk);
|
|
if (space != 16'd255)
|
|
begin $display("ERROR: FIFO space should read 255 not %d at time %d",space,$time); error <= 1; end
|
|
if (occupied != 16'd1)
|
|
begin $display("ERROR: FIFO occupied should read 1 not %d at time %d",occupied,$time); error <= 1; end
|
|
if (o_tvalid == 1'b0)
|
|
begin $display("ERROR: FIFO is not empty, o_tvalid should be 1 at time %d",$time); error <= 1; end
|
|
// Pop FIFO once, check it goes back empty OK.
|
|
@(posedge clk);
|
|
read();
|
|
@(posedge clk);
|
|
@(negedge clk);
|
|
if (space != 16'd256)
|
|
begin $display("ERROR: FIFO is empty, space should read 256 not %d at time %d",space,$time); error <= 1; end
|
|
if (occupied != 16'd0)
|
|
begin $display("ERROR: FIFO is empty, occupied should read 0 not %d at time %d",occupied,$time); error <= 1; end
|
|
if (o_tvalid == 1'b1)
|
|
begin $display("ERROR: FIFO is empty, o_tvalid should be 0 at time %d",$time); error <= 1; end
|
|
// Push FIFO 255 times and see if it goes full incorrectly
|
|
repeat(255) begin
|
|
@(posedge clk);
|
|
write();
|
|
end
|
|
@(posedge clk);
|
|
@(negedge clk);
|
|
if (space != 16'd1)
|
|
begin $display("ERROR: FIFO is nearly full, space should read 1 not %d at time %d",space,$time); error <= 1; end
|
|
if (occupied != 16'd255)
|
|
begin $display("ERROR: FIFO is nearly full, occupied should read 255 not %d at time %d",occupied,$time); error <= 1; end
|
|
if (o_tvalid == 1'b0)
|
|
begin $display("ERROR: FIFO is nearly full, o_tvalid should be 1 at time %d",$time); error <= 1; end
|
|
if (i_tready == 1'b0)
|
|
begin $display("ERROR: FIFO is nearly full, i_tready should be 1 at time %d",$time); error <= 1; end
|
|
// Push FIFO one more time, now it should be full
|
|
@(posedge clk);
|
|
write();
|
|
@(posedge clk);
|
|
@(negedge clk);
|
|
if (space != 16'd0)
|
|
begin $display("ERROR: FIFO is full, space should read 0 not %d at time %d",space,$time); error <= 1; end
|
|
if (occupied != 16'd256)
|
|
begin $display("ERROR: FIFO is full, occupied should read 256 not %d at time %d",occupied,$time); error <= 1; end
|
|
if (o_tvalid == 1'b0)
|
|
begin $display("ERROR: FIFO is full, o_tvalid should be 1 at time %d",$time); error <= 1; end
|
|
if (i_tready == 1'b1)
|
|
begin $display("ERROR: FIFO is full, i_tready should be 0 at time %d",$time); error <= 1; end
|
|
// POP FIFO once, check it went nonfull.
|
|
@(posedge clk);
|
|
read();
|
|
@(posedge clk);
|
|
@(negedge clk);
|
|
if (space != 16'd1)
|
|
begin $display("ERROR: FIFO is nearly full, space should read 1 not %d at time %d",space,$time); error <= 1; end
|
|
if (occupied != 16'd255)
|
|
begin $display("ERROR: FIFO is nearly full, occupied should read 255 not %d at time %d",occupied,$time); error <= 1; end
|
|
if (o_tvalid == 1'b0)
|
|
begin $display("ERROR: FIFO is nearly full, o_tvalid should be 1 at time %d",$time); error <= 1; end
|
|
if (i_tready == 1'b0)
|
|
begin $display("ERROR: FIFO is nearly full, i_tready should be 1 at time %d",$time); error <= 1; end
|
|
// Take FIFO to empty state
|
|
repeat(255) begin
|
|
@(posedge clk);
|
|
read();
|
|
end
|
|
@(posedge clk);
|
|
@(negedge clk);
|
|
if (space != 16'd256)
|
|
begin $display("ERROR: FIFO is empty, space should read 256 not %d at time %d",space,$time); error <= 1; end
|
|
if (occupied != 16'd0)
|
|
begin $display("ERROR: FIFO is empty, occupied should read 0 not %d at time %d",occupied,$time); error <= 1; end
|
|
if (o_tvalid == 1'b1)
|
|
begin $display("ERROR: FIFO is empty, o_tvalid should be 0 at time %d",$time); error <= 1; end
|
|
// Push 1 item onto FIFO
|
|
@(posedge clk);
|
|
write();
|
|
@(posedge clk);
|
|
// Now write twice as fast as we read, and write 256 times, which should leave, 129 elements in FIFO.
|
|
fork
|
|
repeat(256) begin
|
|
write();
|
|
@(posedge clk);
|
|
end
|
|
repeat(128) begin
|
|
read();
|
|
@(posedge clk);
|
|
@(posedge clk);
|
|
end
|
|
join
|
|
@(posedge clk);
|
|
if (space != 16'd127)
|
|
begin $display("ERROR: FIFO space should read 127 not %d at time %d",space,$time); error <= 1; end
|
|
if (occupied != 16'd129)
|
|
begin $display("ERROR: FIFO occupied should read 129 not %d at time %d",occupied,$time); error <= 1; end
|
|
|
|
|
|
|
|
//
|
|
// END
|
|
//
|
|
repeat(10) @(posedge clk);
|
|
$finish;
|
|
end // initial begin
|
|
|
|
endmodule // axi_fifo_tb
|