0

我正在我的 UVM 测试平台中进行以下操作以创建 seq 并开始测试。

  1. 我有一些序列。我正在从以下序列之一复制代码片段。

内部主体():

`uvm_create_on(my_seq, p_sequencer.my_sequencer)
my_seq.randomize();
`uvm_send(my_seq)

2.在我的测试中,我正在执行以下操作来开始一个序列:

   task run_phase(uvm_phase phase);
     ..... 
     phase.raise_objection(this);
     seq.start(env.virtual_sequencer);
     phase.drop_objection(this);
    endtask

现在,如果我这样做,测试将在零时间开始和结束。我的意思是,DUT 不是由我的序列驱动的。如果我进行以下更改,那么它似乎工作正常:

选项1:在测试中更改run_phase-

   task run_phase(uvm_phase phase);
     ..... 
     phase.raise_objection(this);
     seq.start(env.virtual_sequencer);
     #100000;   // Adding delay here. 
     phase.drop_objection(this);
    endtask

如果我这样做,则测试开始,我可以看到 DUT 正在被驱动,并且一切都按预期工作。然而,测试总是在时间 1000000 结束——即使序列尚未完成,将所有事务发送到 DUT。这不好,因为我不知道我的 DUT 需要多长时间才能完成测试。所以,我宁愿尝试这样的事情:

选项 2:在测试中保留默认代码(不在 run_phase 中添加延迟)。在 my_seq 的主体内进行以下更改:

内部主体():

 uvm_test_done.raise_objection(this);
`uvm_create_on(my_seq, p_sequencer.my_sequencer)
 my_seq.randomize();
`uvm_send(my_seq)
 uvm_test_done.drop_objection(this);

如果我这样做,那么它工作正常。这是处理异议的正确方法吗?回到我原来的实现,我假设我的序列是阻塞的。因此,每当我使用 start(...) 在 test 的 run_phase 中启动一个序列时,它将被视为阻塞,并将在该行等待,直到序列完成发送所有事务。所以,我没有在我的原始代码中添加任何延迟。

我想我在这里遗漏了一些东西。任何帮助将不胜感激。

4

2 回答 2

0

您确实必须考虑序列的语义。通常我希望一个序列的主体在它完成之前不会完成。所以做一个 fork/join_none 是不可取的,因为序列的调用者有办法知道序列已经完成。与您在测试中看到的类似。

解决方案是在完成之前不让 my_seq::body 返回。

如果 my_seq 的调用者需要与 my_seq 并行执行某些操作,那么执行适当的分叉应该是他们的责任。

于 2015-02-17T23:08:15.047 回答
0

如果您在主序列中进行分叉,那么它的body()任务(由 调用start())不会阻塞。如果您fork...join_none由于需要某种同步而需要执行,您还应该实施某种机制来知道分叉的进程何时终止,以便您可以在此之前停止 body。例子:

// inside your main sequence
event forked_finished;

task body();
  fork
    `uvm_do(some_sub_seq)
    -> forked_finished;
  join_none
  // do some other stuff here in parallel

  // make sure that the forked processes also finished
  @forked_finished;
endtask

此处的代码假定分叉进程在您的其他代码完成之后完成。在生产代码中,您可能不会依赖此假设,并且会uvm_event先使用 a 来测试事件是否在等待之前已经触发。

因为body()等到一切都完成了刺激,所以在开始这个序列之前你不应该有任何问题设置和反对,一旦完成就降低它。

于 2014-07-26T19:29:15.590 回答