JTAG総合情報サイト>MITOUJTAG開発日記>2018年のJTAG開発日記

2018年のJTAG開発日記

 

UltraScale+のJTAG RESETは余分なTCKを必要とする

2018.11.06

VivadoからMITOUJTAGを介してUltraScale+を認識しようとしたとき、リセット後のデバイスを検出できないという問題がありました。

Usjtag1

Digilentケーブルを使っていればこの画面にUltraScale+本体とARM DAPが出てくるのですが、MITOUJTAG経由だと出てきません。

この問題を徹底的に調査しました。

VivadoがUltraScake+を検出するときのJTAGのシーケンスは次のようになっています。
STATE RESET;
SDR 32 TDI (000000FF) TDO (28E20126);
STATE RESET;
SDR 1056 TDI (000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF) TDO (000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE000001FE28E20126);
SIR 192 TDI (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) TDO (FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0751);
STATE RESET;

ここで、28E20126というのは、UltraScale+のIDCODEを1bit左にシフトさせたもので、これはUltraScale+のDummy DAPが接続されていることに由来します。

まず、VivadoとDigilentのHSケーブルでUltraScale+を認識するところをオシロで見ましたが、MITOUJTAGでも同じシーケンスで出しているはずです。

Scope_6

問題は2回目のSTATE RESETにありました。

JTAGのTAPステートマシンはRESETステートに入るとリセットされるのですが、UltraScale+ではRESETステートで何発かの余分なTCKを与えないといけないのです。

実際にVivadoから送受信されたデータのログを見てみると、

最終送受信データの表示
tms: ff
11111111 01000000 00000000 00000000・・
tdi:
00000000 00001111 11110000 00000000・・
tdo:
11111111 11110110 01001000 00000100・・

と、TMSを1にしたまま、8回ものパルスを与えているのです。

この問題に対処して、RESETステートで複数回のパルスを与えてとどまれるようにしたら、

Usjtag2

ちゃんとリセット後にも2つのデバイスを認識してくれるようになりました。

sun

普通のJTAGデバイスなら、RESETステートを通ってRUNTEST_IDLEに戻るにはTMS=1にしたままTCKに5回のパルスを与えるというのが「常識」ですが、UltraScale+の場合は6回以上のTCKを与えないとうまくいかないのです。

UltraScale+はPLやARM DAPにダミーのものが用意されていて、その切り替えに1クロックかかるからです。

これもまた、UltraScale+の仕様です。バグと言ってもいいと思います。

おそらく、MITOUJTAG以外のJTAGツールでは、SVFを実行してもUltrasScale+は思ったように動作しないでしょう。

sun

また、UltraScale+の動作中にいきなりリセットしても、

Usjtag3_2

一瞬、Not programmedになりますが、Refresh Deviceの操作をすれば元に戻ります。

Usjtag4_2 

場合によっては、Refreshをしなくても勝手に戻ります。

Usjtag5

これで、VivadoからMITOUJTAG経由でJTAGアクセスするということが、ほぼ完璧にできるようになりました。 

 

VivadoとUltraScale+との間の通信を解析(2)

2018.11.04

昨日の続きをやっております。

開発中の新しいバージョンのMITOUJTAGを使って、VivadoからUltraScale+へのJTAGアクセスを解析できたのはいいのですが、それを目で追っていると大変なので、SVFフォーマットで出力できるようにしました。

Svf_capture

それを見ると、かなりプライベート命令を使っているな・・という感想です。

アクセスの最初の部分を見ると、

SIR 16 TDI (902F) TDO (0411); // USER1
SDR 33 TDI (000000000) TDO (000000000);
STATE RESET;
SIR 16 TDI (7E4F) TDO (0411); // ???
SDR 33 TDI (000000000) TDO (060018202);
STATE RESET;
SIR 16 TDI (902F) TDO (0411); // USER1
SDR 18 TDI (1E000) TDO (38000);
SDR 77 TDI (00000000000000000152) TDO (00000000000000000548);
STATE RESET;
SIR 16 TDI (922F) TDO (0411); // USER3
SDR 18 TDI (1E000) TDO (38000);
SDR 77 TDI (00000000000000000152) TDO (00000000000000000548);
SIR 16 TDI (FFFF) TDO (0411);
SIR 16 TDI (903F) TDO (0411); // USER2
SDR 33 TDI (000000000) TDO (000000000);
SIR 16 TDI (FFFF) TDO (0411);
SIR 16 TDI (903F) TDO (0411); // USER2
SDR 43 TDI (000000000D2) TDO (00000000348);
SIR 16 TDI (FFFF) TDO (0411);
SIR 16 TDI (903F) TDO (0411); // USER2
SDR 7 TDI (18) TDO (60);
SDR 43 TDI (000000000D2) TDO (00000000348);
SIR 16 TDI (A32F) TDO (0411); // ????
SDR 97 TDI (0000000000000000000000000) TDO (0000000000000000000000000);
SIR 16 TDI (FFFF) TDO (0411);
SIR 16 TDI (0E4F) TDO (0411); // ????
SDR 33 TDI (000000000) TDO (000000000);
SIR 16 TDI (FFFF) TDO (0411);
・・・
SIR 16 TDI (824F) TDO (0751);
SDR 33 TDI (000000006) TDO (000000000);
・・・

となっています。USER1,2,3はILAなどの内蔵ロジアナを見るためのものだと思いますが、0x7E4F 0xA32F 0x0E4Fという秘密のプライベート命令なので何をやっているかわかりません。

ユーザガイドug1085にもug570にも記述はありません。また、BSDLファイルを解読しても、該当する命令はありません。自力で解析するしかなさそうです。

sun

UltraScale+のJTAGコマンドは上位12bitがPS-PL系へのアクセスで、下位4bitがARM DAPへのコマンドなのですが、上記の解析結果からわかることは、

 

  • 0x7E4は何かの32bitのステータスレジスタ読み出しで、VivadoがJTAGでアクセスをするとそのステータスは変わる。
  • 0xA32は96bitのレジスタがつながる
  • 0x0E4は32bitのレジスタがつながる
  • 0x824は32bitのレジスタがつながる

 

ということです。

sun

UltraScale+のリセット後にDummy DAPからARM DAPに切り替えるJTAG_CTRL命令は見つかりませんでしたが、PS TAPとPL TAPを分離して考えると、上記のプライベート命令というのは既知の命令の組み合わせの表現なのかもしれません。

そう考えると、0x7E4というのは011111 & 100100なので、JTAG_STATUSコマンドとPLに対する24というコマンドの組み合わせです。JTAG_STATUSコマンドでPS TAP Controllerのステータスレジスタが見えるはずです。下位6bit(PL)に対する0x24のコマンドは公開されていませんが、データレジスタ長を0にする命令かもしれません。

0x7E4の後で32bitのDRをスキャンして0x060018202という結果を得ていますが、

Pstap_status

と照らし合わせて、ビンゴじゃないかなと思います。

0xA32は101000 & 110010なのですが、これに該当する命令はありません。ですが、下位6bitの110010はFUSE_DNAコマンドの下位6bitと一致するので、FUSE_DNAを読み出しているのだろうと推測されます。一回しか試せなさそうですが、FUSE_DNAを書き込んで試してみたいところです。上位6bit(PS)に対する0x28もレジスタ長を0にするものかもしれません。

0x0E4は、000011 & 100100と読めるので、PSに対するPMU_MDM命令と解釈できそうです。

0x824は、100000 & 100100と読めるので、PSに対するJTAG_CTRLコマンドで、直後のSDRに6を与えているので、PS TAPとPL TAPとARM DAPを接続するようです。

まとめると

  • 0x7E4はPSのステータス読み出し
  • 0xA32はDNAの読み出し
  • 0x0E4はPMUのMicroblaze Debug Moduleへのアクセス
  • 0x824と続く0x00000006はJTAGチェーンの正常化

なのかと推測されます。

それ以外の902や903、922はUSER1,2,3コマンドで、ILAやVIOの有無を調べているのだと思われるので、重要ではなさそうです。

その他にもプライベート命令はFUSE関係でたくさん出てきましたが、すべて解読できました。

sun

さて、Vivadoが起動した後は、ARMのDAPに対するコマンドが発行されるのが確認できました。

STATE RESET;
SIR 16 TDI (FFF8) TDO (0751);
SDR 36 TDI (000000008) TDO (000000000);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (08000019A) TDO (000000002);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (000000003) TDO (18000000A);
SDR 36 TDI (000000007) TDO (18000000A);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (000000784) TDO (000000002);
SIR 16 TDI (FFFB) TDO (0751);
SDR 36 TDI (000000007) TDO (000000782);
SDR 36 TDI (000000003) TDO (1A3B80022);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (008000784) TDO (000000012);
SIR 16 TDI (FFFB) TDO (0751);
SDR 36 TDI (000000007) TDO (008000782);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (010000784) TDO (223B80012);
SIR 16 TDI (FFFB) TDO (0751);
SDR 36 TDI (000000007) TDO (010000782);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (000000003) TDO (123B00082);
SDR 36 TDI (000000007) TDO (18000000A);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (008000004) TDO (000000002);
SIR 16 TDI (FFFB) TDO (0751);
SDR 36 TDI (400000010) TDO (008000002);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (000000004) TDO (123B00082);
SIR 16 TDI (FFFB) TDO (0751);
SDR 36 TDI (000000001) TDO (000000002);
SIR 16 TDI (FFFA) TDO (0751);
SDR 36 TDI (008000004) TDO (184030212);
SIR 16 TDI (FFFB) TDO (0751);
SDR 36 TDI (000000001) TDO (008000002);

というものですが、SIRの行にあるFFF8、FFFA、FFFBというのがコマンド、続く36bitのがデータです。

この解釈はARM Debug Interface Architecture Specification(https://static.docs.arm.com/ihi0031/c/IHI0031C_debug_interface_as.pdf)ににあります。

ARMのデバッグシステムは以下のような構造になっていて、

Arm_debug

FFF8が発行されるとABORT、FFFAはDPACC、FFFBはAPACCへの読み書きが行われます。

これが何を意味しているかの解読は別の機会にするとしましょう。

 

VivadoとUltraScale+との間の通信を解析

2018.11.03

前の記事で書いたとおり、VivadoからFPGAへのJTAG通信にMITOUJTAGを通すことができるようになったので、どのようなシーケンスが流れているのかを解析してみることにしました。

Xvcs_zu_2

VivadoからのJTAGシーケンスは、TMSやTDIをどのように動かすかという10の羅列なので、TAPコントローラをどのように動かすか、どんなデータがシフトされるかを解析できるようにしました。

Bscan_capture

最初に

tdi=000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF

というシーケンスを送って、IDCODEが返ってくるのを見ています。

次に、

tdi=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE

という長いシーケンスをIRに流して、FFFE0751が返ってきているのですが、IRの長さを測っているのかもしれません。最後のEはARMコアに送るIDCODEのコマンドなので安全です。

次にtdi=902FをIRに流し、その後、DRを33bitスキャンしてます。902はUSER1のコードなので、ILAなどが入っているかを見ているのかもしれません。DRの戻り値は00000000です。

その次は、7E4FをIRに流してから、DRを33bitスキャンしていますが、7E4に該当するコマンドは不明です。返ってきたデータは6001C67Aですが、右1ビットシフトさせて読むと、3000E33Dなります。

何でしょうね。

次に再びtdi=902FをIRに流し、その後、DRを18bitスキャンしてます。USER1のコードですが、DRに1E000を入れて戻り値は38000ですから1bitシフトしているだけでした。

 

VivadoからMITOUJTAGを介してUltraScale+にJTAGアクセス

2018.11.01

Vivadoから開発中の新しいバージョンのMITOUJTAGを介してUltraScale+にJTAGアクセスできるようになりました。

Vivado_mitoujtag

温度と電圧くらいは見えていますが、まだかなり不安定なので、ちょっとしたことをすると切れてしまいます。

例えば、Vivado+Digilentケーブル、あるいはVivado+Platform Cable USBならばUltraScale+をリセットしても復帰できるはずですが、

WARNING: [Labtools 27-3361] The debug hub core was not detected.
Resolution: 
1. Make sure the clock connected to the debug hub (dbg_hub) core is a free running clock and is active.
2. Make sure the BSCAN_SWITCH_USER_MASK device property in Vivado Hardware Manager reflects the user scan chain setting in the design and refresh the device.  To determine the user scan chain setting in the design, open the implemented design and use 'get_property C_USER_SCAN_CHAIN [get_debug_cores dbg_hub]'.
For more details on setting the scan chain property, consult the Vivado Debug and Programming User Guide (UG908).
refresh_hw_device [lindex [get_hw_devices xczu3_0] 0]
CRITICAL WARNING: [Labtools 27-3421] xczu3_0 PL Power Status OFF, cannot connect PL TAP.  Check POR_B signal.
INFO: [Labtools 27-1435] Device xczu3 (JTAG device index = 0) is not programmed (DONE status = 0).

となって、復旧できません。

ただ、MITOUJTAGを通るということは、どのようなシーケンスが流れているのかを解析できるということです。

Xvcs_zu

このような感じで少しずつ解析を行っています。 

 

MITOUJTAG BASIC 3.4をリリースしました

2018.10.31

本日、MITOUJTAG BASIC 3.4をリリースしました。 

また、MITOUJTAGの使い方を簡単に説明するスライドを作成しました。

Mjslide_2

http://www.tokudenkairo.co.jp/jtag/mjbas_usage.pdf

 

MITOUJTAGを使うと、オシロやロジアナでは見れないBGAの裏側の信号を見たり操作したりすることができます。

Mjbas34_2

あるのとないのとでは、FPGAの開発の効率が全然変わってきます。

MITOUJTAG BASIC 3.4では、

 

  • UltraScale+への書き込み、バウンダリスキャン対応
  • XILINX 7シリーズの温度・電圧測定

 

などに対応しました。

Mj_uscale

詳しい更新点はこちらのページをご覧ください。

http://www.tokudenkairo.co.jp/jtag/3xto34.html

 

UltraScale+でJTAGを挿しているとLinux起動中にハングアップする問題

2018.10.30

UltraScale+でJTAGを挿しているとLinux起動中にハングアップする問題があると聞いて、実験してみました。

まず、@ikwzmさんのZynqMP-FPGA-Linux (https://github.com/ikwzm/ZynqMP-FPGA-Linux) で試してみました。

Vivado HLSのコマンドプロンプトで、xsdbと入力すると、デバッガ「XSDK」が起動します。

Xsdb3

ここでconnectと打つと、

Xsdb4

という画面になります。

xsdb% cInfo: Cortex-A53 #1 (target 10) Stopped at 0x0 (Cannot resume. APB AP transaction error, DAP status 30000021)
Info: Cortex-A53 #1 (target 10) Running
xsdb% Info: Cortex-A53 #2 (target 11) Stopped at 0x0 (Cannot resume. APB AP transaction error, DAP status 30000021)
Info: Cortex-A53 #2 (target 11) Running
xsdb% tInfo: Cortex-A53 #1 (target 10) Stopped at 0x0 (Cannot resume. APB AP transaction error, DAP status 30000021)
xsdb% Info: Cortex-A53 #1 (target 10) Running

上のようなメッセージが延々と表示されます。

targetコマンドで見てみると、たまに、

Xsdb5

いくつかのプロセッサが停止しているようなメッセージを出しています。

このとき、LinuxのUARTに出てくるコンソールには、SDカードのトラブルやBlueToothが初期化失敗だの、いろいろなエラーメッセージが出て不安定になっています。

Xsdb6

おそらくLinuxの起動が最後まで行かずに途中でハングすることと思われます。

解決策は、@ikwzmさんや、@marsee101のおっしゃるようにuEnv.txtのbootargsのところにcpuidle.off  =1を付ければいい https://twitter.com/nahitafu/status/1057237499980918784 ようです。

これは、Linuxのカーネルコンパイル時に

CONFIG_CPU_IDLE=y

という設定になっていると、CPUがアイドル状態になることがあり、アイドル状態のときにJTAGアクセスするからおかしくなるようです。

@hidemi_ishihara さんによるとAnswer Recordの69143にあるとのこと。

https://japan.xilinx.com/support/answers/69143.html

を見てみると、確かに、そのようなことが書いてあります。

XSDBはコアのパワーダウンをチェックしているけれども、チェック後に不意にIDLEになるからDAPがエラーを起こすようです。

これなら、CPU_IDLEをOFFにする以外に解決策はなさそうです。

cpuidle.off=1を設定すれば、xsdbのtargetコマンドでも4つのCPUが落ち着いて常にRunning状態で見えます。

Xsdb7

 

 UltraScale+におけるチップの温度をJTAGで拾ってみた

2018.10.18

MITOUJTAGでUltraScale+の温度や電圧が表示されるようにしました。

Zubscan_5

毎秒2回更新します。

JTAGで温度を見る方法はユーザガイドUG580 (v1.9)に書かれているDRPという仕組みを利用します。

簡単に言うと、SYSMON_DRPという命令を使って、読み出したいステータスレジスタのアドレスをセットし、読み出します。

どのようなステータスレジスタがあるかというと、

Zubscan_6

このような感じになっています。

まず、IRにSYSMON_DRPという命令を発行し、次にDRに32bitの値をセットします。

シフトイン値は26bit目を1にし、[25:16]に読み出したいアドレスをセットします。

val = (1 << 26) | (addr << 16) | data;

 

DRPレジスタに書き込むのでなければdataは0でよいでしょう。

こうして、2回スキャンすると、2回目で目的のレジスタの値が読み出されます。

one 温度を測る場合は、

rdvalue / 65536. * 509.3140064 - 280.23087870;

で[℃]に変換します。

two 電圧を測る場合は、

rdvalue / 65536. * 3;

で[V]に変換します。

 

同じ要領でレジスタ0x10~0x1Fを読み出せば、XADCの値が読み出せると思います。

電源ピン電圧の監視では、HR I/Oでは上記の*3が*6になる場合もあるそうです。

sun

なお、JTAG DRPは、バウンダリスキャンとは排他的です。JTAGのデータレジスタにDRPが接続されているときは、バウンダリスキャンレジスタは切り離されています。

Zubscan_7_2

そのため、MITOUJTAGでは、I/Oの状態を表示している時には温度は出ないようにしました。

Zubscan_8_2

 

UltraScale+におけるJTAGの扱いが完璧になった

2018.10.17

UltraScale+のJTAGの扱いが完璧にできるようになりました。

Zubscan_3

まず、リセット後にDummy TAP/DAPが接続される問題は自動で状況を認識して回復するようにしました。

EXTEST時にPSのバウンダリスキャンセルが入れ替わる問題も、ピン名からPSのピンなのかPLのピンなのかを自動的に判別して解決するようにしました。

こういった様々なバグに対してJTAGライブラリの根幹部分を、UltraScale+のためのパッチを書くことで対応したのですが、一つのFPGAファミリのバグ対策のためにここまでMITOUJTAGの深部に手を加えることになるとは思いませんでした。

Zubscan_4

これで、UltraScale+の自動認識とバウンダリスキャンの問題にはすべて対応できたと思います。

 

MITOUJTAGがネイティブでUltraScale+の書き込みに対応

2018.10.16

MITOUJTAGからネイティブでUltraScale+のPLに書き込めるようになりました。

Zujwr_7

sun

書き込みのシーケンスは驚くほど簡単です。

 

  1. TAPをTEST_LOGIC_RESETに移動
  2. TAPをRUNTEST_IDLEに移動
  3. JPROGRAM命令を発行
  4. NOOP命令を発行
  5. RUNTEST_IDLEでしばらく待つ
  6. NOOP命令を発行。書き込みモードに変わったことを確認する
  7. CFG_IN命令を発行
  8. BitStreamをDRに流し込む
  9. RUNTEST_IDLEでトグルして、しばらく待つ
    -----------------------
  10. BYPASS命令を2回発行
  11. JSTART命令を発行
  12. RUNTEST_IDLEでトグルし、しばらく待つ

 

これで、PLが書き変わります。

PLが書き変わってもLinux自体は動作し続けられますが、PLにあるすべてのレジスタはリセットされてしまうので、画面を使うならもう一度再起動しなければならなくなるでしょう。

sun

書き込んで→I/Oを確認→書き込んで→I/Oを確認・・という開発&デバッグのプロセスが楽にできるようになりました。

Zujwr_8

Ultra96ボードへの書き込みだと約10秒でできます。

PLの書き換えだけならば再起動を伴わないので、楽ですよ。

 

 

UltraScale+のバウンダリスキャンがおかしい件

2018.10.13

UltraScale+のバウンダリスキャンにおいて、コントロールセルがおかしい問題は、Answerに書かれていました。

https://japan.xilinx.com/support/answers/62985.html

実はSpartan-6のときにも同様の問題があったのです。

 

 

6シリーズのときは出力ピンとして誤認識されてしまうのに対して、UltraScaleでは入力ピンとして誤認識されます。

7シリーズでは全く問題なかったので、6シリーズとUltraScaleを設計したのは同じグループなのかもしれない。偶数シリーズと奇数誤で設計担当グループが交互に変わるとか、そういう事情があるのかもしれない。

sun

さて、上記のAnswerによると、バウンダリスキャンで方向セルを正しく読めるようにするには、OBUFの代わりにT=0にしたOBUFTを使えとのことでした。

出力ピンにOBUFTを使うようにしたら、PLの入出力セルの方向が正しく読めるようになりました。

Zubscan_1

この波形を作るために書いたコードはこんな感じです。

Zubscan_2

カウンタがある一定値以上になると入力になり、一定値未満ならばバイナリでカウントアップする値を出力するというものです。

sun

これまでにわかっているUltraScale+のJTAGの仕様(バグ?)をまとめると、

 

  • PLはコントロールセルから正しくない値が読み出される。PSは問題ない。
  • PSはSAMPLE時に入出力セルが逆になる。PLは逆にならなない。
  • EXTEST時はPSでも入出力セルは逆にならない。
  • DDR4 SDRAMとのやりとりは見えない。

 

ということなのですが、PSとPLとDDR4でバウンダリスキャンの作りが違って、みんなどこかしら問題を抱えているわけなのです。

どうなっているんでしょう!? 

 

UltraScale+のPLにJTAGで書き込み成功

2018.10.12

Ultra96ボードで実験していて、ついにPLへJTAGで直接書き込むことに成功しました。

まず、PLのデザインのBitファイルを作らなければならないので、

http://zedboard.org/support/design/24166/156

からリファレンスデザインをダウンロードしてきます。

この中のUltra96_Basic_SystemをVivado 2018.2で開きます。

Zujwr_1

Ultra96のサンプルは、PLは使わずに、PSのみで動いているようです。

これだと書き込んでも何も起きないので、簡単なカウンタ回路を作ります

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity counter is
	Port (	clk  : in  std_logic;
			test_o : out std_logic_vector(7 downto 0)
	);
end counter;

architecture Behavioral of counter is
	signal counter : std_logic_vector(24 downto 0); 
begin
	process(clk) begin
		if(clk'event and clk='1') then
			counter <= counter + 1;
		end if;
		if(counter(23) = '1') then
			test_o <= (others => 'Z');
		else
			test_o <= counter(23 downto 16);
		end if;
	end process;

end Behavioral;

カウントアップしながら、一定期間test_oを

そして、VivadoにRTLモジュールとして登録します。

Zujwr_2

これでGenerate Bitstreamすると、Bitstreamができるわけですが、これをSVF形式に変換します。

SVFに変換するには、VivadoのTclコンソールで次のように入力します。

open_hw
create_hw_target my_svf_target
open_hw_target
set device0 [create_hw_device -part xczu3eg]
set_property PROGRAM.FILE {D:/Ultra96_Basic_System/Ultra96_Basic_System.runs/impl_1/design_1_wrapper.bit} [get_hw_devices xczu3_0]
program_hw_devices -disable_eos_check [get_hw_devices xczu3_0]
write_hw_svf -force D:/Ultra96_Basic_System/counter.svf
close_hw_target
close_hw

SVFを生成すると、Hardware Managerが開いて、以下のような画面になります。

Zujwr_3_2

そうしたら、MITOUJTAGで以下のSVFファイルを実行し、PL TAPとARM DAPを有効化します。

STATE RESET;
TDR 0;
HDR 1 TDO (1); // ARMのDAPを無視するため
SIR 16  TDI (83FF) ; // JTAG_CTRL
SDR 32 TDI (00000003) PRINT; // ARM DAPとPL TAPを有効化
RUNTEST RESET 16 TCK;

そして、Vivadoで生成したSVFファイルをMITOUJTAGのSVFプレイヤーで再生します。

Zujwr_4

書き込みには結構な時間がかかります。

書き込んだ後、JTAGロジックアナライザで見てみると、

Zujwr_5

ちゃんとカウントアップして、休む波形が見えました。

ただ、様子がおかしいですね。バウンダリスキャンセルの方向ピンが正しく読み取れていないようです。

Zujwr_6_3

本来は、このDIRと書かれた方向制御ピンは出力時には0になり、入力時には1になるはずです。

しかし、常に1のままで、入力として判断されてしまいます。

 

ZYNQ UltraScale+ MPSoCのJTAGのしくみ 

2018.10.11

ZYNQ UltraScale+ MPSoC(以下、ZU)の仕組みを完全に理解しました。

ZUの中にあるJTAGの構造をかみ砕いて描くと、こうなります。

Zujtag_3_2

ZUの内部には、PS TAP、PL TAP、ARM DAPという3つのJTAGコンポーネントが入っています。

 

  • PS TAPはPSの制御に使われるもので、JTAGステータスを見たりPMU(実体はMicroblaze)のデバッグポート(MDM)に接続されています。
  • PL TAPはPLのバウンダリスキャンやFPGA部分のコンフィグに使われます。
  • ARM DAPはCortex CPUのデバッグに使われます。

 

PL TAPとARM DAPは、デフォルトではDummyのほうを選択されていて、本体は無効になっています。また、PMU MDMとPL TAPとARM DAPにはセキュリティゲートというのがあって、勝手にデバッグをさせないようになっています。

セキュリティゲートは電源ON時やセキュアブートの時、eFUSEが切られているときには有効になっていて、JTAGが突破できません。

しかし、非セキュアブート(つまり普通のブート)するときには、CSUのROMのコードにってセキュリティゲートは無効になり、JTAGアクセスできるようになります。したがって、普通に起動した場合にはJTAGは使えるので、セキュリティゲートを気にする必要はありません。

sun

ZYNQ UltraScale+ MPSoCのJTAG命令レジスタの構造は次の図のようになっています。

Zujtag_6

ただし、PSとPLのIRは合わせて12bitという扱いなので、個別にコマンドを与えることはありません。PLのDRの長さは0bitになることもあります。

あまりPSとPL TAPを分離して考える必要はありませんが、ZUのJTAGのコマンドを解読していくときに、6bitごとに切って考えると理解しやすいところがあります。

ただし、PL TAPも一人前にIDCODEを持っていて、XCZU3EGのPSのIDCODEが0x14710093なのに対して、PLのIDCODEは0x14A42093でした。

このPL IDCODEは特別な命令IDCODE_PL(0x925)やIDCODE_PSPL(0x265)を発行すると読めます。

sun

JTAGのTDIから入ってきた信号はPS TAPを通った後、PL TAPかDummy TAPを通ります。その後、ARM DAPかDummy DAPを通ります。どちらを通るかというのは、PS TAPに対して発行するJTAG_CTRLコマンドで指定します。

具体的には、JTAG_CTRLコマンド(0x83F)をPS-PLに発行して、そのあと、0x00000003をDRに書き込みます。

SVF形式で書くなら、

STATE RESET;
TDR 0;
HDR 1 TDO (1); // ARMのDAPを無視するため
SIR 16  TDI (83FF) ; // JTAG_CTRL
SDR 32 TDI (00000003) ; // ARM DAPとPL TAPを有効化
RUNTEST RESET 16 TCK; // 切り替えた後は、Test-Logic-Resetステートで5回以上 TCKをトグルする

となります。

こうすることで、PL TAPとARM DAPが有効になって、MITOUJTAGの自動認識でも2個のデバイスが見つかるようになりました。

Zujtag_4

そして、ARMのDAPも認識されるようになり、正常にバウンダリスキャンができるようになります。

Zujtag_5

 

まとめると

  • ZYNQ UltraScale+ MPSoCのIRの長さは常に16bit
  • 非セキュアブートではセキュリティゲートは無効になっていて、突破できる
  • リセット後は、PL TAPとARM DAPはDummyが選択されているので、バウンダリスキャンやコンフィギュレーションをするなら、JTAG_CTRLコマンドで有効にしなければならない
  • PMUがJTAGでデバッグできそうだ

となります。

 

Ultra96ボードのJTAGバウンダリスキャンができた

2018.10.09 

Ultra96ボードを使ってZYNQ UltraScale+ MPSoC(以下、ZUと略)のJTAGの仕組みを解明しています。

まず、ZUは本体のPLのJTAGのほか、ARMのDAPや、ダミーのDAPが付いたりして、JTAGチェーンの構成が変わります。JTAGチェーンの構成はおそらくFSBLの中からCSUレジスタを操作することで行われますが、デフォルトのFSBLでは以下のようになります。

Zujtag_1_2

ここで厄介なことが3つあります。JTAGチェーンの構成が変わるたびに、JTAGのTMSを1にして何回かのTCKを与えてTAPをRESETしないといけないことと、JTAGチェーンの構成はソフトで変わることです。そのため、ハードウェアリセットが行われて、PMU→CSU→FSBLと起動のステップが進んだあたりでJTAGをリセットしなければなりません。

また、ZUのARM TAPはJTAGの規格に反してTAP RESET後にDRにIDCODEが現れません。そのため、自動で認識することができないことです。

sun

JTAGを使う汎用的なツールに「MITOUJTAG(みとうジェイタグ)」というのがあります。MITOUJTAGを使うとバウンダリスキャンで端子の状態が見えます。

Ultra96ボードでは以下のように見えます。

Zujtag_2

Ultra96ボードでチカチカ光っているLEDのあたりのピンを見てみます。

Zujtag_3

AB4、AA4、Y5、AA3、AB5番ピンにこれらの端子があります。

ZUでは、普通にバウンダリスキャンでSAMPLEしても、これらの端子の状態は正しく見ることができません。

前の記事で書いたとおり、SAMPLEするときには入力セルから値を読むのが普通なのですが、

Bscan1_2

ZUではなぜか出力セルから入力値が読み込まれるからです。

Bscan2

これは、はっきり言って、ZUのバグだと思います。

しかも、この入力ピンの値が出力セルから読み出される現象は、SAMPLE時のみ発生し、EXTEST時には発生しません。したがって、BSDLファイルの変更では対処できません。

そこで、MITOUJTAGでは、「ZYNQUltraScale+ MPSoCならば、SAMPLE状態のときに、入力セルと出力セルの読み出した値を入れ替える」という方法でこの問題に対処することにしました。

このようにすることで、端子から出力している値と、端子から入力している値を正しく読み出すことに成功しました。

sun

以上の問題を解決し、Ultra96ボードでLinuxが起動する時の波形を見ることに成功しました。

まずは下の波形をご覧ください。

UART0_TXに間欠的に動く波形が出ています。これはコンソールへの文字出力です。

Zujtag_4

起動してから5秒と8秒付近で、それぞれLinuxの起動と、BlueToothとWLANの起動が起こります。このときにMIOのピンの出力状態が変わるのが見てとれます。

Zujtag_5

起動後8秒後くらいというのは、コンソールにこのような文字列が出力されているあたりです。

Zujtag_9

LED0(緑のLED)がチカチカを開始するのが見えています。

Zujtag_6

あと、見て面白いのは起動後8秒付近でUSB1が起動することと、SD1に一瞬だけアクセスすることかなと思います。

Zujtag_7Zujtag_8

sun

UltraScale+のJTAGの仕組みがだいたい解明できました。

ポイントは、

 

  • CSUやFSBLによってソフト的にJTAGチェーンの構成が変わるので、それに合わせてTAP RESETをしなければならない
  • SAMPLE時の入力セルと出力セルが逆になっている
  • DDR4メモリの端子は見えない(これもチップのバグかもしれない)

 

MITOUJTAGでは、このような問題に対処するためのUltraScale+用のパッチを提供する用意があります。

 

MITOUJTAGセミナー(応用編)を開催しました

2018.09.05 

本日、JTAGチャレンジ基板を使った初めてのセミナーを開催しました。

1536284277_mj_semi_3

 

JTAGチャレンジ基板とは

わざと間違いを作りこんだFPGA基板。正常に動作せず、FPGAメーカー純正のツールでもデバッグできない。

1536125922_jtag_challenge2

この基板はそのままでは動作しませんが、MITOUJTAGというツールを使うと、FPGAが起動しない理由や、FPGA間の断線の発見などができるというものです。

 

1536126314_jtag_challenge_bscan

アンケートを集計したところ、5人中3人の方が「とても満足」ごご記入くださいました。

お寄せいただいた感想やご意見はこのような感じでした。

 

  • セミナーの内容とは別の不明点も教えてもらえて、勉強になった。
  • 実際に不具合のある基板を実践的にチェック出来たことは良かったと思います。
  • JTAGはメーカーの独自拡張が跋扈する深い魔窟というイメージでしたが、怖がらずに挑戦できる気がしてきました。
  • Basic版でかなりの事ができることが分かった
  • ALTERAのFPGAは使った事は無かったのですが興味のあるMAX10に触れられた事、SVFプレーヤーが何であるかも分かった

 

ZYNQ UltraScale+のJTAGに異常を発見

2018.08.22

Ultra96ボードを入手して、さっそくやってみたことはJTAGのテストです。

Uscale1

ボードから12Vの電源と、JTAGの配線を引き出してテスト開始です。

MITOUJTAGで認識させてみると、XCZU3しか見つかりません。実際にはXCZU3のほかにARMのDAPというのがつながっているので2個のデバイスが見つかるはずなのですが・・

そこで、SVFプレイヤーを用いて

STATE RESET;
STATE IDLE;
SDR 128 TDI (00000000000000000000000000000000) TDO (00000000000000000000000000000000);

というコマンドを実行して、JTAGの低レベルなデバッグをしてみると、XCZU3のIDCODEが1bitずれたものが読み出されました。

ARM DAPのDRが1bitになっていて(ZYNQ7000では32bitあった)、JTAG IDCODEが存在していないことがわかります。これは、ちょっと問題です。ARM DAPのIRは4bit長なので規格どおりですが。

この点は、ARM DAPのBSDLを作成して手動で追加すれば何とかなりました。

MITOUJTAGのバウンダリスキャンで、端子のI/Oが見えているように見えます。

Uscale2

また、端子のAA3、AA4あたりをEXTESTで動かすとLEDがチカチカするので、MITOUJTAGから操作もできていることがわかりました。

Uscale3

しかし、問題はここからです。基板上のSW4を押してもそれに相当する端子の状態が変化しないのです。

Uscale4

 

これはUltraScale+の持つJTAGのバグではないかと思います。

sun

本来、JTAGバウンダリスキャンでは、I/Oパッドから入力した値は入力セルから読み出されます。

Bscan1_2

しかし、コンフィギュレーションされたUltraScale+では、なぜか出力セルから読み出されます。

Bscan2

これが仕様なのか設計ミスなのかわかりませんが、JTAGの動作としては間違っているように思われます。

なお、バウンダリスキャンセルを手動で書き換えて、出力セルの値を見るようにすると、一見正しい動作をするのですが、FPGAが出力する値を読めなくなってしまうので、これも正しくありません。

Bscan3

BSDLファイルが間違っているというわけではなく、チップレベルで間違っているようです。

sun

それから、DDR4メモリの端子が全く動いていないことも気になります。Ultra96ボードのデフォルトのSDカードでは、DDRメモリは使用していないのでしょうか。 

 

UltraScale+用のJTAG書き込みアルゴリズム 

2018.08.21

AVNETのUltra96ボードを買いました。

Ultra96

私がやるべきことは、UltraScale+のJTAGコンフィギュレーションの仕組みを解析することだと思います。

参考にしたのは、Vivado Design Suiteユーザガイド(ug908)と、UltraScale アーキテクチャ コンフィギュレーション ユーザー ガイド (UG570)です。UG570にはJTAGコンフィギュレーションの仕組みは書いてありますが、実際にどういうシーケンスで動作させるかの実例がないと、不安要素はぬぐえません。

そこで、VivadoにSVFファイルを生成させてみることにします。SVFファイルの生成方法は、UG908の77ページあたりに書かれています。

とりあえずVivadoでZU2CGの適当なデザインを作り、Tclコンソールから下記のように入力します。

open_hw
create_hw_target my_svf_target
open_hw_target

このコマンドを打つと、Hardware Managerがファイル生成モードで開き、VivadoにSVF Operationsという欄が出来ます。

このcreate_hw_targetというのが、SVF生成プログラムを起動するTclコマンドのようです。

Svf1

次に、

set device0 [create_hw_device -part xczu2cg]

とコマンドを打つと、JTAGチェーンにxczu2とarm_dapの2つのデバイスが追加されます。

(紫の部分は実際に使用するデバイスに合わせて変えます)

Svf2_2

以下のコマンドで書き込みたいビットストリームファイルを指定して、書き込み操作を指示します。

set_property PROGRAM.FILE {D:/naitou/uscale/uscale.runs/impl_1/main.bit} [get_hw_devices xczu2_0]
program_hw_devices -disable_eos_check [get_hw_devices xczu2_0]
write_hw_svf -force D:/naitou/uscale/uscale.runs/impl_1/my_svf_target.svf

ただし、SVFモードなので、実際にはデバイスに書き込まれず、SVFファイルが生成されます。

最後に

close_hw_target
close_hw

とやって、Hardware Managerを閉じます。

出来上がったSVFファイルは10Mバイト以上あるのですが、

TRST OFF;
ENDIR IDLE;
ENDDR IDLE;
STATE RESET;
STATE IDLE;
FREQUENCY 1.00E+07 HZ;
HIR 4 TDI (0f) SMASK (0f) ;
TIR 0 ;
HDR 1 TDI (00) SMASK (01) ;
TDR 0 ;
// config/idcode
SIR 12 TDI (0249) ;
SDR 32 TDI (00000000) TDO (04711093) MASK (0fffffff) ;
// config/jprog
STATE RESET;
STATE IDLE;
SIR 12 TDI (090b) ;
SIR 12 TDI (0914) ;
// Modify the below delay for config_init operation (0.100000 sec typical, 0.100000 sec maximum)
RUNTEST 0.100000 SEC;
// config/jprog/poll
RUNTEST 10000 TCK;
SIR 12 TDI (0914) TDO (0011) MASK (0031) ;
// config/slr
SIR 12 TDI (0905) ;
SDR 44549344 TDI (00000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000000400000004000000040000
・・・
・・・
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ;
// config/start
SIR 12 TDI (0249) TDO (0031) MASK (0011) ;
// config/status
STATE RESET;
RUNTEST 5 TCK;
SIR 12 TDI (0905) ;
SDR 160 TDI (0000000400000004800700140000000466aa9955) ;
SIR 12 TDI (0904) ;
SDR 32 TDI (00000000) TDO (3f5e0d40) MASK (08000000) ;
STATE RESET;
RUNTEST 5 TCK;

となっています。

この動作を解説すると、まずHIRとHDRでARM_DAPをBYPASSする設定を与え、次にIDCODEをチェックしています。

090bはJPROGRAMコマンドで、PROG_Bピンと同等の働きをします。その後、0914のISC_NOOP命令(動作なし)に切り替えて、0.1秒待ちます。

再びISC_NOOP命令(914)を行い、IRの下位6bitが01XXX1であることをチェックしています。このbit5はDONEピンの状態を表していて、bit4は内部INITピンの状態を表しています。

つまり、DONE=0で現在のコンフィギュレーションが消えていること、INITで初期化状態であることを確認しています。

次の0905はCFG_INコマンドで、このコマンドを与えた後でJTAGのTDIからBitStreamを流し込めば、コンフィギュレーションが行われます。

次に0249(IDCODE)命令を行っていますが、特にIDCODE命令である必要はないようです。そのときのIRの状態を見て、DONE=0、INIT=1であることを確認しています。

そのあとで、CFG_INとCFG_OUTを実行して、0000000400000004800700140000000466aa9955を送って、3f5e0d40であるかどうかを確認しています。

それでは、0000000400000004800700140000000466aa9955という呪文のようなワードは何かというと、以下のように読みます。

 

  • 66aa9955・・同期ワード
  • 00000004・・NOOP
  • 80070014・・レジスタ7(ステータスレジスタ)を1ワード読む
  • 00000004・・NOOP
  • 00000004・・NOOP

 

つまり、FPGAのコンフィギュレーションレジスタのステータスレジスタを読んでいるようです。ステータスレジスタの値としてチェックしている3f5e0d40というのは逆から読むので、0x02b07afcとなりますが、DONEピンや、GHIGH、GWEなどのビットを確認しているようです。

Statreg

ただし、08000000でマスクしているので、実際にチェックするのはEND_OF_STARTUP_(EOS)_STATUSだけのようです。

ところで、-disable_eos_checkを付けても付けなくても結果は変わらないので、このオプションは効いていないようです。

sun

ただ、これではJSTARTが実行されていないので、FPGAは起動しないような気がするのですが、良いのでしょうか?

おそらく、Vivadoのバグではないかと思います。本来は、

// config/start
SIR 12 TDI (0249) TDO (0031) MASK (0011) ;

ではなく、

// config/start
SIR 12 TDI (090C) ;

ではないかと思います。

disable_eos_checkのオプションが効かない点と、JSTARTが含まれていないので、Vivadoも完璧ではないのかもしれません。

明日にでもVivadoの出力したSVFでコンフィギュレーションできるかどうか、検証してみたいと思います。

 

 

セキュリティキャンプ2018の講師を努めました

2018.08.16

 セキュリティ・キャンプ全国大会2018で講師を務めてまいりました。(写真は公式Twitterや掲示板の画像から引用)

Seccamp1

 

 

 

今年はフィジカルレイヤーという物理層レベルのセキュリティのトラックが新設され、その講師に任命されたので、私の専門であるJTAG(ジェイタグ)について講義と実習を行ってきました。

Seccamp2

添付の写真のような基板を受講者に渡して、JTAGのビット列を解読したり、解読したビット列をもとにEXTESTを使ったLEDをチカチカさせたりといった演習となりました。

Seccamp3

Seccamp4

Seccamp5

 

当日朝まで徹夜でパワポをまとめたり、ソフトをデバッグしたりで大変でしたが、4時間の講義が終わったときのやり遂げたという解放感はひとしおでした。

Seccamp6

 

MITOUJTAGからMAX10に書き込む方法

2018.08.11

XILINXとALTERAのデバイスが同一のJTAGチェーンにつながっている場合に、MITOUJTAGから書き込む方法を紹介します。

まず、Qualtus PrimeでMAX10のデザインを作ります。

Qp_1

QualtusのToolsからProgrammerを起動します。

Qp_2_2

QualtusのProgrammerが起動したら、いちど、まっさらな状態にします。

Qp_20

Add Fileを押して、MAX10の出力したファイルを選択します。

MAX10の内蔵ROMに書き込みたいならPOFを選び、揮発性のコンフィギュレーションをしたいならSOFを選びます。

Qp_8

下の図はPOFを選んだ場合の状態です。

Qp_6

次に、同一チェーン上にあるXILINXデバイスを追加したいのですが、当然ながらALTERAのツールはXILINXデバイスを認識しません。

そこで、Add Deviceボタンを押します。

どのデバイスを追加するかを聞かれるので、Importボタンを押します。

 

 

Qp_3

ファイル名を入力するダイアログが出るので...ボタンを押します。

Qp_4

D:\Xilinx\Vivado18.1\data\parts\xilinx\spartan7\public\bsdlディレクトリを指定し、中にあるxc7s25_csga225.bsdを指定します。

Qp_5

XC7S25が使用できるようになりました。

Qp_7

下の図のように、XILINXとALTERAがJTAGチェーンでつながります。

もし、順番が逆になっている場合にはUpボタンを押します。

Qp_9

sun

次にMITOUJTAGから書き込むために、SVFというファイルを作ります。SVFを作るにはProgrammerのFileからCreate JAM JBC、SVF or ISC Fileを行います。

Qp_12_2

デフォルトでは、下の図のようにjamファイルになっているので、

Qp_14_2

これを選択して、

Qp_11_2

SVFファイルに変更します。また、TCKを1MHzに変更します。(これを行わないと遅くなる)

Qp_13

OKを押します。

Qp_16

これでSVFファイルができました。SVFファイルというのはこのような感じのテキストファイルです。

Qp_10

この中に、Spartan-6とMAX10がチェーンになった場合のMAX10書き込みシーケンスが入っていて、そのまま実行すれば書き込まれるようになっています。

そうしたら、MITOUJTAGを起動して、[ツール]→[SVFプレイヤー]を起動します。

Qp_17

先ほど生成したSVFファイルの中身を貼り付けます。

Qp_18

ここで開始ボタンを押すと、SVFが実行されて、MAX10に書き込まれます。

Qp_19

無事に書き込みが行われ、MAX10が起動しました。

Max10_write_success

sun

下の図は、MAX10につないだシリアルADCを操作して、半固定抵抗の値やマイクで拾った音声を、JTAGロジアナで波形として表示しているようすです。

Max10_adc

 

Max10_adc2

特にWindowsのソフトウェアを組むことなく、FPGAのピンからバイナリの値を出せば、MITOUJTAGのロジアナでそれを拾って、アナログ波形として表示できます。

このやり方は、FPGAやWindowsのソフトを作らなくてもよいので楽ですよ。

 

JTAGチャレンジ基板の実装が上がってきた

2018.08.10

わざと間違いを作りこんでおいて、JTAGバウンダリスキャンでそれを発見するという「JTAGチャレンジ基板」の初期ロット12台が上がってきました。

Jtag_challenge_12

Jtag_challenge

Jtag_challenge_sm

Jtag_challenge_rx

とりあえずは、JTAGケーブルを接続してSpartan-7とMAX10が認識されました。

Jtag_challenge_bscan

この画面が出れば電源とJTAGは正常であることが保証されるので安心できますね。

よく見るとエラーになっていますが、MAX10は書き込み前だとINSTRUCTION_CAPTUREレジスタの値が変わるという変な仕様のためです。

最初は動かなくてかなり焦りました。まさか、こんな罠があるとは・・

coldsweats01

これから動かないことを確認します!

 

Digilentのボードを片っ端からスキャンしてみた

2018.08.09

MITOUJTAGのDigilentプラグインができたので、手元にあるDigilent製ボードを、MITOUJTAGで片っ端からバウンダリスキャンしてみました。

まずは、Artyです。ArtyはXC7A35TのCSG324が乗っているFPGAボードです。

Arty_a7

自動認識すると同じIDCODEのデバイスの候補が見つかるので、この中で324ピンのものを選びます。

 

Arty_detect

Artyが動作しているときの、Artix-7の端子の状態です。

ピンクはHレベル、水色はLレベル、塗りつぶしは出力、網掛けは入力の状態を表しています。

Arty_bscan

ArtyにはSPI ROMが乗っているようで、MITOUJTAGからSPI ROMを認識することもできました。

Artyspirom

Artyが起動するときのSPI ROMの端子の動きや、起動後のLEDチカチカの信号も見えました。

Arty_logana

 

sun

次はSpartan-7が乗ったArty-S7です。Artyとの大きな違いは、Etherのコネクタが無いことです。

Arty_s7

こちらも自動認識すると、同じIDCODEのデバイスが見つかります。この中で324ピンのものを選びます。

 

S7_detect

端子の状態もばっちり見えました。

S7_bscan

Arty-S7のデフォルトのLEDチカチカはPWMがかかって、じわりじわりと点滅します。そのようすがJTAGロジアナでも見えています。

 

S7_logana

sun

最後はZYBO-Z7です。

ZYBOは初期のころの評価ボードなので画面出力がVGA端子だったりしますが、その後HDMI出力やCSIカメラが付いたZYBO Z7というのが出ました。

Zybo_z7

FPGAもXC7Z020にアップグレードされています。

Z7_detect

自動認識すると、ARMコアとFPGAコアの2つのデバイスが見えます。

Z7_bscan

 

LEDチカチカのPWMもよくできています。

Z7_pwm

 

様々な端子の信号を見るとこのような感じになっています。

Z7_logana

sun

MITOUJTAGは、他社製ボードであっても使えます。デフォルトのサンプルデザインが動いている状況でも使えます。つまり、FPGAに何もIPを書き込む必要がありません。

FPGAの起動前であっても信号が見えるので便利ですよ。

 

MITOUJTAGのDigilentプラグインを作成

2018.08.08

Digilent製ボードでMITOUJTAGが使えるようにするため、プラグインを作っています。

ようやくDigilent USB-JTAGの使い方を理解して、MITOUJTAGから使えるようにできました!

まずは、ZYBOとパソコンをつなぎます。ZYBO上のUSB-JTAGで通信するので、USBケーブル1本だけです。

Zybo_3

これでDigilent製のボードはUSBをつなぐだけでI/Oピンや波形が見れるようになったわけなのですが、ZYBOが起動するときの波形をバウンダリスキャンのロジアナで見てみたら、毎秒4000サンプリングほど出ていました。つまり250usくらいのサンプリング周期のようです。

Zybo_bscan

JTAGロジアナで見てみると、DDR3メモリの動きなどが見えます。

Zybo_logana

実は今までのMITOUJTAGにもDigilent USB-JTAGを接続する機能はあったのですが、XILINX ISEがサポートするDigilent Cable Pluginを間接的に使っていたので、ISE(Labtool)が入っていないと使えませんでした。

LabToolはISEのでなければだめで、Vivadoには対応していませんでした。

その意味でも、今回の改良でISEに依存せずにDigilentケーブルが使えるようになったのは大きいといえます。

 

Dflow

 

 

DigilentのJTAGを自分のプログラムで使う方法

2018.08.04

DigilentのボードにはUSB-JTAGが付いています。

このUSB-JTAGを自分のプログラム方法を調べました。

簡単に言うと、Digilent Adeptというライブラリがあって、djtgとdmgrというライブラリを使います。AdeptはJTAG以外にもDigilentが用意するシリアルI/OやパラレルI/Oを統括した、総合的なターゲットボード用ライブラリのようです。

様々なボードがあるので、JTAGの機能にもいろいろなオプションがあるようです。

また、PCに何台のターゲットボードがつながるかもわからないので、最初にEnumerateして、ボードのシリアル番号を調べて、そのシリアル番号を使ってデバイスをオープンするという手順になります。

開いたボードはたいていはFT2232が乗っていて、FT2232のファームウェアでAdeptのターゲットを実装していると思うのですが、そうでないボードもある可能性があるので、ボードが備えているabilityを調べます。

Zyboのボードは、スピード調整や、ピンの設定、WAIT機能、バッチ機能などを備えているようです。

Jtag_program

DigilentのUSB-JTAGを叩いて、ZYBO上のUSB-JTAGのプロパティと、ARMとZYNQコアをスキャンすることに成功。

AUX Resetというポートは存在していて、GPIOは付属していないようですね。

AUX Resetを0にするとARMのJTAGがしばらく認識できなくなるので、何かの機能はあるようです。GPIOは、おそらくCPUのデバッグに用いる補助的なI/Oに使われるものと思われます。最近のARMでは使いませんが、MIPSのころはGPIOが必要でした。

sun

次に、Digilentのボードに乗っているUSB-JTAGを使う実験をしてみました。

最初の感想は、かなり遅い。

それもそのはず。USB 2.0 HighSpeedは、1つの操作をするたびに125us待たなければなりません。FT2232はさらに遅いはずです。

実際に試してみると数百usかかったり、かなり不安定です。

そこで、Adeptにはバッチモードというのが用意されていて、複数のJTAG操作をスクリプト化してまとめて投げるのです。

このバッチモードを使うと、任意の波形をそこそこの速度で出せるようになりました。USBの遅さカバーする方法が私のライブラリと同じ設計思想なのですぐに使い方がわかりました。FTDIのICの動きもだいたい想像できます。

Djtag

 

ZYBOのJTAGでIDCODEを読み出すシーケンスを実行してみました。

Djtag_idcode

ARMとZYNQコアのIDCODEが読み出せているのがわかります。

TCKは最高で30MHzほど出ていて、これが最高速度のようです。

 

JTAGチャレンジ基板の生板ができてきた

2018.08.03

バウンダリスキャンを使って回路設計やエレクトロニクス実装の間違いを見つける「JTAGチャレンジ基板」の生板が出来上がりました。

Np1114_raw

 

来週中には実装が完了する予定です。セキュリティ・キャンプ全国大会2018の講義で使う予定だったので、間に合ってよかった!

そして、9月には誰でも参加できる「JTAGバウンダリスキャン・セミナー」を開催していく予定です。

セミナーの予定はcompassなどで告知していきたいと思いますので、お楽しみに。

 

JTAGチャレンジ基板がほぼ完成

2018.07.30

わざと間違いを作りこんでおいて、それを発見するための基板「JTAGチャレンジ基板」の設計がほぼ終わりました。

Jtagchallenge1

このボードには、FPGAとしてSpartan-7とMAX10が乗っていて、マイコンはRXマイコンとLPCマイコンが乗っています。RXマイコンにはUSB-JTAGの機能が実装されていて、Spartan-7、MAX10、LPC11U35をJTAGでいじくることができます。

Spartan-7にはSPI ROMやBPI Flash ROMとDDR3 SDRAMとΔΣのDACがつながっていて、MAX10にはシリアルADCがつながっています。

シリアルADCにはマイクと半固定抵抗がつながっています。

Jtagchallenge0

マイクで拾った音をシリアルADCでディジタルにして、MAX10からSpartan-7にデータを送り、Spartan-7で再びアナログにするという動作をします。ボイスレコーダみたいなものができます。

sun

ですが、設計ミスによりFPGAは起動しません。

そのミスを修正してFPGAが起動するようになっても、FPGA間の接続に問題があって、MAX10とSpartan-7の間で正しくデータを伝達できません。

DDR3 SDRAMも、BPI Flash ROMも致命的な設計ミスにより動作しません。

そういう間違いが10個くらいあります。

どれも、組み込みの基板設計では、よくありそうなミスを仕込んでいます。

sun

もし、FPGAにDDR3メモリをアクセスする回路を書いて地道にデバッグするとなると、途方もない時間がかかってしまいますが、そこをJTAGを使ってあっという間にデバッグできるようにしようというのが、このセミナーの趣旨となります。

Jtagchallenge2

6層基板で、140mm×100mmの、ほぼ葉書サイズです。

早ければ金曜日に生基板が届き、お盆前には実装が上がる予定です。

 

JTAGチャレンジ基板がだいたいできてきた

2018.07.27

JTAGチャレンジ基板の配線を引き続き進めています。

Spartan-7は電源ピンが少ないので、とても配線がやりやすいですね。

Sp7

MAX10はさらに電源が少なく、さらに3.3V単一電源なので配線がとても引きやすいですね。

Max10

LPC11U35のサブマイコン(JTAGで操作されるだけのマイコン)は、QFNパッケージにしました。初めて触るマイコンなので、BGAだと動かないとさすがにデバッグしづらいし、バグを作りこむものも難しいからです。

Lpc

これで基板の配線がだいたい完成しました。

RXとLPCとか、Spartan-7とMAX10とか、完全な異ベンダー基板になりました。

Jtagchallenge

 

 

JTAGチャレンジ基板の設計再開

2018.07.26

設計ミスをわざと作りこんだ「JTAGチャレンジ基板」の配線を再開しました。

この基板は、わざと間違いを作りこんだ基板をJTAGでデバッグして、いかに早く動くようにできるかという、一種のエクストリームな競技デバッグ(?)のための基板です。

1

JTAGでできることの全部が詰め込まれています。

RX62NマイコンがUSB-JTAG変換をしてSpartan-7とMAX10とLPC11U35マイコンをJTAGでデバッグします。Flash ROMやDDR3 SDRAM、シリアルADCなど面白い部品が満載です。

単純そうに見えて実は6層基板。FPGAやSDRAMはBGAパッケージだし、配線は主に内層を通すので、オシロではプローブできません。Spartan-7とMAX10がチェーンでつながっているからFPGAメーカのデバッグツールも使えない。という、たいへん鬼畜な仕様になっています。

DR3 SDRAMとSpartan-7の配線は、大変かなと思って二の足を踏んでいたけど、やってみたら結構楽に引けました。

2_2

とりあえず、DDR3の配線ができた状態。

3_3

そして、FPGAとつないだ状態です。

4_2

このDDR3の配線、全部内層(茶色)を通したからオシロじゃ見えません。

終端抵抗とViaがあるのは、せめてもの優しさといえるでしょう。

sun

その次はパラレルフラッシュとの接続ですが、DDR3よりもこっちのほうが疲れたかもしれません。42本もあります。電源ピンが1個しかないし、20年前はみんな、こんなのでも動いていたんですね。

5_2

 

JTAGチャレンジ基板(仮称)を作ります

2018.07.12

JTAGチャレンジ基板(仮称)というものを作ります。

これはどういうものかというと、RXマイコン、Spartan-7、MAX10が乗った基板なのですが、基板にいろいろとミスが仕込んであって、動かないのです。

そのミスというのは、回路設計者や基板設計者がやりがちな、よくある設計ミスです。

クロックが来ていないとか、リセットがかからないとか、FPGAが起動しないとか・・そういうミスなのですが、本当の基板でやったら即作り直しになって、再設計費数十万円と1か月を無駄にするような、胃が痛くなるようなミスをたくさん仕込んであります。

Jtagchallenge

 

で、そんな動かない基板をどうするかというと、MITOUJTAGを使えばそういうミスが一瞬で発見できるということを体験してもらおうというわけです。

MITOUJTAGというのは、世界で一番最初にJTAGバウンダリスキャンを組み込み回路のデバッグに活用できるようにしたツールです。

http://www.tokudenkairo.co.jp/jtag/

今までは工場の出荷検査くらいにしか使われてこなかったJTAGバウンダリスキャンを、開発者ひとりひとりが自分の回路のために使えるようにしたツールなのです。

sun

たとえば、DDR3メモリのアドレス線が入れ替わっていたら、どうやってデバッグしますか?MIGを使って何度も作り直す?

たとえば、FPGAにクロックが入っていなかったら、どうやってデバッグしますか?Vivadoの内蔵JTAGアナライザはクロックがなかったら動きませんよね。

もし、6層基板の内層が切れていたら、どうやって発見しますか?片方のFPGAからテスト信号を出して、もう一個のFPGAでロジアナを動かす?そんなめんどくさいこと・・・

でも、内層が切れているかも・・・ということにどうやって気づきますか?

sun

JTAGの本来の機能は「バウンダリスキャン」といって、FPGAやCPUが動作しないレベルの致命的なバグがある基板でも使えるのです。

MITOUJTAGは、バウンダリスキャンを強力なデバッグ手段にすることができ、基板の間違いをもっと早期に、もっとストレスを感じない方法で見つけてもらいたいと思い、この基板を設計しています。

早ければ9月中にこの基板を使って最初のセミナーを開催できればと思っています。 

 

MITOUJTAGから未知のSPI ROMにも書き込みできるようにした

2018.06.04

XILINX FPGAは汎用のSPI ROMをコンフィギュレーションROMとして使用できますが、昨今のメモリ業界は入れ替わりが早く、古いSPI ROMはディスコンとなり、新しいROMはiMPACTからもVivadoからも書き込みができないなど、対応しているROMを探すのが難しくなってしまいました。

MITOUJTAGも同じで、W25Q32だの、JVSIGやSVSIG・・など型番が少し変わったROMに対応させていくのが大変だと感じていました。

すると、SPI ROMデバイスのIDCODEと、そのROMのサイズやアルゴリズムなどをテキストファイルで書いておいて、ツールが動的にそれを読み込めばいいのではないかという発想になります。

MITOUJTAGを改良し、ファイルからSPI ROMのパラメータを読み込めるようにしました。

sun

検証に使ったボードは特電のSpartan-6ボード。このボードのSPI ROMをMacronix社のMX25R3235Fに乗せ換えます。

Sp6mx25

ROMはブランクなので、当然ながらFPGAは起動前の状態で、I/Oは全ピン入力状態としえて見えます。

Mj_sp6_notconfig

MITOUJTAGはこのSPI ROMのIDCODEを知らないので、最初は書き込みができません。不明と出てしまいます。

Mj_unknown_spirom

そこで、下記のようなファイルを作成し、MITOUJTAGのsysフォルダにspiromid.txtというファイル名で置いておきます。

#idcode  , pagesize , maxpages , page_addr_shift , algorithm  , devicename
#
# Choose an algorithm from below.
#   ATMEL ST NUMONIX INTEL SST MICRON WINBOND SPANSION CYPRESS ISSI ONSEMI MACRONIX
#

0xc22816 , 256      , 16384    , 8               , macronix   , MX25R3235F
0xc22015 , 256      , 8192     , 8               , macronix   , MX25L1606E
0xbf2641 , 256      , 8192     , 8               , sst        , SST26VF016B

最初の列はIDCODE、次の列はページサイズです。ページサイズは普通は256です。その次の列はページ数なのですが、ページサイズが普通は256なので、32Mbit品ならここは16384となります。

次は製造元を表す列ですが、 ATMEL ST NUMONIX INTEL SST MICRON WINBOND SPANSION CYPRESS ISSI ONSEMI MACRONIXの中から選びます。これでアルゴリズムが選択されます。

最後はデバイス名です。デバイス名は画面に表示されるだけなので、違っていても動作に影響はありません。

このファイルを記述すると、未知のSPI ROMでも認識できるようになります。

Mj_spirom_update

もちろん書き込みも成功し、

Mj_spirom_success

ちゃんと起動しました。

Mj_sp6

sun

SPI ROMの書き込みアルゴリズムは、ST/Micron/Winbond/Intelなどの標準的なアルゴリズムのほか、ATMEL、SSTなどの変則的なものにも一部対応しています。

今回の改良により、ユーザの手元で書き込みパラメータを編集できるようになりました。これで今後どんなSPI ROMが出てきても怖くありませんね。

この修正パッチは次回のMITOUJTAGの更新で提供しますが、ご必要な方にはすぐに提供しますので、ご連絡ください。

 

MITOUJTAGでVivadoのXDCファイルを読み込めるようにした

2018.06.01

今更ではありますが、MITOUJTAGでVivadoのXDCファイルが読み込めるようにしました。

いままでのMITOUJTAGはXDCに対して機能不足で

 

  • ファイルの一覧にXDCファイルが表示されない
  • -dictを使ったピン定義に対応していない

 

という問題がありました。

XDCファイルが表示されないというのは、下の図のような状況です。

Noxdc

XILINX用のピン定義ファイルを表示しようとしても、XDCが出てきません。ファイル名のところに*.xdcと入れなければなりませんでした。

また、-dict記述に対応していないというのは、XDCでのピン定義はset_property PACKAGE_PINという記述で行いますが、このやり方には2種類あって、

set_property PACKAGE_PIN F17 [get_ports {netic20_f17}]; #IO_L6N_T0_VREF_35
set_property PACKAGE_PIN G18 [get_ports {netic20_g18}]; #IO_L16N_T2_35
set_property PACKAGE_PIN T9 [get_ports {netic20_t9}]; #IO_L12P_T1_MRCC_13
set_property PACKAGE_PIN U9 [get_ports {netic20_u9} ] ; #IO_L17P_T2_13

という書き方と、

set_property -dict {PACKAGE_PIN Y18 IOSTANDARD LVCMOS33} [get_ports {PWM_H_OUT[0]}]
set_property -dict {PACKAGE_PIN Y19 IOSTANDARD LVCMOS33} [get_ports {PWM_L_OUT[0]}]
set_property -dict {PACKAGE_PIN Y16 IOSTANDARD LVCMOS33} [get_ports {DRV_FLT[0]}]
set_property -dict {PACKAGE_PIN Y17 IOSTANDARD LVCMOS33} [get_ports {DRV_EN[0]}]

という書き方の2種類があります。

前者の書き方は、ピンに対してIO規格とピン番号を別の行で指定する方法です。

後者の書き方は-dict {} という記述方法で1行にまとめてしまう方法です。

今までのMITOUJTAGでは前者の方法にしか対応していませんでした。

sun

これらの問題を解決したパッチを作成しました。

今回、動作テストに使ったボードは、Arty-Z7です。デバイスを自動認識させたら、右クリックして、「ピン定義ファイルの読み込み」を行います。

Artyz7_pindef1

一覧にちゃんとXDCファイルが表示されるようになりました。

Artyz7_pindef2

そして、Arty-Z7のXDCファイルを読み込んでロジアナモードを開くと、

Artyz7_pindef3

このようにピンの定義が読み込まれていることがわかります。

この機能は次回のMITOUJTAGの更新の際に取り込んでリリースしますが、パッチだけすぐに欲しいという方はご連絡ください。

 

 

MITOUJTAG Pro 3.2をリリースしました

2018.01.13

約1年半の更新点をまとめた、MITOUJTAG Pro 3.2をリリースしました。

まず、各社の新しいデバイスを認識できるよう、デバイスデータベースが更新されました。

XILINXはSpartan-7や、UltraScale+が認識できるようになりました。

Mj32_xil

この他にはRenesasのRX64、RX65、RX710、RZ。ALTERAではMAX10、Cyclone10。CypressはPSOC6に対応させました。しかし、PSoC6はファイル名はBGAなのにQFPのパッケージの絵が出るのでBSDLファイルが間違っている可能性があります。

Mj32_oth

それから昨日、Spartan-7のFPGAボード、Arty S7を秋月で買ってきて、バウンダリスキャンを試してみました。

Arty-S7はUSB-JTAGがDigilent製なので、MITOUJTAGから使うにはISE14.7が必要ですが、無事にバウンダリスキャンができました。

 

 

その他、ISSI製SPI ROMへの書き込み対応など細かいアップデートや、波形のエクスポート、ファイルの保存ボタンが押せないバグの修正などが行われています。

 

MITOUJTAG ProはこちらのURLからダウンロードできます。

MITOUJTAG BasicとLightのアップデートは来週中に行う予定です。

https://www.tokudenkairo.co.jp/login2/getfile.php?target=MJPro320