SystemVerilog:fork - 连接和编写并行测试平台

时间:2018-02-21 19:19:09

标签: verilog system-verilog fork-join test-bench

我在此链接上关注测试平台示例:

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示例简单得多。

感谢您的帮助!

1 个答案:

答案 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个语句。