user1978273
user1978273

Reputation: 514

Factory overriding parameterized class in UVM

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

Answers (1)

dave_59
dave_59

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

Related Questions