1. 株式会社PALTEK
  2. TECHブログ
  3. 技術情報
  4. 高い抽象度によるテスト環境の構築(Design and Verification LANDSCAPE 2025 Vol-1)

TECHブログ

高い抽象度によるテスト環境の構築(Design and Verification LANDSCAPE 2025 Vol-1)

高い抽象度によるテスト環境の構築(Design and Verification LANDSCAPE 2025 Vol-1)

FPGAプロジェクトにおける機能検証の最大の課題は「充分なテストの作成」であるという調査結果があります。
本記事では、テストベンチやテストスティミュラスの抽象度を高めることで検証作業の生産性を向上させる具体的な手法を、バスファンクショナルモデルの構築からUVM(Universal Verification Methodology)のシーケンス・シナリオレベルまで段階的に解説します。
RTLのクロックサイクルを意識することなく、アルゴリズムやランダム化に集中できるテスト記述の実現を目指すエンジニアに必見の内容です。

この記事でわかること

  • FPGAの機能検証における課題と、ASICプロジェクトとの生産性の差の背景
  • バスファンクショナルモデルを用いたタスク化によるテストスティミュラス記述の簡略化方法
  • SystemVerilogの出力引数を活用したトランザクションレベルへの抽象度引き上げの考え方
  • UVMのシーケンス・ドライバ間の同期メカニズムと、時間概念を排除したテスト記述の実現方法
  • トランザクションレベルでのランダム化による意味あるスティミュラス生成と、検証IPの再利用性向上の効果

はじめに

Wilson Research Group とSiemens EDAのHarry D. Foster氏が行なった2024年の機能検証の市場調査と分析によれば、機能検証の最大の課題は何かという設問に対して、FPGAプロジェクト従事者の43%が「設計を検証する充分なテストの作成」を挙げている。
一方で、例えば制約付きランダム検証などの検証技術を導入して生産性を確保しているFPGAプロジェクトは41%であり、ASICプロジェクトの68%に大きく水をあけられている。

この調査研究によれば、一般的にFPGA の検証プロセスはASICの検証プロセスに比べると遅れているとも指摘しており、生産性の高いテスト手法を導入し活用することは、極めて重要だと言える。

テストベンチ構築やテストスティミュラス生成はソフトウェアそのものである、これはUVM (Universal Verification Methodology, IEEE-1800.2) の開発や標準化に携わった多くの技術者が、DVConやDACなどのカンファレンス、あるいはさまざまな書籍で主張していることである。
彼らはまた、テストベンチやテストスティミュラスは検証対象であるRTL よりも高い抽象度で構築されていなくてはならない、とも言っている。

ここではテストベンチやテストスティミュラスの抽象度を上げ、少しでもテスト記述の生産性を上げ、テスト作成をソフトウェア設計者と共有する方法について解説する。

バスファンクショナルモデルの作成

抽象度を上げる最初の方法はバスファンクションモデルの作成である。このモデルによりバス上に適用するさまざまなコマンド、例えばwrite、read、burst_write、burst_readなどのコマンドレベルでテストスティミュラスが記述できることを意味する。

そこで図1.で示されるような書込みシーケンスに従うバスファンクショナルモデルを作成してみる。このシーケンスでは、bus_ready が立上がり、enable 信号が続き、そしてwrite信号が1 になった際に書込みが行われる。

図1. 1 ワード書込みのシーケンス

図1. 1 ワード書込みのシーケンス

次に、この書込みシーケンスをSystemVerilogで記述する。そしてその書込みシーケンスを行うコードを1つのタスクとして、ここではword_write という名称で定義する。その記述をコード1.に示す。

task word_write(
    input [7:0] addr;
    input [7:0] data;
    );
    begin
        $display ("%t Word Write: addr=%h : data= %h",$time, addr, data);
        wait(bus_ready==1);
        @(posedge clk);
            write_addr = addr;
            enable = 1;
            write_data = data;
        @(posedge clk);
            write = 1;
        @(posedge clk);
            enable = 0;
            write = 0;
    end
endtask

コード1. 1ワードを書込むword_write タスクの定義

このタスクが定義されていれば、テストベンチ側からはword_write(ad, dt) のように呼出すことで、簡単な記述で済む。つまりバスファンクショナルモデルをライブラリのように準備しておくことで、そのタスクを呼出すだけでテストスティミュラスが記述できることになる。
ただし、タスクを立て続けに記述するのではなく、タスクが終了すると思われる時間分を遅延として記述する必要がある。つまり#、もしくは##などの遅延演算子を併用して記述する必要がある。

抽象度を上げるとは

ここで特にハードウェアの世界において抽象度を上げるということが、どのようなことなのかを考察する。
確かにコード1.の例では各ビットを取り扱うよりはタスクを取り扱う方が抽象度は上がっている。同時に考慮しなくてはならないのは、時間である。コード1.の記述の中で、シミュレータ上のハードウェア時間が進むに連れてコードが進む、つまり同期が行われる記述箇所は2種類あり、1つは @(posedge clk)、もう一つはwait(bus_ready==1) である。
しかしこのタスクを呼び出す側から見れば、これらの詳細な時間については考慮する必要がない。むしろ詳細な時間を考慮しなくてはならないとすると、それは抽象度が変わっていないことを意味する。抽象度を上げることの重要な利点は、呼び出した処理が終了するタイミングで辻褄が合っていれば良いということである。であるならば、タスクが終了すると「思われる」時間を遅延として遅延演算子を併用するのではなく、このタスク自体を以下のように書き変えれば良いことになる。

task word_write(
    input  [7:0]  addr;
    input  [7:0]  data;
    output  logic write_done;
    );
    begin
        write_done = 0;
        $display ("%t Word Write: addr=%h : data= %h",$time, addr, data);
        wait(bus_ready==1);
        @(posedge clk);
            write_addr = addr;
            enable = 1;
            write_data = data;
        @(posedge clk);
            write = 1;
        @(posedge clk);
            enable = 0;
            write = 0;
        write_done = 1;
    end
endtask

コード2. 処理が終了したことを知らせる1ワードの書込みタスクの定義

Verilog ではタスクはファンクションのように戻り値を返さないためタスクの内外ではグローバル変数を活用して通信するが、SystemVerilog であればコード2.のようにタスクに出力引数を設けることができるので、タスク外へはこの出力引数によって通信が可能である。
このタスクを呼出す側では、wait(write_done==1)を設けることで、次のタスクの適切な開始タイミングを知ることができる。このような抽象度は、バスファンクショナルモデルというよりも、トランザクションレベルと呼ばれることが多い。

抽象度はさらに上げることが可能で、UVMではトランザクションレベルでの通信をまとめたものをシーケンスと呼ばれる抽象度で扱い、さらに複数シーケンスの順次処理や並行処理によって実現される抽象度をシナリオレベルと呼ばれる抽象度で扱っている。
またPSS (Portable Stimulus and Test Standard) では、UVM のシーケンスを最も抽象度が低いactionに対する実装として呼出し、このactionを階層化したりコンポーネント化したりすることでも抽象度を上げている。さらにaction を実行可能なリソースを制約として、テストシナリオを自動合成する技術もツール要件としている。

UVM におけるテストの抽象度

ここではUVMで抽象度を上げながら、最終的には時間的概念をまったく持たないテスト記述を実現することにより、テストの内容や方法におけるアルゴリズムに注力できるための仕組みについて説明する。
図2.に示すのはUVM の構造であり、DUV (Design Under Verification) に対してトランザクションレベルのモデルとシーケンスレベルのモデルを用いて、テストベンチを構築するためのフレームワークである。

図2. UVM テストベンチ構成例

図2. UVM テストベンチ構成例

図2.においてDUVはRTL デザインが想定されている。またDUVの周りにある点線よりも外側はトランザクションレベルで通信が行われている。UVM では水色部分のエージェントと呼ばれる検証コンポーネントがあり、この中にはモニター、チェッカー、ドライバなどが含まれている。
ドライバとは前出のバスファンクショナルモデルのような記述が含まれており、トランザクションレベルからDUVが理解できるピンレベルとの橋渡しをする。
またシーケンサはドライバに対して一連のトランザクション、アルゴリズムやランダム化によって生成されたトランザクションを渡す。
このAgentと呼ばれる検証コンポーネントは、例えばAXIやUSBなど、標準的なプロトコルに則って動作するように開発することによって、検証IP として再利用性を高めることができる。

このUVM におけるスティミュラス生成のメカニズムについて、抽象度および同期の観点から解説する。なおUVM では検証コンポーネントやトランザクションなどのテストオブジェクトは、すべてクラス実装されている。

図3. Test トップからドライバまでの同期のメカニズム

図3. Test トップからドライバまでの同期のメカニズム

この図にあるコードはUVM およびSystemVerilog で記述されている。同期が行われるメカニズムについて、順番に説明する。

一番左にあるtx_test は、テスト生成に関するトップであり、UVM に実装されているuvm_test クラスを拡張して定義する。テストではrun_phaseと呼ばれるタスクがあり、このタスク内にシーケンス呼出しなどを記述していく。

テストからenv.agt.sqrというテストベンチ環境にあるエージェント、さらにその内部にあるシーケンスをスタートさせている。砂時計のアイコンがある場所は、コールと同時に待機状態に入ることを示している。
コールされたシーケンスはbody メソッドを実行し、repeat構文内にあるreq トランザクション生成と、そのトランザクションを指定してstart_item を起動する。そしてstart_itemは起動されるとリクエストを待つ待機状態になる。

一方で右側にあるドライバはバスファンクショナルモデルの要素を持っており、検証対象のRTL を駆動しながら次のトランザクションを送出しても良いタイミングでシーケンスにリクエストを出す。

ドライバが次のトランザクションをリクエストし、ドライバはトランザクションが来るまで待機状態となる。
制御はシーケンスに戻り、これに続いて送出すべきトランザクションを決定し、ドライバに送出し、シーケンス自身は待機状態になる
ドライバはトランザクションをDUV に送出し、送出し終えたらitem_done を返す
500回のループでトランザクションを送出し終えたらbody() を抜け、制御をテストに戻す

シーケンスのstart_item()とfinish_item()に挟まれる部分は、次に送出するべきトランザクションを決定するアルゴリズムや式、あるいはランダム化などを、時間の概念を気にすることなく、自由に記述することができる。

図4. シーケンス内でのランダム化

図4. シーケンス内でのランダム化

図4.はreq というトランザクションに含まれているrandomize()メソッドを使って、ランダムなトランザクションを生成しては送出し、これが500回行われる。ランダム化がシーケンス内にあるということは、この抽象度でランダム化を行うことを意味している。
前出のword_writeで使用されているwrite、bus_ready、enableなどピンレベルでランダム化を行っても意味がなく、トランザクションレベルでランダム化することで、意味あるスティミュラス生成が可能になる。そしてテストの抽象度であれば、複数のシーケンスをシリアルに、あるいはfork〜joinを用いてパラレルに記述し、全体のテストをシナリオとして制御する。

まとめ

「設計を検証する充分なテストを生成すること」が最大の課題であるとするFPGA プロジェクトに対して、テスト生成の生産性を上げるために、より高い抽象度による記述のポイントを紹介した。
冒頭で紹介した「テストベンチ構築やテストスティミュラス生成はソフトウェアそのものである」というコメントについても、その意味合いが理解できたのではないだろうか。
RTL のクロック数を数えて次のスティミュラスを決定するのではなく、時間の概念を忘れ、アルゴリズムやランダム化に集中してテスト記述ができる高い抽象度が生産性への鍵となる。

テストベンチ構築やテストスティミュラス生成の御作法としてメソドロジという言葉が使われるが、ここには抽象度を上げる手法、デザインと高抽象度のテスト記述とを同期する手法、ランダム化により生産性を上げる手法、モジュール化によって再利用性を高める手法等を実現するために、クラスを用いて開発されたAPIの集合体といった意味合いが含まれている。
特にUVMの登場により、単に手法を実現するだけでなく、業界として統一されたテストベンチのフレームワークに簡単にプラグインすることが可能な検証IPが流通するようになった。
検証IPの活用によりテストベンチ構築の膨大な労力を軽減し、さらなる機能検証の生産性の向上が期待できる。

参考文献

 

設計・検証エンジニアのための技術情報をお届け
設計・検証エンジニアのための技術情報をお届け
検証工数を削減したい
最新の検証手法をキャッチアップしたい
生成AIをどう設計に使えばいいかわからない

そんなお悩みを持つ方に向けて、PALTEKが厳選した下記のような実践的な技術情報を年3〜4回無料配信中。

  • DVConなど国際カンファレンスの最新議論を日本語で
  • SystemVerilog / UVM / フォーマル検証など現場で使えるノウハウ
  • FPGA・ASIC設計者のキャリアにも直結する技術動向
Design and Verification Landscape
技術情報メールニュースに登録

※ 競合製品取り扱い企業様の申込については、お断りする場合がありますので予めご了承ください。

関連ブログ

このブログのシリーズ一覧は下記になります。
是非あわせてお読みください。