FPGAをC言語でプログラミングしてみました。
実際にXilinxのFPGAを使ってシリアル通信+GPIOの制御をしています。
ハードウェア・IPの構築方法から、簡単なテスト方法まで一連の流れを紹介します。
FPGAをC言語でプログラミングしてみた!Xilinx編
C言語でプログラムして、実際にFPGAのボードを動かしてみました。
FPGA内のハードウェアを構築する箇所から始めてみました。
C言語でテストできるソフトCPU(MicroBlaze)・IPの配線方法含めて説明します。
実際にXilinxの開発環境(Vitis)でLチカ+シリアル通信まで確認しています。
実際のテスト動画含めて紹介してますので、是非一緒にご覧ください。
XilinxのFPGAの評価ボードを使用
今回シリアル(UART)通信はFPGAとPC間で行います。
GPIOは評価ボードに実装済のLEDを利用します。
Xilinxのシリーズの中でもスペックの低いSpartan7の評価ボードでテストしています。
今回使った評価ボードに関しては下記記事で紹介しています。(リンク先はこちら)
USBシリアル通信ケーブルを使用
PCとFPGAの間のシリアル(UART)通信はUSBシリアル通信ケーブルを使用しています。
ボードにはTXD,RXDとGNDを接続している形となります。
FPGAの書き込みはJTAGケーブル
FPGAのプログラム書き込みはJTAGケーブルで行います。
「Vivado」同様に「Vitis」でも自動認識して、書き込むことが可能です。
※USB経由でFPGAに書き込める評価ボードならJTAGケーブルは必要ありません。
専用のJTAG-USBケーブルについては下記をご参考ください。(リンク先はこちら)
FPGAの開発環境を用意
C言語でプログラムするためにも、XilinxのFPGAのソフト開発環境(Vitis)を用意します。
本来VitisはOS,メモリなどにインストール要件があります。
但し、今回のテストレベルならば家庭用のノートPCでも十分に実施可能でした。
Vitisの簡単な使い方・インストールに関しては下記記事に記載しています。(リンク先はこちら)
MicroBlazeをVivadoで設定
最初にハードの開発環境「Vivado」の方でハードウェアの環境構築していきます。
Verilog・VHDLなどではなく、C言語でプログラムしたいので今回はMicroBlazeを使います。
※MicroBlaze…FPGA内部に(自由に)作れるソフトコアプロセッサ
今回記載している使い方は一例ですので、参考程度にお願いします。
あくまで趣味で簡単にテストできるブロック・コードを作成したレベルです。
ハードウェア全体像としては下記形です。
MicroBlazeのIPの使い方
Vivadoで「IP INTEGRATOR」→「Create Block Design」を選択します。
FPGAのハードウェアのブロック設計を行います。
「Diagram」の画面が出たら「+」をクリックするとIPを検索・選択できます。
「MicroBlaze」を選択すれば、IPを置くことが可能です。
MicroBlazeのIPを置くと、上に「Run Block Automation」が出てきますので選択します。
細かい設定を確認されますが、そのままOKを進めてもらっても構いません。
あえて言うと「Local Memory」を32KBぐらいに増やしておいた方が良いとは思います。
デフォルトは8KBです。
シリアル通信などの機能を増やしていくと、後々容量が足りない場合がありました。
ソフトCPUを使う上でのリセット・RAM・デバッガなどを自動的に配置されます。
リセットの「ext_reset_in」に関しては、PLLの「locked」の信号と繋げておきます。
PLLは入力をシングルエンドに変更
PLLも自動で作成されますが、差動入力となっているのでシングルエンド入力としています。
また今回は楽してPLLの入力リセット信号も省略します。
クロック100MHzの入力ポート含めて作成すると下記形となっています。
PLLの設定方法に関しては下記記事でも紹介していますので、一緒にご確認下さい。
FPGAのPLLの使い方!ロック信号と一緒にクロック出力してみた
GPIO・IIC・UARTのIPを設定
IPの検索でGPIO,IIC,UARTと検索して各IFのIPが出てきます。今回は3つとも配置します。
※周辺のポート・配線に関しては後ほど自動配置しますので、今は設定しなくて大丈夫です。
FPGA内のAXIバスを接続
MicroBlazeと各IFをAXIバスで接続します。
「Run Connection Automation」を選択して、各IFとポートにチェックを入れます。
自動接続でペリフェラル・ポート含めて配線されているはずです。
GPIOのIPに関しては使う分だけ設定します。今回はLED2個の出力のため下記としています。
- All outuputsにチェック
- GPIO Widthを「2」に変更
UARTに関しては使うボーレートの設定にします。今回は115200bpsとしています。
- Baud Rateを115200に変更
FPGA設計を統合
これまでの操作でIPを使ってMicroBlazeを使用できるブロック図が完成しました。
下記記事でも実施したように、最終的にコンパイルできるように一度統合します。
「Sources」にあるIPブロックを右クリックして「Create HDL Wrapper」を選びます。
おそらく選択子が出てきますが「OK」を進めていけば大丈夫です。
「Sources」にあるVerilog、IPのファイルが無事統合されました。
XDCファイルを設定
最後に評価ボードで使うFPGAのピン配置をXDC(制約)ファイルに設定していきます。
入力100MHzのクロック、UART・GPIO・I2Cのピンを選択します。
ピン配置に関しては各個人で使うFPGAの評価ボードの回路図を参照お願いします。
各ポート名に関しては、先ほど統合したファイルの中を見て確認しておきます。
今回のXDCファイル設定は下記としています。
1 2 3 4 5 6 7 8 9 |
set_property -dict {PACKAGE_PIN N14 IOSTANDARD LVCMOS33} [get_ports uart_rtl_0_rxd]; set_property -dict {PACKAGE_PIN M14 IOSTANDARD LVCMOS33} [get_ports uart_rtl_0_txd]; set_property -dict {PACKAGE_PIN J1 IOSTANDARD LVCMOS33} [get_ports gpio_rtl_0_tri_o[0]]; set_property -dict {PACKAGE_PIN A13 IOSTANDARD LVCMOS33} [get_ports gpio_rtl_0_tri_o[1]]; set_property -dict {PACKAGE_PIN K11 IOSTANDARD LVCMOS33} [get_ports iic_rtl_0_scl_io]; set_property -dict {PACKAGE_PIN K12 IOSTANDARD LVCMOS33} [get_ports iic_rtl_0_sda_io]; set_property -dict {PACKAGE_PIN H4 IOSTANDARD LVCMOS33} [get_ports clk_100M]; |
作成したXDC(制約)ファイルは「Constrains」の箇所に設定します。
XDCファイルをソースに追加する方法は下記記事でも記載しています。
XilinxのFPGAの評価ボードを購入してみた。Spartan7に入門!
コンパイルしてXSAをエクスポート
本来はシミュレーションなどする必要があるのですが、今回は簡単なテストのため省略します。
Vivadoでコンパイルして、作成したブロック図・制約ファイルが問題ないか確認します。
「Generate Bitstream」を選びます。ポップアップが出ますが気にせずOKを押して進めます。
もう一度、論理合成や配線の実行を聞かれますがデフォルトでOKで進めます。
暫く待つとコンパイル成功した場合には「~successfully completed」と表示されます。
選択子がありますが、いったんキャンセルを押してもらえれば大丈夫です。
コンパイル成功した後はハードウェアデザイン(XSA)のファイルを出力します。
「File」→「Export」→「Export Hardware」を選択します。
その後「Fixed」→「include bitstream」を選んで、任意の名前で保存します。
Vitisでプログラミング(C言語)
Vitis(Xilinxのソフトウェア総合開発環境)にてC言語を使い、プログラミングしていきます。
Vitisのインストール方法に関しては下記記事を参考ください。
Vitisを起動
デスクトップにあるショートカットのアイコンから「Vitis」を起動します。
VitisでXSAファイルを選択
左上のタブから「New」→「Application Project」を選択します。
Platformの選択が出てきますので、Vivadoで作成したハードウェアデザインを読み込みます。
「Create…」タブから「Browse…」から.xsaファイルを選びます。
C言語のテンプレートを選択
今回は楽するために、テンプレート箇所では「Hello World」を開いています。
※Cの空のプロジェクトである「Empty Application」でも同様に可能です。
ソースファイルを確認
アプリケーションプロジェクトの「src」フォルダにメインのプログラムが入っています。
※もし空のプロジェクトで作成した方は、src内にCのソースファイルを作成します。
「New」→「Other」→「C/C++」→「Source File」で作ることができます。
C言語でプログラム
ソースファイルに任意のC言語のプログラムを記載します。
実際使用したFPGAのプログラムは下記です。
元々のhelloworld.cに、参照したプログラム同様なGPIOの動作を追記した簡単なものです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#include <stdio.h> #include "platform.h" #include "xil_printf.h" #include <stdint.h> #include <unistd.h> #include "xparameters.h" int main() { volatile uint32_t *axi_gpio_data = (uint32_t *)XPAR_GPIO_0_BASEADDR; volatile uint32_t *axi_gpio_tri = (uint32_t *)(XPAR_GPIO_0_BASEADDR+4); int i, j; *axi_gpio_tri = 0; // Set All Output for(j=0; j<5; j++){ for(i=0; i<4; i++){ *axi_gpio_data = i; xil_printf("j = %d, i = %d\n",j, i); usleep(1000000); // 1sec sleep } } init_platform(); print("Hello World\n\r"); print("Successfully ran Hello World application"); cleanup_platform(); return 0; } |
参考にさせていただいた記事
GPIOのアドレス・ハードウェア・プログラム含めて下記記事を参考にさせていただきました。
運営者様・管理者様にはこの場を借りて深くお礼申し上げます。
https://marsee101.blog.fc2.com/blog-entry-4695.html
https://japan.xilinx.com/products/intellectual-property/axi_gpio.html#documentation
https://www.acri.c.titech.ac.jp/wordpress/archives/7464
Vitisから評価ボードでテスト
C言語で作成したプログラムを実行すると、FPGA評価ボードのLED(GPIO)が点滅します。
また評価ボードからシリアル(UART)出力も行い、メッセージが表示されます。
テストまでの各手順を紹介しますが、実際のテスト動画が下記となります。
プログラム書き込みから実行までの一連の流れが分かります。
Vitisのシリアルターミナル
「Vitis Serial Terminal」のタブから「+」をクリックして、接続するシリアルポートを選択します。
プログラムをビルドして書き込み
プロジェクト箇所で右クリックすると「Build Project」がありますのでビルドします。
ビルドが完了したら「Program FPGA」でFPGAにプログラムを書き込みます。
Vitisでプログラムを実行
プログラム書き込み後は「Run As」→「1 Launch on Hardware…」を選択して、実行します。
LED(GPIO)とシリアル(UART)の出力を確認できています。
まとめ
今回はFPGAでC言語のプログラミングに関して紹介させていただきました。
記事をまとめますと下記になります。
今回はGPIOとUARTを確認しましたが、下記記事でI2Cもテストしています。
ぜひ一緒にご覧ください。
コメント