Vivado & Vitis でC言語高位合成 Hello World チュートリアル

皆様こんにちは。18のhiraです。ソナー作ったら面白そうとか言っている人ですが、そんなソナーに必要なのは「正確な時刻で処理をする」ことです。ただ、一般のCPUで普通のプログラムを動かすと、時間指定したつもりでも処理に数msのズレが生じてしまうこともあります。正確に数百kHzでサンプリングするようなソナーには不向きです。

それを解決する(と勝手に思っている)のがFPGAです。FPGAは中の回路の配線を、使用者が好き勝手につなぎ直すようなことができる特殊なデバイスです。回路を最適化することで使用者が指定した通りに動作でき、さらに大規模並列回路にすることもできます。大量・高速のデータ処理を必要とするAI学習やデータセンターにも採用されています。
しかしそれにはHDLという、レジスタ叩きやビット操作を書き連ねる、長ったらしいプログラムで書かねばならないことが大きな壁でした。

今回使用するFPGAボード「Arty Z7」

そこでFPGAをもっと活かすため、C言語プログラムをHDLに変換して開発を加速させる「高位合成」という技術が近年注目されています。今回はそんなC言語プログラムの高位合成を「Vivado」、「Vitis」という専用ツールを使って初歩の初歩を体験していきます。

今回の流れ・使う物

今回の目標はC言語のHello World定番プログラムをFPGA上で動かすことです。以下の流れで実践していきます。開発環境はLinuxで、Ubuntu20.04LTS上に構成します。また今回はXilinxというメーカーが製造しているFPGAを使うため、同じくXilinxが提供しているFPGA開発ツールのVivado、Vitisを使用します。

この記事は以下のような流れで高位合成を体験します。

  1. Vivado,Vitisのインストール
  2. VivadoによるFPGAハードウェア設定の作製
  3. VitisによるC言語プログラムの高位合成
  4. FPGAに書き込んで動作検証
  5. 今後やりたいこと

設定とか飛ばしてC言語プログラムをそのまま書くだけなのが理想ですが、高位合成というムツカしいことをやるには、2のハードウェアの設定も行ってやる必要があります。
また今回FPGAボードとしてXilinxのFPGAチップを搭載した「Arty Z7」ボードとUSBケーブルを用います。使用するボードや接続ケーブル(書き込みに特殊なケーブル要する物もある)が異なる場合、一部動作が異なるのでご注意ください。

またこの記事はリンクの動画を参考にしています。というか、動画を文字に起こしただけです(パクリやん)。英語の動画で多少バージョン違いによる変更もありますが、実際のカーソルの動きなど非常にわかりやすいので、そっちの方を見ましょう。

1. Vivado, Vitisのインストール

まずはXilinx製の開発ツールVivado,VitisをUbuntuにインストールします。Xilinxの専用ページから「 ザイリンクス統合インストーラー 2020.2: Linux 用自己解凍型ウェブ インストーラー」をダウンロードします。この時Xilinxのアカウントを作製する必要があります。

ダウンロードファイルを実行してインストーラを起動しますが、フォルダ作製などを行うためsudo権限で実行します。

保存先など色々聞かれますが、デフォルトの設定で構いません。70GBくらいと相当な容量を消費するのでご注意ください。

インストールが無事完了すると以下のようなフォルダ構成になります。写真では作製されるXilinxフォルダはデフォルトの/tools/Xilinx/(写真のDocNaviとか)にあります。

今回使用するVivado、Vitisもインストールされているようです。これを起動できるようにするには、Homeディレクトリにある.bashrcに以下の2行を追加します。VivadoフォルダとVitisフォルダにあるsettings64.shのパスを登録します。Xilinxフォルダの作製場所など、人により異なる場合があります。

$ source /tools/Xilinx/Vivado/2020.2/settings64.sh

$ source /tools/Xilinx/Vitis/2020.2/settings64.sh

最下行2行の「source ~~」を追加する

書いたら2つのツールが起動するかテストしましょう。Vivadoの場合ターミナルに「vivado」と、Vitisの場合「vitis」と入力するとツールが起動します。

vivadoの起動画面。左側のターミナルに「vivado」と入力すると右側のツールが起動する

この時パッケージの問題で起動できないことがあります。僕の場合「librdi_commontasks.so not found」というエラーが起きました。曰く何かしらのライブラリが無いようで、関連するパッケージをインストールする必要があります。質問サイトを参考にしたところ、次の様にlibinfo-devをインストールすることで解決しました。

$ sudo apt update

$ sudo apt install libtinfo-dev

$ sudo ln -s /lib/x86_64-linux-gnu/libtinfo.so.6 /lib/x86_64-linux-gnu/libtinfo.so.5

これでvivadoが起動できるようになりました。同様にvitisも起動できるか確かめます。

2. VivadoによるFPGAハードウェア設定の作製

インストールしたVivadoを使いFPGAボードの設定に関する情報を作製します。Vivadoを開き、「Create Project」からプロジェクトを作製します。この時プロジェクト名と保存先を任意で指定します。
写真ではプロジェクト名を「HelloWorld」としています。

Nextを押すとProject Typeの指定に移ります。今回は「RTL Project」を指定します。またこの段階ではソースファイルを用意していないので「Do not specify sources at this time」にチェックを入れ、Nextを押します。

次に使用するハードウェアを選択します。今回は「Arty Z7」です。しかしデフォルトではおそらくArty Z7用のボード情報はインストールされていません。そのため追加する必要があります。

下の図のようにまず左上の選択をPartsからBoardsに切り替え、右上のInstall/Update Boardsから新規ボード情報をインストールします。

インストール画面が開かれたらDigilent Inc以下を展開し、Single Part以下のArty Z7-20を選択します。選択したら上の下矢印マークからボード情報のインストールを行います。写真では既にインストール済みのため灰色になっていますが、未インストールなら青色です。

元の画面に戻るとArty Z7-20の項目が追加されています。これを選びNextを押すとプロジェクトが作製されます。

プロジェクト画面が出たら実際に今回使用するハード設定を作製します。左の「Flow Navigator」欄からIP INTEGRATORのCreate Block Designを選択します。このFlow Navigatorはこの後も使うので名称と場所を覚えておくと理解しやすいです。

ここから使用するハード設定を回路図のようなブロック図で作製します。Design Nameをつけますが、図ではデフォルトのdesign_1としています。
画面が切り替わり、右上に空欄のDiagramが出てきます。中央の+マークを押してIPを追加します。ここでは「ZYNQ7 Processing System」を選択して追加します。

Diagramに青いブロックが出てきます。これが出てきたらその上にある「Run Block Automantation」を押します。ポップアップができてきますがデフォルト設定のまま進めます。

Run Block Automantationが完了すると青色ブロックのDDR、FIXED_IDから矢印が生えます。確認できたらFCLK_CLK0とM_AXI_GPIO_ACLKをクリックし、黒線で接続します。

正常に接続出来たら次の図のようにオレンジ線で結ばれます。これでブロック図は完成です。

続いてFlow NavigatorからProject Managerを開きます。展開されるProject Managerの左上のSourcesのDesign SOurcesに先ほど作製したdesign_1のボード情報があります。

これを右クリックして「Create HDL Wrapper」を行います。デフォルトの「Let Vivado manage~~」を選び続行します。

HDL Wrapperを作製したら次はビットストリームを作製します。同じくFlow Navigatorの下にある「PROGRAM AND DEBUG」を展開し、Generate Bitstreamを実行します。ポップアップが表示されますがデフォルトのままOKを押します。この作業には数分間かかるので気長に待ちましょう。

この時注意する必要があるのは、右上に緑のグルグルが巻いている時はまだビットストリームの作成中です。READY->緑グルグルと表示されますが、この作成中に以降の動作を行っても失敗します。緑のグルグルが無くなり、作製完了と表示されるまで数分間待ちましょう。
「Bitstream Generation Completed」と表示されれば完了です。作製したデザインの表示をするか聞かれますが、特に必要はないのでそのままCancelで構いません。

ビットストリームを作製したら、今までの情報をファイルにまとめます。File -> Export -> Export Hardwareを押します。
Exportする内容を聞かれますが、この時「Include bitstream」の方を選択します。

保存先はプロジェクトと同じ場所(図だとHelloWorldフォルダ)にすると分かりやすいでしょう。design_1_wrapper.xsaが作製され、ここまでで次のようなフォルダ構成となりました。

最後にFlow Nvigatorの先ほどのGenerate Bitstreamの下にある「Open Hardware Manager」からOpen Target -> Auto Connectを実行します。
Auto Connectを実行するとHardware Managerが展開されます。さらに緑の帯が表示されるので、そこの「Program device」を押して実行します。

Prgram deviceが終わればVivadoでの作業は完了です!次からはVitisでの作業に移ります!

Vitisはターミナルからも開けますが、ToolsからVitis IDEを開くこともできます。Vivadoは閉じてしまって構いません。

3. VitisによるC言語プログラムの高位合成

ここからはVitisでC言語HelloWorldプログラムを書き、高位合成を行います。File -> New -> Platform ProjectからVitisプロジェクトを作製します。

Platform project nameの名前つけを求められますのでお好きな名前に設定します。今回はHelloWorldとしました。

続く「Platform」ではXSA Fileに先ほど作製した.xsaのファイルを指定します。この図ではdesign_1_wrapper.xsaです。

完了すると画面中央部にHelloWorldプロジェクトの構成図が描かれたウィンドウが出てきます。
これの「standalone_on_ps7_cortexa9_0」以下にある「Board Support Package」をクリックし、その右欄にある「Modify BSP Settings」を選択します。

ボードの設定を反映するため2か所の設定を変更します。
Overview -> standaloneにある「stdin」、「stdout」のvalueを両者とも「ps7_coresight_comp_0」に変更します。stdin、stdoutの2か所を変更したらOKを選択して続行します。

ここからはC言語のHelloWorldプログラムを作製します。File -> New -> Application Projectを選択します。Application nameの指定が求められます。図では「HelloWorldApp」としました。
この時System projectとして「HelloWorldApp_system」が作製されます。

「Domain」の指定を求められるので「standalone_domain」を選択して続行します。

次にプログラムのテンプレートを指定します。これが今回高位合成を行うC言語プログラムです。
「Hello World」を指定すると、単純なC言語helloworld.cが提供されます。これまでのハードウェア設定にもよりますが、もちろんこのファイルを書き直して好きなC言語プログラムにすることができます。

左欄Explorerから

HelloWorldApp_system -> HelloWorldApp -> src -> helloworld.cを開いてみたのが次の図です。確かに、見慣れたC言語プログラムのHello Worldが作られています。

確認出来たら上図のようにExplorerのHelloWorldApp_systemを右クリックし、Build Projectを実行します。これによりhelloworld.cが高位合成コンパイルされます。

Buildが完了すると次のように下欄のConsoleに「Build Finished」と表示されます。

ここで注意しなくてはならないのは、このBuild Finishedはコンパイルに失敗しても表示されます。本当にCプログラムに問題が無かったか調べるには、隣の「Problems」の項目を表示します。

例えば、次の図では意図的にコード中に「aaaaaaaa…」というような不要な文字を入れています。もちろんC言語では誤りでコンパイルエラーとなります。
この状態でBuild Projectを実行すると、ConsoleにはBuild Finishedと表示されますが、Problemsにはエラーが出たと警告されます。
この警告を見て成功か失敗かを判断するとよいでしょう。

テンプレートのhelloworld.cをそのままコンパイルすれば成功するはずです。

これでFPGAへの書き込みプログラムの高位合成が完了しました!次はいよいよFPGAでの実機動作です!書き込み自体に難しい点はありませんが、緊張の一瞬です。

4. FPGAに書き込んで動作検証

ではFPGAに実際に書き込んで検証します。Arty Z7の場合3か所の接続がジャンパコネクタとなっています。
今回は上のコネクタをQSPI-JTAG(下2ピン)、真ん中のコネクタはつながず、下のコネクタをUSB(左2ピン)をそれぞれ接続しています。
またケーブルはUSBケーブルでPCと接続します。

ここからはPCにFPGAを接続して作業を行います。USBケーブルでPCとArty Z7を接続すると左下の赤色LEDが光ります。

接続したらケーブルのドライバがインストールされているか確認します。DIGILENTの参考サイトにあるようにVitisフォルダにあるファイルを実行してケーブルドライバをインストールします。

$ cd <VitisFolder>/data/xicom/cable_drivers/lin64/install_script/install_drivers/

$ ./install_drivers

またユーザをUSB接続のためにdialout groupに追加します。

$ sudo adduser \ドルUSER dialout

ケーブルで接続したらVitisに戻ります。いよいよ書き込みます。
先ほどのBuild Project同様HelloWorldApp_systemを右クリックし、今度は「Debug As」 -> 「Launch on Hardware」を実行します。これで書き込みが実行されます!

無事書き込みができるとArty Z7の場合、緑色のLEDが光ります。

書き込みができたら実際に動作しているか検証します。今回の目標はC言語プログラム通り「Hello World」が出力されるかです。

FPGAからのUSB出力信号はVitisのConsoleで表示することができます。

Consoleの右側にある下矢印(2つあるうちの左の矢印)を押し、「3TCF~~MPCore #0」を選択します。これでFPGAからの出力を表示できるようになりました。

それでは実行です。上の黄色と緑の右矢印を押すとプログラムが実行されます。プログラムを実行してConsoleに「Hello World」と表示されれば成功です!

高位合成によるFPGAのプログラミングができました!これを発展させればさらに複雑な処理もできるかもしれません。

5. 今後やりたいこと

今回簡単なCプログラムを高位合成しました。しかし最終目標はそのFPGAを使って何ができるかです。今回はやりませんでしたが、ロボットに使うなど複雑な処理をするなら次のようなこともできなくてはなりません。

  1. シミュレーションによるクロックレベルでの動作の確認
  2. GPIOでの入出力
  3. SDカードや他の機器との通信

例えばソナーに使うなら、本当に数十usきっかりごとにセンサの読み取り動作を行っているか確認する必要があります。そしてセンサの読み取りにはGPIOの使用が不可欠です。

GPIOのハードウェア処理にはVivadoでやったようなブロック図の作製が必要になるかと思います。そういった点も今後調べていきたいです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です