Here is the minimal reproducible problem:
file: top.sv
module top(input [31:0] in1, output [31:0] out1);
assign out1 = in1;
endmodule
file top_tb.sv
module top_tb;
shortreal in1_real;
shortreal out1_tb;
shortreal out_dut;
logic [31:0] in1_logic;
logic [31:0] out1_logic;
logic check;
initial in1_real = 2.1;
initial out1_tb = 2.1;
assign #5 in1_logic = $shortrealtobits(in1_real);
top inst_top(.in1(in1_logic),
.out1(out1_logic));
assign #10 out_dut = $bitstoshortreal(out1_logic);
assign #30 check = 1;
always_comb begin
if ((check == 1) && (out1_tb != out_dut)) begin
$display("%t Not matching!!", $time);
end
end
endmodule
When I run a simulation of this dut and tb in modelsim, I am not expecting any mismatch between out1_tb
and out_dut
, but I am seeing a mismatch. When I checked the waveform, both out1_tb
and out_dut
are shown as 2.1 only, still I am seeing a simulation mismatch.
Link to EDA Playground with the design and tesbench code: https://edaplayground.com/x/WDiC
When you click "run", you can see "Not matching" in the log.
When comparing real values, you should use a tolerance value. For example, I set the tolerance to 0.1 in the code below. If the absolute value of the difference between your numbers is greater than 0.1, then the numbers are considered different from each other.
always_comb begin
if ((check == 1) && compare(out1_tb, out_dut)) begin
//if ((check == 1) && (out1_tb != out_dut)) begin
$display("%t Not matching!! %g %g", $time, out1_tb, out_dut);
end
end
function bit compare (shortreal r1, r2);
shortreal diff;
diff = (r1>=r2) ? r1-r2 : r2-r1; // Absolute value
return (diff > 0.1) ? 1 : 0;
endfunction
There is uncertainty with all floating-point variable types. Sometimes, a direct comparison like !=
will work, and other times it will not work. It is not guaranteed to work, which is why a tolerance helps.
This is a general issue with floating-point comparison.