[SystemVerilog] disable label and disable fork

The disable fork statement differs from disable in that disable fork considers the dynamic parent-child relationship of the processes, whereas disable uses the static, syntactical information of the disabled block. Thus, disable shall end all processes executing a particular block, whether the processes were forked by the calling thread or not, while disable fork shall end only the processes that were spawned by the calling thread.
from LRM


disable fork会kill disable fork 所在的当前线程以及所有子线程
disable label 会kill 含有相同label 的进程;

program automatic test;
  task dis_thread(int t);
    fork:fork_la
      repeat(t)begin
        $display("%0d,still alive %t");
        #500;
      end

      begin
        #1000;
        $display("timeout!!");
      end
    join_any
    disable fork_la;   
  endtask

  initial begin
    #2000;
  end

  initial begin
    fork
      dis_thread(1);
      dis_thread(2);
    join
  end
endprogram
result:
1,still alive 0
2,still alive 0
timeout!!

可以看出,当dis_thread(1)被kill后,dis_thread(2)也被kill,因为两个task 进程具有相同的label。


program automatic test;
  task dis_thread(int t);
    fork:fork_la
      repeat(t)begin
        $display("%0d,still alive %t");
        #500;
      end

      begin
        #1000;
        $display("timeout!!");
      end
    join_any
    disable fork;   
  endtask

  initial begin
    #2000;
  end

  initial begin
    fork
      dis_thread(1);
      dis_thread(2);
    join
  end
endprogram
result:
1,still alive 0
2,still alive 0
2,still alive 500
timeout!!

可以看出,当dis_thread(1)被kill后,dis_thread(2)没有被影响。


program automatic test;
  task dis_thread(int t);
    fork
      #600;
      $display("%0d,fork..join_none %t");
    join_none

    fork:fork_la
      repeat(t)begin
        $display("%0d,still alive %t");
        #500;
      end

      begin
        #1000;
        $display("timeout!!");
      end
    join_any
    disable fork; //两个fork均会被kill  
  endtask

  initial begin
    #2000;
  end

  initial begin
    dis_thread(1);
  end
endprogram
result:
1,still alive 0
timeout!!

disable fork 和两个fork 处于同一个父进程中(由于没有离它最近的fork 父进程,所以会kill 整个父进程),因此两个fork 会被kill。





program automatic test;
  task dis_thread(int t);
    fork
      #600;
      $display("fork..join_none %t");
    join_none

    fork  //always use addtional fork to wrap up all the forks that you want to disable
      begin
        fork:fork_la
          repeat(t)begin
            $display("%0d,still alive %t");
            #500;
          end

         begin
           #1000;
           $display("timeout!!");
         end
       join_any
      disable fork; 
     end
     begin//这个进程不会被disable
       #1500;
       $display("extra!!!");
     end
   join
  endtask

  initial begin
    #2000;
  end

  initial begin
    dis_thread(1);
  end
endprogram
result:
1,still alive 0
fork..join_none 600
timeout!!
extra!!

建议把想要disable的fork 用 fork join 包起来,如上面的例子所示。

猜你喜欢

转载自blog.csdn.net/lbt_dvshare/article/details/81327537