我正在创建一个框架,我和我的验证团队可以轻松地编写uvm测试用例。基本思想是my base (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会导致问题吗?我在其他地方没看到这件事。
发布于 2014-06-16 19:25:21
我个人不喜欢打电话给super.run_phase(.)因为如果您想要实现在祖父母类中定义的东西,它可能会产生问题。如果您不期望让测试继承从测试继承的测试,那么您就不会有任何问题。其主要思想是,run_phase几乎总是会被覆盖,但是end_of_ general /start_of_模拟要少一些,这就是为什么它是更一般事物的更好选择的原因。
W.r.t.对于编译问题,请检查是否为set_register*函数创建了任务而不是函数。您的编译器可能比较宽松,允许您在函数内部启动任务(end_of_elaboration是一个函数),最可能的方法是执行相当于fork...join_none的操作。
发布于 2014-06-17 11:53:43
想到两个可能的解决方案: 1.您可以放弃基本序列的概念,创建不同的序列&在body()中设置寄存器,然后调用update()。或者,如果您真的想使用基本序列,可以在pre_body中设置寄存器,然后在body call super.body中设置寄存器,后者将执行update。从方法学的角度来看,我认为将值设置为寄存器(通过更新将值真正转换为reg.write())属于序列,而不是测试。2.如果在测试main_phase中启动序列,则可以将setregs留在测试中,在执行seq.start(seqr)之前,可以设置所有寄存器。
为了只使用一个交替序列的测试,在测试文件中添加:
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
发布于 2016-02-20 08:36:42
您已经知道正确的uvm_end_of_elaboration_phase主要用于微调我们的测试平台,所以它不是设置寄存器的好地方。
我建议运行时阶段可以更好地设置您的寄存器,而不是使用公共阶段,即虚拟任务run_phase(uvm_phase阶段);
我们可以将它拆分为UVM预定义的运行时阶段,这些运行时阶段是

我们可以选择"uvm_configure_phase“和"uvm_main_phase",因此建议的伪代码编辑如下,
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
task main_phase (uvm_phase phase)
// Copy your run_phase code over here
endtask : main_phase
endclass
class test1 extends base_test;
virtual task configure_phase(uvm_phase phase);
set_registerA(....);
set_registerB(....);
endtask
virtual task main_phase(uvm_phase phase);
super.main_phase(phase);
endtask : main_phase
endclass
class test2 extends base_test;
virtual task configure_phase(uvm_phase phase);
set_registerA(....);
set_registerB(....);
endtask : configure_phase
virtual task main_phase(uvm_phase phase);
super.main_phase(phase);
endtask : main_phase
endclass希望这能解决你的问题!
https://stackoverflow.com/questions/24249008
复制相似问题