0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UVMでのFactory Overrideの優先順位

0
Last updated at Posted at 2026-04-15

UVMにはFactory Overrideの機構が組み込まれていて、Factoryに対し指示する事によって、上位の階層クラスから下位クラスのインスタンス化を変更する事ができる。
Factory Overrideで同じ対象に対して複数のインスタンス置換指示をした場合、やり方によってどの指示が優先され、実際のインスタンス化が行われるかが違くなる。なので意図しない置換が実行されてしまい混乱するので注意が必要。

通常のType Overrideでの優先順位

良く使われる通常Type Overrideでは、後に指示をされたものが優先され実行される。通常、プログラミング言語では上から下に順に実行され、後に設定された物がそこから有効になるのでこれは分かり易いであろう。
以下の例の様に同じmy_envに対してmy_env_1と_2へのoverride指示をすると、my_env_1への置換指示は行われず、後に指示したmy_env_2への置換が実行される。

Type Overrideの例(後書き優先)
my_env::type_id::set_type_override(my_env_1::get_type()); // Replace my_env with my_env_1
my_env::type_id::set_type_override(my_env_2::get_type()); // Replace my_env with my_env_2 <-- Prioritized!!!  

こんな事普通はやらないだろうとか思うかもしれないが、ここでは分かり易く説明する為にわざわざ同じ個所にFactory Overrideの指示を書いている。実用上は継承したクラスのfunction内でsuper.の後にFactory Overrideの指示を書いて、親クラスでの指示を上書きして別のFactory Overrideをしたりする事は日常的に良く使う。

Extended Class
virtual function void set_factory_override();
    super.set_factory_override();
    my_env::type_id::set_type_override(my_env_2::get_type());
endfunction

Type Overrideで先に設定された物を優先させる

set_type_overrid()の引数を見てみると以下の様になっている。

set_type_override()
static function void set_type_override (
   	uvm_object_wrapper 	override_type,	  	
   	bit 	replace	 = 	1
)

replaceと言う引数を与える事ができ、replace = 0を設定すると、これ以前にFactory Overridenの指示が有った場合には、そちらを優先し、当該のFactory Overrideは実行されない。

Type Overrideで先書き優先の設定
my_env::type_id::set_type_override(my_env_1::get_type()   ); // Replace my_env with my_env_1 <-- Prioritized!!! 
my_env::type_id::set_type_override(my_env_2::get_type(), 0); // Replace my_env with my_env_2 <-- Yield.

Instance Overrideの優先順位

指定したTypeの全てのInstanceを対象にFactory Overrideを行うType Overrideの他に、個別のInstanceに対してのみFactory Overrideを行うInstance Overrideがある。
Instance Overrideの場合には優先順位が逆となり、先に指示されたものが優先されされる。良く使うType Overrideとは優先順位が違うので、この事を知らないと意図した通りにFactory Overrideがされなくて混乱するので注意が必要。
又、Instance Overrideの後にType OverrideがあってもInstance Overrideの方が優先される。

my_env::type_id::set_inst_override(my_env_2::get_type(), "env", this); // Override to create my_env_2 <-- Prioritized!!!  
my_env::type_id::set_inst_override(my_env_1::get_type(), "env", this); // Override to create my_env_1 <-- Yield.
my_env::type_id::set_type_override(my_env_1::get_type(), 1          ); // Override to create my_env_1 <-- Yield.

なので、優先順位として

  1. Instance Override
  2. Type Override (replace = 1)
  3. Type Override (replace = 0)

の優先順位となる。

継承クラスでInstance Overrideを親クラスから変えたい場合にはsuper.の後ではなく、super.の前に書く必要がある。

Extended Class
virtual function void set_factory_override();
    my_env::type_id::set_inst_override(my_env_x::get_type(), "env", this);
    super.set_factory_override();
endfunction

サンプルテストベンチ

tb.sv
`include "uvm_macros.svh"
module tb;
    import uvm_pkg::*;

    class my_env extends uvm_env;

        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction

        `uvm_component_utils(my_env)

        virtual function void build_phase(uvm_phase phase);
            `uvm_info(get_type_name(), "Building my_env", UVM_MEDIUM)
        endfunction

    endclass

    class my_env_1 extends my_env;

        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction

        `uvm_component_utils(my_env_1)

        virtual function void build_phase(uvm_phase phase);
            `uvm_info(get_type_name(), "Building my_env_1", UVM_MEDIUM)
        endfunction

    endclass

    class my_env_2 extends my_env;

        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction

        `uvm_component_utils(my_env_2)

        virtual function void build_phase(uvm_phase phase);
            `uvm_info(get_type_name(), "Building my_env_2", UVM_MEDIUM)
        endfunction

    endclass

    class my_test extends uvm_test;

        my_env env;

        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction

        `uvm_component_utils(my_test)

        virtual function void build_phase(uvm_phase phase);
            env = my_env::type_id::create("env", this);
        endfunction

        virtual function void end_of_elaboration_phase(uvm_phase phase);
            super.end_of_elaboration_phase(phase);
            uvm_factory::get().print(0);
        endfunction
        

    endclass

    class my_test_1 extends my_test;

        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction

        `uvm_component_utils(my_test_1)

        virtual function void build_phase(uvm_phase phase);
            my_env::type_id::set_type_override(my_env_1::get_type()); // Override to create my_env_1
            my_env::type_id::set_type_override(my_env_2::get_type()); // Override to create my_env_2 <-- Prioritized!!!  
            super.build_phase(phase);
        endfunction

    endclass

    class my_test_2 extends my_test;

        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction

        `uvm_component_utils(my_test_2)

        virtual function void build_phase(uvm_phase phase);
            my_env::type_id::set_type_override(my_env_1::get_type(), 1); // Override to create my_env_1 <-- Prioritized!!!  
            my_env::type_id::set_type_override(my_env_2::get_type(), 0); // Override to create my_env_2
            super.build_phase(phase);
        endfunction

    endclass

    class my_test_3 extends my_test;

        function new(string name, uvm_component parent);
            super.new(name, parent);
        endfunction

        `uvm_component_utils(my_test_3)

        virtual function void build_phase(uvm_phase phase);
            my_env::type_id::set_inst_override(my_env_2::get_type(), "env", this); // Override to create my_env_2 <-- Prioritized!!!  
            my_env::type_id::set_inst_override(my_env_1::get_type(), "env", this); // Override to create my_env_1
            my_env::type_id::set_type_override(my_env_1::get_type(), 1          ); // Override to create my_env_1
            super.build_phase(phase);
        endfunction

    endclass

    initial run_test("my_test");

endmodule

結果

log (my_test_1)
UVM_INFO @ 0: reporter [RNTST] Running test my_test_1...
UVM_INFO @ 0: reporter [TPREGR] Original object type 'my_env' already registered to produce 'my_env_1'.  Replacing with override to produce type 'my_env_2'.
UVM_INFO tb.sv(42) @ 0: uvm_test_top.env [my_env_2] Building my_env_2
UVM_INFO uvm/2020.3.1/src/base/uvm_factory.svh(2050) @ 0: reporter [UVM/FACTORY/PRINT] 
#### Factory Configuration (*)

No instance overrides are registered with this factory

Type Overrides:

  Requested Type  Override Type
  --------------  -------------
  my_env          my_env_2
(*) Types with no associated type name will be printed as <unknown>

####
log (my_test_2)
UVM_INFO @ 0: reporter [RNTST] Running test my_test_2...
UVM_INFO @ 0: reporter [TPREGD] Original object type 'my_env' already registered to produce 'my_env_1'.  Set 'replace' argument to replace the existing entry.
UVM_INFO tb.sv(28) @ 0: uvm_test_top.env [my_env_1] Building my_env_1
UVM_INFO uvm/2020.3.1/src/base/uvm_factory.svh(2050) @ 0: reporter [UVM/FACTORY/PRINT] 
#### Factory Configuration (*)

No instance overrides are registered with this factory

Type Overrides:

  Requested Type  Override Type
  --------------  -------------
  my_env          my_env_1
(*) Types with no associated type name will be printed as <unknown>

####
log (my_test_3)
UVM_INFO @ 0: reporter [RNTST] Running test my_test_3...
UVM_INFO tb.sv(42) @ 0: uvm_test_top.env [my_env_2] Building my_env_2
UVM_INFO uvm/2020.3.1/src/base/uvm_factory.svh(2050) @ 0: reporter [UVM/FACTORY/PRINT] 
#### Factory Configuration (*)

Instance Overrides:

  Requested Type  Override Path     Override Type
  --------------  ----------------  -------------
  my_env          uvm_test_top.env  my_env_2
  my_env          uvm_test_top.env  my_env_1

Type Overrides:

  Requested Type  Override Type   
  --------------  ----------------
  my_env          my_env_1
(*) Types with no associated type name will be printed as <unknown>

####

参考記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?