Is Registering Factory Override on Abstract Base Class valid?

I have following code ::



`include "uvm_macros.svh"
`include "uvm_pkg.sv"
 
 import uvm_pkg::* ;

`define COMP function new( string name , uvm_component parent );\
                 super.new(name,parent);\
             endfunction 

  virtual  class  base_comp  extends  uvm_component ;

      `uvm_component_utils( base_comp ) 
  
      `COMP 

  endclass


  class  env #( BITWIDTH = 128 )   extends  base_comp ;   

      `uvm_component_param_utils( env#( BITWIDTH )  ) 
  
      `COMP 
   
   function void build_phase ( uvm_phase phase ) ;
       
     `uvm_info(get_name(),$sformatf(" In  build_phase of  env #( %0d) ", BITWIDTH ),UVM_NONE)  
     
   endfunction
   
  endclass

  class  my_test extends  uvm_test ; 
  
      `uvm_component_utils( my_test ) 
  
      `COMP 
   
   base_comp  comp_h ;


   function void build_phase ( uvm_phase phase ) ;
     
     `uvm_info(get_name(),$sformatf(" In  build_phase of  my_test "),UVM_NONE)  
 
      env #( 4 ) :: type_id :: set_type_override( env #( 5 ) :: get_type() ) ;

      comp_h =  base_comp :: type_id :: create("comp_h" , this ) ;   //   Valid  ??

   endfunction
   
  endclass


  module  top_tb ; 

     initial  begin
 
        base_comp :: type_id :: set_type_override( env#( 4 ) :: get_type() ) ;

        run_test("my_test") ;

     end

  endmodule


I observe different O/P acrpss simulators !!

Since the UVM Base Class Library is same I am unable to understand the reason for different O/P

**SIMULATOR1  OP  ::** 

**UVM_INFO @ 0: reporter [RNTST] Running test my_test…
UVM_INFO @ 0: uvm_test_top [uvm_test_top] In build_phase of my_test
UVM_INFO @ 0: uvm_test_top.comp_h [comp_h] In build_phase of env #( 5)
**

**SIMULATOR2  OP  ::** 
Error-[SV-ACCNBI] An abstract class cannot be instantiated
/tools/synopsys-/vcs/Q-2020.03-SP1/etc/uvm-1.2/base/uvm_registry.svh, 64
 uvm_pkg, "obj = new(name, parent);"
Instantiation of the object 'obj' can not be done because its type 'base_comp' is an abstract base class.
 Instance stack trace:  uvm_component_registry#($unit::base_comp,"base_comp")

SV basics dictate I can’t call new() on abstract class handle , but in this
code since Factory Override is registered , shouldn’t the Code work ??

In reply to TC_2017:

You cannot do this in UVM 1.2 or earlier because the factory macros inserts class with a create method that calls new() on the abstract class, which is illegal

IEEE UVM 1800.2-2020 adds a new abstract class factory registration mechanism.

In reply to dave_59:

Dave , for better understanding I was going through the Base Class Library for the control flow during create() ::


[1] create()  internally  calls  factory.create_component_by_type() 
   [ As  create()  uses Type - Based  factory  ]  . 

[2] Function  create_component_by_type()  calls   find_override_by_type()  which  would  return 
 
    an  overridden  type  if factory  Override  is  registered ( as in our case ) . 

[3] Finally virtual  function  create_component() (  of  the  Proxy  class  Specialized  to the  overridden  type ) gets  called  which  calls  new() .

So shouldn’t constructor of env#( 4) get called ?

In reply to TC_2017:

It seems there are tool differences in the check for calling the constructor of an abstract class. When the LRM says you cannot “call” the constructor, some have interpreted that as a compile time check, and others have interpreted that as a run-time check.

The registration and override mechanism is separate from the creation mechanism. But uvm_component_registry class contains both. 1800.2-2020 separates the mechanisms to make it tool independent.

The tool that did not produce a compiler error correctly overrode base_comp with env#(4) and it overrode env#(4) with env#(5). So only the env#(5) constructor gets called.

In reply to dave_59:

Hi Dave ,
I was going through the following ::
(a) abstract-classes-uvm-factory

(b) UVM LRM 1800.2-2017 , Section 8.2.5 Abstract registries

I have 2 questions

(1) Some tools throw compilation - error since function create_component in the
proxy class calls new() internally ( although the override ensures it doesn’t ) .

 UVM  LRM  1800.2  , Section 8.2.5.1.2  says  ::

**"As abstract classes cannot be constructed, this method shall generate an error and return null"**  

So for abstract proxy class uvm_abstract_component_registry , within the function create_component :

**(Q1) Source Code won’t call new ( unlike non-abstract proxy class ) thereby avoiding the simulator dependency .
If called ( when no override exists ) it would throw an UVM_ERROR Message .

    Is  my  understanding  correct  ?**

(Q2) Where can I observe the source code as per UVM LRM 1800.2-2017 ?
Is this the next version of UVM i.e UVM 1.3 ?

In reply to ABD_91:

Yes, the source code for
uvm_abstract_object_registry::create_coponent()
calls uvm_report_error() instead of calling new().

UVM 1.2 was the last release prior to being standardized in the IEEE. There will be no UVM 13

The IEEE base class library has the very long name UVM 2020 v1.1 Library Code for IEEE 1800.2 and can be found here.