Electrical – VHDL 2008 – Use of custom floating package

vhdl

I am trying to use the floating point package that comes with VHDL2008 to have a custom floating point type ; I need half-precision (16 bits) floating numbers.

Being unexperienced with VHDL, I folowed the "Floating point package user guide" found here. On page 7, it describes how to use "float_pkg" with custom bit sizes.

To test it, I made a simple file that I simulate with Modelsim.

When trying to compile it :

vcom -work work -2008 -explicit -stats=none C:/.../testfloat.vhdl

I get the error :

** Error: C:/.../testfloat.vhdl(32): (vcom-1443) Interface package "fixed_pkg" requires a package instance actual

I tried to Google that error since I don't understand it, but with no result so far.

Here is my VHDL file :

Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
use IEEE.fixed_float_types.all;
use IEEE.float_pkg.all;

entity test is
  port (
    data_A    : in  std_logic_vector (25-1 downto 0);
    data_B    : in  std_logic_vector (25-1 downto 0);

    data_out  : out std_logic_vector (25-1 downto 0)
    );

end entity test;

architecture rtl of test is

use IEEE.fixed_float_types.all;
package my_float_pkg is new ieee.float_generic_pkg
  generic map (
     float_exponent_width => 5,          -- 5 bits of exponent
     float_fraction_width => 11,         -- default will be float(5 dt –11)
     float_round_style    => round_zero, -- Truncate, don’t round
     float_denormalize    => false,      -- no denormal numbers
     float_guard_bits     => 0,          -- Unused by round_zero, set to 0
     float_check_error    => false,      -- Turn NAN and overflow off.
     no_warning           => true        -- turn warnings off
     );

begin

  process(data_A, data_B)
    variable data_A_float     : work.my_float_pkg.float(5 downto -11);
    variable data_B_float     : work.my_float_pkg.float(5 downto -11);
    variable data_out_float   : work.my_float_pkg.float(5 downto -11);
  begin

    data_A_float := to_float(data_A, data_A'high, data_A'low);

  end process;
end architecture;

The content of the process is not relevant for the moment.

Best Answer

See the formal for the generic package in float_generic_pkg.vhdl:

package fixed_pkg is new IEEE.fixed_generic_pkg
                           generic map (<>)

See IEEE Std 1076-2008

6.5.7.2 Generic map aspects

An actual associated with a formal generic package in a generic map aspect shall be a name that denotes an instance of the uninstantiated package named in the formal generic package declaration, as follows:

...
b) If the formal generic package declaration includes an interface package generic map aspect in the form that includes the box (<>) symbol, then the instantiated package denoted by the actual may be any instance of the uninstantiated package named in the formal generic package declaration.

You're missing an actual for the formal which is a generic package.

Instantiate IEEE.fixed_generic_pkg and provide the new instance name as the actual.

architecture rtl of test is

use IEEE.fixed_float_types.all;
package fixed_pkg is new IEEE.fixed_generic_pkg
    generic map (
        fixed_round_style    => IEEE.fixed_float_types.fixed_round,
        fixed_overflow_style => IEEE.fixed_float_types.fixed_saturate,
        fixed_guard_bits     => 3,
        no_warning           => false
    );
package my_float_pkg is new ieee.float_generic_pkg
  generic map (
     float_exponent_width => 5,          -- 5 bits of exponent
     float_fraction_width => 11,         -- default will be float(5 dt –11)
     float_round_style    => round_zero, -- Truncate, don’t round
     float_denormalize    => false,      -- no denormal numbers
     float_guard_bits     => 0,          -- Unused by round_zero, set to 0
     float_check_error    => false,      -- Turn NAN and overflow off.
     no_warning           => true,       -- turn warnings off
     fixed_pkg            => fixed_pkg   -- ADDED
     );

begin

  process(data_A, data_B)
    variable data_A_float     : my_float_pkg.float(5 downto -11);
    variable data_B_float     : my_float_pkg.float(5 downto -11);
    variable data_out_float   : my_float_pkg.float(5 downto -11);
  begin

    data_A_float := my_float_pkg.to_float (
                    arg            => data_A(data_A_float'length - 1 downto 0), 
                    exponent_width => data_A_float'high, 
                    fraction_width => 0 - data_A_float'low  
                  );
  end process;
end architecture;

Also remove the prefix work from the references to my_float_pkg in the variable declarations in the process. Note the a prefix is added to the to_float call, my_float_pkg is not made visible by use clause.

That leaves you with an error for the to_float conversion function call which is outside the domain of this question. See the declaration in float_generic_pkg:

    -- std_ulogic_vector to float
       function to_float (
          arg                     : STD_ULOGIC_VECTOR;
          constant exponent_width : NATURAL := float_exponent_width; -- length of FP output exponent
          constant fraction_width : NATURAL := float_fraction_width) -- length of FP output fraction
         return UNRESOLVED_float;

The widths are given as naturals. The actual for the width of the fraction should be give the value 0 - data_A_float'low to make the number the natural length. (Note the references data_A'high and 'low were both adjusted to data_A_float'high and 'low, you were defining the wrong length as well).

And now the conversion works if the to_float call arg has the same length as the result type.

Note the IEEE fixed_pkg generic map for generic_fixed_pkg was used without regard to your actual usage (the possible impact of your generic constants of float_generic_pkg on my_float_pkg weren't evaluated).

If you're going to use IEEE.fixed_pkg you can provide that as the actual instead of instantiating fixed_generic_pkg first.

In addition to not using using Synopsys package std_logic_unsigned (which has a -2008 IEEE equivalent numeric_std_unsigned) you also don't use package numeric_std.