Difficulty: Medium · Puzzle 5 of 6 · Topic: randomize() with Puzzles
Will randomize succeed? Explain the exact reason.
class rw_req;
rand bit is_wr;
rand bit [3:0] len;
constraint c {
if (is_wr) len inside {[1:4]};
else len inside {[8:12]};
}
endclass
rw_req r = new();
r.len = 10;
r.len.rand_mode(0);
assert(r.randomize() with { is_wr == 1; });len is no longer randomized but still participates in active constraints.
1) rand_mode(0) on len freezes len at current value 10.
2) Inline sets is_wr=1, activating len inside 1..4.
3) Frozen len=10 violates active constraint.
4) No legal assignment exists, so randomize fails and len stays 10 (Verilator 5.048: returns 0, len==10).Answer: It fails 100%: len is fixed to 10 and cannot satisfy the is_wr==1 branch constraint len in [1:4].
Checked by running a model of the rule in a Python model and Verilator 5. Exact enumeration of the constraint set per the LRM (the LRM defines the distribution; simulator solvers need not be uniform). A frozen rand_mode(0) variable is a single fixed value that every active constraint still has to accept. Verilator 5.048: with len frozen at 10 the is_wr==1 call returns 0 and len stays 10; is_wr==0 (and no inline) pass with is_wr=0.
rand_mode(0) turns len into a state variable, but the constraints that mention it stay active and are checked against its frozen value 10. It is not 'excluded from constraints'. That is why this fails, while the same call with `is_wr == 0` would pass (10 is in 8..12) with exactly one solution.
How can you preserve len=10 and still make randomize pass? Model answer: let the solver choose the branch that fits: `with { is_wr == 0; }` (len=10 lies in 8..12; is_wr=0 is the only solution), or drop the inline and let is_wr float (the solver then must pick is_wr=0). To keep is_wr==1 instead you must change len, e.g. `r.len.rand_mode(1)` or assign a value in 1..4.
It fails every time. Rand_mode zero freezes len at ten, but the constraints that mention len stay active and are checked against that frozen value. The inline sets is_wr to one, which requires len in one to four, and ten does not satisfy that, so randomize returns zero and len stays ten. The trap is thinking a frozen variable is excluded from the constraints. Next I would choose is_wr equal to zero, where ten lies in eight to twelve, or release len with rand_mode one.