Monitor subscriber connection via different analysis port?

In reference to analysis port used in system verilog or UVM monitor, is there any specific guidelines on number of analysis port to be used?
While I understand from SV LRM perspective there is no constraint, but from efficiency point of view what will be better implementation … when we have different subscribers consumes either part or all monitored information sampled by monitor:

  • Monitor to have multiple analysis ports and sending different transaction over those analysis port. Respective subscriber can connect to either one or multiple analysis ports to receive data accordingly.
  • Or Monitor to have SINGLE analysis port only. The transaction sent over analysis port can contain handles to all different transactions? All subscriber to use same analysis port, but can get consume relevant information via handles to different transactions.

In reply to bhupeshpaliwal:

Analysis ports are very efficient for one-to-many subscriber connection. That will be more efficient than many one-to-one connections. As long as all the transactions are the same type.

In reply to dave_59:
Thanks Dave for your kind suggestion. Here transactions are different only however multiple subscriber uses either part OR all of monitored information.



// two types of transaction
class tr_1 extends uvm_transaction;
// ..
endclass
class tr_2 extends uvm_transaction;
// ..
endclass

// option-1: multiple ap in monitor
class my_mon_1 extends uvm_monitor;
  uvm_analysis_port#(tr_1) ap_1;
  uvm_analysis_port#(tr_2) ap_2;
endclass

// subscriber-1 only use tr_1
class my_sub_1 extend uvm_subscriber;
  uvm_analysis_export#(tr_1) exp; // connected to ap_1
endclass

// subscriber-2 only use tr_2
class my_sub_2 extend uvm_subscriber;
  uvm_analysis_export#(tr_2) exp;  // connected to ap_2
endclass

// subscriber-3 only use both tr_1 and tr_2
class my_sub_3 extend uvm_subscriber;
  uvm_analysis_export#(tr_1) exp_1;  // connected to ap_1
  uvm_analysis_export#(tr_2) exp_2;  // connected to ap_2

  // use tr_1 from exp_1
  // use tr_2 from exp_2
endclass


// Option-2: SINGLE analysis port in monitor

// create wrapper having both tr_1 and tr_2
class tr_wrap extends uvm_transaction;
  tr_1 t1;
  tr_2 t2;
// ..
endclass

// single analysis port to send tr_wrap
class my_mon_2 extends uvm_monitor;
  uvm_analysis_port#(tr_wrap) ap;
endclass

// subscriber-1 use tr_1
class my_sub_1 extend uvm_subscriber;
  uvm_analysis_export#(tr_wrap) exp; // connected to ap
  // use tr_wrap.t1 if not null
endclass

// subscriber-2 use tr_2
class my_sub_2 extend uvm_subscriber;
  uvm_analysis_export#(tr_wrap) exp; // connected to ap
  // use tr_wrap.t2 if not null
endclass

// subscriber-3 only use both tr_1 and tr_2
class my_sub_3 extend uvm_subscriber;
  uvm_analysis_export#(tr_wrap) exp; // connected to ap
  // use both tr_wrap.t1 and tr_wrap.t2 if not null
endclass


If I understand correctly I hope I should stick to option-2. Please do confirm or guide accordingly.
While I understand both option-1 and option-2 are expected to work fine, I am just seeking opinion here from better structure and performance point of view.

In reply to bhupeshpaliwal:
Only a small remark. The uvm_subscriber has a built-in analysis_export.

In reply to chr_sue:

Ah yes! True.