![]() |
|
|
|||||||
![]() |
VHDL - Using nested, unconstrained array types? |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
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 (remove d., .7, not, and .NOSPAM to reply) Alex Rast |
|
|
|
|
#2 |
|
Posts: n/a
|
"Alex Rast" <> 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: 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. Alan Fitch |
|
|
|
#3 |
|
Posts: n/a
|
at Fri, 03 Oct 2003 08:49:02 GMT in <bljd5u$ouo$1$8302bc10
@news.demon.co.uk>, (Alan Fitch) wrote : > >"Alex Rast" <> 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 (remove d., .7, not, and .NOSPAM to reply) Alex Rast |
|
|
|
#4 |
|
Posts: n/a
|
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 private.php?do=newpm&u= 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. > Jim Lewis |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| constants as of array of integers, for loops | octavsly | Hardware | 0 | 04-25-2009 11:53 AM |
| Array Programme | rits | Software | 2 | 03-04-2009 05:18 PM |
| Nested FOR loops in VHDL... | yokeshr | Hardware | 0 | 12-16-2008 08:43 AM |