← Design Verification Interviews

Interview Question · Project Defence

Chasing a One-in-500 Failure

L3 SeniorL4 Staffsystemverilograndomizationdebugregression

The Question

The interviewer asks

Walk me through how you reproduce and fix a test that fails on about one seed in 500 in the nightly regression. This is what the log gives you.

log
Illustrative regression excerpt
[nightly] axi_stress seed=1984327711 FAILED at 1284330 ns
  UVM_ERROR scoreboard.sv(212) @ 1284330: [SB] read data mismatch id=5 exp=0x3c07 got=0x0000
[nightly] axi_stress 499 other seeds PASSED
[rerun]   axi_stress seed=1984327711, same build, same plusargs: FAILED at 1284330 ns
Reveal the Model Answer

First rerun that seed with the same build, test and plusargs. This log shows it fails again, so the trigger is in the stimulus. Then find the first divergence between DUT and model, dumping waves only around it, and decide which side is wrong. After the fix, rerun the seed and a fresh batch. Then add a cover point and a directed sequence for the corner. The next code change will move the random stream away from it.

From One Failing Seed to a Fixed and Guarded BugThe order of work after a rare regression failure. Arrows show the next step.
From one failing seed to a fixed and guarded bugThe order of work after a rare regression failure. Arrows show the next step. component Rerun the seed same build, test andplusargs component Find the firstdivergence DUT against model;waves only around it component Does not failagain look for races,uninitialised values,the environment component Fix the wrong side the DUT or the bench component Rerun the seedand a fresh batch the fix holds andnothing else broke component Guard the case a cover point or adirected test fails againpasses
Read the diagram as text
  • Rerun the seed: same build, test and plusargs
  • Find the first divergence: DUT against model; waves only around it
  • Does not fail again: look for races, uninitialised values, the environment
  • Fix the wrong side: the DUT or the bench
  • Rerun the seed and a fresh batch: the fix holds and nothing else broke
  • Guard the case: a cover point or a directed test
  • Rerun the seed → Find the first divergence: fails again
  • Rerun the seed → Does not fail again: passes
  • Find the first divergence → Fix the wrong side
  • Fix the wrong side → Rerun the seed and a fresh batch
  • Rerun the seed and a fresh batch → Guard the case

A saved seed stops reaching the bug after the next bench change, so the last step matters.

  1. Pin the recipe

    Seed, build, test name and plusargs together. One missing argument and the rerun proves nothing.

  2. Reproduce

    Same seed, same build. A pass here means the cause is not the seed: a race, an uninitialised value or an outside input.

  3. Find the first divergence

    The scoreboard error is where it was noticed, not where it started. Walk back to the first wrong transaction.

  4. Fix and lock in

    Rerun the seed and a new batch, and add a cover point and a directed sequence so the corner is hit every night.

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Senior)

A good senior answer first asks whether the seed fails again on the same build. It keeps the seed, the build and the arguments together as one recipe.

Cross-Questions

Where the interviewer goes next. Open a node to practise that follow-up.

WhyWhat IfProve ItBreak ItCompareScale It

  1. Chasing a One-in-500 Failure
  2. WhyWhy a Seed Stops Reproducing After a ChangeL2 Mid-LevelL3 Senior

    Why can the failing seed stop failing after an unrelated testbench change, before any fix?

    Reveal the Model Answer

    A seed fixes the root generator, and every thread and object derives its own seed from its parent in creation order. Add a component, reorder construction or change a loop count, and later objects get different seeds and different stimulus. The bug is still there; the seed just no longer reaches it.

    Creation Order Hands Out the SeedsWhere each object's seed comes from in two runs with the same seed. Arrows show seeds handed to new objects; the dashed pulse is a call to srandom.
    Creation order hands out the seedsWhere each object's seed comes from in two runs with the same seed. Arrows show seeds handed to new objects; the dashed pulse is a call to `srandom`. process Run 1: creatingprocess its generator handsout seeds in order object Burst generator created first: firstseed process Run 2: creatingprocess the same run seed object Debug object created first: firstseed object Burst generator created second:second seed call srandom(seed +1) called right after new newnewnewsets the seed
    1. Run 1

      An object's generator is seeded when the object is created, from the generator of the process that creates it. In run 1 the burst generator is created first and takes the first seed.

      Follow the calls, values and waits
      1. data first seed: Run 1: creating process → Burst generator
    2. Run 2

      In run 2 a debug object is created first and takes that seed. The burst generator gets the next one, so its whole sequence of bursts changes.

      Follow the calls, values and waits
      1. data first seed: Run 2: creating process → Debug object
      2. data second seed: Run 2: creating process → Burst generator
    3. Seed it on purpose

      Calling srandom right after new, with a seed derived from the run's seed, fixes the generator's stream. Adding or reordering other objects no longer shifts it.

      Follow the calls, values and waits
      1. call run seed + 1: srandom(seed + 1) → Burst generator
    Read the diagram as text
    • Run 1: creating process: its generator hands out seeds in order
    • Burst generator: created first: first seed
    • Run 2: creating process: the same run seed
    • Debug object: created first: first seed
    • Burst generator: created second: second seed
    • srandom(seed + 1): called right after new
    • Run 1: creating process → Burst generator: new
    • Run 2: creating process → Debug object: new
    • Run 2: creating process → Burst generator: new
    • srandom(seed + 1) → Burst generator: sets the seed

    Calls on one object never disturb another object's stream; only the order of creation hands out different seeds.

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "The edit fixed the bug, since the seed passes now."

    Without a cover point showing the corner was reached, a passing seed after a change is not evidence of a fix.

    Source Spear & Tumbush, SystemVerilog for Verification (3rd ed.), ch. 6.16.3 (PDF p258)

  3. What IfA Failure Its Own Seed Cannot ReproduceL3 Senior

    Asked if the rerun passes

    What if the same seed on the same build passes when you rerun it?

    Reveal the Model Answer

    Then something besides the seed decides the outcome. Look first for races between testbench and DUT, which can flip with process order. Then check uninitialised values, code that depends on $time or the environment, and the rerun command. Running the seed on a second simulator or with different process ordering often makes a race show itself.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Senior)

    A good senior answer lists the other inputs that can change the result, most likely first. It starts with races at the boundary between testbench and DUT.

    Wrong Altitude

    "Mark it flaky and move on."

    A failure that depends on process order is a real race. It will show up again on another simulator or version, usually at a bad time.

  4. Break ItA Testbench That Drives on the Sampling EdgeL1 JuniorL2 Mid-Level

    The testbench does @(posedge clk) start = 1; and the DUT samples start in always_ff @(posedge clk). Sometimes the DUT reacts a cycle early. Why?

    systemverilog
    // Testbench
    initial begin
      @(posedge clk) start = 1;
    end
    // DUT
    always_ff @(posedge clk) accepted <= start;
    Reveal the Model Answer

    The testbench process and the DUT flop wake on the same edge, in the same region, and their order is unspecified. If the testbench runs first, the DUT samples the new start on that same edge. That is a cycle earlier than real hardware would. Drive after the edge, through a clocking block or with <=, so the DUT always samples the pre-edge value.

    A blocking write at the edge where the DUT samples
    0123clk edge1234din (blocking at edge)11223344q (DUT)old or 1111 or 2222 or 3333 or 44din (NBA at edge)11223344q with NBA driveold112233order unspecified

    With a blocking write, q depends on which process runs first. With a nonblocking write, the DUT always sees the value from before the edge.

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "Put #0 before the drive and the race is gone."

    #0 moves the process to the Inactive region. That works only until another process also uses #0. Then their order is unspecified again, and the result can differ between simulators.

    Source IEEE 1800-2017 §4.4.2.3; Spear & Tumbush, SystemVerilog for Verification (3rd ed.) ch. 4 p141

    Tool as Truth

    "It passes on our simulator, so the testbench is correct."

    Passing on one tool only shows one legal order. The standard allows either order, so the test can fail after a tool update.

    Source IEEE 1800-2017 §4.7

  5. Prove ItSolve 6.7.1: The Monitor That Saw the FutureSimulator-graded

    Show it, don't just say it: this Silicon Lab problem is graded by the simulator.

    Open Problem 6.7.1

  6. CompareKeep the Random Seed or Write a Directed TestL3 Senior

    Once the bug is fixed, do you add the failing seed to the regression, or write a directed test for the corner? Compare them.

    Reveal the Model Answer

    A saved seed is cheap but brittle: the next testbench change moves its stimulus, and it quietly stops testing the corner. A directed test, or a constrained sequence aimed at the corner, keeps hitting it whatever else changes. Add a cover point for the corner as well, so the regression report shows whether random tests reach it on their own.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Senior)

    A good senior answer prefers a directed or targeted test, because it keeps working after the bench changes. It adds a cover point as proof that the case is still hit.

    Half-Truth

    "Add the seed to a golden list and rerun it every night."

    It reruns the same seed, not the same stimulus. After a few changes it tests something else while still passing.

  7. Scale ItTriage When the Nightly Shows Hundreds of FailuresL4 Staff

    At subsystem level the nightly run shows 300 failing seeds. How do you organise triage so the team works on causes, not symptoms?

    Reveal the Model Answer

    Bucket failures automatically by first error signature, with addresses and IDs stripped, and pick the shortest reproducing seed per bucket. Assign each bucket an owner and track it to a cause, because one bug often produces dozens of signatures downstream. Rerun failing seeds automatically to separate reproducible failures from flaky ones, and treat the flaky list as bugs to fix, not noise.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Staff)

    A good staff answer designs the triage flow and its numbers: buckets, owners and how often failures reproduce. It refuses to let flaky failures become accepted background noise.

    Wrong Altitude

    Assigns engineers to failures in log order.

    Several engineers end up debugging the same root cause while other buckets wait.

What People Get Wrong

Common wrong answers and why they fail.

Tool as Truth

"After the fix, rerun that seed; if it passes, the bug is fixed."

Any testbench change can shift the random stream, so that seed may no longer reach the corner. Passing proves nothing until coverage shows the corner was hit.

Source IEEE 1800-2017 §18.14

Wrong Altitude

"Launch 5,000 more seeds and see how often it happens."

That spends a farm on statistics before anyone has looked at the one reproducible failure in hand.

Half-Truth

"If the seed does not reproduce it, it must be a simulator bug."

Testbench races, uninitialised values and inputs such as file order or wall-clock time are far more common causes.

Delivery

Jumps straight into the waveform without saying how reproduction was confirmed.

A senior answer states the reproduction recipe and the plan before the debug session. Without it, the fix cannot be verified.

Learn It, Then Prove It