上节我们说到uvm_object_registry #(T),uvm_object_reistry 又继承自uvm_object_wrapper,所以首先,让我们先看看它爹是啥样子的:

//------------------------------------------------------------------------------
//
// CLASS: 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.
//
//------------------------------------------------------------------------------ virtual class uvm_object_wrapper; // Function: create_object
//
// Creates a new object with the optional ~name~.
// An object proxy (e.g., <uvm_object_registry #(T,Tname)>) implements this
// method to create an object of a specific type, T. virtual function uvm_object create_object (string name="");
return null;
endfunction // Function: create_component
//
// Creates a new component, passing to its constructor the given ~name~ and
// ~parent~. A component proxy (e.g. <uvm_component_registry #(T,Tname)>)
// implements this method to create a component of a specific type, T. virtual function uvm_component create_component (string name,
uvm_component parent);
return null;
endfunction // Function: get_type_name
//
// Derived classes implement this method to return the type name of the object
// created by <create_component> or <create_object>. The factory uses this
// name when matching against the requested type in name-based lookups. pure virtual function string get_type_name(); endclass

从代码注释来看,都是虚类,这只是轻量级的代理proxy, 它只负责搭台,具体实现让子类去实现,也就是所在uvm中create class,无非就两种uvm_object 和uvm_componet. 它只有这两个儿子,古人云:儿孙自有儿孙福,莫为儿孙做远忧。所以,具体的实现还是让我们进一步去看uvm_object_registry(uvm_register.svh中).

首先来看用法:

// Group: Usage
//
// This section describes usage for the uvm_*_registry classes.
//
// The wrapper classes are used to register lightweight proxies of objects and
// components.
//
// To register a particular component type, you need only typedef a
// specialization of its proxy class, which is typically done inside the class.
//
// For example, to register a UVM component of type ~mycomp~
//
//| class mycomp extends uvm_component;
//| typedef uvm_component_registry #(mycomp,"mycomp") type_id;
//| endclass
//
// However, because of differences between simulators, it is necessary to use a
// macro to ensure vendor interoperability with factory registration. To
// register a UVM component of type ~mycomp~ in a vendor-independent way, you
// would write instead:
//
//| class mycomp extends uvm_component;
//| `uvm_component_utils(mycomp);
//| ...
//| endclass
//
// The <`uvm_component_utils> macro is for non-parameterized classes. In this
// example, the typedef underlying the macro specifies the ~Tname~
// parameter as "mycomp", and ~mycomp~'s get_type_name() is defined to return
// the same. With ~Tname~ defined, you can use the factory's name-based methods to
// set overrides and create objects and components of non-parameterized types.
//
// For parameterized types, the type name changes with each specialization, so
// you cannot specify a ~Tname~ inside a parameterized class and get the behavior
// you want; the same type name string would be registered for all
// specializations of the class! (The factory would produce warnings for each
// specialization beyond the first.) To avoid the warnings and simulator
// interoperability issues with parameterized classes, you must register
// parameterized classes with a different macro.
//
// For example, to register a UVM component of type driver #(T), you
// would write:
//
//| class driver #(type T=int) extends uvm_component;
//| `uvm_component_param_utils(driver #(T));
//| ...
//| endclass
//
// The <`uvm_component_param_utils> and <`uvm_object_param_utils> macros are used
// to register parameterized classes with the factory. Unlike the non-param
// versions, these macros do not specify the ~Tname~ parameter in the underlying
// uvm_component_registry typedef, and they do not define the get_type_name
// method for the user class. Consequently, you will not be able to use the
// factory's name-based methods for parameterized classes.
//
// The primary purpose for adding the factory's type-based methods was to
// accommodate registration of parameterized types and eliminate the many sources
// of errors associated with string-based factory usage. Thus, use of name-based
// lookup in <uvm_factory> is no longer recommended.

uvm_object_register的定义如下:

class uvm_object_registry #(type T=uvm_object, string Tname="<unknown>")
extends uvm_object_wrapper;
typedef uvm_object_registry #(T,Tname) this_type; // Function: create_object
//
// Creates an object of type ~T~ and returns it as a handle to a
// <uvm_object>. This is an override of the method in <uvm_object_wrapper>.
// It is called by the factory after determining the type of object to create.
// You should not call this method directly. Call <create> instead. virtual function uvm_object create_object(string name="");
T obj;
`ifdef UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR
obj = new();
if (name!="")
obj.set_name(name);
`else
if (name=="") obj = new();
else obj = new(name);
`endif
return obj;
endfunction const static string type_name = Tname;

type::id::create()

  // Function: create
//
// Returns an instance of the object type, ~T~, represented by this proxy,
// subject to any factory overrides based on the context provided by the
// ~parent~'s full name. The ~contxt~ argument, if supplied, supersedes the
// ~parent~'s context. The new instance will have the given leaf ~name~,
// if provided. static function T create (string name="", uvm_component parent=null,
string contxt="");
uvm_object obj;
uvm_coreservice_t cs = uvm_coreservice_t::get();
uvm_factory factory=cs.get_factory(); if (contxt == "" && parent != null)
contxt = parent.get_full_name();
obj = factory.create_object_by_type(get(),contxt,name);
if (!$cast(create, obj)) begin
string msg;
msg = {"Factory did not return an object of type '",type_name,
"'. A component of type '",obj == null ? "null" : obj.get_type_name(),
"' was returned instead. Name=",name," Parent=",
parent==null?"null":parent.get_type_name()," contxt=",contxt};
uvm_report_fatal("FCTTYP", msg, UVM_NONE);
end
endfunction

create() 调用factory.create_object_by_type()函数,该函数又调用create_object()

// create_object_by_type
// --------------------- function uvm_object uvm_default_factory::create_object_by_type (uvm_object_wrapper requested_type,
string parent_inst_path="",
string name=""); string full_inst_path; if (parent_inst_path == "")
full_inst_path = name;
else if (name != "")
full_inst_path = {parent_inst_path,".",name};
else
full_inst_path = parent_inst_path; m_override_info.delete(); requested_type = find_override_by_type(requested_type, full_inst_path); return requested_type.create_object(name); endfunction

所以tpye::id::create()本质上就是调用该class的new()函数。

uvm_factory——我们的工厂(二)的更多相关文章

  1. uvm_factory——我们的工厂(一)

    factory 机制是实现(功能):通过一个字符串来创建此字符串所代表的的类的一个实例. //----------------------------------------------------- ...

  2. 简单工厂(二)——coding

    public abstract class Video { public abstract void produce(); } public class JavaVideo extends Video ...

  3. uvm_factory——我们的工厂(三)

    现在让我们回过头来想想factory 是用来干什么,它做了什么? fantory就是生产uvm_object 和 uvm_component.用factory 生产和用SV直接new有什么区别了? f ...

  4. c# 设计模式 之:简单工厂、工厂方法、抽象工厂之小结、区别

    很多时候,我发现这三种设计模式难以区分,常常会张冠李戴闹了笑话.很有必要深入总结一下三种设计模式的特点.相同之处和不同之处. 1 本质 三个设计模式名字中都含有“工厂”二字,其含义是使用工厂(一个或一 ...

  5. 面向程序猿的设计模式 ——GoF《设计模式》读书总结(壹)抽象工厂&amp;生成器

    第一部分:创建型模式 创建型模式抽象了实例化过程. 它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.(把一些小的对象组装成大对象,这个工作由专门的类对象来做) 一个类创建型模式使用继承改变被实 ...

  6. Python——工厂模式

    目录 前言 一.简单工厂 二.工厂方法 抽象工厂 结论 参考 前言 工厂模式,顾名思义就是我们可以通过一个指定的"工厂"获得需要的"产品". 在设计模式中主要用 ...

  7. MM 后台配置(转)

    本文转自:https://www.cnblogs.com/yanglikun/p/4124797.html 一.全局配置 1.一般配置 SPRO->SAP NETWEAVER -> GEN ...

  8. MM/PP/SD/FICO 模块常用事物码(T-code)、SAP快捷键

    MM/PP/SD/FICO MM常用T-CODE MM01 创建一般物料 Create Material – GeneralMM02 修改一般物料 Change MaterialMM03 显示一般物料 ...

  9. ABAP权限检查,TCode与权限对象进行关联

    一.确认权限对象,和关联字段: Tcode:SU21 维护权限对象例如"M_MSEG_WMB",它关联字段为'WERKS'M_MSEG_WMB 物料凭证:工厂 二.在ABAP代码中 ...

随机推荐

  1. Redis GEO 特性在 LBS 中的应用总结

    什么是LBS LBS(Location Based Service),基于位置的服务. Redis和GEO Redis 是最热门的 nosql 数据库之一,它的最大特点就是快.所以在 LBS 这种需要 ...

  2. docker容器磁盘

    docker容器磁盘扩容 一.配置文件里更改容器创建时的默认磁盘大小 [root@ip---- ~]# cat /etc/sysconfig/docker-storage DOCKER_STORAGE ...

  3. 【旧文章搬运】KeUserModeCallback用法详解

    原文发表于百度空间及看雪论坛,2010-01-10 看雪论坛地址:https://bbs.pediy.com/thread-104918.htm  代码及附件可到这里下载=============== ...

  4. 【转】cache buffer chain 第一篇

    文章转自:http://www.jydba.net/cache-buffer-chain/ buffer cache的管理有两个重要的数据结构: hash bucket和cache buffer ch ...

  5. 【216】◀▶ IDL 字符串操作说明

    参考:String Processing Routines —— 字符串处理函数 01   STRING 返回字符串. 02   STRCMP 比较字符串,一样返回1,不一样返回0,默认大小写敏感. ...

  6. 算法导论17:摊还分析学习笔记(KMP复杂度证明)

    在摊还分析中,通过求数据结构的一系列的操作的平均时间,来评价操作的代价.这样,即使这些操作中的某个单一操作的代价很高,也可以证明平均代价很低.摊还分析不涉及概率,它可以保证最坏情况下每个操作的平均性能 ...

  7. struts2 中的 addActionError 、addFieldError、addActionMessage的方法

    addActionError .addFieldError.addActionMessage都是ActionSupport的方法 一.addActionError("错误内容"): ...

  8. 原创|高逼格企业级MySQL数据库备份方案,原来是这样....

    很多人,这里说的是运维工程师们,一提到写某某方案,很是头疼.不是上某度一统搜索,就是同样一句话在N个群全部群发一遍:“有没有某某方案,可以共享一下的吗??求助,各位大佬们”,估计十有八九,全部石沉大海 ...

  9. 洛谷 - P1593 - 因子和 - 费马小定理

    类似的因为模数比较小的坑还有卢卡斯定理那道,也是有时候逆元会不存在,因为整除了.使用一些其他方法避免通过逆元. https://www.luogu.org/fe/problem/P1593 有坑.一定 ...

  10. windows 系统 GitBook生成PDF、epub报错Error during ebook generation: 'ebook-convert' 乱码

    解决方法 1. 根据你的系统下载calibre并安装 2. 右键属性打开桌面图标位置 3 .复制该路径: 4. 打开我的电脑-属性-系统-高级系统设置-环境变量,配置环境. 5. 编辑"PA ...