3.3.1 Wait for two workers

EasyImplementVerilator · local serverReview the topic

Start two transfers at once and return only when both have finished.

Hardware context: Verification test lifecycle with timeout and cancellation workers. Wait for two independent bounded hardware-driving tasks to finish.

A test drives two channels of a DMA at the same time. Run one after the other and the second channel starts late, so the test never sees the two transfers overlap, which is the case the DUT gets wrong.

Write run_pair(first_delay, second_delay). Start the supplied transfer_worker(0, first_delay) and transfer_worker(1, second_delay) at the same time, and return only when both have finished.

With delays 1 and 4, channel 0 finishes at 2 ns and channel 1 at 5 ns, so run_pair returns at 5 ns. With delays 8 and 0, it still waits for channel 0, which finishes at 9 ns.

Signals in the timeline

SignalWidthRole
first_delay8input of each check
second_delay8input of each check
Full specification
Given worker and the task you write
task automatic transfer_worker(input int channel, delay_cycles);   // supplied: takes delay_cycles + 1 ns
task automatic run_pair(input int first_delay, second_delay);      // you write this

Delays are 0 to 8. A worker drives its channel, waits delay + 1 ns, records the accepted payload 0x123400 + 256 x channel + delay and its finish time, then finishes.

Result bitsField
79:72returned_after: ns from the call until run_pair returned
71:64done_mask: bit c set when channel c finished
63:56, 55:48finish time of channel 0 and channel 1
47:24, 23:0accepted payload of channel 0 and channel 1

Examples

Example 1

Different delays overlap
Input
first_delay = 1, second_delay = 4
Output
returned_after = 5, done_mask = 'b00000011, channel0_finish = 2, channel1_finish = 5, channel0_payload = 0x123401, channel1_payload = 0x123504

Channel 0 finishes at 2 ns and channel 1 at 5 ns; run_pair returns at 5 ns.

Example 2

Both finish together
Input
first_delay = 0, second_delay = 0
Output
returned_after = 1, done_mask = 'b00000011, channel0_finish = 1, channel1_finish = 1, channel0_payload = 0x123400, channel1_payload = 0x123500

Both finish at 1 ns, and the result does not depend on which one the simulator runs first.

Example 3

The first branch is the slow one
Input
first_delay = 8, second_delay = 0
Output
returned_after = 9, done_mask = 'b00000011, channel0_finish = 9, channel1_finish = 1, channel0_payload = 0x123408, channel1_payload = 0x123500

Channel 1 is done at 1 ns, but run_pair waits for channel 0 until 9 ns.

Constraints and contract

  • Both workers must run at the same time.
  • run_pair returns exactly when the later worker finishes.
  • Keep the signature and call the supplied worker.

Hints

Hint 1

Two calls written one after the other run one after the other. What statement starts several things at once?

Hint 2

There are three ways to end that statement. Which one waits for every branch?

Hint 3

Put each worker call in its own branch and let the statement wait for both before run_pair returns.

What this judge verifies: run_pair is called for every pair of delays from 0 to 8, and each case reports when it returned and when each worker finished. Passing shows the workers overlap and run_pair waits for both.

84 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 6 steps and the final capstone
Your code SystemVerilogSaved locally
Ln 1, Col 1Tab indents · Ctrl/⌘ + Enter runs samples
Not run yet

Different delays overlap

Input
first_delay = 1, second_delay = 4
Expected output
returned_after = 5, done_mask = 'b00000011, channel0_finish = 2, channel1_finish = 5, channel0_payload = 0x123401, channel1_payload = 0x123504

Channel 0 finishes at 2 ns and channel 1 at 5 ns; run_pair returns at 5 ns.

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

Verilator · local server