Testbench Code
`timescale 1ns/1ps
module tb_safe_mux2;
// Inputs
reg [7:0] a, b;
reg sel;
// DUT outputs
wire [7:0] y;
wire sel_unknown;
// Expected (as wires; prefix expected_)
wire [7:0] expected_y;
wire expected_sel_unknown;
// Mismatch signal (for VCD only)
reg mismatch;
wire mismatch_w = (y !== expected_y) || (sel_unknown !== expected_sel_unknown);
// Accounting
integer TOTAL_TEST_CASES = 0;
integer TOTAL_PASSED_TEST_CASES = 0;
integer TOTAL_FAILED_TEST_CASES = 0;
// VCD control
integer VCD_MAX_CASES = 32;
// DUT
safe_mux2 dut(.a(a), .b(b), .sel(sel), .y(y), .sel_unknown(sel_unknown));
// Reference model
assign expected_y =
(sel === 1'b0) ? a :
(sel === 1'b1) ? b : 8'h00;
assign expected_sel_unknown =
(sel === 1'b0) ? 1'b0 :
(sel === 1'b1) ? 1'b0 : 1'b1;
// VCD setup
initial begin
$dumpfile("tb_safe_mux2.vcd");
$dumpvars(0,
tb_safe_mux2.a, tb_safe_mux2.b, tb_safe_mux2.sel, // Inputs
tb_safe_mux2.y, tb_safe_mux2.sel_unknown, // Outputs
tb_safe_mux2.expected_y, tb_safe_mux2.expected_sel_unknown, // Expected
tb_safe_mux2.mismatch // Mismatch
);
$dumpon;
end
initial begin
a = 8'h00; b = 8'h00; sel = 1'b0;
mismatch = 1'b0;
$display(" a b sel | DUT_y DUT_sel_unknown || expected_y expected_sel_unknown | mismatch");
$display("--------------------------------------------------------------------------------------");
end
// Apply vector, settle, log truth table, update counters
task apply_and_check;
input [7:0] ta, tb;
input tsel;
begin
a = ta; b = tb; sel = tsel;
#1; // allow DUT + expected to settle
mismatch = mismatch_w;
TOTAL_TEST_CASES = TOTAL_TEST_CASES + 1;
if (!mismatch) TOTAL_PASSED_TEST_CASES = TOTAL_PASSED_TEST_CASES + 1;
else TOTAL_FAILED_TEST_CASES = TOTAL_FAILED_TEST_CASES + 1;
// Print truth table row
$display("0x%02h 0x%02h %s | 0x%02h %b || 0x%02h %b | %b",
a, b,
(sel===1'b0)?"0":(sel===1'b1)?"1":(sel===1'bx)?"x":"z",
y, sel_unknown,
expected_y, expected_sel_unknown,
mismatch
);
if (TOTAL_TEST_CASES == VCD_MAX_CASES) $dumpoff;
end
endtask
// Stimulus
initial begin
// Clean select
apply_and_check(8'h12,8'h34,1'b0);
apply_and_check(8'h12,8'h34,1'b1);
// X/Z select
apply_and_check(8'hAA,8'h55,1'bx);
apply_and_check(8'hAA,8'h55,1'bz);
// Randomized clean (mask to 0/1)
repeat (12) apply_and_check($random, $random, $random & 1);
// Stress with unknown select
apply_and_check(8'hF0,8'h0F,1'bx);
apply_and_check(8'hFF,8'h00,1'bz);
// Summary logs
$display("--------------------------------------------------------------------------------------");
$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