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

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Puzzle Bank
  • SystemVerilog Language Puzzles25
    • Datatype and Bit Puzzles
    • Fork Join Puzzles
      • join vs join_any vs join_none
      • Loop Variable Capture in Detached Threads
      • wait fork Synchronization Point
      • disable Named Fork Scope
      • join_any Without Cleanup
      • Inner disable fork Does Not Kill Outer Sibling
    • Queue and Array Puzzles
    • String and Casting Puzzles
    • SystemVerilog Language Puzzles: Tricky Q&A
  • Difficulty Guide
  • Full Topic Map
  • Interview-Day Tips
  • Study Route: One Week Before the Interview
  • Study Route: Two Weeks
  • Study Route: Four Weeks (Full Course)4
  • OOP & Testbench Puzzles25
  • Concurrency & Timing Puzzles25
  • Randomization & Constraint Puzzles25
  • SVA Assertion Puzzles25
  • Functional Coverage Puzzles25
  • Logic & Aptitude Puzzles25
  • Scenario & Debug Puzzles25
  • UVM Testbench Puzzles25
  • Clock, Reset & CDC Puzzles25
  • Bus and Interface Protocol Puzzles25
  • Interview Prep: Puzzle Rounds7
  • DV Puzzle Cheatsheet
Loading lesson

←Fork Join Puzzles
  1. Topics
  2. DV Interview Puzzles
  3. SystemVerilog Language Puzzles
  4. Fork Join Puzzles
  5. Loop Variable Capture in Detached Threads
On this page

    VLSI DV Interview PuzzlesAll levels

    Loop Variable Capture in Detached Threads

    Predict every line printed by the two loops and explain why they differ. The LRM does not define the order of lines printed in the same time step, so give the values.

    Puzzle

    Difficulty: Medium · Puzzle 2 of 6 · Topic: Fork Join Puzzles

    Predict every line printed by the two loops and explain why they differ. The LRM does not define the order of lines printed in the same time step, so give the values.

    Code

    p2.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    `timescale 1ns/1ns
    module p2;
      int i;
      initial begin
        // Loop A
        for (i = 0; i < 3; i++) begin
          fork
            #1 $display("A i=%0d", i);
          join_none
        end
        #2;
        // Loop B
        for (i = 0; i < 3; i++) begin
          automatic int k = i;
          fork
            #1 $display("B k=%0d", k);
          join_none
        end
        #2;
      end
    endmodule

    Hint

    Count the storage locations the children can see: one variable for the whole loop, or one variable per iteration. Then ask what that variable holds one time unit later.

    Step-by-step solution

    Diagram
    1) In loop A every child reads the single module-level variable `i`. The parent finishes the loop at the same time step with `i == 3` and children only run at t=1, so all three print `A i=3`.
    2) In loop B, `k` is declared automatic inside the loop body, so every iteration allocates a new `k` initialised from the current `i` before the child forks (LRM 6.21 variable lifetime, 9.3.2 fork/join_none example). The three children print their own copies: 0, 1 and 2.
    3) The rule: static storage is shared by everything that names it, automatic storage is created per entry into the block.

    Answer

    Answer: Loop A: `A i=3` three times. Loop B: `B k=0`, `B k=1`, `B k=2` (one each, order within the time step not defined)

    How this was checked

    Checked by running the code in Verilator 5; the printed output supports the answer above. The three A lines all show 3 (shared static i) while the B lines show per-iteration copies. Order of the B lines within one time step is not defined by the LRM, so each value is checked on its own. Order of the B lines within one time step is not defined by the LRM, so each value is checked on its own. Order of the B lines within one time step is not defined by the LRM, so each value is checked on its own.

    Why candidates get it wrong

    Loop A prints 3 three times because the children share one static variable that the finished loop left at 3; and the order of the three lines in loop B is not guaranteed by the language even if tools print 0, 1, 2.

    Interviewer follow-up

    What if loop A is written `for (int j = 0; j < 3; j++) fork #1 $display(j); join_none`: is it 0,1,2 or 3,3,3? Model answer: do not rely on it, tools differ (Icarus prints 3 3 3, Verilator 5.048 prints 0 1 2), so always copy the index into an `automatic` variable inside the loop body, as loop B does.

    Say it out loud

    I would ask which variable each child reads, because that is what decides the output. In the first loop the children share one static variable that the loop leaves at 3, so I get three lines saying 3. In the second loop each iteration has its own automatic copy, so I get 0, 1 and 2. The trap is that the order of those three lines in the second loop is not defined by the language, even if a tool prints them in order, and the first style can even differ between tools. I would check that every forked child copies the loop index into an automatic variable.

    Related topics

    • Threads and Control: Fork, Disable, Wait, Process

    • Back to Fork Join Puzzles

    • SystemVerilog Language Puzzles section

    Previous

    18 / 293

    Next: wait fork Synchronization Point

    Up next

    Up nextwait fork Synchronization Point

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • join vs join_any vs join_none
    • disable Named Fork Scope
    • join_any Without Cleanup