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

AboutContactPrivacyTerms
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
    • UVM with SVA and Formal
    • Leadership and Senior Judgment
    • Interview Bank
      • Concept Round: Phases, Objections and End of Test
      • Concept Round: Factory and config_db
      • Concept Round: TLM and Analysis
      • Concept Round: Sequences, Sequencers and Drivers
      • Concept Round: Agents, Drivers and Monitors
      • Concept Round: Register Layer and Checking
      • Closure and Sign-off Questions
      • Behavioural Round
      • Coding Round: Whiteboard Drills
      • Debug Round: Find the Bug in This Log
      • Architecture Round: Design the Verification
      • High-Frequency Question Index
      • The Senior DV Interview Loop
Loading lesson

‹Interview Bank
  1. Topics
  2. UVM Verification
  3. Senior Prep: Architecture, Leadership and Interviews
  4. Interview Bank
  5. Concept Round: Phases, Objections and End of Test

Part 13/Senior PrepIntermediate

Concept Round: Phases, Objections and End of Test

Ten high-frequency questions on phase order, objections, drain time, phase_ready_to_end, hangs and early ends, each with the weak answer, the senior answer and the follow-ups.

On this page

    The phases round sounds easy, and that is the trap. Every candidate can recite build, connect, run, report. The interviewer is listening for something else: whether you know what the library does when a count reaches zero, which mistakes end a test early and which hang it, and whether you have ever chased one of those at 2 a.m.

    What separates a senior answer is mechanism plus evidence. "Objections propagate up to the top" is a mid-level line; "each component keeps its own count, the test's total includes the sequence's raise, and when it reaches zero the drain timer starts" is a senior one, especially when it ends with "on our DMA bench that is why the scoreboard re-raises in phase_ready_to_end". Each answer below links to the lesson that teaches it in full.

    Area

    What the interviewer is really testing

    Order and phase kinds

    Do you know why build is top-down and what is illegal after it?

    Objections

    Who owns end of test, and what the library reports when you get it wrong.

    End of test

    Drain time versus phase_ready_to_end: a guess versus a condition.

    Failure modes

    Can you tell an early end from a hang, and triage each in minutes?

    The questions

    Why is build_phase top-down, and what goes wrong if you create a component in connect_phase?

    Weak answer: Parents build before children and connect goes bottom-up; creating late is just bad style.

    Strong answer: A parent's build_phase is where its children are created, so a child can only be built after its parent has run. The same order means any config a parent sets before create() is already in place when the child's build calls get(). connect_phase starts only after the whole tree exists, so every port is there to wire; that guarantee matters far more than the bottom-up order. Creating a component after build is not a style issue: the library reports ILLCRT, illegal to create a component after the build phase has ended, as a fatal. On the DMA bench, dma_env creates in_agt, out_agt and sb in build and wires the monitors' analysis ports to the scoreboard in connect.

    Follow-up: “What runs between connect and run?” end_of_elaboration, where the topology is final and unconnected non-analysis ports are reported, then start_of_simulation.

    Follow-up: “Which phases may consume time?” Only run_phase and the 12 runtime phases. A function void run_phase override is a compile error, because run_phase is a task.

    Home lesson: Why build runs top-down

    You call raise_objection in build_phase. What happens?

    Weak answer: It keeps the build phase alive until you drop it.

    Strong answer: Nothing is kept alive: function phases take zero time and have no objection. The call reports UVM_ERROR UVM/PH/NULL_OBJECTION. Objections exist only for task phases. If something in build seems to need waiting, the design is wrong; build must finish in zero time, and anything that waits belongs in a task phase.

    Follow-up: “And dropping an objection you never raised?” A fatal error, OBJTN_ZERO. It usually means two owners each think they raised, or a drop sits on a path that runs twice.

    Home lesson: Function and task phases

    Your test finishes at time 0 with zero errors. What happened?

    Weak answer: The clock never started, or the simulator has a bug.

    Strong answer: No objection was raised at time 0, so run_phase ended at once. The same thing happens later in a test when the last objection drops while a fork ... join_none thread is still sending: the phase ends after the drain time and kills it. That is an early end, not a hang, and it is dangerous because it looks like a pass. On the DMA bench, dma_early_end_test forks the packet sequence with join_none and drops its objection; the only thing that catches it is the scoreboard's empty check, SB_EMPTY ... no words were compared, at 155 ns.

    Follow-up: “How would you make that impossible across a team?” The base test owns one objection around the stimulus; every scoreboard fails when it compared nothing; and nobody waives SB_EMPTY unconditionally. dma_false_pass_test does exactly that and the verdict says PASS with 0 words compared.

    Home lesson: The early-end playbook

    Who should raise objections: the test, the sequence, the driver or the monitor?

    Weak answer: Everyone who is busy raises one, so nothing ends early.

    Strong answer: One owner per phase window, normally the test or the top virtual sequence it starts. Monitors never raise: they run forever and an objection there hangs every test. Drivers neither, for the same reason. A scoreboard joins in only when it still owes outputs, and it does that in phase_ready_to_end, not per transaction. Every component keeps its own count and each ancestor's total includes it, so a raise propagates all the way to the top; per-item raise and drop in a busy sequence costs real time at scale.

    Follow-up: “How do you see who holds the phase open?” phase.get_objection().display_objections() or +UVM_OBJECTION_TRACE. The description string you pass to each raise is what makes that output readable.

    Home lesson: End-of-test strategy

    What is drain time, and how do you choose it?

    Weak answer: A delay at the end of the test, usually 1 us.

    Strong answer: When a component's objection total reaches zero, the drop waits for that component's drain time before it propagates; a raise inside the window cancels the end. Size it from the DUT's worst-case latency from the last input to the last output, in clocks, not from a number copied from another bench: too short truncates checking, too long adds the margin to every test in the regression. It is still a guess. A scoreboard that knows how many outputs are owed ends the test on a fact instead.

    Follow-up: “Where do you set it?” On the owner, usually the test: phase.get_objection().set_drain_time(this, t) before dropping.

    Follow-up: “Drain time or phase_ready_to_end?” Drain time is a fixed delay; phase_ready_to_end is a condition. Prefer the condition when the bench can compute it.

    Home lesson: Drain time in depth

    How does a scoreboard keep the run phase alive until the last output arrives?

    Weak answer: Raise an objection in write() and drop it when the queue is empty.

    Strong answer: phase_ready_to_end is called when the phase's count reaches zero. The DMA bench's dma_scoreboard_eot checks phase.get_imp() != uvm_run_phase::get() || owed == 0 and returns; otherwise it raises, forks a thread that waits for the last word, drops, and returns. Two details make it senior. The owed count must come from what the DUT was asked to do, not from what was seen, or a missing word passes (a real bench bug). And the run-phase test must compare get_imp(): comparing the phase node itself with uvm_run_phase::get() never matches, because get() returns the imp.

    Follow-up: “Can re-raising loop forever?” The library repeats the ready-to-end round each time someone re-raises, capped at 20 iterations by default (set_max_ready_to_end_iterations).

    Follow-up: “Why not raise in write()?” A write that never comes can never raise; the missing output is exactly the case you need to catch. Per-transaction raises are also expensive.

    Home lesson: phase_ready_to_end

    Your sequence runs in main_phase, but the test raises its objection in run_phase. What happens?

    Weak answer: main_phase is inside run_phase, so it is the same thing.

    Strong answer: run_phase belongs to the common domain and the 12 runtime phases to the uvm domain, and they run in parallel. With no objection in main_phase, main_phase ends at once and the uvm domain marches on to post_shutdown; the sequence started from main_phase is killed when its phase ends, while run_phase stays open on the test's objection doing nothing. Raise in the phase where the stimulus actually runs.

    Follow-up: “Why use runtime phases at all?” Ordered reset, configure, main and shutdown windows, and the ability to jump back to reset. Many teams use only run_phase and handle reset inside it, as the DMA bench does.

    Home lesson: run_phase in parallel with the runtime phases

    The regression has a test that hangs. Walk me through it.

    Weak answer: Add more display statements and rerun.

    Strong answer: A hang means a count never reached zero, usually because a thread holding the objection is blocked. First, a timeout must exist (+UVM_TIMEOUT or set_timeout); the 9200 s default is useless. Then name the holder with the objection trace. The classic cause is a driver handshake: dma_hang_noack_test forgets item_done, the sequencer reports Get_next_item called twice without item_done or get in between, the sequence stays blocked in finish_item, and PH_TIMEOUT fires at 5 us. An activity watchdog is better still: dma_activity_watchdog fatals after 2 us with no traffic while the objection total is above zero, and prints the last transfer it saw.

    Follow-up: “Why a watchdog if you have a timeout?” The timeout is sized for the longest legal test; the watchdog fires within microseconds of the stall and tells you where traffic stopped.

    Home lesson: The hang playbook

    How does a sequence raise an objection today, without starting_phase?

    Weak answer: if (starting_phase != null) starting_phase.raise_objection(this);

    Strong answer: starting_phase is deprecated in UVM 1.2 and removed in IEEE 1800.2. Use get_starting_phase(), or call set_automatic_phase_objection(1) in the constructor. The trap is that both act on the starting phase, which exists only when the sequence was started as a default sequence or someone called set_starting_phase(). A sequence started by hand from the test's run_phase has none, and the automatic objection silently does nothing. The robust pattern is the test raising around seq.start().

    Follow-up: “Should child sequences raise too?” No. Only the top sequence or the test; raising per child adds cost and more places to leak a count.

    Home lesson: Sequences and objections

    How does phase.jump() work for a mid-test reset?

    Weak answer: You call jump to reset_phase and the test restarts immediately.

    Strong answer: phase.jump() is a function: it returns, and the jump happens when the current phase ends; it does not kill the calling thread on the spot. Every component must then be safe to re-enter its runtime phases, which is why production benches rarely jump. The DMA bench handles reset on the fly in run_phase instead: reset-aware drivers park the bus, and dma_scoreboard_ra flushes when reset ends, because a beat can complete on the edge where reset asserts.

    Follow-up: “What must the stimulus side do at reset?” Stop the old sequences with kill() and let the driver release its item; stop_sequences() also flushes the item the driver holds, so a following item_done is fatal.

    Home lesson: Reset and phase jumps

    Rapid fire

    Check yourself A colleague adds phase.raise_objection(this) at the top of a monitor's run_phase "to be safe". What happens to every test?

    The monitor's loop never ends, so it never drops. Every test now runs until the timeout. Monitors never raise objections; end of test belongs to the test, plus a scoreboard through phase_ready_to_end when it still owes items.

    Check yourself A scoreboard's phase_ready_to_end tests if (phase == uvm_run_phase::get()) and never extends the phase. Why?

    uvm_run_phase::get() returns the imp, not the phase node passed in, so the comparison is never true. Compare phase.get_imp() with it, or compare phase.get_name() with "run".

    Check yourself A cleanup task calls disable fork after waiting for a timeout branch, and the scoreboard's checker thread disappears. Why?

    disable fork kills every child of the current process, not only the fork above it. Wrap the fork and the disable fork in their own fork begin ... end join so only that subtree dies.

    Next: Concept Round: Factory and config_db: two places configure the same thing; who wins, and why does the answer change after build?

    Previous

    268 / 280

    Next: Concept Round: Factory and config_db

    Up next

    Up nextConcept Round: Factory and config_db

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Concept Round: TLM and Analysis
    • Concept Round: Sequences, Sequencers and Drivers
    • Concept Round: Agents, Drivers and Monitors