I believe you are misunderstanding a lot of things regarding ports/exports.
analysis_ports and analysis_export belonging together. On the same hierchy level you can only connects ports iwth exports. Only on different hierarchy levels you can connect ports with ports and exports with exports or imps. the ports are requring a method they are calling and the exports/imps have to provide this method. That is very simple but powerful.
After going through source code ( and even trying various codes ) I know one thing for certain , the port-to-port , port-to-export connection if not followed doesn’t have any consequences for analysis_port .
The txn object will still be transferred from starting port to the imp .
Here’s a snippet from uvm_port_base class ::
// if we're an analysis port, allow connection to anywhere
if (get_type_name() == "uvm_analysis_port")
return 1;
Also when it comes to normal ( non analysis port classes ) if I use ::
sub_comp1.sub_comp2.port.connect ( sub_comp3.imp ) ;
// sub_comp2 is child of sub_comp1 . sub_comp1 and sub_comp3 are at same level of hierarchy .
I would still see the transaction being transferred from port to imp .
Here’s a link to a question I had posted regarding the same on accellera forum ::
Look to the UVM Reference Manual. It says:
for
uvm_analysis_port: Broadcasts a value to all subscribers implementing a uvm_analysis_imp.
uvm_analysis_imp: Receives all transactions broadcasted by a uvm_analysis_port. It has to implement the write function.
uvm_analysis_export: Exports a lower-level uvm_analysis_imp to its parent.