2

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.

youR.Fate
  • 796
  • 4
  • 10
  • 29

2 Answers2

3

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.

fru1tbat
  • 1,605
  • 9
  • 16
  • Yes, that kind of goes in the direction, but what I really wanted to do with it is have a linked list of those records, where each elemnt could contain data of an arbitrary type. That is probably not gonna happen in VHDL, though. – youR.Fate Mar 27 '14 at 12:58
  • I can't think of an elegant way to make that possible. There are some inelegant workarounds, like making a linked list node type with multiple data members, but that isn't really generic (and doesn't specifically require VHDL-2008 either, for that matter). – fru1tbat Mar 27 '14 at 16:42
  • 1
    One avenue to consider is a record that stores a dynamically allocated string along with a type indicator. That will allow you to build a generic linked list with some extra work and overhead of converting between string and "native" representations. When I need these types of records, though, I usually just put in all the fields of various types and accept the overhead of unused fields. VHDL isn't a systems programming language so you have to accept that it is challenging to do some tasks. – Kevin Thibedeau Apr 11 '14 at 17:38
2

You can do this nicely in a generic package (see fru1bat post) + a protected type.

The OSVVM packages use protected types. You can couple that with the generic packages above to create your linked list. The simplest one with a linked list is the 2014.01 package, MessagePkg.

You can get the OSVVM packages at either http://www.osvvm.org or http://www.synthworks.com/downloads

Also, if your simulator does not fully support generic packages yet, you can emulate them by doing the following:

package dynrec_pkg_real is
--  generic (
--    datatype : type
--  );
  subtype datatype is real ;
Jim Lewis
  • 3,601
  • 10
  • 20