Issue with fork join

I am seeing an issue with fork join when using within a for loop. I have pasted along with the edaplayground links for both examples

In the first example the sequences are not starting in parallel at the same time though i used a for loop inside a fork join
In the 2nd example i simplified a bare example just to see the flow of fork join vs for loop and that seems to start all the threads at time 0 where as in the 1st example similar concept isn’t starting all my sequences at time0.

Any issues with my code?


class my_sequencer;
  int id;
endclass : my_sequencer

class my_sequence;
  
  task start (my_sequencer seqr);
    int delay = $urandom_range(1,10);
    $display("time: %0d, starting sequence on sequencer with id:%d", $time, seqr.id);
    #(delay * 1us);
    $display("time: %0d, finishing sequence on sequencer with id:%d", $time, seqr.id);
  endtask : start
endclass : my_sequence


module top;
  int temp;
  initial begin
    my_sequencer seqr;
    my_sequencer seqr_q[$];
    my_sequence seq[$];
    my_sequence s;
    static int num_of_seqr = $urandom_range(3,5);
    
    for (int i = 0; i < num_of_seqr; i++) begin
      seqr = new;
      seqr.id = i;
      seqr_q.push_back(seqr);
    end
    
    $display("queue size is %0d",seqr_q.size);
       
   temp = seqr_q.size;
    $display("temp = %0d",temp);
    
    //s = my_sequence::type_id::create("s");   
    s = new(); 
    for(int i=0;i<temp;i++)
      seq.push_back(s);
     
    //seq = new[seqr_q.size()];
    //foreach(seqr_q[i]) seq[i] = my_sequence::type_id::create("seq[i]");
    foreach(seqr_q[i]) seq[i] = new();
    fork begin
      for(int i=0;i<seqr_q.size();i++)begin
        seq[i].start(seqr_q[i]);end
      end
    join
    
    wait fork;

      $display("time%0d, end reached", $time);
  end
endmodule 



queue size is 3
temp = 3
time: 0, starting sequence on sequencer with id:          0
time: 10000, finishing sequence on sequencer with id:          0
time: 10000, starting sequence on sequencer with id:          1
time: 19000, finishing sequence on sequencer with id:          1
time: 19000, starting sequence on sequencer with id:          2
time: 29000, finishing sequence on sequencer with id:          2
time29000, end reached
           V C S   S i m u l a t i o n   R e p o r t 



// Code your testbench here
// or browse Examples


module test;

   initial begin
 
  
     $display("-------------------------------");
  
    
       fork
     	begin
         for(int j=0;j<4;j++) begin
     	
           $display("Thread  %d, %d",j,$time);
           //#1;
         end 
        end
         
         
         begin
           $display("Thread new %d",$time);
         end
         
           
       join
       
       
     end
          
  endmodule




Compiler version Q-2020.03-SP1-1; Runtime version Q-2020.03-SP1-1;  Mar 26 17:21 2021
-------------------------------
Thread            0,                    0
Thread            1,                    0
Thread            2,                    0
Thread            3,                    0
Thread new                    0
           V C S   S i m u l a t i o n   R e p o r t 

In reply to hsam:

You want to be using fork/join_none, not fork/join. Also see https://verificationacademy.com/forums/systemverilog/fork-joinnone-inside-loop#reply-46114

In reply to dave_59:

Thanks. I just had to change the fork to use join_none and use the for loop outside fork and rely on an automatic variable to get this issue resolved.

The thread was very helpful. Thanks a lot Dave as always.



class my_sequencer;
  int id;
endclass : my_sequencer

class my_sequence;
  
  task start (my_sequencer seqr);
    int delay = $urandom_range(1,10);
    $display("time: %0d, starting sequence on sequencer with id:%d", $time, seqr.id);
    #(delay * 1us);
    $display("time: %0d, finishing sequence on sequencer with id:%d", $time, seqr.id);
  endtask : start
endclass : my_sequence


module top;
  int temp;
  initial begin
    my_sequencer seqr;
    my_sequencer seqr_q[$];
    my_sequence seq[$];
    my_sequence s;
    static int num_of_seqr = $urandom_range(3,5);
    
    for (int i = 0; i < num_of_seqr; i++) begin
      seqr = new;
      seqr.id = i;
      seqr_q.push_back(seqr);
    end
    
    $display("queue size is %0d",seqr_q.size);
   
   
   temp = seqr_q.size;
    $display("temp = %0d",temp);
    
    //s = my_sequence::type_id::create("s");   
    s = new(); 
    for(int i=0;i<temp;i++)
      seq.push_back(s);
     
    //seq = new[seqr_q.size()];
    //foreach(seqr_q[i]) seq[i] = my_sequence::type_id::create("seq[i]");
    foreach(seqr_q[i]) seq[i] = new();
    
    for(int i=0;i<seqr_q.size();i++)begin
      //create an automatic variable to store loop value for each thread 
      automatic int k= i;
      	fork
          seq[k].start(seqr_q[k]);
 		join_none
    end
    

      $display("time%0d, end reached", $time);
  end
endmodule 

queue size is 3
temp = 3
time0, end reached
time: 0, starting sequence on sequencer with id:          0
time: 0, starting sequence on sequencer with id:          1
time: 0, starting sequence on sequencer with id:          2
time: 6000, finishing sequence on sequencer with id:          1
time: 8000, finishing sequence on sequencer with id:          2
time: 10000, finishing sequence on sequencer with id:          0