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

  1. Constraining Array Size — .size() bounds, why unconstrained size is dangerous, solver ordering of size vs elements.

  2. foreach Constraints — per-element rules, index-dependent relations, multi-dimensional and associative iteration.

  3. sum() and Aggregate Constraints — checksum and weight-budget problems, the 32-bit overflow trap, other reductions.

  4. unique Constraints — all-distinct arrays, permutation generation, unique vs randc.

  5. Arrays of rand Objects — construct-before-randomize, cross-object element constraints, transaction sequences.

  6. Array Constraint Cookbook — six classic interview problems with complete solutions.

diagram
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.