SystemVerilog 队列
SystemVerilog queue(队列)是一种 First In First Out(先入先出)方案,您可为其设置变量大小,用于存储相同数据类型的各种元素。
它与一维解包阵列类似,同样可以自动伸缩调整大小。队列和一维解包阵列均可通过索引、并置和分片运算符来进行操纵。队列可作为 ref(参考)实参或 non-ref(非参考)实参来传递给任务/函数。
语法和用法
队列根据其大小规格使用 $ 运算符来加以区分。
[data_type] [name_of_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 (index 0) and store in tmp
tmp = q1 [$]; // Get last item of q1 (index 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 队列示例
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", fruits);
// Delete all elements in the queue
fruits = {};
$display ("After deletion, fruits = %p", fruits);
end
endmodule
仿真 log 日志
ncsim> run
fruits[0] = orange
fruits[1] = apple
fruits[2] = kiwi
fruits = '{"orange", "apple", "kiwi"}
After deletion, fruits = '{}
ncsim: *W,RNQUIE: Simulation is complete.
什么是分片表达式?
分片表达式用于选择现有变量中的一小部分。队列元素可使用分片表达式来进行选择,如以下示例所示。
部分仿真器会提供不同的结果,因此建议使用队列方法。
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:$]);
// 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
仿真 log 日志
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", "pineapple"}
V C S S i m u l a t i o n R e p o r t
队列方法
队列方法示例
除阵列运算符外,队列还可提供多种内置方法。
函数 | 描述 |
---|---|
function int size (); | 返回队列中的项数如为空,则返回 0 |
function void insert (input integer index, input element_t item); | 在指定索引位置插入给定的项 |
function void delete ( [input integer index] ); | 删除指定索引处的元素,如果不提供此项元素,则将删除所有元素 |
function element_t pop_front (); | 移除并返回队列的首个元素 |
function element_t pop_back (); | 移除并返回队列的最后一个元素 |
function void push_front (input element_t item); | 在队列前插入给定元素 |
function void push_back (input element_t item); | 在队列末插入给定元素 |
module tb;
string fruits[$] = {"apple", "pear", "mango", "banana"};
initial begin
// size() - Gets size of the given queue
$display ("Number of fruits=%0d fruits=%p", 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 to front of the queue
fruits.push_front("apricot");
$display ("Push apricot, size=%0d fruits=%p", fruits.size(), fruits);
// pop_back() - Pop out element from the back
$display ("Pop %s, size=%0d fruits=%p", fruits.pop_back(), fruits.size(), fruits);
// push_back() - Push element to the back
fruits.push_back("plum");
$display ("Push plum, size=%0d fruits=%p", fruits.size(), fruits);
end
endmodule
仿真 log 日志
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.
如何在 SystemVerilog 中创建类队列?
// Define a class with a single string member called "name"
class Fruit;
string name;
function new (string name="Unknown");
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
仿真 log 日志
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.
如何在 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
仿真 log 日志
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.