SystemVerilog 教程第二章数据类型:队列

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

SystemVerilog 教程第二章数据类型:队列_第1张图片

队列方法

队列方法示例

除阵列运算符外,队列还可提供多种内置方法。

函数 描述
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 中创建动态阵列队列?

SystemVerilog 教程第二章数据类型:队列_第2张图片

动态阵列队列

// 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.

你可能感兴趣的:(verilog,FPGA,fpga开发)