
VHDL(VHSICハードウェア記述言語)は、システムレベルから論理ゲートレベルまで、複数の抽象度レベルでデジタルシステムの動作と構造をモデル化できるハードウェア記述言語です。設計入力、ドキュメント作成、検証に使用できます。この言語は1980年代に米国軍のVHSICプログラム向けに開発され、 IEEE(電気電子学会)によってIEEE Std 1076として標準化されました。最新バージョンはIEEE Std 1076-2019です。アナログシステムやミックスドシグナルシステムをモデル化するために、VHDLをベースとしたIEEE標準化HDLであるVHDL-AMS(正式にはIEEE 1076.1)が開発されました。
1983年、VHDLは、サプライヤー企業が機器に組み込んでいるASICの動作を文書化するために、米国国防総省の要請により開発されました。標準規格MIL-STD-454N [ 2 ]の要件64、セクション4.5.1「VHDLによるASICの文書化」では、「マイクロエレクトロニクスデバイス」のVHDLによる文書化が明示的に要求されています。
このドキュメントの情報に基づいてASICをシミュレーションできるというアイデアは非常に魅力的だったため、 VHDLファイルを読み込めるロジックシミュレータが開発されました。次のステップは、VHDLを読み込み、回路の物理的な実装定義を出力するロジック合成ツールの開発でした。
国防総省は、構文の可能な限り多くをAdaに基づいて構築することを要求しており、Adaの開発において既に徹底的にテストされた概念を再発明することを避けるため、 VHDLは概念と構文の両方においてAdaプログラミング言語から多くの要素を借用しています。
IEEE 1076–1987 [ 3 ]に準拠して設計された VHDL の初期バージョンには、数値 (整数と実数)、論理 (ビットとブール)、文字と時間、および文字列と呼ばれる配列など、幅広いデータ型が含まれていました。bitbit_vectorcharacter
しかし、この版で解決されなかった問題は、信号の駆動強度(なし、弱い、強い)と未知の値も考慮される多値論理でした。これには、9値論理型(スカラーとそのベクトル版)を定義したIEEE標準1164が必要でした。親型の解決済みサブタイプである型信号は、バス構造をモデル化するために複数の駆動を可能にし、接続された解決関数が競合する割り当てを適切に処理します。std_logicstd_logic_vectorstd_Ulogicstd_logic
1993年に更新されたIEEE 1076では、構文の一貫性が向上し、命名の柔軟性が高まり、ISO-8859-1印刷可能文字characterを許容する型が拡張され、演算子が追加されました。xnor
標準規格のマイナーチェンジ(2000年と2002年)により、保護型(C++のクラスの概念に類似)の概念が追加され、ポートマッピング規則のいくつかの制限が削除されました。
IEEE標準1164に加えて、言語の機能を拡張するためにいくつかの派生標準が導入されました。IEEE標準1076.2では、実数型と複素数型のデータ処理が改善されました。IEEE標準1076.3では、ベクトルに対する算術演算を容易にするために、符号付き型と符号なし型が導入されました。IEEE標準1076.1(VHDL-AMSとして知られる)では、アナログ回路と混合信号回路の設計拡張機能が提供されました。
他のいくつかの標準規格は、特にVITAL(VHDL Initiative Towards ASIC Libraries)[ 4 ]やマイクロ波回路設計の拡張など、VHDLのより広範な使用をサポートしています。
2006年6月、 AccelleraのVHDL技術委員会(IEEEから標準の次期更新作業を委任されている)は、VHDL-2006のいわゆるドラフト3.0を承認しました。この提案された標準は、以前のバージョンとの完全な互換性を維持しながら、VHDLコードの記述と管理を容易にする多数の拡張機能を提供します。主な変更点としては、子標準(1164、1076.2、1076.3)をメインの1076標準に組み込むこと、演算子の拡張セット、case文とgenerate文の構文の柔軟性の向上、VHPI(VHDL手続き型インターフェース)(C/C++言語へのインターフェース)の組み込み、およびPSL(プロパティ仕様言語)のサブセットの組み込みなどが挙げられます。これらの変更により、合成可能なVHDLコードの品質が向上し、テストベンチの柔軟性が高まり、システムレベルの記述にVHDLをより広く使用できるようになります。
2008年2月、AccelleraはVHDL 4.0(非公式にはVHDL 2008とも呼ばれる)を承認しました。これはバージョン3.0の試用期間中に発見された90以上の問題に対処し、拡張された汎用型を含んでいます。2008年、AccelleraはIEEEにVHDL 4.0を提出し、IEEE 1076-2008への採用投票にかけました。VHDL標準IEEE 1076-2008 [ 5 ]は2009年1月に発行されました。
IEEE規格1076は、VHSICハードウェア記述言語(VHDL)を定義しています。これは元々、 1983年に米国空軍から授与された契約F33615-83-C-1003に基づき、言語専門家および主契約者としてIntermetrics社、チップ設計専門家としてTexas Instruments社、コンピュータシステム設計専門家としてIBM社からなるチームによって開発されました。この言語は数多くの改訂を経ており、重要な点でVHDLを補完または拡張するさまざまなサブ規格が存在します。
IEEE規格1076は、電子システムの設計における画期的な規格であり、現在もその地位を保っている。[ 6 ]
VHDLは一般的に、論理回路を記述するテキストモデルを作成するために使用されます。このようなモデルは、論理設計の一部である場合にのみ、合成プログラムによって処理されます。シミュレーションプログラムは、設計とインターフェースする論理回路を表すシミュレーションモデルを使用して、論理設計をテストするために使用されます。このシミュレーションモデルの集合は、一般的にテストベンチと呼ばれます。
VHDLシミュレータは、一般的にイベント駆動型シミュレータです。[ 14 ]これは、各トランザクションが特定のスケジュールされた時間でイベントキューに追加されることを意味します。たとえば、信号割り当てが1ナノ秒後に発生する必要がある場合、イベントは時間+1nsでキューに追加されます。遅延がゼロの場合も許可されますが、それでもスケジュールする必要があります。このような場合は、無限に小さな時間ステップを表すデルタ遅延が使用されます。シミュレーションは、トリガーされたステートメントが評価されるステートメント実行と、キュー内のイベントが処理されるイベント処理の2つのモードを交互に実行します。
VHDLにはハードウェア設計に内在する並列性を扱うための構成要素がありますが、これらの構成要素(プロセス)は、Adaの並列構成要素(タスク)とは構文が異なります。Adaと同様に、VHDLは厳密な型付けを持ち、大文字と小文字を区別しません。ハードウェアでよく行われる操作を直接表現するために、VHDLにはAdaにはない多くの機能があり、例えばnandやnorを含む拡張されたブール演算子セットなどがあります。
VHDLはファイル入出力機能を備えており、汎用テキスト処理言語として使用できますが、シミュレーションテストベンチでは刺激データや検証データとしてファイルがより一般的に使用されます。実行可能バイナリを生成するVHDLコンパイラも存在します。この場合、ホストコンピュータ上のファイルを使用して刺激を定義し、ユーザーと対話し、結果を期待値と比較することで、設計の機能を検証するテストベンチをVHDLで作成できる可能性があります。しかし、ほとんどの設計者はこの作業をシミュレータに任せています。
経験の浅い開発者が、シミュレーションは成功するものの、実際のデバイスに合成できない、あるいは実用的ではないほど大きすぎるコードを作成することは比較的容易である。特に陥りやすい落とし穴の一つは、記憶素子としてD型フリップフロップではなく透過ラッチを誤って作成してしまうことである。[ 15 ]
VHDL IDE (FPGA実装用、例えばXilinx ISE、Altera Quartus、Synopsys Synplify、Mentor Graphics HDL Designerなど) でハードウェアを設計して、目的の回路のRTL回路図を作成できます。その後、生成された回路図はシミュレーション ソフトウェアを使用して検証できます。シミュレーション ソフトウェアは、適切なテスト ベンチを生成した後、回路の入力と出力の波形を表示します。特定の回路または VHDL コードに対して適切なテスト ベンチを生成するには、入力を正しく定義する必要があります。たとえば、クロック入力の場合は、ループ処理または反復ステートメントが必要です。[ 16 ]
VHDLモデルがCPLDやFPGAなどのプログラマブルロジックデバイスにマッピングされるゲートとワイヤに変換される場合、プロセッサチップ上でVHDLコードが実行されるのではなく、実際のハードウェアが構成されることになります。
システム設計にVHDLを使用する際の主な利点は、合成ツールが設計を実際のハードウェア(ゲートと配線)に変換する前に、必要なシステムの動作を記述(モデル化)し、検証(シミュレーション)できる点にある。
もう一つの利点は、VHDLが並行システムの記述を可能にすることです。VHDLはデータフロー言語であり、BASIC、C、アセンブリ言語などの手続き型プログラミング言語とは異なり、すべてのステートメントが同時に実行されることを前提としています。手続き型言語では、一連のステートメントが1命令ずつ順次実行されます。
VHDLプロジェクトは多目的です。一度作成した計算ブロックは、他の多くのプロジェクトで使用できます。ただし、多くの構成パラメータや機能パラメータ(容量パラメータ、メモリサイズ、要素ベース、ブロック構成、相互接続構造など)を調整できます。
VHDLプロジェクトは移植性に優れています。ある要素ベース向けに作成されたコンピューティングデバイスプロジェクトは、別の要素ベース(例えば、様々な技術を用いたVLSIなど)に移植することができます。
オリジナルのVerilogと比較した VHDL の大きな利点は、VHDL が完全な型システムを備えていることです。設計者は型システムを使用して、より構造化されたコードを書くことができます (特にレコード型を宣言することによって)。[ 17 ]
VHDLでは、設計は少なくともインターフェースを記述するエンティティと、実際の実装を含むアーキテクチャで構成されます。さらに、ほとんどの設計はライブラリモジュールをインポートします。一部の設計には、複数のアーキテクチャと構成が含まれる場合もあります。
VHDLにおける単純なANDゲートは次のようになります。
-- (これは VHDL コメントです) /* これはブロック コメント (VHDL-2008) */ -- IEEE ライブラリから std_logic をインポートします library IEEE ; use IEEE.std_logic_1164 . all ;-- これはエンティティですentity ANDGATE is port ( I1 : in std_logic ; I2 : in std_logic ; O : out std_logic ); end entity ANDGATE ;-- これはアーキテクチャです。ANDGATEのアーキテクチャRTLは、 O <= I1とI2から始まります。;アーキテクチャRTLの終了;( はレジスタ転送レベルRTL設計を表します。) 上記の例は HDL 初心者には冗長に見えるかもしれませんが、多くの部分はオプションであるか、一度だけ記述すれば済みます。一般的に、このような単純な関数は、このような単純なもの専用のモジュールを用意するのではなく、より大きな動作モジュールの一部となります。さらに、型などの要素の使用は、最初はやりすぎに見えるかもしれません。組み込み型を簡単に使用して、最初はライブラリのインポートを避けることができます。しかし、単純なビット (0,1 )の代わりに、多値論理、特に9 値論理( 、、、、、、、) を使用すると、現在他のどの HDL にも存在しない非常に強力なシミュレーションおよびデバッグツールが設計者に提供されます。std_logicbitUX01ZWHL-
以下の例からわかるように、VHDLコードは非常に簡潔な形式で記述できます。しかし、経験豊富な設計者は通常、可読性と保守性を考慮して、このような簡潔な形式を避け、より冗長なコーディングスタイルを採用します。
VHDLは、電子設計のシミュレーションと、そうした設計の合成という2つの異なる目的で頻繁に使用されます。合成とは、VHDLをコンパイルし、FPGAやASICなどの実装技術にマッピングするプロセスです。
VHDL のすべての構造が合成に適しているわけではありません。たとえば、タイミングを明示的に扱う構造のほとんどは、wait for 10 ns;シミュレーションには有効であっても合成できません。さまざまな合成ツールには異なる機能がありますが、多くの合成ツールで共通のハードウェアにマッピングされる言語構造とイディオムを定義する、VHDL の共通の合成可能なサブセットが存在します。IEEE 1076.6 は、公式の合成サブセットと見なされる言語のサブセットを定義しています。合成結果が不正確または最適でない可能性があるため、合成用に非常に慣用的なコードを書くことが一般的にベストプラクティスとされています。
マルチプレクサ、または通常「MUX」と呼ばれるものは、ハードウェア設計で非常によく使われる単純な構造です。以下の例は、入力AとB、セレクタSと出力を持つ単純な2対1のMUXを示していますX。VHDLでは、同じMUXを表現する他の多くの方法があることに注意してください。[ 18 ]
S = '1'の場合、X <= Aとなる。それ以外の場合はB となる。4×3入力と2ビットセレクタを備えた、より複雑なマルチプレクサの例:
library IEEE ; use IEEE.std_logic_1164. all ; entity mux4 is port ( a1 : in std_logic_vector ( 2 downto 0 ); a2 : in std_logic_vector ( 2 downto 0 ); a3 : in std_logic_vector ( 2 downto 0 ); a4 : in std_logic_vector ( 2 downto 0 ); sel : in std_logic_vector ( 1 downto 0 ); b : out std_logic_vector ( 2 downto 0 ) ); end mux4 ; architecture rtl of mux4 is -- 宣言部分: 空begin p_mux : process ( a1 , a2 , a3 , a4 , sel ) begin case sel is when "00" => b <= a1 ; when "01" => b <= a2 ; when "10" => b <= a3 ; when others => b <= a4 ; end case ; end process p_mux ; end rtl ;透過ラッチとは、基本的にイネーブル信号が出力されたときに更新される1ビットのメモリのことです。これもまた、VHDLでは様々な方法で表現できます。
-- ラッチテンプレート 1: Enable = '1'の場合、Q <= Dそれ以外の場合はQ ;-- ラッチテンプレート 2:プロセス(すべて) begin Q <= D when ( Enable ); end process ;D型フリップフロップは、クロックの立ち上がり(または立ち下がり)エッジで入力信号をサンプリングします。この例では、非同期のアクティブハイリセットを備え、クロックの立ち上がりエッジでサンプリングを行います。
DFF : process ( all ) is begin if RST then Q <= '0' ; elsif rising_edge ( CLK ) then Q <= D ; end if ; end process DFF ;VHDLでエッジトリガー動作を記述するもう一つの一般的な方法は、「event」信号属性を使用することです。信号名と属性名の間には、アポストロフィを1つ記述する必要があります。
DFF : process ( RST , CLK ) is begin if RST then Q <= '0' ; elsif CLK 'event and CLK = '1' then Q <= D ; end if ; end process DFF ;VHDLは、次のような「一行記述」にも適しています。
DFF : RST = '1'のときQ <= '0'、それ以外の場合はrising_edge ( clk )のときD ;または:
DFF : process ( all ) is begin if rising_edge ( CLK ) then Q <= D ; end if ; if RST then Q <= '0' ; end if ; end process DFF ;または:
ライブラリIEEE ; USE IEEE.Std_logic_1164. all ;entity RisingEdge_DFlipFlop_SyncReset is port ( Q : out std_logic ; Clk : in std_logic ; sync_reset : in std_logic ; D : in std_logic ); end RisingEdge_DFlipFlop_SyncReset ;architecture Behavioral of RisingEdge_DFlipFlop_SyncReset is begin process ( Clk ) begin if ( rising_edge ( Clk )) then if ( sync_reset = '1' ) then Q <= '0' ; else Q <= D ; end if ; end if ; end process ; end Behavioral ;これは、このプロセスによって駆動されるすべての信号(レジスタ)をリセットする必要がない場合に役立ちます。
以下の例は、非同期リセット、並列ロード、および構成可能な幅を備えたアップカウンタです。この例では、「unsigned」型、'unsigned'と'std_logic_vector'間の型変換、およびVHDLジェネリクスの使用方法を示しています。ジェネリクスは、C++などの他の従来のプログラミング言語における引数やテンプレートに非常に近いものです。この例はVHDL 2008言語で記述されています。
library IEEE ; use IEEE.std_logic_1164. all ; use IEEE.numeric_std. all ; -- 符号なし型の場合entity COUNTER is generic ( WIDTH : in natural := 32 ); port ( RST : in std_logic ; CLK : in std_logic ; LOAD : in std_logic ; DATA : in std_logic_vector ( WIDTH - 1 downto 0 ); Q : out std_logic_vector ( WIDTH - 1 downto 0 )); end entity COUNTER ;COUNTERのRTLアーキテクチャは始めるprocess ( all ) is begin if RST then Q <= ( others => '0' ); elsif rising_edge ( CLK ) then if LOAD = '1' then Q <= DATA ; else Q <= std_logic_vector ( unsigned ( Q ) + 1 ); end if ; end if ; end process ;エンドアーキテクチャRTL ;より複雑なカウンタでは、rising_edge(CLK) elsifカウントの有効化、特定のカウント値での停止またはオーバーフロー、端末カウント信号などの出力信号の生成といった他の機能を追加するために、if/then/else文を追加することができます。このような制御を併用する場合は、必要な優先順位を設定し、必要な論理レベルの数を最小限に抑えるために、順序とネスト構造に注意する必要があります。
VHDLの大部分はハードウェアに変換できません。このサブセットは、VHDLの非合成サブセットまたはシミュレーション専用サブセットとして知られており、プロトタイピング、シミュレーション、デバッグにのみ使用できます。たとえば、次のコードは周波数50MHzのクロックを生成します 。これは、たとえばシミュレーション中に設計のクロック入力を駆動するために使用できます。ただし、これはシミュレーション専用の構造であり、ハードウェアに実装することはできません。実際のハードウェアでは、クロックは外部で生成され、ユーザーロジックまたは専用ハードウェアによって内部的に縮小できます。
プロセス開始CLK <= ' 1' ; 10 NS待機; CLK <= ' 0' ; 10 NS待機;プロセス終了;シミュレーションのみで構築された構造を用いることで、非常に短時間で複雑な波形を生成することが可能です。このような波形は、例えば、複雑な設計のテストベクトルとして、あるいは将来実装されるシンセサイザロジックのプロトタイプとして利用できます。
プロセス開始START = '1'まで待機; -- START がハイになるまで待機for i in 1 to 10 loop -- その後、数クロック周期待機... CLKが上昇エッジになるまで待機; end loop ;for i in 1 to 10 loop -- 1から10までの数値をDATAに書き込み、サイクルごとに1ずつ書き込むDATA <= to_unsigned ( i , 8 ); wait until rising_edge ( CLK ); end loop ;-- 出力が変わるまで待機RESULTで待機; -- クロック周期の間 ACK を発生させるACK <= '1' ; rising_edge ( CLK ); ACK <= '0'まで待機;-- 以下同様...処理終了;library ieee ; use ieee.std_logic_1164. all ;entity bfm is end entity ; architecture beh of bfm is signal en : std_logic ; begin -- ここに実装を挿入end architecture ;// ------------------------------------------ library ieee ; use ieee.std_logic_1164. all ;エンティティtest1は終了エンティティです。test1のアーキテクチャbehは開始です。ibfm : entity work . bfm ; -- テストベンチ プロセスプロセスエイリアスprobe_enは<< signal . test1 . ibfm . en : std_logic >>です。begin probe_en <= '1' ; wait for 100 ns ; probe_en <= '0' ; wait for 100 ns ; probe_en <= '1' ; wait for 100 ns ; std.env . stop ( 0 ); end process ; end architecture ;標準パッケージとも呼ばれます。
IEEE標準パッケージには以下が含まれます。[ 19 ]
コマーシャル:
他の: