For loop inside fork join_none

are code 1 and code 2 same in system verilog.

code 1

fork 
thread1();
thread2();
for(i=0;i<32;i++) begin
thread3(i);
end
join_none

code 2

fork 
thread1();
thread2();
thread3(0);
thread3(1);
.
.
.
thread(31);
join_none

In reply to pawan:

No. Each statement in a fork is a concurrent thread. A for loop is a single statement and each iteration gets executed serially.

In reply to dave_59:

In that case what’s the solution for this kinda situation where u want to execute same task with different value all at same time.

In reply to pawan:

fork 
  thread1();
  thread2();
join_none
for(int i=0;i<32;i++)
  fork
     int j = i;
     thread3(j);
  join_none

In reply to dave_59:

any reason to do int j=i; rather den just using i ?

In reply to pawan:

Pawan,

If int j=i, and thread3(j) is not used, then it results in calling thread3(32) 32 times in parallel and will not meet your purpose.

Dave,
Shouldn’t the variable ‘j’ declaration be automatic here? (automatic int j = i;)
Otherwise we will hit the same issue again, Is my understanding correct?

In reply to S.P.Rajkumar.V:

Yes, j needs to be declared automatic if this code is not inside a class.

See https://verificationacademy.com/forums/systemverilog/fork-joinnone-inside-loop#reply-38644

In reply to dave_59:
i wrote this code along with declaring automatic int j=i;
now its happening like this
thread3(0);
thread3(1);
thread3(2);
thread3(3);

.
.
.thread3(31);
thread3(31);
thread3(30);
.
.
.
.
thread3(0);

In reply to pawan:

Are you calling thread3(j) twice in the second fork … join_none?
Post your code here.

In reply to S.P.Rajkumar.V:

In reply to pawan:
Are you calling thread3(j) twice in the second fork … join_none?
Post your code here.

for(int i=0; i<32; i++) begin
fork
automatic int j=i;
capture_lookup(j);
join_none
end

this capture lookup is being called 2 time for each of 32 values capture_lookup is a task which has a forever loop inside.

In reply to pawan:

You need show how the for loop gets called. Where is it defined? Also, put a breakpoint or $display statement before the for loop and see if you are hitting it twice.

In reply to dave_59:

In reply to pawan:

fork 
thread1();
thread2();
join_none
for(int i=0;i<32;i++)
fork
int j = i;
thread3(j);
join_none

hi dave why cant we simply use thread3(i) why are we declaring another variable and assing i to j. i am still not clear on this part

In reply to pawan:

Because each procedural statement inside a fork/join_none becomes a process, and that process does not start until after all the for-loop iterations. So there are 32 pending calls to thread(i) and only one instance of the variable i. And that variable will have the value 32 after the for-loop completes. So 32 is the argument that gets passed down to all 32 calls to thread3().

Now assume j is an automatic variable because this code is inside a class, or explicity declared with the prefix automatic keyword. Automatic variables get created and initialized each time the scope they are declared in gets activated. A fork/join activates a scope just like a begin/end block. A declaration is not a procedural statement (even thought the initialization may look like one). It does not become a pending process of a fork.

The code below is slightly modified, but functionally equivalent to the previous example

for(int I=0;i<32;i++)
  begin
     automatic int j = i; // automatic not needed if this code is inside a class
     fork
        begin
          thread3(j);
        end
     join_none
   end

The declaration of j is now outside the fork/join_none block, but still inside the scope of the for-loop statement. It doesn’t matter. There still will be one instance of j per iteration of the for-loop, and each initialization value of j will get the current value of i for that iteration.

In reply to dave_59:

Hi Dave,

Sorry for digging up a old post.

I tried running the modified code where the declaration of J is moved from the fork…join_none to the scope of for loop. But the processes spawned by the fork…join_none seems to get the final iteration’s value only.

module tb;
    initial begin
     for( int i =0; i<3 ; i++) begin
      automatic int k =i;
      fork begin
        $write ("%d ", i);
      end
      join_none
     end
    end
endmodule

the above code in EDA playground run using VCS prints 3 3 3. If the join_none is changed to join the output is 0 1 2.

In reply to MadhanM:

You want to write k, not i.

In reply to dave_59:

sorry, that was a typo. yet it does not change my observation or the results.

In reply to MadhanM:

If you are using a simulator on EDAplayground, it has a bug. Choose a different simulator.

In reply to dave_59:

Thanks for the reply. I will try in another simulator.

In reply to S.P.Rajkumar.V:

Hi Rajkumar, Can you please elaborate on the below statement please:

If int j=i, and thread3(j) is not used, then it results in calling thread3(32) 32 times in parallel and will not meet your purpose.

If i=31, thread(31) will be spawned.
If i=32, then for loop does not execute right because i<32 condition is not met.