Dynamic Arrays, Queues, and Associative Arrays
Choose a testbench collection for variable batches, transaction queues, and indexed results.
Collections for the testbench
Dynamic collections manage a number of transactions that is unknown at compile time. They belong mainly in verification and high-level models rather than synthesizable RTL.
Three forms serve different needs:
- a dynamic array for a size allocated at run time;
- a queue for easy insertion and removal at its ends;
- an associative array for elements indexed by sparse keys.
Dynamic array
int samples[];
samples = new[128];
foreach (samples[i])
samples[i] = i * 2;
$display("count=%0d", samples.size());
samples.delete();new[128] allocates 128 elements. A new allocation can preserve part of the old content with new[new_size](samples). delete() releases the array.
This format fits a data block whose size is known at the beginning of an operation and which needs frequent direct indexing.
Queue
typedef logic [31:0] word_t;
word_t expected_q[$];
expected_q.push_back(32'h1234_5678);
expected_q.push_back(32'hCAFE_BABE);
if (expected_q.size() != 0) begin
word_t expected = expected_q.pop_front();
check_word(expected, observed);
end[$] declares an unbounded queue. push_back and pop_front provide FIFO behavior. Other methods include push_front, pop_back, insert, and delete.
A queue works well in a scoreboard when results leave in the same order as commands.
Associative array
logic [31:0] expected_by_id[int unsigned];
expected_by_id[transaction_id] = predicted_value;
if (expected_by_id.exists(response_id)) begin
assert (observed == expected_by_id[response_id]);
expected_by_id.delete(response_id);
end else begin
$error("Unexpected response id %0d", response_id);
endOnly used keys allocate elements. This format fits responses that may return in a different order, provided each has a unique identifier.
The first, next, last, and prev methods iterate over keys. Their order follows the index type rather than insertion order.
Choose the simplest matching structure
A collection should reflect the real protocol. A queue is enough for an ordered flow. An associative array is useful for reordered responses. Adding complex lookup when a FIFO is sufficient makes the scoreboard harder to trust than the DUT.
Check for an empty collection before pop_front, and verify that collections are empty at the end of the test. A remaining expected item often means a missing response.
Key points
- Dynamic collections mainly belong in testbenches.
- A dynamic array provides resizable, densely indexed storage.
- A queue naturally matches an ordered flow.
- An associative array finds a result by key.
- Queues and tables should be empty or explained at the end of a test.
📝 Test your knowledge - Chapter quiz