lp6m’s blog

いろいろかきます

KV260でVexRiscv動作させた

自分用メモで超手抜き記事です。

rv32imfacアーキテクチャRISC-Vを動作させる。ARMコアからFPGA上に実装したRISC-Vコアを制御する。
Ultra96-V2で動かすための方法は以下リポジトリに(そこそこ詳しく?)まとめています。ほとんど同じです。

github.com

使用するSDイメージ

KV260向けにVitisプラットフォームを作成してDPUを動かす その1 (Vitis 2022.1 + Vitis-AI v2.5) - Qiitaで作ったSDイメージのpetalinuxプロジェクトを基にする。
上記記事のSDイメージではgeneric-uioドライバが有効化されていなかった。後から有効化する方法がよくわからなかったのでとりあえずbootargsを変更して再ビルドしてSDイメージを再生成した。

project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi の修正
bootargsの末尾にuio_pdrv_genirq.of_id=generic-uioを追加
再ビルドしてSDイメージ再生成

petalinux-build
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"

ブロックデザイン

KV260向けにVitisプラットフォームを作成してDPUを動かす その1 (Vitis 2022.1 + Vitis-AI v2.5) - Qiitaで作ったブロックデザインを元にRISC-Vコアを追加した。

ブロックデザイン

pl_clk1は150MHzに設定した。BRAMのサイズやAXI BRAM Controllerなどに設定するメモリアドレスはUltra96-V2のときと同じにした。

プラットフォームをriscv_base_prj.xsaとして生成した。

binの生成

Ultra96-V2のときはpetalinuxで起動時に書き込まれるビットストリームを RISC-Vのものしていたが、KV260ではデバイスツリーオーバレイを使って起動後にビットストリームを書き込むのが標準(?)らしい。
このため手順が異なる。参考: FPGAの部屋 kv260_median_platform のメディアン・フィルタを KV260 の Petalinux から動作させる14

bootgenを使ってビットストリームをbinに変換する。

mkdir bit
cd bit
cp ../vivado/riscv_base_prj/riscv_base_prj.bit system.bit
echo 'all:{system.bit}'>bootgen.bif
bootgen -w -arch zynqmp -process_bitstream bin -image bootgen.bif
mv system.bit.bin riscv_base_prj.bit.bin

pl.dtsiの生成

バイスツリーを生成する。

xsct
createdts -hw vivado/riscv_base_prj/riscv_base_prj.xsa -zocl -platform-name mydevice -git-branch xlnx_rel_v2022.1 -overlay -compile -out mydevice
exit

pl.dtsiの修正

AXI Bram Controllerのデフォルトのドライバはxlnx,axi-bram-ctrl-4.1になっているがgeneric-uioで制御したいのでdtsiファイルを修正する。

mydevice/mydevice/mydevice/psu_cortexa53_0/device_tree_domain/bsp/pl.dtsiを開く

diff pl.dtsi.old ./mydevice/mydevice/mydevice/psu_cortexa53_0/device_tree_domain/bsp/pl.dtsi
54c54
< 				compatible = "xlnx,axi-bram-ctrl-4.1";
---
> 				compatible = "generic-uio";
75c75
< 				compatible = "xlnx,axi-bram-ctrl-4.1";
---
> 				compatible = "generic-uio";

pl.dtsiをコンパイルしてdtboの作成

mkdir device_tree
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
cp mydevice/mydevice/mydevice/psu_cortexa53_0/device_tree_domain/bsp/pl.dtbo device_tree/riscv_base_prj.dtbo

KV260に送るファイルの用意

binファイルとdtboファイル、shell.jsonファイルを1つのディレクトリにまとめる

mkdir riscv_base_prj
cp bit/riscv_base_prj.bit.bin riscv_base_prj
cp device_tree/riscv_base_prj.dtbo riscv_base_prj
touch riscv_base_prj/shell.json

shell.jsonの中身は以下

{
  "shell_type" : "XRT_FLAT",
  "num_slots": "1"
}

KV260に送る

scp -r riscv_base_prj petalinux@192.168.xxx.xxx:~/

KV260でのロード

FPGAビットストリームおよびデバイスツリーを読み込む。

sudo cp -r riscv_base_prj /lib/firmware/xilinx/
sudo xmutil listapps
sudo xmutil unloadapp
sudo xmutil loadapp riscv_base_prj

uioを確認すると、uio4, uio5が新たに増えていた。

RISC-Vコア動作確認

VexRiscv_Ultra96/petalinux at dev · lp6m/VexRiscv_Ultra96 · GitHubでも使用した、floatの足し算を行うテストプログラムを実行しようと思う。
test.cppを2点修正する必要がある。
テストプログラムでは100個のfloatの足し算のテストを行うが、1回のテストごとにRISC-Vコア(+ブロックRAMやAXI Interconnectなどすべて)をリセットする。
上で示したブロックデザインの通り、RISC-Vコアのリセットはpl_rstn1に接続されている。これをPSコアから接続するためのGPIOの番号がUltra96-V2の時と異なる。
参考: lp6m.hatenablog.com

KV260でGPIO情報を見ると以下のように表示される。

xilinx-kv260-starterkit-20221:/home/petalinux# cat /sys/kernel/debug/gpio 
gpiochip1: GPIOs 0-173, parent: platform/ff0a0000.gpio, zynqmp_gpio:
 gpio-0   (QSPI_CLK            )
 gpio-1   (QSPI_DQ1            )
 gpio-2   (QSPI_DQ2            )
 gpio-3   (QSPI_DQ3            )
 gpio-4   (QSPI_DQ0            )
 gpio-5   (QSPI_CS_B           )
 gpio-6   (SPI_CLK             )
 gpio-7   (LED1                |heartbeat           ) out lo 
 gpio-8   (LED2                |vbus_det            ) out hi 

上記ブログ記事を参考にすれば、デバイスに認識されているGPIOの番号がUltra96-V2がgpio-338からgpio-511だったのが、KV260ではgpio-0からgpio-173であることがわかった。(数は同じ174個)
というわけで、pl_rstn1を操作するにはgpio-172を操作すればいい。
下記テストプログラムの510を全て172に変更する。
VexRiscv_Ultra96/test.cpp at dev · lp6m/VexRiscv_Ultra96 · GitHub

また、AXI BRAM Controllerはuio4, uio5として認識されているので、デバイスオープンの/dev/uio0, /dev/uio1/dev/uio4, /dev/uio5に変更する。

FPU含めて動作完了!