← Design Verification Interviews

Interview Question · Concept

Blocking vs Nonblocking Assignments

L0 FresherL1 Juniorsystemverilogschedulingraces
  • Asked at NVIDIA

The Question

The interviewer asks

What is the difference between a blocking (=) and a nonblocking (<=) assignment, and which one do you use for flip-flops?

Reveal the Model Answer

A blocking assignment (=) updates its target at once. So the next statement in the same block already sees the new value. A nonblocking assignment (<=) reads its right-hand side now, but schedules the update for the NBA region. That region runs after every process woken by the edge has read the old values. Use <= for flops in clocked blocks, so the result does not depend on process order. Use = for combinational logic and temporaries.

Two Pipelines Fed by the Same InputA two-stage pipeline written with <= and the same pipeline written with =, fed by the same input. One column per clock period; the rising edges at 5, 15 and 25 start columns 1 to 3.
0123clkd11223344a1 (<=)00112233a2 (<=)001122b1 (=)00112233b2 (=)00112233
  1. Cycle 0

    Before the first edge, d is 11 and both pipelines hold 00.

  2. Cycle 1

    At t=5 the <= pipeline moves 11 into a1 only, and a2 takes the old 00. The blocking pipeline copies 11 into both stages.

  3. Cycle 2

    The value 11 reaches a2 one edge later. b2 never lags b1: the blocking version behaves as one register.

  4. Cycle 3

    After t=25, a2 holds 22 and b2 holds 33, as the last $strobe line shows.

Data moves one stage per edge only when each stage reads the value from before the edge.

  1. Active region

    Every process woken by posedge clk runs. Each <= evaluates its right-hand side with pre-edge values.

  2. NBA region

    All the scheduled updates land together, so q2 <= q1 got the old q1.

  3. Back to Active

    Anything sensitive to the new values runs, in the same time step.

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Fresher)

A good fresher answer says = updates at once, while <= updates at the end of the time step. It says flops use <=, and shows a two-stage shift register going wrong with =.

Cross-Questions

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

WhyWhat IfProve ItBreak ItCompareScale It

  1. Blocking vs Nonblocking Assignments
  2. WhyWhy Nonblocking Makes Process Order IrrelevantL1 Junior

    Two clocked always blocks read each other's outputs. Why does <= make the result independent of which block the simulator runs first?

    Reveal the Model Answer

    With <=, neither block changes a variable during the Active region; each only reads and schedules. Whichever block runs first, both read the same pre-edge values. The updates all land later, in the NBA region. With =, the first block to run changes its output before the second reads it. So the order decides the answer.

    Self-Check

    Tick each key point you covered in your answer.

    What Interviewers Listen For (Junior)

    A good junior answer walks through both orders of the two blocks. It shows they give the same values with <= and different values with =.

    Misconception

    "<= makes the simulator run all always blocks at the same instant."

    Processes still run one after another. The order stops mattering because no process sees another one's update until the NBA region.

    Source IEEE 1800-2017 §4.9.4, §4.7

  3. Break ItBreaking a Clocked Block with a Blocking TemporaryL1 JuniorL2 Mid-Level

    A clocked block computes tmp = a + b; and then sum <= tmp;. Another always block also reads tmp at the same edge. What can go wrong?

    systemverilog
    always @(posedge clk) begin
      tmp = a + b;
      sum <= tmp;
    end
    always @(posedge clk) observed <= tmp;
    Reveal the Model Answer

    Inside the block the code is fine, because tmp is a local temporary. The bug is the second reader: it may run before or after the first block in the same Active region. So it sees either the old or the new tmp. Keep blocking temporaries local to their block, or declare them inside it. Share only flop outputs written with <=.

    Two Legal Orders at One EdgeOne rising edge wakes a writer and a reader in the same Active region. Arrows from the edge and from the Active region are wake-ups and run order; arrows to and from the pins are values.
    Two legal orders at one edgeOne rising edge wakes a writer and a reader in the same Active region. Arrows from the edge and from the Active region are wake-ups and run order; arrows to and from the pins are values. event Rising edge t=5: clk becomes 1 region Active region woken processes;order not specified process Racy driver rdata = a1 after@(posedge clk) process Raw monitor reads rdata after@(posedge clk) signal racy_bus pins rvalid, rdata wakes bothrunsrunswritesreads
    1. The edge wakes botht=5 (illustrative)

      The rising edge at t=5 wakes the driver and the monitor. Both are now waiting to run in the Active region of the same time step.

      Follow the calls, values and waits
      1. call driver: Rising edge → Active region
      2. call monitor: Rising edge → Active region
    2. Order A: driver firstt=5 (illustrative)

      If the scheduler runs the driver first, rdata is already a1 when the monitor reads it. The monitor sees the new beat.

      Follow the calls, values and waits
      1. call run: Active region → Racy driver
      2. data rdata = a1: Racy driver → racy_bus pins
      3. call run: Active region → Raw monitor
      4. data reads a1: racy_bus pins → Raw monitor
    3. Order B: monitor firstt=5 (illustrative)

      If it runs the monitor first, the monitor reads 00, the value from before the edge. The standard allows both orders.

      Follow the calls, values and waits
      1. call run: Active region → Raw monitor
      2. data reads 00: racy_bus pins → Raw monitor
      3. call run: Active region → Racy driver
      4. data rdata = a1: Racy driver → racy_bus pins
    4. Move the write off the edget=5 to t=7 (illustrative)

      A drive through drv_cb with output skew 2 lands at t=7. At t=5 every reader sees 00, in any order, so the race is gone.

      More context

      The DUT reads the pins at the same edge, so it is exposed to the race in exactly the same way as the monitor.

      Follow the calls, values and waits
      1. data reads 00: racy_bus pins → Raw monitor
      2. data rdata = a1 at t=7: Racy driver → racy_bus pins
    Read the diagram as text
    • Rising edge: t=5: clk becomes 1
    • Active region: woken processes; order not specified
    • Racy driver: rdata = a1 after @(posedge clk)
    • Raw monitor: reads rdata after @(posedge clk)
    • racy_bus pins: rvalid, rdata
    • Rising edge → Active region: wakes both
    • Active region → Racy driver: runs
    • Active region → Raw monitor: runs
    • Racy driver → racy_bus pins: writes
    • racy_bus pins → Raw monitor: reads

    A result that depends on which process runs first is not a result. Remove the race; do not pick a winner.

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "Mixing = and <= in one clocked block is always illegal."

    The language allows it. A blocking temporary that only its own block reads is a common, safe pattern. The danger is a temporary that another process reads at the same edge.

  4. Prove ItSolve 6.2.1: The Pipeline That Lost a StageSimulator-graded

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

    Open Problem 6.2.1

  5. What IfA Testbench That Drives on the Sampling EdgeL1 JuniorL2 Mid-Level

    Asked once they say flops use <=

    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

  6. 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

  7. CompareClocking Blocks vs Driving on the Falling EdgeL2 Mid-Level

    Compare a clocking block with driving stimulus on the falling edge as ways to avoid testbench races.

    Reveal the Model Answer

    Driving on the falling edge puts drives and samples in different time steps, so it is simple and race-free. But it only works for single-edge designs with a known duty cycle. A clocking block samples inputs just before the active edge (#1step, the Preponed region). It drives outputs after a set skew, so the testbench stays cycle-based on the real edge. Clocking blocks scale to agents and interfaces; falling-edge drives suit small directed benches.

    Self-Check

    Tick each key point you covered in your answer.

    Spec Misquote

    "An input skew of #1step means one nanosecond before the edge."

    1step is one unit of the time precision, not one nanosecond. The sample is taken in the Preponed region, so it reads the values from just before the edge.

    Source IEEE 1800-2017 §14.4, §4.4.2.1

  8. What IfReading a Clockvar After the Raw EdgeL2 Mid-Level

    Asked if they write a monitor with clocking blocks

    A monitor waits for @(posedge clk) and then reads cb.rdata. It sometimes reports the previous beat. What happened?

    systemverilog
    clocking cb @(posedge clk);
      default input #1step;
      input rdata;
    endclocking
    initial forever begin
      @(posedge clk);
      $display("rdata=%h", cb.rdata);
    end
    Reveal the Model Answer

    Clockvars (the sampled signals of a clocking block) are updated when the clocking event is processed, in the Observed region. A process that resumes on the raw posedge clk can read cb.rdata before that update. It then gets the previous sample. Wait on @(cb) instead, so the read happens after the clockvars change.

    Self-Check

    Tick each key point you covered in your answer.

  9. Scale ItKeeping a Large Testbench Race-FreeL3 SeniorL4 Staff

    You lead verification for a block with several UVM agents. How do you keep the testbench-to-DUT boundary race-free across the whole team?

    Reveal the Model Answer

    Every agent touches the DUT only through clocking blocks in its interface. Drivers write clockvars with <=, and monitors wait on the clocking event and read sampled values. No class code reads or writes raw DUT signals at an edge. Assertions sit in the interface or are bound to the DUT. Lint rules catch blocking writes in clocked blocks, and reviews treat raw signal access in a driver as a defect.

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "Add #1 delays to the drivers until the tests pass."

    A #1 means different times under different time precisions, and it breaks once gate delays appear. It hides the race instead of removing it.

    Source Spear & Tumbush, SystemVerilog for Verification (3rd ed.) ch. 4 p141

    Wrong Altitude

    A senior answer that lists UVM classes but never says where sampling happens.

    At this level the interviewer wants the mechanism and the team rule, not the class names.

What People Get Wrong

Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.

Misconception

"In a clocked block, = and <= give the same flops. It is only coding style."

Statements in one block run in order. So q1 = d; q2 = q1; copies the new d straight into q2, and one flop disappears. The twin shows it after a single edge.

Run It

Two flops written with = in one clocked block. After one edge, does q2 still hold the old q1?

RUNIcarus Verilog · in your browser
Edit the code, then run it
Expected: after one edge: q1=1 q2=1 FAIL: q2 already holds d, so the two flops collapsed into one
See the Fix
module tb;
  logic clk = 0, d = 0, q1 = 0, q2 = 0;
  // The fix: nonblocking updates, so q2 samples q1 from before the edge.
  always @(posedge clk) begin
    q1 <= d;
    q2 <= q1;
  end
  initial begin
    d = 1;
    #5 clk = 1;
    #1 $display("after one edge: q1=%0b q2=%0b", q1, q2);
    if (q2 !== 1'b0) $display("FAIL: q2 already holds d, so the two flops collapsed into one");
    else $display("PASS: q2 still holds the old q1, so there are two flops");
  end
endmodule

Prints: after one edge: q1=1 q2=0 PASS: q2 still holds the old q1, so there are two flops

Misconception

"Nonblocking assignments run in parallel, like real hardware."

The simulator still runs one statement at a time. <= only delays the update to the NBA region, so every right-hand side is read before any target changes.

Source IEEE 1800-2017 §4.9.4, §10.4.2

Tool as Truth

"My simulator runs always blocks in file order, so this race is fine."

The standard leaves the order of processes in one region unspecified. Another simulator, version or file order can pick a different order. That can flip the result.

Source IEEE 1800-2017 §4.6, §4.7

Buzzword Without Mechanism

Names the NBA region but cannot say what it changes.

Knowing the term is not the answer. The point is that every reader at the edge sees pre-edge values. That is why process order stops mattering.

Learn It, Then Prove It