Set whole row in 2D array

T

Tricky

with a 2D array, is it possible to assign an entire row in 1 go?

I have the following 2D array

type A_t is array(natural range <>, natural range <>) of natural;
variable A : A_t(0 to 4, 0 to 4) := ( (1,1,1,1,1),
(2,2,2,2,2),
(3,3,3,3,3),
(4,4,4,4,4),
(5,5,5,5,5)
);

And when I try this:

A(1, 0 to 4) := (9,9,9,9,9);

I get what I think is a bit of an odd error:

** Error: D:/Current_Work/ADWEP/VHDL/play_TB.vhd(25): (vcom-1088)
Badly formed indexed name of "a". Index #2 is a range.
** Error: D:/Current_Work/ADWEP/VHDL/play_TB.vhd(25): Target type
std.standard.integer in variable assignment is different from
expression type.
** Error: D:/Current_Work/ADWEP/VHDL/play_TB.vhd(25): (vcom-1152)
Index value 5 is out of index range 0 to 4 of sub-array #1 of a_t.

How does it come to the conclusion Im trying to assign index value 5?
 
L

logic_guy

I think the problem is that, in an assignment statement, "0 to 4" is
used to refer to a slice of a vector and each element of A is a single
natural, not a vector.

You might try this:
type natural_vector is array(0 to 4) of natural;
type natural_array is array(0 to 4) of natural_vector;
variable A : natural_array := ( (1,1,1,1,1),
(2,2,2,2,2),
(3,3,3,3,3),
(4,4,4,4,4),
(5,5,5,5,5)
);

A(1)(0 to 4) := (9,9,9,9,9);

Charles Bailey
 
T

Tricky

I know about this method - unfortunatly, in the situation I have, it
is not possible.
Guess Ill have to write a function to get it done?
 
J

Jonathan Bromley

I know about this method - unfortunatly, in the situation I have, it
is not possible.

Yes, you have a true 2-dimensional array and there is no way
in VHDL to pick rows and columns of it - only individual
elements.
Guess Ill have to write a function to get it done?

That's the easiest, for sure. You can create functions
to slice by row or by column, and procedures to write
by row or column.

Could I ask why you're using a 2-d array in preference
to an array of arrays? (There are plenty of good possible
reasons; I'm just interested.)
 
T

Tricky

Basically I load a bitmap from a file, and the array length is set at
load time (from the bitmap header). I cant have arrays of arrays,
because the line length is unknown until you actually load the source
image (with output image a function of the input size). I originally
did it with a 1d array type, but offsetting leads to long winded array
indexing and 2d arrays are just neater. (I have the same functions to
cope with the 1d/2d type declaration and type conversion functions).
As someone who works in video processing, these functions have proved
invaluable.

I was in a situation where I wanted to dump an entire line to an
output array (thats actually an image) before writing it to a file
becuase it would have been quicker than a function, if it was
possible, because the model generated entire lines at a time. Guess
Ill either have to use the 1D types and do the crappy line/pixel
offsetting, or just dump the lines into the 2D type pixel by pixel, or
I could write some line dump functions! Oh well, not back at work for
a week, so Ill probably think of something better by then.

This is all simulation - not synthesis.
 
J

Jonathan Bromley

Basically I load a bitmap from a file, and the array length is set at
load time (from the bitmap header). I cant have arrays of arrays,
because the line length is unknown until you actually load the source

Yes, that's the same reason I have done it.
I originally
did it with a 1d array type, but offsetting leads to long winded array
indexing and 2d arrays are just neater.

Agreed. Functions to read/write a 2-d array will surely always
be nicer than hand-cranked indexing.
I was in a situation where I wanted to dump an entire line to an
output array (thats actually an image) before writing it to a file
becuase it would have been quicker than a function

Using a procedure you can easily pass the 2-d array by reference
and there's no significant speed overhead. I don't think this
is excessively painful:

type T_line is array(natural range <>) of natural;
type T_image is array(
natural range <>, -- rows/lines
natural range <> -- columns/pixels
) of natural;

function get_line (image: in T_image; line_num: in natural)
return T_line is
variable result: T_line(T_image'range(2));
begin
for i in result'range loop
result(i) := image(line_num, i);
end loop;
return result;
end;

procedure write_line (
image: inout T_image; -- Assumed to be (0 to R-1, 0 to C-1)
line_num: in natural;
line: in T_line ) is
alias normalized_line: T_line(0 to line'length-1) is line;
begin
-- check sizes match
assert line'length = image'length(2);
for i in normalized_line'range loop
image(line_num, i) := normalized_line(i);
end loop;
end;

If you allow your 2-d image to have non-normalized
subscripts it all gets just a little messier. Best
not to go there.
 
K

KJ

Basically I load a bitmap from a file, and the array length is set at
load time (from the bitmap header). I cant have arrays of arrays,
because the line length is unknown until you actually load the source
image (with output image a function of the input size). I originally
did it with a 1d array type, but offsetting leads to long winded array
indexing and 2d arrays are just neater. (I have the same functions to
cope with the 1d/2d type declaration and type conversion functions).
As someone who works in video processing, these functions have proved
invaluable.

I was in a situation where I wanted to dump an entire line to an
output array (thats actually an image) before writing it to a file
becuase it would have been quicker than a function, if it was
possible, because the model generated entire lines at a time. Guess
Ill either have to use the 1D types and do the crappy line/pixel
offsetting, or just dump the lines into the 2D type pixel by pixel, or
I could write some line dump functions! Oh well, not back at work for
a week, so Ill probably think of something better by then.

You also might want to look at making a package with a protected type
with access functions and procedures. This allows you to hide all of
the gory details within the functions and procedures while providing
an easy to understand interface that you don't need to keep re-
understanding how it works everytime you use it

Get_Pixel/Set_Pixel
Get_Line/Set_Line
Get_Height/Set_Height
Get_Width/Set_Width
Get_Bmp_Type/Set_Bmp_Type -- i.e. color, grayscale, black/white, etc.
Read_File/Write_File
etc.

I've found this method works very well for handling images in
testbenches. If you work with images now, you'll probably work with
them again in the future. Having a simple to use BMP package (TIFF
package, JPEG package, etc.) that you've already debugged and got
working will come in handy for that future work.

Also, by creating pairs of procedures/functions even if you don't have
a need for them *now* it will allow you to more easily create a
testbench to verify your BMP package is working properly...

Img1.Set_Width(100)
assert (Img1.Get_Width = 100) report "OOPS" severity ERROR;

Kevin Jennings
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top