UVM Agent
Table of Contents
- a user-defined agent is extended from uvm_agent, uvm_agent is inherited by uvm_component
- An agent typically contains a driver, a sequencer, and a monitor
- Agents can be configured either active or passive
Active agent
- Active agents generate stimulus and drive to DUT
- An active agent shall consists of all the three components driver, sequencer, and monitor

Passive agent
Passive agents sample DUT signals but do not drive them
A passive agent consists of only the monitor

An agent can be configured as ACTIVE/PASSIVE by using a set config method, the default agent will be ACTIVE. the set config can be done in the 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 UVM Agent
1. An 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 the build phase,
driver and sequencer will be created only for the 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 the 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