Part 1 · Language Foundations · Intermediate
Array Reduction & Locator Methods
sum/product/min/max, find variants with `with` clauses, sort/rsort/shuffle, unique, and why locators return queues.
Reduction methods — fold the array to one value
Every unpacked array family (fixed, dynamic, queue, associative) supports built-in reduction methods : sum(), product(), and(), or(), xor(). A crucial semantic detail: the result width is the element width , so summing a byte array wraps at 8 bits unless you widen with a with clause such as q.sum() with (int'(item)). The item keyword names the current element inside the clause — this width trap is a favorite interview gotcha.
module reduction_demo;
byte payload[$] = {8'hF0, 8'hF0, 8'hF0};
initial begin
// WRONG width: 8-bit accumulation wraps (F0+F0+F0 = 2D0 -> D0)
$display("8-bit sum = %0h", payload.sum());
// Correct: widen each element before accumulating
$display("32-bit sum = %0h", payload.sum() with (int'(item)));
// Conditional reduction: count elements matching a predicate
$display("count > 8'h80 = %0d",
payload.sum() with (int'(item > 8'h80)));
$display("min=%0p max=%0p", payload.min(), payload.max());
end
endmoduleLocator methods — search without loops
Locator methods scan the array against a with expression and always return a queue , even when at most one element can match. Why a queue? Because zero matches must be representable — an empty queue — without inventing a sentinel value. So the idiom is: capture the result, check size(), then use element [0]. find returns matching elements, find_index their positions, find_first/find_last stop at one match, and min/max/unique follow the same queue-return convention.
class txn;
rand int addr;
rand bit is_err;
endclass
txn log_q[$];
txn errs[$];
int idxs[$];
int vals[$];
initial begin
// ... log_q filled by monitor ...
errs = log_q.find(t) with (t.is_err); // all error txns
idxs = log_q.find_index(t) with (t.addr > 'h1000); // their positions
errs = log_q.find_first(t) with (t.is_err); // queue of 0 or 1
if (errs.size() > 0)
$display("first error at addr %0h", errs[0].addr);
else
$display("no errors logged");
vals = {4, 1, 4, 9, 1};
vals = vals.unique(); // {4, 1, 9} - first occurrences kept
endLOCATOR METHODS — ALWAYS RETURN A QUEUE
log_q: ┌────┬────┬────┬────┬────┐
│ ok │ERR │ ok │ERR │ ok │
└────┴────┴────┴────┴────┘
0 1 2 3 4
find(t) with (t.is_err) ──► { e1, e3 } (elements)
find_index(t) with (t.is_err) ──► { 1, 3 } (positions)
find_first(t) with (t.is_err) ──► { e1 } (size 1)
find_first(t) with (t.addr<0) ──► { } (size 0 = miss)
│
▼
always check size() before using [0]Ordering methods — sort, rsort, shuffle, reverse
The ordering methods mutate the array in place and return nothing: sort() ascending, rsort() descending, reverse() flips order, and shuffle() randomizes order (note: shuffle is not controlled by the constraint solver's seed stability rules the way randomize is, so don't lean on it for reproducible stimulus ordering across simulators). For object arrays you must supply a sort key with with, since class handles have no natural order.
txn pending[$];
initial begin
// Sort transactions by address, then walk in order
pending.sort(t) with (t.addr);
foreach (pending[i])
$display("addr %0h", pending[i].addr);
pending.rsort(t) with (t.addr); // descending
pending.shuffle(); // random order, in place
endKey takeaways
Reduction width = element width — widen with sum() with (int'(item)) or results wrap.
Locators always return queues so 'no match' is an empty queue — check size() before [0].
sum() with (int'(predicate)) is the idiomatic loop-free way to count matching elements.
sort/rsort/shuffle mutate in place; object arrays need a with clause for the sort key.
Common pitfalls
byte_q.sum() into an int and wondering why totals are wrong — accumulation already wrapped at 8 bits.
Using find_first(...)[0] directly — empty-queue indexing when nothing matches.
Expecting sort() to return the sorted array — it mutates in place and returns void.
Sorting class-handle arrays without a with clause — there is no default ordering for objects.