« 高位合成のお勉強 | トップページ | ZYNQ UltraScale+のJTAGに異常を発見 »

2018.08.21

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

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を付けても付けなくても結果は変わらないので、このオプションは効いていないようです。

ただ、これでは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でコンフィギュレーションできるかどうか、検証してみたいと思います。

|

« 高位合成のお勉強 | トップページ | ZYNQ UltraScale+のJTAGに異常を発見 »

コメント

コメントを書く



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




« 高位合成のお勉強 | トップページ | ZYNQ UltraScale+のJTAGに異常を発見 »