I want to run the inherited child uvm_test class. The problem is that when you run the test2
class using +UVMTESTNAME=test2
, it also runs the test1
class.
This is because I expect test2
to be the only one executed except test1
.
This means that if I implement 1000 inherited test classes and run the 1000th test class, I might run 1000 classes.
Is this the nature of uvm test execution? or do I miss it?
This class test1
class test1 extends test_base;
`uvm_component_utils(test1)
main_ahb_sequence seq;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
seq = main_ahb_sequence::type_id::create("seq", this);
if(!seq.randomize())
`uvm_error("rand failed", UVM_LOW)
endfunction
task run_phase(uvm_phase phase);
phase.raise_objection(this);
seq.start(ahb0.sequencer);
phase.drop_objection(this);
endtask
this is test2
class inherited from test1
.
class test2 extends test1;
`uvm_component_utils(test2)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
factory.print();
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
phase.raise_objection(this);
`uvm_info("TEST2", "THIS is run_phase from test2", UVM_LOW);
phase.drop_objection(this);
endtask
endclass
This means that if I implement 1000 inherited test classes and run the 1000th test class, I might run 1000 classes.
Of course not. Once a test name has been selected, the run_test()
task calls the factory to create an instance of the test with an instance name of uvm_test_top
. Finally, run_test()
starts the test by cycling through the simulation phases. Note that all the phases are virtual.
I want to run the inherited child
uvm_test
class. The problem is that when you run thetest2
class using+UVMTESTNAME=test2
, it also runs thetest1
class.
As mentioned above, we actually only created one test2
instance. The reason you see the result is because of the inheritance of the class, and calling super.run_phase(phase);
in the subclass test2
.
In common case, the build_phase()
function of the base_test creates the env. This fully creates the top-level environment as each sub-component will create their own children components in their respective build_phase()
functions. All of the definitions in the base_test are inherited by any test that derives from the base_test. This means any derivative test will not have to build the top-level environment if the test calls super.build_phase()
. Likewise, the run_phase()
task behavior can be inherited, as well as all other phases. As you have done, probably the general case will only have the base_test, which creates env, and the test1, which creates sequence and really runs the test. But if the current implementation of test1 does not meet the needs of the extended test, we can write a class test2 that inherits from test1, the build_phase()
and/or run_phase()
, as well as any other run-time phase methods may be refined as needed because they are all virtual. Since the top-level environment is created by the parent test's build_phase()
function, and the run_phase()
task defines the run phase, so the derivative tests can just make minor adjustments. For example, changing the default sequence executed by the agents in the environment.