Is it possible to create an array whose elements have increasing width. For example lets say X is an array that has 10 elements;
X(0) is std_logic_vector(3 downto 0)
There is no solution to solve your question, as you requested, but additionally to Morten's answer I'll try to provide another work around solutions.
I'll use your example: X is an array of 10 elements each with increasing length from 4 to 13.
My solution puts all the vectors into one 1-dimensional vector and eases the access to the bits with functions. The following lines try to present how the bits are organized.
--bit 84 bit 19 bit 13 bit 8 bit 4 bit 0
[X(9)(12..0)]...[X(4)(7..0)][X(3)(6..0)][X(2)(5..0)][X(1)(4..0)][X(0)(3..0)]
Step-by-Step:
Create a vector of INTEGERs(T_INTVEC) or more constrained a vector of NATURALs (T_NATVEC).
type T_NATVEC is array (NATURAL range <>) of NATURAL;
Create a instance of this type and fill it with your array lengths.
constant MY_BITS : T_NATVEC := (
0 => 4,
1 => 5,
[...]
9 => 13
);
Or use a function to calculate it:
function generateVectorLengths return T_NATVEC is
constant Count : NATURAL := 10;
constant Startlength : NATURAL := 4;
variable Result : T_NATVEC(0 to Count - 1);
begin
for i in 0 to Count - 1 loop
Result(i) := StartLength + i;
end loop;
return Result;
end function;
constant MY_BITS : T_NATVEC := generateVectorLengths;
Create some helper function to:
sum all vector lengths
function isum(vec : T_NATVEC) return NATURAL is
variable Result : NATURAL := 0;
begin
for i in vec'range loop
Result := Result + vec(i);
end loop;
return Result;
end function;
get the upper bound of an embedded vector
function low(VectorBits : T_POSVEC; index : NATURAL) return NATURAL is
variable pos : NATURAL := 0;
begin
for i in VectorBits'low to index - 1 loop
pos := pos + VectorBits(i);
end loop;
return pos;
end function;
get the lower bound of an embedded vector
function high(VectorBits : T_POSVEC; index : NATURAL) return NATURAL is
variable pos : NATURAL := 0;
begin
for i in lenvec'low to index loop
pos := pos + VectorBits(i);
end loop;
return pos - 1;
end function;
get an entire embedded vector
function getSubvector(vector : STD_LOGIC_VECTOR; VectorBits : T_POSVEC; index : NATURAL) return STD_LOGIC_VECTOR is
begin
return vector(high(VectorBit, index) downto low(VectorBit, index));
end function;
assign a sub vector to the big vector
procedure assignSubVector(signal slm : out T_SLM; slv : STD_LOGIC_VECTOR; constant VectorBits : T_POSVEC; constant index : NATURAL) is
begin
for i in slv'range loop
slm(high(VectorBit, index) downto low(VectorBit, index)) <= slv;
end loop;
end procedure;
So now you can use this functions to create an 1-dimensional vector like this:
signal Vector_1 : STD_LOGIC_VECTOR(isum(MY_BITS) - 1 downto 0) := (others => 'Z');
-- initialize this vector with 'Z'; this is needed for simulation!
And you can use this vector with high and low function or with the forlast helper function (see function getSubvector
).
signal Vector_X3 : STD_LOGIC_VECTOR(MY_BITS(3) - 1 downto 0);
...
Vector_X3 <= getSubvector(My_Vector, MY_BITS, 3);
Finally, you can use assignSubVector
to assign vectors to the big one:
signal Vector_X4 : STD_LOGIC_VECTOR(MY_BITS(4) - 1 downto 0);
...
assignSubvector(My_Vector, Vector_X4, MY_BITS, 4);
If you find these bit moving and twisting function for vectors and matrixes interesting, here is the complete file :).