Kill task when new task starts

Hi SV forum

lets assume that I have the following task.


task run();
  do_something;
endtask

task do_something();
  forever begin
    @ (posedge signal);
    wait_some_time;
    act;
  end
endtask

when signal first rise task do_something starts.
How can I kill the current task thread if a new signal event occurs before the old one finished.

In reply to shimonc:

Here is a Sample Code which works ::



reg clk = 0 ;

initial begin

  fork
   begin

   #2 clk = ~clk ; // 1st Posedge at #2
   
   #2 clk = ~clk ; // Occurs at #4
   
   #2 clk = ~clk ; // 2nd Posedge at #6

   #2 clk = ~clk ; // Occurs at #8
   
   #2 clk = ~clk ; // 3rd Posedge at #8
   
   #2 clk = ~clk ; // Occurs at #10
   
   end
  join
  $display("TIME:%0t All Clks Triggered",$time) ;
  $finish();

end 

initial begin  // This is similar to task do_something()
 process Sub ;
 semaphore sema= new() ;

  fork
   
   begin

     forever @ ( posedge clk ) 
       begin
           if( Sub != null )
	    begin 
	     Sub.kill(); 
	     $display("TIME:%0t Child Killed ",$time);
	    end

	   sema.put(1);

       end
   end

   begin
    bit b ;
     forever begin

       fork
         begin
        
           Sub = process::self();
	   sema.get(1); // Will Unblock at #2 ; #6 ; #10
	   $display("TIME:%0t Child Starts ",$time);

    // Below if-else block is to be replaced by :: wait_some_time ; act ; 
        if ( b == 0 ) // For 1st Iteration let the thread Complete before Next posedge of CLK
	    begin
               b++ ;
               #3; // Will Complete at 5 Time Unit so that it can wait for posedge at #6 !!
	       $display("TIME:%0t Child Completes ",$time);
	    end
          else  // For 2nd Iteration let the thread still be running so that we kill it at next edge of CLK
	    begin

                #5;   // Will Complete at 6 + 5 i.e 11 Time Unit so that it can be killed at posedge at #10 !!

	    end

          end
        join

	      end
   end
 
  join

end


It gives me Output ::

 **TIME:2 Child Killed 
 TIME:2 Child Starts 
 TIME:5 Child Completes 
 TIME:6 Child Killed 
 TIME:6 Child Starts 
 TIME:10 Child Killed 
 TIME:10 Child Starts 
 TIME:12 All Clks Triggered**

In reply to shimonc:

If you just want to kill and restart, you can do

task do_something();
  @ (posedge signal);
  forever begin : restart
    fork 
      forever begin : f_loop
        wait_some_time;
        act;
        @ (posedge signal);
      end : f_loop
      @ (posedge signal);
    join_any
    disable f_loop; // or disable fork; if this is an isolated fork
  end : restart 
endtask

Thanks Dave and ABD