Disable fork is not working inside fork join

Hi All,

I am trying to achieve when using fork join if any of two threads are completed, fork join has stop. To acheive above functionality I used combination of events and diable fork construct.

module top;
  event a, b, c;
  initial
    begin
      fork
        begin
          #10 $display("%t 1st process", $time);
          -> a;
        end
        begin
          #20 $display("%t 2nd process", $time);
          ->b;
        end
        begin
          #30 $display("%t 3rd process", $time);
          ->c;
        end
        begin
          int count='0;
          forever
            begin
              @(a or b or c)
              count++;
              $display("%d", count);
              if(count == 32'd2)
                begin
                  $display("disable fork");
                  disable fork;
                end
            end
        end
      join
          $display("Completed");
    end
endmodule

output :

10 1st process

1

20 2nd process

2

disable fork

30 3rd process

Completed

Can anyone help me why my code is not working at 2 I can see display of disable fork, but fork is not getting disabled.

In reply to marathuteja:
This worked for me


module top;
  event a, b, c;
  initial
    begin      
    $dumpfile("dump.vcd"); $dumpvars;
      fork: my_fork
        begin
          #10 $display("%t 1st process", $time);
          -> a;
        end
        begin
          #20 $display("%t 2nd process", $time);
          ->b;
        end
        begin
          #30 $display("%t 3rd process", $time);
          ->c;
        end
        begin
          static int  count='0;
          forever
            begin
              @(a or b or c)
              count++;
              $display("%d", count);
              if(count == 32'd2)
                begin
                  $display("disable fork");
                  disable  my_fork;
                end
            end
        end
      join
          $display("Completed");
    end
endmodule
/*run -all
#                   10 1st process
#           1
#                   20 2nd process
#           2
# disable fork
# Completed
# exit
*/

Ben Cohen
Ben@systemverilog.us
Link to the list of papers and books that I wrote, many are now donated.

or Cohen_Links_to_papers_books - Google Docs

Getting started with verification with SystemVerilog

In reply to ben@SystemVerilog.us:

When we use name for fork join it is working.

Please see the below thread to understand the “scope” of ‘disable fork’

Your text to link here…

What’s happening here is that the disable fork is killing all the threads swapned by the parent fork, but doesn’t kill the parent fork itself.

You are working around that by using a “label”. Note that using a “label” isn’t foolproof either, you may end up running the fork with multiple instances of the class, and all the “labels” will get killed, which may not be what you want. So keep that in mind.

I would prefer the following code instead :

module top;
  event a, b, c;
  initial
    begin
      fork begin//isolator
        bit disable_fork_condition;
      fork
        begin
          #10 $display("%t 1st process", $time);
          -> a;
        end
        begin
          #20 $display("%t 2nd process", $time);
          ->b;
        end
        begin
          #30 $display("%t 3rd process", $time);
          ->c;
        end
        begin
          int count='0;
          while(1)
            begin
              @(a or b or c)
              count++;
              $display("%d", count);
              if(count == 32'd2)
                begin
                  $display("disable fork");
                  disable_fork_condition = 1;
                  break;
                end
            end
        end
      join_any
      wait(disable_fork_condition == 1); 
      disable fork;
        
      end join //isolator
      $display("Completed");
    end
endmodule

In reply to KillSteal:

Hi killsteal,

What’s happening here is that the disable fork is killing all the threads swapned by the parent fork, but doesn’t kill the parent fork itself can you expplain this i didnt understand.