什么是SystemVerilog线程或进程?
线程或进程是作为独立实体执行的任何代码段。 在verilog中,每个initial块和always块都是作为单独的线程生成的,这些线程从零时间开始并行运行。 fork…join块还会创建并行运行的不同线程。
有哪些不同的fork-join样式?
在SystemVerilog中,我们有三种不同的fork样式。
Finishes when all child threads are over
Finishes when any child thread gets over
Finishes soon after child threads are spawned
fork join | 当所有子线程结束时完成 |
---|---|
fork join_any | 当任何子线程结束时完成 |
fork join_none | 子线程被派生后很快结束 |
– | – |
这在测试台中用在哪里?
验证环境中的组件可能需要能够同时运行多个任务。 例如,一个进程可能等待某件事发生,而另一个进程继续执行其他任务。 它们都是通过fork … join作为单独的线程生成的。 例如,检查器可以并行产生不同的任务,以捕获和验证源自测试台不同部分的数据。
Verilog的fork-join的局限性是什么?
仅当fork-join内部产生的所有线程都已完成时,才会执行fork … join之后的代码。 因此,检查程序必须等到fork-join中产生的所有线程都完成后,才能继续。
fork join Example
SystemVerilog fork_join将等待所有分叉的进程完成。
module tb_top;
initial begin
#1 $display ("[%0t ns] Start fork ...", $time);
// 主进程:并行派生这些进程并等待它们全部完成
fork
// Thread1 : Print this statement after 5ns from start of fork
#5 $display ("[%0t ns] Thread1: Orange is named after orange", $time);
// Thread2 : Print these two statements after the given delay from start of fork
begin
#2 $display ("[%0t ns] Thread2: Apple keeps the doctor away", $time);
#4 $display ("[%0t ns] Thread2: But not anymore", $time);
end
// Thread3 : Print this statement after 10ns from start of fork
#10 $display ("[%0t ns] Thread3: Banana is a good fruit", $time);
join
// Main Process: Continue with rest of statements once fork-join is over
$display ("[%0t ns] After Fork-Join", $time);
end
endmodule
Simulation Log
ncsim> run
[1 ns] Start fork ...
[3 ns] Thread2: Apple keeps the doctor away
[6 ns] Thread1: Orange is named after orange
[7 ns] Thread2: But not anymore
[11 ns] Thread3: Banana is a good fruit
[11 ns] After Fork-Join
ncsim: *W,RNQUIE: Simulation is complete.
fork join_any示例
SystemVerilog中fork join_any等待直到任何一个分支过程完成。
module tb_top;
initial begin
#1 $display ("[%0t ns] Start fork ...", $time);
// Main Process: Fork these processes in parallel and wait until
// any one of them finish
fork
// Thread1 : Print this statement after 5ns from start of fork
#5 $display ("[%0t ns] Thread1: Orange is named after orange", $time);
// Thread2 : Print these two statements after the given delay from start of fork
begin
#2 $display ("[%0t ns] Thread2: Apple keeps the doctor away", $time);
#4 $display ("[%0t ns] Thread2: But not anymore", $time);
end
// Thread3 : Print this statement after 10ns from start of fork
#10 $display ("[%0t ns] Thread3: Banana is a good fruit", $time);
join_any
read2: Apple keeps the doctor away
// Main Process: Continue with rest of statements once fork-join is exited
$display ("[%0t ns] After Fork-Join", $time);
end
endmodule
Simulation Log
ncsim> run
[1 ns] Start fork ...
[3 ns] Thread2: Apple keeps the doctor away
[6 ns] Thread1: Orange is named after orange
[6 ns] After Fork-Join
[7 ns] Thread2: But not anymore
[11 ns] Thread3: Banana is a good fruit
ncsim: *W,RNQUIE: Simulation is complete.
SystemVerilog中 fork join_none不等待,立即退出该块,从而允许分叉的进程在后台运行。 主线程将继续执行在fork join_none块之后的语句。
module tb_top;
initial begin
#1 $display ("[%0t ns] Start fork ...", $time);
// 主进程:并行地派生这些进程并立即退出
fork
// Thread1 : Print this statement after 5ns from start of fork
#5 $display ("[%0t ns] Thread1: Orange is named after orange", $time);
// Thread2 : Print these two statements after the given delay from start of fork
begin
#2 $display ("[%0t ns] Thread2: Apple keeps the doctor away", $time);
#4 $display ("[%0t ns] Thread2: But not anymore", $time);
end
// Thread3 : Print this statement after 10ns from start of fork
#10 $display ("[%0t ns] Thread3: Banana is a good fruit", $time);
join_none
// Main Process: Continue with rest of statements once fork-join is exited
$display ("[%0t ns] After Fork-Join", $time);
end
endmodule
Simulation Log
ncsim> run
[1 ns] Start fork ...
[1 ns] After Fork-Join
[3 ns] Thread2: Apple keeps the doctor away
[6 ns] Thread1: Orange is named after orange
[7 ns] Thread2: But not anymore
[11 ns] Thread3: Banana is a good fruit
ncsim: *W,RNQUIE: Simulation is complete.
参考文献:
【1】https://www.chipverify.com/systemverilog/systemverilog-threads