`timescale 1ns/1ps
interface booth_intf;
logic [15:0] a_in;
logic [15:0] b_in;
logic mode; // mode = 'b1, signed a b; mode = 'b0 , unsigned a b
logic [31:0] res_out;
endinterface //booth_intf
class Bus;
local virtual booth_intf intf;
rand bit [15:0] a;
rand bit [15:0] b;
rand bit mode;
bit [31:0] result;
function void set_interface(virtual booth_intf intf);
if (intf == null)
$error("intf handler is NULL");
else this.intf = intf;
endfunction
task automatic write();
intf.a_in = a;
intf.b_in = b;
intf.mode = mode;
endtask //automatic
function bit [31:0] res();
if (mode) return $signed(a) * $signed(b);
else return a * b;
endfunction
task automatic check(int id, ref int error_num);
int right = 0;
write();
# 10;
if (intf.res_out == res) right = 1;
else error_num++;
if (mode)
$display("test signed %d: %s, a = %d, b = %d, result = %d, booth = %d",
id, right?"right":"wrong", $signed(a), $signed(b), $signed(res), $signed(intf.res_out));
else begin
$display("test unsigned %d: %s, a = %d, b = %d, result = %d, booth = %d",
id, right?"right":"wrong", a, b, res, intf.res_out);
end
endtask
endclass
module booth_tb;
multi_16 multi_16_u (
.a_in(booth_if.a_in),
.b_in(booth_if.b_in),
.mode(booth_if.mode), // mode = 'b1, signed a b; mode = 'b0, unsigned a b
.res_out(booth_if.res_out)
);
booth_intf booth_if(.*);
int error_num = 0;
Bus b = new;
const int test_num = 10000;
initial begin
b.set_interface(booth_if);
$display("=====test unsigned corner cases=====");
for (int i = 0; i < test_num; i++) begin
assert (b.randomize with {mode == 0; a == 0 || b == 0;})
else $fatal("randomize failed");
b.check(i, error_num);
end
$display("=====test unsigned normal cases=====");
for (int i = 0; i < test_num; i++) begin
assert (b.randomize with {mode == 0;})
else $fatal("randomize failed");
b.check(i, error_num);
end
$display("=====test signed corner cases=====");
for (int i = 0; i < test_num; i++) begin
assert (b.randomize with {mode == 1; a == 0 || b == 0;})
else $fatal("randomize failed");
b.check(i, error_num);
end
$display("=====test signed normal cases=====");
for (int i = 0; i < test_num; i++) begin
assert (b.randomize with {mode == 1;})
else $fatal("randomize failed");
b.check(i, error_num);
end
if (error_num > 0) $display("failed! total %d errors of %d tests", error_num, test_num);
else $display("%d test passed!", test_num);
#50 $stop;
end
endmodule
10-19
313