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 non-negative, 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 built-in 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:

  1. my_q[0] refers to the first element of the queue my_q.
  2. 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

Share/Save/Bookmark



Verification Management
Join Verification Management Group


Book of the Month


From Our Press