For Good FPGA Design

UVMの環境構築!(7) Agent

UVMの環境構築第7回では、エージェントの定義(作成)方法について解説していきます。

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

目次

シリーズ目次

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

エージェントの概要

エージェントはuvm_agentまたはそのサブクラスを継承して定義します。

通常、ドライバー、シーケンサー、コレクター、モニターはセットで使われます。エージェントは、これらをひとまとめにするためのコンポーネントです。したがって、DUTとやり取りをするひとかたまりのコンポーネントとなります(図1)。

1つのエンバイロンメントの中に、複数のエージェントを持つことも可能です。

図1 UVMにおけるエージェント

エージェントの定義方法

エージェントでは、ドライバー、シーケンサー、コレクター、モニターのインスタンスを作成し、これらの接続を行います。

エージェントにはアクティブモードパッシブモードがあります。

  • アクティブモード:スティミュラスを生成し、DUTのドライブする。その上で、DUTのインターフェース信号の監視を行う
  • パッシブモード:DUTのインターフェース信号の監視のみを行う

uvm_agentには、この切り替えを行うためのフィールドis_activeが定義されています。ユーザーはis_activeを使って、アクティブモードとパッシブモードを実装します。

1
2
3
4
5
virtual class uvm_agent extends uvm_component;
  uvm_active_passive_enum is_active = UVM_ACTIVE;
  ...
  ...
endclass

ほとんどの場合は、下記のmy_agent.svに示すような記述になります。

エージェントはコピペでOK。

my_agent

それでは、ソースコードを見ながら、エージェントの定義方法について説明します。

my_agent.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
36
37
38
39
40
41
class my_agent extends uvm_agent;
 
    my_driver driver;
    my_sequencer sequencer;
    my_collector collector;
    my_monitor monitor;
 
    `uvm_component_utils_begin(my_agent)
        `uvm_field_enum(uvm_active_passive_enum, is_active, UVM_DEFAULT)    /* Defined in uvm_agent */
    `uvm_component_utils_end
 
    /* Constructor */
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction
 
    /* Build phase */
    function void build_phase(uvm_phase phase);
        super.build_phase(phase);
 
        collector = my_collector::type_id::create("collector", this);
        monitor = my_monitor::type_id::create("monitor", this);
 
        if (is_active == UVM_ACTIVE) begin
            driver = my_driver::type_id::create("driver", this);
            sequencer = my_sequencer::type_id::create("sequencer", this);
        end
    endfunction
 
    /* Connect phase */
    function void connect_phase(uvm_phase phase);
        super.connect_phase(phase);
 
        collector.analysis_port.connect(monitor.analysis_export);
 
        if (is_active == UVM_ACTIVE) begin
            driver.seq_item_port.connect(sequencer.seq_item_export);
        end
    endfunction
 
endclass
  • 1行目:uvm_agentを継承して、my_agentを定義します。
  • 3~6行目:ドライバー、シーケンサー、コレクター、モニターを定義します。
  • 8~10行目:UVMマクロとフィールドマクロを書きます。is_activeはuvm_agentに定義されていますが、フィールドマクロは指定されていません。したがって、ユーザーはis_activeのフィールドマクロを指定する必要があります。
  • 12~15行目:コンストラクタを定義します。
  • 17~28行目:Build phaseを定義します。DUTの監視はアクティブモードの場合でもパッシブモードの場合でも行うため、まずはコレクターとモニターのインスタンスを作成します。次に、is_activeの値に応じて、アクティブモードの場合はドライバーとシーケンサーのインスタンスを作成します。
  • 30~39行目:Connect phaseを定義します。まずは、コレクターのanalysis_portと、モニターのanalysis_exportを接続します。次に、アクティブモードの場合はドライバーのseq_item_portと、シーケンサーのseq_item_exportを接続します。

まとめ

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

シリーズ目次はこちら

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

コメントを残す

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

CAPTCHA