Testbench Code
`timescale 1ns/1ps
module tb_alu4;
// 1) Inputs
reg [3:0] a, b;
reg [2:0] op;
// 2) DUT outputs
wire [3:0] y;
wire cf;
// 3) Expected (pure combinational, no functions)
wire [4:0] exp_add5 = {1'b0, a} + {1'b0, b}; // ADD
wire [4:0] exp_sub5 = {1'b0, a} + {1'b0, ~b} + 5'b00001; // SUB (a + ~b + 1)
wire [3:0] expected_y =
(op==3'b000) ? exp_add5[3:0] :
(op==3'b001) ? exp_sub5[3:0] :
(op==3'b010) ? (a & b) :
(op==3'b011) ? (a | b) :
(op==3'b100) ? (a ^ b) :
4'b0000;
wire expected_cf =
(op==3'b000) ? exp_add5[4] : // carry for ADD
(op==3'b001) ? ~exp_sub5[4] : // borrow for SUB = ~carry_out
1'b0; // logic ops
// 4) Single mismatch flag (treat X/Z as mismatches)
wire mismatch = ({y, cf} !== {expected_y, expected_cf});
// Accounting
integer TOTAL_TEST_CASES = 0;
integer TOTAL_PASSED_TEST_CASES = 0;
integer TOTAL_FAILED_TEST_CASES = 0;
// Limits
integer VCD_MAX_CASES = 32; // normal printed rows
integer ERROR_MAX_CASES = 32; // error printed rows
integer printed_rows = 0;
integer printed_errors = 0;
// DUT
alu4 dut(.a(a), .b(b), .op(op), .y(y), .cf(cf));
// VCD dump
initial begin
$dumpfile("tb_alu4.vcd");
$dumpvars(0,
tb_alu4.a, tb_alu4.b, tb_alu4.op,
tb_alu4.y, tb_alu4.cf,
tb_alu4.expected_y, tb_alu4.expected_cf,
tb_alu4.mismatch
);
$dumpon;
end
// Header + init
initial begin
a=0; b=0; op=3'b000;
$display(" a b op | y cf | exp_y exp_cf | mismatch");
$display("---------------------------------------------");
end
// Apply + check (drive -> wait -> read combinational mismatch)
task apply_and_check;
input [3:0] ta, tb_;
input [2:0] top;
begin
a = ta; b = tb_; op = top;
#1; // settle
TOTAL_TEST_CASES = TOTAL_TEST_CASES + 1;
if (!mismatch) begin
TOTAL_PASSED_TEST_CASES = TOTAL_PASSED_TEST_CASES + 1;
if (printed_rows < VCD_MAX_CASES) begin
$display("0x%1h 0x%1h %03b | 0x%1h %0d | 0x%1h %0d | %0d",
a, b, op, y, cf, expected_y, expected_cf, mismatch);
printed_rows = printed_rows + 1;
end
end else begin
TOTAL_FAILED_TEST_CASES = TOTAL_FAILED_TEST_CASES + 1;
if (printed_errors < ERROR_MAX_CASES) begin
$display("ERR: a=0x%1h b=0x%1h op=%03b => y=0x%1h cf=%0d (exp y=0x%1h cf=%0d)",
a, b, op, y, cf, expected_y, expected_cf);
printed_errors = printed_errors + 1;
end
end
// Optional: stop VCD after cap of total vectors
if (TOTAL_TEST_CASES == VCD_MAX_CASES) $dumpoff;
end
endtask
integer ia, ib, m;
initial begin
// Directed per op
apply_and_check(4'h0,4'h0,3'b000); // ADD
apply_and_check(4'hF,4'h1,3'b000); // ADD carry
apply_and_check(4'h0,4'h1,3'b001); // SUB borrow
apply_and_check(4'hA,4'h3,3'b001); // SUB
apply_and_check(4'hA,4'h5,3'b010); // AND
apply_and_check(4'hA,4'h5,3'b011); // OR
apply_and_check(4'hA,4'h5,3'b100); // XOR
// Compact sweeps (keep output readable)
for (m = 0; m < 5; m = m + 1)
for (ia = 0; ia < 16; ia = ia + 1)
for (ib = 0; ib < 16; ib = ib + 1)
apply_and_check(ia[3:0], ib[3:0], m[2:0]);
// A few randoms
repeat (24) apply_and_check($random, $random, {$random}%5);
// Summary
$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