UVM Agent

 UVM Agent 


user-defined agent is extended from uvm_agent, uvm_agent is inherited by uvm_component.

An agent typically contains: a driver,sequencer, and monitor.

Agents can be configured either active or passive

 Active agent: 

Active agents generate stimulus and drive to DUT.
Active agent should contain all three components driver,sequencer, and monitor.


 Passive agent: 

Passive agents samples DUT signals but does not drive them.
Passive agent should contain only the monitor.


Agent can be configured as ACTIVE/PASSIVE by using set config method, default agent will be ACTIVE. set config can be done in env or test. 

   set_config_int("path_to_agent", "is_active", UVM_ACTIVE);
   set_config_int("path_to_agent", "is_active", UVM_PASSIVE);

 get_is_active() Method: 
get_is_active() Returns UVM_ACTIVE if the agent is acting as an active agent and UVM_PASSIVE if the agent acting as a passive agent.

 Writing Agent :

1. Agent is written by extending UVM_agent,

class mem_agent extends uvm_agent;

  // UVM automation macros for general components
  `uvm_component_utils(mem_agent)

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

endclass : mem_agent

2. Declare driver, sequencer and monitor instance, 

  //declaring agent components
  mem_driver    driver;
  mem_sequencer sequencer;
  mem_monitor   monitor;


3. Depending on Agent type, create agent components in build phase, 
driver and sequencer will be crated only for active agent.

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

    if(get_is_active() == UVM_ACTIVE) begin
      driver = mem_driver::type_id::create("driver", this);
      sequencer = mem_sequencer::type_id::create("sequencer", this);
    end

    monitor = mem_monitor::type_id::create("monitor", this);
  endfunction : build_phase

4. Connect the driver seq_item_port to sequencer seq_item_export for communication between driver and sequencer in connect phase. 

  // connect_phase
  function void connect_phase(uvm_phase phase);
    if(get_is_active() == UVM_ACTIVE) begin
      driver.seq_item_port.connect(sequencer.seq_item_export);
    end
  endfunction : connect_phase

 Complete Agent code, 

class mem_agent extends uvm_agent;
  //declaring agent components
  mem_driver    driver;
  mem_sequencer sequencer;
  mem_monitor   monitor;

  // UVM automation macros for general components
  `uvm_component_utils(mem_agent)

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

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

    if(get_is_active() == UVM_ACTIVE) begin
      driver = mem_driver::type_id::create("driver", this);
      sequencer = mem_sequencer::type_id::create("sequencer", this);
    end

    monitor = mem_monitor::type_id::create("monitor", this);
  endfunction : build_phase

  // connect_phase
  function void connect_phase(uvm_phase phase);
    if(get_is_active() == UVM_ACTIVE) begin
      driver.seq_item_port.connect(sequencer.seq_item_export);
    end
  endfunction : connect_phase

endclass : mem_agent