Chapter 7 – Agent

We have both monitors, the sequencer and the driver, so the next step is to connect them up. This is a job for the agent.

An agent doesn’t require a run phase, there is no simulation code to be executed in this block but there will be a connect phase, besides of the build phase.

We will construct the monitors, the sequencer and the driver in the build phase. We will also need to create two analysis ports, these ports will act as proxies for the monitors to be connect to an external scoreboard through the agent’s ports.

Note: We could have made the connection from the monitors directly to the scoreboard within the ‘Env’ class without passing by the agent’s ports. There are cases when this is the best option, or other cases when it’s not. It’s always up to the designer to decide the best option.

After we have constructed the components we need, we have to make the connections between them. Using the concepts learned in chapter 6.0.1 about TLM ports, we can connect each port to its destination.

A part of the code for the agent can be seen on Code 7.1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class simpleadder_agent extends uvm_agent;
     `uvm_component_utils(simpleadder_agent)
 
     //Analysis ports to connect the monitors to the scoreboard
     uvm_analysis_port#(simpleadder_transaction) agent_ap_before;
     uvm_analysis_port#(simpleadder_transaction) agent_ap_after;
 
     simpleadder_sequencer        sa_seqr;
     simpleadder_driver        sa_drvr;
     simpleadder_monitor_before    sa_mon_before;
     simpleadder_monitor_after    sa_mon_after;
 
     function new(string name, uvm_component parent);
          super.new(name, parent);
     endfunction: new
 
     function void build_phase(uvm_phase phase);
          super.build_phase(phase);
 
          agent_ap_before    = new(.name("agent_ap_before"), .parent(this));
          agent_ap_after    = new(.name("agent_ap_after"), .parent(this));
 
          sa_seqr        = simpleadder_sequencer::type_id::create(...
          sa_drvr        = simpleadder_driver::type_id::create(...
          sa_mon_before    = simpleadder_monitor_before::type_id::create(...
          sa_mon_after    = simpleadder_monitor_after::type_id::create(...
     endfunction: build_phase
 
     function void connect_phase(uvm_phase phase);
          super.connect_phase(phase);
          sa_drvr.seq_item_port.connect(sa_seqr.seq_item_export);
          sa_mon_before.mon_ap_before.connect(agent_ap_before);
          sa_mon_after.mon_ap_after.connect(agent_ap_after);
     endfunction: connect_phase
endclass: simpleadder_agent

Code 7.1 – Code for the agent

In Figure 7.1, it’s represented the current state of our testbench.

State of the testbench after the agentFor more information about agents you can consult:

The source of the agent component can be found here: