Suppose you have a record type like this:
type record_type_1 is
record
slv_1 : std_logic_vector(15 downto 0);
slv_2 : std_logic_vector(7 downto 0);
end record;
record
slv_1 : std_logic_vector(15 downto 0);
slv_2 : std_logic_vector(7 downto 0);
end record;
Now say we have one more record type where we need to declare elements with the same size as slv_1 and slv_2. How do we do that?
If we try the below method, it wont work:
type record_type_2 is
record
slv_3 : std_logic_vector(record_type_1.slv_1'LEFT downto record_type_1.slv_1'RIGHT));
slv_4 : std_logic_vector(record_type_1.slv_2'LEFT downto record_type_1.slv_2'RIGHT));
end record;
record
slv_3 : std_logic_vector(record_type_1.slv_1'LEFT downto record_type_1.slv_1'RIGHT));
slv_4 : std_logic_vector(record_type_1.slv_2'LEFT downto record_type_1.slv_2'RIGHT));
end record;
The reason is simple, record_type_1 is just the definition of a record type. What we need is a real object to access the range values.
So this is what we do:
--Declare a dummy signal with type record_type_1.
signal dummy : record_type_1;
--Now define the type.
type record_type_2 is
record
slv_3 : std_logic_vector(dummy.slv_1'LEFT downto dummy.slv_1'RIGHT));
slv_4 : std_logic_vector(dummy.slv_2'LEFT downto dummy.slv_2'RIGHT));
end record;
signal dummy : record_type_1;
--Now define the type.
type record_type_2 is
record
slv_3 : std_logic_vector(dummy.slv_1'LEFT downto dummy.slv_1'RIGHT));
slv_4 : std_logic_vector(dummy.slv_2'LEFT downto dummy.slv_2'RIGHT));
end record;
This will compiler without any errors. Also you don't need to worry that you are wasting extra logic declaring a dummy signal. Almost all the synthesis tools will detect that the signal "dummy" is not used anywhere in the design and will trim it during the synthesis process.