Some people told me that sour-chocolate actually tastes good and there are many recipes for sour cream chocolate cake. I understand that people have different tastes, so decided to replace our scoreboard with more liberal one. This article shows how to override a component.
New Scoreboard
This is our new scoreboard that respects any tastes. For those of you who want to see the original scoreboard, please see this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class jelly_bean_liberal_scoreboard extends jelly_bean_sb_subscriber; `uvm_component_utils( jelly_bean_liberal_scoreboard ) function new( string name, uvm_component parent ); super.new( name, parent ); endfunction: new virtual function void write( jelly_bean_transaction t ); if ( t.taste == YUMMY ) begin `uvm_info( "write", { "I know you like this.", t.convert2string() }, UVM_LOW ) end else begin `uvm_info( "write", { "I know you don't like this.", t.convert2string() }, UVM_LOW ) end endfunction: write endclass: jelly_bean_liberal_scoreboard |
Now, let’s replace our old scoreboard with this.
Type Override
There are several ways to override a component using its type.
uvm_component_registry#(T,Tname)::set_type_override(override_type)
The first method is using the uvm_component_registry
. I think this is the easiest way to override a component type. The line 8 instructs that the factory to override the jelly_bean_sb_subscriber
with the jelly_bean_liberal_scoreboard
.
1 2 3 4 5 6 7 8 9 10 11 12 | 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 |
uvm_component::set_type_override_by_type(original_type, override_type)
The second method is using the set_type_override_by_type
function of the uvm_component
. Although the syntax is different, what it does is basically the same as the first method.
1 2 3 4 5 6 7 8 9 10 11 12 | 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 |
uvm_factory.set_type_override_by_type(original_type, override_type)
The third method is using the set_type_override_by_type
function of the uvm_factory
. Actually the above two methods we have seen are merely convenience functions for this third method. The line 7 gets the current factory, and the line 10 calls the function of the factory.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 |
uvm_component::set_type_override(original_type_name, override_type_name)
The fourth method is using the set_type_override
function of the uvm_component
. Unlike the above three methods, this function takes two strings.
The first three methods above take
uvm_object_wrapper
as their argument(s).
1 2 3 4 5 6 7 8 9 10 11 12 | 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"
, and jelly_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.
uvm_factory.set_type_override_by_name(original_type_name, override_type_name)
The last method is using the set_type_override_by_name
function of the uvm_factory
. Actually the fourth method above is a convenience function of this method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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
You can override a specific component instance, instead of replacing all the components of the same type. Similar to the type override, there are five different methods.
uvm_component_registry#(T,Tname)::set_inst_override(override_type, inst_path, parent)
The first method is using the uvm_component_registry
. I think this is the easiest way to override a component instance. The line 8 instructs that the factory to override the jelly_bean_sb_subscriber
with the jelly_bean_liberal_scoreboard
. We specified the instance path ("jb_env.jb_sb"
) relative to the jelly_bean_test
‘s hierarchical instance path.
1 2 3 4 5 6 7 8 9 10 11 12 | 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 |
uvm_component::set_inst_override_by_type(relative_inst_path, original_type, override_type)
The second method is using the set_inst_override_by_type
function of the uvm_component
. Although the syntax is different, what it does is basically the same as the first method.
1 2 3 4 5 6 7 8 9 10 11 12 | 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 |
uvm_factory.set_inst_override_by_type(original_type, override_type, full_inst_path)
The third method is using the set_inst_override_by_type
function of the uvm_factory
. Actually the above two methods we have seen are merely convenience functions for this third method. The line 7 gets the current factory, and the line 10 calls the function of the factory. Note that the function takes the full hierarchical instance path as the third argument. We created the full path by concatenating the two paths.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 |
uvm_component::set_inst_override(relative_inst_path, original_type_name, override_type_name)
The fourth method is using the set_inst_override
function of the uvm_component
. Unlike the above three methods, this function takes three strings.
The first three methods above take
uvm_object_wrapper
as their type argument(s).
1 2 3 4 5 6 7 8 9 10 11 12 | 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 |
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"
, and jelly_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.
uvm_factory.set_inst_override_by_name(original_type_name, override_type_name, full_inst_path)
The last method is using the set_inst_override_by_name
function of the uvm_factory
. Actually the fourth method above is a convenience function of this method. Similar to the third method above, we created the full path by concatenating the two paths.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 |
I covered five different methods to override a type, and another five methods to override an instance. Personally, I use the first methods because they are the simplest. I hope this article clarified the difference of each method.
As always you can view and run the code on EDA Playground.
Hi Keisuke,
Thank you very much for your post, it is always helpful.
I show may code only use the code as follows, which type should it be? I think it is different from your code, is “jelly_bean_sb_subscriber::type_id::” must have? for my understanding, it is necessary for component override. Please correct me.
set_type_override_by_type(bird::get_type(), parrot::get_type())
2. What is the difference between uvm_factory. * and uvm_component.* .
jelly_bean_sb_subscriber::type_id::set_type_override
vs.
factory.set_type_override_by_name
3. in the initial begin, we could also use factory.set_type_override_by_type()…
Do we need to have uvm_factory factory = uvm_coreservice_t::get().get_factory(); somewhere in the top?
Best,
set_type_override_by_type
from within a subclass ofuvm_component
, you don’t need to qualify it withuvm_component::
.jelly_bean_sb_subscriber::type_id::set_type_override
callsuvm_factory.set_type_override_by_type
.uvm_factory.svh
instantiates the singleton factory calledfactory
, so you can use it without getting the factory by yourself. However, if you use UVM 1.2, you need to get the factory by yourself.Hi,
The article is very informative. Could you kindly explain the difference between set_inst_override_by_type and set_inst_override_by_name?
Thanks,
Kumar
set_inst_override_by_type
takes twouvm_object_wrapper
s as its first two arguments, whereasset_inst_override_by_name
takes twostring
s.