In my previous two posts, I've talked about extending the ZPUino with custom peripherals and creating a terminal-like communication link over USB to an application running in an FPGA. Now it's time to combine those two concepts to create a terminal link to the ZPUino over the USB link of a XuLA board.
Why would I do this? For one reason only: to get rid of the FTDI cable I've been using to communicate with the ZPUino. It's just a pain in the ass to have two cables connected to the XuLA: one for downloading bitstreams to the FPGA and the other for loading programs into the ZPUino softcore. Plus, it costs over $25 to get an FTDI cable and that dissuades some who might want to try out the ZPUino just to see what it's like.
The block diagram of the communication link is similar to last time except for the endpoints. One end is now the Arduino-like IDE which compiles C source code and downloads it to the ZPUino. At the other end, naturally, is a ZPUino softcore processor running in the FPGA of a XuLA board.
A valid question at this point is "Why run the USB-to-serial server and null modem? Why not just write a direct interface for the IDE since it's open source?" The answer is that it avoids the effort of creating, maintaining and distributing a new version of the IDE.
For the same reason, nobody wants to change the ZPUino firmware that's used to communicate with the IDE. Therefore, the HostIoComm module has to mimic the UART the ZPUino usually talks to. Since the ZPUino talks to the UART (and other peripherals) through a Wishbone interface, the same interface has to be attached to the HostIoComm module (see the VHDL for the WbHostUart module). The resulting WbHostUart module has to be inserted into slot 1 in the top-level module of the ZPUino VHDL.
In order to pass as the standard UART, the WbHostUart operates as follows:
id that the module reports to the ZPUino core is set as follows:
id <= VENDOR_ID_G & PRODUCT_ID_G
PRODUCT_ID_G are set by default to the same values as the
normal ZPUino UART.
This ensures the ZPUino will accept this UART when it scans the identifiers
of all the peripherals located in the slots.
Data transmission and reception is done through the data register located at address 0. Any time the ZPUino reads this register, it gets the next byte from the download FIFO that receives data from the IDE running on the host PC. Any write to this register queues a byte of data into the upload FIFO for transmission back to the IDE.
Flow control is managed by querying the status register at address 1. If bit 0 is set, then the download FIFO is holding one or more bytes of data from the host PC that can be read by the ZPUino. If bit 1 is set, then the upload FIFO is full and the ZPUino shouldn't try to push any more data into it.
OK, this is all great, but how do you actually use this? Here's a complete list of steps to follow:
git clone -b RGB_LED_Example --recursive https://github.com/xesscorp/ZPUino-HDL.git. Then go to the
ZPUino-HDL\zpu\hdl\zpuino\boards\xula2\xula2folder and build it with
make xula2-lx25. Or you can just download the bitstreams I already compiled for the XuLA2-LX9 and XuLA2-LX25. (These bitstreams also include the RGB LED driver peripheral I talked about here.)
pip install xstools --allow-all-external --allow-unverified intelhex.
xsload -flash xula2-lx9_routed.bit. (I'm using a XuLA2-LX9 here. If you're using a XuLA2-LX25, then just change the commands accordingly.) Then unplug and re-plug the USB connection; toggling the power will make the FPGA load itself with the ZPUino bitstream from the flash.
usb2serial -d -c 8 -m 253.
ZPUino 2.0 on XuLA2 (LX9)as your board and the other end of the null-modem connection for the port (
COM7in this case).
That may sound pretty complicated, but most of these steps only have to be done once. After the first run, developing ZPUino software is just a matter of plugging in the XuLA (the ZPUino bitstream is stored in flash), initiating the usb2serial server (the null-modem emulator is persistent and runs whenever the PC is booted), and starting the ZPUino IDE (all the settings are retained from the last time it was run).
Here's a video of me doing most of it (except for all the software installs):
Share on Twitter
Share on Facebook
Share on Reddit