System Verilog substantiates a programmer by providing many data structures for storing a group of objects, such as 'Arrays' and 'Queues'. An array is a nonvariable size collection of same type of variables. A Queue is a variable size ordered collection of homogeneous objects.
Arrays
There are onedimensional and multidimensional arrays of variables. System Verilog classifies an array as 'PACKED' or 'UNPACKED'.
PACKED ARRAY: The upper and lower bounds of an array are declared in between the variable type and the variable name.
e.g.:reg [3:0] p_array
UNPACKED ARRAY: The upper and lower bounds of an array are declared after the variable name.
e.g.:reg u_array [3:0]
Also, an array may be declared as both packed and unpacked one.
Eg:reg [3:0] p_u_array [3:0]
System Verilog provides 2 types of arrays. They are 'Dynamic' array and 'Associative' Array.
All the packed or unpacked arrays are all static declarations, that is, memories are allocated for the array and there is noway that you can alter that afterwards. As a result, the size of an array can not be changed once it is declared. To overcome this deficiency, System Verilog provides Dynamic Array.
Dynamic Array
The biggest advantage of Dynamic array is that, it allocates storage for elements at run time along with the option of changing the size of one of its dimensions.
e.g.
bit [3:0] nibble[]; // Dynamic array of 4-bit vectors
integer mem[]; // Dynamic array of integers
mem = mem[10]; //creates a 10 element array
Dynamic Array Methods
- new[] — creates or modifies the size of an array
- Eg:array_1 = new [5]; // Array 'array_1' of size 5 is created
- size() — returns the current size of the array as an integer
- Eg:i< array_1.size(); // 'i' must be less than the size of 'array_1', which is 5 in this case
- delete() — deletes all the elements of the array
- Eg:array_1.delete(); // All the elements of array 'array_1' are deleted
Associative Arrays
The main difference between Associative arrays and ordinary arrays is that Associative array subscripts can be any scalar value. It enables us to access array variables using any scalar value we like.
e.g.
fruit ["bananas"] ; // “banana” String as an Index
ev_array [my_class] ; // my_class – Class as an Index
number [ev_array]; // ev_array – Array name as an Index
arr [2'b3]; //Number (2'b3 or 7 or 2) as an Index
typedef struct {
real R; int i [*]; } user_defined;
array_d [user_defined] ; // Any user defined types as as index
An Associative array is a better option when the size of the collection is unknown or the data space is sparse. Also, the storage is allocated only when it is used. It implements a lookup table for the elements of its declared type and the data type used as an index serves as the lookup key, which imposes an ordering. An important fact to remember is that associative arrays always are stored in "random" order. (Actually, it's the order that ensures fastest access, but, effectively, it is random.)
Associative Array is an unpacked array, that is, other than copying and comparing arrays, the individual element must be selected out of the array before using it in most expressions.
Associative Array Methods
- num() — returns the number of entries in the Associative array
- first() — assigns the value of the first index in the Associative array to the given index variable
- last() — assigns the value of the last index in the Associative array to the given index variable
- next() — assigns the value of the next index in the Associative array to the given index variable
- prev() — assigns the value of the previous index in the Associative array to the given index variable
- delete() — removes all the elements in the Associative array.
- If the index is specified, then the element at the specified index is deleted
- exists() — checks if element exists at the specified index in the Associative array
Associative arrays can be assigned only to another Associative array of a compatible type and with the same index type.
Queues
A Queue is a variable size ordered collection of homogeneous objects. There are two main aspects of a queue that makes it attractive for verification purposes. First, a queue can have variable length, including a length of zero. This makes a queue an ideal candidate as a storage element that can shrink or grow as elements are deleted or added to it without fixing an artificial upper limit on its size as a regular fixed size array. The other advantage of having a queue is that, it provides a way to emulate both Last In First Out (LIFO) and First In First Out (FIFO) behavior that are required in so many ordered transactions. At the same time a queue still allows you to access any element randomly within the queue without any overhead just as a regular array.
A Queue is analogous to one dimensional unpacked array that grows and shrinks automatically. Queues are declared using the same syntax as unpacked arrays, but specifying '$' as the array size.
e.g.
byte q1 [$];
integer my_q[$] = {1, 3, 5};
string names [$] = {“Ram, Sham, Laxman”};
bit q [$:255]; // A queue whose maximum size is 256 bits.
Queue Methods
- size() — returns the number of items in the queue
- insert() — inserts the given element at the specified index position
- delete() — deletes the given element at the specified index position
- pop_front() — removes aand returns the first element of the queue
- pop_back() — removes aand returns the last element of the queue
- push_front() — inserts the given element at the front of the queue
- push_back() — inserts the given element at the end of the queue