1

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);
toolic
  • 57,801
  • 17
  • 75
  • 117

1 Answers1

2

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.

toolic
  • 57,801
  • 17
  • 75
  • 117