我正在学习系统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