Testbench Code
`timescale 1ns/1ps
module tb_reg4_sync_reset;
// 1) Inputs
reg CLK, RST;
reg [3:0] D;
// 2) Outputs
wire [3:0] Q;
// 3) Expected outputs (prefixed "expected_")
reg [3:0] expected_Q;
// 4) Mismatch (HIGH when outputs != expected)
wire mismatch;
// DUT
reg4_sync_reset dut(.CLK(CLK), .RST(RST), .D(D), .Q(Q));
// Scoreboard: mirror DUT at posedge
always @(posedge CLK) begin
if (RST) expected_Q <= 4'b0000;
else expected_Q <= D;
end
// 4-state aware compare
assign mismatch = (Q !== expected_Q);
// Counters / limits
integer TOTAL_TEST_CASES = 0;
integer TOTAL_PASSED_TEST_CASES = 0;
integer TOTAL_FAILED_TEST_CASES = 0;
integer VCD_MAX_CASES = 32;
integer ERROR_MAX_CASES = 32;
integer i, j;
// Free-running clock (10 time-unit period)
initial begin
CLK = 1'b0;
forever #5 CLK = ~CLK;
end
// VCD — order: Inputs -> Outputs -> Expected -> mismatch; start at #0
initial begin
$dumpfile("tb_reg4_sync_reset.vcd");
$dumpvars(0,
tb_reg4_sync_reset.CLK,
tb_reg4_sync_reset.RST,
tb_reg4_sync_reset.D,
tb_reg4_sync_reset.Q,
tb_reg4_sync_reset.expected_Q,
tb_reg4_sync_reset.mismatch
);
$dumpon;
end
// Drive RST/D on negedge; check after the next posedge
task drive_and_check;
input rst_v;
input [3:0] d_v;
begin
@(negedge CLK);
RST = rst_v;
D = d_v;
@(posedge CLK); #1;
TOTAL_TEST_CASES = TOTAL_TEST_CASES + 1;
if (!mismatch) begin
TOTAL_PASSED_TEST_CASES = TOTAL_PASSED_TEST_CASES + 1;
end else begin
TOTAL_FAILED_TEST_CASES = TOTAL_FAILED_TEST_CASES + 1;
if (TOTAL_FAILED_TEST_CASES <= ERROR_MAX_CASES)
$display("[FAIL] RST=%b D=0x%1h Q=0x%1h expected_Q=0x%1h t=%0t",
RST, D, Q, expected_Q, $time);
end
if (TOTAL_TEST_CASES == VCD_MAX_CASES) $dumpoff;
end
endtask
initial begin
// Start unknown like real silicon; first edge defines it
RST = 1'b0; D = 4'h0; expected_Q = 4'hx;
@(posedge CLK); #1;
// Directed
drive_and_check(1'b1, 4'hF); // reset dominates
drive_and_check(1'b0, 4'h5); // capture D
drive_and_check(1'b0, 4'hA); // capture D
drive_and_check(1'b1, 4'h3); // reset again
// Two-step sequences (trimmed sweep)
for (i=0; i<4; i=i+1) begin
drive_and_check(i[0], i[3:0]);
for (j=0; j<4; j=j+1)
drive_and_check(j[0], j[3:0]);
end
// Random stress
for (i=0; i<10; i=i+1)
drive_and_check($random, $random);
// Summary
$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");
#2 $finish;
end
endmodule