プログラムdeタマゴ

nodamushiの著作物は、文章、画像、プログラムにかかわらず全てUnlicenseです

Vivadoに入門できない~DFXも分からない~

 Vivadoで DFX (PR)をやってみたので、メモ書き。私は何時になったらVivadoがわかるようになるのか………

デザインの用意

 まずは、元々作ってた Lチカデザインから、LED0を Lチカをするための RTLとポート を削除して、代わりに必要なクロックとリセットをデザインから外に出した、以下の様なデザインを作りました。

f:id:nodamushi:20220307112659p:plain:w320

 

 LED1はHLSでチカらせるサンプルコードで、今回は放置。JTAGやらも関係ない。

 PRしてる間、 LED が消えないことを確認する(書き込み中もFPGAが動作することを確認する)ためだけに乗っています。

※ RTLにするために分離したけど、2021ではしなくても良いのかな

 

 (ちなみに、私が使う必要があるのは2019なのだっ)

DFXプロジェクトにする

 以下のメニューからDFXプロジェクトに変換する。

f:id:nodamushi:20220307112906p:plain

 

 Enable Dynamic Function eXchange...を押して、プロジェクトをPRに対応させる。何かバージョンによってこのメニューの文字列が違うっぽい。

 TCLコンソールに流れるコマンドは以下。

set_property PR_FLOW 1 [current_project] 

 で、先ほど削除したmyrtlをsourceタブで右クリックして、Create Prtition Definition... を実行。

f:id:nodamushi:20220307113227p:plain:w320:w320

 しかしできなかった。 Topでアクティブになっていないとダメらしい。よく分からないけど、トップモジュールで接続しろって事なんでしょう。

f:id:nodamushi:20220307113857p:plain

 

 ということで、雑にトップ接続をした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

f:id:nodamushi:20220307141343p:plain

 再度ボタンを押すと………

f:id:nodamushi:20220307141442p:plain:w320

 …え、パラメタがだめ?……制限多いなっコンニャロウ!仕方がないので、myrtlの Tlocalparam にして再実行。

f:id:nodamushi:20220307141837p:plain

 パーティションの名前を設定する必要があるらしい。とりあえず、ledにしてOKを押しました。

 するとなんか、Partition Definitions というタブが追加された。

f:id:nodamushi:20220307142810p:plain:w320

 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を追加すれば良いらしい。

f:id:nodamushi:20220307143029p:plain

 

 画面は………よく意味分からないけど、Add Fileでmyrtl2を設定してみた。名前はmyled2にした。(同じだとわかりにくいから)

f:id:nodamushi:20220307145308p:plain:w320

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なので隠してます。)

f:id:nodamushi:20220307145026p:plain

 む、入れ子構造の中身が見えていない。

 なるほど、このmyrtl2っていうのは1つのビルド系になる、みたいなイメージなんだな。ソースファイルや制約ファイルとかも全部定義し直し、らしい。

f:id:nodamushi:20220307145616p:plain:w320

 

 RTLに必要なファイルを2つともAddしたら、上手く認識できてるっぽい。

f:id:nodamushi:20220307145731p:plain

 

ここまでを 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が勝手に表示される。

f:id:nodamushi:20220307152838p:plain:w320

 とりあえず、 automatically create configurations を押すと、以下の様になった。

f:id:nodamushi:20220307152930p:plain:w320

 とりあえず、この設定のままで Next を押すと、今度は Runの設定が出てくる。

f:id:nodamushi:20220307152950p:plain:w320

 良く分からないけど、ここでも取りあえず、 automatically create configuration run を押す。

f:id:nodamushi:20220307153104p:plain:w320

 で、良く分からないまま何か良さそうな気がするので、 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」を押す。

f:id:nodamushi:20220307153531p:plain:w320

 とりあえず、全く意味が分からないので X0Y0 を全部選択してみた。

f:id:nodamushi:20220307153657p:plain:w320

f:id:nodamushi:20220307153758p:plain:w320

 

 今回は1つしか作らないので、コレで設定は完了です。Ctrl+Sを押して、xdcファイルに書き出します。

f:id:nodamushi:20220307153952p:plain:w320

 中身

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を走らせると………はい、エラー

f:id:nodamushi:20220307155034p:plain:w320

 ………BSCANってなに?

japan.xilinx.com

 JTAG。ふむ?JTAGの何かを潰しちゃってる?どういうこと?

f:id:nodamushi:20220307160440p:plain:w320

 なんか、ここが怪しい。他の所にはないし。

 で、ここを拡大してみると………

 

f:id:nodamushi:20220307160336p:plain:w320

 あった、BSCAN!あと、上にICAPとかいうのもある。これもDFX用のモジュールで、ロジックからPRを行う場合に使うモジュールらしい。

 なるほど、偶然選んじゃいけないところを選んでしまったらしい。(X0Y0だもの………。選んじゃうよ。)

 というわけで、となりにお引っ越し。

f:id:nodamushi:20220307155954p:plain:w320

 で、もう一回implementを実行。おぉ、配置できた。

f:id:nodamushi:20220307160916p:plain:w320

 

書き込む

 プロジェクト.runs ディレクトリには色々と合成の結果とかが格納されていますが、必要なのはこの2つです。

f:id:nodamushi:20220310121116p:plain

 名前は以下から分かります。

f:id:nodamushi:20220310121200p:plain

 それぞれのディレクトリには、以下の様に2つのBitstream が出来ています。

f:id:nodamushi:20220310121325p:plain

 ●●_prtial.bit が DFXで使うビットストリームで、もう一方(今回はtop.bit)が全体です。

 というわけで、先ずは全体を書き込み。

f:id:nodamushi:20220307161339p:plain:w320

 この段階では、私が作ったRTL は3色LEDが一色ずつ点灯します。

 次に、myrtl2の方のPartial Bitstreamを書き込みます。選択するときにディレクトリと、bitを間違えないように注意。

f:id:nodamushi:20220310121724p:plain

 書き込んでみると、LED1側(DFXと無関係)はずっと光ったままでした。OKOK.

 で、LED0側が………

 f:id:nodamushi:20220310122134p:plain:w320

 f:id:nodamushi:20220310122330p:plain:w320

 あ、あれ?紫色と緑色!?

 本当は白(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 で復元できるようにしたのが以下です。

github.com