我正在创建一个框架,我和我的验证团队可以轻松地编写uvm测试用例。基本思想是我的基础(uvm_)序列只包含 body 任务中的一行:
regs.update(status);
从我的个人(uvm_)测试中,我可以使用方便的辅助函数设置寄存器值。例如,我的测试将包含:
class base_test extends uvm_test;
........
........
virtual function void set_registerA(....);
regs.registerA1.set(....);
regs.registerA2.set(....);
regs.registerA3.set(....);
endfunction
virtual function void set_registerB(....);
regs.registerB1.set(....);
regs.registerB2.set(....);
regs.registerB3.set(....);
endfunction
endclass
class test1 extends base_test;
virtual function void end_of_elaboration_phase(uvm_phase phase);
set_registerA(....);
set_registerB(....);
endfunction
endclass
class test2 extends base_test;
virtual function void end_of_elaboration_phase(uvm_phase phase);
set_registerA(....);
set_registerB(....);
endfunction
endclass
现在我意识到end_of_elaboration阶段可能不是设置寄存器的最佳位置。我的编译器给了我警告说“警告:调用任务”set_registerA“在任务中”end_of_elaboration“。所以我把它改为在run_phase中执行:
class test1 extends base_test;
virtual task run_phase(uvm_phase phase);
super.run_phase(phase);
set_registerA(....);
set_registerB(....);
endfunction
endclass
class test2 extends base_test;
virtual task run_phase(uvm_phase phase);
super.run_phase(phase);
set_registerA(....);
set_registerB(....);
endfunction
endclass
我不确定这是否是我正在尝试做的正确方法?调用super.run_phase会导致问题吗?我没有在其他任何地方看到这种情况。
答案 0 :(得分:1)
我个人不喜欢调用super.run_phase(...),因为如果你想实现祖父母类中定义的东西,它可能会产生问题。如果您不希望测试继承自测试继承的测试,那么您不应该有任何问题。主要的想法是run_phase几乎总是被覆盖,但是end_of_elaboration / start_of_simulation不那么重要,这就是为什么它会成为更一般的东西的更好的候选者。
W.r.t。对于您的编译问题,请检查您是否为set_register *函数创建了任务而不是函数。您的编译器可能更宽松,并允许您在函数内启动任务(end_of_elaboration是一个函数),最有可能通过执行相当于fork ... join_none
答案 1 :(得分:1)
我想到了两种可能的解决方案:
你可以放弃一个基本序列的概念,创建不同的序列&在body()
中设置寄存器,然后调用update()
。或者,如果您真的想使用基本序列,可以在pre_body
中设置寄存器,然后在body
调用super.body
中设置update
。从方法论的角度来看,我认为将值设置为寄存器(通过更新实际转换为reg.write())属于序列而不是测试。
2.您可以将setregs保留在测试中如果在测试main_phase中启动序列,则在执行seq.start(seqr)之前,可以设置所有寄存器
为了仅使用交替序列的1个测试添加到测试文件中:
function void build_phase(uvm_phase phase);
string seq_name;
uvm_sequence_base seq;
uvm_factory factory= uvm_factory::get();
super.build_phase(phase);
$value$plusargs("SEQ_NAME=%s", seq_name);
.......
if(! $cast(seq, factory.create_object_by_name(seq_name)))
`uvm_fatal("", "Failed to create sequence")
if(seq == null)
`uvm_fatal("", "no sequence created seq=null!!")
uvm_config_db #(uvm_sequence_base)::set(this, "master.sequencer.main_phase" ,"default_sequence", seq);
然后在命令行上添加:+ SEQ_NAME = rand_seq
答案 2 :(得分:1)
你认为它是正确的uvm_end_of_elaboration_phase主要用于微调我们的测试平台,因此它不是设置寄存器的好地方。
我建议运行时阶段是更好的设置寄存器的地方,但不是使用公共阶段,即虚拟任务run_phase(uvm_phase阶段);
我们可以将其拆分为UVM预定义的运行时阶段
Create Struts application using Maven
我们可以选择“uvm_configure_phase”& “uvm_main_phase”,所以建议伪代码编辑为,
{{1}}
希望这可以解决您的问题!!!