What's the difference between creating a class in build_phase and creating them on the spot in body()?

What’s the difference between creating a class in build_phase and creating them on the spot in body()?
Look at this two examples:

Example 2: Creating class on the spot in body()


function new(string name = "pas4_otp_mem_dl_seq");
  super.new(name);
endfunction : new

virtual function void build_phase(uvm_phase phase);
  super.build_phase(phase);

  // Class created here
  con = pas4_norm_cont_seq::type_id::create("con");
  send_data_seq = pas4_send_otp_data_seq::type_id::create("send_data_seq");
  wait_data_seq = pas4_wait_for_req_addr_seq::type_id::create("wait_data_seq");
endfunction

virtual task body();
  int del;

  `uvm_info(get_type_name(),"Starting OTP DL Seq",UVM_LOW);

  con.start(m_sequencer);
    
  for(cnt = 0; cnt <8 ; cnt++) begin 
    for(i = 0; i<3; i++) begin
      wait_data_seq.start(m_sequencer);
      if(wait_data_seq.grant) begin
        send_data_seq.start(m_sequencer);
      end
    end
  end
    
  `uvm_info(get_type_name(),"OTP DL Seq Done", UVM_LOW);

endtask : body

Example 2: Creating class on the spot in body()


function new(string name = "pas4_otp_mem_dl_seq");
  super.new(name);
endfunction : new

virtual task body();
  int del;

  `uvm_info(get_type_name(),"Starting OTP DL Seq",UVM_LOW);
  con = pas4_norm_cont_seq::type_id::create("con");

  con.start(m_sequencer);
    
  for(cnt = 0; cnt <8 ; cnt++) begin 
    for(i = 0; i<3; i++) begin
      send_data_seq = pas4_send_otp_data_seq::type_id::create("send_data_seq");     // Class created on the spot
      wait_data_seq = pas4_wait_for_req_addr_seq::type_id::create("wait_data_seq"); // Class created on the spot
      wait_data_seq.start(m_sequencer);
      if(wait_data_seq.grant) begin
        send_data_seq.start(m_sequencer);
      end
    end
  end
    
  `uvm_info(get_type_name(),"OTP DL Seq Done", UVM_LOW);

endtask : body

I have a guess. Is it because that creating them on the spot will reset its values to their initialized values?

In reply to Reuben:

If config_db has anything to do with those class , it may lead to bad handle reference error (as most of get and set usually happens at build phase). And do objects have phases ?.

UVM Components can only be created in build_phase.
UVM Objects (including sequences) can be created any time.
I don’t think your first example will work, because uvm_components don’t have a body() method and uvm_objects don’t have a build_phase() method.
We recommend that sequences be created at run_time, usually from the test, and passed down via the config_db.

In reply to tfitz:

Hi,

Thanks for the info.
May I know why it is recommended to create sequences at run_time?

In reply to Reuben:

You only want to create sequences when you’re going to run them. At build_time, you don’t always know what the component hierarchy is going to look like, since it may depend on configuration parameters. At run_time, you always know what you have, so that’s the best time to decide which sequences to create and run.
If you want to create them before run_phase() begins, you can do this in start_of_simulation_phase() [which is a function] and then actuall start them in run_phase.