読者です 読者をやめる 読者になる 読者になる

tkato’s blog

ブログ名は暫定。

BNN-PYNQをリビルドする

本日3/7、XilinxがPYNQで動くBinarized Neural Network (BNN)の実装を公開しました。 DeepLearnigのアルゴリズムFPGAにオフロードしたい人にとっては、とても良い勉強材料になると思います。

リポジトリ公開当初は、Pythonで共有ライブラリをキックする部分とビルド済みの共有ライブラリしか公開されておらず、ドライバとアクセラレータのソースは非公開でした。

github.com

中身を詳しく追う前に、とりあえずビルドしてみました。

ビルド環境

  • Ubuntu14.04
  • SDSoC 2016.1

ビルド用のスクリプトが付属しているので、それを実行するだけでできました。 SDSoCそのものは使いません。付属のVivadoとVivado HLSを使います。 最初Windowsで試してみましたが、うまくいかず…*1

ビルド手順(ハードウェア)

以下に記載があります

BNN-PYNQ/README.md at master · Xilinx/BNN-PYNQ · GitHub

ハードウェアのビルドは「Hardware design rebuilt」に記載がある通り。

環境変数XILINX_BNN_ROOTは/BNN_PYNQ/bnn/src/network/では動かなかった。/BNN_PYNQ/bnn/src/が正しそう。*2

BNNのアーキテクチャはCNVとLFCがあります。 今回LFCを試したところ、実行開始から10分程度でbitstream生成まで終わりました。

./make-hw.sh lfc-pynq pynq a

f:id:tkat0:20170307231518j:plain

f:id:tkat0:20170307231514j:plain

ビルド手順(ソフトウェア)

Pythonとハードウェアの間にあるCのドライバのビルド方法。こちらは、PYNQ上でビルドする必要があるようです。上記READMEの「Quick Start」に記載ありますね。

その他

自前で書いていたBNNはビルドに少なくとも20分はかかる上、性能もソフトより遅かったので、BNN-PYNQのコードが公開されたことは勉強する上で非常に嬉しい。ソースを見ていると、hls_streamがデータフローの基本になっているよう。

*1:今回Git Bashをつかってスクリプトを叩いた。ちゃんと環境構築すればWindowsでもできるかも?

*2:追記(03/10):公式に修正されたようですね

SDSoC 2015.4でPYNQのOverlayを開発する(3)

SDSoC 2015.4でPYNQの簡単にプラットフォームを作る話です。次はSWプラットフォームの作成。

これはAdam Taylor氏の以下のブログのやり方をそのままやりました。ビルド済みのカーネルをそのままコピーし、自分ではなにもしないので簡単。

forums.xilinx.com

まずGitHubのPYNQリポジトリ*1より、以下をSDSoCプラットフォームのディレクトリ(任意)へコピー

  • devicetree.dtb
  • fsbl.elf
  • u-boot.elf
  • boot.bif

次に、PYNQのSDカードイメージ*2をSDカードに焼き、boot領域からuImageをSDSoCプラットフォームのディレクトリへコピー

最期に、SDSoC用のpfmファイルを作成。パスは、pfmファイルからの相対パス

<?xml version="1.0" encoding="UTF-8"?>
<xd:repository xd:vendor="xilinx.com" xd:library="xd" xd:name="pynq" xd:version="1.0" xmlns:xd="http://www.xilinx.com/xd" >

    <xd:description>Basic platform targeting the PYNQ-Z1 board</xd:description>

    <xd:bootFiles
      xd:os="linux"
      xd:bif="boot/boot.bif"
      xd:readme="boot/generic.readme"
      xd:devicetree="boot/devicetree.dtb"
      xd:linuxImage="boot/uImage"
      xd:ramdisk="boot/uramdisk.image.gz" # これはたしかZyboかなにかのplatformからコピーしてきたような。。。
    />
  
</xd:repository>

SDSoC 2015.4でPYNQのOverlayを開発する(2)

SDSoC 2015.4でPYNQの簡単にプラットフォームを作る話です。まずはHWプラットフォームの作成。

前回のまとめ

現時点でリリースされているPYNQのROMはSDSoC 2015.4でビルドされたライブラリを含むため、それ以外のSDSoCのバージョンを使う場合は、Linuxカーネルのリビルドが必要。SDSoC 2015.4を使うのが一番簡単。

ポイント

HWとSWの2つのプラットフォームを作る必要があります。基本的にAdam Taylor氏のブログの手順と同じことをします。*1。以下のリンクの前後の記事もPYNQの話なので読むことをおすすめ。

forums.xilinx.com

SDSoCプラットフォームの作成については、UG1146 - SDSoC 環境プラットフォーム開発ガイドや以下の動画で全体像を把握しておくことをおすすめ。

SDSoC 環境入門 (パート 3) : カスタム プラットフォームの生成 (日本語吹替) - YouTube

プラットフォーム作成手順を簡単に概要をまとめます。

  • HWプラットフォームの作成
    • Vivado 2015.4で新規プロジェクトを作成
    • ZYNQとreset IP、割り込み信号のconcat IPだけの簡単なデザインをつくる
    • HWプラットフォーム作成用のtclコマンドを実行し、*.pfmファイルを生成
    • メタデータファイルの作成
  • SWプラットフォームの作成

HWプラットフォームの作成

PYNQのリポジトリには、Base OverlayのVivadoプロジェクトファイルがあります。これをベースにしてHWプラットフォームを作成するのが簡単かと思いました。しかし、このプロジェクトはVivado 2016.1で作成されているためVivado 2015.4で扱うことができませんでした。

そのため、Vivado 2015.4でプロジェクトを新規作成することにしました。

Block Designはこのように作りました。

f:id:tkat0:20170215062559p:plain

Adam Taylorのブログでは、LEDなどの結線もありますが今回は省略。これらは、Linux起動直後に呼ばれる以下のPythonスクリプトでLEDを点滅してるのに対応するためのようです。

github.com

ZYNQの設定は、本来ならベンダーが提供する設定ファイル(Zynq Presets)*2をインポートすれば済むはずですが、インポート時にエラーが生じたため、Vivado 2016.1でPYNQのBase Overlayのプロジェクトを開きZYNQの設定を1つ1つ確認しながら、Vivado 2015.4でも同じ設定をしました。

あとは制約ファイル(Master XDC)*3の追加も忘れずに。

最期に、pfmファイルを作成するtclコマンドを実行して、pfmファイルを作ります。tclコマンドは、以下のスクリプトファイルにまとめておいて、実行しました。事前にSDSoCのインストール先のscripts/vivado/sdsoc_pfm.tclを実行して、sdsocのコマンドをVivadoに読み込ませる必要がある点に注意。

set pfm [sdsoc::create_pfm pynq_hw.pfm]
sdsoc::pfm_name        $pfm "xilinx.com" "xd" "pynq" "1.0"
sdsoc::pfm_description $pfm "PYNQ-Z1"
sdsoc::pfm_clock       $pfm FCLK_CLK0 ps7 0 false proc_sys_reset_0_100M
sdsoc::pfm_clock       $pfm FCLK_CLK1 ps7 1 false proc_sys_reset_1_142M
sdsoc::pfm_clock       $pfm FCLK_CLK2 ps7 2 true  proc_sys_reset_2_200M
sdsoc::pfm_clock       $pfm FCLK_CLK3 ps7 3 false proc_sys_reset_3_166M
sdsoc::pfm_axi_port    $pfm M_AXI_GP0 ps7 M_AXI_GP
sdsoc::pfm_axi_port    $pfm M_AXI_GP1 ps7 M_AXI_GP
sdsoc::pfm_axi_port    $pfm S_AXI_ACP ps7 S_AXI_ACP
sdsoc::pfm_axi_port    $pfm S_AXI_HP0 ps7 S_AXI_HP
sdsoc::pfm_axi_port    $pfm S_AXI_HP1 ps7 S_AXI_HP
sdsoc::pfm_axi_port    $pfm S_AXI_HP2 ps7 S_AXI_HP
sdsoc::pfm_axi_port    $pfm S_AXI_HP3 ps7 S_AXI_HP
for {set i 0} {$i < 16} {incr i} {
  sdsoc::pfm_irq       $pfm In$i xlconcat
}
sdsoc::generate_hw_pfm $pfm

これで、pynq_hw.pfmがVivadoのカレントディレクトリに生成されます。HWプラットフォームの作成は以上。

おわりに

プラットフォームを作成したりするとなると、結局Vivadoの知識やLinuxの知識が必要です。Vivadoについては以下の本を読んで概要を理解しました。おすすめです。

www.shuwasystem.co.jp

*1:ただし、使用したSDSoCのバージョンの記載がないなど色々行間を読む必要があり、この記事だけではプラットフォームを作れなかったので前回の記事の通りAnurag Dubey氏に質問したのでした

*2:http://store.digilentinc.com/pynq-z1-python-productivity-for-zynq/

*3:http://store.digilentinc.com/pynq-z1-python-productivity-for-zynq/

SDSoC 2015.4でPYNQのOverlayを開発する(1)

ブログを始めてみました。 この記事は、SDSoC 2015.4でPYNQ向けの環境構築〜開発を行うまでをまとめていくものです。

PYNQとSDSoCは相性が良いです。Cで書いたハードウェアアルゴリズムを高位合成し、それを簡単にPythonから呼び出すことができました。高位合成したIPによってはハードウェアの制約で入力バッファをDRAM上の連続領域に確保する必要がありますが、PythonからLinuxの連続領域を確保することも、PYNQが提供するPythonライブラリが面倒を見てくれます。そのため、PythonからNumPyのようなライブラリを使う感覚で自作のIPをつかった演算ができました*1

PYNQ向けのSDSoCの環境構築は、現状骨が折れる作業です*2。SDSoCはFPGAボード毎に”プラットフォーム”を作成する必要があります。ボードによっては、SDSoCに標準でプラットフォームが付属しているものもありますが、PYNQはそうではありません(今後に期待)。SDSoCプラットフォームの作成方法は、公式のドキュメントやYouTubeの解説動画などが参考になります。しかし、私はHWプラットフォームは作れたもの、SWプラットフォームを上手く作れませんでした…

それでもなんとかSDSoCでPYNQの開発がしたかったので、有識者に聞くことにしました。Anurag Dubey氏です。彼はPYNQのコミッターでもあり、SDSoCを使って開発したPYNQ用のFIRフィルタをGitHubで公開していました*3。メールで「どうやって作ったの?」という内容の質問をしたところ、以下の回答がありました。かなりフレンドリーに回答してくれました。

  • pynqfireはSDSoC 2015.4で開発した
  • PYNQの/usr/lib/libsds_lib.soはSDSoC 2015.4でビルドしてある
  • それ以外のバージョンでビルドした実行ファイルはPYNQで動かない
  • もし違うバージョンのSDSoCを使うなら、Linuxカーネルのリビルドが必要

SDSoC 2015.4を使うのが、一番簡単な方法だとわかりました。

次の記事から、SDSoC 2015.4を使ってPYNQ用のOverlayを作る方法を記載します。 すでに作ったものは以下にあります。

github.com

*1:多少HW寄りの知識は必要ですが、ドライバなど書かずにPython感覚でHWを叩けるのは感動

*2:@hasegawさん達がSDSoC 2016.3のPYNQプラットフォームを構築できたとのこと。私も環境を提供していただき動作確認中

*3:https://github.com/hackwa/pynqfire