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.
For more information about agents you can consult:
- Accellera’s UVM 1.1 User’s Guide, page 43
- Verification Academy’s UVM Cookbook, page 42
The source of the agent component can be found here: