PythonでFPGAを扱える?Ultra96-V2でPYNQを動かしてみた(1) ~ 導入編

FPGAボードUltra96-V2を入手したのでPythonでFPGAが扱えるというPYNQ環境を試してみました。

執筆者 : 原田 秀一


PYNQ

PYNQはPythonからFPGAを利用するフレームワークです。

公式サイト www.pynq.io

元はXilinx Zynqシリーズ向けでしたが現在ではAlveoシリーズやAWS-F1の対応も追加されています。 (対応環境)

調査時にどこかでPythonを使ってFPGAの設計ができるような書き方をされているのを見た気がしますが、 Python記述を高位合成してFPGA設計ができるのではなく、FPGAに実装された機能をPythonから利用することができます。

Ultra96-V2

Ultra96-V2はAvnet社製のFPGAボードでXilinx社製のZynq UltraScale+ MPSoCを搭載しています。

www.avnet.com

FPGAボードは様々なものがありますがおおまかには以下のような理由で選びました。

  • Vitisでのアクセラレーション開発(エンベデッドプラットフォーム)環境を試したい
  • PYNQを試したい
  • 特定の外部インタフェースは不要
  • 組み込み開発の実験用ボードとしても使うかも
  • 低価格(約3万円)、入手性(在庫があった)

もう少し詳しく書いておきます。 Vitisアクセラレーション開発でサポートされるプラットフォームは、アクセラレータカードとエンベデッドプラットフォームがあります。

アクセラレータカードのAlveoシリーズはそこそこ高価(Alveo U50で約30万円)でありそれを取り付けるマシンも必要となります。 エンベデッドプラットフォームはArmコアとFPGAを統合したZynqシリーズを搭載した環境でXilinxおよびパートナー企業が様々なボードを提供しており3万円前後の低価格なものもあります。

私自身が組み込み畑の人間なので、組み込み開発の実験用としても使えるのではないかという期待や、 価格的に手を出しやすかった点からエンベデッドプラットフォームに絞って検討しました。 Ultra96V2の場合、Zynq UltraScale+ MPSoC搭載品でArmコアはCortex-A53 x 4, Cortex-R5 x 2のマルチコア構成と結構ハイスペックにも関わらず3万円程度なのは安いように思いました。 ただしZynq固有のブートシーケンスやFPGAを含むことによる環境の複雑さもありそうなのでFPGAを目的に含まないならば別の組み込み開発ボードを選んだほうが良いかもしれません。

その他の注意としてXilinxのFPGAであれば他にもSpartanシリーズ、Artixシリーズを搭載したボードは もっと安いものもありますが、これらはVitisアクセラレーションのサポート対象ではありません。 ハードウェアとしてのFPGA入門ならこれらのボードで問題ないと思います。

PYNQの動作環境もLinux環境が必要なため対象デバイスは基本的にVitisアクセラレーションと同じようになりますが、 すぐに試せるイメージが提供されているボード環境は限られていました。 公式サイトの対応環境を参考に推奨環境のPYNQ-Z2ボードも検討しましたがVitisプラットフォームの提供状況が把握できなかったので見送りました。 もしPYNQが主目的であればチュートリアルや記事が多いPYNQ-Z2の方が良かっただろうと今回試してみて思いました。

特定の外部インタフェースが不要というのは、今回具体的なインタフェースを必要とする処理を想定してなかったためです。 例えばPYNQ-Z2やZCU104等のHDMIの入出力があるボードであればHDMIで受信したデータを処理してHDMIで送信することができますが、 Ultara96-V2の標準インタフェースはシングルボードコンピュータ用の最低限のものとなっておりUSB, Mini DisplayPort出力しかありません。 購入して詳しく仕様を見てみると任意に使えるLEDやスイッチ類も少な目でした。 (拡張用のコネクタにメザニンボードを取り付けてセンサーを追加するといった拡張は可能) 目的にあったインタフェースや拡張基板が備わっているかもボードを選ぶことは重要です。

PYNQの導入

実際にUltra96-V2にPYNQ環境を入れていきます。

  1. Ultra96-V2用のPYNQ SDカードイメージを入手します。

    Pre-built SD image v2.6 for Ultra96 version 2: http://avnet.me/ultra96v2-pynq-image-v2.6

  2. ダウンロードしたultra96v2_v2.6.0.zip中のimgファイルをmicroSDカードに書き込みます。 私は balenaEtcher を使用して書き込みました(zipのまま指定できます)。

  3. Ultra96-V2ボードとPCをUSBケーブルで接続しmicroSDカードをセットして電源を入れます。

    このとき USB JTAG/UART基板があればUART出力でbootメッセージを確認できます。

    標準のUSB接続のみの場合、こちら側のUSB-UARTはLinux起動後に有効となり自動ログインされるので、それ以降はシリアルコンソールからの操作が可能となります。

    Ultra96-V2にディスプレイ、キーボード、マウスを接続しておけばそちらからも操作できます。

    f:id:harada-va:20211008072026j:plain
    起動後のディスプレイ表示状態

  4. PCとボード間でネットワーク接続できるように設定します。

    ボードのIPアドレスは 192.168.3.1に設定されているので、PC側の該当するネットワークにもこれに合わせてIPアドレスを設定します。

  5. ブラウザから192.168.3.1にアクセスします。

    (パスワードを要求された場合xilinxで入れます。)

    Jupyter Notebookの画面となりノート(拡張子ipynb)、ディレクトリが表示されます。

f:id:harada-va:20210903085239p:plain
Jupyter Notebookを開いた状態

Jupyter Notebookはインタラクティブにプログラムを記述し実行結果も同じノートに保存していける実験に便利な環境です。

Jupyter Notebookの内容

含まれいてる内容は以下のようなものです。

  • Welecome to Pynq.ipynb

    簡単なディレクトリの説明、PYNQ公式等へのリンクや書かれているだけのノートです。

    f:id:harada-va:20210903104716p:plain
    Welcome to Pynqを開いた状態

  • getting_startedディレクトリはJupyter Notebookの使い方等が書かれたノートが入っています。

    f:id:harada-va:20210903085231p:plain
    getting_startedディレクトリ

    初めてJupyter Notebookを使う場合は一度実行してみると使い方やどういうもの理解できると思います。

  • commonディレクトリは基本的にFPGAデザインに依存しない共通的な内容となっているようです。

    f:id:harada-va:20210903085235p:plain
    commonディレクトリ

    手元の環境で試した結果は以下のようになりました。 一部そのままでは期待する結果とならないものがありましたので備考欄に記載しています。

    ノート名 動作 備考
    display_port_introduction OK 前半mini DisplayPort接続必要, USBカメラが無く後半未実施
    ovelay_download OK ビットストリームはsensors96b.bitを指定すればOK
    pogramming_pybind11 OK
    python_random OK
    python_retriebing_shell OK
    ultra96_pmbus OK
    usb_webcam - USBカメラが無く未実施
    wifi OK DNS設定を追加してOK
    zynq_clocks OK このノート実行より前にビットストリームをロードしておく必要あり
  • sensor96bディレクトリはUltra96-V2用でセンサーメザニンアダプタのスターターキットを用いるノートとなっています。

    f:id:harada-va:20210903085227p:plain
    sensor96bディレクトリ

    f:id:harada-va:20210903104505p:plain
    sensors_mezzanine_example.ipynbを開いた状態

    メザニンアダプタ、スターターキットは持っていないので実動作は試せていません。 実際にLCD表示させたり、ボタン状態を取得したりを行うにはスターターキットが必要ですが、 ノートの内容のPython部の実行だけは行うことができます。 (FPGAから先の信号がつながってない状態ですがIO操作だけ行われます)

このようにUltra96-V2用PYNQイメージを入れただけでPYNQ環境としては機能しているのですが、 FPGAを使用するものはsensor96bのみでほとんどできることがありません。 FPGAに仕事をさせるためにはオーバーレイが必要となります。

オーバーレイ

PYNQではFPGAを使用したハードウェアライブラリをオーバーレイと呼んでいます。 オーバーレイの実態はFPGAの設計情報の一部であるhwhファイルおよび コンフィグレーションデータを含むビットストリームとなります。

これらは以下のようにOverlayクラスを使用してロードします。

from pynq import Overlay
overlay = Overlay("base.bit")

これによりビットストリームをFPGAに反映(コンフィグレーション)し、 ビットストリームに対応するhwhファイルの内容を解析しIPブロックを認識しPythonから操作可能になります。

PYNQの紹介記事ではPYNQ-Z1/Z2ボード上で動かしている例が多いのですが、 これはPYNQ-Z1/Z2用のインタフェースに合わせたオーバーレイが存在していることが前提となっています。

残念ながらUltra96-V2用のPYNQイメージには、sensor96bディレクトリ中のノートブックで使用されている センサーメザニンアダプタ用のオーバーレイしか含まれておらず、 PYNQ-Z1/Z2上でPYNQを動作させている記事の通りにはいきません。 (commonディレクトリのようにFPGAデザインに依存しないものは実行可能)

よくあるLEDを点灯させるようなサンプルもセンサーメザニンアダプタ上のLEDを制御する例はありますが、 Ultra96-V2ボード上のLEDを制御することはできません。 PYNQ環境だけあってもそこで動作するオーバーレイがないと何もできないのです。

ということで次回、オーバーレイを作ってみたいと思います。