DigilentのJTAGケーブルがどのようにしてVivadoに認識されるのか、自分のJTAGケーブルをVivadoに認識させることができるか、ということを調べています。
VivadoでDigilent(互換)ケーブルを接続すると、xilinx_tcf/Digilent/シリアル番号という形で表示されます。

このことから想像できるのは、うまくプラグインを作ってやれば、xilinx_tcf/自社名/シリアル番号みたいなJTAGケーブルが作れるのではないかという期待です。
VivadoはOpenHardwareManagerを行う際に、LocalServer以外にRemoteServerを選ぶことができ、このときのポート番号は3121と表示されています。

図にすると、

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

どんなパケットが流れているかを追ってみると、
① 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の波形を表すバイナリなプロトコルなのでしょうか。

このように実際の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というのもあるのですが、このあたりの関係はよくわかりません。
想像図です。
hw_server.exeをダンプしてみると、DigilentのUSB-JTAG(Adept)で使われる関数の名前を見つけました。

このDjtgで始まる関数群がそれです。
つまり、hw_server.exeはDigilentのUSB-JTAGライブラリであるAdeptを呼び出しています。自作のUSB-JTAGをVivadoにネイティブに認識させるには、hw_serverに組み込んでもらうしかないのですが、それは不可能でしょう。
よく見ると、FT_で始まる関数も登録されているので、FTD2xxを使うUSB-JTAGならばFTDIのチップとして認識することができるかもしれません。次はこの線で解析をしていこうと思います。
最近のコメント