UltraScale+用のJTAG書き込みアルゴリズム
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でコンフィギュレーションできるかどうか、検証してみたいと思います。
| 固定リンク
コメント