Mechanism and evidence
Delivery is not a completed barrier.
Track acknowledgements from four required listeners in epoch 27. Duplicate and stale responses cannot satisfy a new obligation.
↓ Send to all four recipients
↓ Collect current-generation acknowledgements
Checkpoint 1 · Freeze the generation’s required set.
- ACK EPOCH
- —
- RECEIVED
- 0000
- REQUIRED
- 1111
- BARRIER
- closed
Compare all 5 checkpoints
1 · Freeze the generation’s required set.
- ACK EPOCH
- —
- RECEIVED
- 0000
- REQUIRED
- 1111
- BARRIER
- closed
2 · A acknowledges epoch 27.
- ACK EPOCH
- 27
- RECEIVED
- 0001
- REQUIRED
- 1111
- BARRIER
- closed
3 · B acknowledges epoch 27.
- ACK EPOCH
- 27
- RECEIVED
- 0011
- REQUIRED
- 1111
- BARRIER
- closed
4 · C and D acknowledge the current generation.
- ACK EPOCH
- 27
- RECEIVED
- 1111
- REQUIRED
- 1111
- BARRIER
- open
5 · Retire the complete generation.
- ACK EPOCH
- 27
- RECEIVED
- 1111
- REQUIRED
- 1111
- BARRIER
- complete
Freeze the generation’s required set.
- Epoch
- 27
- ACK mask
- 0000
- Barrier
- Closed
Broadcast generation 27 to A, B, C, and D. Until every unique required listener acknowledges this generation, the barrier stays closed.
Record the epoch and required recipient set before sending the event.
Inspect the checker Selected checkpoint pseudocode
required[27] = {A, B, C, D};
acked[27] = {};Example contract & limitations
Example contract. The listener set is frozen to A, B, C, D for epoch 27. Acknowledgements include generation and listener identity. The production event-broadcast snippet requires this additional generation-aware barrier tracking. Checkpoints show selected state changes, not equally spaced simulation cycles.
Read the complete walkthrough
Four unique acknowledgements
- Freeze the generation’s required set.. Broadcast generation 27 to A, B, C, and D. Until every unique required listener acknowledges this generation, the barrier stays closed. Evidence: Record the epoch and required recipient set before sending the event.
- A acknowledges epoch 27.. A’s first valid acknowledgement adds one bit to the received set. Evidence: Correlate listener A and generation 27.
- B acknowledges epoch 27.. B contributes a second distinct listener to the current generation. Evidence: Compare both recipient identity and generation before changing the mask.
- C and D acknowledge the current generation.. The remaining received bits are merged. Only a complete required set permits release. Evidence: Compare the received mask against the frozen required mask.
- Retire the complete generation.. Every required unique recipient has acknowledged epoch 27. Retire the barrier once. Evidence: Verify one release and no reuse of the retired generation’s acknowledgements.
Duplicate ACK from A
- Freeze the generation’s required set.. Broadcast generation 27 to A, B, C, and D. Until every unique required listener acknowledges this generation, the barrier stays closed. Evidence: Record the epoch and required recipient set before sending the event.
- A acknowledges epoch 27.. A’s first valid acknowledgement adds one bit to the received set. Evidence: Correlate listener A and generation 27.
- A repeats its acknowledgement.. A duplicate set insertion is idempotent. The count stays at one. Evidence: Compare both recipient identity and generation before changing the mask.
- C and D acknowledge the current generation.. The remaining received bits are merged. Only a complete required set permits release. Evidence: Compare the received mask against the frozen required mask.
- B’s valid ACK finally completes the set.. When B finally acknowledges epoch 27, the mask becomes complete. Earlier duplicate/stale traffic never advanced the barrier. Evidence: Verify one release and no reuse of the retired generation’s acknowledgements.
Stale epoch-26 ACK
- Freeze the generation’s required set.. Broadcast generation 27 to A, B, C, and D. Until every unique required listener acknowledges this generation, the barrier stays closed. Evidence: Record the epoch and required recipient set before sending the event.
- A acknowledges epoch 27.. A’s first valid acknowledgement adds one bit to the received set. Evidence: Correlate listener A and generation 27.
- B sends an old acknowledgement.. An epoch-26 ACK cannot satisfy B’s epoch-27 obligation. Preserve it as stale evidence. Evidence: Compare both recipient identity and generation before changing the mask.
- C and D acknowledge the current generation.. The remaining received bits are merged. Only a complete required set permits release. Evidence: Compare the received mask against the frozen required mask.
- B’s valid ACK finally completes the set.. When B finally acknowledges epoch 27, the mask becomes complete. Earlier duplicate/stale traffic never advanced the barrier. Evidence: Verify one release and no reuse of the retired generation’s acknowledgements.
Related implementation: Global reset broadcast and subscribers
// --- Inside the Virtual Sequence (The Broadcaster) ---
task body();
uvm_event e = uvm_event_pool::get_global("PORESET_EVT");
send_broadcast_packet();
e.trigger(); // Notify everyone the reset has started
endtask
// --- Inside every Agent/Monitor (The Subscriber) ---
task run_phase(uvm_phase phase);
uvm_event e = uvm_event_pool::get_global("PORESET_EVT");
forever begin
e.wait_trigger();
`uvm_info(
"AGT",
"Global Reset Observed! Flushing...",
UVM_LOW
)
this.flush();
end
endtaskThe broadcaster and every subscriber resolve the same global event name. The event follows the DUT broadcast packet, and each listener flushes local state.
Understand the failure+
A typed control-plane message fans out without hierarchy wiring, and the coordinator tracks recipient epochs so stale or duplicate acknowledgements cannot release the test.
release when unique acknowledged recipients = required mask for the current message epoch
One broadcast, many synchronized listeners
The virtual sequence publishes one command and event; listeners consume shared state and converge at an acknowledgement barrier.
- Virtual sequence
- Sends the DUT broadcast packet and owns publication timing.
- Global event
- Named synchronization point used by every subscribed agent.
- Shared config object
- Carries frequency, power state, or other data-heavy payload.
- 100 listeners
- Agents enter Sync State or flush local scoreboards without hierarchy pointers.
- Barrier
- Collects completion from the required subscriber population.
- Broadcast packet -> DUT control plane
- Publication milestone -> global event
- Shared config version + event -> every listener
- Listener reaction -> barrier acknowledgement
- Barrier threshold reached -> test resumes
Why it matters
- A 64-core SoC may need every core to enter low-power mode or invalidate its cache together.
- The verification goal is not only delivery. The command must reach every destination and take effect in the required cycle relationship.
- A scalable testbench needs a global notification mechanism so deeply nested agents can synchronize without a web of upward and downward pointers.
What is difficult
- UVM hierarchy makes direct Agent A to Agent B communication awkward without routing through the environment.
- A broadcast may need to notify 100 agents without scattering uvm_config_db paths or explicit component handles.
- Timing-only events are simple, but data-heavy commands also carry frequency, power state, or other configuration payload.
- The test must know when every subscriber has completed its reaction before proceeding.
Failure signatures
- One or more agents miss the global event and retain stale state.
- Agents react in different cycles even though the architectural command requires simultaneous effect.
- A timing event arrives but its associated configuration payload is stale.
- The test proceeds before all listeners flush or enter their synchronized state.
- An overly broad global event name collides with unrelated hierarchy behavior.
- Point-to-point handles make the environment fragile when agents are added or relocated.
Compare approaches+
Two viable approaches—and their cost
Global UVM event pool
Every agent subscribes to a named event obtained from uvm_event_pool.
- Strong hierarchy decoupling.
- New listeners can subscribe without changing the broadcaster.
- Delivery acknowledgement is not automatic.
- Payload and event-name ownership need a deliberate convention.
Shared global configuration object
Every agent holds a handle to one state object that carries the current global command data.
- Carries complex values such as a new frequency or power state.
- All listeners observe the same object without copying configuration fields.
- A field mutation alone does not provide an ordered notification or completion acknowledgement.
- Readers need synchronization so they do not observe a partially updated state.
Explain it in an interview+
Interview answer, built from the mechanism
- I avoid point-to-point connections for an SoC-wide control plane. A named event from uvm_event_pool acts as the testbench messaging bus.
- When the virtual sequence sends a global command, such as cache invalidate, it triggers the event. Each subscriber enters its sync state or flushes its scoreboard regardless of hierarchy depth.
- For data-heavy broadcasts, I put the payload in a shared typed configuration object and use the event as the publication boundary.
- A uvm_barrier or explicit acknowledgement tracker prevents the test from continuing until the required listener count has completed its reaction.
Assign responsibilities+
Component responsibility contract
| Component | Responsibility | Required change |
|---|---|---|
| Environment | Central dispatch | Create the uvm_event or publish the shared configuration object. |
| Agent | Listener | In run_phase, use wait_trigger() or a synchronized loop on a configuration state. |
| Virtual Sequence | Trigger | Trigger the notification when the broadcast packet is sent to the DUT. |
Build the checker+
Implementation patterns
// --- Inside the Virtual Sequence (The Broadcaster) ---
task body();
uvm_event e = uvm_event_pool::get_global("PORESET_EVT");
send_broadcast_packet();
e.trigger(); // Notify everyone the reset has started
endtask
// --- Inside every Agent/Monitor (The Subscriber) ---
task run_phase(uvm_phase phase);
uvm_event e = uvm_event_pool::get_global("PORESET_EVT");
forever begin
e.wait_trigger();
`uvm_info(
"AGT",
"Global Reset Observed! Flushing...",
UVM_LOW
)
this.flush();
end
endtaskThe broadcaster and every subscriber resolve the same global event name. The event follows the DUT broadcast packet, and each listener flushes local state.
Stress the design+
Stress recipe
- Instantiate the representative 64-core topology or 100 listener agents.
- Send a global cache-invalidate or low-power packet to the DUT.
- Trigger the matching testbench event only at the defined packet milestone.
- Record the cycle at which every listener enters Sync State or flushes its scoreboard.
- Require every listener to acknowledge through a barrier before normal stimulus resumes.
- Repeat with a data-heavy frequency or power-state update and prove listeners observe one coherent payload version.
- Start one subscriber late in a negative test to expose event-persistence and missed-trigger assumptions.
Follow-up questions
How do you ensure all agents finished their reaction before the test continues?
Use a uvm_barrier with the required listener threshold. Every participating agent waits or acknowledges at the barrier, and the test proceeds only after the threshold is satisfied.
What is the difference between a local and global event pool?
A global pool is accessible throughout the testbench. A local pool is owned by a particular hierarchy or object context. Use global naming sparingly for true SoC-level reset and power events.
How do you handle data in a broadcast?
Use a shared, typed Global Config Object for data-heavy state and an event for the timing or publication boundary.

