Search code examples
oopsystem-veriloguvm

Example with super function call in UVM


I have come across this statement and I have used many testbench components with this prototype. super.run_phase(), super.build_phase, super.connect_phase.

Can anyone explain with a simple example why we need to call super functions everytime. I understand we need to construct parent before constructing the child but why do we have to call parent's connect_phase etc?

Thanks


Solution

  • From the UVM component source code, every phase is by default an empty virtual function/task:

    function void uvm_component::connect_phase(uvm_phase phase);
          connect();
          return; 
       endfunction
    function void uvm_component::connect();             
      return; 
    endfunction
    

    It is not mandatory to call super.connect_phase or any phase from base test or base driver etc.

    You might have instantiated environment in base test and henceforth calling super.build_phase shall create the required instances. Similarly, you might connected some ports-exports in base environment/agent and a call to super.connect_phase shall connect them.

    But, build_phase is an exception to this. It is highly recommended to use build_phase/connect_phase for user defined code, instead of using any code in the constructor.

    You can call super.build_phase()/super.connect_phase() in an extended class depending on the overriding requirement or add the the existing functionality in the base class build_phase()/connect_phase().

    You can't completely override a constructor because SystemVerilog requires that the extended class constructor call super.new().

    A call to super.build_phase() is mandatory in base class's build_phase if the field automation macros are used.

    For example:

    class base_test extends uvm_test;
    `uvm_component_utils(base_test)
    //...
    function build_phase(uvm_phase phase);
    super.build_phase(phase); // for automatic configuration of fields
    endfunction
    //...
    function connect_phase(uvm_phase phase);
    super.connect_phase(phase); // normal practice 
    endfunction
    endclass
    
    class my_test extends base_test;
    `uvm_component_utils(my_test)
    //...
    function build_phase(uvm_phase phase);
    super.build_phase(phase); // for environment creation
    endfunction
    //...
    function connect_phase(uvm_phase phase);
    // super.connect_phase(phase); // will compile even if not call-ed
    endfunction
    endclass
    

    From UVM Class reference:

    Any override should call super.build_phase(phase) to execute the automatic configuration of fields registed in the component by calling apply_config_settings. To turn off automatic configuration for a component, do not call super.build_phase(phase).

    The apply_config_settings is used for applying configuration settings to each field of the class.

    If you do not want apply_config_settings to be called for a component, then the build_phase() method should be overloaded and you apply_config_settings call super.build_phase(phase).