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

  • RTL Foundations36
  • Combinational Design25
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
    • Low-Power RTL Hub
    • DFT and Scan Hub
    • Physical Awareness Hub
    • Waveform Debug Hub
    • STA and ECO Hub
    • RTL-to-Implementation Closure
    • DFT-Ready RTL
    • Capstone: Resilient Streaming Peripheral
    • Principal Design Review
    • Senior RTL Interview Questions & Model Answers
      • Interview: Combinational and Arithmetic
      • Interview: Sequential and Pipelines
        • Blocking vs non-blocking: the race demo
        • Pipeline latency vs throughput
        • Stalling without deadlock
        • Enables, resets and counters
      • Interview: FSM and Control
      • Interview: Timing and STA
      • Interview: CDC and Reset
      • Interview: Memories and Buses
      • Interview: Low-Power Design
      • Interview: Debug and ECO
      • Interview: Coding and Whiteboard
  • Glossary and Notation
Loading lesson

‹Interview: Sequential and Pipelines
  1. Topics
  2. RTL Design
  3. Senior & Interview
  4. Senior RTL Interview Questions & Model Answers
  5. Interview: Sequential and Pipelines
  6. Blocking vs non-blocking: the race demo

Part 9 · Senior · Senior

Blocking vs non-blocking: the race demo

Why clocked logic uses non-blocking assignments, shown by two deterministic ordering examples.

On this page

    Why this matters

    With the same input, one register pair returns 0x20 where the other returns 0x10, only because of statement order. Interviewers use this to test whether the blocking rule is a habit or a slogan.

    After this lesson you can: predict the output of blocking and non-blocking shift pairs cycle by cycle, and explain the rule through the scheduling regions.

    The question

    The interviewer asks for the blocking vs non-blocking rule, then follows with a two-rank shift: two registers fed in series from one input, and a swap as a follow-up. The question tests whether the rule is a habit or a slogan.

    What is really under test is cycle discipline. The candidate must predict simulation behaviour from assignment order and say which form synthesizes to the intended registers.

    Model answer

    Use non-blocking assignments (<=) in clocked always_ff blocks and blocking assignments (=) in combinational always_comb blocks. The reason is scheduling, not style.

    An NBA evaluates its right-hand side when the statement executes and schedules its destination update for the NBA region. With inputs stable before the edge, one writer per register and no blocking communication between clocked processes, this models parallel registers reading old state. It does not literally evaluate before the clock edge.

    Context

    Use

    Why

    Clocked always_ff

    Non-blocking q <= d

    Parallel old-state model under stable inputs and disciplined single ownership.

    Combinational always_comb

    Blocking y = a & b

    Immediate update; later statements see earlier ones, like gates.

    Temporary inside always_ff

    Blocking for a combinational intermediate read in the same pass

    Safe only when the temporary is written before it is read and never spans an edge.

    The comparison below feeds both styles the same rising input. Within each single process the result is deterministic, not a simulator race: a agrees while b differs because of statement ordering.

    • Slot 0: d is 0x10. Both a outputs read 0x10. b_nba still reads 0x00 while b_blk already reads 0x10.

    • Slot 1: d is 0x20. b_nba reads 0x10 (the old a) while b_blk reads 0x20 (the new a).

    • Slot 2: d is 0x30. b_nba reads 0x20 while b_blk reads 0x30.

    • Slot 3: d is 0x40. b_nba reads 0x30 while b_blk reads 0x40.

    • Slot 4: d is 0x50. b_nba reads 0x40 while b_blk reads 0x50.

    • Slot 5: d is 0x60. b_nba reads 0x50 while b_blk reads 0x60.

    The NBA pair describes two register ranks. In a = d; b = a;, both registers capture d at the same edge; synthesis can merge equivalent registers. Simulation and synthesis agree on that behavior, but it is not the intended two-rank shift register.

    Follow-ups

    What does a = b; b = a; in one clocked block mean? Both assigned values become the pre-edge b: the second statement reads the newly assigned a. Synthesis preserves that dependency; it does not infer an NBA-style swap. To exchange old values use a <= b; b <= a;. A separate race risk occurs when multiple clocked processes exchange values using blocking assignments and observe execution-order-dependent updates.

    When is a blocking assignment inside clocked logic acceptable? For a combinational temporary written and read within the same pass, before any non-blocking update. The temporary never holds state across an edge.

    NBA is not universal order independence. In one process, q <= a; q <= b; leaves q with b after NBA; reversing the statements leaves a. Also, a testbench driving d with blocking assignment at posedge races a DUT reading d in the active region, even if the DUT uses NBA. Drive away from the accepting edge and observe after NBA, as below.

    Common wrong answers

    A weaker candidate says blocking logic runs faster. Assignment type sets scheduling and data dependencies, not a guaranteed speed. Those dependencies can change inferred register ranks and allow register merging.

    Another says non-blocking belongs everywhere for safety. In combinational blocks it delays updates to the end of the pass, which mismatches gate behaviour and can hold stale values across branches.

    The blocking pair agrees with its own assignment semantics but disagrees with the intended two-rank reference.

    Common pitfall

    Blocking assignments in clocked logic make data dependencies depend on statement order. Reordering two lines can change the inferred hardware. Use an independent behavioral reference; use synthesis/equivalence checks when making claims about the mapped netlist.

    Interview

    State the rule with the mechanism: non-blocking in clocked logic because every register samples pre-edge values in parallel.

    Check yourself Both pairs see d rise from 0x10 to 0x20. Which b output takes the value 0x20 at that edge, and why?

    The blocking b. It reads the already-updated a. The NBA b reads the pre-edge a, so it takes 0x10 and reaches 0x20 one edge later.

    Solution and testbench

    Both shift pairs plus the testbench that sweeps every 8-bit input and checks each against its reference.

    shift_nba.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    module shift_nba (
      input  logic       clk, rst_n,
      input  logic [7:0] d,
      output logic [7:0] a, b
    );
      always_ff @(posedge clk or negedge rst_n)
        if (!rst_n) begin a <= 8'h00; b <= 8'h00; end
        else begin a <= d; b <= a; end             // parallel update: b takes the OLD a
    endmodule
    
    module shift_block (
      input  logic       clk, rst_n,
      input  logic [7:0] d,
      output logic [7:0] a, b
    );
      always_ff @(posedge clk or negedge rst_n)
        if (!rst_n) begin a = 8'h00; b = 8'h00; end
        else begin a = d; b = a; end               // immediate update: b takes the NEW a
    endmodule
    

    Remember

    • An NBA evaluates its right side now and updates the destination later, so registers read old state.

    • Blocking assignments in clocked logic make the hardware depend on statement order.

    • Drive testbench inputs away from the accepting edge and observe after NBA.

    Rule of thumb: non-blocking in clocked blocks, blocking in combinational blocks, and say why.

    How this was checked

    Bench run with Icarus Verilog 13.0 (2026-10-16): prints PASS. It sweeps every 8-bit input against each reference. Passing this simulation shows only the checked behaviour of each model, not a synthesis mismatch or a mapped implementation.

    Keep going

    • Practice: Blocking vs non-blocking in sequential logic

    • Interview: run a mock interview on this topic

    Related topics

    • Edge-triggered state elements

    Previous

    317 / 350

    Next: Pipeline latency vs throughput

    Up next

    Up nextPipeline latency vs throughput

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Stalling without deadlock
    • Enables, resets and counters
    clkd102030405060a_nba102030405060b_nba01020304050b_blk102030405060
    A blocking pair and an NBA pair fed the same rising input