コスモリサーチの凄腕エンジニアたちが日々、難題と格闘した記録
Copyright Cosmo Research Corp.

複数の同一ブロックデザインを含むVivadoプロジェクトで、petalinuxからhdfファイルが読み込めないのを無理やり解決した話

現象(Vivado 2018.3)

Microblazeを含むプロジェクトでLinuxを使いたかったので、簡単に済ませるためにpetalinuxを使うことになった。が、petalinux-config --get-hw-description=<path>コマンドでなぜかhdfが読み込めない([Hsi 55-2019] XXX.hwh file is emptyとか言われる)。

該当のhdfファイルをzip解凍して見てみると、中身はこうなっていた。

合計 12M
-rw-r--r-- 1 saido saido 187K 2月  18 22:01 network_stack_bd.hwh
-rw-r--r-- 1 saido saido  18K 2月  18 22:01 network_stack_bd_bd.tcl
-rw-r--r-- 1 saido saido  12M 2月  18 22:01 RoXGE_udp.bit
-rw-r--r-- 1 saido saido 8.1K 2月  18 22:01 RoXGE_udp.mmi
-rw-r--r-- 1 saido saido 1.5K 2月  18 22:01 sysdef.xml

まぁ、Microblaze関連の諸々がないのでそりゃあエラーになるよな。
ちなみに、正常なhdfファイルの中身はこうなっているはず。

合計 14M
-rw-r--r-- 1 saido saido 676K 2月  15 18:47 microblaze_bd.hwh
-rw-r--r-- 1 saido saido 2.2M 2月  15 18:47 microblaze_bd_axi_smc_periph_0.hwh
-rw-r--r-- 1 saido saido 293K 2月  15 18:47 microblaze_bd_axi_smc_periph_0_bd.tcl
-rw-r--r-- 1 saido saido  41K 2月  15 18:47 microblaze_bd_bd.tcl
-rw-r--r-- 1 saido saido 274K 2月  15 18:47 microblaze_bd_ddr4_0_microblaze_mcs.hwh
-rw-r--r-- 1 saido saido  13K 2月  15 18:47 microblaze_bd_ddr4_0_microblaze_mcs_bd.tcl
-rw-r--r-- 1 saido saido 187K 2月  15 18:47 network_stack_bd.hwh
-rw-r--r-- 1 saido saido  18K 2月  15 18:47 network_stack_bd_bd.tcl
-rw-r--r-- 1 saido saido 9.4M 2月  15 18:47 RoXGE_udp.bit
-rw-r--r-- 1 saido saido 8.1K 2月  15 18:47 RoXGE_udp.mmi
-rw-r--r-- 1 saido saido 1.4K 2月  15 18:47 sysdef.xml

このプロジェクトでは、Microblaze用のブロックデザイン(microblaze_bd)の他に、UDP/IPプロトコルスタックのブロックデザイン(network_stack_bd)を含んでいた。ハードウェアとしては複数のEthernet用の口があるので、network_stack_bdを複数インスタンシエートしたら、hdfファイルがおかしくなった。

原因は不明だが、複数の同じブロックデザインを含むプロジェクトでは、hdfファイル(正確にはsysdefファイル)を作成するためのwrite_hwdefコマンドがエラーになるようだ。手元で適当に試すと以下のようになる。多分2回同じファイルを開こうとしてるんだと思う。

$ write_hwdef -force temp.hdf
zip_exception: zip archive temp.hwdef is already open for writingzip_exception: zip archive temp.hwdef is already open for writingzip_exception: zip archive temp.hwdef is already open for writingzip_exception: zip archive temp.hwdef is already open for writingzip_exception: zip archive temp.hwdef is already open for writingzip_exception: zip archive temp.hwdef is already open for writingzip_exception: zip archive temp.hwdef is already open for writingzip_exception: zip archive temp.hwdef is already open for writingzip_exception: zip archive temp.hwdef is already open for writingtemp.hwdef

対応

hdfファイルが単なるzip圧縮したファイルだということは知っていたので、必要なファイルを集めてzip圧縮すればいいや、と単純に考えたが、なぜかpetalinux-config --get-hw-description=<path>コマンドで弾かれる。

どうやら、改ざんされたhdfファイルかどうかをチェックしている模様。

だがしかし、試行錯誤の末、write_sysdefというコマンドを使ってhdfファイルを作成すればpetalinux-config --get-hw-description=<path>コマンドを騙せるということが分かった。なので、これを使ってhdfファイルを作れば良し。

今回のプロジェクトでは、以下のtclを実行してhdfファイルを作った。

# hdlで複数のブロックデザインを呼び出すとhwdef生成で
# バグって正常にhdfファイルを生成できなくなる。
#
# これを回避するために、hdfファイルを改ざんする。
# ただ、`petalinux-config --get-hw-description=<path>`コマンドでは
# hdfファイルの改ざんを検知するため、改ざんしたhdfファイルは使えない。
#
# 改ざんを隠蔽するためには、`write_sysdef`コマンドを使って
# hdfファイルを再生成する必要がある。

set target_dir hdf/modified
exec mkdir -p $target_dir

# 壊れたhdfファイル(sysdefファイルと同じ)の中身を吸い出す。(sysdef.xmlが欲しい)
# 事前にbitstreamを生成しておく必要がある。
exec unzip -o udp_ip_roxge/udp_ip_roxge.runs/impl_1/RoXGE_udp.sysdef -d $target_dir

# hdf作成に必要なファイルたちを集める。
set bd_base            udp_ip_roxge/udp_ip_roxge.srcs/sources_1/bd
set microblaze_bd      microblaze_bd/hw_handoff/microblaze_bd
set ddr4_mb_mcs        microblaze_bd/ip/microblaze_bd_ddr4_0/bd_0/hw_handoff/microblaze_bd_ddr4_0_microblaze_mcs
set microblaze_axi_smc microblaze_bd/ip/microblaze_bd_axi_smc_periph_0/bd_0/hw_handoff/microblaze_bd_axi_smc_periph_0
set network_stack_bd   network_stack_bd/hw_handoff/network_stack_bd

exec cp -f $bd_base/${microblaze_bd}.hwh         $target_dir/
exec cp -f $bd_base/${microblaze_bd}_bd.tcl      $target_dir/
exec cp -f $bd_base/${ddr4_mb_mcs}.hwh           $target_dir/
exec cp -f $bd_base/${ddr4_mb_mcs}_bd.tcl        $target_dir/
exec cp -f $bd_base/${microblaze_axi_smc}.hwh    $target_dir/
exec cp -f $bd_base/${microblaze_axi_smc}_bd.tcl $target_dir/
exec cp -f $bd_base/${network_stack_bd}.hwh      $target_dir/
exec cp -f $bd_base/${network_stack_bd}_bd.tcl   $target_dir/

# 改竄したhdfファイルをhwdefファイルとして生成する。(単にzip圧縮する)
exec zip -j ${target_dir}.hwdef $target_dir/*

# write_sysdefコマンドで本物のhdfファイルを作ってもらう。
write_sysdef -force \
    -hwdef   ./hdf/modified.hwdef \
    -bitfile ./hdf/modified/RoXGE_udp.bit \
    -meminfo ./hdf/modified/RoXGE_udp.mmi \
    ./modified.hdf

もう一つのバグ

Vivado 2018.3でMicroblazeを使用する場合、AR# 71948 UpdateMEM/SDK 2018.3 デザイン アドバイザリ – MicroBlaze および MicroBlaze MCS の MMI ファイルの生成が原因で発生していた機能的な問題を回避するための緊急パッチにハマるので必ずパッチを当てておく必要がある。
このパッチを当てないとMicroblazeが起動しない。

宣伝

上記の作業は、10GbE向けのUDP/IPプロトコルスタックの性能比較などを行うための実験の一貫だった(RoXGEというのは、RF over 10Gb Ethernetの略)。
コスモリサーチでは、RoF(Radio on Fiber 技術)を実現するためのボードを開発して、様々な実験を行っている。