Reset in the middle of traffic
Derive reset handling from what the DUT preserves or discards, distinguish accepted work from an offer, and prove useful traffic recovers afterwards.
- Lesson
- U10.2
- Time
- 25 min
- Runs on
- Verilator with UVM
- Check
- 6 questions
A test applies reset halfway through, then sends one more value, 80. The design answers 81, correctly, and the scoreboard reports "y=81, expected 33". Before reset, the design had taken 32, and reset threw its result away. The scoreboard still had 33 waiting at the front of its queue.
Columns are selected rising edges. Reset dropped the result for 32, but the scoreboard kept predicting it.
Start from this design’s reset behavior
- Accept and predict45 ns (illustrative)
The input monitor observes 32 being accepted. The model predicts 33, so accepted work has an entry in the scoreboard.
More context
The prediction comes from the observed accept, not from the driver's offer. The first pair, 16 → 17, was already checked at 35 ns.
Follow the calls, values and waits
- data expected 33: Accepted x = 32 → Expected y = 33
- Waiting: Expected y = 33 — Waiting for result 33
- Distinguish the offer50 ns (illustrative)
The driver is offering 48 when reset rises. No transfer accepted 48, so it creates no prediction and contributes nothing to the accepted count.
Follow the calls, values and waits
- Waiting: Offered x = 48 — No acceptance yet
- Apply this reset rule55 ns (illustrative)
Reset discards the pending DUT result. The scoreboard cancels 33 once; the driver abandons 48 while the test flushes the sequencer.
More context
The log prints both lines at 55 ns: "reset: 1 prediction(s) canceled" and "reset: drops x=48, no item_done". Reset turns off again at 70 ns.
Follow the calls, values and waits
- data expected 33: Expected y = 33 → Canceled: 1
- data offer 48: Offered x = 48 → Drop the offer
- Released: Expected y = 33
- Released: Offered x = 48
- Demonstrate recovery85 ns (illustrative)
After reset falls at 70 ns, a new item 80 is accepted.
More context
Restart creates fresh traffic. It does not silently retry the abandoned item.
Follow the calls, values and waits
- data new item 80: Drop the offer → New x = 80
- Check the new result105 ns (illustrative)
Its result 81 is checked at 105 ns. Neither cancellation nor dropping 48 counts as a successful comparison.
Read the diagram as text
- Accepted x = 32: 45 ns: valid and ready are high
- Expected y = 33: One result still owed
- Canceled: 1: 55 ns: remove expected 33
- Offered x = 48: No ready/valid transfer
- Drop the offer: Lower valid; no item_done after flush
- New x = 80: Accepted at 85 ns; 81 checked at 105 ns
- Accepted x = 32 → Expected y = 33: predict
- Expected y = 33 → Canceled: 1: reset
- Offered x = 48 → Drop the offer: reset
- Drop the offer → New x = 80: restart
Arrows show bookkeeping and restart actions. Together with 16 → 17 before reset, the final ledger is 3 accepted = 2 checked + 1 canceled. Offered 48 is outside that ledger.
Reset discards an unfinished result, so the bench must cancel the accepted work it removes, but not an offer that never transferred.
Other designs may finish accepted requests, return an abort response, or preserve work through a soft reset. A memory may retain its contents while its interface resets. Derive cancellation and model updates from that design behavior; UVM supplies no universal rule that all work vanishes.
Here reset changes on falling edges and is sampled on rising edges. At a sampled reset edge, the monitor gives reset priority and reports no transfer. An asynchronous reset or another clock domain needs its own specified sampling and ordering rule.
Coordinate every place that holds state
The test raises reset at 50 ns. At 55 ns the monitor reports reset, the sequencer is stopped, and the driver abandons its pending offer. Each action handles a different kind of state.
| Part | State before reset | Action in this example |
|---|---|---|
| Test and sequencer | The first sequence and its pending request | stop_sequences() kills the sequence and flushes its request |
| Driver | 48 is offered but unaccepted | Lower valid, discard this request, wait for reset release |
| Monitor | A transfer or reset at the sampled edge | Publish reset; do not invent an acceptance for 48 |
| Reference calculation | y = x + 1 has no persistent state | No calculation state to reset; a stateful model would apply the DUT’s reset values |
| Scoreboard | Expected result 33 is pending | Count it as canceled, then remove it |
| Coverage and other consumers | History and possibly local queued work | Apply their own reset rule; keep lifetime progress counts |
A stateful predictor may preserve memory while clearing control state. Reset only the state the DUT specification resets.
U7.2’s analysis FIFOs can also contain old observations, and a consumer may already hold an item outside its FIFO. Flush, finish or cancel that work according to the same reset rule. Clearing the scoreboard queue alone cannot reset a separate model or consumer.
Organizing reset in a larger environment
A reset agent can drive the pin while a coordinator distributes the sampled event and waits for participants to acknowledge recovery. Define the cut before allowing new traffic, especially across clock domains.
UVM has pre_reset, reset and post_reset run-time phases; U1.2 shows the run-time schedule. They provide scheduling callbacks; their names do not drive reset pins or clear models. A domain can revisit phases through a jump, but the bench still supplies every recovery action.
Do not erase lifetime coverage merely because the DUT reset. Gate reset-cycle samples where appropriate, and keep separate coverage of reset during idle, an unaccepted offer, accepted work and repeated resets.
Release the driver after the sequencer flush
stop_sequences() stops sequences registered on that sequencer and removes their requests and reservations. The typed sequencer also clears its request FIFO and handshake flags. It does not reach into the driver to withdraw valid.
This driver uses try_next_item followed by item_done. After the flush, completing the old request would find no outstanding request and raise fatal SQRBADITMDN. The driver instead notices sampled reset, lowers valid, and abandons the request without item_done.
do @(posedge vif.clk);
while (!vif.ready && !vif.rst);
if (vif.rst) begin
vif.valid <= 0;
continue; // the test's stop_sequences() has flushed this request
end
seq_item_port.item_done();The test must call stop_sequences() before the driver's next try_next_item; here both happen at the 55 ns edge, and the driver next asks at 80 ns. While reset remains high, the driver skips try_next_item. Omit item_done only for a request the sequencer has flushed.
For [U6.1](U6-1-uvm-pipelined-driver.html)’s pipelined get driver, request handoff already completed. Its reset logic instead handles local pending requests and any promised responses. Choose whether those responses complete, abort or disappear before changing its bookkeeping.
Count canceled work and demonstrate recovery
Before reset, 16 produced checked result 17. Accepted 32 added prediction 33, which reset cancels. Offered 48 added no prediction. After reset falls at 70 ns, fresh 80 is accepted at 85 ns and result 81 is checked at 105 ns.
if (r.reset) begin
canceled += expected.size();
expected.delete();
return;
endThe ledger is accepted = checked + canceled + waiting. Here it ends as 3 = 2 + 1 + 0. Canceled work was retired without comparison; recovery is demonstrated by new accepted work reaching a comparison after reset.
Gating the scoreboard around reset is cheaper. Suspend both input paths while reset is sampled, discard the stale predictions, and resume at the first edge after reset falls. The checks_enable knob of [U8.4](U8-4-uvm-metric-analyzer-ledger.html) is read at build time, so flipping it mid-run leaves stale predictions behind. What gating loses is the record of which accepted work reset removed.
The example requires exactly 3 accepted, 2 checked and 1 canceled in check_phase, so a run with no traffic, or with only cancellations, fails. A checked count also includes comparisons that found a mismatch, which are errors in their own right.
A late result needs an identity rule
- Retire old bookkeeping
The scoreboard cancels generation 4 and advances its own counter. That changes stored state, not the bits carried by a future response.
- Reuse the ID
A new request uses ID 3. The scoreboard has a generation-5 prediction for it.
More context
The prediction is right for the new request. The trouble is that ID 3 alone no longer names one request across the reset.
Follow the calls, values and waits
- data new ID 3: New request: ID 3 → Which request?
- Receive an ambiguous reply
An old response arrives with ID 3. Stamping it with the current generation would misidentify it as new traffic.
More context
Reuse needs an observable generation, a proven flush, or a bounded period before the ID may be reused.
Follow the calls, values and waits
- data old ID 3: Old request: ID 3 → Late response: ID 3
- data ID 3 only: Late response: ID 3 → Which request?
Read the diagram as text
- Old request: ID 3: Generation 4; canceled at reset
- Late response: ID 3: No generation on the pins
- New request: ID 3: Generation 5; waiting for a reply
- Which request?: Current generation is not proof of origin
- Old request: ID 3 → Late response: ID 3: late reply
- New request: ID 3 → Which request?: expects 3
- Late response: ID 3 → Which request?: lookup ID 3
Arrows follow prediction and response information. This is an illustrative failure, not output from the runnable incrementer. A testbench counter cannot manufacture missing response identity.
The example’s DUT must not emit canceled 33 after reset. Before new work, that result has no prediction and is an error. After 80 is accepted, it mismatches expected 81. A coincidentally equal stale value could evade this untagged comparison.
A generation counter labels each stretch between resets. Pairing generation with an ID keeps old and new predictions distinct in storage. It only identifies a response if its generation is observable, or the protocol guarantees all old responses are gone before reuse.
Preserve response identity, or delay reuse until a specified drain or flush completes. Never silently discard all post-reset output.
Transfer: a soft reset preserves accepted reads
Change the design: soft reset preserves memory and completes accepted reads within 40 ns, while abandoning unaccepted offers. Decide what happens to the prediction for an accepted read, the offered request and an ID that the test wants to reuse.
Reason through the changed reset rule
Keep the accepted read’s prediction and compare its eventual response. It is waiting work, not a cancellation. Abandon the unaccepted offer only through the matching driver/sequencer procedure.
Preserve the model’s memory contents. Reserve the old ID until its response completes, or use protocol-visible identity that distinguishes the new request. Holding reset or waiting only 20 ns, as this incrementer allows, would be too short: allow the 40 ns completion bound before reusing the ID.
Test reset at idle, during a blocked offer, with accepted work pending and twice in succession. Check both the intended cancellation count and useful work completed after recovery.
Try it
Reset rises at 50 ns, with the result for 32 inside the design and 48 on offer. At 55 ns the scoreboard cancels one prediction and the driver drops 48. After reset, 80 goes in and 81 is checked.
Delete expected.delete(); from the scoreboard's reset branch and rerun: 81 is compared against the stale 33, and 81 is left waiting, so the run also ends at the 2,000 ns global timeout. Then change the driver's wait to while (!vif.ready);, ignoring reset, and read the fatal error.
35 ns scoreboard y=17 checked 50 ns test reset on 55 ns scoreboard reset: 1 prediction(s) canceled 55 ns driver reset: drops x=48, no item_done 70 ns test reset off 105 ns scoreboard y=81 checked inputs 3 = checked 2 + canceled 1 UVM_ERROR : 0Check yourself
Remember
- Derive reset handling from the DUT: accepted work may be canceled, completed, aborted or preserved.
- Coordinate sequencer, driver, monitor, model and every consumer; the same reset does different work in each.
- After this try_next_item request is flushed, the driver drops its offer without item_done; a different handoff protocol needs its own cleanup.
- Accepted equals checked plus canceled plus waiting. Require useful checked work, including after recovery.
- A testbench generation counter cannot identify a stale response unless identity or the flush guarantee makes its origin known.
Practice
- The scoreboard that remembered through reset Fix · Medium