SystemVerilog中有界无界的队列
1 队列的声明方式
[data_type] name_of_queue[$];
其中
data_type:队列中元素的类型
name_of_queue:队列名
从声明方式可以看出,队列与其他数组的一个显著区别是队列声明时其大小是通过$指定的。通过使用$可以指定队列为有界队列和无界队列。我们先来了解下无界队列。无界队列指的是没有设置固定大小的队列。声明时仅在队列名后的中括号中写上$即可。如下例所示。
示例中,q_data1和q_data2均为无界队列,q_data1中元素为2bit宽,q_data2中元素为int型,q_data1和q_data2分别采用了不同的初始化方式,q_data1在队列声明时并没有初始化,而是在过程块中对其进行了初始化,q_data2在声明的同时完成了初始化。并且示例中,当访问q_data1[5]和q_data2[9]时,因为这两个元素在队列里边并没有分配值,所以返回的值为队列类型的默认值。
2 队列操作的方法
对于队列的操作一般主要有增加队列元素、删除队列元素、清空队列等,SystemVerilog为实现这些操作提供了一堆方法,下面我们将分别示例说明。
【示例】使用SystemVerilog提供的函数
函数原型如下表所示:
函数名 | 说明 |
function int size(); | 返回队列中元素的个数,如果为0表示队列为空 |
function void insert(input integer index,input element_t item); | 在指定的index处插入元素item |
function void delete([input integer index]); | 删除指定index位置的元素,如果不指定index则删除整个队列中所有元素 |
function element_t pop_front(); | 返回队列中的第一个元素,并在队列中删除该元素 |
function element_t pop_back(); | 返回队列中的最后一个元素,并在队列中删除该元素 |
function void push_front(input element_t item); | 在队列头插入一个元素item |
function void push_back(input element_t item); | 在队列尾插入一个元素item |
除了上例中使用SystemVerilog提供的丰富函数可以实现对于队列的操作外,还可以使用数组拼接操作实现和上例使用函数一样的效果,如下例。
【示例】使用数组拼接操作
3有界队列
与无界队列对应的是有界队列,有界队列在声明的时候需要指定队列的边界,声明格式如下:
[data_type] name_of_queue[$:m_size];
其中
m_size+1:队列中元素最大个数,这里的$表示队列的起始位置
【示例】
示例中,当使用push_back向队列尾部增加元素时,该操作将被忽略掉,原队列中的内容不受影响。当使用push_front向队列首部增加元素时,该元素将被压入队列,与此同时,队列尾部的最后一个元素将被丢弃,即对于有界队列的压入元素的操作不会改变原队列的大小。无界队列相对于有界队列来说,主要区别是其中元素可以根据需要向队列中添加而不会产生溢出和丢弃现象,而有界队列进行访问时,如果操作不当,将会导致压入失败或者元素丢失。
上文通过示例介绍了对队列进行操作可以通过SystemVerilog中提供的函数实现也可以通过数组元素的拼接操作实现,并且通过示例了解了无界队列和有界队列声明方式差异以及使用上的差异,还了解了访问队列之外空间的话,返回的值由数组类型的默认值决定。