« Cosmo-Z Miniのファームウェアアップデート・スクリプトを作った | トップページ | 粗大ごみの回収に向けて »

2018.11.26

XILINXのJTAG to AXI masterのプロトコル

JTAG to AXI masterは便利そうなのですが、Vivadoを起動しないと使えず、またtclで操作するとか、操作するシーケンスをcreateしたりdestroyしたりと、使い勝手の面ではよいとは言えません。

そこで、どのようなプロトコルで通信しているかを探りました。

実験に使ったボードは特電Artix-7ボード

Artixboardt_4

USB3.0に対応していて、オンボードでUSB-JTAGも乗っていて、2.54mmピッチのピンヘッダがあるのが便利です。

Artix-7用に、Vivadoで下の図のようなデザインを作ります。

Jaxi1

そして、VivadoとMITOUJTAGを接続し、Vivadoが出力するJTAGシーケンスをキャプチャします。

Vivadoは以下のようなシーケンスを大量に吐き出します。

SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00060008A9) TDO (0160008000);

最初のSIR 6 TDI (02)は、USER1という命令です。

USER1命令の後は、SDR 32 (データレジスタへの32bitシフト)か、SDR 17 (データレジスタへの17bitシフト)かのどちらかです。

SDR32の中身は04900180か04800100、00000000であることが多く、SDR17の中身は00000 00400 00500 00600 0F000など様々です。

XILINXのILA、VIO、JTAG2AXIはいずれも共通のJTAGコンポーネントを使っているようで、(※ALTERAに例えればJTAG HUB)、何かのHUB的なものの下に複数のJTAGサブコンポーネントをぶら下げているようです。

そのため、JTAG HUB的な何かをコントロールするのが04900180などのコマンドではないかと想像できます。

そして、各コンポーネントのレジスタに具体的な値を与えているのが、

SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00060008A9) TDO (0160008000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00500) TDO (00000);
SDR 27 TDI (1FFF0A9) TDO (7F00000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00600) TDO (00000);
SDR 139 TDI (000000000000000000000000000000000A9) TDO (0000000003F000818081000380008038800);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);

というSDR17のシーケンス。この00400,00500,00600という順番で3個セットで繰り返し出てきます。また、たまに0F000と00000も出てきます。

00400の後はSDR37で、00500の後はSDR27、00600の後はSDRの長さは可変です。そして、データレジスタの末尾は必ずA9になっています。

出てくるパターンをまとめると、

  • SDR32 04900180 -> SDR17 0F000 -> 75bit
  • SDR32 04900180 -> SDR17 00000 -> 1243bit
  • SDR32 04900180 -> SDR17 00400 -> 37bit
  • SDR32 04900180 -> SDR17 00500 -> 27bit
  • SDR32 04900180 -> SDR17 00600 -> 可変

となります。

そんな感じの心の目で見ていくと、VivadoのTclを通じてJTAG2AXIに

create_hw_axi_txn wr [get_hw_axis hw_axi_1] -len 1 -address 40001234 -data 55555555 -type write
run_hw_axi wr
delete_hw_axi_txn wr

で書き込んだ値を出力したと思われる箇所が見つかりました。

SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00000001A9) TDO (0160008000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00500) TDO (00000);
SDR 27 TDI (00006A9) TDO (7FF0000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00600) TDO (00000);
SDR 27 TDI (00000A9) TDO (1001000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00020002A9) TDO (0000001800);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00500) TDO (00000);
SDR 27 TDI (20011A9) TDO (0006000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00600) TDO (00000);
SDR 42 TDI (055555555A9) TDO (2AAA8000000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00020004A9) TDO (0020002000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00500) TDO (00000);
SDR 27 TDI (20010A9) TDO (0011800);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00600) TDO (00000);
SDR 74 TDI (04000123400498400A9) TDO (091A0024C2000000000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00000001A9) TDO (0020004000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00500) TDO (00000);
SDR 27 TDI (00003A9) TDO (0010000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00600) TDO (00000);
SDR 27 TDI (00000A9) TDO (0000000);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00400) TDO (00000);
SDR 37 TDI (00000001A9) TDO (0000001800);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00500) TDO (00000);
SDR 27 TDI (00004A9) TDO (0003800);
SIR 6 TDI (3F) TDO (35);
SIR 6 TDI (02) TDO (35);
SDR 32 TDI (04900180) TDO (04900101);
SDR 17 TDI (00600) TDO (00000);
SDR 27 TDI (00000A9) TDO (0000800);
STATE RESET;

どうやら、データを先に与えてからコマンドを与えるようです。

ただ、この部分シーケンスをSVFプレイヤーで流し込んでも、LEDは変化しませんでした。もっと前後の長い部分を流さなければならないようですが、ちょっと間違えるとVivadoのRefreshの操作をしないと戻らなくなります。

結論としては、JTAG to AXI masterのプロトコルは非常に長く、1ワードのAXIトランザクション発行のために数十行のJTAGコマンドを発行しなければならず、効率が良くありません。

プロトコルも難解でリバースエンジニアリングするのは容易ではなさそうです。

その上、エラーが起きたときの復帰が難しいので、無理に解読して自分のソフトウェアで使えるようにするのは得策ではないと考えられます。

|

« Cosmo-Z Miniのファームウェアアップデート・スクリプトを作った | トップページ | 粗大ごみの回収に向けて »

コメント

コメントを書く



(ウェブ上には掲載しません)




« Cosmo-Z Miniのファームウェアアップデート・スクリプトを作った | トップページ | 粗大ごみの回収に向けて »