Section 12.4

LRM-16

Changes (change in red):

constraint_block is a list of expression statements that restrict the range of a variable or define relations between variables. A constraint_expression is any SystemVerilog expression, or one of the constraint-specific operators: =>, inside and dist (see Sections 12.4.4 12.4.3 and 12.4.5 12.4.4).

Section 12.4.3

LRM-16

Changes (change in red):

 

12.4.3 Set membership

 

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

 

The syntax to define a set expression is:

 

inside_expression ::= expression inside range_list_or_array                                                                                                                                       // from Annex A.8.3

 

range_list_or_array ::=

  variable_identifier

| { value_range { , value_range } }

 

value_range ::=

  expression

| [ expression : expression ]

Syntax 12-3—inside expression syntax (excerpt from Annex A)

 

expression is any integral SystemVerilog expression.

 

range_list_or_array is a comma-separated list of integral expressions and ranges. Value ranges are specified in ascending order with a low and high bound, enclosed by square braces [ ], and separated by a colon ( : ), as in [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 the bound to the right the range is empty and contains no values.

 

The inside operator evaluates to true if the expression is contained in the set; otherwise it evaluates to false.

 

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 denotes that expression lies outside the set: !(expression inside { set }).

 

For example:

 

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; }

 

Set values and ranges can be any integral expression. Values can be repeated, so values and value ranges can overlap.

 It is important to note that the inside operator is bidirectional, thus, the second example above is equivalent to a == b || a == c.

Section 12.4.6

LRM-2

Changes (change in red):

 

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

Section 12.13 (new)

LRM-30

Changes (change in red):

 

12.13 Random weighted case – randcase

 

statement_item ::=                                                                                                                                                ... // from Annex ???

{ attribute_instance } randcase randcase_item { randcase_item } endcase

 

randcase_item ::= expression : statement_or_null

 

The keyword randcase introduces a case statement that randomly selects one of its branches. The randcase item expressions are non-negative integral values that constitute the branch weights. An item’s weight divided by the sum of all weights gives the probability of taking that branch. For example:

 

randcase

3 : x = 1;

1 : x = 2;

4 : x = 3;

endcase

 

The sum of all weights is 8, so the probability of taking the first branch is 0.375, the probability of taking the second is 0.125, and the probability of taking the third is 0.5.

If a branch specifies a zero weight then that branch is not taken. If all randcase items specify zero weights then no branch is taken and a warning may be issued.

 

The randcase weights can be arbitrary expressions, not just constants. For example:

 

byte a, b;

 

randcase

a + b : x = 1;

a - b : x = 2;

a ^ ~b : x = 3;

12’b800 : x = 4;

endcase

 

The precision of each weight expression is self-determined. The sum of the weights is computed using standard addition semantics (maximum precision of all weights), where each summand is unsigned. Each weight expression is evaluated at most once (implementations may cache identical expressions) in an unspecified order. In the example above, the first three weight expressions are computed using 8-bit precision, the fourth expression is computed using 12-bit precision; the resulting weights are added as unsigned values using 12-bit precision. The weight selection then uses unsigned 12-bit comparison.

 

Each call to randcase retrieves one random number in the range zero to the sum of the weights. The weights are then selected in declaration order: smaller random numbers correspond to the first (top) weight statements.

 

Randcase statements exhibit thread stability. The random numbers are obtained from $urandom_range, thus, random values drawn are independent of thread execution order.