System Verilog : Queues
Last modified 2014-06-26
Sini
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 queuecheck;
//Declaration int qint[$]; //queue of integer logic [31:0] qlogic [$]; // queue of 32 bit logic integer qinteger[$:9]; // queue of integers with max 10 elements int i;
initial begin
//Adding and updating elements using unpacked array concatenation qint = {500,1000,1500,2000}; qlogic = {1,0,0,0,0,0,1,1,1,1,0}; qinteger = {10,20,40,50};
$display("qint: %0d : %0d : %0d: %0d",qint[0],qint[1],qint[2],qint[3]);
//Read first item from the queue i = qint[0]; $display("qint -First item: %0d",i);
//Read last item from the queue i = qint[$]; $display("qint -Last item : %0d",i);
//Delete last item from the array qint = qint[0:$-1]; $display("qint -Deleted last item: %0d : %0d : %0d : %0d",qint[0],qint[1],qint[2],qint[3]);
//Write first item in the queue qint[0] = 250; $display("qint -Inserted first item: %0d",qint[0]);
//Write last item in the queue qint[$] = 2500; $display("qint -Inserted last item: %0d",qint[$]);
//Delete entire array qint = {}; $display("qint -After deletion %0d",qint.size);
//size of qinteger $display("qinteger -size %0d",qinteger.size);
//qinteger = {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("qinteger -Before insertion: %0d : %0d : %0d : %0d :%0d",qinteger[0],qinteger[1],qinteger[2],qinteger[3],qinteger[4]);
//Insertion using concatenation qinteger = {qinteger[0:1], 30, qinteger[2:$] }; $display("qinteger -After insertion: %0d : %0d : %0d : %0d :%0d",qinteger[0],qinteger[1],qinteger[2],qinteger[3],qinteger[4]);
qinteger = {10,20,30,40,50,60,70,80,90,100}; $display("qinteger -new size %0d",qinteger.size);
//Read second element from qlogic $display("qlogic %0b",qlogic[1]);
end endmodule /* ncsim> run qint: 500 : 1000 : 1500: 2000 qint -First item: 500 qint -Last item : 2000 qint -Deleted last item: 500 : 1000 : 1500 : 0 qint -Inserted first item: 250 qint -Inserted last item: 2500 qint -After deletion 0 qinteger -size 4 qinteger -Before insertion: 10 : 20 : 40 : 50 :x qinteger -After insertion: 10 : 20 : 30 : 40 :50 qinteger -new size 10 qlogic 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 queuecheck1;
//Declaration int qint[$]; //queue of integer logic [31:0] qlogic [$]; // queue of 32 bit logic integer qinteger[$:9]; // queue of integers with max 10 elements
initial begin
qint = {500,1000,1500,2000}; qlogic = {1,0,0,0,0,0,1,1,1,1,0}; qinteger = {10,20,40,50};
for ( int j = 0; j < qint.size; j++ ) $display( "qint : %0d",qint[j] ); for ( int j = 0; j < qinteger.size; j++ ) $display( "qinteger : %0d",qinteger[j] );
$display("size of queues qint size : %0d, qinteger size : %0d, qlogic size : %0d",qint.size,qinteger.size,qlogic.size);
end endmodule /* ncsim> run qint : 500 qint : 1000 qint : 1500 qint : 2000 qinteger : 10 qinteger : 20 qinteger : 40 qinteger : 50 size of queues qint size : 4, qinteger size : 4, qlogic 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 queueinsertcheck;
integer qinteger[$];
initial begin
qinteger = {10,20,40,50};
$display("qinteger -Before insertion: %0d : %0d : %0d : %0d :%0d",qinteger[0],qinteger[1],qinteger[2],qinteger[3],qinteger[4]);
qinteger.insert(2,30); $display("qinteger -After insertion: %0d : %0d : %0d : %0d :%0d",qinteger[0],qinteger[1],qinteger[2],qinteger[3],qinteger[4]);
end endmodule /* ncsim> run qinteger -Before insertion: 10 : 20 : 40 : 50 :x qinteger -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 queuedeletecheck;
integer qinteger[$];
initial begin
qinteger = {10,20,30,40,50}; $display("qinteger -Before deletion: %0d : %0d : %0d : %0d :%0d",qinteger[0],qinteger[1],qinteger[2],qinteger[3],qinteger[4]);
qinteger.delete(2); $display("qinteger -After deletion of one element: %0d : %0d : %0d : %0d :%0d",qinteger[0],qinteger[1],qinteger[2],qinteger[3],qinteger[4]);
qinteger.delete(); $display("qinteger -After deletion: %0d : %0d : %0d : %0d :%0d",qinteger[0],qinteger[1],qinteger[2],qinteger[3],qinteger[4]);
end endmodule /* ncsim> run qinteger -Before deletion: 10 : 20 : 30 : 40 :50 qinteger -After deletion of one element: 10 : 20 : 40 : 50 :x qinteger -After deletion: x : x : x : x :x ncsim: *W,RNQUIE: Simulation is complete. */
popfront(): The popfront() method removes and returns the first element of the queue.
popback(): The popback() method removes and returns the last element of the queue.
pushfront(): The pushfront() method inserts the given element at the front of the queue.
pushback(): The pushback() method inserts the given element at the end of the queue.
module queuepushpopcheck;
integer qinteger[$];
integer i;
initial begin
qinteger = {10,20,30,40,50,60}; $display("qinteger: %0d : %0d : %0d : %0d :%0d\n",qinteger[0],qinteger[1],qinteger[2],qinteger[3],qinteger[4]);
i = qinteger.popfront(); $display("popfront return: %0d",i); $display("qinteger : After popfront: %0d : %0d : %0d : %0d :%0d \n",qinteger[0],qinteger[1],qinteger[2],qinteger[3],qinteger[4]);
i = qinteger.popback(); $display("popback return: %0d",i); $display("qinteger : After popback: %0d : %0d : %0d : %0d :%0d\n",qinteger[0],qinteger[1],qinteger[2],qinteger[3],qinteger[4]);
qinteger.pushfront(70); $display("qinteger : After pushfront: %0d : %0d : %0d : %0d :%0d\n",qinteger[0],qinteger[1],qinteger[2],qinteger[3],qinteger[4]);
qinteger.pushback(80); $display("qinteger : After pushback: %0d : %0d : %0d : %0d :%0d :%0d\n",qinteger[0],qinteger[1],qinteger[2],qinteger[3],qinteger[4],qinteger[5]); end endmodule /* ncsim> run qinteger: 10 : 20 : 30 : 40 :50
popfront return: 10 qinteger : After popfront: 20 : 30 : 40 : 50 :60
popback return: 60 qinteger : After popback: 20 : 30 : 40 : 50 :x
qinteger : After pushfront: 70 : 20 : 30 : 40 :50
qinteger : After pushback: 70 : 20 : 30 : 40 :50 :80
ncsim: *W,RNQUIE: Simulation is complete. */