SystemVerilog中队列的越界访问

SystemVerilog中队列的当前大小可以通过size()函数获得,队列中元素的个数也可以通过队列中最大索引值和最小索引值获得,在使用队列时,我们经常用SystemVerilog提供的各种方法对队列进行访问,但队列同样也支持通过索引的方式进行访问,并且这种方式也会被经常用到,这个时候就有可能出现访问队列时,索引值大于队列的大小范围,产生队列越界访问的情况,从而可能获得不期望的结果。为此,本文通过示例说明通过索引访问队列产生的一些异常情况,队列正常访问操作可参见《SystemVerilog中有界无界的队列》一文。

开始索引等于结束索引

【示例】 

【仿真结果】
示例中,将q_data[5:5]放在了q_data队列的尾部,然后将队列输出可见q_data[5:5]的值为h6,然后在$display语句中将队列的尾部元素弹出,相当于把刚才压入队列尾部的元素取出,并且通过结果可以看到取出的值就是刚才压入的h6。然后再将q_data[5]放在了q_data队列的尾部并且打印出来,可以看到其结果与将q_data[5:5]压入队列一致。其实这是因为在队列或者数组中,如果通过索引访问其中某个元素,当开始索引与结束索引一致时,此时引用该数组元素时可仅使用开始索引或者结束索引之一即可,即arr[n:n] =arr[n]

2 开始索引大于结束索引

示例 


【仿真结果】
示例中,访问队列q_data中片段q_data[4:2],但是在这个片段索引中开始索引为4,大于结束索引2,此时获得的数组片段为空,即访问队列片段时,如果开始索引值大于结束索引值,那么获得的队列片段为空。

3 开始索引小于0

【示例】

【仿真结果】 
示例中,访问队列片段q_data[(-1):2],得到的结果是队列的前三个元素,即与q_data[0:2]相同。这说明,如果访问队列的结束索引位于队列的大小范围内,开始索引小于0,那么实际访问的效果相当于开始索引从0开始

4 结束索引大于$

【示例】

【仿真结果】
示例中,访问队列片段q_data[4:($+1)],得到的结果是队列的最后四个元素,即与q_data[4:$]相同。这说明,如果访问队列的开始索引位于队列大小范围内,结束索引超过队列最后一个元素,那么实际访问的效果相当于结束索引为$

5 开始索引小于0,结束索引大于$

【示例】 

【仿真结果】
 示例中,访问队列片段q_data[(-1):($+1)],得到的结果是队列的最后四个元素,即与q_data[0:$]相同。这说明,如果访问队列的开始索引和结束索引都位于队列大小范围外(开始索引值小于0,结束索引大于$),那么实际访问的效果相当于访问的是整个队列

6 索引为不定态或者高阻态

【示例】

【仿真结果】

示例中,访问队列中元素时,索引为不定态和高阻态,此时返回的值为队列类型logic的默认值x,并没有访问到任何有效元素。这说明,如果访问队列的索引无不定态或者高阻态,那么实际访问的效果相当于访问队列中不存在的元素,返回的数据值为队列类型的默认值

当然除了上述示例的读访问操作外,也可能存在对队列越界或者无效索引的写访问操作。如下例所示。

【示例】索引为不定态或者高阻态时进行写访问操作

【仿真结果】 

示例中,对队列名为q_data,索引为hxhz的元素进行写访问操作,写操作时候通过foreach将队列q_data中的所有元素输出,并输出队列的大小,发现队列的元素个数和值都没有发生变化,再对索引为hxhz的元素进行读访问操作,读出的数值为队列q_data数据类型的默认值,说明前边的写操作根本就没有影响到队列本身,也并没有写入到索引为hxhz的队列元素中,可见对于索引为不定态或者高阻态时进行的写访问操作会被忽略掉。

【示例】索引小于0时进行写访问操作

【仿真结果】


示例中,对队列名为q_data,索引为-1的元素进行写访问操作,写操作时候通过foreach将队列q_data中的所有元素输出,并输出队列的大小,发现队列的元素个数和值都没有发生变化,再对索引为-1的元素进行读访问操作,读出的数值为队列q_data数据类型的默认值,说明前边的写操作根本就没有影响到队列本身,也并没有写入到索引为-1的队列元素中,可见对于索引为小于0的数时进行的写访问操作会被忽略掉。

【示例】索引大于$时进行写访问操作

【仿真结果】 
示例中,对队列名为q_data,索引为$+1的元素进行写访问操作,写操作时候通过foreach将队列q_data中的所有元素输出,此时对发现队列长度增加了一个元素变为了9,新增加的这个元素就是对于索引为$+1的元素进行写访问操作写入的数值,写入操作完成后,新队列的最后一个元素索引仍然为$,但是该索引相对于原队列索引就是$+1,相当于在队列尾部增加了一个元素,这个过程类似于下图。
从示例仿真结果可以看出对于队列索引为$+1的写操作是可以进行的,写入的元素将压入队列尾部,新的队列的最后一个元素就是这个新压入的元素,此时其对应的索引可通过$表示。

通过上述示例中对于队列的各种读写越界访问操作,汇总结论如下:

Ø 在队列或者数组中,如果通过索引读访问其中某个元素,当开始索引与结束索引一致时,此时引用该数组元素时可仅使用开始索引或者结束索引之一即可,即arr[n:n] =arr[n]

Ø 读访问队列片段时,如果开始索引值大于结束索引值,那么获得的队列片段为空。

Ø 如果读访问队列的结束索引位于队列的大小范围内,开始索引小于0,那么实际访问的效果相当于开始索引从0开始

Ø 如果读访问队列的开始索引位于队列大小范围内,结束索引超过队列最后一个元素,那么实际访问的效果相当于结束索引为$

Ø 如果读访问队列的开始索引和结束索引都位于队列大小范围外(开始索引值小于0,结束索引大于$),那么实际访问的效果相当于访问的是整个队列

Ø 如果读访问队列的索引无不定态或者高阻态,那么实际访问的效果相当于访问队列中不存在的元素,返回的数据值为队列类型的默认值

Ø 对于索引为不定态或者高阻态时进行的写访问操作会被忽略掉。

Ø 对于索引为小于0的数时进行的写访问操作会被忽略掉。

Ø 对于队列索引为$+1的写操作是可以进行的,写入的元素将压入队列尾部,新的队列的最后一个元素就是这个新压入的元素,此时其对应的索引可通过$表示。


全部评论
SystemVerilog中队列的越界
点赞 回复 分享
发布于 2022-10-20 15:22 河南

相关推荐

点赞 1 评论
分享
牛客网
牛客企业服务