Vengineerの妄想(準備期間)

人生は短いけど、長いです。人生を楽しみましょう!

OVM 2.1 : factory(ファクトリ)

Verification Engineerの戯言 : SystemVerilogの世界へようこそ

OVMでのファクトリを用いたインスタンスの生成方法は、ユーザガイド(P.106のAbout the Factory)によると
    type_name::type_id::create(string name, ovm_component parent)
になります。VMM 1.2のファクトリを非常に似ていますが、1つ、大きな違いがあります。
ちなみに、VMM 1.2のファクトリでは、
    type_name::create_instance(vmm_object parent, string name)
になります。引数の順番が逆なだけですが、OVMでは、type_nameと生成関数の間にtype_idが必要です。
なぜ、このtype_idが必要なのかをこの記事では説明します。

OVMでのファクトリは、`ovm_object_utils(T)マクロあるいは`ovm_component_utils(T)マクロを使って登録します。
2つのマクロは、src/macro/ovm_object_defines.svhで定義されています。

ここでは、`ovm_component_utils(T)マクロをみてみます。
`define ovm_component_utils(T) \
   `ovm_component_registry_internal(T,T) \
   `ovm_get_type_name_func(T) \

`define ovm_component_utils_begin(T) \
   `ovm_component_registry_internal(T,T) \
   `ovm_get_type_name_func(T) \
   `ovm_field_utils_begin(T) 

`define ovm_component_utils_end \
     end \
   endfunction

この中で、ovm_component_register_internal(T,T)マクロをみてみると、
`define ovm_component_registry_internal(T,S) \
   class type_id extends ovm_object_wrapper; \
     const static string type_name = `"S`"; \
     virtual function string get_type_name (); \
       return type_name; \
     endfunction \
     `ovm_component_factory_create_func(T) \
     `ovm_factory_override_func \
     `ovm_register_self_func(T) \
   endclass  \
   static function type_id get_type(); \
     return type_id::get(); \
   endfunction \
   virtual function ovm_object_wrapper get_object_type(); \
     return type_id::get(); \
   endfunction 

ここでやっとtype_idが出てきました。
ファクトリのために、クラスの中でtype_idクラスを定義しています。
このtype_idクラスの中のovm_component_factory_create_func(T)マクロをみてみます。
`define ovm_component_factory_create_func(T) \
   function ovm_component create_component (string name, ovm_component parent); \
     T tmp; \
     tmp = new(.name(name), .parent(parent)); \
     return tmp; \
   endfunction \
   \
   static function T create(string name, ovm_component parent, string contxt=""); \
     ovm_factory f; \
     f = ovm_factory::get(); \
     if (contxt == "" && parent != null) \
       contxt = parent.get_full_name(); \
     if(!$cast(create,f.create_component_by_type(get(),contxt,name,parent))) \
        ovm_top.ovm_report_fatal("FACTFL", {"Factory did not return a component of type, ",type_name}, OVM_NONE); \
   endfunction

ここで生成関数(create)を定義しています。戻り値はファクトリに登録したクラス(T)です。

つまり、ファクトリに登録したクラス名の中で定義したtype_idクラスがファクトリクラスになります。

検証、Verification、SystemVerilog、OVM、Open Verification Methodology