What is a Queue? #
A queue in SystemVerilog is a variable-size, ordered collection of homogeneous elements (i.e., all of the same type). It is a single-dimensional unpacked array that can grow or shrink dynamically during simulation.
Unlike fixed-size arrays, queues do not require a predefined upper limit, making them highly useful for scenarios where data sizes vary.
Syntax:
data_type queue_name[$]; // Unbounded queue
Why Use Queues? #
Queues offer two major advantages in verification:
1. Dynamic Size #
- A queue can hold zero or more elements at any time.
- You don’t need to define an artificial limit like in fixed-size arrays.
- Ideal for dynamic data storage such as:
- Transaction lists
- Packets of unknown size
- Temporary buffers
2. Ordered Access & Flexible Behavior #
- Can emulate both:
- FIFO behavior using
push_back()
andpop_front()
- LIFO behavior using
push_back()
andpop_back()
- FIFO behavior using
- Still allows direct index access like a regular array.
Example: Declaring and Using a Queue
module test;
int q[$]; // Declare an unbounded queue
int val;
initial begin
q.push_back(10); // q = {10}
q.push_front(5); // q = {5, 10}
q.push_back(20); // q = {5, 10, 20}
$display("Queue: %p", q);
$display("First: %0d", q[0]);
$display("Last: %0d", q[$]);
val = q.pop_front(); // Removes 5
$display("After pop_front: %p", q);
q.delete(); // Delete entire queue
$display("Size after delete: %0d", q.size());
end
endmodule
Output:
Queue: '{5, 10, 20}
First: 5
Last: 20
After pop_front: '{10, 20}
Size after delete: 0
Built In Methods
Method | Description |
---|---|
push_front(item) | Insert item at front |
push_back(item) | Insert item at end |
pop_front() | Remove and return item from front |
pop_back() | Remove and return item from end |
insert(index, val) | Insert value at a specific index |
delete(index) | Delete element at a specific index |
delete() | Delete all elements |
size() | Return current number of elements |
When to Use Queues #
Use a queue when:
- You need flexible data structures that grow/shrink during simulation
- You’re implementing FIFO/LIFO transaction handling
- You require random access with constant time performance
- You want to simulate hardware buffers, transaction pools, or event queues