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