深入UVM:X::type_id::create是如何创建实例的
X::type_id::create是如何创建实例的
当利用factory机制创建实例的时候,往往使用X::type_id::create(name, parent)来创建实例,比如
function void MyEnv::build_phase(uvm_phase phase); super.build_phase(phase); x = X::type_id::create("x", this); // factory机制创建实例 endfunction : build_phase
当然X::type_id::create本质依然是调用new()去创建实例,但是问题在于其UVM内部是如何一步步实现调用new()成功创建实例的。
X::type_id从何而来
要实现通过X::type_id::create创建实例,首先需要对需要创建的class X进行factory注册,即使用宏uvm_component_utils(X)(或者uvm_object_utils(X)),从宏uvm_component_utils以及uvm_object_uitls是帮我们添加了哪些代码以及一个类型定义(type_id)。所以我们可以使用X::type_id来定位到type_id这个类。深入一下源码,可以看到
typedef uvm_component_register #(T,
"S") type_id;
所以type_id本质就是在X中定义的uvm_component_register #(X, "X")这个类,所以调用X::type_id::create("x", this)就是调用了uvm_component_register #(X, "X")中的create方法。
create方法如何创建实例
在类uvm_component_register #(X, "X")的create方法中有如下代码段
static function T create(string name, uvm_component parent, string contxt = ""); // 这里的T就是我们需要创建的X的类型 ... uvm_object obj; ... obj = factory.create_component_by_type(get(), contxt, name, parent); ... if (!$cast(create, obj)) begin ... end endfunction
可以看出create()方法本质是调用了factory变量的create_component_by_type方法实现的创建实例,create_component_by_type()方法需要的其他三个参数先不关注,重点在于第一个参数,通过get()方法获得。
get()方法也是类uvm_component_register #(X, "X")中的方法,它基于单例模式创建一个类uvm_component_register #(X, "X")的实例me并返回。这里存在一个问题在于:明明我需要创建的对象类型为X,怎么传入create_component_by_type()第一个类型参数的却是type_id类型的实例?于是我们需要继续挖掘create_component_by_type()的函数实现。
create_component_by_type()的创建实例
在class uvm_default_factory中对create_component_by_type()进行了实现
function uvm_component uvm_default_factory::create_component_by_type (uvm_object_wrapper requested_type, string parent_inst_path = "", string name, uvm_component parent); ... return requested_type.create_component(name, parent); endfunction
这里的requested_type就是我们传入的type_id的实例me,原来create_component_by_type()还是调用type_id中的方法create_component()来创建的X的实例,那么create_component()方法是怎么实现的,看看源码
virtual function uvm_component create_component (string name, uvm_component parent); T obj; obj = new(name, parent); return obj; endfunction
就回到了我们熟悉的使用new()函数来创建实例,至此X::type::create(name, parent)创建实例的过程就剖析明白了,当然X::type::create(name, parent)方法不仅仅做了创建实例的工作,其中还包含了在factory中注册等工作,其实现代码没有在本文中细究,有兴趣的可以自己深入源码中探索一番。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架