Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
7 years ago

Passing real parameters from Qsys (platform designer) to the custom IP core.

Hello,

I have developed a custom IP core which uses some calibration information, this information is passed to the top level entity.

However, I have generated the *_hw.tcl file for the qsys (platform designer) and it appears that it cannot pass any floating/real type parameters (there is no support) and converts these parameters to string data type.

So, then I thought that I can simply convert types: from "string" to "real". In VHDL2008 standard there is t'value(x) attribute, which converts string X to value of type T, BUT sadly this is not supported for "real" data type :(

Has anyone encountered this problem? Is there a solution without manually writing coefficients in source files every time I generate Qsys system?

Cheers,

Rihards

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    'value is not just a 2008 attribute.

    You could write a function to do the conversion yourself.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Ou.., I wanted to express that even in VHDL2008 standard 'value attribute does not support real data type.

    But thank You, I'll write my own function.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    My 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;