probllem with $rtoi in verilog testbench

On Feb 19, 11:41 pm, sh...@cadence.com wrote:
If I use Stephen's test program, NC-Verilog also gets a result of 80.
Changing it to print all the real values with %20.18f formats to see
them with more precision, I get

3334.400000000000090949 / 41.679999999999999716 > 80.000000000000000000

So despite the roundoff error in the closest representable values to
3334.4 and 41.68, the value comes out fine.

One of your values must have more than this minimum possible roundoff
error.

For the moment however, the 3334.40 figure ultimately
comes from a simulation timestamp using the
$realtime command.

It is possible that the conversion of the time to a real in $realtime
is accumulating some roundoff error.  However, a test with a timescale
of 10ns/1ns and a delay of #3334.4 gives me the exact same value as
above.

The 41.68 figure comes from the mulitplication
of an 8bit value by a real value.  Hence, the
problem may arise here.  I may have to change this
8bit value to a real quantity.  I will follow
up on this.

It is quite possible that this calculation is causing the additional
roundoff.

(Is this a likely cause of the problem?)

Changing the 8bit value to a real value is unlikely to help.  Small
integer values can be represented exactly in floating point, so that
is not where the roundoff error is coming from.

Ultimately, you need to recognize that floating point representation
and calculation are subject to roundoff error.  You should not expect
to get the exact values that you can get with integers.  You should
switch to integer calculations, or adjust for possible roundoff
error.  For example, you might want to try rounding instead of
truncating.  An implicit conversion from real to integer will round
instead of the truncation that $rtoi does.  Or you can add 0.5 or a
small fudge factor before calling $rtoi.
Thank you for this detailed analysis.

I revisited the numbers and I got the TB to $display them with a
much greater accuracy (%20.18f). It seems that the number that I see
as
3334.40 is in fact slightly different at 3334.3999987.... I had not
anticipated this at the time and as such accuracy is lost in the
calculation.

Now I know why the $rtoi gives a value of 79, as it is merely
truncating
the 79.99999 that is produced by dividing the 33334.3999987... figure
by 41.68.

As regards your last paragraph, I have learned much re the rounding
errors to which floating point number calculations are prone. I will
also
note the truncating effect of the $rtoi function. I will try to
operate in integers instead or a try new approach entirely. I am
also considering using the fudge factor method that you speak of as an
expected margin of error.

Thank you for your time and assistance on this.

Regards
SB.
 
If I use Stephen's test program, NC-Verilog also gets a result of 80.
Changing it to print all the real values with %20.18f formats to see
them with more precision, I get

3334.400000000000090949 / 41.679999999999999716 =
80.000000000000000000

So despite the roundoff error in the closest representable values to
3334.4 and 41.68, the value comes out fine.

One of your values must have more than this minimum possible roundoff
error.

For the moment however, the 3334.40 figure ultimately
comes from a simulation timestamp using the
$realtime command.
It is possible that the conversion of the time to a real in $realtime
is accumulating some roundoff error. However, a test with a timescale
of 10ns/1ns and a delay of #3334.4 gives me the exact same value as
above.


The 41.68 figure comes from the mulitplication
of an 8bit value by a real value. Hence, the
problem may arise here. I may have to change this
8bit value to a real quantity. I will follow
up on this.
It is quite possible that this calculation is causing the additional
roundoff.

(Is this a likely cause of the problem?)
Changing the 8bit value to a real value is unlikely to help. Small
integer values can be represented exactly in floating point, so that
is not where the roundoff error is coming from.

Ultimately, you need to recognize that floating point representation
and calculation are subject to roundoff error. You should not expect
to get the exact values that you can get with integers. You should
switch to integer calculations, or adjust for possible roundoff
error. For example, you might want to try rounding instead of
truncating. An implicit conversion from real to integer will round
instead of the truncation that $rtoi does. Or you can add 0.5 or a
small fudge factor before calling $rtoi.
 
On Feb 18, 4:19 pm, SB <smartba...@yahoo.com> wrote:
Hi there,

I have a problem with the $rtoi function in my verilog testbench.

When I do,
$rtoi(80.000000) it gives me 80.  That is fine.

However, when I do
real x
real a
real b
x = a * 1.0 / b

Where a = 3334.400000 and b = 41.680000

and then  do:
integer y
y =  $rtoi(x) it gives me 79 for y.
I expect to get 80 for y.

When I do a $display on x I get 80.000000, so
the calculation above seems to progress properly.

What could be the problem with this function $rtoi?
Am I missing something here?
Probably roundoff error. $rtoi truncates rather than rounding, so if
you get 79.99999999999, it will come out 79. Numbers like 3334.4
cannot be represented exactly in floating point, and by the time you
do some arithmetic on them, you are unlikely to get exact integer
values. Try doing your $display of x with a high-precision format,
such as %18.20f and you will probably see that it is not exactly 80.
 
On 18 Feb, 21:52, Stephen Williams <spamt...@icarus.com> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

The attached program generates the output you expect when I
run it with Icarus Verilog. I suspect there is more to your
example then you are reporting here. When complaining about
strange behaviors, it is usually best to give a complete example
that demonstrates your problem.





SB wrote:
Hi there,

I have a problem with the $rtoi function in my verilog testbench.

When I do,
$rtoi(80.000000) it gives me 80.  That is fine.

However, when I do
real x
real a
real b
x = a * 1.0 / b

Where a = 3334.400000 and b = 41.680000

and then  do:
integer y
y =  $rtoi(x) it gives me 79 for y.
I expect to get 80 for y.

When I do a $display on x I get 80.000000, so
the calculation above seems to progress properly.

- --
Steve Williams                "The woods are lovely, dark and deep.
steve at icarus.com           But I have promises to keep,http://www.icarus.com        and lines to code before I sleep,http://www.picturel.com      And lines to code before I sleep."
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with SUSE -http://enigmail.mozdev.org

iD8DBQFHuf4yrPt1Sc2b3ikRArccAJ4oSn0RI1MCsfw7/OhwOwZNFKulFQCgy/UF
3togc4i67MzCq8oklV2nsVw> =AJeW
-----END PGP SIGNATURE-----

[tmp.v]

module main;

   real x;
   real a;
   real b;
   integer y;

   initial begin
      a = 3334.4;
      b = 41.68;
      x = a * 1.0 / b;
      y = $rtoi(x);

      $display("x=%f, y=%d", x, y);
   end

endmodule // main- Hide quoted text -

- Show quoted text -
Stephen Williams,

Thank you for the reply. I will try out the
code file that you give tomorrow.

Fair point on the importance of giving more
information on behaviour in problems such as this. I
will to further debug on this.

For the moment however, the 3334.40 figure ultimately
comes from a simulation timestamp using the
$realtime command.

The 41.68 figure comes from the mulitplication
of an 8bit value by a real value. Hence, the
problem may arise here. I may have to change this
8bit value to a real quantity. I will follow
up on this.

(Is this a likely cause of the problem?)

For the record I am using ncvlog.

Thanks
SB.
 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


The attached program generates the output you expect when I
run it with Icarus Verilog. I suspect there is more to your
example then you are reporting here. When complaining about
strange behaviors, it is usually best to give a complete example
that demonstrates your problem.

SB wrote:
Hi there,

I have a problem with the $rtoi function in my verilog testbench.

When I do,
$rtoi(80.000000) it gives me 80. That is fine.

However, when I do
real x
real a
real b
x = a * 1.0 / b

Where a = 3334.400000 and b = 41.680000

and then do:
integer y
y = $rtoi(x) it gives me 79 for y.
I expect to get 80 for y.

When I do a $display on x I get 80.000000, so
the calculation above seems to progress properly.
- --
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFHuf4yrPt1Sc2b3ikRArccAJ4oSn0RI1MCsfw7/OhwOwZNFKulFQCgy/UF
3togc4i67MzCq8oklV2nsVw=
=AJeW
-----END PGP SIGNATURE-----
 
S

SB

Guest
Hi there,

I have a problem with the $rtoi function in my verilog testbench.

When I do,
$rtoi(80.000000) it gives me 80. That is fine.

However, when I do
real x
real a
real b
x = a * 1.0 / b

Where a = 3334.400000 and b = 41.680000

and then do:
integer y
y = $rtoi(x) it gives me 79 for y.
I expect to get 80 for y.

When I do a $display on x I get 80.000000, so
the calculation above seems to progress properly.

What could be the problem with this function $rtoi?
Am I missing something here?

Any help would be great!

Regards,
Paul
 

Welcome to EDABoard.com

Sponsor

Back
Top