Fork/join inside for loop

Hello,

I’m trying multiple forloops and forking inside them. Running into hang issue. Could someone suggest what I’m doing wrong ?

I also apologize for the indentation issues below. Looks fine when I type it, but looses all the coding indentation later.

   forever begin : resetloop
      
      wait(drv_rst_state==RESET_INACTIVE);
          
      fork : resetloop_fork
        for (int i = 0; i < 16; i++) begin
          automatic int j;
          j = i;
          fork
            begin
              main_error_injection_loop(j);
            end
          join_none
        end
        
        for (int i = 0; i < 16; i++) begin
          automatic int j;
          j = i;
          fork
            begin
              event_gen_loop(j);
            end
          join_none
        end

        begin
          wait(drv_rst_state==amd_reset_uvc_pkg::RESET_ACTIVE);
        end
      join_any
      disable resetloop_fork;
    end // block: resetloop

Thanks!

In reply to noel_sumners:

When are you ending this outer process?

forever begin : resetloop
  //...
end // block: resetloop

I don’t need to end that one. It is inside a forever loop and it waits for reset to deassert before forking off the threads. When reset asserts, we disable the forked loops.

But something is messed-up with my forked loops.

In reply to noel_sumners:

The point is, code might be ‘never ending’ because you don’t have any conditions to disable the forever loop.

Also,

forever begin : resetloop
  wait(drv_rst_state==RESET_INACTIVE);

  fork : resetloop_fork

  // Process 1
  fork
  join_none

  // Process 2
  fork
  join_none

  // Process 3
  begin
  wait(drv_rst_state==amd_reset_uvc_pkg::RESET_ACTIVE);
  end

  // You will encounter join_any statement as 
  // Process 1 and 2 finishes immediately.
  join_any
  disable resetloop_fork;

end // block: resetloop

In reply to noel_sumners:

You can use code tags when posting your code. I have added them for you.

Since your for-loops execute with 0 delay, the join_any happens immediately, never waiting for RESET_ACTIVE. I suggest simplifying your code and writing the loop as follows:

forever begin : resetloop
      wait(drv_rst_state==RESET_INACTIVE);
 
      fork begin : body
        for (int i = 0; i < 16; i++) 
          fork
            automatic int j; = i
            main_error_injection_loop(j);
          join_none
        for (int i = 0; i < 16; i++)
          fork
            automatic int j = i;
            event_gen_loop(j);
          join_none
 
        wait(drv_rst_state==amd_reset_uvc_pkg::RESET_ACTIVE);
        disable fork;
      end : body join
    end : resetloop

I discourage the use of disabling named blocks. label names are not re-entrant. If you have multiple activation of this code,( i.e. from multiple instances of a class object) the disable affects all instances. Use disable fork instead.

Thanks Dave! That worked like a charm!! And thanks for the “code tags” pointer. Will use in future.

Thanks Mayur for your comment too!