/* * どうして XSVF ファイルを経由するのか * (JTAG/(X)SVF/PlayXSVF に関しての覚え書き) * by uratan! 2005.1.10 */ 疑問 ・手製の書き込みツールを使おうとすると「XSVF ファイルに変換して」 とかいう話になってややこしくなるのはどうしてか ? 結論 ・(X)SVF はそもそも JTAG 信号の TCK/TMS/TDI/TDO の記述であり、そういう 見方をすれば非常にシンプルである。 しかしながら逆の見方をすると、(X)SVF ファイルには HDL 記述より作成 される静的な回路情報のほかに、書き込み・ベリファイなどのデバイス依存の (レジスタアクセスレベルの)オペレーションや、対象の JTAG チェーンの 状態など環境面までも含んでしまっている。 そもそも書き込みを行うためにはこれらの情報すべてが必要であり、結局 どのレイヤーでこれを担当・処理・隠蔽するか、の違いである。 (iMPACT で直接デバイスをコンフィグする場合はかなりの部分が隠蔽される) 手製ツールにおいては、「(X)SVF の生成にまつわるデバイス依存の制御や .bit/.jed ファイルの読みだし」といった複雑な処理を Xilinx ツールに まかせ、シンプルな面である「XSVF --> TCK/TMS/TDI/TDO (JTAG) の変換」 部分のみを実装する形を取ることがもっとも簡便である。その結果、オペレータ に上記情報を (X)SVF という形で意識させてしまうが、いい機会なので 知見を深めて、ややこしいと思わないようになるべきであろう。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 以下、眉に唾つけてお読みください。 ●JTAG とは、 ・シフト動作をメインに置くことによってインターフェースの 信号数を最低限に少なくしたシリアル通信方式のこと。(?) ●例えば XC9536XL の JTAG の内部レジスタは、 ・下図のような*感じ*になっている。 ・JTAG TAP コントローラの仕様にしたがって制御すれば、任意の内部 レジスタにアクセスできる。 ・ただしベースの JTAG TAP コントローラ仕様では、INSTRUCTION reg と DATA reg の 2分岐しかケアされてない。(最初の * のところ、後述) ・どの DATA reg を選択するか (後の * のところ)は、与えた INSTRUCTION で 制御される。しかし INSTRUCTION の仕様はデバイス依存である。 ・この内部構成を定義したファイルを BSDL ファイルと言い、例えば C:\Xilinx\XC9500XL\data\XC9536XL.bsd がそれで、テキストファイルである。 ・また「config reg --> 内部の書き換え」の仕様もデバイス依存である。 XC9536XL +-------------------------+ | +--------------+ | | | internal ROM | | | +--------------+ | | ^ | |DATA REGs | | | config reg | | +--OOOOOOOO...OO--+ | | | [34bits] | | | | | | | | boundary reg | | | +-*-OOOOOOOOO....OO-*-+ | | | | [108bits] | | | | | | | | | | | | bypass reg | | | | | +-------O---------+ | | | | [1bit] | | | | | | TCK-->| | INSTRUCTION REG | | (O はシフトレジスタの 1ビット) | *------OOOOOOOO-------* | (* はマルチプレクサ/セレクタ、 TMS-->| | [8bits] | | 要は切り替えスイッチ) | | | | TDI-->|TDI TDO|--+ +-------------------------+ | TDO<-------------------------------+ ●INSTRUCTION/DATA reg とデータをやりとりする方法は、 ・ステートダイアグラム(下図)に従って JTAG TAP コントローラを管理し 入出力を行う。ステート遷移は、TMS (Test Mode Select) に 2分岐の方向を 与えて、TCK(Test ClocK) の立ち上がりで行われる。(図の '|'、上から下) ・同じステートに留まるステート遷移もある(図の 'U' のところ) ・XXX-DR というステートが DATA reg をいじるステートで、 XXX-IR というステートが INSTRUCTION reg をいじるステートである。 ・Shift-DR/IR (と Exit-DR/IR) ステートにおいて、指定レジスタとTDI/TDO が 連結され「トコロテン」式にいれたデータが吸い込まれ/出てくる。 (シフトレジスタだから) 必要ビット数分このステートを繰り返す。 /* * ============================== * TAP-Controller State Diagram * ============================== 1) state transition is controled by TMS * 2) 'U' means loop, stay/repeat the state * +------------------+ * | Test-Logic-Reset |<------------------------------------------+ * +-----0--------1---+ | * | U | * +---------------+ +----------------+ +----------------+ | * | Run-Test/Idle 1--->| Select-DR-Scan 1--->| Select-IR-Scan 1--+ * +------------0--+ +--------0-------+ +--------0-------+ * ^ U ^ | | * | | +-----------------+ +-----------------+ * | | | Capture-DR | | Capture-IR | * | | +----0----------1-+ +----0----------1-+ * | | | | | | * | | +------------+ | +------------+ | * | | | Shift-DR | | | Shift-IR | | * | | +----1-----0-+ | +----1-----0-+ | * | | ^ | U V ^ | U V * | | | +--------------+ | +--------------+ * | | | | Exit1-DR | | | Exit1-IR | * | | | +-0----------1-+ | +-0----------1-+ * | | | | | | | | * | | | +----------+ | | +----------+ | * | | | | Pause-DR | | | | Pause-IR | | * | | | +-1------0-+ | | +-1------0-+ | * | | | | U | | | U | * | | | +----------+ | | +----------+ | * | | +-0 Exit2-DR | | +-0 Exit2-IR | | * | | +-1--------+ | +-1--------+ | * | | | V | V * | | +-----------------+ +-----------------+ * | | | Update-DR | | Update-IR | * | | +--1-----------0--+ +--1-----------0--+ * | | | | | | * | +-----+---------------------+ | * +---------------------------------+---------------------+ */ ●JTAG はそう言うわけなので、 ・こういう使い方を普通にする。(JTAG Chain) ・TMS, TCKはパラレル接続で共通なので、すべての TAP コントローラが 全く同じステート遷移をする。 ・なので結果的に、すべての INSTRUCTION reg は連結された形に、 またすべての DATA reg も連結された形になる。 ・たとえば出てくるデータから XCF02S のデータを取りだそうとしても、 最初にでてくるのは XC3S50 のデータなので読み捨てなければならないし、 ・INSTRUCTION を与える時には ゴミが変な命令に解釈されないように XC3S50 の分もケアして、先に XC3S50 の命令 + 後に XCF02S の 命令をセットにしてトコロテン製造器に押し込まなくてはならない。 ・また図のとおり、LSB から先に送り込むし、LSB から先に出てくる。 ・当然 XCF02S が 1個単独である場合とはアクセス方法が変わる。 XCF02S XC3S50 +-------------------------+ +-------------------------+ |DATA REGs | | | | | | | | data0 reg | | | | +--OOOOOOOO...OO--+ | | | | | [4096bits] | | |DATA REGS | | | | | | | | | boundary reg | | | boundary reg | | +-*-OOOOOOOOO....OO-*-+ | | +-*-OOOOOOOOO....OO-*-+ | | | | [25bits] | | | | | | [383bits] | | | | | | | | | | | | | | | | | | bypass reg | | | | | | bypass reg | | | | | +-------O---------+ | | | | +-------O---------+ | | | | [1bit] | | | | [1bit] | | | | | | | | | | | | INSTRUCTION REG | | | | INSTRUCTION REG | | | *------OOOOOOOO-------* | | *------OOOOOOOO-------* | | | [8bits] | | | | [6bits] | | | | | | | | | | TDI-->|TDI TDO|----->|TDI TDO|--+ +-------------------------+ +-------------------------+ | ^ ^ | TMS | | | TCK --------------+--------------------------------+ | | TDO<----------------------------------------------------------------+ ●それで、 ・CPLD の記述をコンパイルした結果の XXX.JED ファイルは、図の "internal ROM" と静的に同じものであるのだ(ろう)が、この XXX.JED を internal ROM に送り込むために、 1) 「その CPLD に依存する書き込み手順」を 2) 「JTAG chain の状態を鑑みた」うえで 3) 「TAP コントローラに手順に則って」 送り込むことが必要となる。 XC9536XL +-------------------------+ | +--------------+ | | | internal ROM | | <--- .EQU. XXX.JED | +--------------+ | | ^ | |DATA REGs | | | config reg | | +--OOOOOOOO...OO--+ | | | [34bits] | | . . . . ●XC9536XL が 1個しかない、と決まっているとすれば、 ・XC9536XL では、書き込みに関して以下のような INSTRUCTION があるので、 ISPEN (11101000) FERASE (11101100) FPGM (11101010) FVFY (11101110) ISPEX (11110000) など ・.jed ファイルを読み込んで上記の INSTRUCTION を順次発行するような C:\> wrt-9536.exe XXX.JED C:\> vrfy-9536.exe XXX.JED とかいうツールも作れるのであろうが、汎用性は低くなってしまう。 なので Xilinx の提唱(?) する構成は以下のとおりである。 +--------+ XXX.JED ------------->| | JTAG chain の構成 | | とデバイスリスト --->| iMPACT |===> "kono-chain-no-kore-ni- (*.BSDL) | (など)| XXX-JED-wo-kakikomu.XSVF" write してから ------>| | | verify するの +--------+ | V C:\> PlayXSVF.exe "kono.....XSVF" ・つまり 「JTAG のステート指定と TDI/TDO の関係だけを書いた「楽譜」を渡して あげるから、それ見て踊っててくれれば OK よ、ややこしい話は オレ(iMPACT==Xilinx) が面倒見るからさ」 という構成である。 ・この「楽譜」を SVF (Serial Vector Format) ファイルといい、 この「楽譜」を見て TCK/TMS/TDI/TDO を駆動する「再生プログラム」が PlayXSVF.exe (後述)というわけなのである。 ・この構成であれば、書き込みツール内では先の FERASE (11101100) FPGM (11101010) などに関して知らなくてもよいし、デバイスや JTAG の状態が変わっても 関与しなくなる。 ●なので、 ・この PlayXSVF の部分のみを EZ-USB にインプリメントすれば、全体として 書き込み装置が完成する。 ・しかも上の PlayXSVF.exe のソースコードも Xilinx より公開されている。 | | j_xapp058.pdf - 「インシステムプログラミング機能」 39ページ | | eisp_pc.zip - xapp058 に付随するコードほか (情報量 2.3MB) | micro.h ... XSVF 解析・TAP ステート (42行) | micro.c ... コントローラ本体 (1826行) | lenval.h ... TDI/TDO データを保持する (93行) | lenval.c ... メモリ管理ルーチン (190行) | ports.h ... 機種依存部分を (31行) | ports.c ... 切り出した部分 (154行) | ・XSVF を経由することで、書き込み装置側において、個別のデバイスや JTAG チェーンに関する話には関わらずにすむようになった。しかし、 別途 XSVF ファイルを生成するという作業が加わるわけで、この XSVF ファイルの生成や取り扱いにおいては、それがどんな情報を含んでいるのか ある程度理解しておくことが要求されるようになる。 ●ちなみに (X)SVF とは ・TI の提唱によりできたフォーマットで、現状ほぼ業界標準になっている? ・XSVF はバイナリフォーマットだが、SVF というテキストフォーマットも あり、両者は(ある面では)等価である(と思う)。 ・SVF を XSVF に変換するツールは Xilinx から提供されている。(svf2xsvf.exe) ・SVF の中身はこんな感じ。 +--- (XCF02S+XC3S50) の XC3S50 に write する SVF の例 -------------- |... |SIR 14 TDI (3fff) SMASK (3fff) TDO (0041) MASK (39c3) ; |TIR 8 TDI (ff) SMASK (ff) ; |HIR 0 ; |HDR 0 ; |TDR 1 TDI (00) SMASK (01) ; |//Loading device with 'idcode' instruction. |SIR 6 TDI (09) SMASK (3f) ; |SDR 32 TDI (00000000) SMASK (ffffffff) TDO (f140d093) MASK (0fffffff) ; |//Loading device with 'bypass' instruction. |SIR 6 TDI (3f) ; |// Loading device with a `jprogram` instruction. |SIR 6 TDI (0b) ; |RUNTEST 10000 TCK; |// Loading device with a `cfg_in` instruction. |// erase first |SIR 6 TDI (05) ; |SDR 223 TDI (0000000000000000700000004000800633554caaffffffff80000000) SMASK (7fffffffffffffffffffffffffffffffffffffffffffffff80000000) ; |// Loading device with a `jshutdown` instruction. |SIR 6 TDI (0d) ; |RUNTEST 12 TCK; |// Loading device with a `cfg_in` instruction. |STATE RESET; |SIR 6 TDI (05) TDO (00) MASK (00) ; |SDR 127 TDI (000000000000000033554caa80000000) SMASK (7fffffffffffffffffffffff80000000) ; |SIR 6 TDI (05) TDO (00) ; |SDR 439423 TDI (000000020000000200000002000000025800000040008006757d0000400000060000000040028006500000004000800600000002000000020000000200000002000000020000000200000002000000020000000200000002000000020000000200000002000000020000000200000002000000 |0200000002000000020000000200000002000000020000000200000002000000020000000200000002000000020000000200000002000000020000000200000002000000020000000200000002000000026000000040008006280000004000800647b7000000000000000000000000000000000000000000000000 |... +---------------------------------- 計 964行 / 223396 バイト ------- ・まあ こんなふうに解釈するのだろう(と思う)。 +------------------------------------------------------------------- |//Loading device with 'idcode' instruction. |SIR 6 TDI (09) SMASK (3f) ; | ....... Shift-IR ステートに自分で行って、INSRTUCTION reg に | 6bit:0x09 を送る |SDR 32 TDI (00000000) SMASK (ffffffff) TDO (f140d093) MASK (0fffffff) ; | ....... Shift-DR ステートに自分で行って、DATA reg に | 32bit:0x00000000 を送り、でてきた 32bit のうち 下28bit が | 期待値 0x140d093 と同じか調べる。 +------------------------------------------------------------------- ・テキストの SVF からバイナリの XSVF に変換する際に、こういう 等価変換を加えたりもできるようだ(?)。 (上で、"SDR 439423 TDI..." とあるが、このオペレーションにより、 データバッファの大きさを小さくできる。svf2xsvf.exe に与える -rlen オプションはこれだと思う(?)) +------------------------------------------------------------------- |SDR 32 TDI (00000000) SMASK (ffffffff) TDO (f140d093) MASK (0fffffff) ; +------------------------------------------------------------------- || +------------------------------------------------------------------- |SDRtuduku 16 TDI (0000) SMASK (ffff) TDO (d093) MASK (ffff) ; |SDRosimai 16 TDI (0000) SMASK (ffff) TDO (f140) MASK (0fff) ; +------------------------------------------------------------------- ---- uratan@miomio.jp