Proposal for array types


Subject: Proposal for array types
From: Paul Graham (pgraham@cadence.com)
Date: Wed Apr 03 2002 - 13:08:11 PST


Here is my proposal for array types in SystemVerilog 3.0. I'm referencing
the draft 5 manual. The intent of this proposal is to implement these
points from my recent e-mail:

    3. Allow reading and writing of whole arrays.

    4. Allow slicing of one-dimensional arrays (for both reading and writing).

    5. Allow general array ports of subprograms and modules.

    6. Provide functions or attributes to get the bounds of a dimension of an
       array. I would suggest new system functions like $left, $right, etc.,
       corresponding to VHDL attributes for querying array bounds.

Here goes ...

Section 4.2 Packed and unpacked arrays

Change this paragraph:

    Dense arrays of small data types such as bits can be stored packed (8
    bits to a byte) or unpacked (1 bit to a word). This choice affects the
    efficiency of operations such as addition of bit vectors or selection of
    individual bits, and is similar to the Verilog-2001 notions of vectored
    and scalared. Assignments and arithmetic operations are allowed for
    packed arrays but not for unpacked. The vectored and scalared modifiers
    shall behave as defined in the IEEE Verilog standard. They may be used
    by software implementations to optimize performance.

to:

    A packed array is a mechanism for subdividing an integer into subfields
    which can be conveniently accessed as array elements. Consequently, a
    packed array is guaranteed to be represented as a contiguous set of
    bits. (An unpacked array may or may not be so represented). A packed
    array differs from an unpacked array in that when a packed array appears
    as a primary, it is treated as an integer.

    [ Need to clarify: if a packed array is declared 'signed', does this
      mean that the array, viewed as a single integer, is a signed integer,
      or does it mean that each element in the array is signed, or both? ]

    [ Also, I see no need to mention 'scalared' and 'vectored' in this
      section. These keywords have nothing to do with SystemVerilog, and
      perhaps should be deprecated. In any case, they don't belong in the
      section on arrays. ]

Add some paragraphs clarifying the operations that can be done on arrays:

    The following operations may be performed on all arrays, packed or
    unpacked. Assume that A and B are arrays:

    Reading/writing the array, e.g., A = B
    Reading/writing a slice of the array, e.g., A[i:j] = B[i:j]
    Reading/writing a variable slice of the array, e.g., A[x+:c] = B[y+:c]
    Reading/writing an element of the array, e.g., A[i] = B[i]

    The following operations may be performed on packed arrays but not
    on unpacked arrays. Assume that A is an array:

    Assignment from an integer, e.g., A = 8'b11111111;
    Treatment as an integer in an expression, e.g., (A + 3)

    When assigning to an unpacked array, the source and target must be
    arrays with the same number of unpacked dimensions, and the length of
    each dimension must be the same. Assignment to an unpacked array is
    done by assigning each element of the source unpacked array to the
    corresponding element of the target unpacked array. Note that an
    element of an unpacked array may be a packed array.

    For the purposes of assignment, a packed array is treated as a integer.
    Any integer expression can be assigned to any packed array. The packed
    array bounds of the target packed array do not affect the assignment.
    
    
4.3 Multiple dimensions

Change:

    Like Verilog memories, the dimensions following the type set the packed
    size. The dimensions following the instance set the unpacked size, where
    access must be by index.

To:

    Like Verilog memories, the dimensions following the type set the packed
    size. The dimensions following the instance set the unpacked size.

After this paragraph:

    Multiple packed dimensions can also be defined in stages with typedef:

    typedef bit [1:5] bsix;
    bsix [1:10] foo5; // 1 to 5 varies most rapidly

add another for unpacked:

    Multiple unpacked dimensions can be defined in stages with typedef:

    typedef bsix mem_type [0:3]; // array of four 'bsix' elements
    mem_type bar [0:7]; // array of eight 'mem_type' elements

4.4 Part selects (slices)

[ I really prefer the VHDL names. In standard Verilog, A[i] is called a bit
  select, and A[i:j] is called a part select. Except that if A is a memory,
  then A[i] doesn't have a name. See section 3.10.3 of the 1364-2001 LRM.
  In VHDL, an expression like A[i] is called an indexed name. An expression
  like A[i:j] is called a slice name. It doesn't matter if A is a
  bit-vector or a multidimensional array, the name is the same. So if you
  don't mind, I'll use the VHDL names here. ]

Change the section title to

    4.4 Indexing and slicing of arrays

Change:

    An expression can select part of a packed array, or any integer
    type, which is assumed to be numbered down to 0:

to:

    An element of a packed or unpacked array can be selected using an
    indexed name.

    One or more contiguous elements can be selected using a slice name. A
    slice name of a packed array is a packed array. A slice name of an
    unpacked array is an unpacked array.

    [ The statement that an integer type "is assumed to be numbered down to
      0" doesn't belong in Chapter 4. Chapter 4 is about arrays. ]

7.4 Operations on logic and bit types

Change the sentence:

    The unary reduction operators (& ~& | ~| ^ ~^) can be applied to any
    packed type, including multidimensional packed arrays.

to:

    The unary reduction operators (& ~& | ~| ^ ~^) can be applied to any
    integer expression (including packed arrays).

11.2 Tasks

Change

    Each formal argument also has a data type which can be explicitly
    declared or can inherit a default type. The default type in
    SystemVerilog is logic, which is compatible with Verilog. SystemVerilog
    allows packed arrays to be specified as formal arguments to a task, for
    example:

    task mytask4(input [3:0][7:0] a, b, output [3:0][7:0] y);
        ...
    endtask

to:

    Each formal argument also has a data type which can be explicitly
    declared or can inherit a default type. The default type in
    SystemVerilog is logic, which is compatible with Verilog. SystemVerilog
    allows an array to be specified as a formal argument to a task, for
    example:

    task mytask4(input [3:0][7:0] a, b[3:0], output [3:0][7:0] y[1:0]);
        ...
    endtask

    [ I assume that the full declaration of b in this example is:

         input [3:0][7:0] b[3:0];

      Am I right? ]

Likewise, change the corresponding sentence for functions in 11.3:

    SystemVerilog allows packed arrays to be specified as formal arguments
    to a function, for example:

    function [3:0][7:0] myfunc4(input [3:0][7:0] a, b);

to:

    SystemVerilog allows an array to be specified as a formal argument to a
    function, for example:

    function [3:0][7:0] myfunc4(input [3:0][7:0] a, b[3:0]);

Also, to allow a function to return an unpacked array, we need to change the
syntax a little. I propose changing:

    function_declaration ::=
        function [automatic] data_type tf_name ; or ( fn_formals )

to:

    function_declaration ::=
        function [automatic] data_type tf_name [unpacked_dimension] ; or ( fn_formals )

That is, allow an optional unpacked_dimension to follow the function name in
its declaration. For instance:

    function [3:0] f [7:0] (input [3:0] x [3:0] );
        return {x, x}; // is this a legal use of array concatenation?
    endfunction

    [ Random style note: I prefer the use of singulars in a reference
      manual. For example, I would prefer to say "a reg may be assigned in
      an always block which is defined in a module" than to say "regs may be
      assigned in always blocks which are defined in modules". If you use
      plurals only when necessary then you avoid ambiguities like: "regs may
      not have multiple drivers" where it is not clear whether you mean to
      say that one reg may not have multiple drivers or several regs must
      share a single driver. ]

12.5 Port declarations

Change:

    With SystemVerilog, a port can be a declaration of a net, an interface,
    an event, a variable of any type, a packed array, a structure or a
    union.

to:

    With SystemVerilog, a port can be a declaration of a net, an interface,
    an event, a variable of any type, an array, a structure or a union.

12.8 Port connection rules.

Add this paragraph:

    For an unpacked array port, the port and the array connected to the port
    must have the same number of unpacked dimensions, and each dimension of
    the port must have the same size as the corresponding dimension of the
    array being connected.

Section 16 System tasks and system functions

16.1 Introduction

Change:

    SystemVerilog adds a system function to determine the bit size of a
    value.

to:

    SystemVerilog adds several system function to determine the bit size of
    a value and the bounds of an array.

Add:

    16.3 Array querying functions

    Five new system functions are provided to return the bounds of an
    array. Each function has the syntax:

        <function>(<array>, <dimension>)

    where <function> is one of {$left, $right, $low, $high, $size}. <array>
    is any declared array. <dimension> specifies which dimension of the
    array is to be queried.

    The dimensions of an array are numbered as follows. The slowest varying
    dimension (packed or unpacked) is dimension 1. Successively faster
    varying dimensions have sequentially higher dimension numbers. For
    instance:

        // Dimension numbers
        // 3 4 1 2
        reg [3:0][2:1] x [1:5][2:8];

    The $left function returns the left bound (msb) of the dimension.
    The $right function returns the right bound (lsb) of the dimension.
    The $low function returns the minimum of $left and $right of the
        dimension.
    The $high function returns the maximum of $left and $right of the
        dimension.
    The $size function returns the number of elements in the dimension, or
        $high - $low + 1.

    For an integer or bit type, only dimension 1 is defined. For an integer
    X declared without a range specifier, its bounds are assumed to be
    [$bits(X)-1:0].

That's it for now...

Paul



This archive was generated by hypermail 2b28 : Wed Apr 03 2002 - 13:09:13 PST