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