VUnit 101:自動化VHDL検証の実践ガイド
VUnitは、Pythonテストスイートランナーと専用VHDLライブラリを組み合わせた主要なオープンソースVHDL検証フレームワークです。これらが連携してテストベンチのコンパイル、実行、結果レポートを自動化し、エンジニアがテスト駆動開発サイクルを実践できるようにします。
このチュートリアルでは、VHDLwhizの作者Ahmadmunthar Zaklouta氏が、インストールと設定からテストベンチ作成、テストケース記述、ModelSimでの実行まで、VUnitワークフロー全体を解説します。すぐに実行可能なサンプルプロジェクトもダウンロード可能です。
概要
サイドバーまたはモバイルナビゲーションボタンを使用してセクション間を移動できます。チュートリアルには視覚的参照用のスクリーンショットが含まれています。
必要要件
- Intel ModelSim - こちらで無料インストール方法を説明。システム
PATHに追加。 - Python 3.6+ - ダウンロードし、
PATHに追加。 - Git(オプション) - ダウンロード。
- Windows Terminal(オプション) - ダウンロード。
基本的なVHDLとModelSimの習熟度を前提としています。
VUnitのインストール
サブモジュール付きでリポジトリをクローン:
git clone --recurse-submodules https://github.com/VUnit/vunit.git
またはZIPをダウンロードし、C:\vunitに展開してからインストール:
cd C:\vunit python setup.py install
環境変数を設定:
VUNIT_MODELSIM_PATH- ModelSim実行ファイルへのパス。VUNIT_SIMULATOR-Modelsimに設定。
設定例のスクリーンショット:

サンプルプロジェクトのダウンロード
ZIPをC:\vunit_tutorialに展開し、同梱スクリプトを実行。
VUnit入門
VUnitは以下を提供することでHDL検証を簡素化します:
- テスト自動化、設定、管理のためのPythonライブラリ。
- 再利用可能な検証コンポーネントを含むVHDLライブラリ。
VHDL側には6つのライブラリがあります。このチュートリアルではloggingとcheckライブラリに焦点を当てます。

テスト対象設計(DUT)
サンプルDUTのmotor_startは、モーターの起動シーケンスを表す3つのLED(赤、黄、緑)を駆動します。インターフェースにはレコード型を使用します。

起動プロセスは3ステップ:
- 設定読み込み(赤LED)
- キャリブレーション(黄LED)
- 回転(緑LED)
起動シーケンス
- 赤LED - 5回点滅後、点灯維持。
- 黄LED - スイッチ2後に10サイクル点灯、その後赤と共に消灯。
- 緑LED - スイッチ3がアクティブな間点灯。
テストベンチ開発
- Python
run.pyスクリプトを設定。 - VUnitスケルトンを構築。
- DUTをインスタンス化し、信号を駆動。
Python実行スクリプト
run.pyスクリプトはパスを定義し、VUnitインスタンスを作成し、設計およびテストベンチライブラリを追加します:
# ROOTディレクトリ
ROOT = Path(__file__).resolve().parent
# ソースパス
DUT_PATH = ROOT / "design"
TEST_PATH = ROOT / "testbench"
# VUnitインスタンス
VU = VUnit.from_argv()
VU.enable_location_preprocessing()
# ライブラリ
design_lib = VU.add_library("design_lib")
design_lib.add_source_files([DUT_PATH / "*.vhdl"])
tb_lib = VU.add_library("tb_lib")
tb_lib.add_source_files([TEST_PATH / "*.vhdl"])
VUnitスケルトン
テストベンチエンティティにVUnitコンテキストと必須ジェネリックを追加:
LIBRARY VUNIT_LIB;
CONTEXT VUNIT_LIB.VUNIT_CONTEXT;
ENTITY motor_start_tb IS
GENERIC(runner_cfg : string := runner_cfg_default);
END ENTITY motor_start_tb;
アーキテクチャにはテストランナープロセスを配置:
ARCHITECTURE tb OF motor_start_tb IS
test_runner : PROCESS BEGIN
test_runner_setup(runner, runner_cfg);
WHILE test_suite LOOP
-- test cases
END LOOP;
test_runner_cleanup(runner);
END PROCESS;
END ARCHITECTURE;
個々のテストケースはIF run("case_name") THENブロックで定義します。
信号宣言とDUTインスタンス化
クロック、リセット、インターフェースレコードを定義:
CONSTANT C_CLK_PERIOD : time := 10 ns;
SIGNAL clk, reset : STD_LOGIC := '0';
SIGNAL motor_start_in : MOTOR_START_IN_RECORD_TYPE := (switch_1 => '0', switch_2 => '0', switch_3 => '0');
SIGNAL motor_start_out : MOTOR_START_OUT_RECORD_TYPE;
DUTをインスタンス化:
motor_start_tb_inst : ENTITY DESIGN_LIB.motor_start(rtl)
PORT MAP(
clk => clk,
reset => reset,
motor_start_in => motor_start_in,
motor_start_out => motor_start_out
);
クロックとリセットを駆動:
clk <= NOT clk after C_CLK_PERIOD / 2;
reset <= '0' after 5 * (C_CLK_PERIOD / 2);
テストケース開発
3つの検証スタイルを探ります:インラインドライバー&チェッカー、制御付きチェッカー、自己完結型チェッカー。
インラインドライバー&チェッカー
switch_1を駆動し、VUnitのcheckファミリーでLED状態をチェックするシンプルなテストケース:
IF run("switch_1_on_output_check") THEN
WAIT UNTIL reset = '0';
WAIT UNTIL falling_edge(clk);
motor_start_in.switch_1 <= '1';
FOR i IN 0 TO 4 LOOP
WAIT UNTIL rising_edge(clk);
check(motor_start_out.red_led = '1', "Red LED should be on");
check_false(motor_start_out.yellow_led, "Yellow LED should be off");
check_equal(motor_start_out.green_led, '0', "Green LED should be off");
END LOOP;
END IF;
制御付きチェッカー
ドライバーはテストケースに残し、チェッカーを別プロセスで実行し、開始/終了イベントで制御。例えばswitch_2有効後の黄LED検証:
check_stable(clock => clk, en => enable,
start_event => yellow_low_start_event,
end_event => yellow_low_end_event,
expr => motor_start_out.yellow_led,
msg => "YELLOW LED low before switch_2");
自己完結型チェッカー
専用プロセスに検証ロジックをカプセル化し、内部でcheckやcheck_stableを使用。ドライバー手順で刺激を簡素化:
PROCEDURE switch_driver(
SIGNAL switches : OUT MOTOR_START_IN_RECORD_TYPE;
CONSTANT clk_period : IN TIME;
CONSTANT sw1_delay : IN INTEGER;
CONSTANT sw2_delay : IN INTEGER;
CONSTANT sw3_delay : IN INTEGER) IS
BEGIN
IF sw1_delay >= 0 THEN
WAIT FOR clk_period * sw1_delay;
switches.switch_1 <= '1';
END IF;
IF sw2_delay >= 0 THEN
WAIT FOR clk_period * sw2_delay;
switches.switch_2 <= '1';
END IF;
IF sw3_delay >= 0 THEN
WAIT FOR clk_period * sw3_delay;
switches.switch_3 <= '1';
END IF;
END PROCEDURE;
テスト実行
ターミナルから:
python .\run.py *switch_1_on_output_check
VUnitが設計をコンパイルし、テストベンチを検出し、指定ケースを実行。出力はC:\vunit_tutorial\vunit_out\test_outputにログ記録されます。
-vで冗長ログ、-lで全ケース一覧、--cleanで前回結果削除、-gでModelSim波形ウィンドウ起動(wave.doファイル必要)。
まとめ
VUnitは、設計チームと検証チームの両方を加速する堅牢で軽量なフレームワークです。Python駆動のテストハーネス、豊富なVHDLライブラリ、柔軟なチェッカーAPIにより、あらゆるHDLワークフローに価値ある追加となります。
次のステップ
以下のフォームからサンプルプロジェクト全体をダウンロードできます。
VHDL
- Cat®機材を最適化:My.Cat.com完全活用ガイド
- TJBot入門:組み立て、設定、音声制御で自分だけのAIロボットを構築
- RAK 831 LoRaゲートウェイをRaspberry Pi 3に導入するステップバイステップガイド
- Raspberry Pi 3 と RAK831 モジュールで LoRa ゲートウェイを構築するステップバイステップガイド
- Arduino初心者チュートリアル01: 最初のプロジェクトを始めよう
- セラミック3Dプリント実践ガイド:技術、材料、設計のコツ
- 保険業界における AI:実践的スターターガイド
- DockerでPLCnextにNode-REDをデプロイ:ステップバイステップガイド
- Code-Ready Containers:Red Hat OpenShiftによるクラウドネイティブプロセス自動化の実践ガイド
- エッジ時代のIoT:成長、データ、セキュリティ、パートナー戦略
- 基本染料の理解:用途・安全性・産業応用