Random Constraints

randomize()
在上一页中,我们看到了randomize()方法的基本用法。 Systemverilog中的randomize()方法具有以下扩展名。

constraint_mode()
rand_mode()
randomize() with
pre_randomize()
post_randomize()

constraint_mode()

Systemverilog提供了预定义的constraint_mode()方法来控制约束是有效的还是无效的。所有约束最初都是有效的。

Syntax

task object[.constraint_identifier]::constraint_mode( bit on_off );
or
function int object.constraint_identifier::constraint_mode();

【1】object_name是在其中定义约束块的对象的名称;
【2】constraint_identifier是要对其执行操作的约束块的名称;
【3】1(ON)将指定的约束块设置为活动状态,以便在随后对randomize()方法的调用中强制执行;
【4】0(OFF)将指定的约束块设置为非活动状态,以便在随后对randomize()方法的调用中不强制执行;
【5】如果指定的约束块在类层次结构中不存在,将发出编译器错误。
当我们想随机化为不同配置编码的类时,constraint_mode方法非常有用。下面的示例显示我们可以使用约束模式。

Example : constraint_mode()

 1 typedef enum {UNICAST=11,MULTICAST,BROADCAST} pkt_type;
  2 
  3 program constaint_mode_ex;
  4   class frame_t; 
  5     rand pkt_type ptype;
  6     rand integer len;
  7     rand bit  [7:0] payload [];
  8     constraint common {
  9       payload.size() == len;
 10     }
 11     // Constraint the members
 12     constraint unicast {
 13       len <= 2;
 14       ptype == UNICAST;
 15     }
 16     // Constraint the members
 17     constraint multicast {
 18       len >= 3;
 19       len <= 4;
 20       ptype == MULTICAST;
 21     }
 22     function string getType(pkt_type ltype);
 23       begin
 24         case(ltype)
 25          UNICAST   : getType = "UNICAST";
 26          MULTICAST : getType = "MULTICAST";
 27          BROADCAST : getType = "BROADCAST";
 28          default   : getType = "UNKNOWN";
 29         endcase
 30       end
 31     endfunction
 32     // Print the members of the class
 33     task print() ;
 34       begin
 35         integer i =0;
 36         $write("Packet type %s\n",getType(ptype));
 37         $write("Size of frame is %0d\n",len);
 38         if (payload.size() > 0) begin
 39           $write("Payload is ");
 40           for (i=0; i < len; i++) begin
 41             $write(" %2x",payload[i]);
 42           end
 43           $write("\n");
 44         end
 45       end  
 46     endtask
 47   endclass
 48  
 49   initial begin 
 50      frame_t frame = new();
 51      integer j = 0;
 52      $write("-------------------------------\n");
 53      // Do contraint for Unicast frame
 54      frame.multicast.constraint_mode(0);
 55      if (frame.multicast.constraint_mode() == 0) begin
 56        if (frame.randomize() == 1) begin
 57          frame.print(); 
 58        end else begin
 59          $write("Failed to randomize frame\n");
 60        end
 61      end else begin
 62         $write("Failed to disable constraint multicast\n");
 63      end
 64      $write("-------------------------------\n");
 65      // Check the status of constraint multicast
 66      $write ("Constraint state of multicast is %0d\n",
 67          frame.multicast.constraint_mode());
 68      $write("-------------------------------\n");
 69      // Now disable the unitcast and enable multicast
 70      frame.unicast.constraint_mode(0);
 71      frame.multicast.constraint_mode(1);
 72      if (frame.randomize() == 1) begin
 73        frame.print(); 
 74      end else begin
 75        $write("Failed to randomize frame\n");
 76      end
 77      $write("-------------------------------\n");
 78   end
 79 endprogram

 -------------------------------
 Packet type UNICAST
 Size of frame is 1
 Payload is  7d
 -------------------------------
 Constraint state of multicast is 0
 -------------------------------
 Packet type MULTICAST
 Size of frame is 3
 Payload is  df 40 f7
 -------------------------------

rand_mode()

Systemverilog提供了预定义的rand_mode()方法来控制随机变量是活动的还是非活动的。 当随机变量处于非活动状态时,将其视为未声明为rand或randc。 所有随机变量最初都是活动的。
Syntax

task object[.random_variable]::rand_mode( bit on_off );
or
function int object.random_variable::rand_mode();

【1】object:object是任何产生定义随机变量的对象句柄的表达式。
【2】random_variable:random_variable是对其应用操作的随机变量的名称。 如果未指定(仅当作为任务调用时才允许),则该操作将应用于指定对象内的所有随机变量。
【3】1(ON):将指定的变量设置为活动状态,以便在随后对randomize()方法的调用中将它们随机化。
【4】0 OFF:将指定的变量设置为无效,以便在随后调用randomize()方法时不会将它们随机化。
当作为函数调用时,rand_mode()返回指定随机变量的当前活动状态。如果变量处于活动状态(ON),则返回1;如果变量处于非活动状态(OFF),则返回0。

Example : rand_mode()

  1 program rand_mode_ex;
  2   class frame_t;
  3     rand bit [7:0] src_addr;
  4     rand bit [7:0] dst_addr;
  5     task print();
  6       begin 
  7         $write("Source      address %2x\n",src_addr);
  8         $write("Destination address %2x\n",dst_addr);
  9       end
 10     endtask  
 11   endclass
 12 
 13   initial begin
 14     frame_t frame = new();
 15     integer j = 0;
 16     $write("-------------------------------\n");
 17     $write("Without Randomize Value\n");
 18     frame.print();
 19     $write("-------------------------------\n");
 20     $write("With Randomize Value\n");
 21     j = frame.randomize();
 22     frame.print();
 23     $write("-------------------------------\n");
 24     $write("With Randomize OFF and Randomize\n");
 25     frame.rand_mode(0);
 26     j = frame.randomize();
 27     frame.print();
 28     $write("-------------------------------\n");
 29     $write("With Randomize ON and Randomize\n");
 30     frame.rand_mode(1);
 31     j = frame.randomize();
 32     frame.print();
 33     $write("-------------------------------\n");
 34     $write("With Randomize OFF on dest addr and Randomize\n");
 35     frame.dst_addr.rand_mode(0);
 36     j = frame.randomize();
 37     frame.print();
 38     $write("-------------------------------\n");
 39   end
 40 endprogram
You could download file rand_mode_ex.sv here
 	 	
space.gif

 	../images/main/4blue_dots_bullets.gif	Simulation Output : rand_mode()
 	 	
space.gif

 -------------------------------
 Without Randomize Value
 Source      address 00
 Destination address 00
 -------------------------------
 With Randomize Value
 Source      address 36
 Destination address 3c
 -------------------------------
 With Randomize OFF and Randomize
 Source      address 36
 Destination address 3c
 -------------------------------
 With Randomize ON and Randomize
 Source      address 7d
 Destination address e2
 -------------------------------
 With Randomize OFF on dest addr and Randomize
 Source      address 0b
 Destination address e2
 -------------------------------

randomize()with

此构造允许在调用randomize()类方法的点声明内联约束。 这些其他约束具有与随机类中声明的约束类型和形式相同的约束类型。 内联约束与对象约束一起应用。 类定义中的原始约束不必更改。
Syntax

inline_constraint _declaration ::=
class_variable_identifier . randomize [
   ( [ variable_identifier_list | null ] ) ]
with constraint_block

[1]class_variable_identifier:是实例化对象的名称。
[2]未命名的constraint_block包含要与在类中声明的对象约束一起应用的其他嵌入式约束。

Example : randomize with

  1 program randomize_with;
  2   class frame_t;
  3     rand bit [7:0] src_addr;
  4     rand bit [7:0] dst_addr;
  5     constraint c {
  6       src_addr <=  127;
  7       dst_addr >=  128;
  8     }
  9     task print();
 10       begin 
 11         $write("Source      address %2x\n",src_addr);
 12         $write("Destination address %2x\n",dst_addr);
 13       end
 14     endtask  
 15   endclass
 16 
 17 
 18   initial begin
 19     frame_t frame = new();
 20     integer i = 0;
 21     $write("-------------------------------\n");
 22     $write("Randomize Value\n");
 23     i = frame.randomize();
 24     frame.print();
 25     $write("-------------------------------\n");
 26     $write("Randomize with Value\n");
 27     i = frame.randomize() with {
 28       src_addr > 100;
 29       dst_addr < 130;
 30       dst_addr > 128;
 31     };
 32     frame.print();
 33     $write("-------------------------------\n");
 34   end
 35 endprogram
 -------------------------------
 Randomize Value
 Source      address 02
 Destination address ab
 -------------------------------
 Randomize with Value
 Source      address 79
 Destination address 81

pre_randomize()和post_randomize()

每个类都包含内置的pre_randomize()和post_randomize()任务,它们在计算新的随机值之前和之后由randomize()自动调用。

Syntax

function void pre_randomize();
function void post_randomize();

调用obj.randomize()时,它首先对obj及其启用的所有随机对象成员都调用pre_randomize()。 然后Pre_randomize()递归调用super.pre_randomize()。
然后Post_randomize()递归调用super.post_randomize()。 您可以在任何类中重载pre_randomize()来执行初始化和设置对象随机化之前的前提条件。
您可以在任何类中重载post_randomize()来执行清理,打印诊断并在对象随机化后检查后置条件。
参考文献:

Example : pre/post randomize()

 1 program pre_post_randomize;
  2 
  3   class frame_t;
  4     rand bit [7:0] data;
  5     bit  parity;
  6     constraint c {
  7      data >  0;
  8     }
  9     function void pre_randomize();
 10       begin
 11         $write("pre_randomize  : Value of data %b and parity %b\n",data,parity);
 12       end
 13     endfunction
 14     function void post_randomize();
 15       begin
 16         parity = ^data;
 17         $write("post_randomize : Value of data %b and parity %b\n",data,parity);
 18       end
 19     endfunction
 20    endclass
 21 
 22   initial begin
 23     frame_t frame = new();
 24     integer i = 0;
 25     $write("-------------------------------\n");
 26     $write("Randomize Value\n");
 27     $write("-------------------------------\n");
 28     i = frame.randomize();
 29     $write("-------------------------------\n");
 30   end
 31 endprogram

	
 -------------------------------
 Randomize Value
 -------------------------------
 pre_randomize  : Value of data 00000000 and parity 0
 post_randomize : Value of data 00000110 and parity 0
 -------------------------------

【1】http://www.asic-world.com/systemverilog/random_constraint2.html#randomize()

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

猜你喜欢

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