Practical example of polymorphism in UVM
UVM factory mechanism makes the testbench more flexible and re-usable by allowing components to be overriden via the
type_id::create() method. The idea is that at run-time, an object of the overridden data-type will be returned instead of the original. However, it might give a compilation error when a member of the new sub-class component is being accessed in the new environment unless properly casted. This post will describe the scenario and how to overcome the error by casting.
Solution to this problem is a no-brainer, but it is a good example of how polymorphism becomes useful and is a very practical scenario. Consider a simple testbench structure as shown below where base_env is instantiated inside a test class called base_test.
class base_env extends uvm_env; ... endclass class base_test extends uvm_test; base_env m_base_env; ... endclass
Let's say that a new derivative product is being developed, and this testbench is going to be re-used by adding more verification components. For example, if the new design has an upgraded bus protocol, then the driver in the original testbench can be substituted with the new driver using factory methods. Consider a similar scenario where base_env and base_test are replaced with new_env and new_test. And if there is a need to call some function called
display() from m_new_env.m_comp in the new test then the code would look like the following.
class comp extends uvm_component; ... function void display (); ... endfunction endclass class new_env extends base_env; comp m_comp; ... endclass class new_test extends base_test; ... factory.set_type_override_by_type (base_env::get_type(), new_env::get_type()); ... m_base_env.m_comp.display (); // Compilation error endclass
The new test will call
set_type_override_by_type() to substitute all objects of type
base_env with the newly created type
display() function is called in the new test, it will result in a compilation error.
m_base_env.m_comp.display (); | ncvlog: *E,NOTCLM (testbench.sv,94|22): m_comp is not a class item.
The reason for this error is quite simple. m_comp does not really exist in the class m_base_env. Remember that the factory override happens at runtime and the base class handle
m_base_env will contain the new object of the overridden data-type
new_env. This sounds a little familiar, a child class object in a base class handle. Polymorphism !
We have to access members using appropriate class handles. In this case, another handle called m_new_env should be declared to access m_comp.
class new_test extends base_test; // Create a new handle of type new_env new_env m_new_env; ... factory.set_type_override_by_type (base_env::get_type(), new_env::get_type()); ... // Typecast base handle containing subclass object to subclass handle $cast (m_new_env, m_base_env); m_new_env.m_comp.display (); endclass