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