SystemVerilog Queue

 

Queue in SystemVerilog

A queue in SystemVerilog is a variable-size, ordered collection of homogeneous elements. “Variable size” means adding or removing elements as needed without specifying a fixed size in advance. “Ordered collection” indicates that the elements are stored in the order in which they were added, following a FIFO (First-In-First-Out) order. SystemVerilog provides various methods to manipulate queues.

A SystemVerilog queue stores elements of the same data type, maintaining an ordered collection in a First-In-First-Out (FIFO) manner. This ensures the elements are arranged in the order they were added, with indexing starting from 0. Each element in the queue is assigned an index value, starting from 0 for the first element, 1 for the second, and so forth.

Accessing elements via their index values facilitates easy retrieval or manipulation of specific elements within the queue. Queue elements can be accessed by index value.

SystemVerilog queue is dynamic but don’t require the `new` operator for memory allocation or resizing. They automatically manage memory allocation and deallocation internally, enabling the user to add or remove elements without explicit memory management.

Queue capable of holding infinite elements. The queue’s capacity is practically boundless in terms of dynamically increasing its size to accommodate elements. However, it’s important to note that the available memory in the system might limit the actual capacity.

 

The `queue_name[$]` syntax represents a queue capable of dynamically handling an arbitrary number of elements. This dynamic nature allows for flexibility in accommodating elements without explicitly allocating memory.

data_type queue_name[$];

 

where:
data_type     – data type of the queue elements.
queue_name – name of the queue.

module queue_tb;
  byte queue[$];
  
  initial
    begin
      queue = {2, -1, 127};
      
      $display(" queue=%p", queue);
      
    end
endmodule

Output:

# run -all
#  queue='{2, -1, 127}
# exit

Queue methods in systemverilog:

queue methods in systemverilog

 

 Method                                     Description

size()                              returns the number of elements in the queue

insert()                          insert the given element  at the specified index position of queue

delete()                          deletes the element at the specified index position of the queue

pop_front()                remove and return the first element of the queue

pop_back()                remove and return the last element of the queue

push_front()             insert the  element at the front of the queue

push_back()              insert the  element at the end of the queue

shuffle()                      shuffle the queue elements in a random manner

reverse()                      reverse the queue elements order

module  queue_tb;
  
  byte queue1[$]={1,2,3,4,6,7};
  int fill_queue;
  
  initial
       begin
       $display("Initial data in queue1=%p   ",queue1,);
         
         //Size-Method
         $display("queue1=%p", queue1.size());
         
      //insert-method
       queue1.insert(4,5);
       $display("queue1=%p    queue1[4]=%0d  insert(4,5) ",queue1,queue1[4]);
      
       queue1.insert(4,5);
       $display("queue1=%p  queue1[5]=%0d insert(5,5) ",queue1,queue1[4]);
         
       //delete- method
       queue1.delete(5); 
       $display("queue1=%p    queue1[5]=%0d  delete(5) ",queue1,queue1[5]);
      
       queue1.insert(0,1);
         $display("queue1=%p    queue1[0]=%0d  insert(0,1) ",queue1,queue1[0]);
         
         //pop_front method
       queue1.pop_front();  
         $display("queue1=%p    queue1[0]=%0d  pop_front(0) ",queue1,queue1[0]);
         
         //push_front method
       queue1.push_front(9);                                        //Element '9'
       $display("queue1=%p      push_front(9) ",queue1);
         
       //push_back method
       queue1.push_back(10);                                        //Element '10'
      $display("queue1=%p      push_back(10) ",queue1,);
         
       // pop_back method
         fill_queue= queue1.pop_back();
         $display("queue1=%p     pop_back(0) fill_queue=%0d", queue1,fill_queue);
              
        // shuffle method
         queue1.shuffle();
         $display("queue1=%p", queue1);
         
         //reverse method
         queue1.reverse();
         $display("queue1=%p", queue1);
       queue1.delete();  
         $display("Final data in queue queue1=%p empty   ",queue1,);
       $stop();  
    end 
  
endmodule  

Output:

Initial data in queue1='{1, 2, 3, 4, 6, 7}     
queue1=          6
queue1='{1, 2, 3, 4, 5, 6, 7}     queue1[4]=5  insert(4,5) 
queue1='{1, 2, 3, 4, 5, 5, 6, 7}   queue1[5]=5 insert(5,5) 
queue1='{1, 2, 3, 4, 5, 6, 7}     queue1[5]=6  delete(5) 
queue1='{1, 1, 2, 3, 4, 5, 6, 7}     queue1[0]=1  insert(0,1) 
queue1='{1, 2, 3, 4, 5, 6, 7}     queue1[0]=1  pop_front(0) 
queue1='{9, 1, 2, 3, 4, 5, 6, 7}       push_front(9) 
queue1='{9, 1, 2, 3, 4, 5, 6, 7, 10}       push_back(10)  
queue1='{9, 1, 2, 3, 4, 5, 6, 7}      pop_back(0) fill_queue=10
queue1='{6, 4, 7, 3, 2, 5, 9, 1} 
queue1='{1, 9, 5, 2, 3, 7, 4, 6} 
Final data in queue queue1='{} empty    

 You can have an unbounded or bounded queue.

Bounded queue: queue with a restricted number of entries or queue size defined.

int queue1[$:7];

Unbounded queue: queue with infinite entries or queue size not specified; 

int queue1[$];

Bounded Queue in systemverilog:

A bounded queue in SystemVerilog is a queue with a restricted number of entries or queue size defined that allows you to store and manage a fixed number of elements in a first-in, first-out (FIFO). Unlike an array, a bounded queue has a fixed size, and when it’s full, adding new elements will require removing older elements to make space.

Bounded queue

Here’s an example of how you can implement a bounded queue in SystemVerilog:

module  queue_tb;
  
  byte queue_1[$:9]={1,2,3,4,6,7};
  int fill_queue;
  
  initial
       begin
         $display("Initial data in queue_1=%p   ",queue_1,);
         
         //Size-Method
         $display("queue_1=%p", queue_1.size());
         
      //insert-method
       queue_1.insert(4,5);
         $display("queue_1=%p    queue_1[4]=%0d  insert(4,5) ",queue_1,queue_1[4]);
      
       queue_1.insert(4,5);
         $display("queue_1=%p  queue_1[5]=%0d insert(5,5) ",queue_1,queue_1[4]);
         
       //delete- method
       queue_1.delete(5); 
         $display("queue_1=%p    queue_1[5]=%0d  delete(5) ",queue_1,queue_1[5]);
      
       queue_1.insert(0,1);
         $display("queue_1=%p    queue_1[0]=%0d  insert(0,1) ",queue_1,queue_1[0]);
         
         //pop_front method
       queue_1.pop_front();  
         $display("queue_1=%p    queue_1[0]=%0d  pop_front(0) ",queue_1,queue_1[0]);
         
         //push_front method
       queue_1.push_front(9);                                        //Element '9'
         $display("queue_1=%p      push_front(9) ",queue_1);
         
       //push_back method
       queue_1.push_back(10);                                        //Element '10'
         $display("queue_1=%p      push_back(10) ",queue_1,);
         
       // pop_back method
         fill_queue= queue_1.pop_back();
         $display("queue_1=%p     pop_back(0) fill_queue=%0d", queue_1,fill_queue);
              
        // shuffle method
         queue_1.shuffle();
         $display("queue_1=%p", queue_1);
         
         //reverse method
         queue_1.reverse();
         $display("queue_1=%p", queue_1);
       queue_1.delete();  
         $display("Final data in queue queue1=%p empty   ",queue_1,);
       $stop();  
    end 
  
endmodule  

Output:

Initial data in queue_1='{1, 2, 3, 4, 6, 7}     
queue_1=          6
queue_1='{1, 2, 3, 4, 5, 6, 7}     queue_1[4]=5  insert(4,5) 
queue_1='{1, 2, 3, 4, 5, 5, 6, 7}   queue_1[5]=5 insert(5,5) 
queue_1='{1, 2, 3, 4, 5, 6, 7}     queue_1[5]=6  delete(5) 
queue_1='{1, 1, 2, 3, 4, 5, 6, 7}     queue_1[0]=1  insert(0,1) 
queue_1='{1, 2, 3, 4, 5, 6, 7}     queue_1[0]=1  pop_front(0) 
queue_1='{9, 1, 2, 3, 4, 5, 6, 7}       push_front(9) 
queue_1='{9, 1, 2, 3, 4, 5, 6, 7, 10}       push_back(10)  
queue_1='{9, 1, 2, 3, 4, 5, 6, 7}      pop_back(0) fill_queue=10
queue_1='{6, 4, 7, 3, 2, 5, 9, 1} 
queue_1='{1, 9, 5, 2, 3, 7, 4, 6} 
Final data in queue queue1='{} empty    

Unbounded Queue in systemverilog:

In SystemVerilog, an unbounded queue is a dynamic data structure that doesn’t have a predefined fixed size. It grows dynamically as elements are added and shrinks as elements are removed.

unbounded queue

Here’s an example of an unbounded queue in SystemVerilog:

module UnboundedQueue;
  // Declare an unbounded queue 
  bit [31:0] myQueue[$];
  // Dequeue elements from the queue
    int element;
  initial begin
    // Enqueue elements into the unbounded queue
    myQueue.push_back(10);
    myQueue.push_back(20);
    myQueue.push_back(30);

    // Display the size of the queue
    $display("Size of the queue: %0d", myQueue.size());

   
    element = myQueue.pop_front();
    $display("Dequeued element: %0d", element);

    element = myQueue.pop_front();
    $display("Dequeued element: %0d", element);

    // Display the size after dequeue
    $display("Size of the queue after dequeue: %0d", myQueue.size());
  end
endmodule

Output:

Size of the queue: 3
Dequeued element: 10
Dequeued element: 20
Size of the queue after dequeue: 1
module top ; 
  int queue [$];
  int temp ; 
  
  initial begin 
    
    queue.push_back(1); 
    queue.push_back(10);
    queue.push_back(40);
    
    $display(" queue size= %0d      value of queue %p" , queue.size(),queue);
    
    queue.push_back(50);    
    $display(" queue size= %0d      value of queue %p" , queue.size(),queue);
    
    queue.pop_front();    
    $display(" queue size= %0d      value of queue %p" , queue.size(),queue);    
    
    queue.pop_front();    
    $display(" queue size= %0d      value of queuet %p" , queue.size(),queue);    
    
    queue.push_front(1); 
    queue.push_front(10);
    queue.push_front(40);    
    $display(" queue size= %0d       value of queuet %p" , queue.size(),queue);

    queue.pop_back();    
    $display(" queue size= %0d       value of queue %p" , queue.size(),queue);    
    queue.pop_back();    
    $display(" queue size= %0d       value of queue %p" , queue.size(),queue);    
    queue.shuffle();    
    $display(" queue size %0d        value of queue %p" , queue.size(),queue);    
    queue.reverse();    
    $display(" queue size %0d        value of queue %p" , queue.size(),queue); 
     queue.pop_back();    
    $display(" queue size %0d        value of queue %p" , queue.size(),queue); 
    temp = queue[1];
    $display(" temp value= %0d      queue value at index 1 %d ", temp, queue[1]);
    queue.delete(1);
    $display(" queue size= %0d      value of queue %p" , queue.size(),queue);    
    queue.delete();
    $display(" queue size= %0d      value of queue %p" , queue.size(),queue);    
    
  end 
endmodule

Output:

queue size= 3      value of queue '{1, 10, 40} 
 queue size= 4      value of queue '{1, 10, 40, 50} 
 queue size= 3      value of queue '{10, 40, 50} 
 queue size= 2      value of queuet '{40, 50} 
 queue size= 5       value of queuet '{40, 10, 1, 40, 50} 
 queue size= 4       value of queue '{40, 10, 1, 40} 
 queue size= 3       value of queue '{40, 10, 1} 
 queue size 3        value of queue '{1, 10, 40} 
 queue size 3        value of queue '{40, 10, 1} 
 queue size 2        value of queue '{40, 10} 
 temp value= 10      queue value at index 1          10 
 queue size= 1      value of queue '{40} 
 queue size= 0      value of queue '{}
           V C S   S i m u l a t i o n   R e p o r t
Scroll to Top