[UVM源代码研究] uvm中的factory机制(uvm-1.2版)

[UVM源代码研究] uvm中的factory机制(uvm-1.2版)

工厂(factory)机制

工厂机制作为设计模式(design pattern)中的一种并不是uvm独有的,但却作为一个重要的概念被uvm引入实现了。

“工厂”表示一个负责创建其他类型对象的类,工厂决定了我们最终创建的类的类型。

factory机制的实现包含了以下几个步骤:

  1. 实现factory机制的类必须使用uvm_object/cmponent_utils系列宏进行注册
  2. 调用set_type_override等override函数对需要创建的类进行覆盖(可选)
  3. 创建类的时候必须使用::type_id::create方法创建(这样才会执行查找override表创建最终的类型)

下面我们分别对以上3个步骤中涉及到的UVM源代码进行解读。

`uvm_object/component_utils系列宏

我们在使用factory机制的时候,必不可少的一个步骤就是相关类在实现的时候必须使用`uvm_object/component_utils宏进行注册,下面以uvm_object为例讲述一系列的相关宏的具体实现。

src/macros/uvm_object_defines.svh中的源代码

在这里插入图片描述

src/macros/uvm_object_defines.svh中的源代码

在这里插入图片描述

src/base/uvm_registry.svh中的源代码

在这里插入图片描述

uvm_object/component_utils宏展开,首先都会调用m_uvm_object_registry_internal/param宏,这两个宏中都定义了一个参数化的uvm_object_registry类类型type_id,不同的是`m_uvm_object_registry_internal宏多了个参数S,而在定义type_id类型的时候将参数S按内容直接替换为字符串作为参数化的类uvm_object_registry的第二个参数。

`uvm_object/component_utils宏的替换实现

下面我们展示将uvm_object/component_utils宏按照上面展开的内容在具体的类apb_transfer代码中替换实现。

使用`uvm_object_utils宏实现的代码

在这里插入图片描述

将`uvm_object_utils宏展开后的代码

在这里插入图片描述

于是我们队`uvm_object_utils宏的实现功能作出如下概括:

  1. 声明了一个type_id类型

  2. 定义了静态函数get_type,返回值为type_id类型

  3. 定义了函数get_object_type,返回值为实际指向type_id类型的uvm_object_wrapper类型

  4. 定义了create函数,返回值为实际指向apb_transfer类型的uvm_object类型(这就是我们在factory机制中创建对象调用的create函数)

  5. 定义了静态字符串常量type_name

  6. 定义了函数get_type_name返回type_name

uvm_object_wrapper类

src/base/uvm_registry.svh中的源代码

在这里插入图片描述

我们先看看verification-academy中对uvm_object_wrapper的描述:

The uvm_object_wrapper provides an abstract interface for creating object and component proxies. Instances of these lightweight proxies, representing every uvm_object-based and uvm_component-based object available in the test environment, are registered with the uvm_factory. When the factory is called upon to create an object or component, it finds and delegates the request to the appropriate proxy.

uvm_object_wrapper是个virtual类,也是无法直接实例化的,它的主要作用就是作为在工厂中创建的各种uvm_object/uvm_component的句柄, uvm_object_wrapper相当于工厂机制创建对象时的一个抽象的描述,它可以指向任何一个我们通过工厂机制所创建的对象。

uvm_object_registry

src/base/uvm_registry.svh中的源代码

在这里插入图片描述

`m_uvm_object_registry_internal/param宏首先定义了一个uvm_object_registry类类型type_id, create就是uvm_object_registry类中定义的静态方法。

这就是为什么只有通过`uvm_object_utils宏注册了的uvm_object派生类才可以用class_name::type_id::create来创建实例。

191行定义了一个this_type类型作为参数化的uvm_object_registry类型的简写。

233-234行以及253-254行都是获取uvm_factory的唯一实例,目的是调用在uvm_factory中定义的相关方法。

224行定义了一个local和static修饰的this type类型实例me,me可以作为uvm_object_registry以T和Tname为参数的唯一实例,获取方式只有通过get,通过前面的学习我们知道这又是单例模式的一种使用。236行调用uvm_factory中定义的register将me注册,后面会将如何实现注册。

258行调用uvm_factory中的create_object_by_type方法创建实例,并返回一个指向T类型的uvm_object_wrapper句柄,所以需要在259将其cast成T类型,如果cast失败即创建实例失败,则执行260-265行的内容打印相关错误提示信息,直接结束仿真,因为这里调用的是uvm_report_fatal。后面我们会讲create_object_by_type的实现。

uvm_facroty的单例模式实现

uvm_factory是一个virtual类,virtual类是没法被实例化的,所以我们前面讲的创建uvm_factory的实例其实创建的是从其派生而来的uvm_default_factory的唯一实例,所以我们并不是直接调用uvm_factory中的get函数来获取单例,而是借助于uvm_coreservice_t这么个中间类来获取factory实例,严格意义上来讲uvm_coreservice_t 也是个virtual类,其实例也跟uvm_factory/uvm_default_facory一样对应着有一个uvm_default_coreservice_t类。

src/base/uvm_factory.svh中的源代码

在这里插入图片描述

src/base/uvm_coreservice.svh中的源代码

在这里插入图片描述

使用factory机制创建类实例

create_object_by_type

src/base/uvm_factory.svh中的源代码

在这里插入图片描述

这里的1231-1238行是根据输入参数来获取所创建对象的完整hierarchy,即我们使用get_full_name()获取的路径。

1240行清空m_override_info队列,后面的find_override_by_type函数会使用到该队列用于递归查找,所以先要执行清空队列以免影响后续操作。

1242行调用的find_override_by_type就是查看requsted_type这样一个对象对应的数据类型是否有被override过,并返回最终的override后的数据类型。

1244行根据1242行返回的数据类型来创建最终的对象并返回给调用create函数的地方。

所以这里创建对象的核心就是1242行的查找override类型的过程,那这里我们就需要知道如何才能执行override。

override相关的4个函数

src/base/uvm_factory.svh中的源代码

在这里插入图片描述

src/base/uvm_fcomponent.svh中的源代码

在这里插入图片描述

uvm_factory中根据override的是inst还是type以及override是以类型进行override还是以name进行override细分出了4中override函数。

这四个函数在uvm_compoent中又分别被封装成了4个函数,这样在uvm_component的排上类里可以直接使用,本质上都是通过factory的单例模式调用uvm_factory里定义的这4个函数。

set_type_override_by_type

src/base/uvm_factory.svh中的源代码

在这里插入图片描述

我们以set_type_override_by_type为例介绍一下override的其中一种方式,其他3中方式原理类似。

937-945行是判断override的前后数据类型是否为相同类型,相同类型则提示UVM_WARNING

m_types是uvm_factory中定义的联合数组,用来标志创建的数据类型是否有被注册过,没有被注册则返回0,再使用register函数进行注册。

src/base/uvm_factory.svh中的源代码

在这里插入图片描述

src/base/uvm_factory.svh中的源代码

在这里插入图片描述

956-979行遍历m_type_overrides队列查找original_type是否有被override过,如果有被override过并且replace=0,则直接返回不进行override的注册。否则执行替换的操作并将replaced置1表明将原有的override替换掉了。

这里替换的映射关系是要靠一个uvm_factory_override类来维护的,其中包含了类型替换、名称替换、路径所需要的相关信息,前面遍历的m_type_overrides就是维护映射信息的uvm_factory_override类队列。

982-990行表明如果在遍历队列里没有找到匹配对,则把这次override关联的两个数据类型添加到匹配队列里,而如果执行了override的替换操作(上面replaced=1的情况则不需要添加,因为上面已经替换掉了原有匹配对)。

总结

以上内容就是UVM源代码中关于factory机制实现的部分原理解析,其中省略了不少关键代码解析,有问题欢迎评论区讨论。

  • 26
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值