UVM ports are never registered with the factory, and covergroups are also never registered with the factory. Why?

Hi All,
This (http://www.sunburst-design.com/papers/CummingsSNUG2012SV_UVM_Factories.pdf) paper brings up a valid point:

From the paper:
“UVM ports are never registered with the factory, and covergroups are also never registered with the factory. In general TLM fifos are also not registered with the factory”

I am curious to know, why?

In reply to Verif Engg:

Only classes can be extended and work with the factory. I suppose Cliff mentions covergroups because both classes and covergroups get constructed with the new() method.

If you were to extend the TLM fifo, you can certainly register the extension with the factory, but the problem is the base TLM fifo is not registered in the base class library. This means you cannot call the create() method of the base class factory object, nor can you specify an override of the base TLM fifo. The same is true for any TLM port. In order to perform an override, both the original requested type and the desired type have to be registered.

I believe that upcoming revisions of the UVM have changed this so most base class library definitions register with the factory.

In reply to dave_59:

Hi Dave,
in factory override for scoreboard/monitor ,how do we handle ports , is it going to take overriden class port handle

thanks

In reply to ramankaur09:

I think you are confusing class types with class variables. The UVM factory gives you ways of creating objects with overridden class types. You can certainly override a scoreboard/monitor with more ports, which just means defined an extended type with more class variables.

In reply to dave_59:

Hello ,
when i try to run my uvm env and try to override the monitor via override monitor then override occurs but null pointer error for port occurs, can u pls suggest,
for m_monitor.aport.connect(agent_aport);` line

UVM_INFO classes_v/axi_scoreboard.sv(24) @ 0: uvm_test_top.m_env.m_axi_scoreboard [SCOREBOARD] BUILD
xmsim: *E,TRNULLID: NULL pointer dereference.
File: /pkg/cadence-xcelium-/21.02.001/i686-linux/tools/methodology/UVM/CDNS-1.1d/sv/src/base/uvm_port_base.svh, line = 463, pos = 38
Scope: worklib.uvm_pkg::uvm_port_base#(uvm_pkg::uvm_tlm_if_base#(T,T))::connect
Time: 0 FS + 13
Verilog Stack Trace:
0: function worklib.uvm_pkg::uvm_port_base#(uvm_pkg::uvm_tlm_if_base#(T,T))::connect at /pkg/cadence-xcelium-/21.02.001/i686-linux/tools/methodology/UVM/CDNS-1.1d/sv/src/base/uvm_port_base.svh:463
1: function worklib.$unit_0x746ee0b2::axi_agent@2763_4.connect_phase at ./classes_v/axi_agent.sv:42
2: function worklib.uvm_pkg::uvm_connect_phase@685_2.exec_func at /pkg/cadence-xcelium-/21.02.001/i686

Please help:
monitor.sv

ifndef AXI_MONITOR define AXI_MONITOR

class axi_monitor extends uvm_monitor;
`uvm_component_utils(axi_monitor)
uvm_analysis_port #(stimulus) monitor_aport;
virtual axi_intf intf;
stimulus m_seq;

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

extern virtual function void build_phase(uvm_phase phase);
extern task run_phase(uvm_phase phase);
extern task collect_data(stimulus m_seq);
endclass:axi_monitor

function void axi_monitor::build_phase(uvm_phase phase);
begin
if(!uvm_config_db#(virtual axi_intf )::get(this,“”,“intf”,intf))
`uvm_error(" ERROR MONITOR",$sformatf("%s ",this.get_type_name()))

monitor_aport = new(“monitor_aport”, this);
end
endfunction

task axi_monitor::run_phase(uvm_phase phase);
begin
@(posedge intf.reset);
m_seq = stimulus::type_id::create(“m_seq”,this);
collect_data(m_seq);
end
endtask

task axi_monitor::collect_data(stimulus m_seq);
begin
forever
begin
@(posedge intf.clk);
m_seq.data = 32’h12345678;
`uvm_info(“MONITOR”,$sformatf(“MONITOR %h”,m_seq.data),UVM_LOW);
monitor_aport.write(m_seq);
end

end
endtask

`endif

ovveride_monitor.sv

class override_monitor extends axi_monitor;
`uvm_component_utils(override_monitor)
uvm_analysis_port #(stimulus) aport;
virtual axi_intf intf;
stimulus m_seq;

// Constructor
function new(string name=override_monitor", uvm_component parent);
super.new(name,parent);
endfunction

extern virtual function void build_phase(uvm_phase phase);
extern task run_phase(uvm_phase phase);
extern task collect_data(stimulus m_seq);
endclass:override_monitor

function void override_monitor::build_phase(uvm_phase phase);
begin
if(!uvm_config_db#(virtual axi_intf )::get(this,“”,“intf”,intf))
uvm_error(" ERROR MONITOR",$sformatf("%s ",this.get_type_name())) uvm_info(“OVERRIDE MONITOR BUILD”,“”,UVM_LOW);
aport = new(“aport”, this);
`uvm_info(“OVERRIDE MONITOR BUILD”,$sformatf(“override monitor %s”,this.sprint()),UVM_LOW)
end
endfunction

task override_monitor::run_phase(uvm_phase phase);
begin
@(posedge intf.reset);
m_seq = stimulus::type_id::create(“m_seq”,this);
collect_data(m_seq);
end
endtask
task override_monitor::collect_data(stimulus m_seq);
begin
forever
begin
@(posedge intf.clk);
m_seq.data = 32’h12345678;
`uvm_info(“override MONITOR”,$sformatf(“MONITOR %h”,m_seq.data),UVM_LOW);
aport.write(m_seq);
end

end
endtask

agent.sv

ifndef AXI_AGENT_PKG define AXI_AGENT_PKG
class axi_agent extends uvm_agent;

`uvm_component_utils(axi_agent)
axi_sequencer m_seqr ;
axi_driver m_driver;
axi_monitor m_monitor;
//axi_config m_config;
uvm_analysis_port #(stimulus) agent_aport;
uvm_analysis_port #(stimulus) monitor_aport;
virtual axi_intf intf;

function new(string name,uvm_component parent);
super.new(name,parent);
monitor_aport = new(“monitor_aport”, this);
endfunction

extern virtual function void build_phase(uvm_phase phase);
extern virtual function void connect_phase(uvm_phase phase);

endclass: axi_agent

function void axi_agent::build_phase(uvm_phase phase);
if(!uvm_config_db# (virtual axi_intf)::get(this,“”,“intf”,intf))
`uvm_error(“ERROR AGENT”,“BUILD_PHASE”)

agent_aport = new("agent_aport", this);

m_seqr = axi_sequencer::type_id::create(“m_seqr”,this);
m_driver = axi_driver::type_id::create(“m_driver”,this);
//m_driver.intf = intf;
m_monitor = axi_monitor::type_id::create(“m_monitor”,this);
`uvm_info(“UMONITOR”,get_type_name(),UVM_LOW);
endfunction

function void axi_agent::connect_phase(uvm_phase phase);
m_driver.seq_item_port.connect(m_seqr.seq_item_export);
m_monitor.aport.connect(agent_aport);`
endfunction

`endif

In reply to ramankaur09:

Please use code tags to make your code better readable and show line 42 in classes_v/axi_agent.sv.