一个线程可以重新启动而不会在systemverilog中被杀死fork-join / join_any禁用fork设置吗?

时间:2015-08-09 15:10:49

标签: multithreading join fork system-verilog

我有一段非常简单的代码令我难以置信。

->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发生时永远不会结束,并且神奇地,所有线程再次开始。

线程如何在未结束时重新启动?为什么即使我们在事件真正发生之前开始等待它们,也不会识别事件?

2 个答案:

答案 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永远不会有机会等待事件。

线程不会神奇地重新开始。你可能在那里有一个循环,再次运行此代码。但是,从你向我们展示的代码来看,这是不可能的。