我正在我的UVM测试平台中进行以下操作以创建seq并开始测试。
体内():
`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中启动一个序列时,它将被视为阻塞,并将在该行等待,直到序列完成发送所有事务。所以,我没有在原始代码中添加任何延迟。
我想我在这里遗漏了一些东西。任何帮助将不胜感激。
答案 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。