3.2.1 Invocation-local accumulator

EasyFixVerilator · local serverReview the topic

Fix a checksum task whose running total survives from one call to the next.

Hardware context: Concurrent testbench services driving independent hardware requests. Compute a request-local result using storage private to that invocation.

This is a Fix problem: the code in the editor has one realistic defect. Find it and fix it.

A driver calls request_checksum for every descriptor it sends. The first checksum of each test is right, but every later one is too big, and the error grows as the test runs. Each call is meant to start from scratch.

For count = 3, payload = 32'hFF030201 and seed = 10, the checksum is 10 + 1 + 2 + 3 = 16. The 0xFF lane is outside the descriptor. A call with count = 0 returns just the seed, however many calls came before it.

Signals in the timeline

SignalWidthRole
count32input of each check
payload32input of each check
seed16input of each check
Full specification
Signature (keep the name and arguments)
task request_checksum(input int count, input logic [31:0] payload, input logic [15:0] seed,
                      output bit valid, output logic [15:0] checksum);

For count 0 to 4: valid = 1 and checksum = seed plus the lowest count bytes of payload (byte 0 is bits 7:0), modulo 65,536. Any other count: valid = 0 and checksum = 0, without reading payload.

Every call is independent: the result never depends on earlier calls. Each case calls the task once more in the same simulation and reports valid and checksum.

Examples

Example 1

Three bytes plus the seed
Input
count = 3, payload = 32'hFF030201, seed = 10
Output
valid = yes, checksum = 0x10

10 + 1 + 2 + 3 = 16 = 0x10. The 0xFF lane is not part of the descriptor.

Example 2

A fresh call after a busy one
Input
count = 0, payload = 32'hFFFFFFFF, seed = 0
Output
valid = yes, checksum = 0x0

Nothing is added and the seed is 0, so the checksum is 0, whatever the earlier calls summed.

Example 3

The sum wraps at 16 bits
Input
count = 4, payload = 32'hFFFFFFFF, seed = 65535
Output
valid = yes, checksum = 0x3fb

65,535 + 4 x 255 = 66,555, which wraps to 1,019 = 0x03FB.

Constraints and contract

  • Inputs are known; count is a signed int.
  • Calls happen one after another in one simulation.
  • Keep the task name and arguments.

Hints

Hint 1

The first call is right and later ones are not. What is different about the second call, if the inputs can be the same?

Hint 2

Look at how long each variable inside the task lives, and when its initializer runs.

Hint 3

A variable that must start fresh on every call has to be created on every call. Which kind of task does that for its local variables?

What this judge verifies: The task is called many times in one simulation: directed calls, invalid counts, empty calls after large sums, and seeded descriptors. Passing shows every call is independent and correct.

247 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

Three bytes plus the seed

Input
count = 3, payload = 32'hFF030201, seed = 10
Expected output
valid = yes, checksum = 0x10

10 + 1 + 2 + 3 = 16 = 0x10. The 0xFF lane is not part of the descriptor.

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

Verilator · local server