Search code examples
vhdlmodelsim

Using the VHDL 2008 generic type feature to create pseudo-dynamic types


I'm trying to create a record that can hold data of different types, would that be possible in some way using VDHL 2008's generic typing feature? I'm not trying to synthesize that code.

My test setup looks like this:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;

entity dynrec is

end entity dynrec;

architecture dyn of dynrec is

  type dynrec is record    -- this is a test record
    datatype : type;       -- type of the data field
    data     : datatype;
    someval  : natural;
  end record dynrec;

  signal testsig1, testsig2 : dynrec;

begin  -- architecture dyn

testsig1 <= (datatype => real,      data => 5.0, someval => 12);
testsig2 <= (datatype => std_logic, data => '1', someval => 12);

end architecture dyn;

You see, what I'm trying to do is have a record that can hold different types of data depending on one of it's fields. However, it fails at compile time with the following error:

# ** Error: dynrec.vhd(13): near "type": expecting STRING or IDENTIFIER or << or '('
# C:/Programme/Mentor/Modelsim10.0b/win32/vcom failed.

is there a way to make something like this work?

I'm using mentorgraphics modelsim 10.0b, and I compiled using vcom dynrec.vhd -2008.


Solution

  • As far as I know, you would have to do something like this:

    package dynrec_pkg is
      generic (
        datatype : type
      );
    
      type dynrec_type is record
        data     : datatype;
        someval  : natural;
      end record dynrec_type;
    end package dynrec_pkg;
    
    ---------------------
    
    library ieee;
    use ieee.math_real.all;
    
    package dynrec_pkg_real is new work.dynrec_pkg generic map (datatype => real);
    
    ---------------------
    
    library ieee;
    use ieee.std_logic_1164.all;
    
    package dynrec_pkg_sl is new work.dynrec_pkg generic map (datatype => std_logic);
    
    ---------------------
    
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.math_real.all;
    
    use work.dynrec_pkg_real.all;
    use work.dynrec_pkg_sl.all;
    
    entity dynrec is
    end entity dynrec;
    
    architecture dyn of dynrec is
    
      signal testsig1 : dynrec_pkg_real.dynrec_type;
      signal testsig2 : dynrec_pkg_sl.dynrec_type;
    
    begin  -- architecture dyn
    
      testsig1 <= (data => 5.0, someval => 12);
      testsig2 <= (data => '1', someval => 12);
    
    end architecture dyn;
    

    Since you want to create instances of records with two different types, this would seem to be the best way. Otherwise, you could make datatype a generic for the entity itself and avoid the extra package, but then you'd only have one dynamic type visible to the entity (of course, you could have multiple generics like datatype1, datatype2, etc).

    The bottom line is that you can't define a record the way you did with an inline generic type - design elements like packages and entities can have generics, but records cannot.

    Note that ModelSim does not seem to support this feature yet anyway (I'm using 10.2c), and I don't have a simulator handy that does, so syntax corrections would be welcome. I think the general idea is sound, though.