I’m trying to use set_type_override_by_type to override base sequence item class into an extend sequence item class which I created for more constraints on the base class properties. However, I’m encountering a compilation err that prevents me to access the new properties that I created inside the extended class. Here is a code example:
In build phase of my test, I override base_seq_item with extended_seq_item:
class test extends uvm_test;
...
function void build_phase( uvm_phase phase );
...
set_type_override_by_type( base_seq_item::get_type(), extended_seq_item::get_type() );
...
// create test evn
...
endfunction
endclass
Inside my sequence, I want to randomize property addr using knob:
the compiler complains that knob is not a class item of base_seq_item, which makes sense to me. However, if this is what I want to do, meaning building more constraints using a new property in an extended class, how can I work around this?
You can further extend the extended_seq_item class adding or overriding more constraints. Then you can replace the factory override with that extended class. (or some other mechanism that overrides the override).
You can also extend your test_sequence class replacing the body method to have a new randomize with constraint.
I prefer the first suggestion and not use the with clause. It is in better keeping with object-oriented programming practices.
I ran below code to access the override class properties but i am unable to achieve this.Could you please help me how to access properties of override class…
class driver extends uvm_driver;
`uvm_component_utils(driver)
//new
endclass
class driver_extended extends driver;
`uvm_component_utils(driver_extended)
string str_val ="RAM";
//new
endcalss
class agent extends uvm_component;
`uvm_component_utils(agent)
driver drv;
//new
function build();
drv = driver::type_id::create("drv",this);
endfunction
endclass
class test_factory extends uvm_test;
agent ag1;
function new(string name="test",uvm_component parent=null);
factory.set_type_override_by_type(driver::get_type(),driver_extended::get_type(),"*"); // overriding component
ag1 = agent::type_id::create("ag1",this);
endfuction
task run();
`uvm_info("VALUE",$psprintf("%s",ag1.drv.str_val),UVM_LOW)
#100;
global_stop_request();
endtask
endclass
For above code,compiler complains as below
str_val is not a class item.
In reply to brambabu:
If you want to access str_val, then you have to have to use a class variable that knows it exists. Also, move your code from OVM to UVM.
task run_phase(uvm_phase phase);
driver_extended drv_ext;
phase.raise_objection(this);
if(!$cast(drv_ext, ag1.drv)) `uvm_error("OOPS","driver override did not work")
`uvm_info("VALUE",$psprintf("%s",drv_ext.str_val),UVM_LOW)
#100;
phase.drop_objection(this);
endtask
Hi Dave,
If the handle to the extended class (drv_ext) is declared, and the same is used to access the variable str_val, where is the override feature coming into picture here? What is the requirement to override, if the declared handle of the extended class is used to access the properties of the extended class, in this scenario?
The test_factory class knows that it has overridden the driver in the agent, but the agent is unaware of the override. The point of OOP is that we can use inheritance in a way that makes code re-usable. If the only thing we override in a class is virtual methods and constraints, their’s no need to access the object with the extended class variable.
I didn’t get ur below statement. Could u please elaborate more on it?
In reply to n.s.suhas:
If the only thing we override in a class is virtual methods and constraints, their’s no need to access the object with the extended class variable.
class agent extends uvm_component;
`uvm_component_utils(agent)
**driver drv;**
//new
function build();
drv = driver::type_id::create("drv",this);
endfunction
endclass
class test_factory extends uvm_test;
agent ag1;
function new(string name="test",uvm_component parent=null);
**factory.set_type_override_by_type(driver::get_type(),driver_extended::get_type(),"*"); // overriding component**
ag1 = agent::type_id::create("ag1",this);
endfuction
endclass
look in test_factory you override driver with driver_extended, using factory. That is good, now everywhere instead of driver object the driver_extended will be used. Everywhere, but agent class.
Look on agent class (bold line). Here you explicitly define drv as “driver” type object. And no factory method can override it, because you explicit define it (without using factory). So for agent class the drv instance is “driver” object type. This is how agent class understands it.
Even though after factory override the drv type is driver_extended, but still for agent class drv is driver type object.
To workaround this we need to user Dave suggested method.
Hi Dave,
How to assign the drv_ext.str_val with a new val from the test_factory which extends the uvm_test? Below seems not working. It only assigns the new_val to the drv_ext not ag1.drv object?
if(!$cast(drv_ext, ag1.drv)) `uvm_error("OOPS","driver override did not work")
drv_ext.str_val = "new_val";
`uvm_info("VALUE",$psprintf("%s",drv_ext.str_val),UVM_LOW)
The point here was str_val only exists in the extended driver. You need an extended driver class variable to reference it even though the handle in the ag1.drv variable has a handle to it.