Testbench Code
`timescale 1ns/1ps
module tb_univ_barrel8;
// 1) Inputs
reg [7:0] x;
reg [2:0] sh;
reg [2:0] mode;
// 2) DUT outputs
wire [7:0] y;
// 3) Expected (purely combinational helper function)
function [7:0] expected8;
input [7:0] fx;
input [2:0] fsh;
input [2:0] fmode;
reg signed [7:0] sfx;
begin
sfx = fx; // signed view for ASR
case (fmode)
3'b000: expected8 = fx; // PASS
3'b001: expected8 = (fx << fsh) & 8'hFF; // LSL
3'b010: expected8 = (fx >> fsh); // LSR
3'b011: expected8 = (sfx >>> fsh); // ASR
3'b100: expected8 = ((fx << fsh) | (fx >> (8 - fsh))) & 8'hFF; // ROL
3'b101: expected8 = ((fx >> fsh) | (fx << (8 - fsh))) & 8'hFF; // ROR
default: expected8 = fx; // reserved → PASS
endcase
end
endfunction
wire [7:0] expected_y = expected8(x, sh, mode);
// 4) Single mismatch flag (treat X/Z as mismatches)
wire mismatch = (y !== expected_y);
// 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
univ_barrel8 dut(.x(x), .sh(sh), .mode(mode), .y(y));
// VCD dump
initial begin
$dumpfile("tb_univ_barrel8.vcd");
$dumpvars(0,
tb_univ_barrel8.x,
tb_univ_barrel8.sh,
tb_univ_barrel8.mode,
tb_univ_barrel8.y,
tb_univ_barrel8.expected_y,
tb_univ_barrel8.mismatch
);
$dumpon;
end
// Header + init
initial begin
x=0; sh=0; mode=3'b000;
$display(" x sh mode | y | expected_y | mismatch");
$display("----------------------------------------------");
end
// Apply + check (drive -> wait -> read combinational mismatch)
task apply_and_check;
input [7:0] tx;
input [2:0] tsh;
input [2:0] tmode;
begin
x = tx; sh = tsh; mode = tmode;
#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%02h %0d %03b | 0x%02h | 0x%02h | %0d",
x, sh, mode, y, expected_y, 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: x=0x%02h sh=%0d mode=%03b => y=0x%02h (exp 0x%02h)",
x, sh, mode, y, expected_y);
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 ix, ish, im;
initial begin
// Directed: sanity per op
// PASS
apply_and_check(8'hA5, 3'd0, 3'b000);
// LSL
apply_and_check(8'h81, 3'd1, 3'b001);
apply_and_check(8'h81, 3'd3, 3'b001);
// LSR
apply_and_check(8'h81, 3'd1, 3'b010);
apply_and_check(8'hFF, 3'd7, 3'b010);
// ASR (sign extend)
apply_and_check(8'h81, 3'd1, 3'b011); // 1000_0001 >>> 1 = 1100_0000
apply_and_check(8'hC0, 3'd3, 3'b011);
// ROL
apply_and_check(8'h96, 3'd2, 3'b100);
// ROR
apply_and_check(8'h96, 3'd3, 3'b101);
// Full Sweep
for (im = 0; im < 6; im = im + 1) // test modes 000..101
for (ish = 0; ish < 8; ish = ish + 1) // shifts 0..7
for (ix = 0; ix < 256; ix = ix + 1) // sample inputs
apply_and_check(ix[7:0], ish[2:0], im[2:0]);
// 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