UVM Phase Synchronization

Hello,

   I am having question related to phase synchronization in uvm. let me explain by code.
  1. my driver class has following phases.
    build_phase, reset_phase, configure_phase, main_phase
     class my_driver extends uvm_driver;
  
      function new********************


     function build_phase(uvm_phase phase);
         // Necessary logic
     endfunction : build_phase


     task reset_phase(uvm_phase phase);
         // Necessary logic
     endtask : reset_phase

    task configure_phase(uvm_phase phase);
         // Necessary logic
     endtask : configure_phase

    task main_phase(uvm_phase phase);
         // Necessary logic
     endtask : main_phase

     endclass : my_driver
  1. my monitor class has following phases.
    build_phase and run_phase.
   class my_monitor extends uvm_monitor;
  
      function new********************


     function build_phase(uvm_phase phase);
         // Necessary logic
     endfunction : build_phase


     task run_phase(uvm_phase phase);
         // Necessary logic

        /* I want to add logic here, which can detect uvm phases of other class,*/
     endtask : run_phase

     endclass : my_monitor

i want to synchronize main_phase of driver class with run_phase of monitor class. my requirement is [b]run_phase of monitor class only start executing when main_phase of driver class is started. is there any mechanism for such issue in uvm?
or is there any mechanism by which i can know which phase is executing?

Please let me know if more details are required from my side.

Thanks in advance.
Mitesh N.Patel

In reply to mitesh.patel:

You want to mix the run-subphases, like reset_phase, configure_phase etc., with the run_phase. This is a bad approach. If you have reasons to deal with the sub-phases Of UVM you should do this in all components. The best solution is to use in your monitor main_phase instead of run_phase.
But I’m not sure that you really need the sub-phases of the run_phase. The key question is, what do you want to do in these phases.

In reply to chr_sue:

Hi chr_sue,

Thanks for response, i know that this approach is not recommended. but in my environment, developed VIPs are having run_phases and i have to reuse that VIPs. and i can not simply use run_phase, i have to compulsory use, 13 phases parallel with run_phase. so is there any mechanism in UVM, by which i can control over above situation?

Thanks in Advance
Mitesh N. Patel

In reply to mitesh.patel:

Do you really need the reset_phase, configure_phase etc.?
Could you please explain why? You can perform a reset and the configuration using reset sequences and configuration sequences while running the run_phase only.

As suggested by chr_sue, the usage of mixed-phases is not recommended practice. Still if you have constraints of multiple phase usage, then you can make use of wait_for_state API of UVM phase.

The uvm_phase class provides the “wait_for_state” task to wait till a particular state of phase is reached. All you need to do is get a handle of implementation of a phase and call the API.

In the build_phase of monitor, get the handle of main_phase implementation. Thereafter, in the run phase, call the wait task to wait till driver reaches main phase.

// Get handle of main phase in monitor
uvm_phase p;
p = phase.find_by_name("main",0);
// find_by_name prototype
// extern function uvm_phase find_by_name(string name, bit stay_in_scope=1);

// Call wait task in monitor run phase
p.wait_for_state(UVM_PHASE_STARTED);
// wait_for_state prototype
// extern task wait_for_state(uvm_phase_state state, uvm_wait_op op=UVM_EQ);

Note that this works in a single phase domain, I have not tested it across multiple domains. Following is an example of how the wait task is invoked to block the monitor.

  class driver extends uvm_component;
    `uvm_component_utils(driver)
    function new(string name = "driver",uvm_component parent = null);
      super.new(name,parent);
    endfunction
    
    task reset_phase(uvm_phase phase);
      phase.raise_objection(this);
      #5;
      $display($time,"\tdriver: reset phase ended");
      phase.drop_objection(this);
    endtask
      
    task main_phase(uvm_phase phase);
      phase.raise_objection(this);
      phase.drop_objection(this);
    endtask
    
  endclass
      
  class monitor extends uvm_component;
    uvm_phase p;
    
    `uvm_component_utils(monitor)
    function new(string name = "monitor",uvm_component parent = null);
      super.new(name,parent);
    endfunction
      
    function void build_phase(uvm_phase phase);
      p = phase.find_by_name("main",0);
      if(p == null) $display("P found null");
    endfunction
    
    task run_phase(uvm_phase phase);
      phase.raise_objection(this);
      p.wait_for_state(UVM_PHASE_STARTED);
      $display($time,"\tMonitor unblocked");
      phase.drop_objection(this);
    endtask
  endclass

  // Output
  UVM_INFO @ 0: reporter [RNTST] Running test test...
                     5	driver: reset phase ended
                     5	Monitor unblocked
  UVM_INFO /apps/vcsmx/etc/uvm-1.1/src/base/uvm_objection.svh(1267) @ 5: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase

For more information refer to uvm_phase.svh and uvm_phase singletons question. This blog post might also be useful.

In reply to sharvil111:

Thanks sharvil111 and chr_sue for response.
i used same code as mentioned by you. but not getting expected output. here i am attaching code. please let me know if i misunderstood, i am using VCS tool for compile and run the simulation.

/*****************************************************************************/
class driver extends uvm_component;
`uvm_component_utils(driver)
function new(string name = “driver”,uvm_component parent = null);
super.new(name,parent);
endfunction

task reset_phase(uvm_phase phase);
  phase.raise_objection(this);
  #5;
  $display($time,"\tdriver: reset phase ended");
  phase.drop_objection(this);
endtask

task main_phase(uvm_phase phase);
  phase.raise_objection(this);
  phase.drop_objection(this);
endtask

endclass
/***********************************************************************/
class monitor extends uvm_component;
uvm_phase p;

`uvm_component_utils(monitor)
function new(string name = "monitor",uvm_component parent = null);
  super.new(name,parent);
endfunction

function void build_phase(uvm_phase phase);
  p = phase.find_by_name("main",0);
  if(p == null) $display("P found null");
endfunction

task run_phase(uvm_phase phase);
  phase.raise_objection(this);
  p.wait_for_state(UVM_PHASE_STARTED);
  $display($time,"\tMonitor unblocked");
  phase.drop_objection(this);
endtask

endclass

/**********************************************************************/
class test extends uvm_test;
`uvm_component_utils(test)

function new (string name, uvm_component parent);
  super.new(name, parent);
endfunction

driver drv;
monitor mon;

function void build_phase(uvm_phase phase);
  uvm_config_db#(int)::set(this, "drv", "delay", 10);
  uvm_config_db#(int)::set(this, "mon", "delay", 100);
  
  drv = driver::type_id::create("drv", this);
  mon = monitor::type_id::create("mon", this);
  
endfunction

function void start_of_simulation_phase(uvm_phase phase);
  //this.set_report_verbosity_level_hier(UVM_HIGH);
endfunction

endclass

/*********************************************************************/
module top;

import uvm_pkg::*;

initial
run_test(“test”);

endmodule
/********************************************************************/

/*
Output:-

(Specify +UVM_NO_RELNOTES to turn off this notice)

UVM_INFO @ 0: reporter [RNTST] Running test test…
0 Monitor unblocked
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_objection.svh(1270) @ 0: reporter [TEST_DONE] ‘run’ phase is ready to proceed to the ‘extract’ phase
5 driver: reset phase ended
UVM_INFO /apps/vcsmx/etc/uvm-1.2/src/base/uvm_report_server.svh(847) @ 5: reporter [UVM/REPORT/SERVER]

*/

In reply to mitesh.patel:

The same code works for me. It blocks monitor for 5ns.

UVM_INFO @ 0: reporter [RNTST] Running test test...
                   5	driver: reset phase ended
                   5	Monitor unblocked
UVM_INFO /apps/vcsmx/etc/uvm-1.1/src/base/uvm_objection.svh(1267) @ 5: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase

Please find the code at Edit code - EDA Playground . Note that I am also using VCS with UVM-1.1d (and UVM-1.2).

In reply to sharvil111:

Yeah sharvil111,

It is working fine.

Thanks
Mitesh N. Patel