Using nested, unconstrained array types?

A

Alex Rast

Guest
I'm trying to determine how you can associate a definite size to type you
want to declare as a nested array (that is, an array of arrays). I can have
a type declared as:

type inner_array is array (natural range <>) of {element type};

then I declare the nested array:

type outer_array is array (natural range <>) of inner_array;

Now if I want to use this type, I would have thought you could make a
declaration like :

signal actual_matrix : outer_array(specific_bit_width1 downto 0)
(specific_bit_width2 downto 0);

but this doesn't work. The compiler seems to want to see the outer array
fixed association, but not the inner array. So how would I declare the
signal so as to associate the desired inner array size?

To make this more concrete, the position is that I (would like to) have a
generic bus arbiter that can switch any of m busses of any width n. So, it
would seem to me natural to define a type : std_logic_tensor as an array of
std_logic_vector. Then the port clause in the entity declaration might look
something like this:

entity genericarbiter is
port(
Input_matrix : in std_logic_tensor;
Output_matrix : out std_logic_tensor;
...)
end entity;

Now I want to use a bus arbiter in a design. So I declare the component.
But now, once in this design, my bit-width and number of busses is fixed.
Let's say my word size is 32 and I have 8 busses. I'd want to declare the
component like this:

component genericarbiter
port(
Input_matrix : in std_logic_tensor(7 downto 0)(31 downto 0)
' Output_matrix : in std_logic_tensor(7 downto 0)(31 downto 0)
...);
end component;

except, of course, as I've noted above, the compiler chokes. How do I make
the declaration so that it actually works? Although it breaks the idea of
what I'm trying to achieve, I tried making the fixed-width port
declarations in the entity declaration, and the compiler still complained,
in the same way. So I can be pretty certain that it's the indexing method
that's screwed up.

--
Alex Rast
ad.rast.7@nwnotlink.NOSPAM.com
(remove d., .7, not, and .NOSPAM to reply)
 
"Alex Rast" <ad.rast.7@nwnotlink.NOSPAM.com> wrote in message
news:940942C9adrastnwnotlinkcom@216.168.3.44...
I'm trying to determine how you can associate a definite size to
type you
want to declare as a nested array (that is, an array of arrays). I
can have
a type declared as:

type inner_array is array (natural range <>) of {element type};

then I declare the nested array:

type outer_array is array (natural range <>) of inner_array;

Now if I want to use this type, I would have thought you could make
a
declaration like :

signal actual_matrix : outer_array(specific_bit_width1 downto 0)
(specific_bit_width2 downto 0);

but this doesn't work. The compiler seems to want to see the outer
array
fixed association, but not the inner array. So how would I declare
the
signal so as to associate the desired inner array size?
Hi Alex,
VHDL doesn't allow the element type of an array to be
unconstrained.

E.g. you can't do

type MyArrayT is array (natural range <> ) of std_logic_vector;
^^^^^^^^^^^^^^^^^^^^

this must be a constrained
vector,
not unconstrained.

You can have multi-dimensional arrays, e.g.

type Array2D is array (natural range <>, natural range<>) of
element_type;

signal actual_matrix : Array2D(size1 -1 downto 0, size2-1 downto 0);

Note: element_type still has to be constrained.

If you're interested in synthesis you'll need to check that your
synthesis tool
is happy of course.

If you are going to use such a type on a port, you must put it into a
package.

If the element type is std_logic, I guess this might be close to what
you
want.

However if you want the element type to be varied in width, then you
need to either
create a constant and declare a subtype in a package, or create a
subtype and
then use 'LENGTH to find out how big it is. E.g.

constant N : NATURAL := 10; -- the element type width
subtype element_type is std_logic_vector(N-1 downto 0);

or

subtype element_type is std_logic_vector(9 downto 0);
constant N : NATURAL := element_type'LENGTH;



regards
Alan




--
Alan Fitch
Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project
Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24
1AW, UK
Tel: +44 (0)1425 471223 mail:
alan.fitch@doulos.com
Fax: +44 (0)1425 471573 Web:
http://www.doulos.com

The contents of this message may contain personal views which are not
the
views of Doulos Ltd., unless specifically stated.
 
at Fri, 03 Oct 2003 08:49:02 GMT in <bljd5u$ouo$1$8302bc10
@news.demon.co.uk>, alan.fitch@doulos.com (Alan Fitch) wrote :

"Alex Rast" <ad.rast.7@nwnotlink.NOSPAM.com> wrote in message
news:940942C9adrastnwnotlinkcom@216.168.3.44...
I'm trying to determine how you can associate a definite size to
type you
want to declare as a nested array (that is, an array of arrays). I
can have
a type declared as:

type inner_array is array (natural range <>) of {element type};

then I declare the nested array:

type outer_array is array (natural range <>) of inner_array;

Now if I want to use this type, I would have thought you could make
a
declaration like :

signal actual_matrix : outer_array(specific_bit_width1 downto 0)
(specific_bit_width2 downto 0);

but this doesn't work....
Hi Alex,
VHDL doesn't allow the element type of an array to be
unconstrained.

E.g. you can't do

type MyArrayT is array (natural range <> ) of std_logic_vector;
^^^^^^^^^^^^^^^^^^^^
this must be a constrained vector, not unconstrained.
You can have multi-dimensional arrays, e.g.

type Array2D is array (natural range <>, natural range<>) of
element_type;
signal actual_matrix : Array2D(size1 -1 downto 0, size2-1 downto 0);

This won't work for me, because in various places I'll need to slice
elements of the array, referencing an outer array element and an inner
array bit-range. I'm sure this would be a common scenario.

It seems to me that VHDL is pretty broken when dealing with multiple,
heterogeneous busses of arbitrary bit-width. Why, if they would allow the
definition of an unconstrained array, would they not allow the elements of
the array to be similarly unconstrained, especially given that you can have
the elements be constrained arrays? This creates an inconsistency in the
language definition. Either the language should allow array elements of
unconstrained arrays to be themselves unconstrained, or it should not allow
arrays to contain elements which are arrays at all. In the second case,
they must then allow multidimensional arrays to be sliced, which in fact
they should allow anyway (another inconsistency).

I've encountered similar, frustrating idiosyncracies with connecting up
mixes of signals, containing both scalar and vector components, into a
single bus.

The net result of the current VHDL definition is that you end up having to
do a lot of tedious, repetitive data entry to use multiple busses. This is
exactly the sort of thing EDA is supposed to prevent! By automating the
tedious, repetitive, low-intelligence-required tasks, EDA is supposed to
free up the time of expensive, highly skilled engineers and make them more
productive. If the tools are forcing high-paid engineers to waste hours of
time simply typing in definitions and connections, a lot of companies are
throwing a lot of money down the drain.

If you are going to use such a type on a port, you must put it into a
package.

If the element type is std_logic, I guess this might be close to what
you
want.

However if you want the element type to be varied in width, then you
need to either
create a constant and declare a subtype in a package, or create a
subtype and
then use 'LENGTH to find out how big it is. E.g.

constant N : NATURAL := 10; -- the element type width
subtype element_type is std_logic_vector(N-1 downto 0);

or

subtype element_type is std_logic_vector(9 downto 0);
constant N : NATURAL := element_type'LENGTH;
Thanks for the solution. I think what you have in mind may work, if I use a
nested array defined in a package and some creative subtype and constant
definitions. I must point out, though, that this is an unnecessarily
circuitous way of arriving at the desired result. It's silly that the
language should force you to jump through so many hoops.
--
Alex Rast
ad.rast.7@nwnotlink.NOSPAM.com
(remove d., .7, not, and .NOSPAM to reply)
 
Alex,
Two issues.
1) Currently cannot make both dimensions unconstrained.
2) In the past, some synthesis tools did not allow
unconstrained ports on entities.

Two Solutions.
===========================================
Solution1:
You have to give up some of your flexability on one of
the dimensions. Bit width of the bus is probably a good
choice. I would define this type as a subtype in a package:

subtype DataBusType is std_logic_vector(31 downto 0) ;

Also define an unconstained type of DataBusType:
type std_logic_tensor is array (natural range <>) of DataBusType;


Then on the entity, use generics (to make the synthesis tools
happy about the unconstrained array):
entity genericarbiter is
generic (
NumDevices : integer
) ;
port(
Input_matrix : in std_logic_tensor (NumDevices-1 downto 0);
Output_matrix : out std_logic_tensor(NumDevices-1 downto 0);
...)
end entity;
===========================================
Solution2:
If constraining the width of the busses pains you too much,
then you must do them as separate arrays. Create the maximum
number you expect for a system and then don't connect the ones
you don't need. In this case you can specify the
width of the bus as a generic:

entity genericarbiter is
generic (
NumDevices : integer ; -- may need this for synthesis?
BusWidth : integer
) ;
port(
Input1 : in std_logic_vector(BusWidth-1 downto 0) ;
Output1 : out std_logic_vector(BusWidth-1 downto 0) ;
Input2 : in std_logic_vector(BusWidth-1 downto 0) ;
Output2 : out std_logic_vector(BusWidth-1 downto 0) ;
Input3 : in std_logic_vector(BusWidth-1 downto 0) ;
Output3 : out std_logic_vector(BusWidth-1 downto 0) ;
Input4 : in std_logic_vector(BusWidth-1 downto 0) ;
Output4 : out std_logic_vector(BusWidth-1 downto 0)
) ;
end entity;
If you only need three inputs, wire it up as:
U_Aribiter_3x32 : genericarbiter is
generic map (
NumDevices => 3,
BusWidth => In1'length
)
port map(
Input1 => In1,
Output1 => Out1,
Input2 => In2,
Output2 => Out2,
Input3 => In3,
Output3 => Out3,
Input4 => (In1'range => '0'),
Output1 => open
) ;

Now you would be asking the synthesis tool to
0ptimize away the fourth case, but with the
input connected to 0, this is a reasonable thing
to get it to do. If not, use the generic with some
generate statements in the architecture to force the
synthesis tool to understand.

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:Jim@SynthWorks.com
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Alex Rast wrote:

I'm trying to determine how you can associate a definite size to type you
want to declare as a nested array (that is, an array of arrays). I can have
a type declared as:

type inner_array is array (natural range <>) of {element type};

then I declare the nested array:

type outer_array is array (natural range <>) of inner_array;

Now if I want to use this type, I would have thought you could make a
declaration like :

signal actual_matrix : outer_array(specific_bit_width1 downto 0)
(specific_bit_width2 downto 0);

but this doesn't work. The compiler seems to want to see the outer array
fixed association, but not the inner array. So how would I declare the
signal so as to associate the desired inner array size?

To make this more concrete, the position is that I (would like to) have a
generic bus arbiter that can switch any of m busses of any width n. So, it
would seem to me natural to define a type : std_logic_tensor as an array of
std_logic_vector. Then the port clause in the entity declaration might look
something like this:

entity genericarbiter is
port(
Input_matrix : in std_logic_tensor;
Output_matrix : out std_logic_tensor;
...)
end entity;

Now I want to use a bus arbiter in a design. So I declare the component.
But now, once in this design, my bit-width and number of busses is fixed.
Let's say my word size is 32 and I have 8 busses. I'd want to declare the
component like this:

component genericarbiter
port(
Input_matrix : in std_logic_tensor(7 downto 0)(31 downto 0)
' Output_matrix : in std_logic_tensor(7 downto 0)(31 downto 0)
...);
end component;

except, of course, as I've noted above, the compiler chokes. How do I make
the declaration so that it actually works? Although it breaks the idea of
what I'm trying to achieve, I tried making the fixed-width port
declarations in the entity declaration, and the compiler still complained,
in the same way. So I can be pretty certain that it's the indexing method
that's screwed up.
 

Welcome to EDABoard.com

Sponsor

Back
Top