Section 12.1

LRM-252

Change (changes in red and blue)

The random constraints are built typically specified on top of an object oriented data abstraction. that models the data to be randomized as objects that contain random variables and user-defined constraints. The constraints determine the legal values that can be assigned to the random variables. Objects are ideal for representing complex aggregate data types and protocols such as Ethernet packets.

Section 12.2

LRM-252

Change (changes in red and blue)

task exercise_bus (MyBus bus);

int res;

 

// EXAMPLE 1: restrict to small addresses

res = bus.randomize() with with {atype == small;};

 

// EXAMPLE 2: restrict to address between 10 and 20

res = bus.randomize()with with {10 <= addr && addr <= 20;};

 

// EXAMPLE 3: restrict data values to powers-of-two

res = bus.randomize()with with {data & (data - 1) == 0;};

endtask

LRM-252

Change (changes in red and blue)

— Constraints support only 2-state values. 4-state values (X and or Z) values and or 4-state operators (e.g., ===, !== ) are illegal and shall result in an error.

LRM-252

Change (changes in red and blue)

function void pre_randomize();

super super.pre_randomize();

$display("Before randomize x=%0d, y=%0d", x, y);

endfunction

Section 12.4

LRM-248

Change in Syntax 12-2 (changes in red and blue)

loop_variables ::= [ index_variable_identifier ] { , [ index_ variable_identifier ] }            // from Annex A.6.8

Section 12.4.2

LRM-252

Change (changes in red and blue)

— The randomize() task is virtual. Accordingly, it treats the class constraints in a virtual manner. When a named constraint is overloaded redefined in an extended class, the previous definition is overridden.

Section 12.4.3

LRM-252

Change (changes in red and blue)

Constraints support integer value sets and the set membership operators (as defined in Section 7.20).

 

Absent any other constraints, all values (either single values or value ranges), have an equal probability of being chosen by the inside operator.

 

The negated form of the inside operator denotes that expression lies outside the set: !(expression inside { set }).

Section 12.4.4

LRM-273

Change in Syntax 12-3 (changes in red and blue):

dist_item ::= value_range [ dist_weight ]

  value_range := expression

| value_range :/ expression

 

dist_weight ::=

  := expression
:/ expression

LRM-276

Change (changes in red and blue)

The distribution set is a comma-separated list of integral expressions and ranges. Optionally, each term in the list can have a weight, which is specified using the := or :/ operators. If no weight is specified for an item, the default weight is :=  1. The weight can be any integral SystemVerilog expression.

LRM-252

Change (changes in red and blue)

In general, distributions guarantee two properties: set membership and monotonic weighting, which means that increasing a weight shall increase increases the likelihood of choosing those values.

Section 12.4.5

LRM-252

Change (changes in red and blue)

The boolean equivalent of the implication operator a -> b is (!a || b). This states that if the expression is true, then random numbers generated are constrained by the constraint (or constraint block set). Otherwise the random numbers generated are unconstrained.

LRM-252

Change (changes in red and blue)

The constraint_set represents any valid constraint or an unnamed constraint block set. If the expression is true, all of the constraints in the constraint block set must also be satisfied.

Section 12.4.6

LRM-252

Change (changes in red and blue)

LRM-252

Change (changes in red and blue)

constraint_set represents any valid constraint or an unnamed constraint block. If the expression is true, all of the constraints in the first constraint or constraint block set must be satisfied, otherwise all of the constraints in the optional else constraint or constraint-block must be satisfied. Constraint blocks sets can be used to group multiple constraints.

Section 12.4.7

LRM-248

Change in Syntax 12-6 (changes in red and blue)

loop_variables ::= [ index_variable_identifier ] { , [ index_ variable_identifier ] }            // from Annex A.6.8

Section 12.4.8

LRM-252

Change (changes in red and blue)

This example uses global constraints to define the legal values of an ordered binary tree. Class A represents a leaf node with an 8-bit value x v. Class B extends class A and represents a heap-node with value v, a left subtree, and a right subtree. Both subtrees are declared as rand in order to randomize them at the same time as other class variables. The constraint block named heapcond has two global constraints relating the left and right subtree values to the heap-node value. When an instance of class B is randomized, the solver simultaneously solves for B and its left and right children, which in turn can be leaf nodes or more heap-nodes.

Section 12.4.9

LRM-252

Change in Syntax 12-7 (changes in red and blue)

constraint_block ::=                                             // from Annex A.1.9

  solve identifier_list before identifier_list ;

| constraint_expression

Section 12.4.10

LRM-252

Change (Create new Syntax 12-8)  (changes in red and blue)

 

static constraint constraint_identifier { contraint_expressions }

 

constraint_declaration ::=                                                   // from Annex A.1.9

 [ static ] constraint constraint_identifier { { constraint_block } }

 

Syntax 12-8—Static constraint syntax (excerpt from Annex A)

Section 12.4.12

LRM-252

Change (changes in red and blue)

0 TRUE FALSE Sub-expression evaluates to TRUE FALSE

1 FALSE TRUE Sub-expression evaluates to FALSE TRUE

LRM-252

Change (changes in red and blue)

— Negation ( ! ): If the sub-expression evaluates to ERROR, then the guard evaluates to ERROR. Otherwise, if the sub-expression evaluates to TRUE or FALSE then the guard evaluates to FALSE or TRUE, respectively.

LRM-252

Change (changes in red and blue)

— If the final result of the evaluation is RANDOM then a guarded conditional constraint is generated.

Section 12.5.1

LRM-252

Change (changes in red and blue)

Conjunction

 

virtual function int randomize();

Section 12.5.3

LRM-252

Change (changes in red and blue)

      The randomize() method shall not is built-in and cannot be overridden.

 

      The randomize() method implements object random stability. An object can be seeded by the $srandom() system call  calling its srandom() method (see Section 12.12.3), specifying the object in the second argument.

Section 12.6

LRM-248

Change in Syntax 12-8 (changes in red and blue)

blocking_assignment ::=                                                     // from Annex A.6.2

...

| class_variable_identifier . randomize [ ( ) ] with constraint_block

 

inline_constraint _declaration ::=                                      // not in Annex A

class_variable_identifier . randomize [ ( [ variable_identifier_list | null ]  )  ]

with { { constraint_block } }

LRM-248

Change (changes in red and blue)

Syntax 12-8—In-line constraint syntax (excerpt from not in Annex A)

Section 12.8

LRM-252

Change (changes in red and blue)

In this example, the toggle_rand function first checks the current active state of the constraint filter1 in the specified Packet object p. If the constraint is active, then the function shall deactivates it; if it is inactive, the function shall activates it. Finally, the function calls the randomize method to generate a new random value for variable source_value.

Section 12.10

LRM-252

Change (note formatting!) (changes in red and blue)

a.randomize();             // random variables: x, y. state variables: v, w

a.randomize( x );          // random variables: x.    state variables: y, v, w

a.randomize( v, w );       // random variables: v, w. state variables: x, y

a.randomize( w, x );       // random variables: w, x. state variables: y, v

Section 12.11

LRM-254

Change (changes in red and blue)

The built-in class randomize method operates exclusively on class member variables. Using classes to model the data to be randomized is a powerful mechanism that enables the creation of generic, reusable objects containing random variables and constraints that can be later extended, inherited, constrained, overridden, enabled, disabled, merged with or separated from other objects. The ease with which classes and their associated random variables and constraints can be manipulated make classes an ideal vehicle for describing and manipulating random data and constraints. However, some less-demanding problems that do not require the full flexibility of classes, can use a simpler mechanism to randomize data that does not belong to a class. The scope randomize method function, std::randomize(), enables users to randomize data in the current scope, without the need to define a class or instantiate a class object.

 

The syntax of the scope randomize method function is:

LRM-248

Change in Syntax 12-9 (changes in red and blue)

statement ::= [ block_identifier : ] { attribute_instance } statement_item   // from Annex A.6.4

 

statement_item ::=

...

| scope_randomize

 

scope_randomize ::=                                                                            // not in Annex A

[ std:: ] randomize ( [ variable_identifier_list ] ) [ with { { constraint_block } } ]

 

variable_identifier_list ::= variable_identifier { , variable_identifier }

LRM-248 LRM-254

Change (changes in red and blue)

Syntax 12-9—scope randomize method function syntax (excerpt from not in Annex A)

LRM-254

Change (changes in red and blue)

The scope randomize method function behaves exactly the same as a class randomize method, except that it operates on he variables of the current scope instead of class member variables. Arguments to this method function specify the variables that are to be assigned random values, i.e., the random variables.

LRM-254

Change (changes in red and blue)

However, for this simple application, the scope randomize method function leads to a straightforward implementation.

 

The scope randomize method function returns 1 if it successfully sets all the random variables to valid values, otherwise it returns 0. If the scope randomize method function is called with no arguments then it behaves as a checker, and simply returns status.

Section 12.11.1

LRM-252 LRM-254

Change (changes in red and blue)

12.11.1 Adding constraints to scope variables - std::randomize() with

 

The std::randomize() with form of the scope randomize method function allows users to specify random constraints to be applied to the local scope variables. When specifying constraints, the arguments to the scope randomize method function become random variables, all other variables are considered state variables.

 

task stimulus( int length );

int a, b, c, success;

 

success = std::randomize( a, b, c ) with { a < b ; a + b < length };

...

success = std::randomize( a, b ) with { b - a > length };

...

endtask

 

The task stimulus above calls std::randomize twice resulting in two sets of random values for its local variables a, b, and c. In the first call variables a and b are constrained such that variable a is less than b, and their sum is less than the task argument length, which is designated as a state variable. In the second call, variables a and b are constrained such that their difference is greater than state variable length.

Section 12.13

LRM-252

Change (changes in red and blue)

      The system randomization calls, $urandom() and, $urandom_range(), and $srandom().

 

      The object and process random seeding method, srandom().

 

      The object randomization method, randomize().

 

Section 12.13.2

LRM-252

Change (changes in red and blue)

integer x, y, z;

fork          //set a seed at the start of a thread

begin $process::self.srandom(100); x = $urandom; end

//set a seed during a thread

begin y = $urandom; $process::self.srandom(200); end

// draw 2 values from the thread RNG

begin z = $urandom + $urandom ; end

join

 

Section 12.13.3

LRM-252

Change (changes in red and blue)

— Objects can be seeded at any time using the $srandom() system task with an optional object argument method.

 

class Foo;

function new (integer seed);

//set a new seed for this instance

$this.srandom(seed, this);

endfunction

endclass

Section 12.14

LRM-252

Change (changes in red and blue)

Sometimes it is desirable to manually seed an object’s RNG using the $srandom() system call method. This can be done either in a class method, or external to the class definition:

 

An example of seeding the RNG internally, as a class method is:

 

class Packet;

rand bit[15:0] header;

...

function new (int seed);

$this.srandom(seed, this);

...

endfunction

endclass

 

An example of seeding the RNG externally is:

 

Packet p = new(200); // Create p with seed 200.

$p.srandom(300, p); // Re-seed p with seed 300.

 

Calling $srandom() in an object’s new() function, assures the object’s RNG is set with the new seed before any class member values are randomized.

Section 12.16.3

LRM-256

Change (changes in red and blue)

The case production statement is analogous to the procedural case statement except as noted below. The case expression is evaluated, and its value is compared against the value of each case-item expression, which are evaluated and compared in the order in which they are given. The production generated is the one associated with the first case-item expression that matches matching the case expression is generated. If no matching case-item expression is found then the production associated with the optional default item is generated, or nothing if there no default item. Multiple default statements in one case production statement shall be illegal. Case-item expressions separated by commas allow multiple expressions to share the production. For example:

Section 12.16.7

LRM-275

Change (Note that the endsequence needs indented) (changes in red and blue)

GAP: { ## ($urandom_range( 1, 20 )); };

endsequence