1、成员值约束
rand integer x, y, z;
constraint c1 {x inside {3, 5, [9:15], [24:32], [y:2*y], z};}
rand integer a, b, c;
constraint c2 {a inside {b, c};}
integer fives[4] = '{ 5, 10, 15, 20 };
rand integer v;
constraint c3 { v inside {fives}; }
注意点:inside约束是双向的,如a inside {b, c},意味着a==b || a==c;
2、权重约束
x dist {100 := 1, 200 := 2, 300 := 5}
x取值100, 200, 300 的权重是1-2-5;
如果如下约束:
x != 200;
x dist {100 := 1, 200 := 2, 300 := 5}
那x的取值为100,300的权重为1-5.
x dist { [100:102] := 1, 200 := 2, 300 := 5}
x可以取值100, 101, 102, 200, 300 ,权重分别为 1-1-1-2-5;
x dist { [100:102] :/ 1, 200 := 2, 300 := 5}
x也可以取值100, 101, 102, 200, 300 ,但权重为1/3-1/3-1/3-2-5.
3、蕴含条件约束 –>
mode == little -> len < 10;
mode == big -> len > 100;
当Mode==little时,len<10,当mode==big时,len》100, mode != little&&mode != big时,不约束。
bit [3:0] a, b;
constraint c { (a == 0) -> (b == 1); }
a == 0时b == 1, a和b总共有256种组合,当a==0时,会排除15种组合{0,0}, {0,2}, … {0,15}. 因此概率计算,a == 0为1/(256-15)。
4、条件约束 if-else
if (mode == little)
len < 10;
else if (mode == big)
len > 100;
5、重复迭代约束- foreach语法:
class C;
rand byte A[] ;
constraint C1 { foreach ( A [ i ] ) A[i] inside {2,4,8,16}; }
constraint C2 { foreach ( A [ j ] ) A[j] > 2 * j; }
endclass
多维数组的循环约束→
int A [2][3][4]; bit [3:0][2:1] B [5:1][4];
foreach( A [ i, j, k ] ) ...
foreach( B [ q, r, , s ] ) ...
动态数组变量约束→
class C;
rand int A[] ;
constraint c1 { A.size inside {[1:10]}; }
constraint c2 { foreach ( A[ k ] ) (k < A.size - 1) -> A[k + 1] > A[k]; }
endclass
6、矩阵相关约束
class C;
rand bit [7:0] A[] ;
constraint c1 { A.size == 5 }
constraint c2 { A.sum() with {int’(item)} < 1000; }
endclass
其中c2的含义,等效如下的约束:
( int’(A[0])+int’(A[1])+int’(A[2])+int’(A[3])+int’(A[4]) ) < 1000
7、全局约束
class A; // leaf node
rand bit [7:0] v;
endclass
class B extends A; // heap node
rand A left;
rand A right;
constraint heapcond {left.v <= v; right.v <= v;}
endclass
8、变量solve顺序
class B;
rand bit s;
rand bit [31:0] d;
constraint c { s -> d == 0; }
endclass
s满足时d==0,虽然理解上s的结果决定了d的结果,但是事实上s和d在solver中是一起判决的.
如果{s,d}有2的33次幂的组合情况,但是只有{1,0}符合要求,实际概率无限接近于0.但是指定slove顺序如下:
class B;
rand bit s;
rand bit [31:0] d;
constraint c { s -> d == 0; }
constraint order { solve s before d; }
endclass
s为1的概率为50%,所以,{1,0}的概率为50%。
9、约束中嵌入函数
function int count_ones ( bit [9:0] w );
for( count_ones = 0; w != 0; w = w >> 1 )
count_ones += w & 1'b1;
endfunction
此函数的作用,计算w中的1的个数。
constraint C1 { length == count_ones( v ) ; }
constraint C2{
length == ((v>>9)&1) + ((v>>8)&1) + ((v>>7)&1) + ((v>>6)&1) + ((v>>5)&1) +
((v>>4)&1) + ((v>>3)&1) + ((v>>2)&1) + ((v>>1)&1) + ((v>>0)&1);
}
10、约束保护
class SList;
rand int n;
rand Slist next;
constraint sort { n < next.n; }
endclass
如上,如果Slist next没有new分配,那么next是空指标的话,n<next.n完全达不到我们约束的期望,因此可以加上保护如下:
constraint sort { if( next != null ) n < next.n; }
还有一些例子,主要是通过创造一个条件,让我们的约束表达更健壮.
class D;
int x;
endclass
class C;
rand int x, y;
D a, b;
constraint c1 { (x < y || a.x > b.x || a.x == 5 ) -> x+y == 10; }
endclass