我在此链接上关注测试平台示例:
http://www.verificationguide.com/p/systemverilog-testbench-example-00.html
我有两个关于fork-join语句的问题。测试环境具有以下启动测试的任务:
task test();
fork
gen.main();
driv.main();
join_any
endtask
task post_test();
wait(gen.ended.triggered);
wait(gen.repeat_count == driv.no_transactions);
endtask
task run;
pre_test();
test();
post_test();
$finish;
endtask
我的第一个问题是为什么我们要等在post_test()任务中触发生成器事件?为什么不做一个常规的fork-join,据我所知,在继续之前会等待两个线程完成。
我读了另一个Stack Overflow问题(System Verilog fork join - Not actually parallel?),说这些线程实际上并不是在CPU意义上并行执行,而只是在模拟意义上。
我的第二个问题是,如果它们实际上没有并行执行,那么fork-joins的重点是什么。没有性能优势,所以为什么不遵循以下顺序算法:
while true:
Create new input
Feed input to module
Check output
对我而言,这似乎比testbench示例简单得多。
感谢您的帮助!
答案 0 :(得分:0)
没有gen和driv的代码,很难说。然而,很可能driv和gen都以某种方式相互通信,即gen
产生driv
消耗并驱动其他东西的数据。
如果gen和driv是以gen输入/ cousume输入方式编写的,那么你的循环很有意义,但很可能它们基于某些事件生成和使用数据,并且不容易在这些函数中轻松分割。像下面这样的东西通常更清洁。
gen:
while() begin
wait(some event);
generateData;
prepareForTheNextEvent;
end
driv:
while() begin
wait(gen ready);
driveData;
end
因此,由于上述原因,您无法按顺序运行它们。它们必须并行运行。出于编程目的,他们 并行运行。更详细地说,它们在同一个线程中运行,但是verilog根据模拟中生成的事件安排执行。所以,你需要fork。
至于join_any
,我认为,你的情况下的测试应该在任何一个线程完成时完成。然而,驾驶员还必须在退出之前完成所有未完成的工作。因此,后测任务中有wait
个语句。