I am creating a framework where my verification team and I can write uvm test cases with ease. The basic idea is that my base (uvm_)sequence only contains the one line in its body task:
regs.update(status);
From my individual (uvm_)tests, I can set the register values using handy helper functions. For example, my tests would contain:
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
Now I realize that end_of_elaboration phase may not be the best place to set the registers. My compiler gave me warnings that said "WARNING: Calling a task "set_registerA" in task "end_of_elaboration". So I changed it to execute in my 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
I am unsure if this is the right methodology for what I am trying to do? Does calling super.run_phase cause problems? I don't see this done anywhere else.
I personally don't like calling super.run_phase(...) because it can create problems if you want to implement something that was defined in a grandparent class. If you don't expect having a test inherit from a test inheriting from a test, then you shouldn't have any problems. The main idea is that the run_phase will almost always get overridden, but end_of_elaboration/start_of_simulation less so, which is why it would be a better candidate for more general things.
W.r.t. to your compile issue, check that you didn't create tasks instead of functions for your set_register* functions. Your compiler might be more lenient and allow you to start tasks inside functions (end_of_elaboration is a function), most probably by doing the equivalent of a fork...join_none