Queues
Next: Queue Methods
What are Queues?
SystemVerilog provides a number of new data structures to store a collection of
objects. A queue is such a data structure. The size of a queue is variable
similar to a dynamic array, but a queue may be
empty with no element and it is still a valid data structure.
Why Do I Need A Queue?
A Queue is a variable size ordered collection of similar 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, as we will see in the
next section, a queue still allows you to access any element randomly within the queue
without any overhead just as a regular array.
Declaring a Queue
A queue is declared simply by putting a $ as the size of an array.
integer my_q[$];
You can initialize a queue at the place of its variable declaration:
integer my_q[$] = {1, 3, 5};
You can also set up an upper limit of index for a queue:
integere my_q[$:127];
Since index of an array can only be nonnegative, the maximum number of elements
for the queue in the above case is 128 (i.e., 0 through 127).
Working with Queues
There are two ways to work with a queue. You can use it as a general array (and
use all the operaions that you can perform on an array). The other way is to
use the builtin methods that a queue provide. We explain each of these below.
A Queue as an array
You can do everything with a queue that an array allows. However, certain
operations due to dynamic sizing of a queue are more interesting than others.
To see these, you need to remember:
 my_q[0] refers to the first element of the queue my_q.
 my_q[$] refers to the last element of my_q (except for
a queue definition.
Let us assume prime_q and odd_q refer to two different queues.
integer prime_q[$] = {2, 3, 5, 7, 11, 13};
integer odd_q[$];
Also, elem is an integer variable.
integer elem;
1. Assigning a queue to another:
odd_q = prime_q;
odd_q is same as prime_q now.
2. Adding an element to a queue
prime_q = {prime_q, 17};
prime_q now has the element 17 to its end.
prime_q = {1, prime_q};
This adds 1 to prime_q as its first elemnent.
2. Deleting elements of a queue
prime_q = prime_q[1:$];
removes the first element and
prime_q = prime_q[0:$1];
removes the last. As a matter of fact, you can shrink a queue by
prime_q = prime_q[lower:upper];
where lower and upper are the bounds that is within this
queue's limits.
And finally, the following will delete all elemnts of a queue and make it
empty.
prime_q = {};
3. Inserting elements in a queue
prime_q[$] = {3, 5, 7, 11, 13};
odd_q[$] = {prime_q[0:3], 9, {prime_q[4:5]};
odd_q is now {3, 5, 7, 9, 11, 13};
While you can use the above ways to directly manipulate the contents
of a queue, SystemVerilog also provides a set of methods that can do
these works for you and then some more. The next page describes these
methods.
Next: Queue Methods
