Testbench Code
`timescale 1ns/1ps
module tb_sat_add8_wrap;
// 1) Inputs
reg [7:0] a, b;
// 2) DUT outputs
wire [7:0] sum;
wire carry;
// 3) Expected (prefixed expected_)
reg [7:0] expected_sum;
reg expected_carry;
// 4) Mismatch (HIGH on fail)
reg mismatch;
wire mismatch_w = (sum !== expected_sum) || (carry !== expected_carry);
// Accounting
integer TOTAL_TEST_CASES = 0;
integer TOTAL_PASSED_TEST_CASES = 0;
integer TOTAL_FAILED_TEST_CASES = 0;
// VCD limit
integer VCD_MAX_CASES = 32;
// Seed for reproducible randomness (change to vary)
integer seed;
initial seed = 32'h5ADD_CAFE ^ $time;
// DUT
sat_add8_wrap dut(.a(a), .b(b), .sum(sum), .carry(carry));
// ---------- Golden model (TB-only) ----------
reg [8:0] raw;
task compute_expected;
input [7:0] ta, tb;
begin
raw = ta + tb; // 9-bit add
expected_carry = raw[8]; // unsigned carry
expected_sum = expected_carry ? 8'hFF // saturation
: raw[7:0];
end
endtask
// VCD dump (Inputs -> Outputs -> Expected -> Mismatch)
initial begin
$dumpfile("tb_sat_add8_wrap.vcd");
$dumpvars(0,
tb_sat_add8_wrap.a, tb_sat_add8_wrap.b, // Inputs
tb_sat_add8_wrap.sum, tb_sat_add8_wrap.carry, // Outputs
tb_sat_add8_wrap.expected_sum, // Expected
tb_sat_add8_wrap.expected_carry, // Expected
tb_sat_add8_wrap.mismatch // Mismatch
);
$dumpon; // start at #0
end
// Header + init
initial begin
a=0; b=0; mismatch=0; expected_sum=0; expected_carry=0;
$display(" a b | sum c | expected_sum expected_carry | mismatch");
$display("----------------------------------------------------------------");
end
// Apply + check (EXPECTED FIRST -> WAIT -> COMPARE)
task apply_and_check;
input [7:0] ta, tb;
begin
a = ta; b = tb;
compute_expected(ta, tb); // compute expected before waiting
#1; // let DUT settle
mismatch = mismatch_w;
TOTAL_TEST_CASES++;
if (!mismatch) TOTAL_PASSED_TEST_CASES++;
else TOTAL_FAILED_TEST_CASES++;
$display("0x%02h 0x%02h | 0x%02h %0d | 0x%02h %0d | %0d",
a, b, sum, carry, expected_sum, expected_carry, mismatch);
if (TOTAL_TEST_CASES == VCD_MAX_CASES) $dumpoff;
end
endtask
integer i;
initial begin
// Directed (compact table, < 20 lines printed)
apply_and_check(8'h00, 8'h00); // 0 + 0
apply_and_check(8'h01, 8'h02); // no carry
apply_and_check(8'h7F, 8'h01); // boundary (no carry, sum=0x80)
apply_and_check(8'h80, 8'h80); // carry -> saturate
apply_and_check(8'hFF, 8'h01); // carry -> saturate
apply_and_check(8'hF0, 8'h20); // carry -> saturate
apply_and_check(8'h10, 8'h10); // no carry
apply_and_check(8'hAA, 8'h55); // no carry
// Small sweep near carry boundary
for (i = 0; i < 8; i = i + 1)
apply_and_check(8'hF8 + i, 8'h07);
// A few randoms (keep total ≤ 32)
repeat (8) apply_and_check($random(seed), $random(seed));
// 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