Here is the design that is supposed to compare two floating point numbers:
// IEEE 764: FP[31] = sign, FP[30:23] = exp, FP[22:0] = mantissa
module compare_fp(input [31:0] floatA,
input [31:0] floatB,
output reg [1:0] compareRes);
// equal: 2, A>B: 1, A<B: 0
assign compareRes[1] = (floatA == floatB); // if they are equal, set the MSB of output to 1
// if A > B set the LSB of output to 1
// 1. A>0, B<0
// 2. sign same, compare exp
// 3. sign and exp same, compare matissa
assign compareRes[0] = ((!floatA[31]) && floatB[31]) ||
(((floatA[31] & floatB[31]) == 1) && (floatA[30:23] < floatB[30:23])) ||
(((floatA[31] | floatB[31]) == 0) && (floatA[30:23] > floatB[30:23])) ||
(((floatA[31] & floatB[31]) == 1) && (floatA[30:23] == floatB[30:23]) && (floatA[22:0] < floatB[22:0])) ||
(((floatA[31] | floatB[31]) == 0) && (floatA[30:23] == floatB[30:23]) && (floatA[22:0] > floatB[22:0]));
endmodule
I wrote a simple testbench following https://verificationguide.com/systemverilog-examples/systemverilog-testbench-example-adder-2/, and I attached it here:
// Code your testbench here
// or browse Examples
class transaction;
randc bit [31:0] floatA;
randc bit [31:0] floatB;
logic [1:0] compareRes;
// constrain the input
//constraint constraint_float {floatA==floatB;}
// actual float
shortreal float_A;
shortreal float_B;
function void display(string name);
$display("---------");
$display("%s",name);
$display("a = %0f, b = %0f, result = %0d", float_A, float_B, compareRes);
$display("a = %0b, b = %0b, result = %0d", floatA, floatB, compareRes);
$display("---------");
endfunction
endclass
class generator;
rand transaction trans;
mailbox gen2drv;
event ended;
int generateCount; // number of cases
function new(mailbox gen2drv);
this.gen2drv = gen2drv;
endfunction
task main();
repeat(generateCount) begin
// create and randomize
trans = new();
if( !trans.randomize()) $fatal("gen: trans randomization failed");
// calculating actual number
trans.float_A = $bitstoshortreal(trans.floatA);
trans.float_B = $bitstoshortreal(trans.floatB);
gen2drv.put(trans);
end
-> ended; //end of generation
endtask
endclass
interface intf;
bit [31:0] floatA;
bit [31:0] floatB;
logic [1:0] compareRes;
endinterface
class driver;
int transaction_count;
mailbox gen2drv;
virtual intf vif;
// constructor
function new(virtual intf vif, mailbox gen2drv);
this.vif = vif;
this.gen2drv = gen2drv;
endfunction
task main;
forever begin
transaction trans;
gen2drv.get(trans);
vif.floatA = trans.floatA;
vif.floatB = trans.floatB;
trans.display("[ Driver ]");
transaction_count++;
end
endtask
endclass
class environment;
generator gen;
driver drv;
mailbox gen2drv;
virtual intf vif;
//constructor
function new(virtual intf vif);
this.vif = vif;
gen2drv = new();
gen = new(gen2drv);
drv = new(vif, gen2drv);
endfunction
task test();
fork
gen.main();
drv.main();
join_any
endtask
task post_test();
wait(gen.ended.triggered);
wait(gen.generateCount == drv.transaction_count);
endtask
task run;
test();
post_test();
$finish;
endtask
endclass
program test(intf intf);
environment env;
initial begin
env = new(intf);
env.gen.generateCount = 3;
env.run();
end
endprogram
module tb;
intf intf1();
test t1(intf1);
compare_fp dut (.floatA(intf1.floatA), .floatB(intf1.floatB), .compareRes(intf1.compareRes));
endmodule
But the output (compareRes
) is always x.
I then wrote a simpler testbench where I manually choose input, and the design works just fine. Below is the simple testbench:
// Code your testbench here
// or browse Examples
interface test;
logic [31:0] floatA;
logic [31:0] floatB;
logic [1:0] compareRes;
endinterface
module tb;
test st();
shortreal float_A;
shortreal float_B;
compare_fp dut(.floatA(st.floatA), .floatB(st.floatB), .compareRes(st.compareRes));
initial begin
#10 st.floatA = 32'b11000000010101001100000001011001;
#10 st.floatB = 32'b01000000010101000111101011100001;
#10 float_A = $bitstoshortreal(st.floatA);
#10 float_B = $bitstoshortreal(st.floatB);
#10 $display("%f %f is %0d", float_A, float_B, st.compareRes);
end
endmodule
So maybe there is something wrong with the value delivery in my testbench? Can anyone give me some suggestion as how to debug the testbench?