Passing resource via config_db Upwards the Hierarchy

Hi all ,

I am trying out code to pass configuration from env to Top-Level Components : uvm_test_top and its sibling



 From low-level  Component we pass resource  to  2 Top-Level  Components ::
 uvm_test_top  N Component instantiated  before  call to  run_test()  !!       
                                                                                                                                                                            


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

  `define COMP_NEW function new ( string name , uvm_component parent ) ; \
                    super.new(name,parent);\
                   endfunction
  
  `define OBJ_NEW function new ( string name = "" ) ; \
                    super.new(name);\
                   endfunction


  class user_config  extends uvm_object ;
  
     `uvm_object_utils(user_config) 
  
     `OBJ_NEW

     bit has_comp ;
     
     bit has_test ;
  
  endclass   
  
  class  user_env  extends  uvm_env ;

     `uvm_component_utils(user_env)

     `COMP_NEW

      user_config  config_h ;

      task  main_phase (  uvm_phase  phase ) ;


        phase.raise_objection(this);

         config_h  =  new("config_h");

         config_h.has_comp = 1 ;

         config_h.has_test = 1 ;

         uvm_config_db #(user_config) ::set(uvm_top,"uvm_test_top","user_config", config_h ) ;
         
         uvm_config_db #(user_config) ::set(uvm_top,"comp_h","user_config", config_h ) ;
        
      phase.drop_objection(this);


      endtask

  endclass    

  class  user_test  extends  uvm_test ;

     `uvm_component_utils(user_test)

     `COMP_NEW

      user_config  config_h ;
      
      user_env     env ;

      function  void  build_phase ( uvm_phase phase ) ;

        `uvm_info(get_name,$sformatf("In build_phase of %0s",get_full_name()),UVM_NONE)

         env = user_env::type_id::create("env",this);

     endfunction


      task  main_phase ( uvm_phase phase ) ;

      phase.raise_objection(this);

        uvm_config_db#( user_config )::wait_modified(this,"","user_config");  //  Same  as  Starting  3  arguments  of set() / get() !!

        if ( uvm_config_db#( user_config )::get(this,"","user_config",config_h)  )
          `uvm_info(get_name(),$sformatf(" Get Successful in  %0s",get_full_name()),UVM_NONE)
        
      phase.drop_objection(this);

      endtask

   endclass


module  TOP  ;


   class  Comp  extends  uvm_component  ;

     `uvm_component_utils( Comp )

     `COMP_NEW

      user_config  config_h ;

      function  void  build_phase ( uvm_phase phase ) ;

         `uvm_info(get_name,$sformatf("In build_phase of %0s",get_full_name()),UVM_NONE)

     endfunction

      task  main_phase ( uvm_phase phase ) ;

       phase.raise_objection(this);

        uvm_config_db#( user_config )::wait_modified(this,"","user_config");   //  Same  as  Starting  3  arguments  of set() / get() !!

        if ( uvm_config_db#( user_config )::get(this,"","user_config",config_h)  )
          `uvm_info(get_name(),$sformatf(" Get Successful in  %0s",get_full_name()),UVM_NONE)
      
       phase.drop_objection(this);


      endtask

   endclass

   Comp   comp_h ;

   initial  begin

      comp_h  = new("comp_h",null ) ;

      run_test("user_test");

    end


endmodule


I Observe different Output across Simulators ( Licensed ones at work )

SIMULATOR1 Output ::

**UVM_INFO @ 0: reporter [RNTST] Running test user_test...
      UVM_INFO @ 0: comp_h [comp_h] In build_phase of comp_h
      UVM_INFO @ 0: uvm_test_top [uvm_test_top] In build_phase of uvm_test_top
      UVM_INFO @ 0: comp_h [comp_h]  Get Successful in  comp_h
      UVM_FATAL @ 9200: reporter [PH_TIMEOUT] Default timeout of 9200 hit, indicating a probable testbench issue

**

SIMULATOR2 Output ::

**UVM_INFO @ 0: reporter [RNTST] Running test user_test…
UVM_INFO @ 0: comp_h [comp_h] In build_phase of comp_h
UVM_INFO @ 0: uvm_test_top [uvm_test_top] In build_phase of uvm_test_top
UVM_INFO @ 0: uvm_test_top [uvm_test_top] Get Successful in uvm_test_top
**

[Q] Shouldn’t both the get() Succeed ?

In reply to MICRO_91:

This is a basic race condition. There is no defined order of execution between the same tasked based phases of different components. If the set() happens before the wait_modified(), it will hang.