On Sun, 2005-12-11 at 14:27 +0100, Tristan Gingold wrote:

> No.  You should run under gdb, and see where it is looping forever.

It seems to be a bug in Image_F64, see the attached patch.

I have also added a test program for the correctness of the output.
Wouldn't it be good to have test cases also in the gna repository?
ritest.vhd would be a start ;-)

Tom

--- vhdl/grt/grt-images.adb.jnx	2005-12-12 13:32:20.000000000 +0100
+++ vhdl/grt/grt-images.adb	2005-12-12 13:33:31.000000000 +0100
@@ -157,18 +157,18 @@
       if V  = 0.0 then
          Exp := 0;
       elsif V < 1.0 then
-         Exp := -1;
+         Exp := 0;
          loop
             exit when V >= 1.0;
             Exp := Exp - 1;
-            V := V / 10.0;
+            V := V * 10.0;
          end loop;
       else
          Exp := 0;
          loop
             exit when V < 10.0;
             Exp := Exp + 1;
-            V := V * 10.0;
+            V := V / 10.0;
          end loop;
       end if;
 
library ieee;
use ieee.math_real.all;

use std.textio.all;

entity real_image_test is
end real_image_test;

architecture testcase of real_image_test is

  function random return integer is
  begin
    assert false report "native" severity failure;
  end random;

  attribute foreign of random : function is "VHPIDIRECT random";

  function max(x : real; y : real) return real is
  begin
    if y > x then
      return y;
    end if;
    return x;
  end max;
  
  procedure test_real(x : in real) is
    variable ln : line;
    variable ok : boolean;
    variable y, tol : real;
  begin
    ln := new string'(real'image(x));
    read(ln, y, ok);
    assert ok report "Cannot parse real'image number: " & ln.all severity 
failure;
    deallocate(ln);
    ln := null;
    write(ln, string'("Number: "));
    write(ln, x);
    write(ln, "  real'image: " & real'image(x) & "  difference: ");
    write(ln, y-x);
    tol := abs(y-x) / max(abs(x), 1.0e-30);
    write(ln, string'(" tolerance: "));
    write(ln, tol);
    writeline(output, ln);
    assert tol < 1.0e-8 report "Tolerance!" severity error;
  end test_real;

begin

  test_p: process
    variable x : real;
  begin
    test_real(1.0);
    test_real(0.0);
    test_real(MATH_PI);
    for i in 1 to 100 loop
      x := real(random);
      if x > 0.0 then
        x := real(random) / x;
      end if;
      if random mod 2 = 1 then
        x := -x;
      end if;
      test_real(x);
    end loop;
    wait;
  end process test_p;

end testcase;

Reply via email to