Uvm_domain

Hi,

Want to add user defined phase in new uvm_domain. Code is as below.
Flow is as under.

  • Taken handle of uvm_domain domain1 in test.
  • Created the object of domain1, domain1 = new() in test.
  • set domain of the env component using m_env1.set_domain(domain1) from test.
  • Since set_domain method call the define_domain method, Have declare define_domain method in env and have done super.define_domain(domain) to add the uvm phases (reset, config, main and shutdown) in the new domain1.
  • After that have added the user define phase using “domain.add (uvm_user_phase::get(),null, domain.find (uvm_reset_phase::get()), null)”.

But from log it seems it is not adding user define phase.

If we add below code in the define_domain function then it is adding the user define phase but i am thinking it is not the correct way because get_uvm_domain is returning the static handle m_uvm_domain of uvm_domain so it is changing the domain from domain1 to m_uvm_domain.

function void define_domain(uvm_domain domain);
      **uvm_domain d;  //ADDED Extra**
      super.define_domain(domain);
      `uvm_info("DEFINE_DOMAIN","In define_domain function",UVM_MEDIUM)
      **d = domain.get_uvm_domain(); // ADDED Extra**
      **//domain.add (uvm_user_phase::get(),null, domain.find (uvm_reset_phase::get()), null); // replaced this line with below line.
      d.add (uvm_user_phase::get(),null, d.find (uvm_reset_phase::get()), null);**
endfunction

Can you please give the correct way to add user defined phase in to new domain?

///////=========Test bench=========///////

// Code your testbench here
// or browse Examples
// Code your testbench here
// or browse Examples
/*
Copyright 2015 Doulos Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Phase jumping, tidying up after a phase jump


`include "uvm_macros.svh"

package pkg;
  import uvm_pkg::*;

typedef test;
class uvm_user_phase extends uvm_task_phase; 
   virtual task exec_task(uvm_component comp, uvm_phase phase); 
      test TEST;
     if ($cast(TEST, comp)) begin
         TEST.user_phase (phase);
         TEST.m_env1.user_phase (phase);
         TEST.m_env2.user_phase (phase);
     end
   endtask
   local static uvm_user_phase m_inst; 
   static const string type_name = "uvm_user_phase"; 
   static function uvm_user_phase get(); 
      if(m_inst == null)
         m_inst = new; 
      return m_inst; 
   endfunction
   protected function new(string name="user"); 
      super.new(name); 
   endfunction
   virtual function string get_type_name(); 
      return type_name; 
   endfunction
endclass

  class env extends uvm_env;
    `uvm_component_utils(env)
    
    int m_delay;
    
    function new (string name, uvm_component parent);
      super.new(name, parent);
    endfunction
    
    function void build_phase(uvm_phase phase);
      if (!uvm_config_db#(int)::get(this, "", "delay", m_delay))
        `uvm_fatal("", "Delay missing from config db")
      `uvm_info("BUILD_PHASE","in build phase",UVM_MEDIUM)
    endfunction
    
    function void connect_phase(uvm_phase phase);
      `uvm_info("CONNECT_PHASE","in connect phase",UVM_MEDIUM)
    endfunction
        
    task reset_phase(uvm_phase phase);
      `uvm_info("", "reset_phase called", UVM_MEDIUM)
      phase.raise_objection(this);
      #(m_delay);
      phase.drop_objection(this);
      `uvm_info("", "reset_phase returning", UVM_HIGH)
    endtask
    
    task configure_phase(uvm_phase phase);
      `uvm_info("", "configure_phase called", UVM_MEDIUM)
      phase.raise_objection(this);
      #(m_delay);
      phase.drop_objection(this);
      `uvm_info("", "configure_phase returning", UVM_HIGH)
    endtask
    
    bit m_busy = 0;
    
    task main_phase(uvm_phase phase);
      `uvm_info("", "main_phase called", UVM_MEDIUM)
      phase.raise_objection(this);
      m_busy = 1;
      #(m_delay);
      m_busy = 0;
      phase.drop_objection(this);
      `uvm_info("", "main_phase returning", UVM_HIGH)
    endtask
    
    task shutdown_phase(uvm_phase phase);
      `uvm_info("", "shutdown_phase called", UVM_MEDIUM)
      phase.raise_objection(this);
      #(m_delay);
      phase.drop_objection(this);
      `uvm_info("", "shutdown_phase returning", UVM_HIGH)
    endtask

    virtual task user_phase (uvm_phase phase);
      `uvm_info ("ENV", $sformatf ("In %s_phase ENV", phase.get_name()), UVM_MEDIUM)
    endtask

    function void define_domain(uvm_domain domain);
      super.define_domain(domain);
      `uvm_info("DEFINE_DOMAIN","In define_domain function",UVM_MEDIUM)
      domain.add (uvm_user_phase::get(),null, domain.find (uvm_reset_phase::get()), null);
    endfunction
// 4) phase_ended can be used to tidy up after a phase jump
//    On a phase jump, all child processes of the phase method are killed
//      and hence any sequences started in that phase are killed automatically
//    All objections for that phase are dropped automatically (objection count is reset to zero)
  
    function void phase_ended(uvm_phase phase);
      if (phase.get_objection() != null)
        assert( phase.get_objection_count() == 0);
      if (m_busy)
        `uvm_info("", {phase.get_full_name(), " phase_ended called when busy"}, UVM_MEDIUM)
      m_busy = 0;     
    endfunction

  endclass

  
  class test extends uvm_test;
    `uvm_component_utils(test)
    
    function new (string name, uvm_component parent);
      super.new(name, parent);
    endfunction
    
    env m_env1;
    env m_env2;

    uvm_domain domain1;
    uvm_domain domain2;
    
    function void build_phase(uvm_phase phase);
      uvm_config_db#(int)::set(this, "m_env1", "delay", 10);
      uvm_config_db#(int)::set(this, "m_env2", "delay", 100);
      
      m_env1 = env::type_id::create("m_env1", this);
      m_env2 = env::type_id::create("m_env2", this);
      
      domain1 = new("domain1");
      m_env1.set_domain(domain1);
      
      domain2 = new("domain2");
      m_env2.set_domain(domain2);

// 3) If another domain is synced to a domain that jumps backward, the synced domain will not jump
//    but will wait for the jumped domain to catch up.
//    If a domain jumps forward, the synced domain will not jump but will be allowed to proceed 
    
      domain1.sync(domain2);
    endfunction
    
    function void start_of_simulation_phase(uvm_phase phase);
      //this.set_report_verbosity_level_hier(UVM_HIGH);
    endfunction
    
    virtual task user_phase (uvm_phase phase);
      `uvm_info ("TEST", $sformatf ("In %s_phase TEST", phase.get_name()), UVM_MEDIUM)
    endtask
    
    task run_phase(uvm_phase phase);

// 1) Can jump a domain forward or backward in the phase sequence
//    Backward jumps should be restricted to run-time phases

      #250; // Middle of main phase
      //domain2.jump(uvm_reset_phase::get());

//    Abandons the current phase for all the components in the given domain

      
// 2) Forward jumps should be restricted to post-run-time common phases

      #250; // Middle of main phase
      //domain2.jump(uvm_extract_phase::get());
      
// Do not attempt to jump over run-time phases or jump into parallel phases

    endtask
    
  endclass
endpackage


module top;

  import uvm_pkg::*;
  import pkg::*;

  initial
    run_test("test");
  
endmodule

//////==========Test bench end=====///////

/////=======output log=======////
UVM_INFO @ 0: reporter [RNTST] Running test test…
UVM_INFO testbench.sv(115) @ 0: uvm_test_top.m_env1 [DEFINE_DOMAIN] In define_domain function
UVM_INFO testbench.sv(115) @ 0: uvm_test_top.m_env2 [DEFINE_DOMAIN] In define_domain function
UVM_INFO testbench.sv(66) @ 0: uvm_test_top.m_env1 [BUILD_PHASE] in build phase
UVM_INFO testbench.sv(66) @ 0: uvm_test_top.m_env2 [BUILD_PHASE] in build phase
UVM_INFO testbench.sv(70) @ 0: uvm_test_top.m_env1 [CONNECT_PHASE] in connect phase
UVM_INFO testbench.sv(70) @ 0: uvm_test_top.m_env2 [CONNECT_PHASE] in connect phase
UVM_INFO testbench.sv(74) @ 0: uvm_test_top.m_env2 reset_phase called
UVM_INFO testbench.sv(74) @ 0: uvm_test_top.m_env1 reset_phase called
UVM_INFO testbench.sv(78) @ 10: uvm_test_top.m_env1 reset_phase returning
UVM_INFO testbench.sv(78) @ 100: uvm_test_top.m_env2 reset_phase returning
UVM_INFO testbench.sv(82) @ 100: uvm_test_top.m_env1 configure_phase called
UVM_INFO testbench.sv(82) @ 100: uvm_test_top.m_env2 configure_phase called
UVM_INFO testbench.sv(86) @ 110: uvm_test_top.m_env1 configure_phase returning
UVM_INFO testbench.sv(86) @ 200: uvm_test_top.m_env2 configure_phase returning
UVM_INFO testbench.sv(92) @ 200: uvm_test_top.m_env2 main_phase called
UVM_INFO testbench.sv(92) @ 200: uvm_test_top.m_env1 main_phase called
UVM_INFO testbench.sv(98) @ 210: uvm_test_top.m_env1 main_phase returning
UVM_INFO testbench.sv(98) @ 300: uvm_test_top.m_env2 main_phase returning
UVM_INFO testbench.sv(102) @ 300: uvm_test_top.m_env2 shutdown_phase called
UVM_INFO testbench.sv(102) @ 300: uvm_test_top.m_env1 shutdown_phase called
UVM_INFO testbench.sv(106) @ 310: uvm_test_top.m_env1 shutdown_phase returning
UVM_INFO testbench.sv(106) @ 400: uvm_test_top.m_env2 shutdown_phase returning
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_report_server.svh(847) @ 400: reporter [UVM/REPORT/SERVER]
/////========output log end==////

Thanks and regards,
Piyush

In reply to piyushpatel123:

Hi Piyush,

For user defined phase , following link would be helpful.
User-defined Phases in uvm - EDA Playground

Hi Piyush,
did you get any solution for this? I am also facing the similar issue with set_domain
Thanks