MITOUJTAGとは何か
製品について
ご購入を検討中の方へ
サポート
JTAGについて
JTAG技術サービス(有料)
JTAG開発日記
JTAGを熱く語る
2018年のJTAG開発日記
UltraScale+のJTAG RESETは余分なTCKを必要とする
2018.11.06
VivadoからMITOUJTAGを介してUltraScale+を認識しようとしたとき、リセット後のデバイスを検出できないという問題がありました。
Digilentケーブルを使っていればこの画面にUltraScale+本体とARM DAPが出てくるのですが、MITOUJTAG経由だと出てきません。
この問題を徹底的に調査しました。
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でも同じシーケンスで出しているはずです。
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ステートで複数回のパルスを与えてとどまれるようにしたら、
ちゃんとリセット後にも2つのデバイスを認識してくれるようになりました。
![]()
普通のJTAGデバイスなら、RESETステートを通ってRUNTEST_IDLEに戻るにはTMS=1にしたままTCKに5回のパルスを与えるというのが「常識」ですが、UltraScale+の場合は6回以上のTCKを与えないとうまくいかないのです。
UltraScale+はPLやARM DAPにダミーのものが用意されていて、その切り替えに1クロックかかるからです。
これもまた、UltraScale+の仕様です。バグと言ってもいいと思います。
おそらく、MITOUJTAG以外のJTAGツールでは、SVFを実行してもUltrasScale+は思ったように動作しないでしょう。
また、UltraScale+の動作中にいきなりリセットしても、

一瞬、Not programmedになりますが、Refresh Deviceの操作をすれば元に戻ります。
場合によっては、Refreshをしなくても勝手に戻ります。
これで、VivadoからMITOUJTAG経由でJTAGアクセスするということが、ほぼ完璧にできるようになりました。
VivadoとUltraScale+との間の通信を解析(2)
2018.11.04
昨日の続きをやっております。
開発中の新しいバージョンのMITOUJTAGを使って、VivadoからUltraScale+へのJTAGアクセスを解析できたのはいいのですが、それを目で追っていると大変なので、SVFフォーマットで出力できるようにしました。
それを見ると、かなりプライベート命令を使っているな・・という感想です。
アクセスの最初の部分を見ると、
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ファイルを解読しても、該当する命令はありません。自力で解析するしかなさそうです。
![]()
UltraScale+のJTAGコマンドは上位12bitがPS-PL系へのアクセスで、下位4bitがARM DAPへのコマンドなのですが、上記の解析結果からわかることは、
- 0x7E4は何かの32bitのステータスレジスタ読み出しで、VivadoがJTAGでアクセスをするとそのステータスは変わる。
- 0xA32は96bitのレジスタがつながる
- 0x0E4は32bitのレジスタがつながる
- 0x824は32bitのレジスタがつながる
ということです。
![]()
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という結果を得ていますが、
と照らし合わせて、ビンゴじゃないかなと思います。
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関係でたくさん出てきましたが、すべて解読できました。
![]()
さて、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のデバッグシステムは以下のような構造になっていて、
FFF8が発行されるとABORT、FFFAはDPACC、FFFBはAPACCへの読み書きが行われます。
これが何を意味しているかの解読は別の機会にするとしましょう。
VivadoとUltraScale+との間の通信を解析
2018.11.03
前の記事で書いたとおり、VivadoからFPGAへのJTAG通信にMITOUJTAGを通すことができるようになったので、どのようなシーケンスが流れているのかを解析してみることにしました。
VivadoからのJTAGシーケンスは、TMSやTDIをどのように動かすかという10の羅列なので、TAPコントローラをどのように動かすか、どんなデータがシフトされるかを解析できるようにしました。
最初に
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+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を通るということは、どのようなシーケンスが流れているのかを解析できるということです。
このような感じで少しずつ解析を行っています。
MITOUJTAG BASIC 3.4をリリースしました
2018.10.31
本日、MITOUJTAG BASIC 3.4をリリースしました。
また、MITOUJTAGの使い方を簡単に説明するスライドを作成しました。
http://www.tokudenkairo.co.jp/jtag/mjbas_usage.pdf
MITOUJTAGを使うと、オシロやロジアナでは見れないBGAの裏側の信号を見たり操作したりすることができます。
あるのとないのとでは、FPGAの開発の効率が全然変わってきます。
MITOUJTAG BASIC 3.4では、
- UltraScale+への書き込み、バウンダリスキャン対応
- XILINX 7シリーズの温度・電圧測定
などに対応しました。
詳しい更新点はこちらのページをご覧ください。
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」が起動します。
ここでconnectと打つと、
という画面になります。
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コマンドで見てみると、たまに、
いくつかのプロセッサが停止しているようなメッセージを出しています。
このとき、LinuxのUARTに出てくるコンソールには、SDカードのトラブルやBlueToothが初期化失敗だの、いろいろなエラーメッセージが出て不安定になっています。
おそらく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状態で見えます。
UltraScale+におけるチップの温度をJTAGで拾ってみた
2018.10.18
MITOUJTAGでUltraScale+の温度や電圧が表示されるようにしました。
毎秒2回更新します。
JTAGで温度を見る方法はユーザガイドUG580 (v1.9)に書かれているDRPという仕組みを利用します。
簡単に言うと、SYSMON_DRPという命令を使って、読み出したいステータスレジスタのアドレスをセットし、読み出します。
どのようなステータスレジスタがあるかというと、
このような感じになっています。
まず、IRにSYSMON_DRPという命令を発行し、次にDRに32bitの値をセットします。
シフトイン値は26bit目を1にし、[25:16]に読み出したいアドレスをセットします。
val = (1 << 26) | (addr << 16) | data;
DRPレジスタに書き込むのでなければdataは0でよいでしょう。
こうして、2回スキャンすると、2回目で目的のレジスタの値が読み出されます。
温度を測る場合は、
rdvalue / 65536. * 509.3140064 - 280.23087870;
で[℃]に変換します。
電圧を測る場合は、
rdvalue / 65536. * 3;
で[V]に変換します。
同じ要領でレジスタ0x10~0x1Fを読み出せば、XADCの値が読み出せると思います。
電源ピン電圧の監視では、HR I/Oでは上記の*3が*6になる場合もあるそうです。
![]()
なお、JTAG DRPは、バウンダリスキャンとは排他的です。JTAGのデータレジスタにDRPが接続されているときは、バウンダリスキャンレジスタは切り離されています。

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

UltraScale+におけるJTAGの扱いが完璧になった
2018.10.17
UltraScale+のJTAGの扱いが完璧にできるようになりました。
まず、リセット後にDummy TAP/DAPが接続される問題は自動で状況を認識して回復するようにしました。
EXTEST時にPSのバウンダリスキャンセルが入れ替わる問題も、ピン名からPSのピンなのかPLのピンなのかを自動的に判別して解決するようにしました。
こういった様々なバグに対してJTAGライブラリの根幹部分を、UltraScale+のためのパッチを書くことで対応したのですが、一つのFPGAファミリのバグ対策のためにここまでMITOUJTAGの深部に手を加えることになるとは思いませんでした。
これで、UltraScale+の自動認識とバウンダリスキャンの問題にはすべて対応できたと思います。
MITOUJTAGがネイティブでUltraScale+の書き込みに対応
MITOUJTAGからネイティブでUltraScale+のPLに書き込めるようになりました。
![]()
書き込みのシーケンスは驚くほど簡単です。
- TAPをTEST_LOGIC_RESETに移動
- TAPをRUNTEST_IDLEに移動
- JPROGRAM命令を発行
- NOOP命令を発行
- RUNTEST_IDLEでしばらく待つ
- NOOP命令を発行。書き込みモードに変わったことを確認する
- CFG_IN命令を発行
- BitStreamをDRに流し込む
- RUNTEST_IDLEでトグルして、しばらく待つ
----------------------- - BYPASS命令を2回発行
- JSTART命令を発行
- RUNTEST_IDLEでトグルし、しばらく待つ
これで、PLが書き変わります。
PLが書き変わってもLinux自体は動作し続けられますが、PLにあるすべてのレジスタはリセットされてしまうので、画面を使うならもう一度再起動しなければならなくなるでしょう。
![]()
書き込んで→I/Oを確認→書き込んで→I/Oを確認・・という開発&デバッグのプロセスが楽にできるようになりました。
Ultra96ボードへの書き込みだと約10秒でできます。
PLの書き換えだけならば再起動を伴わないので、楽ですよ。
UltraScale+のバウンダリスキャンがおかしい件
2018.10.13
UltraScale+のバウンダリスキャンにおいて、コントロールセルがおかしい問題は、Answerに書かれていました。
https://japan.xilinx.com/support/answers/62985.html
実はSpartan-6のときにも同様の問題があったのです。
- http://nahitafu.cocolog-nifty.com/nahitafu/2009/09/spartan-6-11d0.html
- http://nahitafu.cocolog-nifty.com/nahitafu/2009/11/spartan-6-0b37.html
- http://nahitafu.cocolog-nifty.com/nahitafu/2010/12/spartan-6mitouj.html
6シリーズのときは出力ピンとして誤認識されてしまうのに対して、UltraScaleでは入力ピンとして誤認識されます。
7シリーズでは全く問題なかったので、6シリーズとUltraScaleを設計したのは同じグループなのかもしれない。偶数シリーズと奇数誤で設計担当グループが交互に変わるとか、そういう事情があるのかもしれない。
![]()
さて、上記のAnswerによると、バウンダリスキャンで方向セルを正しく読めるようにするには、OBUFの代わりにT=0にしたOBUFTを使えとのことでした。
出力ピンにOBUFTを使うようにしたら、PLの入出力セルの方向が正しく読めるようになりました。
この波形を作るために書いたコードはこんな感じです。

カウンタがある一定値以上になると入力になり、一定値未満ならばバイナリでカウントアップする値を出力するというものです。
![]()
これまでにわかっている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で開きます。
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モジュールとして登録します。
これで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が開いて、以下のような画面になります。
そうしたら、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プレイヤーで再生します。
書き込みには結構な時間がかかります。
書き込んだ後、JTAGロジックアナライザで見てみると、
ちゃんとカウントアップして、休む波形が見えました。
ただ、様子がおかしいですね。バウンダリスキャンセルの方向ピンが正しく読み取れていないようです。
本来は、このDIRと書かれた方向制御ピンは出力時には0になり、入力時には1になるはずです。
しかし、常に1のままで、入力として判断されてしまいます。
ZYNQ UltraScale+ MPSoCのJTAGのしくみ
2018.10.11
ZYNQ UltraScale+ MPSoC(以下、ZU)の仕組みを完全に理解しました。
ZUの中にあるJTAGの構造をかみ砕いて描くと、こうなります。
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は使えるので、セキュリティゲートを気にする必要はありません。
![]()
ZYNQ UltraScale+ MPSoCのJTAG命令レジスタの構造は次の図のようになっています。
ただし、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)を発行すると読めます。
![]()
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個のデバイスが見つかるようになりました。
そして、ARMのDAPも認識されるようになり、正常にバウンダリスキャンができるようになります。
まとめると
- 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では以下のようになります。
ここで厄介なことが3つあります。JTAGチェーンの構成が変わるたびに、JTAGのTMSを1にして何回かのTCKを与えてTAPをRESETしないといけないことと、JTAGチェーンの構成はソフトで変わることです。そのため、ハードウェアリセットが行われて、PMU→CSU→FSBLと起動のステップが進んだあたりでJTAGをリセットしなければなりません。
また、ZUのARM TAPはJTAGの規格に反してTAP RESET後にDRにIDCODEが現れません。そのため、自動で認識することができないことです。
![]()
JTAGを使う汎用的なツールに「MITOUJTAG(みとうジェイタグ)」というのがあります。MITOUJTAGを使うとバウンダリスキャンで端子の状態が見えます。
Ultra96ボードでは以下のように見えます。
Ultra96ボードでチカチカ光っているLEDのあたりのピンを見てみます。
AB4、AA4、Y5、AA3、AB5番ピンにこれらの端子があります。
ZUでは、普通にバウンダリスキャンでSAMPLEしても、これらの端子の状態は正しく見ることができません。
前の記事で書いたとおり、SAMPLEするときには入力セルから値を読むのが普通なのですが、

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

これは、はっきり言って、ZUのバグだと思います。
しかも、この入力ピンの値が出力セルから読み出される現象は、SAMPLE時のみ発生し、EXTEST時には発生しません。したがって、BSDLファイルの変更では対処できません。
そこで、MITOUJTAGでは、「ZYNQUltraScale+ MPSoCならば、SAMPLE状態のときに、入力セルと出力セルの読み出した値を入れ替える」という方法でこの問題に対処することにしました。
このようにすることで、端子から出力している値と、端子から入力している値を正しく読み出すことに成功しました。
![]()
以上の問題を解決し、Ultra96ボードでLinuxが起動する時の波形を見ることに成功しました。
まずは下の波形をご覧ください。
UART0_TXに間欠的に動く波形が出ています。これはコンソールへの文字出力です。
起動してから5秒と8秒付近で、それぞれLinuxの起動と、BlueToothとWLANの起動が起こります。このときにMIOのピンの出力状態が変わるのが見てとれます。
起動後8秒後くらいというのは、コンソールにこのような文字列が出力されているあたりです。
LED0(緑のLED)がチカチカを開始するのが見えています。
あと、見て面白いのは起動後8秒付近でUSB1が起動することと、SD1に一瞬だけアクセスすることかなと思います。
![]()
UltraScale+のJTAGの仕組みがだいたい解明できました。
ポイントは、
- CSUやFSBLによってソフト的にJTAGチェーンの構成が変わるので、それに合わせてTAP RESETをしなければならない
- SAMPLE時の入力セルと出力セルが逆になっている
- DDR4メモリの端子は見えない(これもチップのバグかもしれない)
MITOUJTAGでは、このような問題に対処するためのUltraScale+用のパッチを提供する用意があります。
MITOUJTAGセミナー(応用編)を開催しました
2018.09.05
本日、JTAGチャレンジ基板を使った初めてのセミナーを開催しました。
JTAGチャレンジ基板とは
わざと間違いを作りこんだFPGA基板。正常に動作せず、FPGAメーカー純正のツールでもデバッグできない。
この基板はそのままでは動作しませんが、MITOUJTAGというツールを使うと、FPGAが起動しない理由や、FPGA間の断線の発見などができるというものです。
アンケートを集計したところ、5人中3人の方が「とても満足」ごご記入くださいました。
お寄せいただいた感想やご意見はこのような感じでした。
- セミナーの内容とは別の不明点も教えてもらえて、勉強になった。
- 実際に不具合のある基板を実践的にチェック出来たことは良かったと思います。
- JTAGはメーカーの独自拡張が跋扈する深い魔窟というイメージでしたが、怖がらずに挑戦できる気がしてきました。
- Basic版でかなりの事ができることが分かった
- ALTERAのFPGAは使った事は無かったのですが興味のあるMAX10に触れられた事、SVFプレーヤーが何であるかも分かった
ZYNQ UltraScale+のJTAGに異常を発見
2018.08.22
Ultra96ボードを入手して、さっそくやってみたことはJTAGのテストです。
ボードから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が見えているように見えます。
また、端子のAA3、AA4あたりをEXTESTで動かすとLEDがチカチカするので、MITOUJTAGから操作もできていることがわかりました。
しかし、問題はここからです。基板上のSW4を押してもそれに相当する端子の状態が変化しないのです。
これはUltraScale+の持つJTAGのバグではないかと思います。
![]()
本来、JTAGバウンダリスキャンでは、I/Oパッドから入力した値は入力セルから読み出されます。

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

これが仕様なのか設計ミスなのかわかりませんが、JTAGの動作としては間違っているように思われます。
なお、バウンダリスキャンセルを手動で書き換えて、出力セルの値を見るようにすると、一見正しい動作をするのですが、FPGAが出力する値を読めなくなってしまうので、これも正しくありません。
BSDLファイルが間違っているというわけではなく、チップレベルで間違っているようです。
![]()
それから、DDR4メモリの端子が全く動いていないことも気になります。Ultra96ボードのデフォルトのSDカードでは、DDRメモリは使用していないのでしょうか。
UltraScale+用のJTAG書き込みアルゴリズム
2018.08.21
AVNETの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コマンドのようです。
次に、
set device0 [create_hw_device -part xczu2cg]
とコマンドを打つと、JTAGチェーンにxczu2とarm_dapの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などのビットを確認しているようです。
ただし、08000000でマスクしているので、実際にチェックするのはEND_OF_STARTUP_(EOS)_STATUSだけのようです。
ところで、-disable_eos_checkを付けても付けなくても結果は変わらないので、このオプションは効いていないようです。
![]()
ただ、これでは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や掲示板の画像から引用)
MITOUJTAGからMAX10に書き込む方法
2018.08.11
XILINXとALTERAのデバイスが同一のJTAGチェーンにつながっている場合に、MITOUJTAGから書き込む方法を紹介します。
まず、Qualtus PrimeでMAX10のデザインを作ります。
QualtusのToolsからProgrammerを起動します。
QualtusのProgrammerが起動したら、いちど、まっさらな状態にします。
Add Fileを押して、MAX10の出力したファイルを選択します。
MAX10の内蔵ROMに書き込みたいならPOFを選び、揮発性のコンフィギュレーションをしたいならSOFを選びます。
下の図はPOFを選んだ場合の状態です。
次に、同一チェーン上にあるXILINXデバイスを追加したいのですが、当然ながらALTERAのツールはXILINXデバイスを認識しません。
そこで、Add Deviceボタンを押します。
どのデバイスを追加するかを聞かれるので、Importボタンを押します。
ファイル名を入力するダイアログが出るので...ボタンを押します。

D:\Xilinx\Vivado18.1\data\parts\xilinx\spartan7\public\bsdlディレクトリを指定し、中にあるxc7s25_csga225.bsdを指定します。
XC7S25が使用できるようになりました。
下の図のように、XILINXとALTERAがJTAGチェーンでつながります。
もし、順番が逆になっている場合にはUpボタンを押します。
![]()
次にMITOUJTAGから書き込むために、SVFというファイルを作ります。SVFを作るにはProgrammerのFileからCreate JAM JBC、SVF or ISC Fileを行います。
デフォルトでは、下の図のようにjamファイルになっているので、

これを選択して、

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

OKを押します。
これでSVFファイルができました。SVFファイルというのはこのような感じのテキストファイルです。
この中に、Spartan-6とMAX10がチェーンになった場合のMAX10書き込みシーケンスが入っていて、そのまま実行すれば書き込まれるようになっています。
そうしたら、MITOUJTAGを起動して、[ツール]→[SVFプレイヤー]を起動します。
先ほど生成したSVFファイルの中身を貼り付けます。
ここで開始ボタンを押すと、SVFが実行されて、MAX10に書き込まれます。
無事に書き込みが行われ、MAX10が起動しました。
![]()
下の図は、MAX10につないだシリアルADCを操作して、半固定抵抗の値やマイクで拾った音声を、JTAGロジアナで波形として表示しているようすです。
特にWindowsのソフトウェアを組むことなく、FPGAのピンからバイナリの値を出せば、MITOUJTAGのロジアナでそれを拾って、アナログ波形として表示できます。
このやり方は、FPGAやWindowsのソフトを作らなくてもよいので楽ですよ。
JTAGチャレンジ基板の実装が上がってきた
2018.08.10
わざと間違いを作りこんでおいて、JTAGバウンダリスキャンでそれを発見するという「JTAGチャレンジ基板」の初期ロット12台が上がってきました。
Digilentのボードを片っ端からスキャンしてみた
2018.08.09
MITOUJTAGのDigilentプラグインができたので、手元にあるDigilent製ボードを、MITOUJTAGで片っ端からバウンダリスキャンしてみました。
まずは、Artyです。ArtyはXC7A35TのCSG324が乗っているFPGAボードです。
自動認識すると同じIDCODEのデバイスの候補が見つかるので、この中で324ピンのものを選びます。
Artyが動作しているときの、Artix-7の端子の状態です。
ピンクはHレベル、水色はLレベル、塗りつぶしは出力、網掛けは入力の状態を表しています。
ArtyにはSPI ROMが乗っているようで、MITOUJTAGからSPI ROMを認識することもできました。
Artyが起動するときのSPI ROMの端子の動きや、起動後のLEDチカチカの信号も見えました。
![]()
次はSpartan-7が乗ったArty-S7です。Artyとの大きな違いは、Etherのコネクタが無いことです。
こちらも自動認識すると、同じIDCODEのデバイスが見つかります。この中で324ピンのものを選びます。
端子の状態もばっちり見えました。
Arty-S7のデフォルトのLEDチカチカはPWMがかかって、じわりじわりと点滅します。そのようすがJTAGロジアナでも見えています。
![]()
最後はZYBO-Z7です。
ZYBOは初期のころの評価ボードなので画面出力がVGA端子だったりしますが、その後HDMI出力やCSIカメラが付いたZYBO Z7というのが出ました。
FPGAもXC7Z020にアップグレードされています。
自動認識すると、ARMコアとFPGAコアの2つのデバイスが見えます。
LEDチカチカのPWMもよくできています。
様々な端子の信号を見るとこのような感じになっています。
![]()
MITOUJTAGは、他社製ボードであっても使えます。デフォルトのサンプルデザインが動いている状況でも使えます。つまり、FPGAに何もIPを書き込む必要がありません。
FPGAの起動前であっても信号が見えるので便利ですよ。
MITOUJTAGのDigilentプラグインを作成
2018.08.08
Digilent製ボードでMITOUJTAGが使えるようにするため、プラグインを作っています。
ようやくDigilent USB-JTAGの使い方を理解して、MITOUJTAGから使えるようにできました!
まずは、ZYBOとパソコンをつなぎます。ZYBO上のUSB-JTAGで通信するので、USBケーブル1本だけです。
これでDigilent製のボードはUSBをつなぐだけでI/Oピンや波形が見れるようになったわけなのですが、ZYBOが起動するときの波形をバウンダリスキャンのロジアナで見てみたら、毎秒4000サンプリングほど出ていました。つまり250usくらいのサンプリング周期のようです。
JTAGロジアナで見てみると、DDR3メモリの動きなどが見えます。
実は今までのMITOUJTAGにもDigilent USB-JTAGを接続する機能はあったのですが、XILINX ISEがサポートするDigilent Cable Pluginを間接的に使っていたので、ISE(Labtool)が入っていないと使えませんでした。
LabToolはISEのでなければだめで、Vivadoには対応していませんでした。
その意味でも、今回の改良でISEに依存せずにDigilentケーブルが使えるようになったのは大きいといえます。
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機能、バッチ機能などを備えているようです。
DigilentのUSB-JTAGを叩いて、ZYBO上のUSB-JTAGのプロパティと、ARMとZYNQコアをスキャンすることに成功。
AUX Resetというポートは存在していて、GPIOは付属していないようですね。
AUX Resetを0にするとARMのJTAGがしばらく認識できなくなるので、何かの機能はあるようです。GPIOは、おそらくCPUのデバッグに用いる補助的なI/Oに使われるものと思われます。最近のARMでは使いませんが、MIPSのころはGPIOが必要でした。
![]()
次に、Digilentのボードに乗っているUSB-JTAGを使う実験をしてみました。
最初の感想は、かなり遅い。
それもそのはず。USB 2.0 HighSpeedは、1つの操作をするたびに125us待たなければなりません。FT2232はさらに遅いはずです。
実際に試してみると数百usかかったり、かなり不安定です。
そこで、Adeptにはバッチモードというのが用意されていて、複数のJTAG操作をスクリプト化してまとめて投げるのです。
このバッチモードを使うと、任意の波形をそこそこの速度で出せるようになりました。USBの遅さカバーする方法が私のライブラリと同じ設計思想なのですぐに使い方がわかりました。FTDIのICの動きもだいたい想像できます。
ZYBOのJTAGでIDCODEを読み出すシーケンスを実行してみました。
ARMとZYNQコアのIDCODEが読み出せているのがわかります。
TCKは最高で30MHzほど出ていて、これが最高速度のようです。
JTAGチャレンジ基板の生板ができてきた
2018.08.03
JTAGチャレンジ基板がほぼ完成
2018.07.30
わざと間違いを作りこんでおいて、それを発見するための基板「JTAGチャレンジ基板」の設計がほぼ終わりました。
このボードには、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にはマイクと半固定抵抗がつながっています。
マイクで拾った音をシリアルADCでディジタルにして、MAX10からSpartan-7にデータを送り、Spartan-7で再びアナログにするという動作をします。ボイスレコーダみたいなものができます。
![]()
ですが、設計ミスによりFPGAは起動しません。
そのミスを修正してFPGAが起動するようになっても、FPGA間の接続に問題があって、MAX10とSpartan-7の間で正しくデータを伝達できません。
DDR3 SDRAMも、BPI Flash ROMも致命的な設計ミスにより動作しません。
そういう間違いが10個くらいあります。
どれも、組み込みの基板設計では、よくありそうなミスを仕込んでいます。
![]()
もし、FPGAにDDR3メモリをアクセスする回路を書いて地道にデバッグするとなると、途方もない時間がかかってしまいますが、そこをJTAGを使ってあっという間にデバッグできるようにしようというのが、このセミナーの趣旨となります。
6層基板で、140mm×100mmの、ほぼ葉書サイズです。
早ければ金曜日に生基板が届き、お盆前には実装が上がる予定です。
JTAGチャレンジ基板がだいたいできてきた
2018.07.27
JTAGチャレンジ基板の配線を引き続き進めています。
JTAGチャレンジ基板の設計再開
2018.07.26
設計ミスをわざと作りこんだ「JTAGチャレンジ基板」の配線を再開しました。
この基板は、わざと間違いを作りこんだ基板をJTAGでデバッグして、いかに早く動くようにできるかという、一種のエクストリームな競技デバッグ(?)のための基板です。
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の配線は、大変かなと思って二の足を踏んでいたけど、やってみたら結構楽に引けました。
とりあえず、DDR3の配線ができた状態。
そして、FPGAとつないだ状態です。
このDDR3の配線、全部内層(茶色)を通したからオシロじゃ見えません。
終端抵抗とViaがあるのは、せめてもの優しさといえるでしょう。
その次はパラレルフラッシュとの接続ですが、DDR3よりもこっちのほうが疲れたかもしれません。42本もあります。電源ピンが1個しかないし、20年前はみんな、こんなのでも動いていたんですね。
JTAGチャレンジ基板(仮称)を作ります
2018.07.12
JTAGチャレンジ基板(仮称)というものを作ります。
これはどういうものかというと、RXマイコン、Spartan-7、MAX10が乗った基板なのですが、基板にいろいろとミスが仕込んであって、動かないのです。
そのミスというのは、回路設計者や基板設計者がやりがちな、よくある設計ミスです。
クロックが来ていないとか、リセットがかからないとか、FPGAが起動しないとか・・そういうミスなのですが、本当の基板でやったら即作り直しになって、再設計費数十万円と1か月を無駄にするような、胃が痛くなるようなミスをたくさん仕込んであります。
で、そんな動かない基板をどうするかというと、MITOUJTAGを使えばそういうミスが一瞬で発見できるということを体験してもらおうというわけです。
MITOUJTAGというのは、世界で一番最初にJTAGバウンダリスキャンを組み込み回路のデバッグに活用できるようにしたツールです。
http://www.tokudenkairo.co.jp/jtag/
今までは工場の出荷検査くらいにしか使われてこなかったJTAGバウンダリスキャンを、開発者ひとりひとりが自分の回路のために使えるようにしたツールなのです。
![]()
たとえば、DDR3メモリのアドレス線が入れ替わっていたら、どうやってデバッグしますか?MIGを使って何度も作り直す?
たとえば、FPGAにクロックが入っていなかったら、どうやってデバッグしますか?Vivadoの内蔵JTAGアナライザはクロックがなかったら動きませんよね。
もし、6層基板の内層が切れていたら、どうやって発見しますか?片方のFPGAからテスト信号を出して、もう一個のFPGAでロジアナを動かす?そんなめんどくさいこと・・・
でも、内層が切れているかも・・・ということにどうやって気づきますか?
![]()
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のパラメータを読み込めるようにしました。
![]()
検証に使ったボードは特電のSpartan-6ボード。このボードのSPI ROMをMacronix社のMX25R3235Fに乗せ換えます。
ROMはブランクなので、当然ながらFPGAは起動前の状態で、I/Oは全ピン入力状態としえて見えます。
MITOUJTAGはこのSPI ROMのIDCODEを知らないので、最初は書き込みができません。不明と出てしまいます。
そこで、下記のようなファイルを作成し、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でも認識できるようになります。
もちろん書き込みも成功し、
ちゃんと起動しました。
![]()
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ファイルが表示されないというのは、下の図のような状況です。
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では前者の方法にしか対応していませんでした。
![]()
これらの問題を解決したパッチを作成しました。
今回、動作テストに使ったボードは、Arty-Z7です。デバイスを自動認識させたら、右クリックして、「ピン定義ファイルの読み込み」を行います。
一覧にちゃんとXDCファイルが表示されるようになりました。
そして、Arty-Z7のXDCファイルを読み込んでロジアナモードを開くと、
このようにピンの定義が読み込まれていることがわかります。
この機能は次回のMITOUJTAGの更新の際に取り込んでリリースしますが、パッチだけすぐに欲しいという方はご連絡ください。
MITOUJTAG Pro 3.2をリリースしました
2018.01.13
約1年半の更新点をまとめた、MITOUJTAG Pro 3.2をリリースしました。
まず、各社の新しいデバイスを認識できるよう、デバイスデータベースが更新されました。
XILINXはSpartan-7や、UltraScale+が認識できるようになりました。
この他にはRenesasのRX64、RX65、RX710、RZ。ALTERAではMAX10、Cyclone10。CypressはPSOC6に対応させました。しかし、PSoC6はファイル名はBGAなのにQFPのパッケージの絵が出るのでBSDLファイルが間違っている可能性があります。
それから昨日、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








































































































































