-2

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

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 实际上是并行的?)说这些线程实际上并不是在 CPU 意义上并行执行,而只是在模拟意义上。

我的第二个问题是,如果它们实际上没有并行执行,那么分叉连接的意义何在。不会有性能优势,所以为什么不遵循如下顺序算法:

while true:
  Create new input
  Feed input to module
  Check output

对我来说,这似乎比测试台示例简单得多。

谢谢你的帮助!

4

1 回答 1

0

没有gen和drive的代码,很难说。但是,很可能驱动器和生成器都以某种方式相互通信,即gen产生driv消耗和驱动其他东西的数据。

如果 gen 和 drive 以 gen 输入/cousume 输入方式编写,那么您的循环将是有意义的,但是,它们很可能会根据某些事件生成和使用数据,并且不能轻易地在此类函数中拆分。像下面这样的东西通常更干净。

gen:
    while() begin
       wait(some event);
       generateData;
       prepareForTheNextEvent;
    end

driv: 
    while() begin
       wait(gen ready);
       driveData;
   end

因此,由于上述原因,您不能按顺序运行它们。它们必须并行运行。出于所有编程目的,它们并行运行。更详细地说,它们在同一个单线程中运行,但 verilog 根据模拟中生成的事件安排它们的执行。所以,你需要叉子。

至于join_any,我认为,您的案例中的测试应该在任何一个线程完成时完成。但是,驱动程序还必须在退出之前完成所有未完成的工作。wait因此,在后测任务中有这些陈述。

于 2018-02-21T19:45:41.433 回答