uvm_config_dbでのUVMシーケンスのコンフィグレーションにおける注意点

UVMでシーケンスのコンフィグレーションしたり、RAL(Register Abstraction Level) Modelを取ってきたい場合がある。その場合、シーケンスのコンフィグレーションをConfig DBから取ってくる。取ってくる方法はuvm_config_dbのget()を使うが、一般的には[Config/ConfiguringSequences](https://verificationacademy.com/cookbook/config/configuringsequences)でも紹介されている様にsequenceの中で以下の様にget_full_name()を使って書くと思う。

```verilog:get_full_name()を使ったsequence内でのコンフィグレーション参照方法
seq_config  m_cfg;

virtual task body();
  if(!uvm_config_db #(seq_config)::get( null , get_full_name(), "seq_config", m_cfg ))
    `uvm_error("SEQ BODY", "seq_config config_db lookup failed!")
endtask
```

しかし、これでは問題が生じてコンフィグレーションを取ってこれない場合がある。UVMテストトップでシーケンサーにnullが指定されてstartされた[バーチャルシーケンスが使われた場合](https://qiita.com/vega77/items/b14815341873da583ea7#b-%E3%83%90%E3%83%BC%E3%83%81%E3%83%A3%E3%83%AB%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B9%E3%82%92%E4%BD%BF%E7%94%A8)である。ここで使用されているシーケンスのメンバ関数get_full_name()を見てみると、UVMコンポーネント向けの定義に代えてUVMシーケンス向けにuvm_sequecer_item内で以下の様に定義されている。

```verilog:uvm_sequence_itemでのget_full_name()の定義
  function string get_full_name();

    if(m_parent_sequence != null) 
      get_full_name = {m_parent_sequence.get_full_name(), "."};
    else if(m_sequencer!=null)
      get_full_name = {m_sequencer.get_full_name(), "."};

    if(get_name() != "") 
      get_full_name = {get_full_name, get_name()};
    else begin
      get_full_name = {get_full_name, "_item"};
    end

  endfunction
```
要するに親シーケンスがある場合は親シーケンスから、親シーケンスがないトップのシーケンスの場合は設定されたシーケンサーから階層パス名を取ってきてドットを付けて自分の名前を付け加えている。なのでこれだとシーケンサーの指定がない（nullで指定された）バーチャルシーケンスが大元のトップシーケンスだった場合、get_full_name()の出力結果はシーケンサーの階層パス名から始まらず、いきなりトップのバーチャルシーケンスの名前から始まってしまう。なのでその場合、get_full_name()では正しい階層パス名指定が出来ず、上記のuvm_config_db::get()でのコンフィグレーションの参照はエラーになってしまう。
そこで、get_full_name()を使わずにコンフィグレーションを参照する必要がある。その方法として[ResourceAccessForSequences](https://verificationacademy.com/cookbook/resourceaccessforsequences)では以下の様なそのシーケンスのシーケンサーである[m_sequencer](https://qiita.com/vega77/items/4161239195547ef9f95e#m_sequencer)を使用してuvm_config_db::get()にシーケンサーの階層パスを指定する方法も提案されている。

```verilog:m_sequencerを使用したsequenceでのコンフィグレーション参照方法
  if(!uvm_config_db #(seq_config)::get( m_sequencer, "", "seq_config", m_cfg ))
    `uvm_error("SEQ BODY", "seq_config config_db lookup failed!")
```
子シーケンスは自分より上位のトップのシーケンスにバーチャルシーケンスが使われているのかシーケンサー情報を持ったリアルシーケンスが使われているのかを関知しない。なのでシーケンスではget_full_name()を使用してのコンフィグレーションの参照方法を使うべきではない。
但しこの[m_sequencer](https://qiita.com/vega77/items/4161239195547ef9f95e#m_sequencer)を使用した方法でもまだ不十分である。これだとシーケンス毎に違うコンフィグレーションを参照したい場合に対応できないのである。この方法ではuvm_config_db::get()に与えているパスがシーケンサーのパスなのでそのシーケンサー上で動くシーケンスは全て同じになってしまい区別ができないのである。そこでシーケンスを個別に区別する為に、少しだけ変えて以下の様な方法を提案する。

```verilog:m_sequencerとget_sequence_path()を使用したsequenceでのコンフィグレーション参照方法
  if(!uvm_config_db #(seq_config)::get( m_sequencer, get_sequence_path(), "seq_config", m_cfg ))
    `uvm_error("SEQ BODY", "seq_config config_db lookup failed!")
```
[m_sequencer](https://qiita.com/vega77/items/4161239195547ef9f95e#m_sequencer)と共にget_sequence_path()を与えてでシーケンス毎に違うパス名にしている。get_sequence_path()もuvm_sequence_itemで定義されていて、get_full_name()と違い、必ずトップシーケンスからのシーケンス階層パス名をstringで返す関数である。なのでこれでシーケンス毎に違うコンフィグレーションを参照する事ができる。更にもう少し変えて以下の様にする。

```verilog:get_sequencer()とget_sequence_path()を使用したsequenceでのコンフィグレーション参照方法
  if(!uvm_config_db #(seq_config)::get( get_sequecer(), get_sequence_path(), "seq_config", m_cfg ))
    `uvm_error("SEQ BODY", "seq_config config_db lookup failed!")
```
[m_sequencer](https://qiita.com/vega77/items/4161239195547ef9f95e#m_sequencer)の代わりに[get_sequencer()](https://qiita.com/vega77/items/4161239195547ef9f95e#get_sequencer)を使っただけだが、シーケンサーを参照するのに[m_sequencer](https://qiita.com/vega77/items/4161239195547ef9f95e#m_sequencer)は使わず[get_sequencer()](https://qiita.com/vega77/items/4161239195547ef9f95e#get_sequencer)の方を使う事が推奨されているのでこちらの方が良いだろう。

**結論
シーケンスでのコンフィグレーションでConfig DBのget()にはget_full_name()は使わず全て[get_sequencer()](https://qiita.com/vega77/items/4161239195547ef9f95e#get_sequencer)とget_sequence_path()を使用した方法にすること。**

このシーケンスのコンフィグレーションでのget_full_name()の問題とget_sequence_path()による解決はちょっと検索してみた所では言及されている記事を見つける事が出来なかった。割と良く起こりうるだろう問題なので、この記事を見た人は是非この方法を覚えておくとよいだろう。

参考
[Verification Academy](https://verificationacademy.com)/[UVM Forum](https://verificationacademy.com/forums/uvm/all)/[Configuration of sequences started from a virtual sequence]
(https://verificationacademy.com/forums/uvm/configuration-sequences-started-virtual-sequence)