• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

深入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中注册等工作,其实现代码没有在本文中细究,有兴趣的可以自己深入源码中探索一番。

posted on 2022-09-16 23:40  SOC验证工程师  阅读(2997)  评论(1)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3