我有一段非常简单的代码令我难以置信。
->ev1; //Trigger the event of interest
fork : main_fork
begin : T1
$display("T1 is RUNNING");
fork
begin
$display("T1.B3 is RUNNING");
$display("T1.B3 END");
end
begin
$display("T1.B0 is RUNNING");
$display("T1.B0 END");
end
join
$display("T1 END");
end : T1
begin :T2
$display("T2 is RUNNING");
@ev1;
$display("T2 END");
end : T2
join_any : main_fork
disable main_fork;
所以,想法是ev1
发生时,我希望 T2结束,从而有效地杀死 T1 中的所有内容。如果ev1
永远不会发生,那么我希望线程T1.B3后跟T1.B0执行,并在禁用main_fork后继续执行代码。
现在,这是有趣/令人困惑的部分。当我grep上面的语句时,我可以在时间戳看到一组RUNNING打印:X ......但我从未看到任何END打印,然后再次在时间戳:X + 100,我再一次看到所有RUNNING打印
我可以看到事件ev1
已经发生在我们第一次开始运行T2之后,我预计T2会在那个时候被杀死,T2会打印到T2。但是,看起来T2在ev1
发生时永远不会结束,并且神奇地,所有线程再次开始。
线程如何在未结束时重新启动?为什么即使我们在事件真正发生之前开始等待它们,也不会识别事件?
答案 0 :(得分:2)
我仔细阅读了LRM之后解决了这个问题。当你命名你的fork,main_fork时,在这种情况下......你必须在join_any语句中使用它,我没有。这可能是一个错误的原因。
其次,当您编写disbale main_fork..its本质上是一个在verilog意义上使用的禁用语句并且不会杀死我们认为它会杀死的东西..disable fork是我为此目的所需的系统verilog版本。所以,当我删除fork的名称并替换disable main_fork时;禁用分叉;并重新编译并重新运行失败的测试,瞧..我可以看到线程何时结束,我还可以看到所有其他线程按预期结束。
答案 1 :(得分:0)
查看您给出的示例,T1将在0时间内完成,这将禁用fork
,这意味着T2永远不会有机会等待事件。
线程不会神奇地重新开始。你可能在那里有一个循环,再次运行此代码。但是,从你向我们展示的代码来看,这是不可能的。