Disabling all the threads called in a fork join

Hi
Please let me know how i can disable all the threads inside a fork join

 for(int i =0 ; i < total; i = i + 1)begin
    fork 
      automatic int j = i;
      create_commands(j);  
    join_none
  end

How do i disable all the threads at the same time after a particular wait statement?

You can use a disable fork statement to disable all threads forked by the current thread. You may need to wrap your code with another fork/join to isolate any other fork/join_none threads you may have spawned before the one inside this loop.

...
fork
  begin 
   for(int i =0 ; i < total; i = i + 1)
    fork 
      automatic int j = i;
      create_commands(j);  
    join_none
  wait(for_something_particular);
  disable fork;
  end
join
...

Another option is to use the fine-grain process control described in section 9.7 of the 1800-2012 LRM. You can create a list of process you want to disable with the process::kill() method.

In reply to dave_59:

Thanks Dave. The solution works !

In reply to meenu2k11:

Hi Dave,

I had a question on this. If we disable a fork. Is there anyway to reenable it later ? I thought once we disable a fork and next time the same task is called again the fork gets enabled again…
But it does not work like that. In the code snippet below it looks like once the disable fork() in task monitor_sb_transaction gets activated. It does not execute the threads once this task is called again.

And because of this my test is stuck here in this task: check_transaction() on this message foreover: Actual transaction seen in interface: SRC_ID: %0h, DEST_ID:%0h, OPCODE: %0h … Waiting for Expected Transaction …

How to fix this problem. WHat I want here is when the task monitor_transaction() is called again the threads should not be disabled from last invocation of the task.

 task monitor_transaction();
        fork
	begin
          wait ((vif.p || vif.np) == 1); 
        end
	begin: timeout
	  #1us;
            `ovm_fatal(get_name(), $psprintf("Timeout ..." ))
	end
 	join_any
 	disable fork;
    endtask 
    
   task check_transaction(input logic[7:0]src_id, [7:0] dest_id, [7:0] opcode);

       if((vif.src_id == src_id) && (vif.dst_id == dest_id) && (vif.opcode == opcode)) begin
         `ovm_info(get_name(), $sformatf("Detected Expected  transaction: SRC_ID: %0h, DEST_ID:%0h, OPCODE: %0h", src_id, dest_id, opcode), OVM_MEDIUM);
       end else begin
         `ovm_info(get_name(), $sformatf("Actual transaction seen in interface: SRC_ID: %0h, DEST_ID:%0h, OPCODE: %0h .. Waiting for Expected Transaction: SRC_ID: %0h, DEST_ID:%0h, OPCODE: %0h", vif.src_id, vif.dst_id, vif.opcode,src_id,dest_id,opcode), OVM_MEDIUM); 
          monitor_and_check_transaction(src_id,dest_id,opcode);     
       end	      
    endtask 

   task monitor_and_check_transaction(input logic[7:0]src_id, [7:0] dest_id, [7:0] opc);
	monitor_transaction();
   	check_transaction(src_id, dest_id, opc);
    endtask

In reply to sriram.seshagiri:

Please use code tags making your code easier to read. I have added them for you.

I do not understand your situation. When task monitor_sb_transaction gets called again, the fork/join/any starts again. Are you missing other fork/joins in the code you show. How does monitor_sb_transaction gets called again?

In reply to dave_59:

Hi Dave,

This task : Check_transaction () calls the task below in else part of the code

monitor_and_check_transaction(src_id,dest_id,opcode)

which in turn calls the task monitor_transaction() again.;

In reply to sriram.seshagiri:

You have a recursive calling thread. Perhaps you need to explain the sequence of events without SystemVerilog code

In reply to dave_59:

Hi Dave,

Yes I found out that later. I do a have a recursive calling thread there but, not sure why it is stuck the way it was. In my understanding the monitor_transaction() should have waited for the next transaction. And then should have called the task check_transcation(). So once a fork gets disabled inside a task and if we call that the task later the fork does get reenabled again right.
Anyways I have simplified the code and got rid of this recursion happening. Trying a rerun now…


task monitor_and_check_transaction(input logic[7:0]src_id, [7:0] dest_id, [7:0] opc);

      while (txn_hit ! = 1) begin
	monitor_transaction();
   	check_transaction(src_id, dest_id, opc);
      end
    endtask

In reply to sriram.seshagiri:
You have a recursive calling thread. Perhaps you need to explain the sequence of events without SystemVerilog code

In reply to sriram.seshagiri:

Hi Dave,

There was nothing wrong with the old code with recursive calling thread. The issue was both the disable fork and next call to this task to make it respawn occurs at the same zero time causing a zero time simulation hang and an infinite loop.

Added a small delay after disable fork and that fixed my issue

disable fork ;
#1 ns;