Explicit Import Interferes with Preceding Import

Below we have two packages that contain a class called test. In the testbench, pkg1 is imported using a wildcard import while pkg2 is referenced explicitly. My expectation would be that test from pkg1 would run. However we get a UVM warning that ‘test’ is already registered with the factory, and test from pkg2 gets run by Questa. I understand that once we reference something in pkg2 it “exists” but I did not expect its unreferenced class to dominate the scope as it is doing. Are my expectations incorrect, or is this to be expected?


package pkg1;
    import uvm_pkg::*;
    `include "uvm_macros.svh"

    const int value = 1;

    class test extends uvm_test;
        `uvm_component_utils (test)

        function new (string name, uvm_component parent);
            super.new (name, parent);
        endfunction : new

        task run_phase (uvm_phase phase);
            phase.raise_objection (this);
            $display ("Running test 1.");
            phase.drop_objection (this);
        endtask
    endclass
endpackage

package pkg2;
    import uvm_pkg::*;
    `include "uvm_macros.svh"

    const int value = 2;
    class test extends uvm_test;
        `uvm_component_utils (test)

        function new (string name, uvm_component parent);
            super.new (name, parent);
        endfunction : new

        task run_phase (uvm_phase phase);
            phase.raise_objection (this);
            $display ("Running test 2.");
            phase.drop_objection (this);
        endtask
    endclass
endpackage

module testbench;
    import uvm_pkg::*;
    import pkg1::*;

    initial
    begin
        $display ("%d", pkg2::value);
        run_test ("test");
    end
endmodule

In reply to sbellock:

This is the expected behavior. The reason is that the `uvm_component_utils macros declare static variables whose initialization call functions that populate the factory. These static variables exist regardless of any code referencing the class that contain it. In fact the factory registration declares a proxy class that references your test class to call its constructor. The string-based factory lookup requires this behavior so you can choose a test class dynamically at run time. Thew UVM factory string based database does not know anything about which package a registration came from.

For more information about how the factories in general work, please see Using parameterized classes & factories: Object-oriented verification