当前位置:   article > 正文

systemverilog-随机约束_systemverilog assert randomize

systemverilog assert randomize

目录

1.随机约束的意义

2.随机化步骤

3.随机化形式

3.1 表达式约束

3.2 权重约束

3.3 inside运算符

3.4 条件约束

3.5 内嵌约束

3.6 软约束

3.7 数组约束

3.8 其他约束形式

4 约束的解

5 约束的开关


1.随机约束的意义

随机的意义:随着芯片设计规模的增大,编写单一的定向测试来测试功能已经不能满足需求。随机测试相对定向测试可以减少代码量,同时产生的激励更多样,可以找出一些意想不到的缺陷。

约束的意义:只产生随机激励而不对约束进行约束会加大测试时间,产生很多无效的激励。需要对随机激励进行一定约束,定义到感兴趣的点,才能提高测试效率。

2.随机化步骤

对于SV的随机化步骤总结如下。

1.在一个类中封装一些信息,例如data,addr等。

2.然后将其声明为rand 或者randc变量

3.编写约束块

4.例化类后调用randomize() 或是增加内嵌约束。

示例:

  1. class random_csrt;
  2. rand bit [31:0] addr; //声明随机变量
  3. rand bit [31:0] data;
  4. constraint c_1{
  5. addr < 100 ;
  6. data > 10 ;
  7. } //对变量进行约束,约束块是声明语句,不需要加;
  8. endclass
  9. random_csrt a;
  10. initial begin
  11. a = new(); //例化
  12. assert(a.randomize()) //随机化 失败返回0成功返回1
  13. else $fatal(0,"randomize fatal");
  14. end
  • rand和randc的区别,rand等每次抽一幅新的扑克牌,每次的随机值可以一样。randc等于从一副扑克牌中抽牌,每次抽出来的都不一样。
  • 不能在类的构造函数里随机化对象,因为随机化前可能需要打开或关闭约束,改变权重以及添加新的约束。

3.随机化形式

3.1 表达式约束

 约束块中只能包含表达式(<、<= 、== 、>= 、>)等。对于赋值操作,需要用==来代替(约束某个变量 为固定值 等价于赋值)。

示例:

  1. class cstr_blk;
  2. rand bit [3:0] low,mid,high;
  3. constraint error_cstr{
  4. low < mid < high
  5. } //错误
  6. constraint right_cstr{
  7. low < mid ;
  8. mid< high ;
  9. } 正确
  10. endclass
  11. /*可能结果
  12. 36 230 300
  13. 230 36 77
  14. */

约束块中无法进行连续约束,上述代码块先计算(low<mid),返回的值为0 或1。在对0(1) < high 进行判断,最后得到结果与预期不符,实现上并没有受到约束。

3.2 权重约束

对于约束设定其权重,进一步将约束限制到感兴趣的点。

示例:

  1. class dist_cstr;
  2. rand bit [31:0] drv,rec;
  3. constraint cstr_d{
  4. drv dist {0:= 40,[1:3] := 60}; //0 概率为40/40+60*3
  5. rec dist {0:/ 40,[1:3] :=/60}; //0 概率为40/40+60
  6. }
  7. endclass
  • := 等于范围内每一份权重都相等,而:/权重均分到范围内每一个值。

3.3 inside运算符

在值的集合中进行约束。

示例:

  1. class inside_cstr;
  2. rand bit [31:0] drv,rec;
  3. constraint cstr_i{
  4. drv inside {[1:100]} ; //将drv的值限定在1-100的范围内
  5. }
  6. constraint cstr_r{
  7. ! (rec inside {[1:100]}) ; // 0<rec<1 100<rec<2^32-1;
  8. }
  9. endclass

3.4 条件约束

使用 -> 或if-else进行约束。

示例:

  1. class cndt_cstr;
  2. ……
  3. constraint a_cstr {
  4. (open_mode) -> data inside {[1:10]} ;
  5. }
  6. constraint b_cstr {
  7. if (open_mode)
  8. addr inside {[1:100]} ;
  9. else
  10. addr inside {[3:40]} ;
  11. }
  12. endclass

3.5 内嵌约束

sv允许使用randomize()with 来增加额外的约束。

示例:

  1. class transaction ;
  2. rand bit [31:0] addr,data;
  3. constraint cstr {
  4. addr inside {[1:100]};
  5. }
  6. endclass
  7. transaction t;
  8. initial begin
  9. t = new();
  10. void'(t.randomize() with {addr >= 50 ;});
  11. $display("addr is %0d",t.addr);
  12. end
  • 内嵌约束 with里的范围是transaction类的,因此不需要声明t.addr,而对于打印时,需要声明t.addr 才能找到addr变量。

3.6 软约束

通过soft来作为软约束的关键词,若新的约束与软约束冲突,则按照新随机化的约束的值来限制,若软约束不冲突则是两个约束的交集。

示例:

  1. class transaction ;
  2. rand bit [31:0] addr,data;
  3. constraint cstr {
  4. soft addr inside {[1:100]};
  5. }
  6. endclass
  7. transaction t;
  8. initial begin
  9. t = new();
  10. void'(t.randomize() with {addr == 150 ;} ); //与软约束冲突,现有约束成功。
  11. $display("addr is %0d",t.addr); //打印结果: addr is 150
  12. end

3.7 数组约束

 约束还可以对随机化数组进行约束。

示例:

  1. class dyn_cstr;
  2. rand bit [31:0] dyn[];
  3. constraint d_size {
  4. dyn.size() inside {[1:10]}; //动态数组大小为1-10
  5. dyn.sum() < 1000 ; //约束数组元素的总和
  6. foreach(dyn[i]) dyn[i] < 100; //约束每个元素
  7. };
  8. endclass
  9. dyn_cstr d;
  10. initial begin
  11. string s;
  12. d = new();
  13. assert(d.randomize());
  14. foreach(d.dyn[i])
  15. s = {s,$sformatf("%0d ",d.dyn[i])};
  16. $display("sum = %0d , val = %s",d.dyn.sum(),s); //打印结果 sum = 110 , val = 27 33 50
  17. end
  18. endmodule

产生唯一元素值的数组

示例:

  1. class unique_array;
  2. rand bit [7:0] unq_array[32];
  3. constraint c{
  4. foreach(unq_array[i]) //对数组中每个元素
  5. foreach(unq_array[j])
  6. if(i!= j) //除了自身
  7. unq_array[i] != unq_array[j] ;
  8. }
  9. endclass
  10. class unique_array_1;
  11. rand bit [7:0] unq_array[32];
  12. constraint c_1{ unique {unq_array}; } //使用关键词 unique 更简洁
  13. endclass

3.8 其他约束形式

$random()  ——返回32位有符号随机数

$urandom()  ——返回32位无符号随机数

$urandom_range()  —— 在指定范围内的平均分布

以及调用系统函数std::randomize()进行随机化。

4 约束的解

  • 约束是并行的,取所有约束的交集,若有一个约束不满足,则随机化失败。
  • 约束是双向的,即若 约束为{(a == 0) ->( c == 0) } 那么当 c 不等于 0时,a也不等于0。

5 约束的开关

constraint_mode() 控制类的约束;

rand_mode ()来控制变量的约束;

randmozide(变量名)选择随机化变量;

示例:

  1. class transaction ;
  2. rand bit [31:0] addr ,data ;
  3. constraint cstr_s {addr inside {[1:10]};
  4. data inside {[1:100]};};
  5. constraint cstr_l {addr inside {[10:100]};
  6. data inside {[100:10000]};};
  7. endclass
  8. transaction t;
  9. initial begin
  10. t = new();
  11. t.cstr_s.constraint_mode(0);
  12. assert(t.randomize());
  13. $display("addr is %0d , data is %0d",t.addr,t.data); // 打印结果:addr is 75 , data is 1069 cstr_l 起效
  14. t.constraint_mode(0);
  15. t.cstr_s.constraint_mode(1);
  16. t.data.rand_mode(0);
  17. t.data = 6;
  18. assert(t.randomize());
  19. $display("addr is %0d , data is %0d",t.addr,t.data); // 打印结果:addr is 5 , data is 6 cstr_s 起效 data没有被randomize 这里若不给data赋值 随机化会失败,虽然关闭了随机化 当上次的data1096 不符合约束的求解。
  20. end

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号