Fork中的SystemVerilog任务

Fork中的SystemVerilog任务,verilog,system-verilog,hdl,Verilog,System Verilog,Hdl,我正在执行一段其他人编写的代码,它可以工作,但我不明白发生了什么 initial begin: running_test fork task1(); task2(); join task3(); end: running_test 当我在模拟中跟随调试器时,我看到当task1()命中时钟语句时,调试器跳到task2(),当task2()同样命中时钟语句时,调试器跳到task3() 这就是

我正在执行一段其他人编写的代码,它可以工作,但我不明白发生了什么

    initial begin: running_test

        fork
            task1();
            task2();
        join
        task3();

end: running_test
当我在模拟中跟随调试器时,我看到当task1()命中时钟语句时,调试器跳到task2(),当task2()同样命中时钟语句时,调试器跳到task3()

这就是我感到困惑的地方,因为task2()是一个很长的任务,所以为什么在完成它之前它会移动(连接)到task3()

当我继续运行调试器时,我经常看到调试器在task1()、task2()和task3()之间跳跃

这完全违背了我对Fork/Join的理解。 我希望调试器不会移动到task3(),除非它是通过task1()和task2()完成的,但是很明显,每次它点击一个时钟语句(在任何一个任务中),它都会转到另一个任务


有人能解释一下发生了什么事吗

task2
&
task3

如果task2和task3中存在任何join_none或join_any,则模拟器将从这两个任务中生成线程,并退出该任务。因此,依次从
fork…join退出并首先计算task3

这是一个示例代码,它将帮助您理解我的解释:

//在这里编写测试台代码 //或浏览示例

module top();
  bit clk;

  always #5 clk = ~clk;

  initial
    begin
      fork 
        task1();
        task2();
      join
      task3();
    end

  task task1();
    fork
      begin
        @(posedge clk);
        $display("@%0t : In Task1", $time);
      end
    join_none
  endtask

  task task2();
    fork
      begin
        @(negedge clk);
        $display("@%0t : In Task2", $time);
      end
    join_none
  endtask

  task task3();
    $display("@%0t : In Task3", $time);
  endtask
endmodule
上面代码的输出写在下面。请注意,在此输出中,task3 display语句在task1、task2完成之前已打印

// Output
@0 : In Task3
@5 : In Task1
@10 : In Task2

我已经看到了你关于上述情况的一个场景的问题,你解释了这个场景是可能的。 根据我的说法,在task2或task1内部称为task1的情况下,这是可能的。 我还提供了相同的代码

class A;

  task task1;
    #10 $display("@ time = %t Here is first task\n",$realtime);
  endtask

  task task2;
    #15 $display("@ time = %t  Here is second task\n",$realtime);
    task3;
    #10 $display("@ time = %t  Here is second task\n",$realtime);
  endtask

  task task3;
     #5 $display("@ time = %t  Here is third task\n",$realtime);
  endtask

endclass


program mailbox;
  mailbox m1;
  A a1;

  initial
    begin
      a1 = new;
      m1 = new;


      fork
        a1.task1;
        a1.task2;
  join
  a1.task3;


end

endprogram

包含task1和task2的一个片段您是否有任何
分叉..在
task1()
task2()中加入\u none
或类似的东西?由于task1和task是并发的,模拟器将在它们之间来回跳转。请在代码中包含task1和task2。请注意
加入
。确保它不是
join_any
join_none
,并且可以重复执行task3的唯一方法是如果没有显示循环,或者存在包含初始块的模块的多个实例。