4
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

KV260向けにVitisプラットフォームを作成してDPUを動かす その1 (Vitis 2022.1 + Vitis-AI v2.5)

Last updated at Posted at 2022-09-20

ようやくKV260ボードを手に入れました。
KV260向けにはkv260-smartcamなどのスタートキットのSDイメージを使用することで既にDPUが搭載されたアプリケーションを試すことができます。しかしながら、DPUのコンフィグレーションを変更したり、DPU以外に自作の回路を足すなど色々としたいので、自分でプラットフォームを作ってDPUを搭載することにしました。

参考

今回の作業を行うにあたって、たくさんの記事を参考にさせていただきました。ありがとうございます。Vitis2022.1 + KV260向けの記事はいくつか存在し、それぞれ微妙に手順は異なりますが、概ね手順は同じです。本記事の手順も参考記事をベースにしています。

環境

各環境のインストール手順は省略します。

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に設定しました。
Screenshot from 2022-09-20 23-57-15.png

  • 完成したブロックデザイン
    Screenshot from 2022-09-20 23-56-41.png
  • プラットフォームのクロック設定
    Screenshot from 2022-09-20 23-57-35.png
  • プラットフォームのAXIポート設定
    Screenshot from 2022-09-20 23-57-29.png

参考記事同様にビットストリームを生成し、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を有効化
    Screenshot from 2022-09-21 00-35-33.png
    今回は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のファームウェアを更新してください。

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は空欄のままにしました。
Screenshot from 2022-09-21 01-00-15.png
ビルドはすぐに終わります。

<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

Screenshot from 2022-09-21 01-28-12.png

File->New->Application Projectからプロジェクトを作成します。プロジェクト名は今回はdpuprjとしました。ベースとなるプラットフォームは先程作成したプラットフォームを選択します。

sysrootに先程sdk.shを実行して展開したsysrootディレクトリの中のcortexa72-cortexa53-xilinx-linuxディレクトリを設定します。
Screenshot from 2022-09-21 01-32-01.png
テンプレートからDPU Kernelを選択して、プロジェクトを作成します。
Screenshot from 2022-09-21 01-33-34.png

dpuコンフィグレーションの変更

Explorerウインドウのdpu_trd_kernelsからsrc->prj->Vitis->dpu_conf.vhを開いてDPUのコンフィグレーションを変更します。

Screenshot from 2022-09-21 01-35-01.png

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個に変更しました。

Screenshot from 2022-09-21 01-38-58.png

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

指定したとおりのクロックとポートが設定されていました。
Screenshot from 2022-09-21 01-54-58.png

ビルドにより生成された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_tensorflowvai_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を動作させてみたいと思います。

4
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?