KV260でのILAの使い方(Lチカの次に覚えたいこと)
この記事はHardware Description Language Advent Calendar 2024向けに書いた記事です。
はじめに
過去に下記のような幾つかの LEDチカチカ記事を書いてきましたので、引き続きの入門記事です。
今日は Lチカの次に覚えておきたい内容として、ILA(Integrated Logic Analyzer) を使った実機デバッグの方法や、シミュレーションの方法がありますので、今回は KV260 で ILA を使ってみる話を書きます。
FPGA 開発では他のソフトウェア開発と同様に、開発中に実機で実際に実行してみながらデバッグする事が出来ます。
実機で動かしてみる事で、データシートだけでは理解しずらい FPGA 内外のいろいろなデバイスの動作を理解したり、時にソフトウェアバグを解析するためのロジックを埋めたり、効率の良いデバッグツールとして活用していく事が出来ます。
また、非同期などで、シミュレーションではちゃんと動いているのに実機では動きがおかしいなんてこともしばしあります。
こんな時に、SystemVerilog などで書いた変数の中身を実機でも覗いてみたくなります。これを可能にするのが ILA(Integrated Logic Analyzer) です。
かつては Xilinx の合成ツールの主役が ISE というツールだった時代に ChipScope という名前で親しまれていた機能ですが、Vivado になり ILA という名前でツールに統合されています。
Verilog の中の信号を ILA で覗いてみる
今回はこちらを題材に説明していきます。
SystemVerilog の 変数を覗いてみるわけですが、論理合成ではしばしば最適化によって目的の変数の信号が変化してしまい、デバッグで覗きたい形と変わってしまう事があります。
それを抑止して、確実にデバッグ用に信号を最適化せずに残してくれる機能として Vivado には MARK_DEBUG という属性が用意されています。
LEDチカチカするカウンタなどの変数に、下記のように属性を設定して合成してみます。
// counter
(* MARK_DEBUG = "true" *) logic [26:0] counter = '0;
(* MARK_DEBUG = "true" *) logic [7:0] led = '0;
always_ff @(posedge clk) begin
counter <= counter + 1'b1;
if ( counter >= 27'(100_000_000 - 1) ) begin // 1秒をカウントする
counter <= '0;
led <= led + 1'b1;
end
end
合成で来たら 「Open Synthesized Design」を選んで、合成済みデザインを開いて、「Layout」から「Debug」を選びます。
そうすると、MARK_DEBUG 属性の信号が出てきますので、右クリックして「Set Up Debug」を選びます。
「Set Up Debug」ダイアログが出てくるので「Next」を選ぶと、「Nets to Debug」に進みます。ここでデバッグで観測したい信号を追加したり削除したりします。
観測したい信号の数が増えると埋め込まれるロジックアナライザユニットの規模が大きくなっていくので、ここで取捨選択します。今回はすべてそのまま観測するのでそのまま「Next」を押します。
「ILA Core Options」に進むので、ここで信号を観測する時間の長さや、高度なトリガを使うかどうかなどを設定します。
今回はそのまま 「Next」を押して、最後に「Finish」を押します。
保存すると設定が xdc ファイルに保存されます。
今回は下記のような内容が書き出されました。
create_debug_core u_ila_0 ila
set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0]
set_property ALL_PROBE_SAME_MU_CNT 1 [get_debug_cores u_ila_0]
set_property C_ADV_TRIGGER false [get_debug_cores u_ila_0]
set_property C_DATA_DEPTH 1024 [get_debug_cores u_ila_0]
set_property C_EN_STRG_QUAL false [get_debug_cores u_ila_0]
set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0]
set_property C_TRIGIN_EN false [get_debug_cores u_ila_0]
set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0]
set_property port_width 1 [get_debug_ports u_ila_0/clk]
connect_debug_port u_ila_0/clk [get_nets [list u_design_1/zynq_ultra_ps_e_0/inst/pl_clk0]]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0]
set_property port_width 8 [get_debug_ports u_ila_0/probe0]
connect_debug_port u_ila_0/probe0 [get_nets [list {led[0]} {led[1]} {led[2]} {led[3]} {led[4]} {led[5]} {led[6]} {led[7]}]]
create_debug_port u_ila_0 probe
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe1]
set_property port_width 27 [get_debug_ports u_ila_0/probe1]
connect_debug_port u_ila_0/probe1 [get_nets [list {counter[0]} {counter[1]} {counter[2]} {counter[3]} {counter[4]} {counter[5]} {counter[6]} {counter[7]} {counter[8]} {counter[9]} {counter[10]} {counter[11]} {counter[12]} {counter[13]} {counter[14]} {counter[15]} {counter[16]} {counter[17]} {counter[18]} {counter[19]} {counter[20]} {counter[21]} {counter[22]} {counter[23]} {counter[24]} {counter[25]} {counter[26]}]]
set_property C_CLK_INPUT_FREQ_HZ 300000000 [get_debug_cores dbg_hub]
set_property C_ENABLE_CLK_DIVIDER false [get_debug_cores dbg_hub]
set_property C_USER_SCAN_CHAIN 1 [get_debug_cores dbg_hub]
connect_debug_port dbg_hub/clk [get_nets clk]
あとはそのまま、配置配線まで実行して bitstream を生成します。
bitstream のダウンロード
単独の Artix や Spartan などのように Hardware Manager から bitstream をプログラムして動かす方法もありますが、ZynqMP などでは PS と共存できるのがメリットです。また、しばし Hardware Manager からのダウンロードは PS で実行中の Linux のカーネルパニックなどを誘発するケースもあるので、ここは Linux カーネルにある FPGA Manager を経由してダウンロードしましょう。
ダウンロード方法各種はこちらなどでも記事にしています。
なお、Linux の環境によっては ブート時のオプションに cpuidle.off=1 を指定しておく必要がある場合があります。こちらなどを参考にしてください。
Hardware Manager での接続
KV260 の USB を PC に接続しておきます。ケーブルドライバーのインストールが出来ている必要があります。Windows だと Vivado のインストール時に入っていると思いますが、Linux だと忘れがちなのでこちらなどを参考にしてください。
Flow Navigater から 「Open Hardware Manager」をクリックします。
Auto Connect で接続できるケースが多いと思いますが、「Open New Target」から詳しい設定をしたり、hw_server を使ってネットワーク越しに繋ぐことも出来ます。
xck26_0 のようなものが見えていればOKです。
接続がうまく行くと、xck26_0 の下に hw_ila_1 が見えます。
信号が表示されていない場合は 「+」ボタンを押して信号を追加して、「▶」ボタンを押すと現在の波形を覗くことが出来ます。
ここで見たい部分の波形を見る上でトリガ機能が重要です。
今回は led 信号の最下位ビットの立ち上がり (Rise) で、トリガがかかるように二進数(Radix = [B])で XXXX_XXXR をトリガ条件にしています。
ここで X は無視する意味で、トリガには 0, 1, R, F, B などが利用できます。
(おまけ) Block Designer で ILA を追加してみる
ここで下記の記事で使った PS から LEDチカチカするサンプルの Block Designer 部分にILA を追加してみたいと思います。
Block Designer の画面で 「ILA」 を探して追加してください。
生成した ILA に AXI バスを繋ぐことが出来ます。
ILA のキャプチャする信号の長さなど設定できます。
同様に接続するとAXIバスが観測できます。
例えば AWVALID にトリガーを仕掛けると、PS から書き込みを行ったときの波形を観測できます。
このサンプルは LED チカチカなので、0 と 1 を書くシングルアクセスを繰り返すだけですが、ここからいろいろな回路を自分で書きながら AXI バス仕様の勉強をするのにも役立ちます。
なお、該当するコードはここにあります。
おわりに
非常にざっくりではあるのですが、Linux など使って PS からのダウンロードをしている場合でも、きちんと気を付けて使えば ILA が使えるようなので、デバッグのお供にお勧めです。
ただし、Linux の都合を無視して PC 側から不用意に書き換えたり、逆にPCから ILA 操作中に、Linux から PL を書き換えたりすると不安定になるケースもあるようですので気を付けて使う事が重要そうです。
また、Hardware Manager で接続していると Linux がうまく起動しないケースもあるようです。
もし急に起動しなくなったら、一度 USBケーブルを抜いて、起動するかどうか試してみてください。
それでは、楽しい FPGA ライフをお送りください。
Discussion