Constraint Blocks

在最后几页中,我们看到了如何将随机变量约束到要生成的合法范围内。 在接下来的几页中,我们将看到。
【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

发布了124 篇原创文章 · 获赞 8 · 访问量 6683

猜你喜欢

转载自blog.csdn.net/qq_43042339/article/details/104553653