Why Dynamic Arrays
Verilog allows one-dimensional arrays
of variables all along and Verilog-2001 allows multi-dimensional ones too.
SystemVerilog classifies an array as 'packed' or 'unpacked' depending on how
it is declared. If the array upper and lower bounds are declared between the
variable type and the variable name, such as
reg [7:0] a_reg_array;
The
array is called packed. If the array bounds are declared after the variable
name, it is called an unpacked array, such as,
int int_array [7:0];
Of
course, an array may have both packed and unpacked parts.
reg [7:0] reg_array [3:0][7:0];
Whether
you are declaring packed or unpacked arrays of whatever dimensions, one thing
that remains common is they are all static declarations. Once an array is
declared this way, the tool that parses the declaration will statically
allocate memories for the array and there is no way that you can alter that
afterwards. As a result, the size of an array, for example, cannot be changed
once it is declared.
There
are occasions, however, when you would want to declare an array whose size
cannot be pre-determined. A temporary buffer for variable rate incoming data
stream, a list that has variable number of elements are few examples of
problems that need array size that needs to be changed dynamically. Using a
very large array with the assumption that it can hold the largest data (yet
whose size is unknown) is neither safe nor efficient. So, the question is how
can we declare an array whose size is dynamically alterable?
SystemVerilog
dynamic array type addresses this need. In a sense, dynamic arrays are
equivalent of malloc library function in C that allows one to dynamically
alter the size of an array (or pointer).
Declaring a Dynamic
Array
A dynamic array lets you keep the
number of elements in the array unspecified at the declaration time. You can
define the number of elements it holds during run time. Moreover, once
declared, the number of elements can be altered at a later point of time too.
However,
these benefits come at a price. There are some limitations on dynamic arrays.
These limitations are:
The
dynamic part of the array must be of unpacked nature. A packed array cannot
be dynamic (can you guess why?)
The
unpacked (and dynamic) part of the array must be one dimensional. More than
one dimension is not allowed for dynamic arrays.
With
this rules and regulations, here is the syntax for declaration for dynamic
array:
data_type array_name [];
Note
the empty square brackets ([]) that indicate that the array is dynamic. Here
are some examples of dynamic array declaration (similar to static arrays
declared above):
reg [7:0]
a_reg_array []; // dynamic array of 8 bit reg
reg [7:0][3:0] b_reg_array []; //
dynamic array of two packed dimension
int int_array []; //
dynamic array of integers
Several
things are noteworthy above.
The
variable a_reg_array is dynamic only in its unpacked part. The packed part is
still static (and 8 bit wide) showing mixing static packed and dynamic unpacked
parts is okay.
The
variable b_reg_array even has two dimensions in its packed part. It is only
the unpacked part that is one-dimensional.
The
variable int_array shows a case whose packed part is not an array.
Working
with Dynamic Arrays
Once
you have declared a dynamic array, there are few built-in operator and
methods that you can use that help you to use the array effectively. These
are
The
new[] operator.
The
size() built-in method.
The
delete() built-in method.
The new[] Operator
The new[] operator creates or modifies the depth
of an array. Consider the following example:
int int_array[]; // declare an integer array
...
int_array = new[25]; // creates 25-deep array
In the above example,
after the declaration of int_array no space has been allocated for it
and hence using any array element is illegal. The memory allocation for the
elements are not done until the new operator is encountered. At this point, it
is legal to use the array indexes 0 through 24.
Another use of the new[] operator is to modify an existing
dynamic array. In the following example, int_array2 is a second dynamic array.
// Declare an integer array
int int_array[];
// Declare another integer array
int int_array2[];
...
// Creates 25-deep array for int_array
int_array = new[25];
...
// Creates 50-deep array for int_array2
// and then copies first 25 elements from int_array
int_array2 = new[50](int_array);
In the above example,
the last line indicates how new[50] creates an array of 50 elements for int_array2. Then the (int_array) part copies the existing int_array into
first 25 locations of int_array2. Rest 25 locations
of int_array will
remain empty.
What will happen if int_array2 has less number of elements, say 15,
than int_array? In that
case, only the first 15 elements of int_array will be copied to int_array2.
A clever use of the new[] operator in the above manner lets you
modify the size of an existing dynamic array.
// declare an integer array
int int_array[];
...
// creates a 25-deep array
int_array = new[25];
...
// deletes the last 10 elements
int_array = new[15](int_array);
...
// increases the size of int_array to 30
// preservng the old values
int_array = new[30](int_array);
The method size()
The method size() returns the current size of a dynamic
array as an integer.
int current_size;
...
current_size = int_array.size();
If a dynamic array is
not created yet, then the returned size will be zero.
The method delete()
The method delete() simply deletes all the elements of a
synamic array and leaves it at the state of declaration when the array was not
created.
int_array.delete();
The size of a deleted
dynamic array, as can be expected, is zero.
|
No comments:
Post a Comment