Reputation: 514
I have a parameterized seq_item as below
class seq_item#(int A = 64) extends uvm_sequence_item;
`uvm_object_param_utils(seq_item#(A))
rand logic [A-1:0] v;
constraint v_c {
v inside {[0:1000]};
}
endclass : seq_item
class extended_seq_item#(int A = 64) extends seq_item#(A);
`uvm_object_param_utils(extended_seq_item#(A))
constraint extended_v_c {
v inside {[10:50]};
}
endclass : extended_seq_item
class reg_adapter#(int A = 100) extends uvm_reg_adapter;
`uvm_object_param_utils(reg_adapter#(A))
typedef seq_item#(A) seq_item_t;
function new(string name = "reg_adapter")
seq_item_t req;
req = seq_item_t::type_id::create("req");
endfunction
endclass : reg_adapter
class test extends uvm_test;
`uvm_component_utils(test)
reg_adapter#(10) adapter;
function void build_phase(uvm_phase phase);
seq_item#(10)::type_id::set_type_override(extended_seq_item#(10)::get_type());
super.build_phase(phase);
adapter = reg_adapter::type_id::create("adapter");
endfunction : build_phase
endclass : test
In my UVM TB, I need to factory override all seq_item instances with extended_seq_item. Different instances will have different parameter values of A. How do I factory override this?
The problem is seq_item is from common collateral which has generic constraint for rand variable v which holds good for all IPs. For my IP, I need to add an additional constraint for v as given in extended_seq_item. My IP nuses reg_adapter which is expected to take extended_seq_item with additional constraints added
Thanks & Regards, Kiran
Upvotes: 4
Views: 5270
Reputation: 42623
Unfortunately, parameterized classes with different parameter values (specializations is the LRM's terminology) are treated as separate class types, so you'll need to provide an override for each parameter value.
seq_item#(10)::type_id::set_type_override(extended_seq_item#(10)::get_type());
seq_item#(20)::type_id::set_type_override(extended_seq_item#(20)::get_type());
seq_item#(30)::type_id::set_type_override(extended_seq_item#(30)::get_type());
If you can get this code into a place where A is already parametrized, like in a the build_phase of a parameterized env or agent, then it might not be as painful as the above.
Now that I see more code, the problem is the class scope in this line, which should have been caught as an error
adapter = reg_adapter::type_id::create("adapter");
should be written as
adapter = reg_adapter#(10)::type_id::create("adapter");
Upvotes: 3