Forum Discussion
Altera_Forum
Honored Contributor
7 years agoMy straight forward implementation for future reference:
-- synopsis directives:
-- synthesis VHDL_INPUT_VERSION VHDL_2008
library ieee;
use ieee.std_logic_1164.all,
package functions is
function to_real( str:string ) return real;
end package;
package body functions is
function extract_exponent_value( str_exp:string ) return real is
variable i : natural;
variable is_inverse : boolean := false;
variable ret : real := 0.0;
variable digit : natural;
begin
for i in str_exp'low to str_exp'high loop
-- skip character if it exists
if (str_exp(i) = 'E') or (str_exp(i) = 'e') then
report "Exponent sign";
next;
end if;
-- we can safely skip '+' sign
if (str_exp(i) = '+') then
report "Plus sign";
next;
end if;
-- is exponent 'negative'
if (str_exp(i) = '-') then
report "Minus sign";
is_inverse := true;
next;
end if;
digit := integer'value(str_exp(i to i));
ret := ret + real(10)**( digit*(str_exp'high-i+1));
report "Exponent: " & real'image(ret);
end loop;
--
if is_inverse then
ret := 1.0/ret;
end if;
return ret;
end function;
function extract_exponent( str:string ) return real is
variable i : natural;
begin
-- finc exponent
for i in str'low to str'high loop
if (str(i) = 'E') or (str(i) = 'e') then
return extract_exponent_value( str(i to str'high) );
end if;
end loop;
-- if there was no exponent, let's return identity
return 1.0;
end function;
function to_real( str:string ) return real is
variable i : natural;
variable pos_decimal : natural := 0;
variable pos_start : natural := str'low;
variable pos_end : natural := str'high;
variable is_negative : boolean := false;
variable exponent : real := 1.0;
variable ret : real := 0.0;
begin
-- check for negative sign
if( str(str'low) = '-') then
pos_start := str'low + 1;
is_negative := true;
end if;
for i in pos_start to pos_end loop
-- get decimal point position
if( str(i) = '.') then
pos_decimal := i;
next;
end if;
-- check if exponent form
if (str(i) = 'E') or (str(i) = 'e') then
exponent := extract_exponent(str);
pos_end := i-1;
exit;
--report "Exponent form is not supported!" severity FAILURE;
end if;
end loop;
-- whole digits
for i in pos_start to pos_decimal-1 loop
ret := ret + real(integer'value(str(i to i))) * (real(10)**(pos_decimal-i-1));
end loop;
-- fractional digits
for i in pos_decimal+1 to pos_end loop
ret := ret + real(integer'value(str(i to i))) * (real(10)**(pos_decimal-i));
end loop;
-- inverse the value if necesarry
if is_negative then
ret := -ret;
end if;
-- multiply by our exponent value
ret := ret * exponent;
report "string '" & str & "' converted to " & real'image(ret);
return ret;
end function;
end package body;