【UVM】Factory Pattern In UVM
使用工厂模式可以动态的生成对象,能够封装具体类型的实例化操作,通过让子类型决定要创建的对象达到将对象创建的过程封装的目的.工厂机制不仅是OO的精华,也是UVM的基石,通过Factory机制实现了通过字符串创建实例,面对UVM测试平台中众多的组件,使用该机制可以方便实现组件的注册和创建,极大地简化了测试平台的搭建,可以说,Factory贯穿每一个UVM测试平台的始终,因此其重要性可见一斑。为此本文将以具体示例叙述工厂机制的基本原理。
在UVM中,一般使用工厂机制主要实现以下几个操作:
1.注册;
2.实例化;
3.重载(通过类型或者名称进行重载);
为了简化UVM复杂的工厂机制的原理,本文以汽车的制造销售为例,简要阐述Factory工作的基本原理,示例结构与UVM源代码中Factory类似,但是功能不如UVM源代码完全,只为大家方便理解构建环境时一些奇怪的写法的原因。
【示例概述】工厂负责生产不同品牌汽车的部件,4S点可以根据工厂提供的部件组装汽车然后贴牌销售。基本结构如下图所示:
car_base为原型车,一般包括所有汽车的共性,例如轮子、方向盘等;
car_brand是基于原型车派生的各种类型的汽车,例如燃油汽车、电动汽车等;
下图为燃油汽车派生出的不同品牌的汽车,例如法拉利、劳斯莱斯、宾利等,当同品牌的汽车更新换代时,可以使用新一代的汽车代替(override)旧一代的汽车,例如雅阁9覆盖雅阁8;
car_licence为制造销售汽车的许可证,其中包含了销售店铺必须具有的基本条件和要求等;
car_4s_proxy为取得销售汽车资质的销售不同品牌的店铺,本例中一个店铺仅制造销售一个品牌的汽车;
而制造销售店铺(car_4s_proxy)一般并不存放大量的具体汽车(car_brand),一般情况下客户都是到店里看车模或者宣传册,然后由店里向汽车部件生产制造商提出某品牌汽车部件需求,汽车生产制造工厂(car_factory)然后制造相关汽车相关汽车的部件。根据汽车销售和制造的流程,我们结合下述代码对工厂机制工作流程进行简要分析。
上图的类属框图如下图所示:
当客户想购买一辆Ferrari时,需要到取得销售Ferrari的4s店进行购买,这个4s店通过该车定义时"`car_brand_utils(Ferrari)"与销售Ferrari的4s店关联起来(成立一个销售Ferrari的4s店),同时将该店注册到(factory.register)可以为该店生产汽车部件的生产工厂名录中(该工厂只为该名录中的4s店生产汽车部件),这样后续如果要生产Ferrari汽车部件,工厂就可以在其名录中找到对应的4s店,然后根据其销售汽车的品牌提供对应的服务。我们这里构建的工厂可以生产不同品牌的汽车部件,具体生产哪些品牌的汽车部件都是根据工厂名录决定的,4s店在得到具体汽车部件后进行组装,最终提供给用户。由此建立了三者之间的关系:制造、组装销售。
上例中Ferrari更新换代为了Ferrari_911,因此工厂对其修改名录进行更新,当用户来到4s店购买Ferrari时,4s店将最终提供的车型为新款的Ferrari_911,仿真结果如下:
为此我们对上述的购车活动再次进行细化分析。当顾客需要一辆Ferrari汽车的时候,调用4s店的"Ferrari::type_id::build_car",为了生产出具体的汽车,4s店的build_car会通知工厂准备对应的部件(create_object_by_type),工厂收到请求后准备好原材料,通知4s店,4s店通过build完成对应的Ferrari汽车的组装生产,生产组装完成的Ferrari就可以根据其功能进行使用了。整个买车四步走的过程如下图所示:
第一部:注册(宏定义);
第二步:调用对象创建函数(build_car);
第三部:具体示例化对象(build);
第四部:返回实例;
我们在具体构建UVM的验证平台时,经常会遇到在类定义的开始处调用宏,其实与此例中的"`car_brand_utils(Ferrari)"作用类似,然后都是通过层层调用实现特定对象的实例化,与此例中的"Ferrari::type_id::build_car"工作原理类似,一个验证结构中的组件被一个新的组件重载的过程就类似与此例中的"car_factory::override_type("Ferrari","Ferrari_911")"。
【示例】
1.静态函数或者变量可以通过类名直接引用;
2.define和typedef参数的传递;
3.静态变量和初始化发生在编译阶段;
4.关联数组类似于Perl等语言中的hash结构;
5.抽象类不能实例化,其派生类如果需要实例化需要实现抽象类中所有的纯虚方法(pure virtual);
6.抽象类中可以包括纯虚方法(仅存在于抽象类中),也可以包括有定义的非纯虚方法,纯虚方法不包括方法体,仅包括方法原型即可。