在最后几页中,我们看到了如何将随机变量约束到要生成的合法范围内。 在接下来的几页中,我们将看到。
【1】包含和排除(设置成员资格)inclusive and exclusive (set membership);
【2】分配distribution;
【3】条件约束conditional constraint;
【4】前言foreach;
还有一些高级约束主题。
Set Membership
有时我们想在一组值(包括)中随机化一个变量,有时我们想从生成的随机值中排除一些值(不包括)。
【1】[]用于指定范围;
【2】内部运算符的取反形式表示表达式位于集合外部:!(表达式位于{set}内部);
【3】如果没有任何其他约束,所有值(单个值或值范围)都有相同的概率被内部操作符选中。
示例:设置成员(Set Membership)
1 program set_membership;
2 class frame_t;
3 rand bit [7:0] src_port;
4 rand bit [7:0] des_port;
5 constraint c {
6 // inclusive
7 src_port inside { [8'h0:8'hA],8'h14,8'h18 };
8 // exclusive
9 ! (des_port inside { [8'h4:8'hFF] });
10 }
11 function void post_randomize();
12 begin
13 $display("src port : %0x",src_port);
14 $display("des port : %0x",des_port);
15 end
16 endfunction
17 endclass
18
19 initial begin
20 frame_t frame = new();
21 integer i,j = 0;
22 for (j=0;j < 4; j++) begin
23 $display("-------------------------------");
24 $display("Randomize Value");
25 $display("-------------------------------");
26 i = frame.randomize();
27 end
28 $display("-------------------------------");
29 end
30 endprogram
-------------------------------
Randomize Value
-------------------------------
src port : 3
des port : 2
-------------------------------
Randomize Value
-------------------------------
src port : 0
des port : 2
-------------------------------
Randomize Value
-------------------------------
src port : 18
des port : 3
-------------------------------
Randomize Value
-------------------------------
src port : 2
des port : 0
-------------------------------
分布约束Distributions Constraints
当Systemverilog中需要基于权重的随机化时,我们可以使用Distribution。
constraint_block ::=
...
| expression dist { dist_list } ;
dist_list ::= dist_item { , dist_item }
dist_item ::= value_range [ dist_weight ]
dist_weight ::=
:= expression
| :/ expression
dist_item ::=
value_range := expression
| value_range :/ expression
expression_or_dist ::= expression [ dist { dist_list } ]
【1】expression:可以是引用至少一个声明为rand的变量的任何Systemverilog表达式;
【2】dist:如果表达式包含在集合中,则dist运算符返回true;否则,返回true。 否则返回false;
【3】:= weight中:=运算符将权重分配给item,min,如果有范围(即min:max),则将范围内的每个值(即所有)分配给权重 。 weight可以是任何Systemverilog表达式)。
【4】:/ weight 中: /运算符将权重值除,并在范围内的所有元素之间平均分配。 如果范围中有n个值,则每个值的权重为range_weight / n。 (权重可以是任何Systemverilog表达式)。
Example : Distributions
1 program distribution;
2 class frame_t;
3 rand bit [7:0] src_port;
4 rand bit [7:0] des_port;
5 rand bit [15:0] length;
6 constraint len {
7 length dist {
8 [64 : 127 ] := 10,
9 [128 : 511 ] := 10,
10 [512 : 2048] := 10
11 };
12 }
13 constraint src {
14 src_port dist {
15 0 := 1,
16 1 := 1,
17 2 := 5,
18 4 := 1
19 };
20 }
21 constraint des {
22 des_port dist {
23 [0 : 5 ] :/ 5,
24 [6 : 100 ] := 1,
25 [101 : 200 ] := 1,
26 [201 : 255 ] := 1
27 };
28 }
29
30 function void post_randomize();
31 begin
32 $display("src port : %0x",src_port);
33 $display("des port : %0x",des_port);
34 $display("length : %0x",length);
35 end
36 endfunction
37 endclass
38
39 initial begin
40 frame_t frame = new();
41 integer i,j = 0;
42 for (j=0;j < 4; j++) begin
43 $display("-------------------------------");
44 $display("Randomize Value");
45 $display("-------------------------------");
46 i = frame.randomize();
47 end
48 $display("-------------------------------");
49 end
50
51 endprogram
-------------------------------
Randomize Value
-------------------------------
src port : 0
des port : 36
length : bd
-------------------------------
Randomize Value
-------------------------------
src port : 2
des port : 5e
length : 43b
-------------------------------
Randomize Value
-------------------------------
src port : 2
des port : 83
length : 4fe
-------------------------------
Randomize Value
-------------------------------
src port : 2
des port : e4
length : 6d9
-------------------------------
Implication Constraints隐含的约束
约束为声明条件(谓词)关系提供了两个构造:implication和if…else。
【1】Implication =>
【2】if-else
在e语言中,Implication和when是相似的。它的工作原理是,如果条件为真,那么应用约束。If-else类似于Implication => constraint,两者都可以使用。
Example : conditional
1 program conditional_con;
2 class frame_t;
3 typedef enum {RUNT,NORMAL,OVERSIZE} size_t;
4 rand bit [15:0] length;
5 rand size_t size;
6
7 constraint frame_sizes {
8 size == NORMAL -> {
9 length dist {
10 [64 : 127 ] := 10,
11 [128 : 511 ] := 10,
12 [512 : 1500] := 10
13 };
14 }
15 if (size == RUNT) {
16 length >= 0;
17 length <= 63;
18 } else if (size == OVERSIZE) {
19 length >= 1501;
20 length <= 5000;
21 }
22 }
23 function void post_randomize();
24 begin
25 $display("length : %0d",length);
26 case(size)
27 RUNT : $display ("Frame size_t is RUNT");
28 NORMAL : $display ("Frame size_t is NORMAL");
29 OVERSIZE : $display ("Frame size_t is OVERSIZE");
30 endcase
31 end
32 endfunction
33 endclass
34
35 initial begin
36 frame_t frame = new();
37 integer i,j = 0;
38 for (j=0;j < 4; j++) begin
39 $write("-------------------------------\n");
40 $write("Randomize Value\n");
41 i = frame.randomize();
42 end
43 $write("-------------------------------\n");
44 end
45
46 endprogram
-------------------------------
Randomize Value
length : 4948
Frame size_t is OVERSIZE
-------------------------------
Randomize Value
length : 4317
Frame size_t is OVERSIZE
-------------------------------
Randomize Value
length : 1774
Frame size_t is OVERSIZE
-------------------------------
Randomize Value
length : 610
Frame size_t is NORMAL
-------------------------------
Iterative constraints迭代约束
迭代约束允许使用循环变量和索引表达式以参数化方式约束数组变量。foreach构造指定数组元素上的迭代。 它的参数是一个标识符,它指定任何类型的数组(固定大小,动态,关联或队列),后跟用方括号括起来的循环变量列表。 每个循环变量对应于数组的维度之一。
Example : Iterative
1 program iterative_con;
2 class frame_t;
3 rand bit [15:0] data [];
4
5 constraint frame_sizes {
6 data.size inside {[1:10]};
7 foreach (data[i])
8 data[i] == i;
9 }
10 function void post_randomize();
11 begin
12 $display("length : %0d", data.size());
13 for (integer i = 0; i < data.size(); i++) begin
14 $write ("%2x ",data[i]);
15 end
16 $write("\n");
17 end
18 endfunction
19 endclass
20
21 initial begin
22 frame_t frame = new();
23 integer i,j = 0;
24 for (j=0;j < 4; j++) begin
25 $write("-------------------------------\n");
26 $write("Randomize Value\n");
27 i = frame.randomize();
28 end
29 $write("-------------------------------\n");
30 end
31
32 endprogram
-------------------------------
Randomize Value
length : 4
00 01 02 03
-------------------------------
Randomize Value
length : 2
00 01
-------------------------------
Randomize Value
length : 8
00 01 02 03 04 05 06 07
-------------------------------
Randomize Value
length : 9
00 01 02 03 04 05 06 07 08
-------------------------------
Variable Ordering可变顺序
求解器必须确保选择随机值以在合法值组合上给出均匀的值分布。 为了实现上述目的,SystemVerilog提供了称为“solve before”的功能。
Example : Variable Ordering
1 program ordering;
2 class frame_t;
3 rand bit zero;
4 rand bit [15:0] data [];
5
6 constraint frame_sizes {
7 solve zero before data.size;
8 zero -> data.size == 0;
9 data.size inside {[0:10]};
10 foreach (data[i])
11 data[i] == i;
12
13 }
14 function void post_randomize();
15 begin
16 $display("length : %0d", data.size());
17 for (integer i = 0; i < data.size(); i++) begin
18 $write ("%2x ",data[i]);
19 end
20 $write("\n");
21 end
22 endfunction
23 endclass
24
25 initial begin
26 frame_t frame = new();
27 integer i,j = 0;
28 for (j=0;j < 4; j++) begin
29 $write("-------------------------------\n");
30 $write("Randomize Value\n");
31 i = frame.randomize();
32 end
33 $write("-------------------------------\n");
34 end
35
36 endprogram
-------------------------------
Randomize Value
length : 2
00 01
-------------------------------
Randomize Value
length : 0
-------------------------------
Randomize Value
length : 0
-------------------------------
Randomize Value
length : 5
00 01 02 03 04
-------------------------------
randcase
randcase语句指定一个语句块,其中一个语句块是随机执行的。关键字randcase引入了一个case语句,该语句随机选择它的一个分支。randcase项表达式是组成分支权重的非负整数值。一个项目的权重除以所有权重的总和,就得到了该分支的概率。
Syntax : randcase
statement_item ::=
...
| randcase_statement
randcase_statement ::=
randcase randcase_item { randcase_item } endcase
randcase_item ::= expression : statement_or_null
Example : randcase
1 module randcase_statement;
2
3 task do_randcase();
4 begin
5 randcase
6 20 : begin
7 $write ("What should I do ? \n");
8 end
9 20 : begin
10 $write ("Should I work\n");
11 end
12 20 : begin
13 $write ("Should I watch Movie\n");
14 end
15 40 : begin
16 $write ("Should I complete tutorial\n");
17 end
18 endcase
19 end
20 endtask
21
22 initial begin
23 repeat(10) begin
24 // You need to run for more iteration to
25 // get proper distribution
26 do_randcase();
27 end
28 $finish;
29 end
30 endmodule
Should I watch Movie
Should I complete tutorial
Should I watch Movie
What should I do ?
Should I complete tutorial
Should I watch Movie
Should I complete tutorial
Should I complete tutorial
Should I work
Should I watch Movie
参考文献:
【1】http://www.asic-world.com/systemverilog/random_constraint9.html