Part 3 · Constraint Randomization · Intermediate
Randomizing Arrays & Queues
Hub — size constraints, foreach, sum() aggregates, unique, arrays of rand objects, and a worked constraint cookbook.
Overview
Real stimulus is rarely a handful of scalars. Packets carry variable-length payloads , DMA descriptors form lists , and arbitration tests need sequences of related transactions . Array randomization is how you describe all of that declaratively: constrain the .size(), constrain each element with foreach, constrain relationships between elements, and constrain aggregates like sum() — all solved together in one randomize() call.
This topic is interview-critical . Nearly every senior verification interview includes at least one array constraint puzzle — "generate a sorted array", "exactly 3 elements equal to 5", "payload bytes sum to the length field". The patterns are few and reusable; once you know the size-then-foreach-then-aggregate template and the sum-of-booleans counting idiom, most puzzles fall in under a minute.
Sub-topics
Constraining Array Size — .size() bounds, why unconstrained size is dangerous, solver ordering of size vs elements.
foreach Constraints — per-element rules, index-dependent relations, multi-dimensional and associative iteration.
sum() and Aggregate Constraints — checksum and weight-budget problems, the 32-bit overflow trap, other reductions.
unique Constraints — all-distinct arrays, permutation generation, unique vs randc.
Arrays of rand Objects — construct-before-randomize, cross-object element constraints, transaction sequences.
Array Constraint Cookbook — six classic interview problems with complete solutions.
ARRAY RANDOMIZATION TOPIC MAP
rand byte data[]; rand pkt q[$];
| |
v v
+--------------------------------------------+
| one randomize() call |
| |
| size : data.size() inside {[4:16]}; |
| elements : foreach (data[i]) ...; |
| relations : data[i] < data[i+1]; |
| aggregate : data.sum() with (...) == N; |
| distinct : unique { data }; |
+--------------------------------------------+
|
v
solver resolves size + every element + aggregates
SIMULTANEOUSLY (declarative, not sequential)
Objects are different:
rand txn seq[]; <-- handles must be new()'d BEFORE
randomize(); solver never calls new()Key takeaways
Size, elements, and aggregates are solved together in one constraint set — always bound .size() or risk memory blowup.
foreach is the per-element workhorse; guard index arithmetic at array boundaries.
sum()/unique/sorted/count-K are a small set of reusable idioms that cover most interview array puzzles.
Arrays of objects need explicit construction before randomize() — the solver randomizes fields, never allocates handles.