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