For Good FPGA Design

UVMの環境構築!(5) Collector

UVMの環境構築第5回では、コレクターの定義(作成)方法について解説していきます。

なお、ソースコードはGitHubに公開しています。

目次

シリーズ目次

UVMの環境構築!シリーズの目次は、第1回 解説編の一番下をご覧ください。

コレクターの概要

コレクターはuvm_componentを継承して定義します。uvm_collectorというのはUVMでは定義されていません

UVMでは、モニター

  • DUTのレスポンスをサンプリングし、
  • トランザクションに変換し、
  • 他のコンポーネントに送信する

と定義されています。その他モニターでは、レスポンスのチェックやカバレッジ計算を行うため、非常に盛りだくさんです。

そこで、DUTのレスポンスのサンプリング→トランザクションに変換→他のコンポーネントに送信 を専門に行うコンポーネントとしてコレクターを定義し、モニターから分離するのが一般的となっています。

DUTのレスポンスの取得はvirtual interfaceを使用します。DUTのポートに接続したinterfaceと、コレクターに定義したvirtual interfaceはつながっています(やり方はmy_collector_base.svで説明します)。したがって、DUTのポートの信号が変化すると、コレクターのvirtual interfaceの信号にも反映されます。

図1 UVMにおけるコレクター

コレクターの定義方法

コレクターを定義する際は、DUTによらずお決まりで書くことがあります。したがって、次の手順で記述するとよいです。

  • uvm_componentを継承し、お決まりの部分だけ記述したベースクラスmy_collector_baseを定義
  • my_collector_baseを継承し、DUTに対応させたmy_collectorを定義

my_collector_base

それでは、ソースコードを見ながら、コレクターの定義方法について説明します。

my_collector_base.sv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class my_collector_base #(type TR = uvm_seqeuence_item) extends uvm_component;
 
    VIF_COLLECTOR               vif;
    uvm_analysis_port #(TR)     analysis_port;
 
    /* Constructor */
    function new(string name, uvm_component parent);
        super.new(name, parent);
        analysis_port = new("analysis_port", this);
    endfunction
 
    /* Connect phase */
    function void connect_phase (uvm_phase phase);
        super.connect_phase(phase);
 
        if (!uvm_config_db #(VIF_COLLECTOR)::get(this, get_full_name(), "vif", vif))
            `uvm_error("VIF_NOT_SET", {"No interface assigned to ", get_full_name(), ".vif"});
    endfunction
 
    /* Run phase */
    task run_phase(uvm_phase phase);
        collect_response();
    endtask
 
    /* Sub class must implement this behaviour */
    virtual task collect_response(); endtask
 
endclass
  • 1行目:uvm_componentを継承してmy_collector_baseを定義します。トランザクションのタイプをTRとして変更できるようにします。
  • 3行目:virtual interfaceを定義します。pkg.svの中で、インターフェースのタイプVIF_COLLECTORを次のように定義しています。
1
typedef virtual my_if VIF_COLLECTOR;
  • 4行目:DUTのレスポンスを詰め込んだトランザクションを、他のコンポーネントに送信するためのAnalysis portを定義します。
  • 6~10行目:コンストラクタを定義します。この中でanalysis_portのインスタンスを作成します。
  • 12~18行目:Connect phaseを定義します。uvm_config_dbにより、virtual interfaceの設定をします。
  • 20~23行目:Run phaseを定義します。DUTのレスポンスを収集するcollect_resopnse()を呼びます。collect_response()の中身は、サブクラスで実装する必要があります。

my_collector

my_collector_baseを継承して、DUTに対応したmy_collectorを定義します。

my_collector.sv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class my_collector extends my_collector_base #(my_item);
 
    `uvm_component_utils(my_collector)
 
    /* Constructor */
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
 
    /* Collect response in Run phase */
    task collect_response ();
 
        my_item data;
        data = my_item::type_id::create("response");
 
        forever begin
            @(vif.cb) begin
                if (vif.start == 1'b1) begin
                    data.a_in = vif.a_in;
                    data.b_in = vif.b_in;
                    data.rst  = vif.rst;
                end
 
                if (vif.rst == 1'b0) begin       /* Reset released */
                    if (vif.valid == 1'b1) begin
                        data.mult_out = vif.mult_out;
                        analysis_port.write(data);
                    end
                end
            end
        end
 
    endtask
 
endclass
  • 1行目:my_collector_baseを継承して、my_collectorを定義します。トランザクションのタイプはmy_itemにしました。今回は、シーケンサー、ドライバー間で使っているトランザクションmy_itemにしましたが、テスト環境によっては、同じにする必要はありません。なお、my_itemは、my_item.svで定義しています。
  • 3行目:UVMマクロを書きます。
  • 5~8行目:コンストラクタを定義します。
  • 10~33行目:collect_response()の中身を実装します。クロッキングブロックvif.cbのイベント待ち解除のとき、vif.startが1であれば入力値を取り込み、vif.valid = 1であれば出力値を取り込みます。そして、入力値・出力値をトランザクションとしてanalysis_portから送信します。クロッキングブロックのイベント待ち解除は、DUTのレスポンスが確定した後に起こるので、安全にレスポンスをサンプリングできます。

まとめ

今回は、コレクターの定義方法について解説しました。シリーズを通してご覧いただけると、UVM検証環境が構築できるようになりますので、ぜひ他のコンポーネントの解説もご覧ください。

シリーズ目次はこちら

アバター画像
この記事を書いた人
ジーノ。大手電機メーカーで、基板設計の全般と、FPGAの設計に従事した経験を活かし、FPGAについて情報発信中。
RTL設計、シミュレーション、タイミング・クロージャ、FPGAまわりのハードウェア開発まで、幅広く取り扱っております。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA