uvm_config_db, uvm_resource_db

すみません、嘘を書いていました(↓)ので修正しました。修正ポイントは、uvm_config_dbなどを利用する際に、`uvm_field_intなどで登録しなければならない、というところ。

OVM、UVMに慣れていない人には、きっと難しい内容だと思います。でも理解する価値は十分あります。

uvm_config_db

  • 各種UVMのclass(sequence, sequence_itemはダメ)に用意しておいたメンバに値をセットしたり読みだしたりするのに使います。
  • 例えば、5つの動作モードのあるIFのモデルがあって、このテストではモード1を使いたいんだ、とかのとき、uvm_config_dbを使ってモードをセットしてテストします。
  • OVMまでは、set_config_xxxというメソッドでしたが、UVM1.1から?uvm_config_dbに統一されたらしいです(ググった結果ですが)。
  • 注意点として、uvm_config_db(旧set_config_xxx)でアクセスできる対象は、UVMクラスを継承したクラスであって、かつ
    • `uvm_component_utils_begin(class_name)
    • `uvm_field_int(master_id, UVM_DEFAULT)
    • `uvm_component_utils_end(ubus_master_driver.svから引用)
    • のように、メンバを登録する必要があります。
  • 利用イメージとしては、値を書き込む空間が用意されており、そこへ「名前」を登録して「値」を書き込む(set)。そしてその値を読み込む(get)。そういう使い方をイメージしていれば、間違いないと思います。
  • uvm_field_int、のところは、対象メンバに合わせて変える必要があります。uvm-1.1.dではこんな感じ。_aa_ はassociative arrayです。
    • uvm_field_int
    • uvm_field_real
    • uvm_field_enum
    • uvm_field_object
    • uvm_field_event
    • uvm_field_string
    • uvm_field_array_enum
    • uvm_field_array_int
    • uvm_field_sarray_int
    • uvm_field_sarray_enum
    • uvm_field_array_object
    • uvm_field_sarray_object
    • uvm_field_array_string
    • uvm_field_sarray_string
    • uvm_field_queue_enum
    • uvm_field_queue_int
    • uvm_field_queue_object
    • uvm_field_queue_string
    • uvm_field_aa_int_string
    • uvm_field_aa_string_string
    • uvm_field_aa_object_string
    • uvm_field_aa_int_int
    • uvm_field_aa_int_int_unsigned
    • uvm_field_aa_int_integer
    • uvm_field_aa_int_integer_unsigned
    • uvm_field_aa_int_byte
    • uvm_field_aa_int_byte_unsigned
    • uvm_field_aa_int_shortint
    • uvm_field_aa_int_shortint_unsigned
    • uvm_field_aa_int_longint
    • uvm_field_aa_int_longint_unsigned
    • uvm_field_aa_int_key
    • uvm_field_aa_string_int
    • uvm_field_aa_object_int
    • uvm_field_aa_int_enumkey
  • メソッド(追記:2018/02/11, 動作は未チェック)
    • get(uvm_component context, string inst_name, string field_name, inout T value);
      • Get the value for field_name in inst_name, using component context as the starting search point.
      • inst_name is an explicit instance name relative to context and may be an empty string if the context is the instance that the configuration object applies to.
      • field_name is the specific field in the scope that is being searched for.
    • set(uvm_component context, string inst_name, string field_name, T value);
    • exists(uvm_component context, string inst_name, string field_name, bit spell_check)
    • wait_modified(uvm_component context, string inst_name, string field_name)

uvm_resource_db

  • 各種設定値をセットしておき、それを他のclassから読みだして使います。
  • 使い道としては、例えばテストモードを設定しておき、セレクタを切り替えたりするのに使います。
  • 「ふつうにテストベンチトップに値を置いておけばいいじゃん」という話もありますが、それは「特定のテストベンチ」に依存します。テストベンチが変われば、その値へのアクセスパスが変わるのが普 通です。
  • 例えば3つのテストベンチ、tb_top1, tb_top2, tb_top3があったとします。これらmoduleにvectorを宣言しておき、その値をモデルが参照するとしましょう。するとモデルは、参照するときに 「tb_top1/vector」、「tb_top2/vector」、「tb_top3/vector」とします。名前が変わってしまうので、これを賢くやり過ごすには、例えばトップ名をdefineする方法があります。`define _TOP tb_top1 な ど。
  • このように、普通にmoduleの中に値を置いておいてアクセスする場合、「階層名」に依存してしまうことに注意が必要です。
  • uvm_resource_dbを使うと、scopeを意識すればとても楽ちんです。
    • 例:SATA関係ならば、scope=sata
    • 例:USB関係ならば、scope=usb
  • こんなふうに使えばいいわけです。
  • 簡単な使い方
    • 値のセット
      • uvm_resource_db#(type)::set(string scope, string name, value (depend on type));
      • 例:uvm_resource_db#(int)::set("sata0", "version", 1);
      • typeのところは、それこそint、string、classなど一通り使えるはず。arrayは知りません。
    • 値の読出し
      • int value;
      • bit result;
      • result = uvm_resource_db#(int)::read_by_name("sata0", "version", value);
      • // 返値が0のときは、指定したscope, name, 型で不一致で読み込めないとき
  • 難しい使い方
    • 調査中
  • 元の定義:class uvm_resource_db #(type T=uvm_object);
  • メソッド
    • get_by_type(string scope)
    • get_by_name(string scope, string name, bit rpterr=1)
    • 3つ目の引数がよくわかりません... report error??
    • set_default(string scope, string name)
    • set(input string scope, input string name, T val, input uvm_object accessor = null)
    • read_by_name(input string scope, input string name, inout T val, input uvm_object accessor = null)
      • 値は第3引数(val)で受け取る。
      • メソッドの返値は、読み込み成功(1)、失敗(0)
    • read_by_type(省略)
    • write_by_name(input string scope, input string name, T val, input uvm_object accessor = null)
    • write_by_type(略)
    • dump()