Testbench Code
`timescale 1ns/1ps
module tb_led_blinker;
reg clk;
reg rst;
wire led;
wire expected_led;
wire mismatch;
localparam integer TB_COUNTER_WIDTH = 2;
localparam integer TB_TOGGLE_EVERY = 3;
led_blinker #(
.COUNTER_WIDTH(TB_COUNTER_WIDTH),
.TOGGLE_EVERY(TB_TOGGLE_EVERY)
) dut (
.clk(clk), .rst(rst), .led(led)
);
reg [TB_COUNTER_WIDTH-1:0] exp_cnt;
reg exp_led_q;
assign expected_led = exp_led_q;
always @(posedge clk) begin
if (rst) begin
exp_led_q <= 1'b0;
exp_cnt <= {TB_COUNTER_WIDTH{1'b0}};
end else begin
if (exp_cnt == TB_TOGGLE_EVERY-1) begin
exp_led_q <= ~exp_led_q;
exp_cnt <= {TB_COUNTER_WIDTH{1'b0}};
end else begin
exp_cnt <= exp_cnt + {{(TB_COUNTER_WIDTH-1){1'b0}},1'b1};
end
end
end
assign mismatch = (led !== expected_led);
initial begin
clk = 1'b0;
forever #5 clk = ~clk;
end
initial begin
@(posedge clk);
$dumpfile("tb_led_blinker.vcd");
$dumpvars(0,
clk, rst, // 1) Inputs
led, // 2) Outputs
expected_led, // 3) Expected Outputs
mismatch // 4) Mismatch
);
end
task apply_cycles;
input integer n; integer i;
begin for (i=0;i<n;i=i+1) @(posedge clk); end
endtask
integer TOTAL_TEST_CASES, TOTAL_PASSED_TEST_CASES, TOTAL_FAILED_TEST_CASES;
task run_window;
input integer cycles;
input [8*48-1:0] name;
integer i; reg case_failed;
begin
case_failed = 0;
for (i=0; i<cycles; i=i+1) begin
@(posedge clk);
if (mismatch) case_failed = 1;
end
$display("CASE=%s : %s", name, case_failed ? "MISMATCH" : "OK");
TOTAL_TEST_CASES = TOTAL_TEST_CASES + 1;
if (!case_failed) TOTAL_PASSED_TEST_CASES = TOTAL_PASSED_TEST_CASES + 1;
else TOTAL_FAILED_TEST_CASES = TOTAL_FAILED_TEST_CASES + 1;
apply_cycles(1);
end
endtask
initial begin
rst = 1'b1;
exp_cnt = {TB_COUNTER_WIDTH{1'b0}};
exp_led_q = 1'b0;
apply_cycles(4);
@(negedge clk) rst = 1'b0;
TOTAL_TEST_CASES = 0; TOTAL_PASSED_TEST_CASES = 0; TOTAL_FAILED_TEST_CASES = 0;
run_window(TB_TOGGLE_EVERY-1, "no_toggle_before_first");
run_window(1, "toggle_at_first_count");
run_window(TB_TOGGLE_EVERY, "next_toggle_after_interval");
@(negedge clk) rst = 1'b1;
apply_cycles(2);
@(negedge clk) rst = 1'b0;
run_window(TB_TOGGLE_EVERY, "post_reset_first_toggle");
$display("TOTAL_TEST_CASES=%0d", TOTAL_TEST_CASES);
$display("TOTAL_PASSED_TEST_CASES=%0d", TOTAL_PASSED_TEST_CASES);
$display("TOTAL_FAILED_TEST_CASES=%0d", TOTAL_FAILED_TEST_CASES);
$display("ALL_TEST_CASES_PASSED=%s", (TOTAL_FAILED_TEST_CASES==0) ? "true" : "false");
$finish;
end
endmodule