XVC Remote debug

hello there,
did anyone have a try at adding the Xilinx XVC (Xiinx Virtual cable) functionality for remote debugging on any Pynq-based board? Help welcome.
I am trying on my custom Zynq-based board and struggling to get the hardware and petalinux working, but once I am done I would like to update my PYNQ porting with it.
I am starting from this:

I managed to get the AXI Debug Bridge working on the Ultra96 with a Jupyter notebook that implements the XVC protocol. The aim there was to perform JTAG debugging without needing the JTAG adapter for the board. It’s not particularly quick but it seems to work.

I’ve put the notebook up as a gist and attached the bitstream/tcl/hwh file as a zip file. It’s built on top of 2018.3. It uses the Debug Bridge IP to connect the JTAG chain to and AXI slave port and has a DMA engine in fabric with the ILA attached to its AXI interfaces to provide something to look at inside of chipscope.

If you want to connect the JTAG pins to something externally you should just be able to change the Debug Bridge configuration and re-use the same server code. All of this code is based on the xcvServer example.

Peter (472.2 KB)


I don’t understand how you send and retrieve stuff to\from the debug bridge, to be honest… what is IP the address to be used? How do you set the Vivado Hardware manager to work with it? From the AN I mentioned above I assumed something Pynq kernel recompiling and SD regeneration could be needed…

In the system I created the Debug Bridge is connected as a regular AXI IP - same as any other PYNQ design so there’s no need to recompile the kernel. The Python code in the notebook will listen on the 1542 and translate the “shift” commands in the XVC protocol into register reads and writes on the Debug IP. In the Vivado Hardware Manager you create a new target on the local hardware server instance and in the prompt there is an option to connect to XVC where you can put in the IP address of the board and the port that the notebook opened (1542 in this case).


So you mean that the only thing I need to do is modifying this line in the notebook:
server_task = asyncio.start_server(xvc_server, ‘’, 1542)
server_task = asyncio.start_server(xvc_server, myBoardIp, mySelctedPort)
run the notebook and start debugging with the Vivado hardware manager?
Wow, that would be easy!

You shouldn’t need to change the port from - that will bind to all network interfaces. In theory - yes changing the port and assigning the correct IP to the debug_bridge variable all that should be be required. If you are on a Zynq Ultrascale+ board you may also need to do the cpuidle fix to prevent the processor from locking when the JTAG chain is accessed. Note that it may not be particularly quick. This was put together as a proof of concept rather than something production ready.


Thanks Peter,
it is working!
I don’t understand how and why, sigh, yet… but it works!
I may need to devolve some time and study into asyncio probably
Thank you very much for your help