五星上将麦克阿瑟曾经说过:这是我看过最清晰的Systerm Verilog约束文章。
目录
文章难免有些纰漏,也欢迎大家批评指正。共同进步!约束对于仿真的重用很大,同时,也会经常的用到。本文简单的做了一下整理。
0 介绍
IC验证工程师,如果想要做好验证这项工作。那么他必须要学会使用System Verilog的约束,只有学会用约束,后面的验证工作才能有效地开展。
毕竟定向case很难发现芯片中存在的问题。只有通过随机约束,才能让仿真工作变得更有意义。话不多说,下面开始我们的正文。
采用受约束的随机测试法(CRT)自动产生测试集。System Verilog中的随机化。
1. 常数约束
第一种约束:固定值约束
rand bit [7:0] var_a1;
//1.1 fixed value
constraint var_a1_c{
var_a1 == 100;
}
第二种约束:(0~255中取值)
rand bit [7:0] var_a2;
第三种约束:(双向验证)
rand bit [7:0] var_a3[2];
constraint var_a3_c{
var_a3[0] > 100;
var_a3[0] <= var_a3[1];
var_a3[1] < 120;
var_a3[0]+var_a3[1] == 230;
}
可以知道var_a3[0]的取值为100<~<=120,var_a3的取值为<120,且它们之和必须等于230.
第四种约束:(内嵌约束)
rand bit [7:0] var_a4[4];
constraint var_a4_0_c{
var_a4[0] inside{[10:20]};
}
//1.
可以知道取值的范围是10<=~<=20
第五种约束:(权重分布)
rand bit [7:0] var_a5[3];
constraint var_a5_0_c{
var_a5[0] dist {0:=20,[1:5]:=50,[6:10]:=10};
}
20+50*5+5*10=320
0:20/320;
1:50/320
2:50/320
3:50/320
4:50/320
5:50/320
6:10/320
7:10/320
8:10/320
9:10/320
10:10/320
也可以理解为概率的分布。
还有这种分布:
constraint var_a5_1_c{
var_a5[1] dist {0:/20,[1:5]:/50,[6:10]:/30};
}
20+50+30=100
0:20/100
1:10/100
2:10/100
3:10/100
4:10/100
5:10/100
6:6/100
7:6/100
8:6/100
9:6/100
10:6/100
第六种约束:条件约束
rand bit [7:0] var_a6[3];
rand bit var_a6_en[3];
constraint var_a6_1_c{
//var_a6_en[0] == 0;
var_a6[0] inside{[100:200]} -> var_a6_en[0] == 1;
}
结果如下:
第七种约束:给bit位赋值
rand bit [7:0] var_a7;
constraint var_a7_c{
var_a7[1:0] == 0;
var_a7[7:2] >= 4;
var_a7[7:2] <= 7;
}
第八种约束:solve ... before
这样执行就有了先后顺序。先执行var_a8_en,再执行var_a8。所以说还是要规范做事。
rand bit [7:0] var_a8;
rand bit var_a8_en;
constraint var_a8_c{
var_a8 inside{[1:200]};
(var_a8_en == 1) -> var_a8 inside{[1:5]};
solve var_a8_en before var_a8;
}
第九种约束:洗牌约束
这种约束还是比较好的,尤其是ram的地址的约束场景。
randc bit [3:0] var_a9;
constraint var_a9_c{
var_a9 inside{[1:9]};
}
第十种约束:软约束
randomize() 函数遇到约束方面的问题时返回0.
rand bit [7:0] var_aa;
//1.10 soft
constraint var_aa_c{
soft var_aa inside{[10:100]};
}
...
assert(a_i.randomize() with{var_aa == 5;}) else $display("a_i randomize failed");
假设外界的值是5,那么最终的结果也会是5。
第十一种约束:判断约束
bit var_ab_cond;
//1.11 condition
constraint var_ab_c{
if(var_ab_cond) var_ab inside{[10:100]}; else var_ab inside{[100:200]};
}
第十二种约束:函数约束
下面的这个函数就是数1的个数。
function int count_ones(bit [15:0] a);
int rst = 0;
for(rst = 0; a !=0; a>>=1)begin
rst += (a & 1'b1);
end
return rst;
endfunction
constraint var_ac_c{
var_ac[0] >0 ;
var_ac[1] == var_ac[0];
var_ac_len[0] == count_ones(var_ac[0]);
var_ac_len[1] == $countones(var_ac[1]);
}
2. 数组约束
rand bit [7:0] var_b1[];
rand bit [7:0] var_b2[10];
rand bit [3:0] var_b3[16];
rand bit [3:0] var_b4[][];
rand bit [7:0] var_b5[$];
第一种约束:动态约束
约束了数组的个数,以及加起来的总数。
constraint var_b1_c{
var_b1.size inside{[2:10]};
var_b1.sum < 1024;
foreach (var_b1[i]){
var_b1[i] inside {[100:200]};
}
}
第二种约束:排序
constraint var_b2_c{
foreach (var_b2[i]){
if(i >0){
var_b2[i] > var_b2[i-1];
}
}
}
第三种约束:唯一约束
constraint var_b3_c{
unique {var_b3[0:14]};
}
第四种约束:多维数组约束
constraint var_b4_c{
var_b4.size inside{[2:10]};
foreach(var_b4[i]){
var_b4[i].size inside{[2:4]};
}
foreach(var_b4[i,j]){
var_b4[i][j] inside{[10:12]};
}
}
第五种约束:队列约束
constraint var_b5_c{
var_b5.size() inside {[4:6]};
}
第六种约束:Static Arrays约束
Randomization of static arrays are straight-forward and can be done similar to any other type of SystemVerilog variable.
第七种约束:Static Arrays约束
Dynamic arrays are arrays where the size is not pre-determined during array declaration.These arrays can have variable sizeas new members can be added to the array at any time.
Consider the example below where we declare a dynamic array as indicated by the empty square brackets []of typerand . A constraint is defined to limit the size of the dynamic array to be somewhere in between 5 and 8.Anotherconstraint is defined to assign each element in the array with the value of its index.
3. 类的约束
下面是一个带有随机变量和约束的类,以及使用这个类的测试平台代码。
可以看到的是E_cfg2种嵌套E_cfg1。
class E_cfg1;
rand bit [7:0] var_e11;
constraint var_e11_c{
var_e11 == 100;
}
endclass
class E_cfg2;
rand bit [7:0] var_e21;
rand E_cfg1 ecfg1;
constraint var_e21_c{
var_e21 == 6;
}
function new;
ecfg1 = new();
endfunction
function print_me();
$display("var_e21=%d",var_e21);
$display("var_e11=%d",ecfg1.var_e11);
endfunction
endclass
4. 约束高级用法
function void pre_randomize();
$display("This function will be called before randomize");
endfunction
function set_var_c1_max();
clean_var_c1_wgt();
WGT_C1_MAX = 1;
endfunction
function void post_randomize();
$display("This function will be called after randomize");
if(var_c1 == 20) begin
var_c2 = $urandom_range(20);
end
endfunction
Callback回调函数!就是在randomize之前可以先执行pre_randomize,同样,randomize之后也可以执行post_randomize. 就好比做事情有了先后的顺序一样。
5. 静态约束和动态约束
在SV/V语言中,定义的变量默认都是静态的。Class中定义的变量都是动态的。
如果在SV中想要用动态变量,就要添加automatic关键字;如果在class中用静态变量就要添加static关键字。
那么什么是静态变量?什么是动态变量?
简单的说,静态变量至始至终都伴随这仿真的开始到结束。动态变量具有生命的周期性,如同烟花一瞬即逝,产生后就自动销毁。
6. 总结
欢迎大家留言评论,共同进步!
欢迎大家一起讨论学习!需要相关文档资料的同学可以给我发邮件!lixingyi09@qq.com
振兴中华