General

Renumber Sections 20.5 through 20.12 to be subsections of 20.4 (20.4.1 through 20.4.8. Move Section 20.17 to 20.4.9.

 

Move Section 20 to be after Section 11 and renamed to Section 12 and renumber existing Sections 12 and on to be 13 and on.

Section 20.1

Change as shown in red:

 

Constraint-driven test generation allows users to automatically generate tests for functional verification. Random testing can be more effective than a traditional, directed testing approach. By specifying constraints, one can easily create tests that can find hard-to-reach corner cases. SystemVerilog allows users to specify constraints in a compact, declarative way. The constraints are then processed by a solver that generates random values that meet the constraints.

Section 20.2

Change as shown in red:

 

This section introduces the basic concepts and uses for generating random stimulus within objects. SystemVerilog uses an object-oriented method for assigning random values to the member variables of an object subject to user-defined constraints.

 

and

The MyBus class inherits all of the random variables and constraints of the Bus class, and adds a random variable called type that is used to control the address range using another constraint. The addr_range constraint uses implication to select one of three range constraints depending on the random value of type. When a MyBus object is randomized, values for addr, data, and type are computed such that all of the constraints are satisfied. Using inheritance to build layered constraint systems enables the development of general-purpose models that can be constrained to perform application-specific functions.

 

and

This example illustrates several important properties of constraints:

— Constraints can be any SystemVerilog expression with variables and constants of integral type (bit, reg, logic, integer, enum, packed struct, etc…).

      Constraint expressions follow SystemVerilog syntax and semantics, including precedence, associativity, sign extension, truncation, and wrap-around.

and

— Constraints interact bidirectionally. In this example, the value chosen for addr depends on type and how it is constrained, and the value chosen for type depends on addr and how it is constrained. All expression operators are treated bidirectionally, including the implication operator (=>).

 

and

The ability to enable or disable constraints allows users to design a constraint hierarchies.

 

and

Similarly, the $rand_mode() method can be used to enable or disable any random variable. When a random variable is disabled, it behaves in exactly the same way as other nonrandom variables.

 

and (make sure font for pre_randomize and post_randomize is the same):

 

Occasionally, it is desirable to perform operations immediately before or after randomization. That is accomplished via two built-in methods, pre_randomize() and post_randomize(), which are automatically called before and after randomization. These methods can be overloaded with the desired functionality:

 

and for the 2nd to last paragraph make the change shown in red:

 

By default, pre_randomize() and post_randomize() call their overloaded parent class methods. When pre_randomize() or post_randomize() are overloaded, care must be taken to invoke the parent class’ methods, unless the class is a base class (has no parent class), otherwise the base class methods will not be called.

Section 20.3

Change as shown in red:

 

      The solver can randomize singular variables of any integral type such as integer, enumerated types, and packed array variables of any size.

 

      Arrays can be declared rand or randc, in which case all of their member elements are treated as rand or randc.

 

      Dynamic and associative arrays can be declared rand or randc. All of the elements in the array are randomized, overwriting any previous data. If the array elements are of type object, all of the array elements must be non-null. Individual array elements may be constrained, in which case the index expression must be a literal constant.

 

      The size of a dynamic array declared as rand or randc may also be constrained. In that case, the array will be resized according to the size constraint, and then all the array elements will be randomized. The array size constraint is declared using the size method. For example,

 

rand bit[7:0] len;

rand integer data[*];

constraint db { data.size == len ; );

 

The variable len is declared to be 8 bits wide. The randomizer computes a random value for the len variable in the 8-bit range of 0 to 255, and then randomizes the first len elements of the data array.

 

If a dynamic array’s size is not constrained then randomize() randomizes all the elements in the array.

 

      An object handle can be declared rand in which case all of that object’s variables and constraints are solved concurrently with the other class variables and constraints of the object that contains the handle. Objects cannot be declared randc.

Section 20.3.2

Change as shown in red:

 

The semantics of random-cyclical variables requires that they be solved before other random variables.

Section 20.4

Change as shown in red:

 

The values of random variables are determined using constraint expressions that are declared using constraint blocks. Constraint blocks are class members, like tasks, functions, and variables. They must be defined after the variable declarations in the class, and before the task and function declarations in the class. Constraint block names must be unique within a class.

 

and

randc variables cannot be specified in ordering constraints (see solve..before in Section 20.12).

Section 20.6

Change as shown in red:

 

      A constraint in a derived class that uses the same name as a constraint in its parent classes effectively overrides the base class constraints. For example:

 

Remove the last bullet as shown in red:

 

      The randomize() task is virtual, accordingly, it treats the class constraints in a virtual manner. When anamed constraint is overloaded, the previous definition is overridden.

 

— The built-in methods pre_randomize() and post_randomize() are functions and cannot block.

Section 20.7

Change as shown in red:

 

The syntax to define a set expression is:

expression inside { value_range_list };

or

expression inside array_identifier; // fixed-size, dynamic, or associative array

 

and

 

value_range_list is a comma-separated list of integral expressions and ranges. Ranges are specified with a low and high bound, enclosed by square braces [ ], and separated by a colon: [low_bound : high_bound]. Ranges include all of the integer elements between the bounds. If the bound to the left of the colon is greater than or equal to the bound to the right, otherwise the range is empty and contains no values.

 

change the example as shown in red:

 

rand integer x, y, z;

constraint c1 {x inside {3, 5, [9:15], [24:32], [y:2*y], z};}

 

rand integer a, b, c;

constraint c2 {a inside {b, c};}

 

integer fives[0:3] = { 5, 10, 15, 20 }; 

rand integer v;

constraint c3 { v inside fives; }

Section 20.8

Change the last paragraph adding as shown in red:

 

Limitations:

      A dist operation may not be applied to randc variables.

      A dist expression requires that expression contain at least one rand variable.

      A dist expression can only be a top-level constraint (not a predicated constraint).

Section 20.9

Clean-up font usage in this section (sizes are inconsistent).

 

and change as shown in red:

 

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

 

and in the last example:

 

bit[3:0] a, b;

constraint c {(a == 0) => (b == 1) ; };

 

and remove the last paragraph:

 

It is important to that the constraint solver be designed to cover the whole random value space with uniform probability. This allows randomization to better explore the whole design space than in cases where certain value combinations are preferred over others.

Section 20.10

Change as shown in red:

 

If-else style constraints are also supported.

 

and

 

constraint_block represents an unnamed constraint block. If the expression is true, all of the constraints in the first constraint block must be satisfied, otherwise all of the constraints in the optional else-constraint-block must be satisfied. Constraint blocks may be used to group multiple constraints.

 

and

 

Just like implication, if-else style constraints are bidirectional. In the declaration above, the value of mode constraints the value of len, and the value of len constrains the value of mode.

 

Section 20.11

Change as shown in red:

 

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. Class B extends class A and represents a heap-node with value v, a left sub-tree, and a right sub-tree. Both sub-trees 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 sub-tree 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 may be leaf nodes or more heap-nodes.

Section 20.12

Change as shown in red:

 

The solver must assure that the random values are selected to give a uniform value distribution over legal value combinations (that is, all combinations of values have the same probability of being the solution). This important property guarantees that all value combinations are equally probable, which allows randomization to better explore the whole design space.

 

and

 

variable_list is a comma-separated list of integral singular variables or array elements.

 

and

 

      The variables must be integral singular values.

 

and

— Variables that are not explicitly ordered will be solved with the last set of ordered variables. These values are deferred until as late as possible to assure a good distribution of values.

Section 20.13.1

Change as shown in red:

 

Checking the return status may be necessary because the actual value of state variables or addition of constraints in derived classes may render seemingly simple constraints unsatisfiable.

Section 20.13.2

Change as shown in red:

 

When obj.randomize() is invoked, it first invokes pre_randomize() on obj and also all of its random object members that are enabled. pre_randomize() then recursively calls super.pre_randomize(). After the new random values are computed and assigned, randomize() invokes post_randomize() on obj and also all of its random object members that are enabled. post_randomize() then recursively calls super.post_randomize().

 

and

 

If these methods are overloaded, they must call their associated parent class methods, otherwise their pre- and post-randomization processing steps will be skipped.

 

The pre-randomize() and post-randomize() methods are not virtual. However, because they are automatically called by the randomize() method, which is virtual, they appear to behave as virtual methods.

 

Notes: 20.13.3 Randomization methods notes

 

and

 

      If randomize() fails, post_randomize() is not be called.

 

      The randomize() method may not be overloaded.

 

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

 

      The built-in methods pre_randomize() and post_randomize() are functions and cannot block.

Section 20.14

Change as shown in red:

 

The unnamed constraint block contains additional in-line constraints to be applied along with the object constraints declared in the class.

Section 20.15

Change as shown in red:

 

The function form of $rand_mode() only accepts singular variables, thus, if the specified variable is an array, a single element must be selected via its index.

Section 20.17

Change as shown in red:

 

A constraint block can be defined as static by including the static keyword in its definition.

Section 20.19.1

Change as shown in red:

 

The system function $urandom provides a mechanism for generating pseudorandom numbers. The function returns a new 32-bit random number each time it is called. The number is unsigned.

and

The random number generator is deterministic. Each time the program executes, it cycles through the same random sequence. This sequence can be made nondeterministic by seeding the $urandom function with an extrinsic random variable, such as the time of day.

 

and

The $urandom function is similar to the $random system function, with two exceptions. $urandom returns unsigned numbers and is automatically thread stable (see Section 20.20.2).

Section 20.19.3

Change as shown in red:

 

The system function $srandom() allows manually seeding the Random Number Generator (RNG) of objects or threads.

Section 20.20.1

Change as shown in red:

 

Object stability is guaranteed as long as object and thread creation, as well as random number generation, are done in the same order as before. In order to maintain random number stability, new objects, threads and random numbers can be created after existing objects are created.

Section 20.21

Change as shown in red:

 

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 22.3

Change as shown in red:

 

$dimensions shall return the number of dimensions in the array, or 0 for a singular object

Annex A

 

Add the following BNF as appropriate:

 

Constraints BNF

Expression

 

<expression> ::= <verilog_expression>           // Add <inside> to <expression>

                 | <inside>

 

<inside> ::= <expression> 'inside' <range_list_or_array>

 

                 // Note: outside is specified as '!' '(' <inside> ')'

 

<range_list_or_array> ::= <array_identifier>   // fixed, dynamic, associative

    | '{' <value_range> { ',' <value_range> } '}'

 

<value_range> ::=    <expression>

    | '[' <expression> ':' <expression> ']'

Constraints

 

<constraint_declaration> ::= ['static'] 'constraint' <identifier>

'{' { <constraint_block> } '}'

 

<constraint_block> ::= 'solve' <identifiers> 'before' <identifiers> ';'

 | <expression> 'dist' '{' <dist_list>} '}' ';'

 | <constraint>

 

<constraint> ::= <expression> ';'

               | <expression> '=>' <constraints>

               | 'if' '(' <expression> ')' <constraints> [ 'else' <constraints> ]

 

<constraints> ::= <constraint>

  | '{' { <constraint> } '}'

 

<dist_list> ::= <dist_item> { ',' <dist_item> }

<dist_item> ::=        <value_range> ':=' <expression>

                     | <value_range> ':/' <expression>