How to Run Both Parent and Child sequence_item in a UVM Test?

Hello,

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

Do update this thread once you try this out

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?

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 )

I am not clear on your question

After the 2nd type override, do you want to register a 3rd type override for B type ?

After switching back to A using A_ext, I want to switch again to B. With this approach, I’d need to define another class, like B_ext

short answer: yes

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

Thanks, it worked.