
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. */
Hi,
I’m trying to use struct as data type in queues. Like as shown below:
typedef struct {bit[31:0] addr, bit[3:0] id, bit[63:0] data; bit flag}
packet_t;
packet_t q1 [$];
I want to populate the addr everytime a new addr comes in, like:
if (intf.a && intf.b)begin
q1.push_front.addr = intf.address;
q1.push_front.id = intf.id;
end
I would like to store the addr and id in the same item (index) of the queue.
(On the next cycle, if intf.a and intf.b evaluate to True, I want to store the id and addr as the second queue item)
Will the above code achieve the intent?
Are there examples of using struct as data type in queues and manipulating them?
When data arrives(along with data id), I plan to use the “find_first with” to find the queue item that matches with the id to store the data into.
Please let me know your inputs.
Thanks!
Ramya
Hi,
One idea is to use mailbox instead of structure to solve your problem.
If i want to store the value into the queue which is data_in of asynchronous fifo. What i have to do? please tell me i am a learner. This is to check whether the output and input are same.
Hi Mam,
I need to check the elements of the queue . how to do that
and also Please let me know what is the operation of find_index with and find _index method
Thanks,
Shanar