Vivadoで DFX (PR)をやってみたので、メモ書き。私は何時になったらVivadoがわかるようになるのか………
デザインの用意
まずは、元々作ってた Lチカデザインから、LED0を Lチカをするための RTLとポート を削除して、代わりに必要なクロックとリセットをデザインから外に出した、以下の様なデザインを作りました。
LED1はHLSでチカらせるサンプルコードで、今回は放置。JTAGやらも関係ない。
PRしてる間、 LED が消えないことを確認する(書き込み中もFPGAが動作することを確認する)ためだけに乗っています。
※ RTLにするために分離したけど、2021ではしなくても良いのかな
あと2021.2あたりでBlock Design ContainerのDFX対応入ったので、RTLじゃなくてもいいはず。
— Kenta IDA (@ciniml) March 10, 2022
(ちなみに、私が使う必要があるのは2019なのだっ)
DFXプロジェクトにする
以下のメニューからDFXプロジェクトに変換する。
Enable Dynamic Function eXchange...を押して、プロジェクトをPRに対応させる。何かバージョンによってこのメニューの文字列が違うっぽい。
TCLコンソールに流れるコマンドは以下。
set_property PR_FLOW 1 [current_project]
で、先ほど削除したmyrtlをsourceタブで右クリックして、Create Prtition Definition... を実行。
しかしできなかった。 Topでアクティブになっていないとダメらしい。よく分からないけど、トップモジュールで接続しろって事なんでしょう。
ということで、雑にトップ接続をしたRTLを作ります。(※古いバージョンではRTLじゃないとダメ)
`timescale 1 ps / 1 ps module top ( output wire [2:0] led0, output wire [2:0] led1, input wire reset, input wire sys_clock); wire aclk; wire aresetn; myrtl#(.T(50 * 1000 * 1000)) myrtl( .clk(aclk), .resetn(aresetn), .led(led0) ); design_1_wrapper design_1( .aclk(aclk), .aresetn(aresetn), .led1(led1), .reset(reset), .sys_clock(sys_clock)); endmodule
再度ボタンを押すと………
…え、パラメタがだめ?……制限多いなっコンニャロウ!仕方がないので、myrtlの T
を localparam
にして再実行。
パーティションの名前を設定する必要があるらしい。とりあえず、ledにしてOKを押しました。
するとなんか、Partition Definitions というタブが追加された。
TCLコンソールには以下が実行されてた。
update_compile_order -fileset sources_1 create_partition_def -name led -module myrtl create_reconfig_module -name myrtl -partition_def [get_partition_defs led ] -define_from myrtl
PR に他のモジュールを追加
同じ領域に別のRTLを差し込む(DFX)には、 Add Reconfiguarable Module からRTLを追加すれば良いらしい。
画面は………よく意味分からないけど、Add Fileでmyrtl2を設定してみた。名前はmyled2にした。(同じだとわかりにくいから)
update_compile_order -fileset sources_1 create_reconfig_module -name myled2 -partition_def [get_partition_defs led ] add_files -norecurse ■■■■■/src/rtl/myrtl2.v -of_objects [get_reconfig_modules myled2]
(■は私のPCのPathなので隠してます。)
む、入れ子構造の中身が見えていない。
なるほど、このmyrtl2っていうのは1つのビルド系になる、みたいなイメージなんだな。ソースファイルや制約ファイルとかも全部定義し直し、らしい。
RTLに必要なファイルを2つともAddしたら、上手く認識できてるっぽい。
ここまでを CMake化
ひとまず、ここまでをCMakeから復元できるか試してみます。デザインファイルを読み込んだ後に、以下のTCLコマンドを実行するように変更しました。
set_property PR_FLOW 1 [current_project] create_partition_def -name led -module myrtl create_reconfig_module -name myrtl -partition_def [get_partition_defs led ] -define_from myrtl create_reconfig_module -name myled2 -partition_def [get_partition_defs led ] add_files ${root}/src/rtl/myrtl2.v \ ${root}/src/rtl/_myrtl2.sv \ -of_objects [get_reconfig_modules myled2] update_compile_order
update_compile_order
は実行すべきなのか、いつやるのかよく分からない。
とりあえず、これで再度プロジェクトを生成し直してみると、同様の設定で復元されました。よしよし。
Configuration 定義
ここまで来たら、一度合成を実行する。合成が完了して、Open Synthesized Design を押すと、以下のEdit Configurationsが勝手に表示される。
とりあえず、 automatically create configurations を押すと、以下の様になった。
とりあえず、この設定のままで Next を押すと、今度は Runの設定が出てくる。
良く分からないけど、ここでも取りあえず、 automatically create configuration run を押す。
で、良く分からないまま何か良さそうな気がするので、 Nextを押して完了する。
TCL コンソールには以下が実行されていた。
create_pr_configuration -name config_1 -partitions [list myrtl:myrtl ] create_pr_configuration -name config_2 -partitions [list myrtl:myled2 ] set_property PR_CONFIGURATION config_1 [get_runs impl_1] create_run child_0_impl_1 -parent_run impl_1 -flow {Vivado Implementation 2021} -pr_config config_2
リージョン定義
このまま、PRの場所の定義をする。
PRするモジュールを右クリックして「Floorplanning」→「Draw Pblock」を押す。
とりあえず、全く意味が分からないので X0Y0 を全部選択してみた。
今回は1つしか作らないので、コレで設定は完了です。Ctrl+Sを押して、xdcファイルに書き出します。
中身
startgroup create_pblock pblock_myrtl resize_pblock pblock_myrtl -add CLOCKREGION_X0Y0:CLOCKREGION_X0Y0 add_cells_to_pblock pblock_myrtl [get_cells [list myrtl]] -clear_locs endgroup close [ open F:/Workspace/xilinx/study/study/vivado/dfx.xdc w ] add_files -fileset constrs_1 ■■■■■/vivado/dfx.xdc set_property target_constrs_file ■■■■■//vivado/dfx.xdc [current_fileset -constrset] save_constraints -force
保存した制約ファイルの追加自体は普通に add_files -fileset constrs_1
でいいっぽい
Implementをして見るも失敗
で、implementを走らせると………はい、エラー
………BSCANってなに?
JTAG。ふむ?JTAGの何かを潰しちゃってる?どういうこと?
なんか、ここが怪しい。他の所にはないし。
で、ここを拡大してみると………
あった、BSCAN!あと、上にICAPとかいうのもある。これもDFX用のモジュールで、ロジックからPRを行う場合に使うモジュールらしい。
なるほど、偶然選んじゃいけないところを選んでしまったらしい。(X0Y0だもの………。選んじゃうよ。)
というわけで、となりにお引っ越し。
で、もう一回implementを実行。おぉ、配置できた。
書き込む
プロジェクト.runs ディレクトリには色々と合成の結果とかが格納されていますが、必要なのはこの2つです。
名前は以下から分かります。
それぞれのディレクトリには、以下の様に2つのBitstream が出来ています。
●●_prtial.bit が DFXで使うビットストリームで、もう一方(今回はtop.bit)が全体です。
というわけで、先ずは全体を書き込み。
この段階では、私が作ったRTL は3色LEDが一色ずつ点灯します。
次に、myrtl2の方のPartial Bitstreamを書き込みます。選択するときにディレクトリと、bitを間違えないように注意。
書き込んでみると、LED1側(DFXと無関係)はずっと光ったままでした。OKOK.
で、LED0側が………
あ、あれ?紫色と緑色!?
本当は白(RGB全部)→消灯(RGB消灯)を繰り返すつもりだったのが何故か「RB点灯」→「G点灯」を繰り返しています。
ちなみに、点滅部分のコードは以下。
always_ff @(posedge clk) begin if (!resetn) led <= 0; // 0初期化 else if (counter >= T) led <= ~led; // 分周して、反転するだけ end
これ、PR時にFFの値が初期化されてないな?
後で教えてもらったのですが、7seriese だと PR してもリセットが入らないそうです。 https://japan.xilinx.com/support/documentation/sw_manuals_j/xilinx2020_2/ug909-vivado-partial-reconfiguration.pdf#page=34
リセットをするには、以下の制約を設定しておくみたいです。
set_property RESET_AFTER_RECONFIG true [get_pblocks <reconfig_pblock_name>]
(※ただ、今回は私は、リージョンの範囲を中途半端に指定したため、この設定が出来ませんでした。)
CMake化
ここまでの作業を CMake で復元できるようにしたのが以下です。