— Constraints interact
bidirectionally. In this example, the value chosen
for addr depends on atype and how it is constrained, and the value
chosen for atype depends on addr and how it is constrained. All expression
operators are treated bidirectionally, including the
implication operator (->).
—
Constraints
support only 2-state values. X and
Z values and 4-state operators (e.g., ===, !== ) are illegal and shall result in an error.
Variable ordering can be used
to force selected corner cases to occur more frequently than they would
otherwise. However, a "solve ... before ..." constraint does not change the
solution space, and so cannot cause the solver to fail.
Forces y to be solved before x. Thus,
constraint D is solved separately before
constraint C, which uses the values of y and F(y) as
state variables. Note that the behavior for variable ordering
implied by function arguments differs from the behavior for ordering specified
using the "solve... before..." constraint; function argument
variable ordering subdivides the solution space thereby changing it. Since
constraints on higher-priority variables are solved without considering
lower-priority constraints at all this subdivision can cause the overall
constraints to fail. Within each
prioritized set of constraints, cyclical (randc) variables are solved first.
blocking_assignment ::=
...
| class_variable_identifier . randomize [ ( ) ] with constraint_block ;
12.11
Randomization of scope variables — std::randomize()
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, std::randomize(), enables users to randomize data in the current
scope, without the need to define a class or instantiate a class object.
scope_randomize ::= [ std:: ]
randomize ( [ variable_identifier_list ] ) [
with { constraint_block } ]
For example:
module stim;
bit [15:0]
addr;
bit [31:0]
data;
function bit gen_stim();
bit success,
rd_wr;
success = ::randomize( addr, data,
rd_wr ); // call std::randomize
return rd_wr ;
endfunction
...
endmodule
The function gen_stim calls std::randomize() with
three variables as arguments: addr, data,
and rd_wr.
Thus, std::randomize() assigns new random variables to those variables that
are visible in the scope of the gen_stim function. Note that addr and data have
module scope, whereas rd_wr has scope local to the function. The above example can
also be written using a class: