Part 7 · Advanced & Integration · Intermediate

Q&A: Races & Scheduling

Interview-format answers — TB races, NBA vs blocking at the boundary, clocking blocks, program blocks, assertion sampling, force vs deposit — with senior vs junior contrasts.

Core questions

Q1: What is a TB race and how do you prevent it?

A race exists when two processes scheduled in the same region of the same time step touch the same signal, and the LRM leaves their order to the simulator — so two legal executions give two different results. The canonical case is a testbench blocking drive or immediate sample at the same clock edge the RTL uses. Prevention is region separation : RTL uses nonblocking assignments internally, and the TB samples and drives through clocking-block skews (inputs in Preponed, output drives in Re-NBA), so no TB access competes with RTL in the Active region. Delays like #0 or #1 only relocate the ambiguity.

Q2: Explain NBA vs blocking at the boundary.

A blocking assignment updates its target immediately, mid-Active-region — other processes at the same edge see old or new value depending on run order. A nonblocking assignment splits read and write: the right side is read now, the left side updates later in the NBA region, after every same-edge process has done its reads . That read-all-then-update-all discipline is why NBA-coded RTL is internally deterministic, and why a TB blocking write into that edge re-introduces the very ambiguity NBA removed.

Q3: What does a clocking block actually do?

Two things, both about when , not what. Inputs are sampled with #1step skew — the stable pre-edge value from the Preponed region, the same value the design's flops capture. Output drives are applied in the Re-NBA region — after all RTL reads for that edge are complete, so the design consumes them at the next edge. It does not reorder the scheduler; it moves TB sample and drive points into regions where no design process competes, making every legal ordering produce the same result. The bundled signal view, modport enforcement, and ##N cycle delays come along with it.


Differentiating questions

Q4: Program block vs clocking block — are they the same fix?

No — they attack the same race from different directions. A program block moves where TB code executes (the Reactive region, after design settling). A clocking block moves where TB signal accesses take effect (Preponed sampling, Re-NBA driving) regardless of where the code runs. Modern class-based methodology generally treats clocking blocks as the essential piece and program blocks as optional — a module-based TB that strictly samples and drives through clocking blocks is already race-free at the boundary.

Q5: Why does my assertion see a different value than my $display?

Because they read in different regions. A concurrent assertion samples its operands in Preponed — the value just before the edge. A $display inside an always_ff prints mid-Active, and $monitor/$strobe print the settled Postponed value, after NBA updates. On the edge where a counter goes 4 to 5: the assertion judges 4, an in-block $display shows 4, and $strobe shows 5. All three are correct — they are snapshots of different pipeline stages of the same time step.

Q6: Force vs deposit — when each?

Force is a continuous override: the signal is pinned and every driver loses until an explicit release — right for error injection windows and documented bring-up hacks, dangerous when forgotten because the net is dead from then on. Deposit sets a value once and lets normal drivers overwrite it at their next evaluation — right for initializing state or preloading memories. Rule of thumb: deposit to set a starting point, force-with-guaranteed-release to temporarily overrule the design, and both only through a centralized, auditable access layer.


Senior vs junior contrasts

diagram
SAME QUESTION, TWO ANSWERS

  Q: "Your test passes on VCS and fails on Questa. What now?"

  Junior: "File a Questa bug; VCS is our sign-off tool anyway."
  Senior: "Both behaviors are probably LRM-legal — that fingerprint
           means a same-region race. Find the blocking drive or raw
           sample at the RTL's clock edge, route it through the
           clocking block, and the test will pass on BOTH."

  Q: "There's a #0 in the driver. Should I remove it?"

  Junior: "It works, don't touch it."
  Senior: "A #0 is a fossilized race. Find what ordering it was
           papering over, fix it with cb skews or an event
           handshake, then delete the #0 — otherwise the next
           optimization flag flips the coin again."

  Q: "Why not just force the FSM into the error state to test it?"

  Junior: forces it inline in the test, no release, ships it.
  Senior: adds inject/restore tasks to the hierarchy-access layer
          with an ID and owner, scopes the force to one test,
          releases on every exit path — and asks whether a real
          stimulus sequence could reach that state instead.

What interviewers are actually probing

  • Whether you explain races with the region model (mechanism) or with anecdotes (luck).

  • Whether you know clocking-block skew semantics precisely — #1step Preponed sampling is the give-away detail.

  • Whether you treat #0, #1, and stray forces as debt to remove, not tricks to keep.

  • Whether your cross-boundary access story includes audit and removal, not just capability.

Key takeaways

  • Answer race questions with the region pipeline — Preponed sampling, Active reads, NBA updates, Re-NBA TB drives.

  • Clocking blocks make ordering irrelevant; program blocks relocate code; know the difference crisply.

  • Assertion-vs-$display discrepancies are region snapshots, not bugs — explain which region each reads.

  • Senior answers always include the discipline: centralized XMRs, released forces, deleted #0s.

Common pitfalls

  • Saying 'add a small delay' as a race fix in an interview — instant credibility loss.

  • Claiming program blocks are required for race-free TBs — clocking-block discipline is the load-bearing piece.

  • Confusing #1step with a 1ns delay when explaining input skew.

  • Describing force for initialization where deposit is correct — it signals you have been burned by neither.