Ultra96/Ultra96-V2 向け Debian GNU/Linux で XRT(Xilinx Runtime) を動かす(実践編)







# はじめに


筆者は Ultra96/Ultra96-V2(ZynqMP) 向けに Debian GNU/Linux を提供しています[1]。また、XRT(Xilinx Runtime) はXilinx社が提供する開発環境(Vitis)で開発したプログラムをプラットフォームで動かすための環境です[2]。

本来なら MPSoC Edge Device 用の [XRT] は Xilinx が提供する Linux 環境(Petalinux) でしか動きませんが、XRT を Ultra96/Ultra96-V2 向け Debian GNU/Linux で動かすための手順を幾つかのパートに分けて説明します。 



  * [概要編]
  * [ビルド編]
  * [インストール編]
  *  __実践編(この記事)__  
  * [Vitis編]



この記事では、 XRT が動作している Ultra96/Ultra96-V2 向け Debian GNU/Linux で、あるサンプルプログラムを動かす手順について説明します。




## 注意


  __この記事で紹介している Debian Package は Xilinx 社の公式なものではありません。__  




# サンプルの紹介


この実践編で紹介する XRT のサンプルは[「FPGAの部屋」]というブログを書いている @marsee101 さんから提供されたものです。この場をお借りして感謝申し上げます。このサンプルのビルド方法や詳しい説明はブログの次のページを参照してください。

* [『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す1』]
* [『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す2』]
* [『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す3』]
* [『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す4』]




# サンプルのダウンロード


上で紹介したサンプルのバイナリファイルを、@marsee101 さんの許可のもとに、githubで公開しています。

* https://github.com/ikwzm/ZynqMP-FPGA-XRT-Example-1-Ultra96



このリポジトリを ZynqMP-FPGA-XRT をインストールした Ultra96-V2 にダウンロードしてください。


```console
shell$ git clone https://github.com/ikwzm/ZynqMP-FPGA-XRT-Example-1-Ultra96
Cloning into 'ZynqMP-FPGA-XRT-Example-1-Ultra96'...
remote: Enumerating objects: 13, done.
remote: Counting objects: 100% (13/13), done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 13 (delta 3), reused 13 (delta 3), pack-reused 0
Unpacking objects: 100% (13/13), done.
```


```console
shell$ cd ZynqMP-FPGA-XRT-Example-1-Ultra96
```




 


# XRT 環境の設定


XRT 用の環境変数を設定します。XRT には環境変数の設定用に　/opt/xilinx/xrt/setup.sh が用意されているので、これを使います。


```console
shell$ source /opt/xilinx/xrt/setup.sh
XILINX_XRT      : /opt/xilinx/xrt
PATH            : /opt/xilinx/xrt/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
LD_LIBRARY_PATH : /opt/xilinx/xrt/lib:
PYTHONPATH     : /opt/xilinx/xrt/python:
```





# FPGA ビットストリームファイルの準備


ダウンロードしたリポジトリにはすでに FPGA ビットストリームファイル(streaming_lap_filter5.bin) は含まれていまが、この節では、このビットストリームファイルの作り方を説明しておきます。



このビットストリームファイルは Partial Reconfiguration のベースとなります(ここらへんの話は [インストール編] の「Device Tree の準備」を参照してください)。本来ならベースとなるビットストリームファイルは xclbin を作ったときに別に作られるべきものですが、このサンプル例では「たまたま」 xclbin ファイルに含まれているビットストリームファイルと同じです。したがって、まず、xclbinutil コマンドを使ってビットストリームファイルを取り出します。


```console
shell$ xclbinutil --input streaming_lap_filter5.xclbin --dump-section BITSTREAM:RAW:streaming_lap_filter5.bit
XRT Build Version: 2.6.0 (2019.2_Ultra96)
       Build Date: 2020-03-26 13:46:25
          Hash ID: 4a669990dd872f3b683009c0e2200b3bd3d2a9c0
------------------------------------------------------------------------------
Warning: The option '--output' has not been specified. All operations will
         be done in memory with the exception of the '--dump-section' command.
------------------------------------------------------------------------------
Reading xclbin file into memory.  File: streaming_lap_filter5.xclbin
Section: 'BITSTREAM'(0) was successfully written.
Format: RAW
File  : 'streaming_lap_filter5.bit'
Leaving xclbinutil.
```




次に、bootgen コマンドを使って streaming_lap_filter5.bin を作ります。streaming_lap_filter5.bif はリポジトリに含まれています。


```console
shell$ bootgen -arch zynqmp -image streaming_lap_filter5.bif -o tmp.bin
****** Xilinx Bootgen v2019.2
  **** Build date : Jan 16 2020-08:00:00
    ** Copyright 1986-2019 Xilinx, Inc. All Rights Reserved.

```




bootgen コマンドは XRT(Xilinx Runtime) には含まれていません。以下の記事を参考にインストールしてください。

* [『bootgen を Debian GNU/Linux、Ubuntu で動かす』@Qiita]




# zocl の準備


ZynqMP-FPGA-XRT をインストールした際に zocl (MPSoC Edge Device 用の Linux カーネルモジュール)もインストールされています。ただしzocl は Linux にインストールしただけでは有効になりません。zocl を有効にするためには Device Tree が必要です。そこで次のような Device Tree を用意しています。


```devicetree:zocl.dts
/dts-v1/; /plugin/;
/ {
	fragment@0 {
		target-path = "/fpga-full";
		__overlay__ {
			firmware-name = "streaming_lap_filter5.bin";
		};
	};
	fragment@1 {
		target-path = "/amba_pl@0";
		__overlay__ {
			#address-cells = <2>;
			#size-cells = <2>;
			zyxclmm_drm {
				compatible = "xlnx,zocl";
				status = "okay";
				reg = <0x0 0xA0000000 0x0 0x10000>;
			};
			fclk0 {
				compatible    = "ikwzm,fclkcfg-0.10.a";
				clocks        = <&zynqmp_clk 0x47>;
				insert-rate   = "100000000";
				insert-enable = <1>;
				remove-rate   = "1000000";
				remove-enable = <0>;
			};
		};
	};
};

```

* 2020年6月17日追記: 元の記事では "#size-cells = <1>;" "reg = <0x0 0xA0000000  0x10000>;" になっていましたが、Linux Kernel 5.4 だとエラーになります。Linux Kernel 5.4 になってからは、 "#size-cells"  の値にベースの Device Tree と異なる値を設定することができなくなったようです。


streaming_lap_filter5.bin を /lib/firmware にコピーします。


```console
shell$ sudo cp streaming_lap_filter5.bin /lib/firmware/
```




zocl.dts を Device Tree Overlay します。 dtbicfg.rb というDevice Tree Overlay 用の ruby スクリプトを用意していますので、こちらを使います。


```console
shell$ sudo ./dtbocfg.rb --install zocl --dts zocl.dts
<stdin>:14.16-18.6: Warning (unit_address_vs_reg): /fragment@1/__overlay__/zyxclmm_drm: node has a reg or ranges property, but no unit name

```




dmesg でカーネルのログを確認します。fpga manager によってstreaming_lap_filter5.bin が FPGA にプログラムされたこと、zocl カーネルモジュールがロードされたこと、fclkcfg によって PL Clock0 の周波数が 100MHz に設定されたことを確認できたら成功です。


```console
shell$ dmesg | tail -12
[ 4824.024388] fpga_manager fpga0: writing streaming_lap_filter5.bin to Xilinx ZynqMP FPGA Manager
[ 4824.176574] [drm] Probing for xlnx,zocl
[ 4824.176710] [drm] FPGA programming device pcap founded.
[ 4824.176715] [drm] PR Isolation addr 0x0
[ 4824.178392] [drm] Initialized zocl 2018.2.1 20180313 for a0000000.zyxclmm_drm on minor 1
[ 4824.180629] fclkcfg amba_pl@0:fclk0: driver installed.
[ 4824.180640] fclkcfg amba_pl@0:fclk0: device name    : amba_pl@0:fclk0
[ 4824.180644] fclkcfg amba_pl@0:fclk0: clock  name    : pl0_ref
[ 4824.180649] fclkcfg amba_pl@0:fclk0: clock  rate    : 99999999
[ 4824.180674] fclkcfg amba_pl@0:fclk0: clock  enabled : 1
[ 4824.180677] fclkcfg amba_pl@0:fclk0: remove rate    : 1000000
[ 4824.180681] fclkcfg amba_pl@0:fclk0: remove enable  : 0
```





# サンプルの実行


サンプルを実行します。次のような結果が出たら成功です。


```console
shell$ ./streaming_lap_filter5.exe streaming_lap_filter5.xclbin
Using FPGA binary file specfied through the command line: streaming_lap_filter5.xclbin
Found Platform
Platform Name: Xilinx
Loading: 'streaming_lap_filter5.xclbin'
total time = 0.001533 sec
Success HW and SW results match
```

もし次のようなメッセージがでて失敗した場合は、デバイスファイル(/dev/dri/renderD128) のパーミッションが有効になっていないかもしれません。


```console
shell$ ./streaming_lap_filter5.exe streaming_lap_filter5.xclbin
Using FPGA binary file specfied through the command line: streaming_lap_filter5.xclbin
XRT build version: 2.6.0
Build hash: 7104cc336e010e3e0755264ff832d811ff605e2c
Build date: 2020-03-24 21:07:36
Git branch: 2019.2_Ultra96
PID: 670
UID: 1000
[Wed Dec  2 11:31:07 2020]
HOST: debian-fpga
EXE: /home/fpga/examples/ZynqMP-FPGA-XRT-Example-1-Ultra96/streaming_lap_filter5.exe
[XRT] ERROR: No devices found
../src/krnl_streaming_lap_host3.cpp:71 Error calling err = cl::Platform::get(&platforms), error code is: -1
```




次のようにデバイスファイル(/dev/dri/renderD128) のパーミッションを変更してみてください。


```console
shell$ sudo chmod o+rw /dev/dri/renderD128
```








# 参考


* https://github.com/Xilinx/XRT
* https://github.com/ikwzm/ZynqMP-FPGA-Linux
* https://github.com/ikwzm/ZynqMP-FPGA-XRT
* https://github.com/ikwzm/ZynqMP-FPGA-Ubuntu18.04-Ultra96
* https://github.com/ikwzm/ZynqMP-FPGA-XRT-Example-1-Ultra96
* [『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す1』]
* [『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す2』]
* [『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す3』]
* [『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す4』]
* [『bootgen を Debian GNU/Linux、Ubuntu で動かす』@Qiita]


[1]: https://github.com/ikwzm/ZynqMP-FPGA-Linux "https://github.com/ikwzm/ZynqMP-FPGA-Linux"
[2]: https://github.com/Xilinx/XRT "https://github.com/Xilinx/XRT"
[ZynqMP-FPGA-Linux]: https://github.com/ikwzm/ZynqMP-FPGA-Linux "https://github.com/ikwzm/ZynqMP-FPGA-Linux"
[XRT]: https://github.com/Xilinx/XRT "https://github.com/Xilinx/XRT"
[概要編]: https://qiita.com/ikwzm/items/0d3a8adfe725cd17f932 "『Ultra96/Ultra96-V2 向け Debian GNU/Linux で XRT(Xilinx Runtime) を動かす(概要編)』@Qiita"
[ビルド編]: https://qiita.com/ikwzm/items/d8013ea91125a3fc46aa "『Ultra96/Ultra96-V2 向け Debian GNU/Linux で XRT(Xilinx Runtime) を動かす(ビルド編)』@Qiita"
[インストール編]: https://qiita.com/ikwzm/items/6612eacc4a0d324a0a68 "『Ultra96/Ultra96-V2 向け Debian GNU/Linux で XRT(Xilinx Runtime) を動かす(インストール編)』@Qiita"
[実践編]: https://qiita.com/ikwzm/items/58cfea3f9d0f42840511 "『Ultra96/Ultra96-V2 向け Debian GNU/Linux で XRT(Xilinx Runtime) を動かす(実践編)』@Qiita"
[Vitis編]: https://qiita.com/ikwzm/items/e70d8d0e44fe3784a708 "『Ultra96/Ultra96-V2 向け Debian GNU/Linux で XRT(Xilinx Runtime) を動かす(Vitis編)』@Qiita"
[『bootgen を Debian GNU/Linux、Ubuntu で動かす』@Qiita]: https://qiita.com/ikwzm/items/97811fcff7876181209f "『bootgen を Debian GNU/Linux、Ubuntu で動かす』@Qiita"
[「FPGAの部屋」]: https://marsee101.blog.fc2.com "「FPGAの部屋」"
[『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す1』]: https://marsee101.blog.fc2.com/blog-entry-4823.html "『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す1』"
[『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す2』]: https://marsee101.blog.fc2.com/blog-entry-4824.html "『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す2』"
[『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す3』]: https://marsee101.blog.fc2.com/blog-entry-4825.html "『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す3』"
[『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す4』]: https://marsee101.blog.fc2.com/blog-entry-4826.html "『Vitis 2019.2 で RTL カーネルを使用してストーミング接続を試す4』"