Fork

时间:2016-02-17 03:36:39

标签: verilog system-verilog hdl

我正在执行其他人编写的一段代码,但它确实有效,但我不明白发生了什么!

    initial begin: running_test

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

end: running_test

当我在模拟中跟随调试器时,我看到当task1()命中时钟语句时,调试器跳转到task2(),并且一旦task2()同样命中时钟语句,则调试器跳转to task3()!!!!!

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

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

这完全违背了我对Fork / Join的理解。 我期望看到调试器不会移动到task3(),除非它完成了task1()和task2(),但显然每次它都遇到一个时钟语句(在任一任务中),它会转到一个不同的任务!!!

有人可以解释发生了什么吗?

2 个答案:

答案 0 :(得分:1)

我已经看到了你的一个场景的问题,上面的案例由你解释是可能的。 根据我在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

答案 1 :(得分:0)

fork...join_none& {}中必须有某种fork...join_anytask2task3

如果task2&中有任何join_none或join_any。 task3,然后模拟器将从两个任务中生成线程,并退出任务。因此,反过来,它将退出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显示语句已在task1之前打印,task2已完成。

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