VHDLで自己検証テストベンチを構築する実践ガイド
自己検証テストベンチとは、手動検査なしでデバイス・アンダー・テスト(DUT)の正確性を検証するVHDLプログラムです。実行すると自動的にOKまたはFailedステータスを報告するため、信頼性の高いVHDL開発に不可欠なツールです。
すべてのVHDLモジュールには自己検証テストベンチを付けるべきです。DUT本体、サブモジュール、インターフェースのいずれを変更しても、回帰バグをサイレントに導入しないことを保証します。よく作られたテストベンチは、巧妙なバグに対する第一の防衛線となります。
テスト対象デバイス(DUT)
シンプルながら説明しやすいDUTとして、バイナリ・ツー・グレイコード変換器を使用します。以下が完全なRTL実装です。
library ieee;
use ieee.std_logic_1164.all;
entity gray_converter is
port (
bin : in std_logic_vector;
gray : out std_logic_vector
);
end gray_converter;
architecture rtl of gray_converter is
begin
process(bin) is
begin
gray(gray'high) <= bin(bin'high);
for i in bin'high - 1 downto bin'low loop
gray(i) <= bin(i + 1) xor bin(i);
end loop;
end process;
end architecture;
グレイコードは、連続する値間で1ビットのみが変化するバイナリ符号化方式で、シリアル通信やデジタルカウンタでのエラー確率を最小化します。以下は4ビット値のマッピング表。
| 10進 | 2進 | グレイ |
|---|---|---|
| 0 | 0000 | 0000 |
| 1 | 0001 | 0001 |
| 2 | 0010 | 0011 |
| 3 | 0011 | 0010 |
| 4 | 0100 | 0110 |
| 5 | 0101 | 0111 |
| 6 | 0110 | 0101 |
| 7 | 0111 | 0100 |
| 8 | 1000 | 1100 |
| 9 | 1001 | 1101 |
| 10 | 1010 | 1111 |
| 11 | 1011 | 1110 |
| 12 | 1100 | 1010 |
| 13 | 1101 | 1011 |
| 14 | 1110 | 1001 |
| 15 | 1111 | 1000 |
テストベンチの骨格
以下はDUTをインスタンス化し、必要な信号を宣言した最小限のテストベンチです。std.env.finish(VHDL-2008機能)を含め、シミュレーションをクリーンに終了します。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.env.finish;
entity gray_converter_tb is
end gray_converter_tb;
architecture sim of gray_converter_tb is
signal bin : std_logic_vector(3 downto 0) := (others => '0');
signal gray : std_logic_vector(3 downto 0);
DUT : entity work.gray_converter(rtl)
port map (
bin => bin,
gray => gray
);
end architecture;
VHDL-2008準拠シミュレータ(ModelSimなど)でコンパイルする場合、ファイルの言語バージョンを2008に設定する必要があります。ModelSimではファイルを右クリック→Properties→VHDL→Use 1076-2008。
全入力パターンの網羅的生成
次に、あり得るすべての4ビット値を完全にスイープします。網羅的テストはコーナーケースまで網羅するため推奨されます。
PROC_SEQUENCE : process
begin
-- すべての4ビット値を反復
for i in 0 to 2**bin'length - 1 loop
bin <= std_logic_vector(to_unsigned(i, bin'length));
wait for 10 ns;
end loop;
-- 初期状態にラップアラウンド
bin <= (others => '0');
wait for 10 ns;
report "Test: OK";
finish;
end process;
10nsの遅延は任意。DUTが純粋組み合わせ回路なので、正の値なら何でも構いません。最終的なfinish文でシミュレーションを正常終了。
DUT出力の検証
単に「Test: OK」と表示するだけでは、出力が間違っていても意味がありません。正しさを強制するため、DUTのグレイ出力をグレイコードの基本特性(連続出力はちょうど1ビットのみ異なる)と比較します。
PROC_CHECKER : process
variable prev : std_logic_vector(gray'range);
variable count : integer;
begin
wait on bin;
prev := gray;
-- 組み合わせロジックの伝播を待つ
wait for 1 ns;
count := 0;
for i in gray'range loop
if gray(i) /= prev(i) then
count := count + 1;
end if;
end loop;
assert count = 1
report integer'image(count) & " bits changed, should have been 1"
severity failure;
end process;
このプロセスはbinの変化を監視し、前回のグレイ出力を取得、伝播待ち後、異なるビット数をカウントし、ちょうど1ビットであることをアサートします。アサーション失敗時は即座にシミュレータが停止し、「Test: OK」メッセージは表示されません。
テストベンチの実行
ModelSimでシミュレーション開始後、run -allを実行。成功時の出力:
VSIM 1> run -all # ** Note: Test: OK # Time: 170 ns Iteration: 0 Instance: /gray_converter_tb
テストベンチの堅牢性確認
チェッカーが故障を検出するか確認するため、DUTに一時的にエラーを導入します。例:gray(3)を0に固定。
process(bin) is
begin
gray(gray'high) <= bin(bin'high);
for i in bin'high - 1 downto bin'low loop
gray(i) <= bin(i + 1) xor bin(i);
end loop;
-- スタックアットゼロ故障をエミュレート
gray(3) <= '0';
end process;
テストベンチ実行でアサーション失敗が発生し、変化したビット数が正確に表示されます:
VSIM 2> run -all # ** Failure: 0 bits changed, should have been 1 # Time: 81 ns Iteration: 0 Process: /gray_converter_tb/PROC_CHECKER File: gray_converter_tb.vhd # Break in Process PROC_CHECKER at ray_converter_tb.vhd line 61
自己検証テストベンチへの第一歩
すべてのVHDLモジュールに自己検証テストベンチを書く習慣をつけましょう。早期に回帰を検出し、設計意図の明確な記録になります。テストベンチは合成可能である必要はありませんが、明確で保守しやすく、最新のVHDL構文を用いて可読性と効率を高めるべきです。
より深い学習には、仕様からFPGAプロトタイプまでの全設計フローをカバーし、厳格な検証プラクティスを強調する上級コースを検討してください。
2020年10月12日更新: VHDLとFPGAコースを完了しました。下記画像をクリックで詳細。
ドットマトリクスVHDL/FPGAコースの詳細はこちら!
開講:
未定。
VHDL
- フリクションレスなユーザー体験の構築:UXデザインのブループリント
- 初めてのAWS CloudFormationテンプレート構築:実践ガイド
- Cloud Center of Excellence(CCoE)構築:移行成功と顧客成功のための戦略
- 戦略的クラウド導入計画の構築:実践ロードマップ
- 人間中心のスマートシティ構築:戦略的ブループリント
- VHDLで文字列リストを作成する: ベスト・プラクティスと実装例
- Tcl駆動テストベンチでVHDLコード・ロック・モジュールを検証する
- VHDLテストベンチ・シミュレーションを優雅に終了させる方法
- VHDLでPWMコントローラを実装: 設計、シミュレーション、FPGAデモ
- VHDLで保護型とアクセスポインタを用いた動的リンクリスト実装
- Javaオブジェクト配列の作成:ステップバイステップガイド