2.4.2 Wide population reduction

EasyImplementVerilator · local serverReview the topic

Count and sum selected bytes with array reductions, and keep the results wide enough to hold the answer.

Hardware context: Coverage and performance analysis of observed bus transactions. Count and sum accepted transfer bytes without overflowing the monitor accumulator.

A watchdog counted stuck reads with age.sum() with (item > 1000). Two reads hung, yet the count said 0: the sum took the 1-bit type of the comparison, and 1 + 1 wrapped to 0. A reduction is only as wide as what it adds up.

Write summarize_bytes(bytes, keep, count, minimum). Of the first count bytes, select every byte whose keep bit is 1 and whose value is at least minimum. Return how many bytes were selected, the population, and the sum of their values.

With 256 bytes of 0xFF, all kept and minimum 0, the population is 256 and the sum is 65,280. Neither fits in 8 bits.

A selected byte of 0 still counts in the population. A count outside 0 to 256 returns status 1 with both results 0. Use the array reduction methods.

Signals in the timeline

SignalWidthRole
first_32_bytes256input of each check
keep256input of each check
count32input of each check
minimum8input of each check
Full specification
Signature (keep it)
function automatic logic [39:0] summarize_bytes(input byte unsigned bytes[256], input bit keep[256],
  input int count, input byte unsigned minimum);
// returns {status[7:0], population[15:0], sum[15:0]}

Byte i is selected when i < count, keep[i] = 1 and bytes[i] >= minimum. minimum is unsigned, so 0x80 is 128, not a negative number.

The population can reach 256 (9 bits) and the sum 65,280 (16 bits). Do not change the input arrays.

Examples

Example 1

The largest answer
Input
256 bytes of FF, every keep bit 1, count = 256, minimum = 0
Output
status = OK (0), population = 256, sum = 65280

256 bytes are selected and they add up to 65,280. An 8-bit count or an 8-bit sum would wrap.

Example 2

The threshold is unsigned and inclusive
Input
bytes = [00, FF, 80, 7F], keep = 1111, count = 4, minimum = 128
Output
status = OK (0), population = 2, sum = 383

FF (255) and 80 (128) reach the minimum; 7F (127) and 00 do not. 255 + 128 = 383.

Example 3

Only kept bytes count
Input
bytes = [FF, FF], keep = 01, count = 2, minimum = 0
Output
status = OK (0), population = 1, sum = 255

Only byte 0 is kept, so one byte with sum 255.

Constraints and contract

  • Bytes, keep bits and minimum are known; only count is checked.
  • Bytes and keep bits at or after count must not affect either result.
  • Keep the signature.

Hints

Hint 1

Build one 0-or-1 value per position saying whether that byte is selected. What does a reduction over those values give you?

Hint 2

With a with clause, a reduction takes the type of the with expression. How wide is item, and how wide must each term be for the total to fit?

Hint 3

Widen each term inside the with expression, for example with a 16-bit cast, rather than assigning a narrow result to a wide variable afterwards.

What this judge verifies: Your function is called on the largest population and sum, unsigned thresholds around 0x80, kept and dropped bytes, zero bytes, leftover data after count and invalid counts. Passing shows both reductions are right on these inputs.

128 checks on Verilator · local server. Run the examples first, then check the full regression. The suite is local and inspectable. A passing result establishes the tested cases, not a proof for all possible inputs.

See all 5 steps and the final capstone
Your code SystemVerilogSaved locally
Ln 1, Col 1Tab indents · Ctrl/⌘ + Enter runs samples
Not run yet

The largest answer

Input
256 bytes of FF, every keep bit 1, count = 256, minimum = 0
Expected output
status = OK (0), population = 256, sum = 65280

256 bytes are selected and they add up to 65,280. An 8-bit count or an 8-bit sum would wrap.

Run samples executes all 3 example checks. Check all tests runs 128 checks.

Verilator · local server