Vengineerの妄想(準備期間)

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

VMM 1.2 : factory(ファクトリ)

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

今年(2010年)、最初の日記は、VMM 2.1のファクトリです。

VMM 1.2では、factory(ファクトリ)が導入されました。OVMでは最初から導入されていましたが、、、

ユーザーマニュアルの2-63のTransactionsでは、トランザクションはファクトリをイネーブルにするとあります。
    You should always make transaction factory enabled.

ファクトリをイネーブルにするとは、クラス定義の中に次のようなマクロを追加することを意味します。
    `vmm_class_factory(transaction_class)
`vmm_class_factoryマクロの引数は、トランザクションのクラス名になります。


`vmm_class_factoryマクロは、sv/std_lib/vmm_factory_macros.svで次のように定義されています。

`define vmm_class_factory(classname) \
 \
  typedef vmm_class_factory_base#(classname) _factory_base; \
 \
  static function Xadd_patternX(vmm_factory_pattern_info#(classname) fact); \
     _factory_base::XpatternXQ.push_front(fact); \
  endfunction \
 \
  static function classname this_type(); \
     bit flg; \
     return _factory_base::Xfactory_typeX(flg); \
  endfunction \
 \
  static function classname create_instance(vmm_object parent, \
                                            string name, \
                                            string fname = `"`", \
                                            int lineno   = 0); \
     return _factory_base::create_instance(parent, name, fname, lineno); \
  endfunction \
 \
  static function void override_with_new(string name,  \
                                     classname factory, \
                                     vmm_log log, \
                                     string fname = "", \
                                     int lineno   = 0); \
     _factory_base::override_with_new(name, factory, log, fname, lineno); \
  endfunction \
 \
  static function void override_with_copy(string name,  \
                                      classname factory, \
                                      vmm_log log, \
                                      string fname = "", \
                                      int lineno   = 0); \
     _factory_base::override_with_copy(name, factory, log, fname, lineno); \
  endfunction \


マクロの中のcreate_instance関数が実際のファクトリ関数になります。
ちょっとわかりにくいので必要な部分だけを切り出すと、次のようになります。
  typedef vmm_class_factory_base#(classname) _factory_base; 

  static function classname create_instance(vmm_object parent, 
                                            string name, 
                                            string fname = `"`", 
                                            int lineno   = 0); 
     return _factory_base::create_instance(parent, name, fname, lineno); 
  endfunction 

create_instance関数は、_factory_baseクラスcreate_instance関数'''を呼び出すだけです。
_factory_baseクラスは、vmm_class_factory_base#(classname)ですので、結果として、
vmm_class_factory_base#(classname)クラスcreate_instance関数を呼び出します。
vmm_class_factory_base#(classname)クラスは、sv/std_lib/vmm_factory.svで定義されています。

create_instance関数の例は、A-7のfactoryクラスにあります。
    ahb_trans tr;
    virtual function void_build_ph();
        tr = ahb_trans::create_instance(this, "Ahb_Tr0", `__FILE__, `__LINE__);
        ...
    endfunction
ahb_transクラスインスタンスahb_trans::create_instance関数で生成しています。

new関数ではなく、ファクトリを使う理由については、おいおいと。

検証、Verification、SystemVerilog、VMM、Verification Methodology Manual