Real value printed with %f is 0.0000, but condition '>0' does not apply (after using $floor in a task)

huangapple go评论58阅读模式
英文:

Real value printed with %f is 0.0000, but condition '>0' does not apply (after using $floor in a task)

问题

声明我的变量:

real meas_diff_div;

我有一个任务,在其中我使用这个变量:

measure_task(meas_diff_div);

之后,我基于这个real的值过滤错误

if (meas_diff_div > 0)
    error("错误消息。%f", meas_diff_div);

有时,即使打印的值为0.000000,错误也会触发

在任务声明中,第一行如下所示:

task measure_task(output real output_value);

在任务中,这个real被填充(在这个上下文中,我使用$floor来解决real上应用%“模”运算符的问题类型):

output_value = realtime_val1 - realtime_val2 * $floor(realtime_val1/realtime_val2);
英文:

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);

答案1

得分: 2

问题是如何显示real值。

%f只显示零,因为它没有足够的小数精度位来显示非常小的浮点值。使用%g以科学格式显示数字,以查看它是否真的不为零。同样,使用%f并指定足够大的精度值。

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

输出:

0.000000
0.0000001
1e-07

如您所见,当信号具有小的非零值,例如0.0000001时,if评估为true,因为它大于0。

尽管IEEE Std 1800-2017没有明确规定,%f似乎表现得像%.6f(小数点后默认位数为6)。由于此语法借用自C,请参阅:What is c printf %f default precision?

对于您的滤波器,您可以这样做:

if (meas_diff_div > 0.001) `error("error message. %f", meas_diff_div);

在您的代码中,问题不在于$floor。两个real值的差异可能会产生非零值。

英文:

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.

huangapple
  • 本文由 发表于 2023年2月8日 18:21:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75384341.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定