tb.v — locked
`timescale 1ns/1ps
module tb;
reg clk=0, rst=1, wr_en=0, rd_en=0; reg [7:0] wr_data=0;
wire [7:0] rd_data; wire full, empty;
reg [7:0] model [0:15]; integer head=0, tail=0, count=0;
integer i, errors=0; reg [31:0] lfsr = 32'hCAFE;
reg do_push, do_pop;
challenge dut (.clk(clk), .rst(rst), .wr_en(wr_en), .wr_data(wr_data),
.rd_en(rd_en), .rd_data(rd_data), .full(full), .empty(empty));
always #5 clk = ~clk;
initial begin
$dumpfile("wave.vcd"); $dumpvars(0, tb);
repeat (2) @(negedge clk); rst = 0;
for (i = 0; i < 500; i = i + 1) begin
@(negedge clk);
lfsr = {lfsr[30:0], lfsr[31]^lfsr[21]^lfsr[1]^lfsr[0]};
wr_en = lfsr[0]; rd_en = lfsr[1]; wr_data = lfsr[15:8];
// flags BEFORE the edge decide what happens at the edge
#1;
if (full !== (count == 4)) begin
errors = errors + 1;
if (errors < 6) $display("FAIL @%0t: full=%b count=%0d", $time, full, count);
end
if (empty !== (count == 0)) begin
errors = errors + 1;
if (errors < 6) $display("FAIL @%0t: empty=%b count=%0d", $time, empty, count);
end
if (count > 0 && rd_data !== model[head % 16]) begin
errors = errors + 1;
if (errors < 6) $display("FAIL @%0t: rd_data=%h want=%h",
$time, rd_data, model[head % 16]);
end
do_push = wr_en && (count < 4);
do_pop = rd_en && (count > 0);
@(posedge clk);
if (do_push) begin model[tail % 16] = wr_data; tail = tail + 1; end
if (do_pop) head = head + 1;
count = tail - head;
end
if (errors == 0) $display("TB PASS");
else $display("TB FAIL (%0d errors)", errors);
$finish;
end
endmodule