A simple and frequent task, how to set and read some random FPGA pin for test purposes? Sure this can be done over JTAG. Even the free JTAG BUZZ can do this. Well if you manage to get it up and running of course. My own ToolZ can readout in standard version, and theoretically could force pin state too, but well this function is currently not exposed. So there is an option to create a VIO core and connect it to the pin(s) of interest. This is always doable and works, but you are pretty much bound to make a new project every time and need to recompile new bitstream what takes its time.
OK amazingly JTAG BUZZ worked on brief testing, it allows single pin monitoring and continuity testing. There seems to be no function to set a single pin to static value.
But we wanted something for FPGA, the idea is that we can create a ready made bitstreams that implement some sort of generic VIO to GPIO gateway that connects at once to all available FPGA IO pins. Done, the IP Core includes about 10 lines of significant source code total.
Startup provides the FPGA internal free running clock so we do not depend on any external clocks being present. VIO_GPIO provides read-back of all connected IO pin simultaneously, selecting one pin by its index. The selected pin can be made output and its value can be forced to 0 or 1. At the same time this one pin is read back, and also connected to frequency meter IP Core. So if there are external clocks connected to the FPGA then we can measure their frequency (using internal clock a reference).
Does it work? First try out and indeed all works as intended!
Here out1 is value to be written to the indexed pin, out2 is direction control (1 is output), out0 is pin index. The frequency meter also works, if we change the indexed pin output with mouse very quickly, then the frequency meter can show 1 Hz of detected frequency.
This design would work on all Xilinx 7 series FPGA and SoC or newer devices. Pretty much anything that can be programmed with Vivado can be used.
The first design was created for Zynq 7014 CLG484 package, it would without modifications also work for CLG400 package. For 7020 the same design should be one time recompiled.
For the XDC file I used the boundary scan order for the pins, so it is possible to look up the PAD number from Xilinx BSDL file, and convert to the "index" in the design. It is also possible to get the index from the XDC file. If we use package different from that in the original design then only the BSDL flow works to determine the ball-index mapping.