1.factory机制的作用
在SystemVerilog中,我们知道,要创建一个类的实例,必须使用new()函数。而在UVM中,提供了factory机制:它可以根据类名创建这个类的一个实例;另外,还可以在创建类的实例时根据是否有重载类型来决定是创建原始的类,还是创建重载后的类的实例。
从本质上来看,factory机制其实是对SystemVerilog中new函数的重载:原始的new函数功能太过简单。经过factory机制的改良后,进行实例化的方法多了很多。
2.使用factory机制进行重载
factory机制最伟大的地方在于其具有重载(override)功能。当然,对于任何一种面向对象语言来说,都具有重载功能。在SystemVerilog中,当在父类中定义一个函数或任务时,如果将其设置为virtual类型,就可以在子类中重载这个函数或任务。
重载方法可以将其原来所属的类型替换为另一个新的类型。在重载之后,原本用于创建(create)原属类型的请求,将由factory机制来创建新的替换类型:这样就可以在不修改原有代码的条件下,用子类替代其父类。这就是用factory机制进行重载的作用。
在实例化时,UVM会通过factory机制在自己内部的一张表格中查看是否有相关的重载记录(在使用set_type_override() 或 set_inst_overide() 等重载方法后,就相当于在factory机制的表格中加入了一条重载记录):当查到有重载记录时,就会使用新的类来替代旧的类。
使用factory机制的重载必须满足的条件:
(1)首先,最重要的一点是:新的用于替换的类型,必须继承于原有类型:
class comp2 extends comp1;
comp2用于替换comp1,即用于重载的类必须是原有的类的子类。
(2)无论是用于重载的类(comp2)还是被重载的类(comp1),都要在定义的时候注册到factory机制中:
`uvm_component_utils(comp1)
`uvm_component_utils(comp2)
(3)被重载的类在实例化时,必须使用factory机制的实例化方式(create),而不能使用传统的 new 方式:
c1 = comp1::type_id::create("c1", null);
(4)在被重载的类中,需要重写的方法,必须定义为virtual类型,否则访问不到重载类中的这个被重写后的方法。
3.factory机制的使用步骤
第一步,将类注册到factory中:使用 `uvm_component_utils() 宏或 `uvm_object_utils() 宏。取决于该类是继承于uvm_component还是uvm_object基类。uvm_component类中的组建构成了UVM验证环境的层次,而uvm_object类构成了验证环境的属性(如配置)和数据传输;
第二步,在例化前设置重载对象和类型。此步只在需要进行重载时执行;
第三步,创建对象:使用factory机制创建:create。