system verilog中的constraint

本文介绍sv中的约束。

简单表达式

1
2
3
4
constraint c_simple{
lo < med;
med < hi;
}

等效表达式

1
2
3
4
5
6
constraint C1{
len == 42;
}
constraint c2{
len == mode * 4 + payload.size();
}

权重分布

也可动态改变权重,只需要将权重改为变量即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
constraint c_dist{
src dist{0:=40,[1:3]:=60};
// src = 0, weight = 40/220
// src = 1, weight = 60/220
// src = 2, weight = 60/220
// src = 3, weight = 60/220

dst dist {0:/40,[1:3]:/60};
// dst = 0, weight = 40/100
// dst = 1, weight = 20/100
// dst = 2, weight = 20/100
// dst = 3, weight = 20/100
}

集合成员和inside

1
2
3
4
5
6
constraint c_range1{
c inside{[lo:hi]};
}
constraint c_range2{
!(c inside {[lo:hi]});
}

条件约束

1
2
3
4
5
6
constraint c_len{
if(op == READ)
len inside {[1:2]};
else
len == 0;
}

约束中solve..before操作

有时,我们希望某种组合出现的频率更高一些,比如

1
2
3
4
5
6
7
class B;
rand bit s;
rand bit[31:0] d;
constraint c{
s->d==0;
}
endclass

约束中s和d是同时确定的,{s,d}共有2^33种组合,但是s仅在{1,0}这种情况下才是真的,因此s为真的概率为1/2^33,近似为零。

因此约束中为排序提供了一种机制,这样s可以独立于d被选择。

1
2
3
4
5
6
7
8
9
10
class B;
rand bit s;
rand bit[31:0] d;
constraint c{
s->d==0;
}
constraint order{
solve s before d;
}
endclass

这样,order约束块的结算器指示s在d的被求解之前求解,这时候s就具有50%的概率被选择为真,接下来d根据s的值被选择,相应的,d==0的概率也为50%。

结构体中某一项之和

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef struct{
rand bit[5:0] wlen;
rand int x;
}f_t;
class test;
rand f_t ta[];
constraint ta_c{
ta.size == 3;
ta.sum with (int'(item.wlen)) == 20;
foreach(ta[i]){
ta[i].wlen <=20;
}
}

其中10-12行是为了确保每一项的内容都小于20,不然可能会出现溢出情况,比如随机出来是 -1,21,0 的情况。