SystemVerilog -- 2.11 Data Types ~ SystemVerilog Queue
SystemVerilog Queue
目录
SystemVerilog Queue是一种先进先出的方案,它可以具有可变大小来存储相同数据类型的元素。
他类似于一个自动增长和收缩的一维unpacked数组。他们也可以通过索引、串联和切片运算符来操作。队列可以作为ref或!ref参数传递给task/function。
Types of Queues
有界queue具有特定的大小,可以容纳有限数量的条目。下面显示的是深度为N的有界队列,其中包含N个项目,无法接受更多项目。
[data_type] [name_of_queue] [$:N];
int bounded_queue [$:10]; // Depth 10
无界queue可以有无限数量的条目。下面显示的是一个无界queue,其中包含5个项目,可以接受更多项目。
[data_type] [name_of_queue] [$];
int unbounded_queue [$]; // Unlimited entries
SystemVerilog Queue Usage
Queue的区别在于它使用$运算符指定大小。
string name_list [$]; // A queue of string elements
bit [3:0] data [$]; // A queue of 4-bit elements
logic [7:0] elements [$:127]; // A bounded queue of 8-bits with maximum size of 128 slots
int q1 [$] = {1, 2, 3, 4, 5}; // Integer queue, initialize elements
int q2 [$]; // Integer queue, empty
int tmp; // Temporary variable to store values
tmp = q1 [0]; // Get first item of q1 (insex 0) and store in tmp
tmp = q1 [$]; // Get last item of q1 (insex 4) and store in tmp
q2 = q1; // Copy all elements in q1 into q2
q1 = {}; // Empty the queue (delete all items)
q2[2] = 15; // Replace element at index 2 with 15
q2.insert (2, 15); // Inserts value 15 to index# 2
q2 = {q2, 22}; // Append 22 to q2
q2 = {99, q2}; // Put 99 as the first element of q2
q2 = q2 [1:$]; // Delete first item
q2 = q2 [0:$-1]; // Delete last item
q2 = q2 [1:$-1]; // Delete first and last item
SystemVerilog Queue Example
module tb;
// Create a queue that can store "string" values
string fruits[$] = {"orange", "apple", "kiwi"};
initial begin
// Iterate and access each queue element
foreach (fruits[i])
$display ("fruits[%0d] = %s", i, fruits[i]);
// Display elements in a queue
$display ("fruits = %p", i, fruits);
// Delete all elements in the queue
$display ("After deletion, fruits = %p", fruits);
end
endmodule
模拟日志
ncsim> run
fruits[0] = orange
fruits[1] = apple
fruits[2] = kiwi
fruits = '{"orange", "apple", "kiwi"}
After deletion, fruits = '{}
ncsim: *W,RNQUIE: Simulation is complete.
What are queue slice expressions ?
slice表达式选择现有变量的子集。可以使用slice表达式选择queue元素,如以下示例所示。
Some simulators provide different results, hence using queue methods is recommended. |
module tb;
// Create a queue that can store "string" values
string fruits[$] = {"orange", "apple", "lemon", "kiwi"};
initial begin
// Select a subset of the queue
$display ("citrus fruits = %p", fruits[1:2]);
// Get elements from index 1 to end of queue
$display ("fruits = %p", fruits[1:2]);
// Add element to the end of queue
fruits[$+1] = "pineapple";
$display ("fruits = %p", fruits);
// Delete first element
$display ("Remove orange, fruits = %p", fruits[1:$]);
end
endmodule
模拟日志
Compiler version J-2014. 12-SP1-1; Runtime version J-2014. 12-SP1-1; May 15 16:21 2018
citrus fruits = '{"apple", "lemon"}
fruits = '{"apple", "lemon", "kiwi"}
fruits = '{"orange", "apple", "lemon", "kiwi", "pineapple"}
Remove orange, fruits = '{"apple", "lemon", "kiwi", "pipeapple"}
SystemVerilog Queue Methods
SystemVerilog queue方法使出了数组运算符之外的几个内置方法,用于对queue进行操作,如下表所示。
Methods | Descrition |
---|---|
function int size (); | Returns the number of items in the queue, 0 if empty |
function void insert (input integer index, input element_t_item); | Inserts the given item at the specified index position |
function void delete ([input integer index]); | Deletes the element at the specified index, and if not provided all elements will be deleted |
function element_t_pop_front (); | Removes and returns the first element of the queue |
function element_t_pop_back (); | Removes and returns the last element of the queue |
function void push_front (input element_t_item); | Inserts the given element at the front of the queue |
function void push_back (input element_t_item); | Inserts the given element at the end of the queue |
SystemVerilog Queue Methods Example
module tb;
string fruits[$] = {"apple", "pear", "mango", "banana"};
initial begin
// size() - Gets size of the given queue
$display ("Number of fruits=%0d", fruits.size(), fruits);
// insert() - Insert an element to the given index
fruits.insert (1, "peach");
$display ("Insert peach, size=%0d fruits=%p", fruits.size(), fruits);
// delete() - Delete element at given index
fruits.delete (3);
$display ("Delete mango, size=%0d fruits=%p", fruits.size(), fruits);
// pop_front() - Pop out element at the front
$display ("Pop %s, size=%0d fruits=%p", fruits.pop_front(), fruits.size(), fruits);
// push_front() - Push a new element at the front of the queue
$display ("Push apricot, size=%0d fruits=%p", fruits.size(), fruits);
// pop_back() - Pop out element at the back
$display ("Pop %s, size=%0d fruits=%p", fruits.pop_back(), fruits.size(), fruits);
// push_back() - Push a new element at the front of the queue
$display ("Push plum, size=%0d fruits=%p", fruits.size(), fruits);
end
endmodule
模拟日志
ncsim> run
Number of fruits=4 fruits='{"apple", "pear", "mango", "banana"}
Insert peach, size=5 fruits='{"apple", "peach", "pear", "mango", "banana"}
Delete mango, size=4 fruits='{"apple", "peach", "pear", "banana"}
Pop apple, size=3 fruits='{"peach", "pear", "banana"}
Push apricot, size=4 fruits='{"apricot", "peach", "pear", "banana"}
Pop banana, size=3 fruits='{"apricot", "peach", "pear"}
Push plum, size=4 fruits='{"apricot", "peach", "pear", "plum"}
ncsim: *W,RNQUIE: Simulation is complete.
How to create a queue of classes in SystemVerilog ?
// Define a class with a single string member called "name"
class Fruit;
string name;
function new (string name="Unkown");
this.name = name;
endfunction
endclass
module tb;
// Create a queue that can hold values of data type "Fruit"
Fruit list [$];
initial begin
// Create a new class object and call it "Apple" and push into the queue
Fruit f = new ("Apple");
list.push_back (f);
// Create another class object and call it "Banana" and push into the queue
f = new ("Banana");
list.push_back (f);
// Iterate through queue and access each class object
foreach (list[i])
$display ("list[%0d] = %s", i, list[i].name);
// Simply print the whole queue, note that class handles are printed and not class object contents
$display ("list = %p", list);
end
endmodule
模拟日志
ncsim> run
list[0] = Apple
list[1] = Banana
list = '{$unit_0x4ccdf83b::Fruit@2_1, $unit_0x4ccdf83b::Fruit@4_1}
ncsim: *W,RNQUIE: Simulation is complete.
How to create a queue of dynamic arrays in SystemVerilog ?
// Declare a dynamic array to store strings as a datatype
typedef string str_da [];
module tb;
// This is a queue of dynamic arrays
str_da list [$];
initial begin
// Initialize separate dynamic arrays with some values
str_da marvel = '{"Spiderman", "Hulk", "Captain America", "Iron Man"};
str_da dcWorld = '{"Batman", "Superman"};
// Push the previously created dynamic arrays to queue
list.push_back (marvel);
list.push_back (dcWorld);
// Iterate through the queue and access dynamic array elements
foreach (list[i])
foreach (list[i][j])
$display ("list[%0d][%0d] = %s", i, j, list[i][j]);
// Simply print the queue
$display ("list = %p", list);
end
endmodule
模拟日志
ncsim> run
list[0][0] = Spiderman
list[0][1] = Hulk
list[0][2] = Captain America
list[0][3] = Iron Man
list[1][0] = Batman
list[1][1] = Superman
list = '{' {"Spiderman", "Hulk", "Captain America", "Iron Man"}, '{"Batman", "Superman"}}
ncsim: *W,RNQUIE: Simulation is complete.