For Good FPGA Design

UVMの環境構築!(2) TransactionとInterface

UVMの環境構築第2回では、トランザクションとインターフェースの定義(作成)方法について解説していきます。

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

目次

シリーズ目次

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

DUTとdefine

DUTについては第1回 解説編の下記の記事で説明したものを使います。

DUTのポートのビット幅は、defineした値を使って、トップモジュールで指定します。このdefineの値はトランザクションとインターフェースの定義でも使用しています。

my_definitions.sv

1
2
3
4
5
6
7
/* DUT parameters */
`define BW_A           8
`define BW_B           4
 
/* Sequence */
`define N_TRIAL_MIN    10
`define N_TRIAL_MAX    20

トランザクション

トランザクションはUVMのコンポーネント間の通信で使われるデータです。たとえば、次のように使われます。

  • シーケンサーがDUTをドライブするための情報をトランザクションとして生成し、ドライバーに渡す
  • コレクターがDUTのレスポンスをサンプリングし、その情報をトランザクションにしてモニターに渡す

では、早速トランザクションのソースコードを見ながら解説していきます。

再利用性を高めるため、my_item_baseとmy_itemに分けて作成します。

my_item_base.sv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class my_item_base extends uvm_sequence_item;
 
    rand bit                        rst;
    rand bit [`BW_A - 1:0]          a_in;
    rand bit [`BW_A - 1:0]          b_in;
    logic    [`BW_A + `BW_B - 1:0]  mult_out;                   
 
    `uvm_object_utils_begin(my_item_base)
        `uvm_field_int(rst, UVM_DEFAULT)
        `uvm_field_int(a_in, UVM_DEFAULT)
        `uvm_field_int(b_in, UVM_DEFAULT)
        `uvm_field_int(mult_out, UVM_DEFAULT)
    `uvm_object_utils_end
 
    function new(string name = "my_item_base");
        super.new(name);
    endfunction
 
endclass
  • 1行目:トランザクションはuvm_sequence_itemまたはそのサブクラスを継承して定義します。
  • 3~6行目:フィールドを定義します。ここにDUTをドライブするための値を格納します。したがって、フィールドが無ければトランザクションとして意味がありません。フィールドには、必要に応じてrand (またはrandc)属性をつけます。シーケンサーがトランザクションを生成する際にrandomizeします。
  • 8~13行目:UVMマクロとフィールドマクロを書きます。
  • 15~17行目:コンストラクタを定義します。

my_item.sv

1
2
3
4
5
6
7
8
class my_item extends my_item_base;            
    `uvm_object_utils(my_item)
    constraint CA { (a_in >= 1) && (a_in <= 200); }
    constraint CB { (b_in >= 1) && (b_in <= 10); }
    function new(string name = "my_item");
        super.new(name);
    endfunction
endclass

rand属性をつけたフィールドに制約を与えます。制約を与えることで、実際に入力され得る値の中で乱数を発生させることができます。

制約はテストケースによる場合が多いため、my_item_baseには制約をつけません。テストケースによって制約を変え、my_item1, my_item2,…というのを定義していくとよいです。

  • 1行目:my_item_baseを継承して、my_itemを定義します。
  • 2行目:UVMマクロを書きます。
  • 3~4行目:制約を与えます。if文で書くような条件式を記述します。その他、a_in inside{[1:200]}などの書き方があります。
  • 5~7行目:コンストラクタを定義します。

インターフェース

UVMではvirtual interfaceを使用して、ドライバーとDUT、またはコレクターとDUTを接続するので、インターフェースの定義が必須となります。

以下に定義を示します。インターフェースとDUTの接続は、トップモジュールの記事で解説します。

my_if.sv

1
2
3
4
5
6
7
8
9
10
11
interface my_if (input bit clk);
    logic                         rst;
    logic [`BW_A - 1:0]           a_in;
    logic [`BW_B - 1:0]           b_in;
    logic                         start;
    logic [`BW_A + `BW_B - 1:0]   mult_out;
    logic                         valid;
 
    clocking cb @ (posedge clk); endclocking
 
endinterface
  • 1行目:interface <インターフェース名> (クロック) と書きます。
  • 2~7行目:DUTのポートに対応する信号を定義します。
  • 9行目:DUTのレスポンスをサンプリングする際に使用するため、クロッキングブロックを定義します。

まとめ

今回は、トランザクションとインターフェースの定義方法について解説しました。UVMではどちらの定義も必要となります。

次回からは、UVM環境を構成するコンポーネントの作成方法について解説していきます。

シリーズ目次はこちら

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

コメントを残す

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

CAPTCHA