系统Verilog分叉连接-实际上不是并行的



我正在学习系统verilog,并且认为fork/join中的每个进程都创建了单独的线程。但是,我发现如果我在第一个进程中有一个while循环,我的第二个进程不会启动,这使我认为fork/join实际上不是并行的。

class A;
task run();
$display("A started");
while(1);
endtask
endclass
class B;
task run();
$display("B started");
endtask
endclass
class C;
task run();
fork
   A.run();
   B.run(); 
join
endtask
endclass

输出是

 Class A started 

,程序将永远运行。我觉得应该打印

 Class A started
 Class B started

并永远运行。有人能指出我遗漏了什么吗?

SystemVerilog fork/join语句创建的进程仅在模拟意义上是并行的。但是,这些进程在多核意义上不是并行的——这些进程不会在处理器的多个线程上执行。这些进程将在相同的模拟时间戳上安排在执行队列上。但是,这些将在单个逻辑CPU上执行,因此,从CPU的角度来看,它们将按顺序执行。

在您的代码示例中,A类和B类run任务都计划在同一模拟时间执行。当SystemVerilog模拟器遇到fork/join语句时,它将它们放到执行队列中。当您运行模拟时,您的模拟器首先启动A.run。由于A.run进程进入了一个不产生结果的无限循环,因此模拟器没有机会执行B.run。请注意,如果在同一模拟时间安排了多个任务,那么SystemVerilog LRM不会规定首先执行哪个任务。其他模拟器可能在启动A.run之前执行了B.run

你可以在while(1)中设置#0延迟,让第二帧依次执行:

task run();
$display("A started");
while(1) #0;
endtask

最新更新