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