Analysis port data type conflict from derived classes

I’m getting the following data type mismatch error:

xmelab: *E,TYCMPAT formal and actual do not have assignment compatible data types (expecting datatype compatible with ‘class derived_pkg::derived_master_req_transfer’ but found ‘class derived_pkg::derived_slave_req_transfer’ instead), detected while elaborating ‘class derived_pkg::my_predictor#(.T(class derived_pkg::derived_master_req_transfer))’

I have two derived classes, derived_slave_req_transfer and derived_master_req_transfer, from base_sequence_item.

The predictor I have receives both of these derived objects and I’m looking to copy the stuff1 and stuff2 back into a base class and use write_transaction to write it out to the anaylsis out_port.

I think I may have figured out my solution in creating this example. I just don’t have a simulator to run it right now.
Could I solve my problem by getting rid of the case statement and create a virtual function for each data type argument for write_transaction. Therefore, the compiler won’t fail in the evaluation of datatype going to the out_port.

Like:

function void my_predictor::write_transaction(input derived_master_req_transfer trans);
and
function void my_predictor::write_transaction(input derived_target_req_transfer trans);

I don’t get an error if I use the out_derived_master_port and out_derived_slave_port which defines the data type per case.

EDIT: *After doing some reading, I guess what I’m asking for is overloading for SystemVerilog which is not supported. I guess the best concise code would be to create a imp_decl for each data_type and define:

uvm_analysis_port#(base_sequence_item ) out_port;

Here is my example:



class base_sequence_item extends uvm_sequence_item;
      bit stuff1;
      bit stuff2;

endclass

class derived_slave_req_transfer extends base_sequence_item;
     bit stuff_idca1


endclass

class derived_master_req_transfer extends base_sequence_item;
     bit stuff_idca1;


endclass



class my_predictor #(type T = base_sequence_item) extends base_component;

  `uvm_component_param_utils(my_predictor #(T))
   
   typedef my_predictor #(T) this_type;
   
   `uvm_analysis_imp_decl(_transaction)
   
   uvm_analysis_imp_transaction #(T, this_type) trans_port;
   
   uvm_analysis_port#(T) out_port; 
   uvm_analysis_port#(derived_master_req_transfer) out_derived_master_port;
   uvm_analysis_port#(derived_slave_req_transfer)  out_derived_slave_port;

   
   function new(string name = "my_predictor", uvm_component parent);
      super.new(name, parent);

      trans_port = new("trans_port", this);
      out_port = new("out_port",  this);
      out_derived_port = new("out_derived_port",  this);
    
   endfunction // new
   
   extern function void write_transaction(input T trans);

endclass // my_predictor

function void my_predictor::write_transaction(input T trans);


  base_sequence_item base_req_trans ;	
  base_req_trans = new();	    

   
     
     case(trans.get_type_name())  
       "derived_master_req_transfer":begin
	  if($cast(base_req_trans,trans))
	    out_port.write(base_req_trans);   // <------------ERROR occurs here
	  else
	    `tb_error(get_type_name(),$sformatf("Problems casting trans"))	      
	      end
       "derived_slave_req_transfer":begin
	  if($cast(base_req_trans,trans))
	    out_port.write(base_req_trans);   // <------------ERROR occurs here
	  else
	    `tb_error(get_type_name(),$sformatf("Problems casting trans"))	      
	      end
       default:
	 begin
	    out_port.write(trans);
	 end
     endcase
  

endfunction // write_transaction



In reply to edward_dfw:

How did you instantiate the class “my_predictor”? I believe you passed the type “derived_slave_req_transfer” or “derived_master_req_transfer” to “my_predictor” class when you created it, right?

If so, the type of “out_port” is mismatched the type of “base_req_trans” transaction and you got error.