KV260でVexRiscv動作させた
自分用メモで超手抜き記事です。
rv32imfacアーキテクチャのRISC-Vを動作させる。ARMコアからFPGA上に実装したRISC-Vコアを制御する。
Ultra96-V2で動かすための方法は以下リポジトリに(そこそこ詳しく?)まとめています。ほとんど同じです。
使用する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でのロード
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含めて動作完了!