A regression job intermittently stalls near end-of-test despite DUT waveforms appearing idle and reset clean. Logs show no fatal error, but simulation never exits under CI seeds.
The signal you would look at: Mismatch between expected test completion time and observed run timeout rate across nightly regressions.
Whether you localise before you theorise: you ask what is stuck before you guess why.
Whether you separate three different hangs that look the same from outside: simulation time frozen, time moving but the phase never ends, and one process blocked forever.
Whether your fix removes the cause structurally instead of hiding it behind a bigger timeout.
Follow these steps in order. The order matters: each step narrows the search so that the next one is cheap.
Restate the symptom and ask what changed: which seed, which test, which recent commit. Ask whether the same seed hangs every time.
Decide which kind of hang it is: does simulation time stop advancing (a zero-delay loop), does time advance but the run phase never ends (an objection that is never dropped), or is one process blocked for ever (a get, a lock, a missing item_done)?
Ask for the outstanding objections and who raised them. If the count is not zero at the timeout, you have your first suspect.
Walk the handshake: count get_next_item against item_done on every branch, including early continue, return and error paths.
Name the hypothesis in one sentence and say which log line would prove it or kill it.
Fix the structure (drop or release on every exit path), then add a guard: a watchdog that reports which phase and which component is still holding things, not a larger global timeout.
A model transcript of the first part of the round. Do not memorise the words; copy the order of the moves.
Interviewer: A nightly test hangs about one seed in twenty. Waves look idle. Where do you start?
Candidate: First question: does simulation time still advance at the hang, or is it frozen? That splits a zero-delay loop from a phase that never ends.
Interviewer: Time advances. The clock keeps toggling until the CI timeout.
Candidate: Then the run phase is not ending, so I suspect an outstanding objection or a process that never returns. I would print the outstanding objections and their owners at the timeout.
Interviewer: One objection is still held by the test. The test calls a helper that has an early return.
Candidate: That is the classic leak: raise_objection runs, the early return bypasses drop_objection. I would check every exit path of that helper, and also whether a join_none background thread is still running.
Interviewer: Why not just raise the global timeout?
Candidate: A bigger timeout hides the leak and makes every real hang slower to find. I would make the drop structural so every exit path passes through it, and keep a timeout only as a watchdog that prints who holds the objection.
Interviewer: Suppose the objection count is zero but the test still stalls.
Candidate: Then a process is blocked. I would look for a driver waiting on get_next_item with no item_done on one branch, a semaphore token that was never returned, or a bounded mailbox that is full with nobody reading.Assuming DUT deadlock first while missing a UVM objection leak in the environment.
Ignoring blocked mailbox/semaphore paths because basic smoke tests pass.
Adding coarse global timeouts instead of isolating the offending phase or process.
Fixing the one leaking branch you found without checking the other exit paths of the same task.
Work these cold, with the timer, before you rehearse the conversation.
dead-002: Background Poller Keeps Running After Traffic Ends (M)
round-002: Round Walkthrough: Objection Deadlock with Clean Waves (H)