FPGA組み込み設計の実践ガイド:実装からビットストリーム書き込みまで
より強力なFPGAと効果的なプログラミング環境の登場により、FPGA実装は広くアクセス可能になりましたが、FPGAの使用は依然として困難に見えるかもしれません。

編集部注:スマート製品設計向けの高度なアルゴリズムが登場し続ける中、開発者はこれらのアルゴリズムに関連する処理要求を満たす組み込みシステムの実装に苦労することがよくあります。FPGAは必要な性能を提供できますが、FPGA設計は長らくFPGAプログラミング専門家の領域と見なされてきました。しかし今日、より強力なFPGAとより効果的な開発環境の利用により、FPGA開発は広くアクセス可能になっています。この抜粋では、『Architecting High-Performance Embedded Systems』の第4章から、FPGAデバイス、実装言語、FPGA開発プロセスの包括的なレビューと、独自設計へのFPGA実装を開始する方法の詳細なウォークスルーを提供します。完全な抜粋は以下の連載で提示されます: 1: ハードウェアリソース
2: 実装言語
3: 開発プロセス
4: プロジェクト構築
5: 実装(この記事)
『Architecting High-Performance Embedded Systems』(Jim Ledin著)から抜粋・翻訳。
ロジック動作のテスト
FPGA内でロジックを実行する前に、シミュレーションを使用してロジックの動作をテストすることが重要です。シミュレーション環境では問題の検出と修正が、FPGA内で実行中のロジックよりもはるかに容易だからです。Vivadoシミュレーションツールは回路動作を非常に良く表現します:
- Sources サブウィンドウで Simulation Sources を右クリックし、Add Sources… を選択:

図 4.18 – Simulation Sources の Add Sources… メニュー選択
- Add Sources ダイアログで Add or create simulation sources が選択されていることを確認し、Next をクリック。
- Add or Create Simulation Sources ダイアログで Create File をクリック。
- ファイル名に vhdl と入力し、OK をクリック。
- Finish をクリックして Add or Create Simulation Sources ダイアログを閉じ、Define Module ダイアログで OK をクリックし、確認ダイアログで Yes をクリック。
- Simulation Sources の下にある Adder4 TestBench (Behavioral) (Adder4TestBench.vhdl) をダブルクリック。vhdl エディタウィンドウの自動生成された内容を削除し、以下のコードを Adder4TestBench.vhdl エディタに入力:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity ADDER4_TESTBENCH is end entity ADDER4_TESTBENCH; architecture BEHAVIORAL of ADDER4_TESTBENCH is component ADDER4 is port ( A4 : in std_logic_vector(3 downto 0); B4 : in std_logic_vector(3 downto 0); SUM4 : out std_logic_vector(3 downto 0); C_OUT4 : out std_logic ); end component; signal a : std_logic_vector(3 downto 0); signal b : std_logic_vector(3 downto 0); signal s : std_logic_vector(3 downto 0); signal c_out : std_logic; signal expected_sum5: unsigned(4 downto 0); signal expected_sum4: unsigned(3 downto 0); signal expected_c : std_logic; signal error : std_logic; begin TESTED_DEVICE: ADDER4 port map ( A4 => a, B4 => b, SUM4 => s, C_OUT4 => c_out ); TEST: process begin -- 2つの4ビット加数の全組み合わせをテスト(計256テスト) for a_val in 0 to 15 loop for b_val in 0 to 15 loop -- ADDER4コンポーネントの入力を設定 a <= std_logic_vector(to_unsigned(a_val, a'length)); b <= std_logic_vector(to_unsigned(b_val, b'length)); wait for 1 ns; -- 2つの4ビット値の5ビット和を計算 expected_sum5 <= unsigned('0' & a) + unsigned('0' & b); wait for 1 ns; -- 和を4ビット出力とキャリービットに分解 expected_sum4 <= expected_sum5(3 downto 0); expected_c <= expected_sum5(4); wait for 1 ns; -- 'error' 信号はエラー発生時のみ 1 になる if ((unsigned(s) = unsigned(expected_sum4)) and (c_out = expected_c)) then error <= '0'; else error <= '1'; end if; -- 内側ループの各パスは 10 ns かかる wait for 7 ns; end loop; end loop; wait; end process TEST; end architecture BEHAVIORAL;
このコードは、A4 と B4 入力に 4 ビット数の全組み合わせを提示することで、4 ビット加算器の機能を検証します。Adder4 コンポーネントの SUM4 と C_OUT4 出力を、同じ入力に対する独立計算値と比較します。各加算演算後、出力が期待値と一致すれば error 信号を 0 に、不一致なら 1 に設定します。
Adder4TestBench.vhdl のコードは、ネストした for ループを使用してテスト入力の全組み合わせを Adder4 コンポーネントに適用する点で、従来のソフトウェアコードに似ています。シミュレーションモードで実行されるテストコードは合成不能であり、純粋なハードウェアロジック回路を表さず、for ループの反復実行のような従来のソフトウェア的操作が可能です。
しかし、物理回路と同様に、テストベンチコードで <= 演算子を使って信号に値を割り当てた場合、その瞬時において後続の式でその信号を使用することはできません。これはシミュレーション環境が、微小な FPGA デバイス内であっても現実世界の伝播遅延の影響を表現するためです。テストベンチコード内の 3 つの wait for 1 ns; 文は、直前の wait 文で計算された信号値が伝播し、後続の文で使用可能になるまでの時間を与えます。内側ループの最後の wait for 7 ns; 文は、シグナルトレース表示でシミュレーションループの各反復結果を明確に見るためのポーズです。
- Simulation Sources の下にある Adder4 TestBench (Behavioral) (Adder4TestBench.vhdl) を右クリックし、Automatic Update and Compile Order を選択。これにより ADDER4_TESTBENCH がシミュレーション実行のトップレベルオブジェクトに設定されます:

図 4.19 – Automatic Update and Compile Order 設定メニュー
- Run Simulation をクリックし、Flow Navigator ウィンドウで Run Behavioral Simulation を選択してシミュレーションモードに入る。エディタファイルが未保存の場合は保存を促されるので Save をクリック。シミュレーションが実行されます:

図 4.20 – Run Behavioral Simulation メニュー選択
- SIMULATION ウィンドウが開いたら、タイトル Untitled 1 のシミュレーション出力ウィンドウの最大化ボタンをクリック:

図 4.21 – シミュレーション結果ウィンドウ
内側ループの 1 パスあたりの総シミュレーション時間は 10 ns です。Adder4TestBench.vhdl には 256 パスがあるため、シミュレーション実行時間は 2560 ns となります。
- トップツールバーのシミュレーション実行時間を 2560 ns に設定(以下の図の ステップ 1)、左向きの再起動ボタンを押す(ステップ 2)、右向きの実行ボタンを押して 2560 ns 間シミュレーションを実行(ステップ 3)、最後に Zoom Fit ボタンを押して(ステップ 4)シミュレーション出力データ範囲をウィンドウにフィットさせる:

図 4.22 – 実行開始から終了までのシミュレーション結果
虫眼鏡アイコンでトレースの任意のポイントを拡大し、テスト中に実行された各加算演算の結果を観察できます。例えば、次の図は 10 進数の 6 と 2 が加算され、結果 8、キャリー 0 が生成されたことを示します。これらの値は期待値と一致し、error は 0 に設定されました。error 信号はすべての 256 テストケースで 0 であり、ロジック回路がすべてのテストをパスしたことを示します:

図 4.23 – シミュレーション結果の拡大ビュー
- データトレース上部の青い SIMULATIONバーの X をクリックしてシミュレーションモードを閉じる。閉じるか確認されたら OK をクリック。
行動テストをパスしたので、設計で使用する I/O 信号を定義します。
I/O 信号の定義
次のステップは、回路の入出力を Arty ボード上のハードウェアデバイスに接続することです。入力はボードのスイッチとプッシュボタン、出力は LED となります。
以下の手順で、FPGA デバイス上で使用する I/O ピンと、Arty ボード上でそれらのピンに接続される機能を記述する制約ファイルを作成します。制約ファイルの拡張子は xdc です:
- Sources サブウィンドウで Constraints を右クリックし、Add Sources… を選択。
- Add Sources ダイアログで Add or create constraints が選択されていることを確認し、Next をクリック。
- Add or Create Constraints ダイアログで Create File をクリック。
- ファイル名に Arty-A7-100.xdc (またはデバイスに適した Arty-A7-35.xdc)と入力し、OK をクリック。
- Finish をクリックして Add or Create Constraints を閉じる。
- Constraints ソースツリーを展開し、Arty-A7-35.xdc をダブルクリック。
- Digilent は Arty A7 ボード用の事前入力済み制約ファイルを提供しています。https://raw.githubusercontent.com/Digilent/digilent-xdc/master/Arty-A7-35-Master.xdc にアクセスし、ブラウザウィンドウの全内容を Vivado の Arty-A7-35.xdc エディタウィンドウにコピーします。デバイスに応じて https://raw.githubusercontent.com/Digilent/digilent-xdc/master/Arty-A7-100-Master.xdc を使用してください。
- 制約ファイル内のすべての I/O ピンは # 文字でコメントアウトされています。使用するピンの行頭の # を削除してアンコメントします。以下のセクションで Arty-A7-100.xdc ファイルに記載されるピンを使用します: Switches、RGB LEDs(ただし最初の緑色 LED のみ led0_g)、LEDs、Buttons。以下の図はこれらの行をアンコメントした後の様子です:

図 4.24 – 制約エディタウィンドウ
次のセクションでは、加算器コードを I/O デバイスと接続するトップレベル VHDL ファイルを作成します。
トップレベル VHDL ファイルの作成
4 ビット加算器コンポーネントをボード I/O 信号に接続するトップレベル VHDL ファイルを作成します:
- Sources サブウィンドウで Design Sources を右クリックし、Add Sources… を選択。
- Add Sources ダイアログで Add or create design sources が選択されていることを確認し、Next をクリック。
- Add or Create Design Sources ダイアログで Create File をクリック。
- ファイル名に vhdl と入力し、OK をクリック。
- Finish をクリックして Add or Create Design Sources ダイアログを閉じ、Define Module ダイアログで OK をクリックし、確認ダイアログで Yes をクリック。
- Design Sources の下にある vhdl をダブルクリック。ArtyAdder.vhdl エディタウィンドウの自動生成された内容を削除し、以下のコードを ArtyAdder.vhdl エディタに入力:
-- 標準ライブラリの読み込み library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity ARTY_ADDER is port ( sw : in STD_LOGIC_VECTOR (3 downto 0); btn : in STD_LOGIC_VECTOR (3 downto 0); led : out STD_LOGIC_VECTOR (3 downto 0); led0_g : out STD_LOGIC ); end entity ARTY_ADDER; architecture BEHAVIORAL of ARTY_ADDER is -- 以前に定義した 4 ビット加算器コンポーネントを参照 component ADDER4 is port ( A4 : in std_logic_vector(3 downto 0); B4 : in std_logic_vector(3 downto 0); SUM4 : out std_logic_vector(3 downto 0); C_OUT4 : out std_logic ); end component; begin ADDER : ADDER4 port map ( A4 => sw, B4 => btn, SUM4 => led, C_OUT4 => led0_g ); end architecture BEHAVIORAL;
このコードは、Arty-A7-100.xdc で命名された I/O デバイスの信号名 sw(4 スイッチ)、btn(4 プッシュボタン)、led(4 単色 LED)、led0_g(最初のマルチカラー LED の緑チャネル)を ADDER4 の入出力にマッピングします。
VHDL は大文字小文字を区別しませんが、Vivado での xdc 制約ファイルの処理は大文字小文字を区別します。xdc ファイルで定義された I/O デバイス名のケースは、VHDL ファイルで参照する際に完全に一致する必要があります。具体的には、このファイルでは制約ファイルで小文字であるため、VHDL の I/O 信号名も小文字にする必要があります。
これで設計の合成、実装、Arty ボードへのプログラミングの準備が整いました。
FPGA ビットストリームの合成と実装
あるいは、Generate Bitstream を選択すれば、Vivado が合成、実装、ビットストリーム生成の必要なすべてのステップをユーザー介入なしで実行します。致命的エラーが発生した場合、プロセスは停止しエラーメッセージが表示されます。ビットストリーム生成の手順は以下の通り:
- Generate Bitstream をクリックしてビルド開始。テキストエディタの保存を促されたら Save。実装結果がなく合成と実装を起動してよいか聞かれたら Yes をクリック:

図 4.25 – Generate Bitstream メニュー選択
- Launch Runs ダイアログが表示されます。Number of jobs にコンピュータのプロセッサコア数までの値を選択可能。コアを多く使うと高速化しますが、長時間のビルド中にマシンを使い続けたい場合はボトルネックになる可能性があります。OK をクリックしてビルド開始:

図 4.26 – Launch Runs ダイアログ
- ビルドプロセス中、Vivado はメインウィンドウの右上隅にステータスを表示。必要に応じて、ステータス表示横の Cancel をクリックしてビルドを中断可能:

図 4.27 – コンパイルステータス表示
- ビルドプロセス完了時(致命的エラーがないと仮定)、Bitstream Generation Completed ダイアログが表示。他のオプションも提示されますが、ここでは直接 Arty ボードへのビットストリームダウンロードに進みます。Open Hardware Manager を選択し OK をクリック:

図 4.28 – Bitstream Generation Completed ダイアログ
次に、ビットストリームを FPGA にダウンロードします。
ビットストリームのボードへのダウンロード
Arty A7 ボードへのビットストリームダウンロード手順:
- HARDWARE MANAGER ダイアログが表示され、No hardware target is open と示されます。
- Arty A7-35 または A7-100 ボードを USB でコンピュータに接続。数秒待ってボードが認識されたら、Open target、次に Auto Connect をクリック:

図 4.29 – Open target と Auto Connect 選択
- 数秒後、Vivado がボード接続を示す。Program device をクリックして FPGA ビットストリームを Arty にダウンロード。ビットストリームファイルの選択を促される。この例と同じディレクトリ構造を使用している場合、ファイルは C:/Projects/ArtyAdder/ArtyAdder.runs/impl_1/ARTY_ADDER.bit にあります:

図 4.30 – Program Device ダイアログ
- Program をクリックしてプログラムを FPGA デバイスにダウンロードし、起動
- Arty I/O でプログラムの動作をテスト可能。4 つのスイッチをすべて off 位置(隣接するボードエッジ側に移動)にし、4 つのプッシュボタンを押さない。4 つの緑色 LED がすべて消灯するはず。
- 任意のスイッチをオンにするか、任意のプッシュボタンを押すと、対応する緑色 LED が点灯。スイッチの任意の組み合わせをオンにしながら任意の数のプッシュボタンを押すと、対応する 4 ビット数が加算され、LED に結果が表示される。キャリーが発生する場合(例:SW3 をオンにし BTN3 を同時に押す)、緑色のキャリー LED が点灯。
ここで実行したプログラミングプロセスはプログラムを FPGA RAM に格納します。FPGA ボードの電源をサイクルすると、プログラムを再ロードするためにプログラミングプロセスを繰り返す必要があります。あるいは、次のセクションで説明するように、FPGA コンフィギュレーションファイルをオンボードフラッシュメモリに格納できます。
ビットストリームのオンボードフラッシュメモリへの書き込み
Arty ボードに電源が投入されるたびに FPGA を構成するには、FPGA コンフィギュレーションファイルをボード上のフラッシュメモリに格納する必要があります。MODE ジャンパが装着されている場合、FPGA は電源投入時にオンボードフラッシュメモリからコンフィギュレーションファイルのダウンロードを試みます。このメモリは Artix-7 FPGA に隣接する別チップにあります。フラッシュメモリへのプログラミング手順:
- Arty ボードに MODE ジャンパが装着されていなければ装着
- Generate Bitstream を右クリックし、Bitstream Settings… を選択。
- Settings ダイアログで -bin_file の横のチェックボックスをオンにし OK をクリック:

図 4.31 – Bitstream settings ダイアログ
- メイン Vivado ダイアログで Generate Bitstream をクリックし、ビットストリーム生成プロセスを繰り返す。Bitstream Generation Completed ダイアログが出たら Cancel をクリック
- Hardware ダイアログで FPGA 部品番号(xc7a100t_0)を右クリックし、Add Configuration Memory Device… を選択:

図 4.32 – Add Configuration Memory Device… メニュー選択
- Search に s25fl127 と入力。一致する部品番号が 1 つ表示されるので選択し OK をクリック:

図 4.33 – Add Configuration Memory Device ダイアログ
- Do you want to program the configuration memory device now? と尋ねられるので OK をクリック。
- Program Configuration Memory Device ダイアログでコンフィギュレーションファイル名を要求される。Configuration file 右の … ボタンをクリックし、C:/Projects/ArtyAdder/ArtyAdder.runs/impl_1/ARTY_ADDER.bin を選択し OK をクリック:

図 4.34 – Program Configuration Memory Device ダイアログ
- プログラミングプロセスには数秒かかります。ファイルがボードフラッシュメモリにプログラミングされると成功メッセージが表示されます:

図 4.35 – Program Flash complete ダイアログ
これで、ボード電源をサイクルするたびに 4 ビット加算器プログラムがロードされ実行されます。ただし、今回使用したコンフィギュレーションファイル読み込み設定では、プログラムのロードに長時間かかります。待ち時間を避けるには、以下の手順でコンフィギュレーションファイル読み込み速度を改善できます:
- Flow Navigator で Open Synthesized Design を選択。
- Vivado メインメニューで Tools/Edit Device Properties… を選択。
- General タブで Enable Bitstream Compression を TRUE に設定。
- Configuration タブで Configuration Rate (MHz) を 33 に設定し OK をクリック。
- 再度ビットストリームを生成し、前述の手順でフラッシュメモリをプログラミング。コンフィギュレーションメモリデバイスを削除して再追加し、再プログラミングオプションを表示させる必要があります。
- Hardware Manager を閉じる。
- Arty ボードの USB ケーブルを抜き、再度挿入。プログラムが電源投入とほぼ同時に実行開始するはず。
このセクションでは、FPGA I/O ピン上の信号と相互作用する単純な組み合わせロジックの例を示しました。ここでの意図は、Vivado ツールスイートに慣れ、ツールを使用して完全な FPGA 開発サイクルを実行する方法を示すことです。
まとめ
この章は、リアルタイム組み込みシステムアーキテクチャにおける FPGA の効果的な活用についての議論で始まり、標準的な FPGA デバイスとそれらに含まれる低レベルコンポーネントの説明に続きました。HDL、ブロック図手法、C/C++ などの一般的なソフトウェアプログラミング言語を含む FPGA 設計言語の範囲を紹介。FPGA 開発プロセスの概要を提示し、要件声明から始まり、低コスト FPGA 開発ボード上で機能するシステムの実装で終わる、FPGA 開発サイクルの完全な例で締めくくられました。
この章を完了すると、FPGA がリアルタイム組み込みシステムアーキテクチャでどのように効果的に適用できるかを理解し、FPGA 集積回路内のコンポーネントを把握できます。FPGA アルゴリズム設計に使用されるプログラミング言語、FPGA 開発サイクルのステップ、FPGA 開発プロセスの手順の順序を理解できます。
次の章では、FPGA 開発プロセスを拡張し、FPGA を含むリアルタイム組み込みシステムのアーキテクチャへの完全なアプローチを提供します。また、後の章の例として機能するプロトタイプ高性能組み込みシステム、デジタルオシロスコープの開発を開始します。
Packt Publishing の許可を得て再掲。Copyright © 2021 Packt Publishing

Jim Ledin氏は Ledin Engineering, Inc. の CEO。組み込みソフトウェアとハードウェアの設計、開発、テストのエキスパート。組み込みシステムのサイバーセキュリティ評価とペネトレーションテストにも精通。アイオワ州立大学航空宇宙工学学士、ジョージア工科大学電気・コンピュータ工学修士。カリフォルニア州登録プロフェッショナル電気技師、CISSP、CEH、CPT 資格保有。
関連コンテンツ:
- FPGA を用いた組み込み設計:ハードウェアリソース
- FPGA を用いた組み込み設計:実装言語
- FPGA を用いた組み込み設計:開発プロセス
- オープンソースツールで FPGA プログラミングを簡素化
- FPGA または ASIC で浮動小数点アルゴリズムを実装
- ディープラーニングに FPGA を活用
- AI アプリケーション向けに GPU コードを FPGA に移行するソフトウェアツール
Embedded の週刊メールニュースレターを購読して、さらに多くの情報を入手してください。
埋め込み
- ロウソククレヨンで3Dプリント部品を着色:新しい後処理技法
- ANSYSチーフテクノロジストインタビュー:シミュレーションで金属3Dプリンティング成功を導く
- 高度なアディティブ・マニュファクチャリング・ソフトウェアで生産を最大化
- 組み込みシステム設計:手順、原則、実世界での応用
- 組み込みAIでビッグデータを実用的なスマートインサイトに変換
- USB-Cをマスターする:高速データと電力のための設計課題と実践的ソリューション
- テクノロジーの未来を再構築する組み込み設計トレンド
- Foundries.io、プロセッサ非依存のLinux & ZephyrでIoTのRed Hatを目指す
- Clientron PST650:ホスピタリティ&小売向け統合サーマルプリンタ搭載オールインワンPOSターミナル
- MAXREFDES220# - 光学センサーによるカフレス血圧モニタリング
- FPGA実装言語: VHDLとVerilogからハイレベルC/C++まで