Search code examples
system-veriloguvm

Getting a handle to a derived class member using uvm_factory


If I have a base class and 3 derived classes, is there a method to access the derived class variables using a pointer of base class type?

Example: (taken out irrelevant code - constructor etc)

class Base extends uvm_object;
  bit[7:0] data;
  virtual function void set_address(bit[7:0 a);
    // do nothing
  endfunction
endclass

class DerivedA extends base;
  bit[7:0] address;
  virtual function void set_address(bit[7:0 a);
    address = a
  endfunction
endclass

class DerivedB extends base;
  bit[7:0] address;
  virtual function void set_address(bit[7:0 a);
    address = a
  endfunction
endclass

class DerivedC extends base;
  bit[7:0] address;
  virtual function void set_address(bit[7:0 a);
    address = a
  endfunction
endclass

Now, lets say I override base by type to DerivedA from my uvm_test. I have a scoreboard though is common to all types - Base, DerivedA, DerivedB and DerivedC.

class Scb extends uvm_scoreboard;

  Base item = Base::type_id::create("m_item"); <------- item will be of type derivedA
  item.address = 'hAA;    <------ illegal
  item.set_address('hAA); <------ legal

endclass

This is all well and great but actually, I have multiple member variables and do not want to create access functions for all of them. I am trying something like the below but not able to figure out what to do.

class Scb extends uvm_scoreboard;

  string s;
  uvm_factory f = uvm_factory::get();
  Base item = Base::type_id::create("m_item"); <------- item will be of type derivedA
  s = item.get_type_name() <----- DerivedA
  $cast(type_name_handle, f.create_object_by_type_name(s)); <----- this is what I want - to create a handle of derived type so I can then access the Derived variables.

endclass

This all may seem unneccessary but it is due to a combination of things that are beyond my control - ie I need all the 4 classes above and would like to avoid using case statements based on type_name (there are many derived classes).

Any solution here? So far I am starting to think this isn't possible.


Solution

  • It's not possible to do what you want given the requirements presented. If address was intended to be in every derived class, why wasn't it put in a common base class, either your Base, or some intermediate base class that sits in-between your Base and the DerivedX classes? That's the point of inheritance.

    You must use the accessor functions, or conditionally branch based on the type name or the result of $casting to each class type.