Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I extract elements from a record using an integer reference in VHDL?

Tags:

record

vhdl

Firstly here is what I'm aiming to do, using made-up VHDL syntax...

type type_johns_record is
  first_element : std_logic;
  second_element: std_logic_vector(3 downto 0);
  third_element : boolean;
end record;
....
....

for ii in johns_record'range loop
  if johns_record.type_johns_record'val(ii) = .... then
    exit;
  end if;
end loop;

Hopefully you can see that I'm trying to reference the elements of a record using similar syntax to that which can be used to reference an enumerated type. This however (of course) does not work. Is there a similar syntax that will work? My solution at the moment is to use a record_info field and work using std_logic_vectors as shown below....

type type_johns_record is record
    first_element : std_logic;
    second_element : std_logic_vector(3 downto 0);
    third_element : boolean;
    record_info : type_integer_array(2 downto 0);
  end record;

  function type_johns_record2slv(d : type_johns_record) return std_logic_vector is
  begin
    return (d.first_element & d.second_element & bool2sl(d.third_element));
  end function;

  constant johns_record_zero : type_johns_record := (first_element => '0',
                                                     second_element => "0000",
                                                     third_element => false,
                                                     record_info => (1, 4, 1));

  -- can be used with any type for which a record_info is known
  function get_record_element(input : std_logic_vector; element_number : integer; record_info :     type_integer_array) return std_logic_vector is
    variable r : type_slv32_array(record_info'length-1 downto 0);
    variable pos : integer := 0;
  begin
    for ii in record_info'range loop
      r(ii)(record_info(ii)-1 downto 0) := input(pos+record_info(ii)-1 downto pos);      
    end loop;
    return r(element_number)(record_info(element_number)-1 downto 0);
  end function;

I can then use these functions (which are in a package) as follows...

 for ii in johns_record.record_info'range loop
   if get_record_element(type_johns_record2slv(johns_record), ii, johns_record.record_info) = conv_std_logic_vector(4, johns_record.record_info(ii)) then
      exit;
   end if;
 end loop;    

This really sucks and specifying the record_info is error prone and only marginally less time consuming that writing out individual element comparisons line by line. Please offer a better solution!!!

like image 820
John Harrison Avatar asked Oct 16 '25 13:10

John Harrison


2 Answers

In the IEEE VHDL Standards group, there are actually two proposals relating to this: http://www.eda.org/twiki/bin/view.cgi/P1076/RecordMemberAttribute and http://www.eda.org/twiki/bin/view.cgi/P1076/RecordIntrospection

This does not mean relax, someone else will address the issue. Instead, we need you to comment on it and/or propose additional use models (to help with justification). All of our work is done by volunteers - just like you - no memberships required for basic participation. Much of our work is done on the TWIKI and email reflector and all with VHDL background are welcome to participate. Drop me an email, I will get you setup - see my Stack Exchange profile for details.

To participate, start here: http://www.eda.org/twiki/bin/view.cgi/P1076/

Current proposals: http://www.eda.org/twiki/bin/view.cgi/P1076/CollectedRequirements

Meeting information: http://www.eda.org/twiki/bin/view.cgi/P1076/MeetingMinutes

like image 167
Jim Lewis Avatar answered Oct 18 '25 22:10

Jim Lewis


If you'd like to shorten your implementation code slightly, you could write a custom function for each record type (which you already have to do to convert to slv; this would just be a bit longer) that returns the nth element, like:

function get_record_element(input : johns_record_type; element_number : natural) return std_logic_vector is
begin
  case element_number is
    when 0 =>
      return to_slv(input.first_element);
    when 1 =>
      return to_slv(input.second_element);
    ...
end function;

...    

if get_record_element(johns_record, 2) = ... then

where to_slv is just a set of helper functions to convert other types. Is that more or less tedious than writing a more generic function and using an extra record element?

like image 42
fru1tbat Avatar answered Oct 18 '25 22:10

fru1tbat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!