Title

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.

posted on 2024-05-03 17:25  松—松  阅读(40)  评论(0编辑  收藏  举报

导航