Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Arrays of constants in VHDL?

Status
Not open for further replies.

wturri

Newbie level 4
Joined
Sep 1, 2011
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,332
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!
 

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"?
 

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.
 

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
 

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"));
 

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)(y);

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.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top