I declare my variable:
real meas_diff_div;
I have a task, where I use this variable:
measure_task(meas_diff_div);
After that I filter for an error based on the value of this real
:
if(meas_diff_div > 0)`error("error message. %f", meas_diff_div);
Sometimes the error is triggered, even if the printed value is 0.000000
At the task declaration, the 1st line looks like this:
task measure_task(output real output_value);
In the task this real
is 'filled' up with (I use $floor
in this context to get around the % 'modulo' operator applied to 'real' problemtype):
output_value = realtime_val1 - realtime_val2 * $floor(realtime_val1/realtime_val2);
The problem is how you $display
the real
value.
%f
shows only zeroes because it does not have enough digits of precision to show very small floating point values. Use %g
to show the number in scientific format to see it really is non-zero. Similarly, use %f
and specify a large enough precision value.
module tb;
real meas_diff_div;
initial begin
meas_diff_div = 0.0000001;
if (meas_diff_div > 0) $display("%f" , meas_diff_div);
if (meas_diff_div > 0) $display("%1.7f", meas_diff_div);
if (meas_diff_div > 0) $display("%g" , meas_diff_div);
end
endmodule
Outputs:
0.000000
0.0000001
1e-07
As you can see, when the signal has a small non-zero value, like 0.0000001, the if
evaluates to true since it is larger than 0.
Although not explicitly stated in the IEEE Std 1800-2017, %f
seems to behave like %.6f
(the default number of digits after the decimal point is 6). Since this syntax was borrowed from C
, see also: What is c printf %f default precision?
For your filter you could do something like:
if (meas_diff_div > 0.001) `error("error message. %f", meas_diff_div);
In your code, the problem is not $floor
. The difference of 2 real
values can produce a non-zero value.