赞
踩
目录
随机的意义:随着芯片设计规模的增大,编写单一的定向测试来测试功能已经不能满足需求。随机测试相对定向测试可以减少代码量,同时产生的激励更多样,可以找出一些意想不到的缺陷。
约束的意义:只产生随机激励而不对约束进行约束会加大测试时间,产生很多无效的激励。需要对随机激励进行一定约束,定义到感兴趣的点,才能提高测试效率。
对于SV的随机化步骤总结如下。
1.在一个类中封装一些信息,例如data,addr等。
2.然后将其声明为rand 或者randc变量
3.编写约束块
4.例化类后调用randomize() 或是增加内嵌约束。
示例:
- class random_csrt;
- rand bit [31:0] addr; //声明随机变量
- rand bit [31:0] data;
-
-
- constraint c_1{
- addr < 100 ;
- data > 10 ;
- } //对变量进行约束,约束块是声明语句,不需要加;
-
- endclass
-
- random_csrt a;
-
- initial begin
- a = new(); //例化
- assert(a.randomize()) //随机化 失败返回0成功返回1
- else $fatal(0,"randomize fatal");
- end
约束块中只能包含表达式(<、<= 、== 、>= 、>)等。对于赋值操作,需要用==来代替(约束某个变量 为固定值 等价于赋值)。
示例:
- class cstr_blk;
- rand bit [3:0] low,mid,high;
-
- constraint error_cstr{
- low < mid < high
- } //错误
-
-
- constraint right_cstr{
- low < mid ;
- mid< high ;
- } 正确
- endclass
-
- /*可能结果
-
- 36 230 300
- 230 36 77
-
- */
约束块中无法进行连续约束,上述代码块先计算(low<mid),返回的值为0 或1。在对0(1) < high 进行判断,最后得到结果与预期不符,实现上并没有受到约束。
对于约束设定其权重,进一步将约束限制到感兴趣的点。
示例:
- class dist_cstr;
-
- rand bit [31:0] drv,rec;
-
- constraint cstr_d{
-
- drv dist {0:= 40,[1:3] := 60}; //0 概率为40/(40+60*3)
-
- rec dist {0:/ 40,[1:3] :=/60}; //0 概率为40/(40+60)
-
- }
-
- endclass
在值的集合中进行约束。
示例:
- class inside_cstr;
-
- rand bit [31:0] drv,rec;
-
- constraint cstr_i{
- drv inside {[1:100]} ; //将drv的值限定在1-100的范围内
- }
-
- constraint cstr_r{
- ! (rec inside {[1:100]}) ; // 0<rec<1 100<rec<2^32-1;
- }
- endclass
使用 -> 或if-else进行约束。
示例:
- class cndt_cstr;
-
- ……
-
- constraint a_cstr {
- (open_mode) -> data inside {[1:10]} ;
- }
-
- constraint b_cstr {
- if (open_mode)
- addr inside {[1:100]} ;
- else
- addr inside {[3:40]} ;
- }
- endclass
sv允许使用randomize()with 来增加额外的约束。
示例:
- class transaction ;
-
- rand bit [31:0] addr,data;
- constraint cstr {
- addr inside {[1:100]};
- }
- endclass
-
-
- transaction t;
-
- initial begin
- t = new();
- void'(t.randomize() with {addr >= 50 ;});
- $display("addr is %0d",t.addr);
- end
通过soft来作为软约束的关键词,若新的约束与软约束冲突,则按照新随机化的约束的值来限制,若软约束不冲突则是两个约束的交集。
示例:
- class transaction ;
-
- rand bit [31:0] addr,data;
- constraint cstr {
- soft addr inside {[1:100]};
- }
- endclass
-
-
- transaction t;
-
- initial begin
- t = new();
- void'(t.randomize() with {addr == 150 ;} ); //与软约束冲突,现有约束成功。
- $display("addr is %0d",t.addr); //打印结果: addr is 150
- end
约束还可以对随机化数组进行约束。
示例:
- class dyn_cstr;
- rand bit [31:0] dyn[];
-
- constraint d_size {
- dyn.size() inside {[1:10]}; //动态数组大小为1-10
- dyn.sum() < 1000 ; //约束数组元素的总和
- foreach(dyn[i]) dyn[i] < 100; //约束每个元素
- };
- endclass
-
- dyn_cstr d;
-
- initial begin
- string s;
- d = new();
- assert(d.randomize());
- foreach(d.dyn[i])
- s = {s,$sformatf("%0d ",d.dyn[i])};
- $display("sum = %0d , val = %s",d.dyn.sum(),s); //打印结果 sum = 110 , val = 27 33 50
-
- end
-
- endmodule
产生唯一元素值的数组
示例:
- class unique_array;
- rand bit [7:0] unq_array[32];
-
- constraint c{
- foreach(unq_array[i]) //对数组中每个元素
- foreach(unq_array[j])
- if(i!= j) //除了自身
- unq_array[i] != unq_array[j] ;
- }
-
- endclass
-
-
- class unique_array_1;
- rand bit [7:0] unq_array[32];
-
- constraint c_1{ unique {unq_array}; } //使用关键词 unique 更简洁
-
- endclass
$random() ——返回32位有符号随机数
$urandom() ——返回32位无符号随机数
$urandom_range() —— 在指定范围内的平均分布
以及调用系统函数std::randomize()进行随机化。
constraint_mode() 控制类的约束;
rand_mode ()来控制变量的约束;
randmozide(变量名)选择随机化变量;
示例:
- class transaction ;
-
- rand bit [31:0] addr ,data ;
- constraint cstr_s {addr inside {[1:10]};
- data inside {[1:100]};};
- constraint cstr_l {addr inside {[10:100]};
- data inside {[100:10000]};};
-
- endclass
-
-
- transaction t;
-
- initial begin
- t = new();
- t.cstr_s.constraint_mode(0);
- assert(t.randomize());
- $display("addr is %0d , data is %0d",t.addr,t.data); // 打印结果:addr is 75 , data is 1069 cstr_l 起效
- t.constraint_mode(0);
- t.cstr_s.constraint_mode(1);
- t.data.rand_mode(0);
- t.data = 6;
- assert(t.randomize());
- $display("addr is %0d , data is %0d",t.addr,t.data); // 打印结果:addr is 5 , data is 6 cstr_s 起效 data没有被randomize 这里若不给data赋值 随机化会失败,虽然关闭了随机化 当上次的data是1096 不符合约束的求解。
-
- end
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。