如何在测试序列中使用uvm_test_done异议?

时间:2014-07-26 03:32:21

标签: verilog system-verilog uvm

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

  1. 我有一些序列。我正在复制下面其中一个序列的代码片段。
  2. 体内():

    `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:在test-

    中更改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正在被驱动,一切都按预期工作。但是,即使序列没有完成将所有事务发送到DUT,测试总是在1000000时结束。这不好,因为我不知道我的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_phase中启动一个序列时,它将被视为阻塞,并将在该行等待,直到序列完成发送所有事务。所以,我没有在原始代码中添加任何延迟。

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

2 个答案:

答案 0 :(得分:0)

如果您在主序列中执行分叉,则其body()任务(由start()调用)不会阻止。如果由于需要某种同步而需要执行fork...join_none,则还应该实现某种机制来了解分叉进程何时终止,以便在此之前可以停止正文。例如:

// 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进行测试。

因为body()等到一切都结束了w.r.t.刺激,那么在开始这个序列之前你不应该有任何问题设置和异议,并且一旦完成就降低它。

答案 1 :(得分:0)

你真的必须考虑序列的语义。通常我希望序列的主体在完成之前不会完成。因此,执行fork / join_none是不合需要的,因为序列的调用者可以知道序列已经完成。与您在测试中看到的相似。

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

如果my_seq的调用者需要与my_seq并行执行某些操作,那么他们应该负责执行相应的fork。