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もテストしています。
ぜひ一緒にご覧ください。



コメント