« TE0790のピン配置と使い方 | トップページ | GOWINのGW1NR_9をバウンダリスキャンすることができた »

2020.03.07

XILINXのJTAGケーブル拡張を調査(1)

DigilentのJTAGケーブルがどのようにしてVivadoに認識されるのか、自分のJTAGケーブルをVivadoに認識させることができるか、ということを調べています。

VivadoでDigilent(互換)ケーブルを接続すると、xilinx_tcf/Digilent/シリアル番号という形で表示されます。

Xilinx_tcf

このことから想像できるのは、うまくプラグインを作ってやれば、xilinx_tcf/自社名/シリアル番号みたいなJTAGケーブルが作れるのではないかという期待です。

VivadoはOpenHardwareManagerを行う際に、LocalServer以外にRemoteServerを選ぶことができ、このときのポート番号は3121と表示されています。

Local3121

図にすると、

Hwserver_layer

となります。

WireSharkを使ってローカルポートへの3121の通信をキャプチャしてみると、

Capture3121

どんなパケットが流れているかを追ってみると、

① Vivado→hw_server

LocatorHello["ZeroCopy"]

② hw_server→Vivado

LocatorHello["ZeroCopy","Dpc","MicroPython","JtagFpga","ContextXvc","DebugCorePolling","DebugCore","XicomEverest","svf","XicomSysmon","zynqflash","XicomFlash","bpi","spi","xsdb","Xicom_v1.00","Xicom_v1.01","xicom_0","Xicom","XilinxReset","JtagDevice","JtagCable","Jtag","ContextParams","Diagnostics","Profiler","Disassembly","DPrintf","PathMap","Streams","Expressions","FileSystem","LineNumbers","SymbolsProxyV2","SymbolsProxyV1","Symbols","StackTrace","Registers","MemoryMap","Memory","Breakpoints","RunControl","ContextReset","ContextQuery","Locator"]

③ Vivado→hw_server

JtagCablegetServerDescriptions

④ hw_server→Vivado

Xicom_v1.00numChannelsUpdated"arg_0"![["clients_connected","int",1]]EJtagCableserverAdded[{"ID":"jss7","ServerID":"digilent-ftdi","isActive":true}]EJtagCableserverAdded[{"ID":"jss8","ServerID":"xilinx-ftdi","isActive":true}]EJtagCableserverAdded[{"ID":"jss9","ServerID":"digilent-djtg","isActive":true}]EJtagCableserverAdded[{"ID":"jss10","ServerID":"xilinx-pcusb","isActive":true}]EJtagCableserverAdded[{"ID":"jss11","ServerID":"bscan-jtag","isActive":true}]EJtagcontextAdded[{"ID":"jsn-JTAG-ONB4-251633059800A","Name":"whole scan chain","idCode":255,"idCode2":0,"irLen":0,"isTap":true}]EXicom_v1.00contextAdded"jsn-JTAG-ONB4-251633059800A""arg_0"[["server_id","string","jss7"],["manufacturer","string","Digilent"],["product_id","string","JTAG-ONB4"],["serial","string","251633059800A"],["port_description","string","JTAG-ONB4"],["port_is_active","bool",true],["port_is_initializing","bool",false],["port_is_error","bool",false],["esn","string","Digilent/251633059800A/"],["name","string","whole scan chain"],["idcode","int",255],["irlen","int",0],["is_tap","bool",true],["is_mux","bool",false],["is_branch","bool",false],["is_active","bool",false]]EJtagCablecontextAdded[{"ID":"jsn-JTAG-ONB4-251633059800A","ServerID":"jss7","Manufacturer":"Digilent","ProductID":"JTAG-ONB4","Serial":"251633059800A","Description":"JTAG-ONB4","isActive":true}]EJtagcontextChanged[{"ID":"jsn-JTAG-ONB4-251633059800A","Name":"whole scan chain","idCode":255,"idCode2":0,"irLen":0,"isTap":true}]EXicom_v1.00contextChanged"jsn-JTAG-ONB4-251633059800A"?"arg_0"[["name","string","whole scan chain"],["idcode","int",255],["irlen","int",0],["is_tap","bool",true],["is_mux","bool",false],["is_branch","bool",false],["is_active","bool",false]]EJtagcontextAdded[{"ID":"jsn-JTAG-ONB4-251633059800A-0362f093-0","ParentID":"jsn-JTAG-ONB4-251633059800A","Name":"xc7s50","idCode":56815763,"idCode2":0,"irLen":6,"isTap":true,"isActive":true}]EXicom_v1.00contextAdded"jsn-JTAG-ONB4-251633059800A-0362f093-0""arg_0"[["mask","int",268435455],["irlen","int",6],["name","string","xc7s50"],["reg.bypass","int",63],["reg.idcode","int",9],["irlen_detect_off","int",0],["frame_count","int",5420],["debug_node_id","int",0],["arch_name","string","spartan7"],["is_sysmon_supported","int",1],["is_program_supported","int",1],["is_programmable","int",1],["is_cfgmem_supported","int",1],["is_xicom_program_supported","int",1],["is_config_register_supported","int",1],["is_bitstream_reader_supported","int",1],["is_svf_supported","int",1],["is_efuse_writeable","int",1],["is_efuse_readable","int",1],["is_pdi_program_supported","int",0],["is_axi_debug_supported","int",0],["reg.family","int",70],["reg.slr_count","int",1],["reg.xadc_drp_slr0","int",55],["reg.user_count","int",4],["reg.usercode","int",8],["reg.user1","int",2],["reg.user2","int",3],["reg.user3","int",34],["reg.user4","int",35],["reg.cfg_in_slr0","int",5],["reg.cfg_out_slr0","int",4],["reg.jprogram","int",11],["reg.jstart","int",12],["reg.jshutdown","int",13],["reg.fuse_cts_slr0","int",48],["reg.fuse_key_slr0","int",49],["reg.fuse_dna_slr0","int",50],["reg.fuse_user_slr0","int",51],["reg.fuse_cntl_slr0","int",52],["reg.isc_dna","int",23],["reg.isc_program_key","int",18],["reg.isc_disable","int",22],["reg.isc_enable","int",16],["reg.isc_program_slr0","int",17],["reg.isc_noop","int",20],["reg.isc_read_slr0","int",21],["reg.jstart_delay","int",100],["reg.has_dap","int",0],["reg.wpf","int",101],["reg.fdr_pipe_depth","int",0],["reg.boot_check","int",53],["reg.boot_check_mask","int",63],["reg.init_done_check","int",17],["reg.init_done_check_mask","int",49],["reg.prog_done_check","int",49],["reg.prog_done_check_mask","int",49],["server_id","string","jss7"],["manufacturer","string","Digilent"],["product_id","string","JTAG-ONB4"],["serial","string","251633059800A"],["port_description","string","JTAG-ONB4"],["port_is_active","bool",true],["port_is_initializing","bool",false],["port_is_error","bool",false],["esn","string","Digilent/251633059800A/"],["parent_id","string","jsn-JTAG-ONB4-251633059800A"],["version","int",0],["idcode","int",56815763],["is_tap","bool",true],["is_mux","bool",false],["is_branch","bool",false],["is_active","bool",true]]EJtagcontextChanged[{"ID":"jsn-JTAG-ONB4-251633059800A","Name":"whole scan chain","idCode":255,"idCode2":0,"irLen":0,"isTap":true,"isActive":true}]EXicom_v1.00contextChanged"jsn-JTAG-ONB4-251633059800A"≫"arg_0"[["name","string","whole scan chain"],["idcode","int",255],["irlen","int",0],["is_tap","bool",true],["is_mux","bool",false],["is_branch","bool",false],["is_active","bool",true]]ERunControlcontextAdded[{"ID":"JTAG-jsn-JTAG-ONB4-251633059800A-0362f093-0","ProcessID":"JTAG-jsn-JTAG-ONB4-251633059800A-0362f093-0","Name":"xc7s50","CanSuspend":true,"CanResume":1,"CanCount":0,"IsContainer":true,"WordSize":8,"RCGroup":"JTAG-jsn-JTAG-ONB4-251633059800A-0362f093-0","SymbolsGroup":"JTAG-jsn-JTAG-ONB4-251633059800A-0362f093-0","CPUGroup":"JTAG-jsn-JTAG-ONB4-251633059800A-0362f093-0","JtagDeviceID":56815763,"JtagNodeID":"jsn-JTAG-ONB4-251633059800A-0362f093-0","JtagGroup":"JTAG-jsn-JTAG-ONB4-251633059800A-0362f093-0"}]

⑤ hw_server→Vivado

[{"ServerID":"digilent-ftdi"},{"ServerID":"xilinx-ftdi"},{"ServerID":"digilent-djtg"},{"ServerID":"xilinx-pcusb"},{"ServerID":"xilinx-xvc","ParamNames":["host","port"]},{"ServerID":"xilinx-null","ParamNames":["name"]},{"ServerID":"bscan-jtag"}]

⑥ Vivado→hw_server

JtagCableopenServer"digilent-ftdi"{}

⑦ hw_server→Vivado

JtagCableserverAdded[{"ID":"jss7","ServerID":"digilent-ftdi","isActive":true}]R2"jss7"

⑥ Vivado→hw_server

[{"ID":"jsn-JTAG-ONB4-251633059800A","ServerID":"jss7","NodeID":"jsn-JTAG-ONB4-251633059800A","Manufacturer":"Digilent","ProductID":"JTAG-ONB4","Serial":"251633059800A","Description":"JTAG-ONB4","isActive":true}]

このようにケーブルの一覧を要求して、どのケーブルを使用するかを選ぶというプロトコルが行われていました。

当初は自分でポート3121のプロトコルを喋るサーバを作ればよいのかと思いましたが、この期待は容易に打ち砕かれました。まず、プロトコルはバイナリで、内容は謎です。

次の図はXADCで温度をモニタしているときのパケットですが、30~37あたりの値がやたらと多いのですが意味はわかりません。JTAGの波形を表すバイナリなプロトコルなのでしょうか。

Xadc

このように実際のJTAGケーブルの操作方法が全くわかりません。hw_server.exeがSysmonプロトコルを全部やってVivadoは高レベルの指示を出しているだけかもしれません。

また、④のステップでDigilentケーブルの情報をhw_serverがVivadoに送っているということは、hw_serverはDigilentケーブルの扱い方を知っていて、各種ケーブルの扱いはポート3121のプロトコルよりも下のレイヤーで行われているのです。

自作のJTAGケーブルをVivadoに認識させるのは、27Mバイトもあるhw_serverと同じレベルのソフトを作らなければならず、それはリバースエンジニアリングで軽く作るのは不可能でしょう。

 

他の方法としては、XVCを使う方法や、XSDKからはTCFという言葉も出てくるし、vcse_serverというのも出てきます。

  • TCF:Target Communication Frameworkで、おそらくEclipseの拡張プロトコルなのだと思います。XSDKから接続する際に使うようです。おそらくUDPのポート1534を使っています。
  • CSE:ChipScope Engineの略で、おそらくChipScopeから発展してVIOなど様々なプロトコルに対応していったのだと思います。ISEの14のどこかで大幅にプロトコルが変わりました。Vivadoではさらに変わっているものと思われますし、使用しているかどうかもわかりません。
  • VCSE:Vivado版のCSEだと思われます。これを起動するとTCPポート3000~3003(各種CPUに対応)、3142などがListenになります。
  • XVC:Xilinx Virtual Cableです。プロトコルが公開されていますが、1/0のビット列をそのまま送る低レベルなやつで、面白味はありません。ポート番号はTCPの2542です。

libCseTcfPlugin.dllというのもあるのですが、このあたりの関係はよくわかりません。

想像図です。

Tcfcse  

 

hw_server.exeをダンプしてみると、DigilentのUSB-JTAG(Adept)で使われる関数の名前を見つけました。

Djtag_found

このDjtgで始まる関数群がそれです。

つまり、hw_server.exeはDigilentのUSB-JTAGライブラリであるAdeptを呼び出しています。自作のUSB-JTAGをVivadoにネイティブに認識させるには、hw_serverに組み込んでもらうしかないのですが、それは不可能でしょう。

 

よく見ると、FT_で始まる関数も登録されているので、FTD2xxを使うUSB-JTAGならばFTDIのチップとして認識することができるかもしれません。次はこの線で解析をしていこうと思います。

 

|

« TE0790のピン配置と使い方 | トップページ | GOWINのGW1NR_9をバウンダリスキャンすることができた »

コメント

コメントを書く



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




« TE0790のピン配置と使い方 | トップページ | GOWINのGW1NR_9をバウンダリスキャンすることができた »