Discussion:
Set whole row in 2D array
(too old to reply)
Tricky
2009-12-24 10:05:51 UTC
Permalink
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?
logic_guy
2009-12-26 22:24:20 UTC
Permalink
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
Tricky
2009-12-27 08:18:44 UTC
Permalink
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?
Post by 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.
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
Jonathan Bromley
2009-12-27 10:02:22 UTC
Permalink
Post by Tricky
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.
Post by Tricky
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.)
--
Jonathan Bromley
Tricky
2009-12-27 16:05:18 UTC
Permalink
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.
Post by Jonathan Bromley
Post by Tricky
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.
Post by Tricky
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.)
--
Jonathan Bromley
Jonathan Bromley
2009-12-27 17:23:00 UTC
Permalink
Post by 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
Yes, that's the same reason I have done it.
Post by Tricky
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.
Post by Tricky
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.
--
Jonathan Bromley
KJ
2009-12-30 17:59:54 UTC
Permalink
Post by 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.
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

Continue reading on narkive:
Loading...