Lattice Radiant SoftwareではFPGAの中の動作をRevealというコアで観測することができます.Xilinx/AMDのFPGAであればChipscopeやILA,IntelのFPGAであればSignalTapという名前のアレです.この記事では,exLeaf-iを使った開発でRevealを使う手順を紹介します.
準備
まずはプロジェクトを用意します.一通りの開発手順は Radiant SoftwareでexLeaf-i開発をする を参考にしてください.この記事ではプロジェクト名はreveal_testとしました.ソースコードは次のようなLチカに一つ入力ポートを追加したものです.
module top(
input wire CLK,
input wire RESET,
output wire CLKEN,
output wire LED0,
output wire LED1,
output wire LED2,
input wire BTN1,
output wire [3:0] PMOD3B
);
assign CLKEN = 1'b1;
(* keep*) reg [31:0] counter = 32'h0;
reg [2:0] q = 3'b001;
assign PMOD3B = counter[23:20];
always @(posedge CLK) begin
counter <= counter + 1;
end
wire ENABLE_LED = 1'b1;
wire led_power_up = 1'b1;
wire RGB0;
wire RGB1;
wire RGB2;
assign RGB0 = counter[22];
assign RGB1 = counter[21];
assign RGB2 = counter[20];
RGB#(.CURRENT_MODE(0),
.RGB0_CURRENT("0b111111"),
.RGB1_CURRENT("0b111111"),
.RGB2_CURRENT("0b111111")
) RGB_DRIVER(
.RGBLEDEN(ENABLE_LED),
.RGB0PWM(RGB0),
.RGB1PWM(RGB1),
.RGB2PWM(RGB2),
.CURREN(led_power_up),
.RGB0(LED0),
.RGB1(LED1),
.RGB2(LED2)
);
endmodule // top
このコードの counter
をRevealで観測してみましょう.
Revealコアの挿入
Revealでデバッグする際にはプロジェクトにRevealコアを挿入する必要があります.Revealコアを挿入するには,まず,ツールバーからコアのインサータを起動します.Tools -> Reveal Inserterをクリックしてください.
次のようにRevealコアのインサータが起動します.
まずは,Trace Signal SetupペインのTraceに,観測対象の信号を追加します.中央に並んでいる信号をドラッグアンドドロップして追加することができます.次の図は counter
と BTN1
をTraceに追加したところです.また,これらのクロックとして CLK
を Trace Signal Setupの Sample Clockフィールドにドラッグアンドドロップしてセットしました.
次に,トリガのセットアップをします.Trace Signal Setupの右のTrigger Signal Setupを選択し,ペインを切り替えます.Trigger Signal Setupでは,トリガユニット(TU)とトリガ式(TE)の二つを指定します.TUはトリガ信号と条件,TEはTUが発動する関係式を設定します.
TUには,トリガの元になる信号をドラッグアンドドロップでセットし,トリガ条件をOperatorとValueでセットします.次の図は,トリガの元となる信号として BTN1
を指定し,この信号が0のときをトリガ条件として設定したところです.
TUは複数用意することができます(もちろん一つでも構いません).TUをセットしたらTEを定義します.TEでは,TUを組み合わせてトリガの発動条件を定義します.Expressionフィールドに式を入力して設定します.次の図は二つのTUを定義し,それらが共に成立した場合( &
)の場合に,トリガが発動するという設定の例です.TUがどちらも同じ設定なので意味がありませんが.
一つのTUの条件が成立したときにトリガを発動したければ,単にそのTU名をExpressionフィールドに設定しておけばOKです.&
や |
を利用することができます.
これでRevealコアの設定は完了です.Ctrl-sなどで保存します.名前はわかりやすければなんでも構いません.今回は,デフォルトのままreveal_test.rvlで保存しました.
コアを作ったらプロジェクトに登録します.Radiantの左ペインのプロジェクトツリーの Debug Filesで右クリックしてコンテクストメニューを開き,Add -> Exsiting File… としてファイルを追加します.
追加するのは,先ほど作成したrvlファイルです.
次のようにプロジェクトにrvlファイルが登録されました.
プロジェクトの準備が整ったので,合成します.合成は,ツールバー左端の緑色の三角ボタンをクリックすればOKです.
注意
Verilogでコードを書いている人の中には,`default_nettype none
などとして信号名のスペルミスを防いでいる人もいると思います.Revealを使う場合トップモジュールにこの記述があると合成に失敗します(2022年7月現在).これは,ツールがトップモジュールにRevealコアを追加したラッパーモジュールを作るのですが,そこで wire
と定義されていないポートを出力するからです.あきらめて `default_nettype none
の使用をあきらめましょう(少なくともファイルの最後に `default_nettype wire
と書いてもダメでした)
ピン配置の指定
合成がおわってDevice Constraint Editorを開くと,自分が定義した入出力ピン以外にRevealでFPGA内部にアクセスするための JTAG_{TMS,TDI,TDO,TCK}
が追加されている様子が確認できます.これらのピンを自分で設定できる/しなければならない,のは面白いですね.
exLeaf-iでは,Flash ROM書き込み用のピンは動作時には使いません.そこで,今回はFlash ROM書き込み用のピンをRevealを使う場合のピンとして再利用することにします.
具体的なピン配置の設定は次の通りです.Device Constraint Editorを使って指定してもいいですし,このファイルをプロジェクトに追加しても構いません.
ldc_set_location -site {16} [get_ports JTAG_TMS]
ldc_set_location -site {14} [get_ports JTAG_TDI]
ldc_set_location -site {15} [get_ports JTAG_TCK]
ldc_set_location -site {17} [get_ports JTAG_TDO]
ldc_set_location -site {48} [get_ports {PMOD3B[0]}]
ldc_set_location -site {46} [get_ports {PMOD3B[1]}]
ldc_set_location -site {44} [get_ports {PMOD3B[2]}]
ldc_set_location -site {42} [get_ports {PMOD3B[3]}]
ldc_set_location -site {34} [get_ports CLKEN]
ldc_set_location -site {35} [get_ports CLK]
ldc_set_location -site {39} [get_ports LED0]
ldc_set_location -site {40} [get_ports LED1]
ldc_set_location -site {41} [get_ports LED2]
ldc_set_location -site {6} [get_ports BTN1]
ピン配置を決めたら,再度,合成と配置配線をおこなってFPGA用のbitファイルを作成します.
Flash ROMへの書き込み
作成したbitファイルをFlash ROMに書き込みます.書き込み方法はRadiant SoftwareでexLeaf-i開発をする を参考にしてください.書き込み前に,ディップスイッチの1番をONにするのを忘れないようにしてください.
Revealでコアの内部を観測する
Flash ROMにbitファイルを書き込んだら,一度exLeaf-iへの電源供給を切断しプログラミングアダプタもとりはずします.ディップスイッチの1番をOFFにして電源を供給するとLEDがチカチカ点滅しはじめるはずです.
この状態で,プログラミングアダプタを再度接続します.接続はFlash ROM書き込み時と同じです(同じになるようにRevealのJTAGのピン配置を設定した)
では内部状態の観測を始めましょう.メニューから Reveal Analyzerを起動します.Tools -> Reveal Analyzer/Controllerとクリックします.
次のようにReveal Analyzerのセットアップウィザードが開きます.Create a new file を選択し,使用するプログラミングアダプタ(ここでは HW-USBN-2B)とUSBポート(ここではFTUSB-0)を適切に設定します.RVL sourceにはRevealコアインサータで作ったファイルを設定します.設定したらOKをクリックしてウィザードを閉じましょう.
Revealアナライザが起動しました.インサータで起動したTUやTEが表示されています.TEは利用するものを選択できます.今回は一つしかないので,必然的にその一つを選択することになります.Ready右の再生ボタン(のような緑地に白い三角のアイコン)をクリックするとトリガ待ち状態になります.
トリガ条件はBTN1が 0
であることです.ディップスイッチの1番をONにしてBNT1を 0
にしてみると,次のようにトリガが発動してFPGA内部の信号を取り込むことができました.
拡大して,counterの表示をHexにするとカウントアップしている様子が確認できます.
おわりに
今回は,Radiantに付属のRevealを使ってexLeaf-i内部の様子を観測する方法を紹介しました.JTAGポートのピン配置を自分で設定しないといけない,というのが,他のベンダのFPGAに慣れている人にとっては,一風変わっているでしょうか.
Revealではトリガ発動時の信号取り込み用に内部のBlock RAM(EBR)を利用します.exLeaf-iに搭載しているiCE40UP5KのEBRは決して潤沢といえるほどにはありません.本番ロジックに手軽にRevealを入れておくというような使い方は難しいかもしれませんが,それでも実機でデバッグできるのは便利です.工夫して活用してみてください.
コメント