3.4.1 Persistent initialization flag

EasyImplementVerilator · local serverReview the topic

Wait for a state that was announced once, whether you arrive before or after the announcement.

Hardware context: Testbench synchronization around DUT initialization and repeated traffic phases. Allow a late-starting agent to observe that DUT initialization already completed.

A driver waits for the DUT to finish initializing before it sends traffic. On most seeds that works. On a few, the driver hangs: it arrived after the initialization event had already fired, and an event keeps no record of the past.

Write wait_for_initialization(observed_tick). The monitor sets startup_ready to 1 when initialization ends, and keeps it at 1; it also triggers startup_notification once at that moment. Return as soon as startup_ready is 1, with observed_tick set to the time since startup_origin, in ns.

A driver that arrives after initialization returns at once, at its own arrival time. A driver that arrives earlier returns when initialization ends.

Signals in the timeline

SignalWidthRole
initialize_at8input of each check
consumer_at8input of each check
Full specification
Given state and the task you write
bit   startup_ready;          // set to 1 when initialization ends, and stays 1
event startup_notification;   // triggered once at that moment
time  startup_origin;
task automatic wait_for_initialization(output int observed_tick);

Each case starts initialization at initialize_at ns and calls your task at consumer_at ns. At 8 ns any task still waiting is stopped. The result is {done, observed_tick, final_ready}; a stopped task reports done = 0 and observed_tick = 65535. A correct task always returns at max(initialize_at, consumer_at).

Examples

Example 1

Initialization already happened
Input
initialize_at = 2, consumer_at = 5
Output
done = yes, observed_tick = 5, final_ready = yes

The flag has been 1 since 2 ns, so the driver returns at once, at 5 ns.

Example 2

The driver arrives first
Input
initialize_at = 5, consumer_at = 2
Output
done = yes, observed_tick = 5, final_ready = yes

The driver waits from 2 ns until initialization ends at 5 ns.

Example 3

Both happen at the same time
Input
initialize_at = 3, consumer_at = 3
Output
done = yes, observed_tick = 3, final_ready = yes

Waiting on the flag gives 3 ns whichever of the two the simulator runs first.

Constraints and contract

  • initialize_at and consumer_at are 0 to 7 ns.
  • startup_ready never goes back to 0 during a case.
  • Keep the signature.

Hints

Hint 1

What does waiting on an event do if the event was triggered before you started waiting?

Hint 2

Which of the two things the monitor gives you still says "initialized" a nanosecond later?

Hint 3

Wait on the value of the flag; if it is already 1, the wait returns at once.

What this judge verifies: The task is called for every arrival time before, at and after initialization, with a watchdog that stops a waiter that never returns. Passing shows the driver never misses an initialization.

39 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

Initialization already happened

Input
initialize_at = 2, consumer_at = 5
Expected output
done = yes, observed_tick = 5, final_ready = yes

The flag has been 1 since 2 ns, so the driver returns at once, at 5 ns.

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

Verilator · local server