Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
Skip to lesson

Course contents

  • Start Here4
  • UVM Foundations14
  • UVM Phases & Simulation Lifecycle26
  • Factory & Configuration15
  • Transaction-Level Modeling (TLM)13
  • UVM Sequences & Stimulus21
  • UVM Agents & Protocol VIP21
  • Environment & Test Classes11
  • Checking & Coverage in UVM21
  • UVM Register Abstraction Layer (RAL)22
  • Advanced UVM in Practice13
  • Debug & Regression10
  • Coding Practice47
  • Verification in Industry Practice10
  • Senior Prep: Architecture, Leadership and Interviews32
    • Verification Architecture and Planning
      • Writing a Testplan from the Spec
      • Estimating Verification Effort
      • A Block Bench That Upstream Can Reuse
      • From Block to Subsystem to SoC
      • Configuration Strategy Across Levels
      • Passive Agents and Who Owns the Check
      • Buy vs Build VIP, and Qualifying VIP
      • Choosing the Verification Strategy per Block
    • UVM with SVA and Formal
    • Leadership and Senior Judgment
    • Interview Bank
Loading lesson

←Verification Architecture and Planning
  1. Topics
  2. UVM Verification
  3. Senior Prep: Architecture, Leadership and Interviews
  4. Verification Architecture and Planning
  5. Passive Agents and Who Owns the Check
On this page

    Part 13 of 15, lesson 6 of 32Part 13 of 15/Senior Prep/Lesson 6 of 32Intermediate

    Passive Agents and Who Owns the Check

    What still runs in a passive agent, the observability rule for keeping block scoreboards, and the DMA's decision record per level.

    At chip level the CPU programs the DMA, the interconnect delivers its input stream, and every one of your agents is passive. A design reviewer asks two questions. Is your block scoreboard still checking anything? And: the subsystem lesson keeps block scoreboards on, but your chip plan turns some off. Which is it? Both are fair, and the answer is neither "always on" nor "always off". It is a rule you can state in one sentence and a record of where you applied it.

    The idea: passive means no driver, not no checking

    A passive agent builds only its monitor. It stops driving because something else, a DUT or a CPU, now owns the bus. Everything that depends only on observation keeps working: the monitor publishes transactions, protocol checks in the monitor or bound to the interface keep firing, and coverage collected from monitored traffic keeps counting. What a passive agent cannot do is create traffic, respond as a slave, or know anything that only a driver knew.

    A football referee is a passive agent. They never touch the ball, but they see every play, apply every rule and keep the record. A referee who could only judge plays they had started themselves would be useless in a real match. A monitor that only works when its own driver is present is that referee.

    Whether a scoreboard keeps running is a separate question with a simple rule: keep a block scoreboard wherever every one of its inputs is still observable by a monitor; turn it off only when some input is not. If the predictor's inputs are on buses you can still watch, the scoreboard is free localisation. If an input disappears (inside a hard macro, folded into another block, or not visible on an emulator), the scoreboard would only produce noise, and a higher-level check must cover that block instead.

    The picture: deciding check ownership

    Flowchart: if every scoreboard input is observable by a monitor, keep the block scoreboard; otherwise turn it off and let a higher-level check cover the block; either way, record the decision.
    The observability rule. The decision, and the reason, go into a short written record per level.

    Build it: what a monitor must not depend on

    The agent side is one if: the monitor is built unconditionally, the driver and sequencer only when active.

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // snippet: from the course DMA bench
    class axis_agent extends uvm_agent;
      `uvm_component_utils(axis_agent)
      axis_sequencer sqr;
      axis_driver    drv;
      axis_monitor   mon;
      uvm_analysis_port #(axis_item) ap;
    
      function new(string name, uvm_component parent);
        super.new(name, parent);
      endfunction
    
      function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        mon = axis_monitor::type_id::create("mon", this);
        if (get_is_active() == UVM_ACTIVE) begin
          sqr = axis_sequencer::type_id::create("sqr", this);
          drv = axis_driver::type_id::create("drv", this);
        end
      endfunction
    
      function void connect_phase(uvm_phase phase);
        ap = mon.ap;
        if (get_is_active() == UVM_ACTIVE)
          drv.seq_item_port.connect(sqr.seq_item_export);
      endfunction
    endclass

    That is necessary, not sufficient. A monitor that will be passive somewhere must be written as if its driver never existed:

    • No driver state. It must not read the driver's variables, wait on events the driver triggers, or assume the sequence's timing. It reconstructs each transfer from the pins alone: for AXI-Stream, a beat is the clock edge where TVALID and TREADY are both high.

    • Its own reset handling. At chip level resets come from a reset controller, not the test. The monitor must drop a half-seen transfer when reset asserts, on its own.

    • No assumptions about traffic shape. The block driver never produced back-to-back beats (the coverage hole gap=0); a real upstream block will. Coverage and checks must handle traffic the block bench never generated.

    • A fresh object per transfer, because more subscribers attach at higher levels, and they store what they receive.

    The decision record for the DMA

    This is the table a reviewer should be able to read for any level. It applies the observability rule to each DMA component:

    Component

    Block

    Subsystem

    Chip

    Reason

    APB agent

    Active

    Active

    Passive

    The CPU owns the register bus at chip level; the monitor still sees every KEY write

    dma0.in_agt

    Active

    Active

    Passive

    At chip level the interconnect feeds dma0

    dma1.in_agt

    Active

    Passive

    Passive

    dut0 drives the middle bus

    out_agt

    Passive

    Passive

    Passive

    The DUT drives it at every level

    dma0.sb, dma1.sb

    On

    On

    On

    KEY, input and output are all observable by monitors

    dma_e2e_scoreboard

    None

    On

    On, or replaced by a memory-model check

    Covers the chain as a whole

    Coverage

    On

    On

    On, merged per instance

    Monitored traffic is real traffic

    Block scoreboard on an emulator

    n/a

    n/a

    Off

    Input bus not captured in the emulator's transactor; chip-level check instead

    This also settles the reviewer's second question. The subsystem and chip lessons agree: block scoreboards stay on, as in vertical reuse, unless an input becomes unobservable, and the record says where that happens and what replaces the check.

    Watch it run: a scoreboard fed entirely by a passive agent

    Diagram
    +UVM_TESTNAME=dma_subsys_test   (run.sh dma_subsys_tb.sv)
    UVM_INFO dma_tb.sv(411) @ 875000: uvm_test_top.env.dma1.sb [SB] 10 words matched, 0 mismatched
    UVM_INFO dma_tb.sv(1182) @ 875000: uvm_test_top.env.e2e [E2E] 10 words matched end to end, 0 mismatched
    • `dma1.sb` matched 10 words with no driver anywhere on its input. Its predictions come from the passive dma1.in_agt watching the middle bus, and its KEY from dma1's APB monitor.

    • The same monitor feeds two checkers: dma0's output monitor and dma1's input monitor both watch mid. Two monitors on one bus cost nothing; two drivers would be a bug.

    What breaks: the monitor that only worked when its driver was there

    A team once moved a block bench to chip level and switched its stream agent to passive. Every chip test passed. Weeks later someone noticed the block scoreboard's line said zero items matched. The monitor had been written to sample on an event the driver triggered after each handshake, because that was easy and it worked in every block test. With the driver gone the event never fired, the monitor published nothing, and the scoreboard compared nothing, silently, because that scoreboard did not fail on an empty run.

    Two habits catch this. First, the course bench's own guard: dma_scoreboard raises SB_EMPTY in check_phase when nothing was compared, and the end-to-end checker raises E2E_EMPTY, so a silent monitor turns into a red test the first night. Second, keep one block-level test that runs every agent passive against a replayed or DUT-driven stream; if the monitor depends on its driver, that test shows it at block level, where it is cheap to fix.

    "Your agent is passive at SoC level. What still runs in it, and who does the checking?"

    A weak answer: "Only the monitor runs, so the SoC scoreboard does all the checking."

    A strong answer gives the rule and the record: "The monitor, its protocol checks and its coverage all still run; only the sequencer and driver are gone. Block scoreboards stay on wherever all their inputs are still observable, because they localise failures. On our DMA, KEY comes from the APB monitor and data from the stream monitors, so both block scoreboards keep checking even with the CPU programming the DMAs. I turn a scoreboard off only when an input disappears, like a bus inside a hard macro or on an emulator, and then a chip-level check covers that block. I write that down per level. And I make sure every scoreboard fails on zero compares, because a passive monitor that depended on its driver goes silent rather than failing."

    Follow-ups: Should coverage be collected in passive mode? (yes: it measures real traffic, often more varied than block stimulus). What can a passive monitor not tell you? (anything only the driver knew, such as the intended transaction before an error was injected).

    Check yourself At chip level the DMA's input comes from a memory-read block whose output bus is inside the same hard macro as the DMA, with no observable pins. What happens to dma0.sb, and what replaces it?

    Its input monitor sees nothing, so its predictions are missing and it would report leftovers or nothing at all. Turn it off with has_scoreboard = 0 and record why. Replace it with a check at the macro boundary: a memory-model scoreboard that predicts the DMA's output from the memory contents and the programmed KEY, or end-to-end checking from the observable source to the sink.

    Check yourself Coverage from passive monitors at chip level shows gap=0 hit thousands of times, though the block regression never hit it. Is that good news?

    It is good news about coverage and a warning about checking. The DMA has now seen back-to-back input that its block regression never generated. Confirm the block scoreboard was on and matched those words, and consider adding a block-level test that reproduces the traffic, because a chip-level failure there would be slower to debug.

    Next: much of what goes passive at chip level is protocol VIP. Buy vs Build VIP is the decision behind it.

    Related topics

    • Two passive monitors, one bus

    • Active and passive in delivery

    • End-of-test checks

    • Active-passive mixes and composition debug

    Previous

    254 / 280

    Next: Buy vs Build VIP, and Qualifying VIP

    Up next

    Up nextBuy vs Build VIP, and Qualifying VIP

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Writing a Testplan from the Spec
    • Estimating Verification Effort
    • A Block Bench That Upstream Can Reuse