# Arrays of constants in VHDL?

Status
Not open for further replies.

#### wturri

##### Newbie level 4
Hello,

We have a 2D window filter implemented that we'd like to make more reusable. Presently we use a 7x7 kernel, and we assign the coefficient values to individually-named constants, which are then assigned to a 2D array of signals in the body of the design (this can then be operated on using for-loop constructs). For example we assign the first row of coefficient values as:

--Kernel constant definition
constant kernel00 : std_logic_vector(10 downto 0) := b"00000000011"; --x"0003";
constant kernel01 : std_logic_vector(10 downto 0) := b"00000001000"; --x"0008";
constant kernel02 : std_logic_vector(10 downto 0) := b"00000010000"; --x"0010";
constant kernel03 : std_logic_vector(10 downto 0) := b"00000010100"; --x"0014";
constant kernel04 : std_logic_vector(10 downto 0) := b"00000010000"; --x"0010";
constant kernel05 : std_logic_vector(10 downto 0) := b"00000001000"; --x"0008";
constant kernel06 : std_logic_vector(10 downto 0) := b"00000000011"; --x"0003";
We have six more blocks. Now, because these are individually named, we have to assign them to the signal array explicitly as:

kernel(0)(0) <= kernel00;
kernel(0)(1) <= kernel01;
kernel(0)(2) <= kernel02;
kernel(0)(3) <= kernel03;
kernel(0)(4) <= kernel04;
kernel(0)(5) <= kernel05;
kernel(0)(6) <= kernel06;
What we would like to do is something more like:

for i in 0 to KERNEL_HEIGHT loop
for j in 0 to KERNEL_WIDTH loop
kernel(i)(j) <= kernelconst(i)(j);
end loop;
end loop;
Where "kernelconst" would be assigned more like this:

constant kernelconst(0)(0) : std_logic_vector(10 downto 0) := b"00000000011"; --x"0003";
constant kernelconst(0)(1) : std_logic_vector(10 downto 0) := b"00000001000"; --x"0008";
constant kernelconst(0)(2) : std_logic_vector(10 downto 0) := b"00000010000"; --x"0010";
constant kernelconst(0)(3) : std_logic_vector(10 downto 0) := b"00000010100"; --x"0014";
constant kernelconst(0)(4) : std_logic_vector(10 downto 0) := b"00000010000"; --x"0010";
constant kernelconst(0)(5) : std_logic_vector(10 downto 0) := b"00000001000"; --x"0008";
constant kernelconst(0)(6) : std_logic_vector(10 downto 0) := b"00000000011"; --x"0003";
So my question is, (1) can I declare a 2D array of constants, and (2) if so, how? I suspect I would have to use "deferred constants" to declare the array type in a package, but I cannot find any coding examples.

Help is appreciated, thank you!

#### barry

Have you looked at using a "Generate" construct?

#### wturri

##### Newbie level 4
Have you looked at using a "Generate" construct?
I thought that constructs such as for loops and generate statements have to be used after the "begin" of the architecture...whereas constants are declared prior.

Can I use a generate construct between "architecture" and "begin"?

#### FvM

##### Super Moderator
Staff member
You need to declare the 2D array type first and then the constant. Use brackets {{ }} to assign all elements in a single statement.

A package would be suggested, if you wan to use the 2D array in multiple design entities.

#### wturri

##### Newbie level 4
You need to declare the 2D array type first and then the constant. Use brackets {{ }} to assign all elements in a single statement.

A package would be suggested, if you wan to use the 2D array in multiple design entities.
Hmmm...something like the following, then, in my case (simplified for a 3x3 kernel)?

--Kernel constant definition
-- Could define constants as 2D array of values that can be assigned in for loops
type KERNEL_CONSTANTS_ROW is array (0 TO 2) OF std_logic_vector(20 downto 0);
type KERNEL_CONSTANTS is array (0 TO 2) OF KERNEL_CONSTANTS_ROW;

-- Try assigning values in one big block
constant kernelconst : KERNEL_CONSTANTS := {{(b"00000000011"), (b"00000000011"), (b"00000000011")},
{(b"00000000011"), (b"00000000011"), (b"00000000011")},
{(b"00000000011"), (b"00000000011"), (b"00000000011")}};
I'm not sure about where to use the braces, parens, commas, etc.

Thanks! :-D

#### FvM

##### Super Moderator
Staff member
It's in fact (()) instead of {{}}. Here's the shortest form:

Code:
type KERNEL_CONSTANTS is array (0 TO 2,0 TO 2) OF std_logic_vector(10 downto 0);

-- Try assigning values in one big block
constant kernelconst : KERNEL_CONSTANTS := (("00000000011", "00000000011", "00000000011"),
("00000000011", "00000000011", "00000000011"),
("00000000011", "00000000011", "00000000011"));

#### TrickyDicky

Be sure you know the differences between the code you wrote and what FvM has just suggested. Both ways are equally valid, but make sure you know how to handle either of them.

Your post is an array of arrays. So you index it with a single indeces in the brackets:

out <= KERNAL_CONSTANTS(x);

you could also return an entire row at a time:

out_row <= KERNAL_CONSTANT(x);

for FvM's suggestion you can only return single values at a time like this:

out <= KERNAL_CONSTANT(x,y);

with this, you canot return a whole row in 1 go.

Status
Not open for further replies.