I have a 2d array of std_logic_vector of size 10x10. I want add specific elements of a column of the array, for instance:
array(4 downto 0,1) <= std_logic_vector(unsigned('0'&array(3 downto 2,2)) + unsigned('0'&array(1 downto 0,2)));
But I get the error: Badly formed indexed name of "array". Index #1 is a range. Why can't I add these vectors?
Note array is a reserved word in VHDL. We can presume you are intentionally trying to abstract your object name in a code snippet that doesn't qualify as a Minimal, Complete, and Verifiable example.
The Problem
The apparently Modelsim error message references the definition of a slice. See IEEE Std 1076-2008, 8.5 Slice names:
A slice name denotes a one-dimensional array composed of a sequence of consecutive elements of another one-dimensional array. A slice of a signal is a signal; a slice of a variable is a variable; a slice of a constant is a constant; a slice of a value is a value.
slice_name ::= prefix ( discrete_range )
The prefix of a slice shall be appropriate for a one-dimensional array object. The base type of this array type is the type of the slice.
The standard doesn't directly explain why slices are only for one-dimensional array objects, but it has to do with the type of a value found in an expression.
See 5.3.2 Array types, 5.3.2.1 General:
An array object is a composite object consisting of elements that have the same subtype. The name for an element of an array uses one or more index values belonging to specified discrete types. The value of an array object is a composite value consisting of the values of its elements.
A slice in a dimensional index of a multi-dimensional array is not of the element type. Besides not having a recognizable and declared type, the number of type declarations you could require is dependent on the number of dimensions and the number of slice lengths possible in each dimension.
Defining those various types would be the only way to get assignment to work, assignment is a basic operation not a subprogram to be overloaded.
Solutions
By definition you could do this with a sequence of statements where you perform in this case addition on aggregates constructed of elements gathered from the array. An aggregate assignment would be used to put the added elements into their proper place. This depends on the required types being declared and you might note effectively makes operations that occur on slices of a single-dimensional arrays of elements.
Subprograms
It's possible to write subprograms to perform the functionality you are expressing. It involves passing the values of all the multi-dimensional array types involved along with expressions providing the dimensionality of any 'slices' and indexes for 'operands' separately.
This is analogous to sweeping the complexity under the rug.
You could fold the assignment in as well using a procedure with a signal port of mode inout.
Arrays of Arrays
Your example uses an operator and assignment on a single-dimensional array slice in a two dimensional array. To deal with a slice we need the array type being sliced to be the element type of an array.
By reversing the dimension index order and defining an array type as an array of elements of an array type we can avoid all sorts of complexity:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity foo is
end entity;
architecture fum of foo is
type array_type is array (natural range 0 to 9) of
std_logic_vector(9 downto 0);
signal some_array: array_type;
begin
-- The original code snippet formatted for readability:
-- array(4 downto 0,1) <= std_logic_vector(
-- unsigned('0' & array(3 downto 2,2)) +
-- unsigned('0' & array(1 downto 0,2))
-- );
some_array(1)(2 downto 0) <=
std_logic_vector (
('0' & unsigned(some_array(2)(3 downto 2))) +
('0' & unsigned(some_array(2)(1 downto 0)))
);
end architecture;
Now are slices are of a single-dimensional array. We get something that analyzes, elaborates and runs (demonstrates that there are no bounds errors in the assignment).
If you need a 5 element assignment:
some_array(1)(4 downto 0) <=
std_logic_vector (
("000" & unsigned(some_array(2)(3 downto 2))) +
("000" & unsigned(some_array(2)(1 downto 0)))
);
Your original assignment suffered as Renaud Pacalet commented from a bounds (length) mismatch between the operator result and the left hand side of the assignment.
In both cases you'd only end up with a two bit adder with carry following synthesis.
An array of an array method only works if you don't need to operate on the 10x10 array with a slice on more than one dimension. Slicing on a second index and you'll need subprograms or sequences of statements.