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那些由调用线程(the calling thread)产生的进程;
disable fork会kill disable fork 所在的当前线程以及所有子线程中激活的进程;
disable label 会kill 含有相同label 的进程;
进程、线程定义可看之前文章 fork join_none
使用disable fork,要考虑:
- 哪些语句属于进程,哪些语句属于线程;
- 哪些进程处于激活状态;
program automatic test;
task dis_thread(int t);
fork:fork_la
repeat(t)begin
$display("%0d,still alive %t",t,$realtime);
#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",t,$realtime);
#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
begin
#600;
$display("%0d,fork..join_none %t",t,$realtime);
end
join_none
fork:fork_la
repeat(t)begin
#500;
$display("%0d,still alive %t", t ,$realtime);
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 500
disable fork 和两个fork 处于同一个父进程中(由于没有离它最近的fork 父进程,所以会kill 整个父进程),因此两个fork 会被kill。
program automatic test;
task dis_thread(int t);
fork
begin
#600;
$display("fork..join_none %t",$realtime);
end
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
#500;
$display("%0d,still alive %t",t, $realtime);
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 500
fork..join_none 600
extra!!
建议把想要disable的fork 用 fork join 包起来,如上面的例子所示。