systemverilog 中的constraint

本篇主要介绍一些 systemverilog 中的constraint。

1. 简单表达式

我们可以用> < >= <=等符号来对变量进行简单的约束, 注意的是当要把某个变量设为定值时, 需要使用==符号。

比如下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class myClass;
rand bit [3:0] min, typ, max;
rand bit [3:0] fixed;
constraint my_range { 3 < min;
typ < max;
typ > min;
max < 14; }
constraint c_fixed { fixed == 5; }
function string display ();
return $sformatf ("min=%0d typ=%0d max=%0d fixed=%d", min, typ, max, fixed);
endfunction
endclass
module tb;
initial begin
for (int i = 0; i < 10; i++) begin
myClass cls = new ();
cls.randomize();
$display ("itr=%0d %s", i, cls.display());
end
end
endmodule

那么运行的结果就是:

1
2
3
4
5
6
7
8
9
10
11
12
13
ncsim> source ../edaTools/cadence/INCISIV131/tools/inca/files/ncsimrc
ncsim> run
itr=0 min=5 typ=6 max=7 fixed= 5
itr=1 min=5 typ=7 max=13 fixed= 5
itr=2 min=7 typ=11 max=12 fixed= 5
itr=3 min=4 typ=10 max=13 fixed= 5
itr=4 min=6 typ=8 max=13 fixed= 5
itr=5 min=4 typ=8 max=11 fixed= 5
itr=6 min=5 typ=10 max=11 fixed= 5
itr=7 min=4 typ=8 max=12 fixed= 5
itr=8 min=4 typ=8 max=10 fixed= 5
itr=9 min=4 typ=12 max=13 fixed= 5
ncsim: *W,RNQUIE: Simulation is complete.

2. inside 表达式

(1) 也可以使用inside关键字申明变量的范围或者申明变量只能取某些特定的值, 比如:

1
2
3
4
5
6
7
constraint my_range { typ > 32;
typ < 256; }
// typ >= 32 and typ <= 256
constraint new_range { typ inside {[32:256]}; }

// Choose from the following values
constraint spec_range { type inside {32, 64, 128}; }

(2) 如果加上符号!表示变量不在某个范围内

1
2
rand bit [2:0] typ;
constraint inv_range { ! (typ inside {[3:6]}); }

3. 权重分布

当在随机化变量的时候, 需要某些值出现的更加频繁一些。 就可以用关键字dist进行权重的约束。

:=表示的是, 对于指定范围的值, 权重都一样, 比如[1:5]:=50;表示的是[1:5]范围的任何一个值, 其权重都是50;

:/表示的是, 对于指定范围的值, 权重均分, 比如[1:5]:=50;表示的是[1:5]范围的任何一个值, 其权重都是10;

1
2
rand bit [2:0] typ;
constraint dist1 { typ dist { 0:=20, [1:5]:=50, 6:=40, 7:=10}; }

上面约束表示的含义是: 0的权重是20, 6 是40, 7是10, 1:5 中的每个数都是50. 总共320, 那么选择0的概率就是20/320

1
2
rand bit [2:0] typ;
constraint dist2 { typ dist { 0:/20, [1:5]:=50, 6:/10, 7:/20}; }

这个约束表示的含义就不同了, 选中0的概率就是20/100

4. 多重约束

多重约束存在时, 取的是交集:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class myClass;
rand bit [3:0] val;
constraint c1 { val > 3;
val < 12; }

constraint c2 {val >= 10; }
endclass

module tb;
initial begin
for (int i = 0; i < 10; i++) begin
myClass cls = new ();
cls.randomize();
$display ("itr=%0d typ=%0d", i, cls.val);
end
end
endmodule

比如上面的例子, val的值被约束在了[10, 12)

5. implication 约束

implication约束使用的符号是->, 代表的是某两个或者多个变量之间的关系。 有些类似于if - else申明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class ABC;
rand bit [3:0] mode;
rand bit mod_en;

// If 5 <= mode <= 11, mod_en should be 1
constraint c_mode { mode inside {[4'h5:4'hB]} -> mod_en == 1; }

endclass

module tb;
initial begin
ABC abc = new;
for (int i = 0; i < 10; i++) begin
abc.randomize();
$display ("mode=0x%0h mod_en=0x%0h", abc.mode, abc.mod_en);
end
end

endmodule

上面例子的运行结果为:

1
2
3
4
5
6
7
8
9
10
11
12
ncsim> run
mode=0xf mod_en=0x1
mode=0x9 mod_en=0x1
mode=0x3 mod_en=0x1
mode=0xe mod_en=0x1
mode=0x1 mod_en=0x1
mode=0x0 mod_en=0x0
mode=0x1 mod_en=0x0
mode=0xe mod_en=0x0
mode=0x5 mod_en=0x1
mode=0x0 mod_en=0x0
ncsim: *W,RNQUIE: Simulation is complete.