ようやくKV260ボードを手に入れました。
KV260向けにはkv260-smartcam
などのスタートキットのSDイメージを使用することで既にDPUが搭載されたアプリケーションを試すことができます。しかしながら、DPUのコンフィグレーションを変更したり、DPU以外に自作の回路を足すなど色々としたいので、自分でプラットフォームを作ってDPUを搭載することにしました。
参考
今回の作業を行うにあたって、たくさんの記事を参考にさせていただきました。ありがとうございます。Vitis2022.1 + KV260向けの記事はいくつか存在し、それぞれ微妙に手順は異なりますが、概ね手順は同じです。本記事の手順も参考記事をベースにしています。
-
KRIA XILINXのSOMボードのVitisプラットフォームの作り方(2022.1 版)
- こちらの記事ではXILINX KIRA K26(KV260) Petalinux2022.1用起動用SDカードイメージの作り方でBSPから作成したSDイメージを使用しています。
- こちらの記事では
KRIA向け起動用ブートファイルを作成するには、ハードウェア情報のない状態でファイルを作成する必要があります。
と書かれています。 - この記事の通りに作業を行うとvaddの動作確認までできましたが、プラットフォームのベースとなるVivadoプロジェクトから生成するプラットフォーム名と、Vitis IDEでプラットフォームをビルドするときに指定するプラットフォーム名(プロジェクト名)を一致させる必要があるので注意です。
-
Kria KV260 and PetaLinux 2022.1: Part 02- Vitis Platform
- こちらの方法ではBSPを使用したpetalinuxプロジェクトから
sdk.sh
生成時に--get-hw-description
を実行しています。 - 手順を間違えたのか、この方法で作成したSDイメージはLinux起動中に
Starting Create System Users
で止まってしまいました。
- こちらの方法ではBSPを使用したpetalinuxプロジェクトから
- KV260 の ブートファームウェアを更新
環境
- Ubuntu 18.04
- Vitis/Vivado/Petalinux 2022.1
- Vitis-AI v2.5
- v2.5 tagはGPU向けDockerイメージのビルドに失敗するため、v2.5より少し進んだコミットID(
469a4
を使用します)
- v2.5 tagはGPU向けDockerイメージのビルドに失敗するため、v2.5より少し進んだコミットID(
各環境のインストール手順は省略します。
Vitis-AIのClone
色々なところでファイルを使用するので先にCloneしておきます。
cd <YOUR_WORKING_DIRECTORY>
git clone https://github.com/Xilinx/Vitis-AI
cd Vitis-AI
git checkout 469a4b7bc7b7213d76507c34eeb258580322befd
CPUイメージはdockerhub上にありますが、GPUイメージはビルドする必要があります。
cd docker
./docker_build_gpu.sh #1時間以上はかかります
プラットフォームの作成
Vivadoベースデザインの作成
KRIA XILINXのSOMボードのVitisプラットフォームの作り方(2022.1 版)を参考にして作ります。プロジェクト名はkv260_platform_clk5
としました。
参考記事とはクロックの数が異なりますが、それ以外は同じように作成します。色々な周波数のクロックを使用したいため5種類(100/150/200/300/400)の周波数をClocking Wizard
に設定しました。
参考記事同様にビットストリームを生成し、Export Platform
からxsaファイルを生成します。プラットフォーム名をVivadoプロジェクト名と同じくkv260_platform_clk5
としてkv260_platform_clk5.xsa
ファイルを生成します。
オーバレイ用pl.dtboファイルの生成
先程の参考記事のオーバーレイ用デバイスツリーを作成する。と同じ手順でデバイスツリーオーバレイ用のデバイスツリーを生成します。
source /tools/Xilinx/Vitis/2022.1/settings64.sh
xsct
createdts -hw <YOUR_VIVADO_PROJECT>/kv260_platform_clk5.xsa -zocl -platform-name mydevice -git-branch xlnx_rel_v2022.1 -overlay -compile -out mydevice
exit
dtc -@ -O dtb -o mydevice/mydevice/mydevice/psu_cortexa53_0/device_tree_domain/bsp/pl.dtbo mydevice/mydevice/mydevice/psu_cortexa53_0/device_tree_domain/bsp/pl.dtsi
mkdir dtg_output
cp mydevice/mydevice/mydevice/psu_cortexa53_0/device_tree_domain/bsp/pl.dtbo dtg_output
生成したpl.dtbo
は後でKV260に転送します。
Petalinuxプロジェクトの作成
PetalinuxプロジェクトをBSP(Board support package)から作成します。
(Ultra96のときはBSPなしで1からプロジェクトを作ってもMACHINE_NAMEさえ設定すればなんとかなったのですが今回はうまくいかなかったので大人しくBSPを使うことにしました)
今回はxilinx-kv260-starterkit-v2022.1-05140151.bsp
を使用します。xilinx-wikiからダウンロードリンクを取得します。
Petalinuxの更新
アップデートしないと生成したSDイメージはKV260で起動しません。PetaLinux 2022.1 Kria Update 2
source <YOUR_PETALINUX_INSTALL_PATH>/settings.sh
petalinux-upgrade -u http://petalinux.xilinx.com/sswreleases/rel-v2022/sdkupdate/2022.1_update2/ -p "aarch64" --wget-args "--wait 1 -nH --cut-dirs=4"
プロジェクトの作成
petalinux-create -t project xilinx-kv260-starterkit-v2022.1-05140151.bsp
cd xilinx-kv260-starterkit-2022.1
XRTの有効化
petalinux-config -c rootfs
からMenuconfigを起動して設定することもできますがコマンドで作業しました
sed -i 's/# CONFIG_xrt is not set/CONFIG_xrt=y/g' project-spec/configs/rootfs_config
プロジェクトへのVitis-AI-Libraryの追加
KV260で動作するPetalinuxシステムではパッケージ管理のdnfが使用可能です。Petalinuxをビルドするときにrootfsのconfigを変更してパッケージを追加しなくても、後からボード上でdnf install
によってパッケージの追加が可能です。
Vitis-AIを動作させるに当たって必要なライブラリはpackagegroup-petalinux-vitisai
という名前で公開されているのですが、記事執筆現時点で2022.1向けにはパッケージが公開されておらず利用できません:[Petalinux 2021.1]packagegroup-petalinux-vitisai problem
Githubではrpmパッケージが公開されているのですが、パッケージの依存が解決できずボード上でインストールすることはできませんでした。
ということで、Petalinuxビルド時に予めVitis-AI-Libraryを含めることにしました。この手順はVitis-AIのGithubでも公開されています:To rebuild the system by configuring PetaLinux
- Vitis-AIレシピファイルのコピー
cp -r <Vitis-AI Directory>/setup/petalinux/recipes-vitis-ai ./project-spec/meta-user/
- rootfsコンフィグの修正
./project-spec/meta-user/conf/user-rootfsconfig
に下記を追記
CONFIG_vitis-ai-library
CONFIG_vitis-ai-library-dev
CONFIG_vitis-ai-library-dbg
- vitis-ai-libraryの有効化
petalinux-config -c rootfs
でmenuconfigを起動してuser packages --->
からvitis-ai-libraryを有効化
今回はdbgもdevも全部選択しました。(全部は要らなさそう)
ビルド+SDイメージの作成、ブート確認
petalinux-package --boot --u-boot --force
petalinux-package --wic --images-dir images/linux/ --bootfiles "ramdisk.cpio.gz.u-boot,boot.scr,Image,system.dtb,system-zynqmp-sck-kv-g-revB.dtb" --disk-name "mmcblk1"
petalinux-build
をしていると、Fetcher failure: Unable to find file
のエラーが出てビルドが失敗することがあります。私の環境ではunset HTTP_PROXY
を実行してからもう一度ビルドするとビルドに成功しました。
参考:Error when trying to build a PetaLinux project
生成された./images/linux/petalinux-sdimage.wic
がブート可能なSDイメージです。これをetcher等でSDカードに書き込んでKV260の電源を接続し起動します。USBケーブルでPCと接続し、sudo screen /dev/ttyUSB1 115200
でシリアルコンソールに接続できます。ユーザ名petalinux
でログインして初回はパスワードを設定します。
有線LANを接続し今後はssh接続でアクセスすることにします。
※KV260のファームウェアを更新しないと私の環境ではブートに失敗しました。下記記事を参考にしてKV260のファームウェアを更新してください。
-
KV260 の ブートファームウェアを更新
- BSPでrecommendになっている
BOOT_xilinx-k26-starterkit-v2022.1-07250622_update2.BIN
に更新しました:Boot-Firmware-Updates
- BSPでrecommendになっている
sysrootの作成
Vitisでアプリケーションを作成する際はsysrootが必要になるので生成します。先程の工程で追加したVitis-AI-Library込みのsysrootが生成されます。
petalinux-build --sdk
cd images/linux
./sdk.sh #展開する任意のディレクトリを入力
Vitisプラットフォームの生成
mkdir <VITIS_PLATFORM_PRJ_DIR>
cd <VITIS_PLATFORM_PRJ_DIR>
vitis -workspace ./
参考記事のVitisでプラットフォームの作成。と同じ手順で作成します。
ワークスペースの場所は何でも良いですが、プラットフォーム名はベースデザインと同じ名前(今回はkv260_platform_clk5
)にしてください。(同じにしないと筆者環境では後のDPUを載せる工程で失敗しました)
参考記事同様、Boot Components Directory, FAT32 Partition Directory
は空のディレクトリを設定、Sysroot Directory
は空欄のままにしました。
ビルドはすぐに終わります。
<VITIS_PLATFORM_PRJ_DIR>/<PLATFORM_NAME>/export
にプラットフォームが生成されます。
プラットフォーム情報を確認しておきます。
platforminfo ./export/kv260_platform_clk5/kv260_platform_clk5.xpfm
Vitisインストールディレクトリにコピーしておくと使い勝手がいいのでコピーしておきました。
cd export
cp -r kv260_platform_clk5 /tools/Xilinx/Vitis/2022.1/platforms/
やっとプラットフォームができました。。
VitisでDPUを搭載したデザインの作成
DPUを搭載したデザインを作成するにはVivadoフローとVitisフローの2種類のフローがXilinxから公開されています。今回はVitisフローを使用します。
Vitis-AI v1.4まではGithubリポジトリ上にIPやフローが公開されていたのですが、なぜかv2.5ではリポジトリ外で公開されています。Vitis-AI/reference_designからKV260やUltra96などのMPSoCで使用できるDPU IPDPUCZDX8G
のIPおよびプロジェクトのテンプレートDPUCZDX8G.tar.gz
を
ダウンロードして解凍します。
cp ~/Downloads/DPUCZDX8G.tar.gz <YOUR_WORKING_DIRECTORY>
cd <YOUR_WORKING_DIRECTORY>
tar xvf DPUCZDX8G.tar.gz
ここからはDPU + vadd on Ultra96v2 (Vitis 2020.2)とほぼ同じ手順です。
プロジェクトの作成
Vitisを起動し、Window->Preferences->Library Repositories
の設定を開き、先程ダウンロードしたDPUCZDX8Gディレクトリを追加します。
cd <YOUR_DPUPRJ_DIR>
vitis
File->New->Application Project
からプロジェクトを作成します。プロジェクト名は今回はdpuprj
としました。ベースとなるプラットフォームは先程作成したプラットフォームを選択します。
sysrootに先程sdk.sh
を実行して展開したsysrootディレクトリの中のcortexa72-cortexa53-xilinx-linux
ディレクトリを設定します。
テンプレートからDPU Kernel
を選択して、プロジェクトを作成します。
dpuコンフィグレーションの変更
Explorerウインドウのdpu_trd_kernelsからsrc->prj->Vitis->dpu_conf.vhを開いてDPUのコンフィグレーションを変更します。
KV260にはB3136を載せることができます。使用するモデルに応じて機能の有効化/無効化を設定することができます。今回は以下のような設定にしました。
dpu_conf.vh
/*
* Copyright 2019 Xilinx Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//Setting the arch of DPU, For more details, Please read the PG338
/*====== Architecture Options ======*/
// |------------------------------------------------------|
// | Support 8 DPU size
// | It relates to model. if change, must update model
// +------------------------------------------------------+
// | `define B512
// +------------------------------------------------------+
// | `define B800
// +------------------------------------------------------+
// | `define B1024
// +------------------------------------------------------+
// | `define B1152
// +------------------------------------------------------+
// | `define B1600
// +------------------------------------------------------+
// | `define B2304
// +------------------------------------------------------+
// | `define B3136
// +------------------------------------------------------+
// | `define B4096
// |------------------------------------------------------|
`define B3136
// |------------------------------------------------------|
// | If the FPGA has Uram. You can define URAM_EN parameter
// | if change, Don't need update model
// +------------------------------------------------------+
// | for zcu104 : `define URAM_ENABLE
// +------------------------------------------------------+
// | for zcu102 : `define URAM_DISABLE
// |------------------------------------------------------|
`define URAM_ENABLE
//config URAM
`ifdef URAM_ENABLE
`define def_UBANK_IMG_N 5
`define def_UBANK_WGT_N 17
`define def_UBANK_BIAS 1
`elsif URAM_DISABLE
`define def_UBANK_IMG_N 0
`define def_UBANK_WGT_N 0
`define def_UBANK_BIAS 0
`endif
// |------------------------------------------------------|
// | You can use DRAM if FPGA has extra LUTs
// | if change, Don't need update model
// +------------------------------------------------------+
// | Enable DRAM : `define DRAM_ENABLE
// +------------------------------------------------------+
// | Disable DRAM : `define DRAM_DISABLE
// |------------------------------------------------------|
`define DRAM_ENABLE
//config DRAM
`ifdef DRAM_ENABLE
`define def_DBANK_IMG_N 1
`define def_DBANK_WGT_N 1
`define def_DBANK_BIAS 1
`elsif DRAM_DISABLE
`define def_DBANK_IMG_N 0
`define def_DBANK_WGT_N 0
`define def_DBANK_BIAS 0
`endif
// |------------------------------------------------------|
// | RAM Usage Configuration
// | It relates to model. if change, must update model
// +------------------------------------------------------+
// | RAM Usage High : `define RAM_USAGE_HIGH
// +------------------------------------------------------+
// | RAM Usage Low : `define RAM_USAGE_LOW
// |------------------------------------------------------|
`define RAM_USAGE_HIGH
// |------------------------------------------------------|
// | Channel Augmentation Configuration
// | It relates to model. if change, must update model
// +------------------------------------------------------+
// | Enable : `define CHANNEL_AUGMENTATION_ENABLE
// +------------------------------------------------------+
// | Disable : `define CHANNEL_AUGMENTATION_DISABLE
// |------------------------------------------------------|
`define CHANNEL_AUGMENTATION_ENABLE
// |------------------------------------------------------|
// | ALU parallel Configuration
// | It relates to model. if change, must update model
// +------------------------------------------------------+
// | setting 0 : `define ALU_PARALLEL_DEFAULT
// +------------------------------------------------------+
// | setting 1 : `define ALU_PARALLEL_1
// |------------------------------------------------------|
// | setting 2 : `define ALU_PARALLEL_2
// |------------------------------------------------------|
// | setting 3 : `define ALU_PARALLEL_4
// |------------------------------------------------------|
// | setting 4 : `define ALU_PARALLEL_8
// |------------------------------------------------------|
`define ALU_PARALLEL_DEFAULT
// +------------------------------------------------------+
// | CONV RELU Type Configuration
// | It relates to model. if change, must update model
// +------------------------------------------------------+
// | `define CONV_RELU_RELU6
// +------------------------------------------------------+
// | `define CONV_RELU_LEAKYRELU_RELU6
// |------------------------------------------------------|
`define CONV_RELU_LEAKYRELU_RELU6
// +------------------------------------------------------+
// | ALU RELU Type Configuration
// | It relates to model. if change, must update model
// +------------------------------------------------------+
// | `define ALU_RELU_RELU6
// +------------------------------------------------------+
// | `define ALU_RELU_LEAKYRELU_RELU6
// |------------------------------------------------------|
`define ALU_RELU_RELU6
// |------------------------------------------------------|
// | DSP48 Usage Configuration
// | Use dsp replace of lut in conv operate
// | if change, Don't need update model
// +------------------------------------------------------+
// | `define DSP48_USAGE_HIGH
// +------------------------------------------------------+
// | `define DSP48_USAGE_LOW
// |------------------------------------------------------|
`define DSP48_USAGE_HIGH
// |------------------------------------------------------|
// | Power Configuration
// | if change, Don't need update model
// +------------------------------------------------------+
// | `define LOWPOWER_ENABLE
// +------------------------------------------------------+
// | `define LOWPOWER_DISABLE
// |------------------------------------------------------|
`define LOWPOWER_DISABLE
// |------------------------------------------------------|
// | DEVICE Configuration
// | if change, Don't need update model
// +------------------------------------------------------+
// | `define MPSOC
// +------------------------------------------------------+
// | `define ZYNQ7000
// |------------------------------------------------------|
`define MPSOC
Hardware Link Configの変更
Explorerからdpuprj_system_hw_link.prj
を開いてカーネルの個数の設定を変更します。
今回はsoftmaxコアは不要なのでsfm_xrt_topは削除し、DPUCZDX8Gの個数を2個から1個に変更しました。
makefileの生成
この時点でExplorerからdpuprj_system
を選択し、トンカチアイコンからHardware
を選択してHardwareビルドします。
恐らくサブプロジェクトのdpuprj_kernels
のみビルドに成功し、他は失敗するはずです。(後述するdpu-link.cfgのテンプレートに不要な文字が含まれているため)
ビルド試行によって、makefileが生成されればこの段階では十分です。
以降はVitis IDEは使用しないので閉じても問題ありません。
クロックとポート設定の変更
dpuprj_system_hw_link/Hardware/dpu-link.cfg
をテキストエディタで開いて修正します。このファイルはVitis IDEで修正したとしても、ビルド開始をすると自動的にテンプレートからコピーされて上書きされてしまいます。このためこれ以降の作業でVitis IDEからビルドを走らせることはありません。Vitis-AI公式のフローにも
The gui flow only support default configuration. if want to other configuration, please use commandline flow.
と書かれています。
私の環境ではテンプレートから作成されたdpu-link.cfg
に
[# * http://www]
apache.org/licenses/LICENSE-2.0
[# * Licensed under the Apache License, Version 2]
0 (the "License");
という部分が含まれており、cfgの形式として正しくないのでエラーになるのでこの部分を削除しました。
そのうえで、[clock], [connectivity]
を以下のように設定しました。
[clock]
#100, 150, 200, 300, 400
id=2:DPUCZDX8G_1.aclk
id=4:DPUCZDX8G_1.ap_clk_2
[connectivity]
nk=DPUCZDX8G:1:DPUCZDX8G_1
sp=DPUCZDX8G_1.M_AXI_GP0:HPC0
sp=DPUCZDX8G_1.M_AXI_HP0:HP0
sp=DPUCZDX8G_1.M_AXI_HP2:HP1
今回使用しているプラットフォームにはid=0から順に100, 150, 200, 300, 400[MHz]
のクロックが存在するので、上記の設定ではid=2,4
を指定しているのでDPUには200MHzと400MHzのクロックが設定されることになります。
dpu-link.cfg
の修正後、コマンドラインからmakeを実行します。DPUの搭載されたブロックデザインが自動的に生成され、合成が始まります。
cd <YOUR_DPUPRJ_DIR>/dpuprj_system_hw_link/Hardware
make
自動生成されたブロックデザインをVivadoで確認することもできます。
vivado ./dpu.build/link/vivado/vpl/prj/prj.xpr
ビルドにより生成されたdpuprj_system_hw_link/Hardware/dpu.xclbin
ファイルがKV260で使用するファイルになります。
xclbinにはビットストリームだけでなくIPのメモリアドレスの情報なども含まれています。
参考:FPGAカーネル超入門 (2)
これでVitisでDPUを搭載したデザインの作成は完了です。
dpuprj
にはresnet50を使用したサンプルアプリケーションが含まれています。Vitis-AI Libraryを含んだsysrootも設定しているのでビルドには成功しますが、使用されているxmodelファイル(DPU向けのモデルファイル)は今回使用したDPUのコンフィグレーションと異なるためそのままではアプリは動かないのでアプリケーション自体が不要です。
最後に、DPUのコンフィグレーション情報を表すJSONファイルを使い勝手の良い場所にコピーしておきます。
vai_c_tensorflow
やvai_c_pytorch
などのVitis-AIのツールを使ってDNNモデルをDPU向けにコンパイルする際にこのファイルが必要になります。
cp ./dpuprj_system_hw_link/Hardware/dpu.build/link/vivado/vpl/prj/prj.gen/sources_1/bd/design_1/ip/design_1_DPUCZDX8G_1_0/arch.json <VITIS_AI_REPO_DIR>/kv260_myarch.json
DPUを含んだデザインのロード確認
KV260上でDPUを含んだFPGAビットストリームの読み込みに成功するかを確認します。
ビルド+SDイメージの作成、ブート確認で作成したSDカードを使用してKV260を起動しておきます。
ビットストリームを含むDPUデザインを、KV260上で「アプリケーション」として登録するのに必要なファイルを集めてきます。
mkdir sd
cp dtg_output/pl.dtbo ./sd/
cp dpuprj/dpuprj_system_hw_link/Hardware/dpu.xclbin ./sd/
touch ./sd/shell.json
shell.json
は以下の内容で作成します。
{
"shell_type" : "XRT_FLAT",
"num_slots": "1"
}
用意したファイルをKV260に転送します。
scp -r ./sd petalinux@192.168.xxx.xxx:~/
以降はKV260で作業を行います。/lib/firmware/xilinx/
以下にファイルを格納することでアプリケーションユーティリティxmutil
にアプリケーションが認識されます。
cd ~/sd
sudo mkdir /lib/firmware/xilinx/dpuprj
sudo cp pl.dtbo shell.json /lib/firmware/xilinx/dpuprj/
sudo cp dpu.xclbin /lib/firmware/xilinx/dpuprj/binary_container_1.bin
xclbinに関しては拡張子を.bin
に変更する必要があるようです。
sudo xmutil listapps
sudo xmutil unloadapp #デフォルトのk26-starter-kitsをアンロード
sudo xmutil loadapp dpuprj
Loaded to slot 0
と表示されればビットストリームが書き込めています!
記事が長くなってしまったので、次の記事ではDPUでYOLOv4を動作させてみたいと思います。