Disabling processes from within a function


event an_event;

initial begin
   myfunction();
   #5ns;
   ->an_event;
   #100ns;
end

function void myfunction();
   fork
      begin : THREAD_1
         #10ns;
         $display("Ending Thread 1");
      end   : THREAD_1
      begin : THREAD_2
         wait(an_event.triggered);
         disable THREAD_1;
      end   : THREAD_2
   join_none
endfunction

When I run the following code, THREAD_1 isn’t disabled until 10ns… but because the “an_event” is triggered at 5ns, shouldn’t THREAD_2 disable THREAD_1 at 5ns?

In reply to ce_2015:
I don’t see the rror you quoted.
See Edit code - EDA Playground
The Ending Thread 1 does not occur


module top; 
  event an_event;
 
initial begin
   myfunction();
   #5ns;
   ->an_event;
  $display("@ %t an_event", $realtime); 
   #100ns;
end
 
function void myfunction();
   fork
      begin : THREAD_1
        $display("Thread_1 start"); 
         #10ns;
         $display("Ending Thread 1");
      end   : THREAD_1
      begin : THREAD_2
         wait(an_event.triggered);
        $display("Thread_2 start"); 
        //  wait(an_event.triggered);
         disable THREAD_1;
        $display("End Thread_2 start"); 
      end   : THREAD_2
   join_none
endfunction
endmodule 
// ---------------------SIM results
Thread_1 start
@                    5 an_event
Thread_2 start
End Thread_2 start
 

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact Home - My cvcblr


  1. Verification Horizons - March 2018 Issue | Verification Academy
  2. SVA: Package for dynamic and range delays and repeats | Verification Academy
  3. SVA in a UVM Class-based Environment
    SVA in a UVM Class-based Environment | Verification Horizons | Verification Academy

In reply to ce_2015:
It works for me. What makes oyu think it’s not working?

I fear the worst…

I copied and pasted Ben’s code just for sanity purposes but my simulator outputs:

Thread_1 start

@ 5.000ns an_event

Thread_2 start

Ending Thread 1

Interestingly I never see the message “End Thread_2 start” for no matter how long I run the sim… maybe the disable is disabling the wrong thread?

I fear the worst… Questa 10.7a must have a bug. Sigh…

Thank you Ben and Dave for getting back to me.

In reply to ce_2015:
This forum does not discuss specific tools; in fact, specific tools should not be addressed. Tools can be addressed as generalities (e.g., simulators can …, formal verification can…) Any tool issue should be addressed directly with the vendor.
The purpose of this forum is to address language usage and LRM understanding.
n your case, your model is LRM compliant.
Ben

Agreed.

That was indeed the purpose of my post was to determine whether it was LRM compliant. Before now, I did not know there was a tool issue. With this newfound knowledge I am now taking this up with the vendor.

Thanks!

I dont think it is good idea to kill one thread from another thread. This creates lots of confusion in future.
If possible Id suggest you take our the disable THREAD_1; statement from THREAD_2 and move it out from fork/join_none. Most of the cases you can change your logic to work in this way.

In reply to haykp:

  1. SV allows the use of the disable
  2. i can see cases where it is clear and convenient to fire one or more threads. This is particularly true for systems-level modeling.
  3. an easy example: thread1 does a large transfer of data.
    Thread2 does a check on the transfer or some other activity (e.g. A cpu interrupt) and based on thread2 conditions decides to kill the thread1 activity.
    By creating the concurrent separate threads, those thresds are easier to write and understand as they run independently from each other.

Ben systemverilog.us

In reply to ben@SystemVerilog.us:

@ben my point is from my experience almost always you can modify your logic to kill the Thread outside of for-join.
So let me change your example to following:

fork

begin : THREAD_1  // -- does a large transfer of data.
end

begin : THREAD_2 // check on the transfer or some other activity 

  <Do Some Checks or generate interrupt>
// disable THREAD_1  

// my point is:: done use diable THREAD_1 here
// use return instead to come out the loop 

end

join_any

// Better use disable here
diasble fork