Part 6 · Testbench Architecture · Intermediate

Testbench Synchronization & Phasing

Hub — component handshakes, hand-built phasing, the objection pattern, TB race conditions, and coordinating parallel agents.

Overview

A class-based testbench is a set of free-running threads — generator, driver, monitors, model, scoreboard — and the hard part is not writing them but coordinating them: who tells whom that work is available, how the bench moves from reset to traffic to checking, and crucially how everyone agrees the test is over . Every mechanism UVM provides for this (phases, objections, barriers) can be built by hand from mailboxes, events, and semaphores — and building them once is the best way to understand why UVM looks the way it does.

The same primitives that coordinate components can also deadlock them or race them. This topic covers the handshake patterns that work, the phase discipline that keeps a bench ordered, an objection counter built from scratch, the same-timestep races that corrupt sampling, and the coordination of multiple agents on multiple interfaces.

Sub-topics

  1. Component Handshakes — done signaling, request-response, blocking vs nonblocking calls, deadlock patterns.

  2. Phasing a Hand-Built TB — reset/config/main/drain/report phases by convention, env-orchestrated run().

  3. End-of-Test: The Objection Pattern by Hand — from naive #delay to a raise/drain objection class.

  4. TB Race Conditions — same-timestep event races, mailbox ordering, NBA discipline, clocking blocks.

  5. Coordinating Parallel Agents — multi-interface benches, event barriers, scenario coordinator, EOT aggregation.

diagram
SYNCHRONIZATION MAP OF A HAND-BUILT TB

              env.run()  ── orchestrates phases in order ──
                 │
   reset ──► config ──► main ──► drain ──► report
                          │
              ┌───────────┼──────────────┐
              ▼           ▼              ▼
          generator ──► driver       monitors ──► scoreboard
              │  mbx (handshake)         │   mbx (stream)
              │                          │
              └── done? ───┐   ┌──── done? ──┘
                           ▼   ▼
                     objection counter == 0  AND  drain idle
                           │
                           ▼
                    end of test  report phase

Key takeaways

  • Coordination is the real design problem in a class-based TB — threads are the easy part.

  • Phases, objections, and barriers are all buildable from mailboxes, events, and semaphores.

  • End-of-test must be a positive agreement among components, never a guessed #delay.