diff options
-rw-r--r-- | libraries/std/textio_body.vhdl | 144 | ||||
-rw-r--r-- | src/ghdldrv/ghdlrun.adb | 2 | ||||
-rw-r--r-- | src/grt/grt-files.ads | 3 | ||||
-rw-r--r-- | src/grt/grt-lib.adb | 21 | ||||
-rw-r--r-- | src/grt/grt-lib.ads | 7 | ||||
-rw-r--r-- | src/grt/grt-types.ads | 3 | ||||
-rw-r--r-- | src/std_names.adb | 1 | ||||
-rw-r--r-- | src/std_names.ads | 5 |
8 files changed, 53 insertions, 133 deletions
diff --git a/libraries/std/textio_body.vhdl b/libraries/std/textio_body.vhdl index 823b4b67e..36a11fc23 100644 --- a/libraries/std/textio_body.vhdl +++ b/libraries/std/textio_body.vhdl @@ -16,6 +16,8 @@ -- <http://www.gnu.org/licenses/>. package body textio is + attribute foreign : string; --V87 + --START-V08 -- LRM08 16.4 -- The JUSTIFY operation formats a string value within a field that is at @@ -334,6 +336,17 @@ package body textio is write (l, str (1 to pos - 1), justified, field); end write; + procedure textio_write_real + (s : out string; len : out natural; value: real; ndigits : natural); + + attribute foreign of textio_write_real : procedure is "GHDL intrinsic"; + + procedure textio_write_real + (s : out string; len : out natural; value: real; ndigits : natural) is + begin + assert false report "must not be called" severity failure; + end textio_write_real; + -- Parameter DIGITS specifies how many digits to the right of the decimal -- point are to be output when writing a real number; the default value 0 -- indicates that the number should be output in standard form, consisting @@ -350,133 +363,12 @@ package body textio is -- STR contains the result of the conversion. variable str : string (1 to 320); - -- POS is the index of the next character to be put in STR. - variable pos : positive := str'left; - - -- VAL contains the value to be converted. - variable val : real; - - -- The exponent or mantissa computed is stored in MANTISSA. This is - -- a signed number. - variable mantissa : integer; - - variable b : boolean; - variable d : natural; - - -- Append character C in STR. - procedure add_char (c : character) is - begin - str (pos) := c; - pos := pos + 1; - end add_char; - - -- Add digit V in STR. - procedure add_digit (v : natural) is - begin - add_char (character'val (character'pos ('0') + v)); - end add_digit; - - -- Add leading digit and substract it. - procedure extract_leading_digit is - variable d : natural range 0 to 10; - begin - -- Note: We need truncation but type conversion does rounding. - -- FIXME: should consider precision. - d := natural (val); - if real (d) > val then - d := d - 1; - end if; - - val := (val - real (d)) * 10.0; - - add_digit (d); - end extract_leading_digit; + variable len : natural; begin - -- Handle sign. - -- There is no overflow here, since with IEEE implementations, sign is - -- independant of the mantissa. - -- LRM93 14.3 - -- The sign is never written if the value is non-negative. - if value < 0.0 then - add_char ('-'); - val := -value; - else - val := value; - end if; - - -- Compute the mantissa. - -- FIXME: should do a dichotomy. - if val = 0.0 then - mantissa := 0; - elsif val < 1.0 then - mantissa := -1; - while val * (10.0 ** (-mantissa)) < 1.0 loop - mantissa := mantissa - 1; - end loop; - else - mantissa := 0; - while val / (10.0 ** mantissa) >= 10.0 loop - mantissa := mantissa + 1; - end loop; - end if; - - -- Normalize VAL: in [0; 10[ - if mantissa >= 0 then - val := val / (10.0 ** mantissa); - else - val := val * 10.0 ** (-mantissa); - end if; - - if digits = 0 then - for i in 0 to 15 loop - extract_leading_digit; - - if i = 0 then - add_char ('.'); - end if; - exit when i > 0 and val < 10.0 ** (i + 1 - 15); - end loop; + textio_write_real (str, len, value, digits); + assert len <= str'length severity failure; - -- LRM93 14.3 - -- if the exponent is present, the `e' is written as a lower case - -- character. - add_char ('e'); - - if mantissa < 0 then - add_char ('-'); - mantissa := -mantissa; - end if; - b := false; - for i in 4 downto 0 loop - d := (mantissa / 10000) mod 10; - if d /= 0 or b or i = 0 then - add_digit (d); - b := true; - end if; - mantissa := (mantissa - d * 10000) * 10; - end loop; - else - if mantissa < 0 then - add_char ('0'); - mantissa := mantissa + 1; - else - loop - extract_leading_digit; - exit when mantissa = 0; - mantissa := mantissa - 1; - end loop; - end if; - add_char ('.'); - for i in 1 to digits loop - if mantissa = 0 then - extract_leading_digit; - else - add_char ('0'); - mantissa := mantissa + 1; - end if; - end loop; - end if; - write (l, str (1 to pos - 1), justified, field); + write (l, str (1 to len), justified, field); end write; --START-V08 @@ -493,8 +385,6 @@ package body textio is end Hwrite; --END-V08 - attribute foreign : string; --V87 - procedure untruncated_text_read --V87 (variable f : text; str : out string; len : out natural); --V87 procedure untruncated_text_read --!V87 diff --git a/src/ghdldrv/ghdlrun.adb b/src/ghdldrv/ghdlrun.adb index 6e2351343..55165fac4 100644 --- a/src/ghdldrv/ghdlrun.adb +++ b/src/ghdldrv/ghdlrun.adb @@ -189,6 +189,8 @@ package body Ghdlrun is Def (Ortho, Grt.Files.Ghdl_Untruncated_Text_Read'Address); elsif Name = "textio_read_real" then Def (Ortho, Grt.Lib.Textio_Read_Real'Address); + elsif Name = "textio_write_real" then + Def (Ortho, Grt.Lib.Textio_Write_Real'Address); elsif Name = "control_simulation" then Def (Ortho, Grt.Lib.Ghdl_Control_Simulation'Address); elsif Name = "get_resolution_limit" then diff --git a/src/grt/grt-files.ads b/src/grt/grt-files.ads index 3c6191f36..e5c797ec9 100644 --- a/src/grt/grt-files.ads +++ b/src/grt/grt-files.ads @@ -75,9 +75,6 @@ package Grt.Files is function Ghdl_Text_Read_Length (File : Ghdl_File_Index; Str : Std_String_Ptr) return Std_Integer; - type Std_Integer_Acc is access Std_Integer; - pragma Convention (C, Std_Integer_Acc); - procedure Ghdl_Untruncated_Text_Read (File : Ghdl_File_Index; Str : Std_String_Ptr; Len : Std_Integer_Acc); diff --git a/src/grt/grt-lib.adb b/src/grt/grt-lib.adb index 3c16392be..9aa3558cc 100644 --- a/src/grt/grt-lib.adb +++ b/src/grt/grt-lib.adb @@ -22,6 +22,8 @@ -- covered by the GNU General Public License. This exception does not -- however invalidate any other reasons why the executable file might be -- covered by the GNU Public License. + +with Interfaces; with Grt.Errors; use Grt.Errors; with Grt.Options; with Grt.Fcvt; @@ -277,9 +279,26 @@ package body Grt.Lib is subtype Str1 is String (1 .. Natural (Str.Bounds.Dim_1.Length)); begin return Ghdl_F64 (Grt.Fcvt.From_String - (Str1 (Str.Base (0 .. Str.Bounds.Dim_1.Length)))); + (Str1 (Str.Base (0 .. Str.Bounds.Dim_1.Length - 1)))); end Textio_Read_Real; + procedure Textio_Write_Real (Str : Std_String_Ptr; + Len : Std_Integer_Acc; + V : Ghdl_F64; + Ndigits : Std_Integer) + is + -- FIXME: avoid that copy. + S : String (1 .. Natural (Str.Bounds.Dim_1.Length)); + Last : Natural; + begin + Grt.Fcvt.Format_Digits + (S, Last, Interfaces.IEEE_Float_64 (V), Natural (Ndigits)); + Len.all := Std_Integer (Last); + for I in 1 .. Last loop + Str.Base (Ghdl_Index_Type (I - 1)) := S (I); + end loop; + end Textio_Write_Real; + function Ghdl_Get_Resolution_Limit return Std_Time is begin return 1; diff --git a/src/grt/grt-lib.ads b/src/grt/grt-lib.ads index 97ee669a8..6e01ea9de 100644 --- a/src/grt/grt-lib.ads +++ b/src/grt/grt-lib.ads @@ -94,6 +94,11 @@ package Grt.Lib is function Textio_Read_Real (Str : Std_String_Ptr) return Ghdl_F64; + procedure Textio_Write_Real (Str : Std_String_Ptr; + Len : Std_Integer_Acc; + V : Ghdl_F64; + Ndigits : Std_Integer); + function Ghdl_Get_Resolution_Limit return Std_Time; procedure Ghdl_Control_Simulation @@ -124,6 +129,8 @@ private pragma Export (C, Textio_Read_Real, "std__textio__textio_read_real"); + pragma Export (C, Textio_Write_Real, + "std__textio__textio_write_real"); pragma Export (C, Ghdl_Get_Resolution_Limit, "std__env__get_resolution_limit"); diff --git a/src/grt/grt-types.ads b/src/grt/grt-types.ads index 5fb60f2d5..d9b17f67e 100644 --- a/src/grt/grt-types.ads +++ b/src/grt/grt-types.ads @@ -55,6 +55,9 @@ package Grt.Types is subtype Std_Integer is Ghdl_I32; + type Std_Integer_Acc is access Std_Integer; + pragma Convention (C, Std_Integer_Acc); + type Std_Time is new Ghdl_I64; Bad_Time : constant Std_Time := Std_Time'First; diff --git a/src/std_names.adb b/src/std_names.adb index 60d96d4f4..4e2f05f04 100644 --- a/src/std_names.adb +++ b/src/std_names.adb @@ -399,6 +399,7 @@ package body Std_Names is Def ("maximum", Name_Maximum); Def ("untruncated_text_read", Name_Untruncated_Text_Read); Def ("textio_read_real", Name_Textio_Read_Real); + Def ("textio_write_real", Name_Textio_Write_Real); Def ("get_resolution_limit", Name_Get_Resolution_Limit); Def ("control_simulation", Name_Control_Simulation); diff --git a/src/std_names.ads b/src/std_names.ads index 0dc3143f3..2f75e8b0e 100644 --- a/src/std_names.ads +++ b/src/std_names.ads @@ -473,8 +473,9 @@ package Std_Names is Name_Maximum : constant Name_Id := Name_First_Misc + 023; Name_Untruncated_Text_Read : constant Name_Id := Name_First_Misc + 024; Name_Textio_Read_Real : constant Name_Id := Name_First_Misc + 025; - Name_Get_Resolution_Limit : constant Name_Id := Name_First_Misc + 026; - Name_Control_Simulation : constant Name_Id := Name_First_Misc + 027; + Name_Textio_Write_Real : constant Name_Id := Name_First_Misc + 026; + Name_Get_Resolution_Limit : constant Name_Id := Name_First_Misc + 027; + Name_Control_Simulation : constant Name_Id := Name_First_Misc + 028; Name_Last_Misc : constant Name_Id := Name_Control_Simulation; Name_First_Ieee : constant Name_Id := Name_Last_Misc + 1; |