Welcome ! This website will help YOU (recent graduates/professionals) learn verification languages like SystemVerilog and UVM. Register for free and access more content !

What is a monitor ?

A UVM monitor is responsible for capturing signal activity from the design interface and translate it into transaction level data objects that can be sent to other components.

In order to do so, it requires the following:

  • A virtual interface handle to the actual interface that this monitor is trying to monitor
  • TLM Analysis Port declarations to broadcast captured data to others.

What does a UVM monitor do ?

A UVM monitor is derived from uvm_monitor base class and should have the following functions :

  1. Collect bus or signal information through a virtual interface
  2. Collected data can be used for protocol checking and coverage
  3. Collected data is exported via an analysis port

The UVM monitor functionality should be limited to basic monitoring that is always required.It may have knobs to enable/disable basic protocol checking and coverage collection. High level functional checking should be done outside the monitor, in a scoreboard.

uvm-monitor-env

Steps to create a UVM monitor

1. Create custom class inherited from uvm_monitor, register with factory and call new
 
// my_monitor is user-given name for this class that has been derived from "uvm_monitor"
class my_monitor extends uvm_monitor;
 
  // [Recommended] Makes this monitor more re-usable
  `uvm_component_utils (my_monitor)
 
  // This is standard code for all components
  function new (string name = "my_monitor", uvm_component parent = null);
    super.new (name, parent);
  endfunction
 
  // Rest of the steps come here
endclass
 
2. Declare analysis ports and virtual interface handles
 
  // Actual interface object is later obtained by doing a get() call on uvm_config_db
  virtual if_name vif;
 
  // my_data is a custom class object used to encapsulate signal information
  // and can be sent to other components
  uvm_analysis_port  #(my_data) mon_analysis_port;
 
3. Build the UVM monitor
 
   virtual function void build_phase (uvm_phase phase);
      super.build_phase (phase);
 
      // Create an instance of the declared analysis port
      mon_analysis_port = new ("mon_analysis_port", this);
 
      // Get virtual interface handle from the configuration DB
      if (! uvm_config_db #(virtual if_name) :: get (this, "", "vif", vif)) begin
         `uvm_error (get_type_name (), "DUT interface not found")
      end
   endfunction  
 
4. Code the run_phase
 
  // This is the main piece of monitor code which decides how it has to decode 
  // signal information. For example, AXI monitors need to follow AXI protocol
  virtual task run_phase (uvm_phase phase);
 
 
    // Fork off multiple threads "if" required to monitor the interface,  for example:
    fork
      // Thread 1: Monitor address channel
      // Thread 2: Monitor data channel, populate "obj" data object
      // Thread 3: Monitor control channel, decide if transaction is over
 
      // Thread 4: When data transfer is complete, send captured information 
       // through the declared analysis port
      mon_analysis_port.write(obj);
    join_none
  endtask
 

UVM Monitor Example

 
class my_monitor extends uvm_monitor;
   `uvm_component_utils (my_monitor)
 
   virtual dut_if   vif;
   bit              enable_check = 1;
 
   uvm_analysis_port #(my_data)   mon_analysis_port;
 
   function new (string name, uvm_component parent= null);
      super.new (name, parent);
   endfunction
 
   virtual function void build_phase (uvm_phase phase);
      super.build_phase (phase);
 
      // Create an instance of the analysis port
      mon_analysis_port = new ("mon_analysis_port", this);
 
      // Get virtual interface handle from the configuration DB
      if (! uvm_config_db #(virtual dut_if) :: get (this, "", "vif", vif)) begin
         `uvm_error (get_type_name (), "DUT interface not found")
      end
   endfunction
 
   virtual task run_phase (uvm_phase phase);
      my_data  data_obj = my_data::type_id::create ("data_obj", this);
      forever begin
         @ ([Some event when data at DUT port is valid]);
         data_obj.data = vif.data;
         data_obj.addr = vif.addr;
 
         // If protocol checker is enabled, perform checks
         if (enable_check) 
            check_protocol ();
 
         // Send data object through the analysis port
         mon_analysis_port.write (data_obj);
      end
   endtask
 
   virtual function void check_protocol ();
      // Function to check basic protocol specs
   endfunction
endclass
 

Note the following from the example above :

  • Monitor is extended from uvm_monitor
  • Virtual interface handle is declared as vif and assigned from UVM database via uvm_config_db::get()
  • Additional knobs are provided for enabling/disabling protocol checker (enable_check) and coverage (enable_coverage)
  • Coverage group is defined as cg_trans and will be sampled during run phase
  • During run_phase(), data from interface is captured into local class object, protocol check is performed when enabled, and coverage group is sampled when enabled
  • Data object class is broadcast to other verification components via the analysis port
The knobs can be disabled from the test by using UVM database.

 
uvm_config_db #(bit) :: set (this, "*.agt0.monitor", "enable_check", 0);
uvm_config_db #(bit) :: set (this, "*.agt0.monitor", "enable_coverage", 0);
 

Recommended Practice

uvm_monitor class should be used as the base class for user-defined monitors so that it:

  • Allows you to distinguish monitors from other component types also using its inheritance
  • Any future changes and additions to the base UVM monitor class will be automatically included in your derived class

Was this article helpful ?

We use cookies to personalize content and ads, to provide social media features and to analyze our traffic. You consent to our cookies if you continue to use our website. To find out more about the cookies we use and how to delete them, see our privacy policy.

  I accept cookies from this site.
Agree
EU Cookie Directive plugin by www.channeldigital.co.uk