Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get attribute of a field from a VHDL record type

Consider the following VHDL record:

type big_record_t is record
    field_a : unsigned(15 downto 0);
    field_b : unsigned(23 downto 0);
end record;

Is it possible to get attributes on the record fields without instantiating the record itself? eg

signal ex : unsigned(big_record_t.field_a'range);

modelsim reports the following error:

(vcom-1260) Type mark (big_record_t) cannot be prefix of selected name.

I know that getting the attribute of a instantiated signal is possible but for this specific situation I want to get the type attributes from the type itself.

like image 377
Maurice Avatar asked Apr 15 '16 09:04

Maurice


2 Answers

You cannot use the 'range attribute on a type , which is what you are trying to do in your code. If you were to do something like this:

signal big_record_instance : big_record_t;
signal ex : unsigned(big_record_instance.field_a'range);

It should work, because you are now trying to get the range of an instance, not a type.

An alternative if you don't have an instance might be to have your width based on constants in the same package that your record type is defined, something like this:

constant field_a_width : integer := 16;

type big_record_t is record
        field_a : std_logic_vector(field_a_width-1 downto 0);
        field_b : std_logic_vector(23 downto 0);
end record;

signal ex : std_logic_vector(field_a_width-1 downto 0);

Or perhaps

constant field_a_width : integer := 16;

subtype field_a_type is std_logic_vector(field_a_width-1 downto 0);

type big_record_t is record
        field_a : field_a_type;
        field_b : std_logic_vector(23 downto 0);
end record;

signal ex : field_a_type;

see exception in comments

like image 65
scary_jeff Avatar answered Nov 15 '22 10:11

scary_jeff


One other suggestion is to do something like:

subtype field_a_range is range 15 downto 0;
subtype field_b_range is range 31 downto 0:
type big_record_t is record
    field_a : unsigned(field_a_range);
    field_b : unsigned(field_b_range);
end record;

Then later you can do something like:

signal ex : unsigned(field_a_range);

Another fix might be to use a function that is a bit goofy--use a function. Though this effectively creates an instance (though hides it a bit).

function field_a_length return natural is
  variable tmp : big_record_t;
begin
  return tmp.field_a'length;
end function field_a_length;

Then use it as:

signal ex : unsigned(field_a_length-1 downto 0);
like image 24
PlayDough Avatar answered Nov 15 '22 10:11

PlayDough