Constrained Random Stimulus
rand and randc, constraints with inside, dist and implication, inline constraints, and checking that the solver obeyed.
Hand-writing every test case does not scale to designs with billions of possible inputs. Constrained-random verification lets the simulator pick random values that still obey the rules of the protocol. The tests explore cases nobody thought of, while the constraints keep them legal and steer them towards interesting areas.
A randomized bus transaction
dist gives weights: READ 6, WRITE 3, IDLE 1 out of 10.
inside {[lo:hi]} restricts to a range; addr[1:0] == 2'b00 forces word alignment.
kind == IDLE -> len == 0 is an implication: the right side applies only when the left side is true.
randc cycles through all 4 port values in random order before repeating any.
Controlling randomization
t.randomize(); // result ignored if (t.randomize() == 0) $fatal(1, "randomize failed");
If the constraints cannot be satisfied, randomize() returns 0 and the object keeps its old values: the test silently repeats the same transaction.
constraint c { len > 0; len < 0; } constraint c { len inside {[1:16]}; }
Contradictory constraints make every randomize() fail. Keep constraints simple and test them over many randomizations.
What is the difference between:= and:/ in a dist?:= assigns the weight to every value in a range;:/ divides the weight equally across the range. [1:4]:= 2 gives each of 4 values weight 2 (total 8); [1:4]:/ 2 gives each 0.5.
Why use randc instead of rand?
randc guarantees every value is produced once before any repeats (a random permutation), which covers a small field completely in the minimum number of randomizations.