Parallel Thread execution inside for loop →
TRAIL 1 :
OUTPUT → Thread i=5 is spawned five times
Reason why this dint work :
• Loop Variable Sharing: In this snippet, the loop variable i is shared among all iterations. When
the fork block is executed, it captures the reference to i. Since i is incremented in each iteration, by
the time the threads actually run, i has already reached its final value (5).
• Thread Execution: All threads will see i as 5, leading to unexpected behavior because they all
operate on the same variable.
TRAIL 2 :
Lets try declaring a local variable inside a for loop – say int local_i like below
OUTPUT → Thread i=4 is spawned five times (NO LUCK!!)
The issue arises because the local_i variable is declared inside the loop but not as an automatic variable.
In System Verilog, variables declared inside a loop are not automatically treated as automatic, meaning
they do not get a unique instance for each iteration of the loop. As a result, all forked threads end up
sharing the same local_i variable, which holds the final value of i (which is 4 after the loop completes).
TRAIL 3 :
Lets try declaring a local variable inside a for loop – say automatic int local_i like below
OUTPUT → All threads are spawned as expected (YAY!!)
Any guess why automatic int local_i worked???
Here’s why :
• Scope and Lifetime: The automatic variable local_i is created anew for each iteration of the loop,
ensuring that each thread gets a unique value.
• Thread Safety: Each thread operates on its own copy of local_i, preventing the threads from
interfering with each other.
TRAIL 4 :
Lets add automatic int local_i inside fork-join_none
OUTPUT → Thread i=5 is spawned five times
The reason you're seeing 5 5 5 5 5 is because the fork block captures the value of i at the time
the fork block is created, not when the thread actually runs. By the time the threads execute, the loop has
completed, and i has reached its final value of 5.
Even though local_i is declared as automatic inside the fork block, it still captures the value of i at the time
the fork block is created. This means all threads end up seeing the final value of i, which is 5.
TRAIL 5 :
Lets remove the begin end of fork-join_none, so automatic int local_i and thread(local_i) are two parallel
threads
OUTPUT → All threads are spawned as expected (YAY!!)
1. Scope of automatic Variable:
• With begin and end: The automatic int local_i = i; declaration and the thread(local_i); call
are enclosed within a begin and end block. This ensures that local_i is treated as a local
variable within the scope of the begin and end block, and each forked process gets its own
instance of local_i.
• Without begin and end: The automatic int local_i = i; declaration and
the thread(local_i); call are not enclosed within a begin and end block. This means
that local_i is still treated as an automatic variable, but the scope is limited to the single
statement following the fork.
2. Behaviour:
• With begin and end: Each forked process has its own begin and end block, ensuring
that local_i is unique to each process.
• Without begin and end: The fork statement directly forks the thread(local_i); call
with local_i being an automatic variable. This still works correctly because local_i is
declared as automatic, ensuring each forked process gets its own copy of local_i.
Do try out more cases, I’ll love to know if there are more possible scenarios :
Here’s the EDA Playground session
SystemVerilog Randomization - EDA Playground