Cut the Cord: Using the ZPUino Without an FTDI Cable

Posted by: Dave Vandenbout 5 years, 5 months ago


Cutting the cord. 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.

Complete communication link.

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.

HostIoComm Wishbone interface.

In order to pass as the standard UART, the WbHostUart operates as follows:

  • The id that the module reports to the ZPUino core is set as follows:

           id <= VENDOR_ID_G & PRODUCT_ID_G

    where VENDOR_ID_G and 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:

  1. Get the ZPUino HDL code using git clone -b RGB_LED_Example --recursive Then go to the ZPUino-HDL\zpu\hdl\zpuino\boards\xula2\xula2 folder and build it with make xula2-lx9 or 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.)
  2. Download the ZPUino IDE for your operating system and install it.
  3. Install the Python version of the XSTOOLs using pip install xstools --allow-all-external --allow-unverified intelhex.
  4. Download the com0com null-modem emulator and use it to create a null modem connection between two COM ports (I usually choose COM7 and COM8).
  5. Plug a XuLA2-LX9 board into a USB port and flash it with the ZPUino bitstream via the command 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.
  6. Start the USB-to-serial server in debugging mode to create a connection between the USB port and one of the COM ports (I used COM8 here): usb2serial -d -c 8 -m 253.
  7. Start the ZPUino IDE and select the ZPUino 2.0 on XuLA2 (LX9) as your board and the other end of the null-modem connection for the port (COM7 in this case).
  8. Create, compile, and download some ZPUino C source code. I used the RGB LED demo code found here. Once the object code is downloaded and starts executing, the ZPUino will run an RGB LED through a sequence of colors.

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):

Current rating: 3


  • William Tambe 5 years, 4 months ago

    Awesome !!!

    Is it possible to implement more than one UART through the same cabling ?

    Link / Reply
    • Dave Vandenbout 5 years, 4 months ago

      Yes. You could instantiate a WbHostUart with a different module id (like 252, for example) to another slot (like 9, for example). Then you would have to make a second null-modem emulator COM port pair (like COM9 and COM10). Then run another usb2serial server like this:

      usb2serial -c 10 -m 252

      Then have your terminal program link up with COM9.

      Link / Reply
      • William Tambe 5 years, 4 months ago

        Amazing !!!

        It opens up a whole host of possibilities where more than one communication channel could be used with the XuLA through the same cabling.

        Link / Reply
  • Cedric Martin 4 years, 9 months ago

    Woud it be possible to drive an LCD panel (via LVDS) using ZPUino ?

    Link / Reply
    • Andy Craner 4 years, 1 month ago


      I'm not sure how far you've gotten with LVDS, but thought I'd share what I have. It doesn't have any ZPuino code in it, but runs a laptop screen that is 1024x600 visible (1200 x 625 total) @ 156MHz / 7 slots for 22.5 Mhz @ 30 FPS. (If my memory serves me)

      The video component needs to be able to read from RAM, and I was using the DualPortSdramCtrl provided by Dave.

      If you don't have LVDS working at all yet, my HDL should get you close, but there are some caveats regarding hardware. As the SDRAM and SD CARD are using the 3.3v LVDS ports, you have to go with 2.5v BLVDS.
      You will need a part from Digikey (CAT16-LV4F12). The part is extremely small. Maybe Dave can make a breakout board? :) I used channels 1 through 8.
      You can get the details on page 36.

      I've just started trying to work with the ZPuino, but I can't figure out how to get the usb2serial (or similar) to work on ubuntu. As for getting LVDS to work with ZPuino, it shouldn't be too hard ;) As long as the FIFO can read from the RAM fast enough. I'm not sure if wishbone can do it or not.

      Good Luck!

      Link / Reply

New Comment

required (not published)

Recent Posts






RSS / Atom