Systemverilog支持集合操作符inside,合理使用inside操作,可以使得编码更为高效和简洁。inside操作符可以方便的比较一个数值、多个可能值或连续区间值之间的关系。它的语法格式为:
inside_expression ::= expression inside {open_range_list}
open_range_list可以是单个取值的列举,也可以是使用[a:b]表达的范围,或者unpacked数组,或者几者的混用组合。open_range_list的值可以重复,所以单个取值和范围取值可以有重叠的。如果[a:b]中左边的值大于右边的值,那么该range会被认为时无效的,没有包含任何value。
示例:
int array[$]='{3,4,5};
if (ex inside {1,2,array,[10:12]}) //same as {1,2,3,4,5,10,11,12}
inside操作符会将左边expression的值与右边open_range_list里的值逐一比较,如果找到匹配的值,返回1,反之返回0。那么inside是如何判断两个值是否相等的呢?我们可以先来看一下systemverilog里支持的三种值比较操作符。
-
Logical equality:==, !=,该运算符中如果运算数包含有x/z态,那么结果就是x态。只有在两边的bit都不包含x/z态,最终结果才会为0(False)或1(True);
-
Case equality:===, !==,该运算符中会把两边运算数的x/z态都考虑进去,最终结果肯定是0或1;
-
Wildcard equality:==?, !=?,该运算符的右边是wildcard匹配,右边操作数的x或z bit对应于左边的bit可以为任何数字,但左边的x或z不能被认为是wildcard。因此该运算符的结果可能有x/0/1三种结果,如果左边的x/z态不能被右边的wildcard匹配,那么结果就是x态,如果左边的x/z态会被右边的wildcard匹配,那么结果就为0/1;
结论:
对于非整形值,inside是采用logical equality(==)运算符来比较的。对于整形值,inside是使用wildcard equality(==?)来比较的,所以open_range_list中值含有的x/z bit不参与比较,但inside左边的x/z仍然是需要比较的。inside没有匹配到相等的值时,如果一些比较结果有x,那么将整体返回1'bx。
例子如下:
logic [2:0] val;
while(val inside {3'b1?1}) //matches 3'b101 ,3'b111 ,3'b1x1 ,3'b1z1
wire r;
assign r=3'bz11 inside {3'b1?1,3'b011}; //r=1'bx