I have a sequence_item named A, and I have another sequence_item named B that inherits from A. In my test, I want to run both A (the parent) and B (the child). I am using the set_type_override function to switch between the two types during the simulation.
Here is the relevant code snippet:
task protocol_rx_uvm_random_test::run_phase(uvm_phase phase);
uvm_test_done.raise_objection();
super.run_phase(phase);
repeat(1) begin
// Override A with B
A::type_id::set_type_override(B::get_type(), 1);
// Send background items of type B
background_send_seq();
// Restore A as the active type
A::type_id::set_type_override(A::get_type(), 1);
end
uvm_test_done.drop_objection();
endtask
Here is the background_send_seq task that I am using:
task rx_uvm_base_test::background_send_seq();
fork
begin
this.m_protocol_rx_uvm_sequences = sequences_base_seq::type_id::create("m_protocol_sequences", this);
this.m_protocol_rx_uvm_sequences.protocol_cfg = this.protocol_tx_cfg;
if (!m_protocol_rx_uvm_sequences.randomize())
uvm_report_fatal(this.get_full_name(), "\n\nProtocol sequence randomization failed!!!\n\n");
m_protocol_rx_uvm_sequences.start(this.m_env.m_agent_tx.m_sequencer);
end
join
endtask: background_send_seq
The issue I am facing is that after I reset the type override back to A using A::type_id::set_type_override(A::get_type(), 1), it does not create objects of type A as expected.
I have read about a similar question in the forum, but even after implementing the suggested solution, it still does not work for me.
How can I ensure that the type correctly reverts to A so I can run both the parent (A) and the child (B) during the same test?
Any suggestions or guidance would be greatly appreciated!
Which version of UVM are you using ?
My understanding that your 2nd override will take effect only in UVM 1.2 , for version 1.d the 2nd type override throws a UVM_WARNING message during registration of the type override.
To register the 2nd type override you would need to define a new class ::
class A_ext extends A;
`uvm_object_utils( A_ext)
// Your std. 3 line Object constructor comes here
// No extra code required as all other stuff gets implicitly inherited
endclass
Then register the 2nd type override as ::
repeat(1) begin
// Override A with B
A::type_id::set_type_override(B::get_type(), 1);
// Send background items of type B
background_send_seq();
// Restore A as the active type
A::type_id::set_type_override(A_ext::get_type(), 1);
end
Thank you for the detailed explanation and suggestion! I followed your approach, defining the A_ext class and using it for the second type override, and it worked perfectly!
Thanks again!
But now I want to switch back to type B, and with your approach, I would need to create yet another extension (e.g., B_ext). While this works, it feels a bit cumbersome to keep extending classes every time I want to toggle between types.
Do you know of a cleaner or more efficient way to handle such scenarios without repeatedly creating new extensions? Or is this the best practice for managing multiple type overrides in UVM?
I am still not clear on your additional requirement.
If you want to switch back to B ( after A_ext ) I believe this should work ::
repeat(1) begin
// Override A with B
A::type_id::set_type_override(B::get_type(), 1);
// Send background items of type B
background_send_seq();
// Restore A as the active type
A::type_id::set_type_override(A_ext::get_type(), 1);
// Again override A with B
A::type_id::set_type_override(B::get_type(), 1);
end