System Verilog : Queues

System Verilog : Queues

In your system verilog code, if extraction and insertion order of array elements are important, `queue` would be the best option. A queue is a variable-size, ordered collection of homogeneous elements. It is declared using the same syntax as unpacked arrays, but specifying $ as the array size. It is analogous to a one-dimensional unpacked array that grows and shrinks automatically. So like arrays, queues can be manipulated using concatenation, slicing, indexing and quality operators.

Each element in a queue is identified by an ordinal number that represents its position within the queue. In this 0 represents the first and $ represents the last. Insertion and deletion of elements from random locations using an index are also possible with queues.

Bounded queues Queue size can be limited by giving the last index (upper bound) as follows

int queueA[$:99]; // A queue whose maximum size is 100 integers

These are called bounded queues.It will not have an element whose index is higher than the queue's declared upper bound. Operators on bounded queue can be applied exactly the same way as unbounded queues, except that, result should fall in the upper bound limit.

module queue_check;

//Declaration int q_int[$]; //queue of integer logic [31:0] q_logic [$]; // queue of 32 bit logic integer q_integer[$:9]; // queue of integers with max 10 elements int i;

initial begin

//Adding and updating elements using unpacked array concatenation q_int = {500,1000,1500,2000}; q_logic = {1,0,0,0,0,0,1,1,1,1,0}; q_integer = {10,20,40,50};

$display("q_int: %0d : %0d : %0d: %0d",q_int[0],q_int[1],q_int[2],q_int[3]);

//Read first item from the queue i = q_int[0]; $display("q_int -First item: %0d",i);

//Read last item from the queue i = q_int[$]; $display("q_int -Last item : %0d",i);

//Delete last item from the array q_int = q_int[0:$-1]; $display("q_int -Deleted last item: %0d : %0d : %0d : %0d",q_int[0],q_int[1],q_int[2],q_int[3]);

//Write first item in the queue q_int[0] = 250; $display("q_int -Inserted first item: %0d",q_int[0]);

//Write last item in the queue q_int[$] = 2500; $display("q_int -Inserted last item: %0d",q_int[$]);

//Delete entire array q_int = {}; $display("q_int -After deletion %0d",q_int.size);

//size of q_integer $display("q_integer -size %0d",q_integer.size);

//q_integer = {10,20,30,40,50,60,70,80,90,100,0}; //Warning: Unpacked array concatenation contains too many queue elements. //Warning: SystemVerilog queue overflow beyond 10 items, tail entry lost

$display("q_integer -Before insertion: %0d : %0d : %0d : %0d :%0d",q_integer[0],q_integer[1],q_integer[2],q_integer[3],q_integer[4]);

//Insertion using concatenation q_integer = {q_integer[0:1], 30, q_integer[2:$] }; $display("q_integer -After insertion: %0d : %0d : %0d : %0d :%0d",q_integer[0],q_integer[1],q_integer[2],q_integer[3],q_integer[4]);

q_integer = {10,20,30,40,50,60,70,80,90,100}; $display("q_integer -new size %0d",q_integer.size);

//Read second element from q_logic $display("q_logic %0b",q_logic[1]);

end endmodule /* ncsim> run q_int: 500 : 1000 : 1500: 2000 q_int -First item: 500 q_int -Last item : 2000 q_int -Deleted last item: 500 : 1000 : 1500 : 0 q_int -Inserted first item: 250 q_int -Inserted last item: 2500 q_int -After deletion 0 q_integer -size 4 q_integer -Before insertion: 10 : 20 : 40 : 50 :x q_integer -After insertion: 10 : 20 : 30 : 40 :50 q_integer -new size 10 q_logic 0 ncsim: *W,RNQUIE: Simulation is complete. */

There are some built in methods available in queue to do insertion, deletion, pushing, popping etc, without using the above methods.

Queue Methods size() : The size() method returns the number of items in the queue. If the queue is empty, it returns 0.

module queue_check1;

//Declaration int q_int[$]; //queue of integer logic [31:0] q_logic [$]; // queue of 32 bit logic integer q_integer[$:9]; // queue of integers with max 10 elements

initial begin

q_int = {500,1000,1500,2000}; q_logic = {1,0,0,0,0,0,1,1,1,1,0}; q_integer = {10,20,40,50};

for ( int j = 0; j < q_int.size; j++ ) $display( "q_int : %0d",q_int[j] ); for ( int j = 0; j < q_integer.size; j++ ) $display( "q_integer : %0d",q_integer[j] );

$display("size of queues q_int size : %0d, q_integer size : %0d, q_logic size : %0d",q_int.size,q_integer.size,q_logic.size);

end endmodule /* ncsim> run q_int : 500 q_int : 1000 q_int : 1500 q_int : 2000 q_integer : 10 q_integer : 20 q_integer : 40 q_integer : 50 size of queues q_int size : 4, q_integer size : 4, q_logic size : 11 ncsim: *W,RNQUIE: Simulation is complete. */

insert(): The insert() method inserts the given item at the specified index position.

function void insert (int index, qtype item); inserts an item at the index location insert()

If the index argument has any bits with unknown (x/z) value, or is negative, or is greater than the current size of the queue, then the method call shall have no effect on the queue and may cause a warning to be issued.

module queue_insert_check;

integer q_integer[$];

initial begin

q_integer = {10,20,40,50};

$display("q_integer -Before insertion: %0d : %0d : %0d : %0d :%0d",q_integer[0],q_integer[1],q_integer[2],q_integer[3],q_integer[4]);

q_integer.insert(2,30); $display("q_integer -After insertion: %0d : %0d : %0d : %0d :%0d",q_integer[0],q_integer[1],q_integer[2],q_integer[3],q_integer[4]);

end endmodule /* ncsim> run q_integer -Before insertion: 10 : 20 : 40 : 50 :x q_integer -After insertion: 10 : 20 : 30 : 40 :50 ncsim: *W,RNQUIE: Simulation is complete. */

delete(): The delete() method deletes the item at the specified index. Index is optional. If index is not specified, entire elements in the queue will get deleted leaving the queue empty. If the index argument has any bits with unknown (x/z) value, or is negative, or is greater than or equal to the current size of the queue, then the method call shall have no effect on the queue and may cause a warning to be issued.

module queue_delete_check;

integer q_integer[$];

initial begin

q_integer = {10,20,30,40,50}; $display("q_integer -Before deletion: %0d : %0d : %0d : %0d :%0d",q_integer[0],q_integer[1],q_integer[2],q_integer[3],q_integer[4]);

q_integer.delete(2); $display("q_integer -After deletion of one element: %0d : %0d : %0d : %0d :%0d",q_integer[0],q_integer[1],q_integer[2],q_integer[3],q_integer[4]);

q_integer.delete(); $display("q_integer -After deletion: %0d : %0d : %0d : %0d :%0d",q_integer[0],q_integer[1],q_integer[2],q_integer[3],q_integer[4]);

end endmodule /* ncsim> run q_integer -Before deletion: 10 : 20 : 30 : 40 :50 q_integer -After deletion of one element: 10 : 20 : 40 : 50 :x q_integer -After deletion: x : x : x : x :x ncsim: *W,RNQUIE: Simulation is complete. */

pop_front(): The pop_front() method removes and returns the first element of the queue.

pop_back(): The pop_back() method removes and returns the last element of the queue.

push_front(): The push_front() method inserts the given element at the front of the queue.

push_back(): The push_back() method inserts the given element at the end of the queue.

module queue_push_pop_check;

integer q_integer[$];
integer i;

initial begin

q_integer = {10,20,30,40,50,60}; $display("q_integer: %0d : %0d : %0d : %0d :%0d\n",q_integer[0],q_integer[1],q_integer[2],q_integer[3],q_integer[4]);

i = q_integer.pop_front(); $display("pop_front return: %0d",i); $display("q_integer : After pop_front: %0d : %0d : %0d : %0d :%0d \n",q_integer[0],q_integer[1],q_integer[2],q_integer[3],q_integer[4]);

i = q_integer.pop_back(); $display("pop_back return: %0d",i); $display("q_integer : After pop_back: %0d : %0d : %0d : %0d :%0d\n",q_integer[0],q_integer[1],q_integer[2],q_integer[3],q_integer[4]);

q_integer.push_front(70); $display("q_integer : After push_front: %0d : %0d : %0d : %0d :%0d\n",q_integer[0],q_integer[1],q_integer[2],q_integer[3],q_integer[4]);

q_integer.push_back(80); $display("q_integer : After push_back: %0d : %0d : %0d : %0d :%0d :%0d\n",q_integer[0],q_integer[1],q_integer[2],q_integer[3],q_integer[4],q_integer[5]); end endmodule /* ncsim> run q_integer: 10 : 20 : 30 : 40 :50

pop_front return: 10 q_integer : After pop_front: 20 : 30 : 40 : 50 :60

pop_back return: 60 q_integer : After pop_back: 20 : 30 : 40 : 50 :x

q_integer : After push_front: 70 : 20 : 30 : 40 :50

q_integer : After push_back: 70 : 20 : 30 : 40 :50 :80

ncsim: *W,RNQUIE: Simulation is complete. */