英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论