uvm_primer ch23 sequence

330 阅读1分钟

uvm_primer ch23 sequence

virtual sequence find

uvm_pkg中有一个对象是uvm_top 是uvm_root 类型的class的实例;
uvm_top.find方法可以根据一个string来找到这个对象,然后返回这个对象的handle

class runall_sequence extends uvm_sequence #(uvm_sequence_item);
   `uvm_object_utils(runall_sequence);

   protected reset_sequence reset;
   protected maxmult_sequence maxmult;
   protected random_sequence random;
   protected sequencer sequencer_h;
   protected uvm_component uvm_component_h;  //重点
 function new(string name = "runall_sequence");
   super.new(name);
    uvm_component_h =  uvm_top.find("*.env_h.sequencer_h");//重点
    if (uvm_component_h == null)
     `uvm_fatal("RUNALL SEQUENCE", "Failed to get the sequencer")
    if (!$cast(sequencer_h, uvm_component_h))
      `uvm_fatal("RUNALL SEQUENCE", "Failed to cast from uvm_component_h.")
    reset = reset_sequence::type_id::create("reset");
    maxmult = maxmult_sequence::type_id::create("maxmult");
    random = random_sequence::type_id::create("random");
 endfunction : new
 task body();
    reset.start(sequencer_h);
    maxmult.start(sequencer_h);
    random.start(sequencer_h);
 endtask : body
endclass : runall_sequence

uvm_root

其实uvm,并没有限定uvm_top下,只能有一个叶子节点,也就是uvm_test,也可以有多个叶子节点,也就是多个uvm_test。只不过,两个字节点的名字,都不能叫做uvm_test_top。
uvm使用双顶层的用法

方法

  • uvm_root::get(); 返回一个uvm_root类型的handle
  • uvm_root::find() ; 返回uvm_component 类型的handle
  • uvm_root::run_test() //top_tb中, UVM_TESTNAME指定的testcase 作为参数传入run_test()
  • print_topology()

属性

  • uvm_component top_levels[$];//各个top注册在这 i.e test,It includes the uvm_test_top component that is created by run_test as well as any other top level components that have been instantiated anywhere in the hierarchy.
  • bit enable_print_topology = 0;//如果被设置,在end_of_elaboration phase结束的时候打印拓扑结构
  • bit finish_on_completion = 1;//If set, then run_test will call $finish after all phases are executed.
  • time phase_timeout = `UVM_DEFAULT_TIMEOUT;
  • static local uvm_root m_inst;
  • bit m_phase_all_done;//所有阶段执行完毕

不指定sequencer的用法

class full_test extends tinyalu_base_test;
   `uvm_component_utils(full_test);
   runall_sequence runall_seq;
   task run_phase(uvm_phase phase);
      runall_seq = new("runall_seq");
      phase.raise_objection(this);
      runall_seq.start(null); //没有指定sequencer
      phase.drop_objection(this);
   endtask : run_phase
   function new (string name, uvm_component parent);
      super.new(name,parent);
   endfunction : new
endclass

在runall_seq指定sequencer

class runall_sequence extends uvm_sequence #(uvm_sequence_item);
   `uvm_object_utils(runall_sequence);

   protected reset_sequence reset;
   protected maxmult_sequence maxmult;
   protected random_sequence random;
   protected sequencer sequencer_h;
   protected uvm_component uvm_component_h;
 function new(string name = "runall_sequence");
   super.new(name);
    uvm_component_h =  uvm_top.find("*.env_h.sequencer_h");
    if (uvm_component_h == null)
     `uvm_fatal("RUNALL SEQUENCE", "Failed to get the sequencer")
    if (!$cast(sequencer_h, uvm_component_h))
      `uvm_fatal("RUNALL SEQUENCE", "Failed to cast from uvm_component_h.")
    reset = reset_sequence::type_id::create("reset");
    maxmult = maxmult_sequence::type_id::create("maxmult");
    random = random_sequence::type_id::create("random");
 endfunction : new
 task body();
    reset.start(sequencer_h);  //指定sequencer
    maxmult.start(sequencer_h);
    random.start(sequencer_h);
 endtask : body
endclass : runall_sequence