UVM Component Override
一、類型的重寫(Type Override)
There are several ways to override a component using its type.
- uvm_component_registry#(T, Tname)
- 使用uvm_component的set_type_override_by_type函数
- 使用uvm_factory的set_type_override_by_type函数
- 使用uvm_component的set_type_override函数
- 使用uvm_factory的set_type_override_by_name函数
1.1、uvm_component_registry#(T,Tname)::set_type_override(override_type)
第一种方法是使用uvm_component_registry。我认为这是override component类型的最简单方法。第8行指示factory用jelly_bean_liberal_scoreboard override jelly_bean_sb_subscriber。
class jelly_bean_test extends uvm_test;
`uvm_component_utils( jelly_bean_test )
jelly_bean_env jb_env;
function void build_phase( uvm_phase phase );
super.build_phase( phase );
jelly_bean_sb_subscriber::type_id::set_type_override( jelly_bean_liberal_scoreboard::get_type() );
jb_env = jelly_bean_env::type_id::create( .name( "jb_env" ), .parent( this ) );
endfunction: build_phase
// ...
endclass: jelly_bean_test
1.2、uvm_component::set_type_override_by_type(original_type, override_type)
第二种方法是使用uvm_component的set_type_override_by_type函数。尽管语法不同,但它的作用基本上与第一个方法相同。
class jelly_bean_test extends uvm_test;
`uvm_component_utils( jelly_bean_test )
jelly_bean_env jb_env;
function void build_phase( uvm_phase phase );
super.build_phase( phase );
set_type_override_by_type( jelly_bean_sb_subscriber::get_type(), jelly_bean_liberal_scoreboard::get_type() );
jb_env = jelly_bean_env::type_id::create( .name( "jb_env" ), .parent( this ) );
endfunction: build_phase
// ...
endclass: jelly_bean_test
1.3、uvm_factory.set_type_override_by_type(original_type, override_type)
第三种方法是使用uvm_factory的set_type_override_by_type函数。实际上,上面我们看到的两种方法只是第三种方法的便利函数。第7行获取当前factory,第10行调用factory的函数。
class jelly_bean_test extends uvm_test;
`uvm_component_utils( jelly_bean_test )
jelly_bean_env jb_env;
function void build_phase( uvm_phase phase );
uvm_factory factory = uvm_coreservice_t::get().get_factory();
super.build_phase( phase );
factory.set_type_override_by_type( jelly_bean_sb_subscriber::get_type(), jelly_bean_liberal_scoreboard::get_type() );
jb_env = jelly_bean_env::type_id::create( .name( "jb_env" ), .parent( this ) );
endfunction: build_phase
// ...
endclass: jelly_bean_test
1.4、uvm_component::set_type_override(original_type_name, override_type_name)
第四种方法是使用uvm_component的set_type_override函数。与上面的三个方法不同,这个函数有两个字符串。上面的前三个方法以uvm_object_wrapper作为它们的参数。
class jelly_bean_test extends uvm_test;
`uvm_component_utils( jelly_bean_test )
jelly_bean_env jb_env;
function void build_phase( uvm_phase phase );
super.build_phase( phase );
set_type_override( jelly_bean_sb_subscriber::type_name, jelly_bean_liberal_scoreboard::type_name );
jb_env = jelly_bean_env::type_id::create( .name( "jb_env" ), .parent( this ) );
endfunction: build_phase
// ...
endclass: jelly_bean_test
- The
type_name
represents the type name which was created by the`uvm_component_utils
macro. In our case,jelly_bean_sb_subscriber::type_name
is"jelly_bean_sb_subscriber"
,andjelly_bean_liberal_scoreboard::type_name
is"jelly_bean_liberal_scoreboard"
. - The
`uvm_component_utils
macro creates thetype_name
, but`uvm_component_param_utils
macro does not. You need to create your owntype_name
variable andget_type_name
function in the latter case.
1.5、uvm_factory.set_type_override_by_name(original_type_name, override_type_name)
最后一个方法是使用uvm_factory的set_type_override_by_name函数。实际上,上面的第四种方法是这种方法的一个便利函数。
class jelly_bean_test extends uvm_test;
`uvm_component_utils( jelly_bean_test )
jelly_bean_env jb_env;
function void build_phase( uvm_phase phase );
uvm_factory factory = uvm_coreservice_t::get().get_factory();
super.build_phase( phase );
factory.set_type_override_by_name( jelly_bean_sb_subscriber::type_name, jelly_bean_liberal_scoreboard::type_name );
jb_env = jelly_bean_env::type_id::create( .name( "jb_env" ), .parent( this ) );
endfunction: build_phase
// ...
endclass: jelly_bean_test
二、實例的重寫(Instance Override)
您可以重写特定的组件实例,而不是替换相同类型的所有组件。与类型覆盖类似,有五种不同的方法。
- 使用uvm_component_registry
- 使用uvm_component的set_inst_override_by_type函数
- 使用uvm_factory的set_inst_override_by_type函数
- 使用uvm_component的set_inst_override函数
- 使用uvm_factory的set_inst_override_by_name函数
2.1、uvm_component_registry#(T,Tname)::set_inst_override(override_type, inst_path, parent)
第一种方法是使用uvm_component_registry。我认为这是覆盖组件实例的最简单方法。第8行指示工厂用jelly_bean_liberal_scoreboard覆盖jelly_bean_sb_subscriber。我们指定了与jelly_bean_test的分层实例路径相关的实例路径(“jb_env.jb_sb”)。
class jelly_bean_test extends uvm_test;
`uvm_component_utils( jelly_bean_test )
jelly_bean_env jb_env;
function void build_phase( uvm_phase phase );
super.build_phase( phase );
jelly_bean_sb_subscriber::type_id::set_inst_override( jelly_bean_liberal_scoreboard::get_type(), "jb_env.jb_sb", this );
jb_env = jelly_bean_env::type_id::create( .name( "jb_env" ), .parent( this ) );
endfunction: build_phase
// ...
endclass: jelly_bean_test
2.2、uvm_component::set_inst_override_by_type(relative_inst_path, original_type, override_type)
第二种方法是使用uvm_component的set_inst_override_by_type函数。尽管语法不同,但它的作用基本上与第一个方法相同。
class jelly_bean_test extends uvm_test;
`uvm_component_utils( jelly_bean_test )
jelly_bean_env jb_env;
function void build_phase( uvm_phase phase );
super.build_phase( phase );
set_inst_override_by_type( "jb_env.jb_sb", jelly_bean_sb_subscriber::get_type(), jelly_bean_liberal_scoreboard::get_type() );
jb_env = jelly_bean_env::type_id::create( .name( "jb_env" ), .parent( this ) );
endfunction: build_phase
// ...
endclass: jelly_bean_test
2.3、uvm_factory.set_inst_override_by_type(original_type, override_type, full_inst_path)
第三种方法是使用uvm_factory的set_inst_override_by_type函数。实际上,上面我们看到的两种方法只是第三种方法的便利函数。第7行获取当前factory,第10行调用factory的函数。注意,该函数将完整的分层实例路径作为第三个参数。我们通过连接这两条路径创建了完整的路径。
class jelly_bean_test extends uvm_test;
`uvm_component_utils( jelly_bean_test )
jelly_bean_env jb_env;
function void build_phase( uvm_phase phase );
uvm_factory factory = uvm_coreservice_t::get().get_factory();
super.build_phase( phase );
factory.set_inst_override_by_type( jelly_bean_sb_subscriber::get_type(), jelly_bean_liberal_scoreboard::get_type(), { get_full_name(), ".jb_env.jb_sb" } );
jb_env = jelly_bean_env::type_id::create( .name( "jb_env" ), .parent( this ) );
endfunction: build_phase
// ...
endclass: jelly_bean_test
2.4、uvm_component::set_inst_override(relative_inst_path, original_type_name, override_type_name)
第四种方法是使用uvm_component的set_inst_override函数。与上面的三个方法不同,这个函数有三个字符串。
class jelly_bean_test extends uvm_test;
`uvm_component_utils( jelly_bean_test )
jelly_bean_env jb_env;
function void build_phase( uvm_phase phase );
super.build_phase( phase );
set_inst_override( "jb_env.jb_sb", jelly_bean_sb_subscriber::type_name, jelly_bean_liberal_scoreboard::type_name );
jb_env = jelly_bean_env::type_id::create( .name( "jb_env" ), .parent( this ) );
endfunction: build_phase
// ...
endclass: jelly_bean_test
- type_name表示由' uvm_component_utils宏创建的类型名。在我们的例子中,jelly_bean_sb_subscriber::type_name是“jelly_bean_sb_subscriber”,jelly_bean_liberal_scoreboard::type_name是“jelly_bean_liberal_scoreboard”。
- `uvm_component_utils宏创建type_name,但是' uvm_component_param_utils宏不创建type_name。在后一种情况下,需要创建自己的type_name变量和get_type_name函数。
2.5、uvm_factory.set_inst_override_by_name(original_type_name, override_type_name, full_inst_path)
最后一个方法是使用uvm_factory的set_inst_override_by_name函数。实际上,上面的第四种方法是这种方法的一个便利函数。与上面的第三个方法类似,我们通过连接两个路径创建了完整的路径。
class jelly_bean_test extends uvm_test;
`uvm_component_utils( jelly_bean_test )
jelly_bean_env jb_env;
function void build_phase( uvm_phase phase );
uvm_factory factory = uvm_coreservice_t::get().get_factory();
super.build_phase( phase );
factory.set_inst_override_by_name( jelly_bean_sb_subscriber::type_name, jelly_bean_liberal_scoreboard::type_name, { get_full_name(), ".jb_env.jb_sb" } );
jb_env = jelly_bean_env::type_id::create( .name( "jb_env" ), .parent( this ) );
endfunction: build_phase
// ...
endclass: jelly_bean_test
三、結論
- 我介绍了Override Type的五种不同方法,以及Override Instance的另外五种方法。就我个人而言,我使用第一种方法是因为它们是最简单的。我希望本文能够澄清每种方法的不同之处。