SV笔记
数据类型
四值逻辑类型:integer、logic、reg、net-type(例如wire、tri)
二值逻辑类型:byte、short int、int、long int、bit
有符号类型:byte、short int、int、long int、integer
无符号类型:bit、logic、reg、net-type(例如wire、tri)
定宽数组:int a[x]; a[] = '{ };
动态数组:int a[]; a = new[x]; a[x] = '{ };
队列: int a[$]; a = {};
logic:任何使用线网的地方均可以使用logic,但要求logic不能有多个结构性驱动,例如在对双向总线建模的时候,需要使用线网类型。
**定宽数组:**int a[5] = '{1,2,3,4,5}
**动态数组:**int a[]; a = new[5]; a.delete(); 动态数组需要new创建,delete删除,其他使用与定宽数组相同
**队列:**int a[$]; a.delete(); 队列需要delete删除,不需要new创建
常用方法:a.insert(pos, data); a.pop_front(); a.pop_back(); a.push_front(data); a.push_back(data)
**关联数组:**bit[63:0] assoc[int], idx=1;
repeat(64) begin assoc[idx]=idx; idx = idx<<1; end
assoc.delete();
数组的方法:
- 数组缩减方法:sum求和、product积、and与、or或、xor异或
- 数组定位方法:
- a.min();
- a.max();
- a.unique();
- a.find with(item>3)
- a.find_first with(item>3)
- a.sum with(item>3)
- a.sum with((item>3)*item)
- 数组的排序
- a.reverse();
- a.sort();
- a.rsort();
- shuffle();
typedef创建新的类型:
parameter OPSIZE=8;
typedef reg[OPSIZE-1:0] opreg_t;
opreg_t op_a,op_b;
使用struct创建新的类型:
typedef struct {bit[7:0] r,g,b;} pixel_s;
pixel_s my_pixel;
枚举类型:
typedef enum {RED, BLUE, GREEN} color;
color c1,c2;
类型转换:
- 静态转换:int’(10.0);
- 动态转换:$cast(a, b);
流操作符:“>>”把数据从左至右变成流,“<<”把数据从右至左变成流
**常量:**const
**字符串:**s = “IEEE”;
常用方法:
- s.getc(pos, s1);
- s.putc(pos, s1);
- s.toupper();
- s.tolower;
- s.substr(start, end);
- 格式化字符串
- $psprintf("%s %5d", s,42);
- $sformatf("%s %5d", s,42);
过程语句和子程序
-
任务、函数以及void函数
忽略函数的返回值:void’(function())
-
ref:
function void print_checksum(const ref bit [31:0] a[]);
systemverilog允许不带ref进行数组参数的传递,这时数组会被复制到堆栈区里。这种操作的代价很高,除非是对特别小的数组。
systemvrilog规定了ref参数智能被用于带自动存储的子程序中。如果你对程序或模块指明了automatic属性,则整个程序内部都是自动存储的。
向子程序传递数组时应尽量使用ref以获取最佳性能。如果你不希望子程序改变数组的值,可以使用const ref修饰。
-
函数声明中,必须声明变量的类型与输入或输出