VHDLの書き方 初級編|entity・architectureの構造と記述のポイントをコード例で解説
FPGAを使った開発に取り組み始めると、必ず最初にぶつかるのがHDL(ハードウェア記述言語)の記述です。中でもVHDLは、厳密な文法と型のルールをもつ言語であるため、C言語などのソフトウェア開発に慣れている方ほど、記述の作法が独特に感じられて戸惑いやすい傾向があります。
この記事では、VHDLの土台となるentityとarchitectureという構造の考え方から、process文による順次処理の記述、同期回路の書き方までを、実際のコード例を交えながら整理します。細かな文法をすべて暗記することよりも、記述した内容がどのような回路になるのかをイメージできるようになることを目的として読み進めていただければと思います。
▶ 関連コラム:VHDLとは?FPGA設計における特徴とVerilogとの違いをわかりやすく解説
VHDLはプログラムではなく回路を記述する言語
VHDLを学ぶうえで最初に切り替えなければならないのが、記述が上から順番に実行されるわけではないという感覚です。ソフトウェアのソースコードは、書かれた命令が一つずつ順を追って処理されていきますが、VHDLで記述したものは、合成を経てFPGA内部の実際の回路になります。回路は電源が入っているあいだ常にすべてが同時に存在し、同時に動き続けます。
そのため、architectureの中に並べて書いた複数の代入文は、上に書いたものが先に実行されるのではなく、すべてが並行して動作する別々の回路として構成されます。この違いを理解しないまま記述を進めると、シミュレーションでは動いているように見えても、実機に載せた途端に想定と異なる挙動になるという事態が起こりがちです。VHDLの学習は、文法を覚える作業であると同時に、記述と回路構造を頭の中で結びつける訓練でもあります。
VHDLの基本構造は宣言・entity・architectureの三層で成り立つ
VHDLのソースファイルは、大きく分けて、使用するライブラリの宣言、回路の外部インターフェースを定めるentity、そして内部の動作を記述するarchitectureという三つの部分で構成されます。どのような規模の設計であっても、この骨格は変わりません。
ライブラリとパッケージの宣言
ファイルの先頭では、使用する型や関数が定義されたライブラリを読み込みます。ほとんどの設計では、次の三行が基本形になります。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
STD_LOGIC_1164は、ハードウェアの信号線を表現するstd_logic型やstd_logic_vector型を提供するパッケージです。NUMERIC_STDは、信号を数値として扱って加算や比較を行うためのsignedおよびunsigned型を提供します。古い資料ではSTD_LOGIC_ARITHやSTD_LOGIC_UNSIGNEDを使った例を見かけることがありますが、これらはIEEEの標準として定められたものではないため、新規に起こす設計ではNUMERIC_STDに統一しておくほうが、後々の移植性や保守性の面で安全です。
entityは回路の外部インターフェースを定める
entityは、その回路がどのような入出力をもつのかを宣言する部分です。基板設計でいえば、ICのピン配置に相当する情報がここに集約されます。
entity counter is
port (
CLK : in std_logic;
RST_N : in std_logic;
EN : in std_logic;
Q : out std_logic_vector(7 downto 0)
);
end counter;
portの宣言では、信号の名前、方向、型を指定します。方向にはinとoutのほか、双方向バスに使うinoutなどがあります。ここで定義した信号名と幅は、上位階層から接続するときの窓口となり、複数人で分担して設計を進める際には事実上のインターフェース仕様書としても機能します。名前の付け方やアクティブレベルの表現をプロジェクト内で統一しておくと、後から読む人の負担が大きく変わります。
architectureは回路の中身を記述する
architectureは、entityで宣言した入出力のあいだで、どのような処理が行われるのかを記述する部分です。begin以前が宣言部、begin以降が本体にあたります。
architecture RTL of counter is
signal cnt : unsigned(7 downto 0);
begin
-- ここに回路の動作を記述する
end RTL;
宣言部で定義したsignalは、回路の内部配線に相当します。entityのportが外部に出るピンであるのに対し、signalはブロック内部で信号を受け渡すための線という位置づけです。上の例ではカウンタの値を数値として扱いたいため、内部信号をunsigned型で宣言しています。出力ポートはstd_logic_vector型なので、最終的に型変換を行ってから接続することになります。
並行処理記述と順次処理記述の違いを押さえる
architectureの本体に直接書かれた代入文は、すべて並行処理記述として扱われます。記述の順序に関係なく、それぞれが独立した回路として同時に動作するため、記述の並び替えによって動作が変わることはありません。組み合わせ回路の単純な接続や、信号の別名付けのような処理は、この形で書くのが簡潔です。
一方、条件分岐が入り組んだ処理や、クロックに同期して値を保持する処理は、process文の中に記述します。process文の内部は順次処理記述として解釈され、記述された順に評価されます。ただし、これは命令が順番に実行されるという意味ではありません。後に書かれた代入が優先される構造の回路が合成されるという意味であり、あくまで結果として一つの回路にまとめられます。この点を取り違えると、意図しない優先順位の回路ができあがってしまいます。
同期回路はprocess文とクロックエッジで記述する
実際のFPGA設計では、大半の回路がクロックに同期して動作する同期回路として構成されます。VHDLでは、次のような形で記述するのが定型です。
process (CLK, RST_N)
begin
if RST_N = '0' then
cnt <= (others => '0');
elsif rising_edge(CLK) then
if EN = '1' then
cnt <= cnt + 1;
end if;
end if;
end process;
processの直後の括弧内はセンシティビティリストと呼ばれ、この中に並べた信号が変化したときにprocessが評価されます。上の例では非同期リセットを使っているため、クロックとリセットの両方を記載しています。センシティビティリストに必要な信号を書き漏らすと、シミュレーション上の動作と、合成された実回路の動作が食い違うという厄介な不具合につながります。合成ツールはセンシティビティリストを無視して回路を作るのに対し、シミュレータはリストに従って評価するためです。
なお、出力ポートへ値を渡す際には、内部で使っていたunsigned型からstd_logic_vector型への変換が必要になります。
Q <= std_logic_vector(cnt);
この一行を書かなければならないところに、VHDLの性格がよく表れています。ビット列としては同じものを扱っていても、数値として扱う型と信号線として扱う型は別物であると言語が定めているため、変換を明示しない限りコンパイルが通りません。
型の厳密さは記述の手間と引き換えに間違いを減らす
VHDLは、型の扱いが厳格な言語です。ビット幅の異なる信号をそのまま代入することはできませんし、異なる型どうしの演算も許されません。慣れないうちは、変換関数を挟む記述が煩わしく感じられるかもしれません。
しかしこの厳密さは、設計の誤りを早い段階で検出できるという大きな利点をもたらします。ビット幅の取り違えや、符号の有無の勘違いといった間違いは、回路として動かしてみるまで気づきにくく、実機でのデバッグに入ってから発覚すると原因の特定に長い時間を要します。VHDLはこうした誤りの多くをコンパイルの時点で弾いてくれるため、規模が大きく、長期にわたって保守される設計ほど、型の厳密さが効いてきます。航空宇宙や医療、産業機器といった、高い信頼性が求められる分野でVHDLが選ばれ続けてきた背景には、こうした言語としての性格があります。
▶ より詳しい実装のポイント:FPGA設計のポイント
文法よりも、どのような回路になるかを思い描けるかが重要
VHDLの文法そのものは、集中して学べば数週間で一通り書けるようになります。難しいのはその先で、同じ動作をする回路であっても、記述の仕方によって使用するリソースの量や動作可能な周波数が変わってくるという点です。
たとえば、条件分岐を深く重ねた記述は、そのまま多段の選択回路として合成されるため、信号が通過する経路が長くなり、動作周波数の上限を下げてしまうことがあります。また、条件を書き漏らしたことで意図せずラッチが生成され、タイミング解析が正しく行えなくなるといった問題も、初学者が陥りやすい典型例です。演算器を共通化するか並列に持つかという判断も、リソースと性能のどちらを優先するかによって答えが変わります。
こうした判断は、文法書を読むだけでは身につかず、合成結果のレポートを確認し、タイミング解析の結果と照らし合わせながら記述を見直す経験の積み重ねによって養われていきます。VHDLを書けることと、FPGAで動く回路を設計できることのあいだには、この経験の差があります。
▶ 関連コラム:VHDLによるFPGA設計の進め方|仕様検討からシミュレーション・論理合成・実機検証までの流れ
VHDLによるFPGA設計のご相談はアイディアイへ
VHDLの記述には着手できたものの、思うような性能が出ない、タイミング制約が収束しない、規模が大きくなるにつれて検証が追いつかなくなってきた。FPGA設計の現場では、こうした段階でつまずくケースが少なくありません。
▶ サービス紹介:VHDLによるFPGAボード 開発サービス
アイディアイは、FPGAの論理設計を長年にわたって手がけてきた設計会社です。VHDLとVerilogのどちらにも対応しており、記述の作成だけでなく、シミュレーションによる検証、タイミング制約の設定、実機での動作確認までを一貫してお引き受けできます。さらに、FPGAを搭載する基板の設計やファームウェアの開発、装置としての組み立てまで社内で対応できる体制を備えているため、論理設計と基板のどちらに原因があるのか切り分けが難しいような場面でも、工程をまたいだ調整に手間を取られることなく前に進められます。
FPGA設計でお悩みの皆様、構想段階のご相談からで構いませんので、ぜひお気軽に当社までお問い合わせください。お客様の課題に合わせた最適なご提案をさせていただきます。
▶ サービス紹介:FPGA設計開発 代行サービス
技術情報・技術コラム

- 機能・性能試験装置
試験装置は一から作るべき?市販の計測器を活かした試験装置・試験治具という選択肢
当コラムでは、試験装置を一から作るか市販の計測器を活かすかという判断のポイントから、汎用計測器だけでは試験が回らない理由、計測ラインの切り替え素子の選定や高速信号の切り替え、制御とロギングによる自動化、段取り替え・保守を見据えた設計ノウハウ、他社製の既存試験装置を改造するという選択肢までを解説します。

- 組み込みボード
VHDLによるFPGA設計の進め方|仕様検討からシミュレーション・論理合成・実機検証までの流れ
当コラムでは、VHDLを用いたFPGA設計がどのような流れで進むのかを、仕様の整理とアーキテクチャ検討、RTL記述、シミュレーションによる機能検証、論理合成、配置配線とタイミング制約、実機での動作確認という工程ごとに整理し、各工程で検討すべきことやつまずきやすいポイント、内製化の壁となるスキルの違いまでを分かりやすく解説します。

- 組み込みボード
VHDLの書き方 初級編|entity・architectureの構造と記述のポイントをコード例で解説
当コラムでは、VHDLの基本構造であるライブラリ宣言・entity・architectureの考え方から、並行処理記述と順次処理記述の違い、process文とクロックエッジによる同期回路の書き方、型の厳密さがもたらす利点までを、カウンタ回路のコード例を交えて解説し、記述がどのような回路になるかを思い描くためのポイントを整理します。

- 組み込みボード
FPGA開発の費用と期間はどう決まる?委託前に知っておきたいコスト構造
当コラムでは、電子部品の生産終了(ディスコン)やASICの再製造コスト高騰が引き起こす製品の供給停止リスクを踏まえ、柔軟な回路再構築が可能な「FPGA」への置き換えのメリットと実践ポイントについて、異メーカー間での移植や複数ロジックICの集約、資料不足時のリバースエンジニアリングからタイミング・電圧の注意点まで、製品の安定供給や信頼性向上につながる具体的な設計手法と進め方を分かりやすく解説します 。

- 組み込みボード
VHDLとは?FPGA設計における特徴とVerilogとの違いをわかりやすく解説
当コラムでは、電子部品の生産終了(ディスコン)やASICの再製造コスト高騰が引き起こす製品の供給停止リスクを踏まえ、柔軟な回路再構築が可能な「FPGA」への置き換えのメリットと実践ポイントについて、異メーカー間での移植や複数ロジックICの集約、資料不足時のリバースエンジニアリングからタイミング・電圧の注意点まで、製品の安定供給や信頼性向上につながる具体的な設計手法と進め方を分かりやすく解説します 。

- 組み込みボード
ディスコン部品・ASICの置き換えにFPGAを活用する設計手法と進め方
当コラムでは、電子部品の生産終了(ディスコン)やASICの再製造コスト高騰が引き起こす製品の供給停止リスクを踏まえ、柔軟な回路再構築が可能な「FPGA」への置き換えのメリットと実践ポイントについて、異メーカー間での移植や複数ロジックICの集約、資料不足時のリバースエンジニアリングからタイミング・電圧の注意点まで、製品の安定供給や信頼性向上につながる具体的な設計手法と進め方を分かりやすく解説します 。

- 組み込みボード
FPGA設計を外注すべきか?内製との比較と、委託先選びで失敗しないためのポイント
当コラムでは、電子部品の生産終了(ディスコン)やASICの再製造コスト高騰が引き起こす製品の供給停止リスクを踏まえ、柔軟な回路再構築が可能な「FPGA」への置き換えのメリットと実践ポイントについて、異メーカー間での移植や複数ロジックICの集約、資料不足時のリバースエンジニアリングからタイミング・電圧の注意点まで、製品の安定供給や信頼性向上につながる具体的な設計手法と進め方を分かりやすく解説します 。

- 組み込みボード
内部配線を排除する「マザーボード型」Raspberry Pi用拡張ボードの設計手法
当コラムでは、HATのスタック構造が引き起こす厚みの増大・排熱問題・耐振動性の低下といった物理的な限界を踏まえ、Raspberry Piをコンポーネントの一部として1枚の基板に集約する「マザーボード型」設計手法のメリットと実践ポイントについて、内部配線の排除から電源回路の統合・PoE対応まで、製品の小型化・メンテナンス性向上につながる具体的な設計手法を分かりやすく解説します。

- 組み込みボード
古い機械を「スマート化」する。既存設備に後付け可能な、レガシーI/F対応のラズパイHAT開発
当コラムでは、RS-232CやRS-485・4-20mA電流ループ・アナログ信号といった現代のIoTを阻む「レガシーの壁」を踏まえ、Raspberry Pi用の専用拡張ボードを活用して古い産業機器をネットワーク化する「レトロフィット」設計手法のメリットと実践ポイントについて、信号レベル変換とフォトカプラによる絶縁から既存プロトコルのエッジ処理・複数規格の統合まで、過酷な現場でも止まらない設備延命とDX推進につながる具体的な設計アプローチを分かりやすく解説します。

- 組み込みボード
Raspberry Piを「試作」で終わらせない。製品化に不可欠な専用HAT(拡張ボード)開発の進め方
当コラムでは、Raspberry Piを試作どまりで終わらせず製品化・量産化につなげるために、なぜ市販のHATではなく専用カスタム拡張ボードが必要なのかを解説します。供給不安・過剰コスト・信頼性不足という市販HATの3つのリスクから、機能集約による小型化・コスト最適化・品質安定化のメリット、さらに製品寿命を延ばすための回路設計ポイントまで、製品開発の実情に沿って分かりやすく紹介します。


