**Could you elaborate on “you have recursive Consumer object construction” .
**
Via my own abd_pkg [ Useful for Debugging purposes :) ] I see that ::
uvm_test_top.cons.child.put_imp
uvm_test_top.cons.child.child.put_imp
uvm_test_top.cons.child.child.childput_imp
…
Goes on being created ( Hence the Simulation Hang !! )
The intent behind the code was to see apart from typical 'this' ( in 2nd argument while calling new() of imp-port ) what if I delegate the component implementing the interface ( put() method ) to an extended type ( Consumer_child in my original code ) .
Here’s the code of blocking_put_imp class ::
class uvm_blocking_put_imp #(type T=int, type IMP=int) extends uvm_port_base #(uvm_tlm_if_base #(T,T) ) ;
local IMP m_imp;
function new (string name, IMP imp);
super.new (name, imp, UVM_IMPLEMENTATION, 1, 1);
m_imp = imp ;
m_if_mask = MASK ;
endfunction
`UVM_BLOCKING_PUT_IMP (m_imp, T, t)
endclass
So what leads to the simulation hanging ? Essentially 2nd arg. does is
m_imp = imp ;
Which is equivalent to assigning a base class handle to extended class object .
You are creating a child uvm_component whose build_phase will get called. Since Component_child has a build_phase that it inherited from Consumer, its build_phase gets called recursively.
Instead of used the factory override as I show, you could instead extend Consumer_child from uvm_component directly and change the declaration of put_imp. But then the put() task would not have access to anything in the Consumer object.
The above issue is resolved by adding following in Consumer_child ::
function void build_phase ( uvm_phase phase ) ;
$display(" This should solve the issue !! "); // Indeed it does !!
endfunction
Also to call put() of Consumer_child ( Consumer_extended rather is a better name as you suggested ) one would have to simply declare put() task in Consumer class as virtual !!