xvcd - The Xilinx Virtual Cable Daemon
I recently discovered an almost undocumented function in Xilinx ISE: the Xilinx virtual cable driver. It’s basically “a platform cable without a platform cable” (as marcan said so nicely) - it allows you use Impact (and Chipscope, and all other tools) over TCP/IP.
Normally, ISE comes with a limited set of cable drivers: It supports cables on the parallel port, such as the Xilinx Parallel Cable III (DLC5), which can be DIY’ed easily, or the faster Xilinx Parallel Cable IV (which has an integrated CPLD), or the - quite expensive, but also sophisticated - USB Platform cables. There are also cheap clones of the platform cables (the first version used an FX2+CPLD), which I won’t link to, and then there’s Digilent Inc., which build actually useful FPGA development board, which have a USB platform cable on board (like the very cool, but slightly outdated Spartan-3A starter kit). Unfortunately, the USB platform cable itself is mysteriously missing in the schematics. Newer boards as the Digilent Atlys or the Avnet Spartan-6 LX9 MicroBoard (an, excuse me, terrible board - but that aside) don’t have the clumsy and expensive FX2+CPLD combination anymore. Instead, they come with a cheaper solution and a corresponding plugin for the Xilinx tools. However, the plugin SDK is not available publicly, so it’s not easily possible to write a plugin for arbitrary JTAG dongles (like a generic FTDI 2232 board) without either licensing the SDK or reversing the API.
For OpenVizsla I wanted to get programming working from Impact. Programming the CPLD and FPGA is supported via an on-board FTDI chip, and usually done with urjtag. However, you can’t use - for example - Chipscope.
There are solutions like this neat hack, which basically LD_PRELOADs into ISE, pretends to be libusb, provides a virtualized platform cable, and then talks to some different back end.
But it turns out - there’s a much easier, albeit undocumented, solution. It’s called xilinx_xvc, or “Xilinx Virtual Cable”. It’s a plugin - the only one next to the Digilent plugin - that can be used as a cable. It opens a TCP connection to a specific host, and sends JTAG “shift” instructions over TCP. The protocol is really, really simple: There’s only one command that I ever saw being used, called
shift:. After that, a 32-bit little endian word specifies the number of bits, and after that, two byte-padded strings are the bits to be shifted out on TMS and TDI (in that order). The response is a byte-padded string of the bits shifted out on TDO. That’s all - a nice, abstracted JTAG PHY.
I implemented a client for this for the awesome NeTV here (requires some hardware hacking though to get the JTAG pins connected), and a generic FTDI version (based on libftdi) here (feel free to merge and send me a pull request!).
The xvcd is a daemon that listens on port 2542, and allows multiple programs to access the JTAG chain at the same point (it switches between them only when it’s “safe”; it relies on the programs to idle the chain every once in a while by going through TLR and then staying in RTI). It also works around a weirdness where Impact, whenever an IR or DR is written, goes back to the Capture-IR/DR state before exiting back to RTI (which almost always screws up the register). xvcd follow the JTAG state machine and just ignores this these instructions.