UVM基础之---------uvm factory机制base

从名字上面就知道,uvm_factory用来制造uvm_objects和component。 在一个仿真过程当中,只有一个factory的例化存在

用户定义的object和component types经过typedef或者宏在factory中注册,factory产生和保存轻量级的代理(proxy):
  1.  uvm_object_registry #(T,Tname) for objects 
  2.  uvm_component_registry #(T,Tname) for components
每一个代理只知道如何建立本身所表明的object或者component的一个例化,并且这对memory 使用也是颇有效率的。

当用户请求一个object或者component的例化, the factory will determine what type of object to create based on its configuration, then ask that type’s proxy to create an instance of the type, which is returned to the user. uvm中整个factory的结构以下。


在介绍UVM实现的factory机制以前,咱们先本身实现一个简单的factory,考虑下为何要实现factory机制?

OVM Cookbook中对OVM中的工厂模式进行了详细的介绍,其中使用了一个toy factory的例子来阐述工厂模式的实现原理,让读者的理解更加深刻。
 
几个重要的概念须要强调一下:
 
1. 单例模式实现的重点:
 
将构造函数申明为私有成员函数,防止外部调用构造函数来建立对象
申明一个类型为自己的静态对象句柄,经过静态函数来建立惟一的一个对象,并将其赋值给此对象句柄。此对象句柄就能够做为访问此单例的一个窗口,也能够用静态函数返回值来访问此单例的对象句柄。
2. 工厂中能够互相overide的类型必须来自于同一个基类
 
因为工厂中保存的是对象的关联数组,在有些编程语言中也叫作字典(python中好像就这么称呼),此关联数组的关键字(key)是对象句柄。而关联数组要求关键字必须是同一个类型,因此overrige的类型必须从属于同一个基类,以保证他们是同一个类型。
对每个类,都生成一个wrapper类,此wrapper类也是一个单例,其对象被静态建立,这个对象一旦被建立,其对象句柄就是惟一的(由于只有一个对象实例)。所以很容易定位此对象句柄,从而经过这个句柄来访问关联数组。
3. 静态函数,静态变量
 
静态函数和静态变量不会和具体的对象实例相关联,实在运行时初始化阶段被建立的,某一种类型只有惟一的一套。所以能够经过类型修饰符"::"访问,而非静态函数和变量是不能用类型修饰符进行访问的。好比OVM Cookbook中实例04-07中:
将 h = family_base::type_id::create();语句换成以下语句:
 
h = family_base::type_id::create_object();
 
就会报错,由于create_object()并非静态函数。不能经过类型修饰符访问。(使用create_object建立对象是不能实现类型重载的,在这里只是用来演示用)
 
静态函数是静态建立的,那么他也只能访问类型的静态变量和静态函数,由于其余变量并无被建立。
4. OVM除了提供以对象句柄做为关键字的关联数组来实现工厂,同时也提供了以字符串做为关键字的关联数组来实现工厂。
 
+OVM_TESTNAME="testcase1" 这种命令行参数中,字符串工厂比较实用,仅此而已
字符串工厂实现更简单,不须要引入wrapper类。直接经过factory.create_component_by_name()函数来建立对象,返回类型必须经过向下转型(downcast)来赋值到实际的具体类型。
字符串工厂并无类型检查,没有对象句柄方式安全。
5  wrapper的设计思想
 
wrapper#(T)是单例的,所以外部不能调用其构造函数,只能经过get_type()来获得其惟一的一个静态对象
get_type()除了用来生成wrapper类的惟一对象,同时还将自身注册到factory工厂中的关联数组中,注册也就是给关联数组增长一个元素,其关键字就是此wrapper#(T)的惟一静态对象的句柄。
wrapper# (T)必须提供一个函数来生成类型T的对象,此函数就是create_object(), 类型T的对象实际中可能有多个,所以create_object()不一样的调用将返回不一样的类型T的对象,此函数不须要是静态的,此函数仅仅被工厂中的关 联数组的值(关联数组的值就是具体的对象句柄)来调用。
wrapper#(T)必须提供一个静态函数,经过类型方式进行调用,也就是create()函数。wrapper中的静态create()函数将经过调用工厂中的create函数来建立对象。
来源: <http://electron64.blog.163.com/blog/static/10603397020110106130965/>


相关文章
相关标签/搜索