System Verilog Basic(一)
1、接口
使用方法:
a.首先例化一个接口,将testbench里的时钟模块传进来;
b.例化一个testcase,将接口传到testcase里面;
c.将DUT连接到接口上。
例子:
1 router_io top_io(SystemClock); //——>a 2 test t(top_io); //——>b 3 router dut( 4 .reset(top_io.reset_n), //——>c 5 .clock(top_io.clock) 6 );
即testcase驱动interface,interface驱动dut。
2、在sv中,logic类型替代了reg和wire类型数据。
3、enum
默认数据类型是int
格式:typedef enum [data_type]{name constant} enumtype;
例子:
1 typedef enum{IDLE,TEST,START} state;//没有定义data_type,默认是int 2 enum bit[2:0] {s0='b001,s1='b010,s2='b100} st;
4、固定数组
格式:type array_name[size]{initial value}
注:$dimensions()函数,用于求数组的维度;
例子:
1 int c[2][3]='{{3,7,1},{5,1,9}};//2行3列,2是第一维,3是第二维 2 bit [31:0] a[2][3]=c; //[31:0]第三维,定义了一个三维数组a,并将c的值赋给a; 3 for(int i=0;i<$dimensions(a)); 4 $dispaly($size(a,i+1)); //2,3,32
5、动态数组
格式:typearray_name[][=initial_value]
例子:
1 reg [7:0] array[]=new[16]; 2 reg [7:0] ID,data_array; 3 ID = new[100]; 4 data_array=new[$size(ID)](ID);//给data_array分配一个和ID一样大的空间,并将ID的内部值复制给data_array 5 data_array=ID;//直接复制
6、队列
格式:type array_name[$][initial_value]
7、联合数组
格式:type array_name[index_type];
type array_name[*];
注:index——>索引可以是数字、字符串和类
例子:
1 integer ID_array[*]; 2 ID_array[71]=99; //给地址71赋值99 3 ID_array.delete(71); //直接删除元素
8、Array Method
a.function array_type[$] array.find() with (expression) //找到数组中匹配的元素,并将结果存到队列中
b.function int_or_index[$] array.find_index() with (expression) //找出数组中匹配的元素,并将数组的索引存到队列中
注:如果找不到匹配值,则返回空队列。
Example:
1 program test; 2 bit [7:0] SQ_array[$] = {2,1,8,3,5}; 3 bit [7:0] SQ[$]; 4 int idx[$]; 5 SQ=SQ_array.find() with (item > 3);//SQ[$] contains 5,8 6 idx=SQ_array.find_index() with (item > 3);//idx[$] contains 2,4 7 endprogram
c.function array_type[$] array.find_first()[with (expression)]
//First element satisfying the with expression is return
//If with expression is omitted,first element is return
//First matching element is return in array_type[0]
d. function int_or_index_type[$] array.find_first_index [with (expression)]
//First index satisfying the with expression is return
//If with expression is omitted,first index is return
//First matching index is return in int_or_index_type[0]
注:如果找不到匹配值,则返回空队列。
Example:
1 program test; 2 int array[]=new[4]; 3 int idx[$],value[$]; 4 foreach(array[i]) 5 array[i] = 4-i//{4,3,2,1} 6 value = array.find_first() with (item > 3);//value[0]=4 7 8 idx = array.find_first_index() with (item < 0);//idx.size()=0 9 endprogram 10 11 Examples of other array methods: 12 find_last(),find_last_index(),unique(),unique_index, 13 min(),max(),reverse(),sort(),rsort(),shuffle() 14 15 program test; 16 initial begin 17 int data[]=new[10],data_min[$],data_max[$]; 18 foreach(data[i]) begin 19 data[i] = 255 >> 1; 20 %dispaly("data[%0d] = %0d",i,data[i]); 21 end 22 $display("size of data array=%0d",data.size()); 23 $display("sum of array content=%0d",data.sum()); 24 data_max=data.max(); 25 data_min=data.min(); 26 $display("smallest value is =%0d",data_min[0]); 27 $display("largest value is = %0d",data_max[0]); 28 end 29 endprogram
9、System Function:Randomization
a.$random:返回一个32位的有符号随机数
方法:$random(seed):set random seed for $random,seed不同,返回不同的随机数;
b.$urandom:返回一个32位的无符号随机数
方法:$urandom(seed):set random seed for $random,seed不同,返回不同的随机数;
c.urandom_range():指定无符号随机数的范围
d.randcase:选择一个可执行语句
1 randcase 2 10:f1(); 3 20:f2();//f2() is twice as likely to be executed as f1() 4 50:x=100; 5 30:randcase ... endcase;//randcase can be nested(嵌套) 6 endcase
10、用户自定义类型:
a.Use typedef to creat a synonym for another type
1 typedef bit [31:0] uint; 2 typedef bit [0:5] bsix_t;//define new type 3 bsix_t my_var; //creat 6-bit variable
b.Use<type>'(<value>|<variable>) to dynamically convert data types
1 typedef bit [31:0] uint; 2 bit [7:0] payload[]; 3 int temp = $random; 4 payload = new[(temp%3)+2]; //(0,1,2,3,4) 5 payload = new[(uint'(temp)%3)+2];//(2,3,4) 6 payload = new[(unsigned'(temp)%3)+2];//{2,3,4}
11、Know your operators !!!
VCS对于含有x的运算结果返回x,如果此时用x去判断的话,VCS会不知道怎么去判断,应避免这种写法:
1 reg [3:0] sample,rwf_data; 2 sample = dut.cb.dout[3:0]; 3 if(sample != ref_data) $display("Error!"); //对x无法控制 when sample = 4'b101x & ref_data = 4'b1010,VCS无法判断 4 else $display("Pass!");
//应使用下面的方法
1 sample = dut.cb.dout[3:0]; 2 if(sample == ref_data); 3 else $display("Erros!");
12、函数和任务
区别:函数内部不消耗时间,任务内部可以消耗时间,函数不能调用任务,任务可以调用函数;
const ref——>只读取值,不做改变
task里可以使用ref传递参数:
1 task print_sum(ref integer a[],input int start=0);//ref将数组的地址传进来,此时如果外面的操作对此数组影响,此值也变化,它的变化也影响原有的值 2 //start=0 默认参数定义,调用此任务是可以task(a); 3 automatic int sum = 0;//声明动态变量,每调用一次,sum的值都是变化的 4 for(int j = start;j<a.size();++) 5 sum += a[j]; 6 $display("sum of array is %0d",sum); 7 endtask 8 ... 9 print_sum(my_array);
Function Example:
1 function automatic int factorial(int n);//function只有输入没有输出,但是有返回值,返回值就是函数名 2 satic int shared_value = 0; 3 if(n<2) return(1); 4 else return(n*factorial(n-1)); 5 endfunction 6 ... 7 result = factorial(my_valeu);
注:task缺省的参数默认是 logic 输入:
1 task my_task(a,b,output bit [15:0] u,v,const ref byte c[]);//a,b默认为logic 输入