Helioボード: システムコンソール入門
はじめに
Quartus II付属のシステムコンソールを用いると、FPGA側のLEDなどのペリフェラルに対して簡単に状態取得や制御ができます。(今日知りました^^;) システムコンソールは、SoCボードのLinuxを停止した状態でも使えるため、回路単体でのデバッグに重宝しそうです。今回は、システムコンソールからLチカ、プッシュボタンの状態取得、オンチップメモリーの読み書きを試してみます。
flickr: Arashiyama Bamboo Forest in Sagano, Kyoto, Japan
システムコンソールとは
Quartus IIに付属するコマンドラインツールです。Tcl言語のコマンドを専用コンソールに入力することで、FPGAボードと対話的にやりとりできます。これにより、デバッグの効率を上げることができます。裏ではJTAGを通して通信が行われます。
準備
HelioボードのJTAGポートとPCをUSBケーブルで接続します。
Quartus IIのProgrammerでFPGAに回路を転送します。
Quartus II -> Tools -> System Debugging Tools -> System Consoleを選択します。
Tcl Consoleに以下のコマンドを入力します。
% get_service_paths master /devices/5CSE(BA5|MA5)|5CSTFD5D5|..@2#USB-1#Helio/(link)/JTAG/sldfabric.node_1/phy_0/f2sdram_only_master.master /devices/5CSE(BA5|MA5)|5CSTFD5D5|..@2#USB-1#Helio/(link)/JTAG/sldfabric.node_2/phy_1/fpga_only_master.master /devices/5CSE(BA5|MA5)|5CSTFD5D5|..@2#USB-1#Helio/(link)/JTAG/sldfabric.node_3/phy_2/hps_only_master.master
列挙されたパスは、JTAG to Avalon Master Bridgeと呼ばれる種類のコンポーネントで、Qsysからその存在を確認できます。Qsysでfpga_only_masterインスタンスのmasterポートからの結線先を確認すると、
- sysid_qsys
- jtag_uart
- button_pio
- dispsw_pio
- led_pio
- onchip_memory2_0
- intr_capturer_0
に接続されています。これらは、すべてFPGA側のペリフェラルで(fpga_only_masterというネーミングはそれを表している)、Avalon Memory Mapped Slaveのポートに接続されています。と言うことは、fpga_only_masterから、これらのAvalon Memory Mapped Slaveに対して読み書きしたら状態取得や制御ができそうです。と、予想しました。実際、当たっていました。
まずは、後から参照しやすいように、fpga_only_masterのパスをm1という変数に格納します。
% set m1 [lindex [get_service_paths master] 1] /devices/5CSE(BA5|MA5)|5CSTFD5D5|..@2#USB-1#Helio/(link)/JTAG/sldfabric.node_2/phy_1/fpga_only_master.master
fpga_only_masterをオープンします。
% open_service master $m1
最後に、Linuxをシャットダウンしておきます。バックグラウンドで動作しているLEDの点灯プログラムが邪魔なのと、Linuxが停止した状態でシステムコンソールからの状態取得・制御ができることを確認するためです。
root@socfpga:~# shutdown -h now
これで準備が整いました。
Lチカ
Helioにはled_pioから制御できるLEDが4つ実装されています。これらのLEDを制御してみます。
led_pioのベースアドレスは0x10040です。このアドレスに対して書き込めばLEDを点灯消灯できます。
では、システムコンソールで試していきます。
LEDをすべて点灯。負論理なので、0で点灯です。
% master_write_32 $m1 0x10040 0x0
LEDをすべて消灯。
% master_write_32 $m1 0x10040 0xf
LEDを左から順番に1つずつ点灯。負論理でややこしいので、exprでbit反転を使って読みやすくしてみました。イミディエイト値で入力するよりずっと読みやすいですね。
% master_write_32 $m1 0x10040 [expr ~0b0001] % master_write_32 $m1 0x10040 [expr ~0b0010] % master_write_32 $m1 0x10040 [expr ~0b0100] % master_write_32 $m1 0x10040 [expr ~0b1000]
プッシュボタンの状態取得
button_pioが認識するプッシュボタンは2つです。プッシュボタンは3つ実装されていますが、1番右のボタンは死んでいます。
プッシュボタンのベースアドレスは0x100c0です。このアドレスに対して読み込めばプッシュボタンの状態を取得できます。
プッシュボタンもLEDと同様に負論理です。
2つとも押していない状態で取得すると、0x3 = 0b11が返ります。
% master_read_32 $m1 0x100c0 1 0x00000003
左側のボタンを押した状態で取得すると、0x2 = 0b10が返ります。
% master_read_32 $m1 0x100c0 1 0x00000002
右側のボタンを押した状態で取得すると、0x01 = 0b01が返ります。
% master_read_32 $m1 0x100c0 1 0x00000001
両方のボタンを押した状態で取得すると、0x00が返ります。
% master_read_32 $m1 0x100c0 1 0x00000000
オンチップメモリーの読み書き
オンチップメモリー(onchip_memory2_0)のベースアドレスは0です。
0x12345678を書き込んでみます。
% master_write_32 $m1 0x0 0x12345678
書き込んだ値を取得します。取得できました。
% master_read_32 $m1 0x0 1 0x12345678
後始末
作業が終わったら、クローズしておきます。
% close_service master $m1
参考情報
システムコンソールの使い方は、以下のページの解説が参考になりました。
おわりに
ネットで調べ物をしていたら、システムコンソールの存在を知り、急遽実験してみました。
これまでリファレンスデザインに実装されている、JTAG to Avalon Master Bridgeコンポーネント郡の役割がよく分かっていませんでしたが、今回の実験で理解できました。