I have a real number delay
which I would like to convert to the first multiple of 10. For example, if delay = 0.0024, I want the output to be 240.
In the following code snippet, delay
= 1.52e-6. After while
loop execution, I was expecting delay
to be 1520. However, I'm seeing that delay
= 1.52e17 after while
loop. I checked the waveform, and it looks like the value of delay
was 1.5200000000000001e-6 to begin with. Why is it so? Am I doing something wrong?
Here is the code:
real delay = 1.52e-6;
function real mod (real a, real b);
mod = a - b*$floor(a/b);
endfunction
initial begin
while (mod(delay, 10) != 0) delay = delay*10;
end
In the following code snippet, delay = 1.52e-6
Note quite.
Floating point types are commonly encoded using binary64 or the like. This 64-bit encoding can encode about 264 different values exactly. 1.52e-6 is not one of them as it is not a Dyadic rational (some integer times a power of 2). Instead code starts working with a nearby value of 1.5200000000000000582720720634921640623815619619563e-06 or 0x198059AC99A685 * 2-72.
Further complications occurs because many of the delay = delay*10
incur a rounding error.
Amend goal or use a different approach.
"convert to the first multiple of 10" sounds like a secondary goal. What is the higher level goal?
Note: All finite floating point values are exact. It is how we operate on them that often leading to a result that differs from the exact math result we learned in school.