Using nested, unconstrained array types?

Discussion in 'VHDL' started by Alex Rast, Oct 3, 2003.

  1. Alex Rast

    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

    (remove d., .7, not, and .NOSPAM to reply)
    Alex Rast, Oct 3, 2003
    #1
    1. Advertising

  2. Alex Rast

    Alan Fitch Guest

    "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, Oct 3, 2003
    #2
    1. Advertising

  3. Alex Rast

    Alex Rast Guest

    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, Oct 4, 2003
    #3
  4. Alex Rast

    Jim Lewis Guest

    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:
    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, Oct 6, 2003
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. FE
    Replies:
    0
    Views:
    1,638
  2. Victor Hannak
    Replies:
    1
    Views:
    525
    Mike Treseler
    Nov 25, 2003
  3. Amal
    Replies:
    5
    Views:
    8,630
    Brandon
    Mar 8, 2006
  4. jens
    Replies:
    3
    Views:
    818
  5. Replies:
    2
    Views:
    574
Loading...

Share This Page