IC验证学霸笔记3——SV 数据类型小结
1.内建数据类型
相比于Verilog 将寄存器类型reg和net(线网)类型区分如此清楚,在SV中引入了logic数据类型。任何使用线网的地方均可以使用logic,但要求logic不能有多个结构性的驱动,例如在对双向总线建模时。此时,需要使用线网类型。四值逻辑类型有:logic,reg,wire,integer;
二值逻辑类型有:bit, byte,int,shortint,longint;
按照有无符号还可以分为:
有符号类型:integer, byte, int,shortint,longint;
无符号类型:logic,reg,wire,bit;
注意:
在遇到变量类型时,应注意它们的符号类型和逻辑类型,在变量的运算中,尽可能避免两种不一致的变量进行操作。
1.对于有符号类型,例如:byte变量的最大值是127,而不是255(它的范围是-128–127)。
2.对于逻辑变量类型,四值逻辑类型默认值为X,二值逻辑类型的默认值为0。
2.定宽数组
2.1.定宽数组的声明与赋值
注意:当测试平台通过存储器数据的变化来唤醒时,通过@操作符实现,这个操作符只能用于标量或者合并数组。例如上边代码中的非合并数组array,只可以将array[0]或者1w作为敏感信号,但不能用整个array数组,除非把它扩展成:@(array[0] or array[1] or array[2])。
可能用到的系统函数:
$dimensions(array_name) :返回数组的维度
$left(array_name,dimensions) :返回数组指定维度最左边索引值
$size(array_name,dimensions) :返回数组指定维度的大小
$bits(expression) :返回数组存储比特数
2.2 基本的数组操作----复制和比较
2.2 基本的数组操作----for & foreach
SV中$size函数返回数组的宽度。在foreach循环中,只需要指定数组名,并在其后的()中给出索引变量,系统便会自动遍历数组中的元素,索引变量自动声明,并只在循环中有效。3.动态数组
动态数组在声明时使用空的下标[ ],这意味着数组的宽度不在编译时给出,而在程序运行时指定。数组在最开始是空的,所以必须调用new[ ]操作符来分配空间,同时在方括号中传递数组宽度。 动态数组有一些内建的子程序,例如delete和size。
只要基本数据类型相同,比如都是int,定宽数组和动态数组之间可以相互赋值,在元素数目相同的情况下,可以把动态数组的值复制给定宽数组。也可以将定宽数组的值复制给动态数组,此时,SV会调用构造函数new[ ]来分配空间并赋值。
只要基本数据类型相同,比如都是int,定宽数组和动态数组之间可以相互赋值,在元素数目相同的情况下,可以把动态数组的值复制给定宽数组。也可以将定宽数组的值复制给动态数组,此时,SV会调用构造函数new[ ]来分配空间并赋值。
4.队列
队列的声明是使用带有美元符号的下标[$],但不需要使用构建函数new[ ]来开辟空间,。
队列的操作:
队列中的元素是连续存放的,所以队列的初始化赋值用{},而不加'。同样由于其是连续存放数据,所以,在队头和队尾pop/push数据非常方便,执行速度很快,这与队列的长度没有关系。但是在队列中间增加或者删除数据则需要搬移腾出空间,所以该操作耗时与队列的长度有关,应呈现线性相关。另可将动态数组,定宽数组的值复制给队列。
5.关联数组
针对与对一个非常大的地址空间寻址时,可利用关联数组,来保存这些稀疏矩阵的元素,只为实际写入的元素分配空间。 关联数组采用在 [ ]中放置数据类型的形式来声明,例如:[int], 可通过X.exists()索引某一元素是否存在。
6.数组的方法
6.1 缩减方法
所谓缩减方法是将一个数组变成一个值,常见的方法有sum(和),product(积),and(与),or(或)和xor(异或),对于以上运算,要特别注意变量的位宽。SV中没有提供专门从一个数组中随机挑选单个元素的方法,对于定宽数组,队列,动态数组和关联数组可以采用$urandom_range($size(array)-1),而对于队列和动态数组还可以采用$urandom_range(array.size()-1).6.2 定位方法
1)定位方法可以帮助查找数组中的最大值,特定值之类的信息,但是注意这些方法的返回值通常是一个队列。 2)find定位方法:
当把缩减方法与条件语句with结合使用时,sum操作符返回的结果是条件为真时的次数。
6.3排序方法
所谓排序方法是对原有数组的数据进行重新定位的方法。
X.reserve() 倒序 不能带with使用
X.sort() 从小到大排序
X.rsort() 从大到小排序
X.shuffle() 随机 不能带with使用
7. typedef 自定义方法
7.1使用struct创建新类型
Verilog最大的缺陷就是没有数据结构,而在SV中可以通过struct语句创建数据结构,struct为一个数据的集合,所以它是可综合的。伴随着typedef可以用来创建新的类型,并利用新类型声明更多的变量。 为共享该类型,通过typedef来创建新类型
7.2枚举类型
枚举创建一种强大的变量类型,它仅限于一些特定名称的集合,例如指令中的操作码或者状态机的状态名。例如ADD,MOVE这些名称有利于编写和维护代码。枚举类型enum经常和typedef搭配使用,由此便于用户自定义枚举类型共享使用 。 枚举值缺省是 为 从0开始递增的整数,如上缺省默认INIT为0,DECODE为1,IDLE为2。也可以自己定义,如下:
如果没有特别指出,枚举类型会被当成int类型,由于枚举类型缺省值为0,所以在给枚举常量赋值赋值时要小心。
枚举类型的子程序:
1. first() 返回第一个枚举常量;
2. last() 返回最后一个枚举常量;
3. next() 返回下一个枚举常量;
4. next(N) 返回后N个枚举常量;
5. prev() 返回前一个枚举常量;
6.prev(N) 返回前N个枚举常量;
当到达枚举常量列表的头和尾时,函数next和prev会自动环形绕回。
字符串常见的几种操作:
get(N):返回位置N上的字节
toupper 返回一个所有字符大写的字符串
tolower返回一个小写的字符串
{ }用于串接字符串
putc(M,C)把 字节C写到字符串的M位上
substr(start,end)提取出从位置start到end的所有字符。
1. first() 返回第一个枚举常量;
2. last() 返回最后一个枚举常量;
3. next() 返回下一个枚举常量;
4. next(N) 返回后N个枚举常量;
5. prev() 返回前一个枚举常量;
6.prev(N) 返回前N个枚举常量;
当到达枚举常量列表的头和尾时,函数next和prev会自动环形绕回。
8. 字符串
与C不同,字符串的结尾并不带标示符null,所有尝试使用字符“\0”的操作会被忽略。字符串采用动态存储方式,所以不用担心存储空间会被用完 。字符串常见的几种操作:
get(N):返回位置N上的字节
toupper 返回一个所有字符大写的字符串
tolower返回一个小写的字符串
{ }用于串接字符串
putc(M,C)把 字节C写到字符串的M位上
substr(start,end)提取出从位置start到end的所有字符。
注:优秀验证学员随堂笔记,已经征求到学生的同意,会持续给牛友们分享!
大家看完记得 一键三连!多多支持