There are a couple of other methods besides using subprogram calls to assign elements of one type to elements of another type.
You can use a qualified expression:
record_s <= data_t'(vector_s(7 downto 3), vector_s (2 downto 0));
Where the aggregate comprised of two slices of vector_s with an explicit type matching the record. See IEEE Std 1076-2008 9.3.6 Qualified expressions.
During simulation new values for signals are validated. See 14.7.3.4 Signal update:
b) If S is a composite signal (including a slice of an array), the effective value of S is implicitly converted to the subtype of S. The subtype conversion checks that for each element of S there is a matching element in the effective value and vice versa. An error occurs if this check fails. The result of this subtype conversion is then assigned to the variable representing the current value of S.
Besides having a matching element (subelement,...) subtype conversion changes the index ranges to match the target.
You can specify the slice index ranges with subtype index ranges:
library ieee;
use ieee.std_logic_1164.all;
entity record_conversion is
end entity;
architecture subtypes of record_conversion is
type data_t is record
top : std_ulogic_vector(4 downto 0);
bottom : std_ulogic_vector(2 downto 0);
end record data_t;
signal record_s : data_t;
signal vector_s : std_ulogic_vector(7 downto 0);
subtype t is std_logic_vector (
vector_s'LEFT downto vector_s'LEFT - record_s.top'length + 1
);
subtype b is std_logic_vector (
vector_s'LEFT - record_s.top'length downto 0
);
begin
record_s <= data_t'(vector_s(t'range), vector_s(b'range));
end architecture;
Here the subtypes index range slices of the right hand side expression elements.
You can describe the slices with aliases:
architecture aliases of record_conversion is
type data_t is record
top: std_ulogic_vector(4 downto 0);
bottom: std_ulogic_vector(2 downto 0);
end record data_t;
signal record_s: data_t;
signal vector_s: std_ulogic_vector(7 downto 0);
alias vector_s_top: std_ulogic_vector(record_s.top'range) is
vector_s(7 downto 3);
alias vector_s_bottom: std_ulogic_vector(record_s.bottom'range) is
vector_s (2 downto 0);
begin
record_s <= data_t'(vector_s_top, vector_s_bottom);
end architecture;
Here the two aliases describe fields of vector_s. If you were guaranteed to always assign the record composite object you could actually do away with records and simply use aliases. The closest VHDL comes to unions.
The above examples analyze, elaborate and simulate without error, demonstrating there are no slice boundary issues.
Qualified expressions, subtype declarations and aliases incur no additional simulation overhead while subprogram calls do.