Does using type_id::create(..) in build_phase creates the instance in that phase?

I tried to print the fields of env after creating it in the build_phase but to my surprise I see the fields printed as 0 though in the gui I can see that they have taken appropriate values

virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
uvm_config_db#(int)::set(this,“adc_dac_env”,
“num_tx_lanes”, 3);
uvm_config_db#(int)::set(this,“adc_dac_env”,
“num_rx_lanes”, 5);
$display(“NUMBER of tx and rx lanes are set here HELLO”);
// create UVC top environment
adc_dac_env = er_j204_env::type_id::create(“adc_dac_env”, this);
$display(“Num of tx lanes %0d”, adc_dac_env.num_tx_lanes);
$display(“Num of rx lanes %0d”, adc_dac_env.num_rx_lanes);
endfunction : build_phase

The code is similar to the one seen in ubus example supplied in the UVM library. The code in ubus looks like this -
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
uvm_config_db#(int)::set(this,“ubus0”,
“num_masters”, 1);
uvm_config_db#(int)::set(this,“ubus0”,
“num_slaves”, 1);

ubus0 = ubus_env::type_id::create("ubus0", this);
scoreboard0 = ubus_example_scoreboard::type_id::create("scoreboard0", this);

endfunction : build_phase

In reply to shrawan_vaidya:

What you are displayying is wrong. num_tx_lanes is not a variable or Parameter. It is simply a name (string) used in the config_db.
I guess your piece of code is your test?

In reply to chr_sue:

Hi,
I still didn’t understand it that well.Below is the full class. You can see that adc_dac_env is the instance that has num_tx_lanes and num_rx_lanes. I called create to build it and then I am trying to read these variables.

class er_j204_example_tb extends uvm_test;

  `uvm_component_utils(er_j204_example_tb)

  // UVC environment
  er_j204_env adc_dac_env;

  // Constructor
  function new(string name = "er_j204_example_tb",
    uvm_component parent=null);
    super.new(name,parent);
  endfunction : new

  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    uvm_config_db#(int)::set(this,"adc_dac_env",
                               "num_tx_lanes", 3);
    uvm_config_db#(int)::set(this,"adc_dac_env",
                               "num_rx_lanes", 5);
    $display("NUMBER of tx and rx lanes are set here HELLO");
    // create UVC top environment
    adc_dac_env = er_j204_env::type_id::create("adc_dac_env", this);
    $display("Num of tx lanes %0d", adc_dac_env.num_tx_lanes);
    $display("Num of rx lanes %0d", adc_dac_env.num_rx_lanes);
  endfunction : build_phase

endclass : er_j204_example_tb


In reply to shrawan_vaidya:

Calling type_id::create() constructs the class when called. It doesn’t care when it gets called. However, the uvm_component base class constructor has a check that produces an error if a component gets constructed after the build_phase ends. The build_phase() of any children constructed by a parent does not get called until after the build_phase of the parent has returned.

The main thing you have to make sure of is that you call uvm_config_db::set() before anybody tries to do a uvm_config_db::get(). If the set()s and get()s are called in the build_phase of the respective components, that should be taken care of for you. But we need to see how er_j204_env makes the call to get().

In reply to dave_59:

I can see now see the error in my code. create() will create the instance but that does not ascertain that build_phase of that instance has been run. When the build phase runs and there are calls to get() then only num_tx_lanes and num_rx_lanes will get updated.

Thanks Dave! You pretty much cleared everything.

Is it a good practive to use pre_build for set() and build for get() or may be build for set() and connect for get() ?

thanks
shrawan

In reply to shrawan_vaidya:

Using pre_build won’t help you here because you are still trying to access members before they have been assigned a value with get(). And the build_phase typically needs to get() config data to affect how it constructs its children.

Since your parent is setting num_tx_lanes and num_rx_lanes, there is no need to reach into the children to find out their values. You already know what they should be.

But you could use the end_of_elaboration_phase to access any other component because you know by then everything has been constructed, connected, and configured by then.