How is "test1" instantiated in UVM express example 04?

Hi,

I’m looking at the UVM express example 04. In the file tests.sv I see:

module tests();
...
  import test1_pkg::*; // Bring in the test1_pkg package.

initial begin
...
   run_test("test1");
end

“test1” is a class defined in the test1_pkg. But, I cannot find where the test1 is instantiated. How is it that run_test can find test1?

the only clue is (in test1.sv):

class test1 extends uvm_test;
  `uvm_component_utils(test1)
...
   function new(string name = "test1"), uvm_component parent = null);
      super.new(name, parent);
   endfunction

So, I can see that it is creating itself with the the name “test1”, but if the class is not instantiated, how can the new() function ever be called?

Thanks,
-Mike

In reply to mike_bradley63:

One other thought, perhaps because the file name is “test1.sv” rather than “test1.svh”, that the compiler is instructed to create an object of the class automatically?

Hi Mike,

Short answer:
(step 1) you called `uvm_component_utils(test1) in your test class declaration - this registers a named wrapper class with the UVM factory at static initialization time. That wrapper can be looked up by name in the factory’s table of known components and objects, and instantiated on demand
(step 2) meanwhile, you called UVM’s global run_test(test_name) entry point, which instantiates the singleton class uvm_root, calls its run_test(test_name), which instantiates the singleton class uvm_factory, checks the command line for a +UVM_TESTNAME=x plusarg, and then calls the uvm_factory to create an instance of the required test_name component, before finally starting UVM phasing which does the rest.

The UVM factory instantiates the class.

That’s what run_test does. It creates an instance of test1 from the factory. See the Cookbook here and here for more information. We usually recommend that you call run_test() with no arguments and specify the test name on the command line via +UVM_TESTNAME.

In reply to gordon:

OK, that makes sense.

the other puzzling thing I see is that the “test” instantiates the “env”.

so, if I have multiple tests, each one should instantiate the “env”, but only one of the tests will actually get created by the factory.

I would have thought the env would be instantiated somewhere outside the test, and then the test could connect to it via the factory ::connect functions.
That way the env is always created independent of the test.

Maybe its a strange question, but things are so separated and sequestered in UVM, I’m surprized that “tests” and “env” are not also separated.

In reply to tfitz:

In my defense, the example I copied from the UVM express download … But, I see the logic in using run_test() with no arguments.

In reply to mike_bradley63:

You’re right. It is a strange question. ;-)
Due to the way the build_phase() process works, each component, starting with the test, must instantiate any children in the build_phase() method. If you want the env to be separate from your test, you could pass in the type of your env via a config to the test, and have the test pull it and instantiate it, but that’s a bit clunky.