通过任务设置uvm_reg值时发出警告

时间:2014-06-16 17:26:10

标签: system-verilog uvm

我正在创建一个框架,我和我的验证团队可以轻松地编写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会导致问题吗?我没有在其他任何地方看到这种情况。

3 个答案:

答案 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}}

希望这可以解决您的问题!!!