Electronics

Revisiting Xilinx JTAG Programming from a Raspberry Pi

Nearly a year ago I wrote about a way to program Xilinx XC9500XL series chips from a Raspberry Pi. Since then a new version of Raspberry Pi OS has been released which completely breaks this and there are new tricks I’ve created which may be useful to some. So, this blog post is a revisit of the subject with a new tutorial.

Update 2022-10-02: I have designed a Pi JTAG board to make the wiring even easier with protection voltage translators for the Pi. It is available here.

Update 2022-05-20: Thanks to Eriond for pointing out that a username and password is no longer automatic. I have added a section for this.

I’ve adjusted this tutorial so that it will work with any Pi version currently available, but I have used a Raspberry Pi 3A+ for the examples. I’m going to be doing this completely headless, but feel free to use a monitor and keyboard to make things easier. This tutorial is written with Linux in mind, it should work in macOS too and likely Windows PowerShell.

Pi Software

First thing you are going to need (beyond a Raspberry Pi) is the Pi OS. You can use the installer from the Raspberry Pi Website. I recommend selecting the “Lite” version for this but any version will work.

Once you have installed this on an SD card, mount the “boot” partition on your computer and create an empty file on it called “ssh”, in Linux and macOS you can do this by typing touch ssh in the command line. This will turn on SSH access.

Now create a file called wpa_supplicant.conf with the following contents (alter for your WiFi settings, the ssid and psk details are case sensitive):

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
network={
    ssid="YOUR_SSID"
    psk="YOUR_WIFI_PASSWORD"
    key_mgmt=WPA-PSK
}

Finally you need to have a user created as this no longer happens on boot, if you create a file called userconf.txt with the following contents you will have a username ‘pi’ and password ‘raspberry’:

pi:$6$4VKVEKkbxmVaadgx$1yOzCvT58onJsH5UdWhnpksIaHtFTVCnJ8lydLCEAfzJ43S3RXrYQYZXfZcXWZJHP9Ea0J9lWbHmwGScac3Ni/

You can safely eject the SD card, put it into the Pi and turn it on. The first boot will take a few minutes as it resizes the filesystem to use the whole SD card and a few other first-boot things.

The following command will let you SSH into your Raspberry Pi:

ssh pi@raspberrypi.local

Now that you are on the Pi, this set of instructions will install the latest xc3sprog tool to flash Xilinx chips. I’ve spent a long time trying to get OpenOCD to work with Raspberry Pi and Xilinx CPLDs but it never quite works right, whereas xc3sprog makes it easy:

sudo apt update
sudo apt -y dist-upgrade
sudo apt install build-essential libusb-dev libftdi-dev libgpiod-dev git cmake
git clone https://github.com/matrix-io/xc3sprog
mkdir xc3sprog/build
cd xc3sprog/build
cmake .. -DUSE_WIRINGPI=OFF
make
sudo make install

Note that we are turning “wiringpi” off, this is no longer supported in the latest Raspberry Pi OS, which means we have to use another access method called “sysfsgpio”. This works with any Pi version but is about 50% slower and requires “sudo” to work. It is still fast enough for daily usage and removes the need for you to have to compile “wiringpi” yourself.

JTAG Wiring

This is the default wiring pinout for xc3sprog:

PinJTAG
7TMS
9 (or any Ground pin)GND
11TCK
13TDO
15TDI
17 (or pin 1)3V3

Note that if you wish to wire this differently, for example if the Pi is already wired to your CPLD in board such as the RGBtoHDMI, you can edit sysfscreator.cpp and recompile. Here you will see the code:

IOSysFsGPIO(4, 17, 22, 27)

These are the GPIO numbers, not pin numbers so are in the order of TMS, TCK, TDI, TDO. The mapping can be seen in the image below:

This is what it looks like wired to an Amiga Flash Kickstart board:

Using xc3sprog

The first useful command is:

sudo xc3sprog -c sysfsgpio_creator -j

This probes the JTAG chain and lists everything on it. For example, some Terrible Fire cards will identify two Xilinx chips on it. This is useful because in subsequent commands you can specify which chip you are talking to with the -p parameter. Since there is only one chip in my chain, we will just be talking to that one:

sudo xc3sprog -c sysfsgpio_creator -v -p 0 myxilinx.jed:r
sudo xc3sprog -c sysfsgpio_creator -v -p 0 FLASH_KICKSTART.jed

The first command here reads the Xilinx chip and saves it to disk, the second one writes new firmware to the Xilinx chip.

Remote Programming

It is possible to use the Pi to remotely program from your computer. First of all it may be useful to copy your SSH public key over to the Pi. There are dozens of tutorials on this so I’ll skip this for now, it just saves you having to enter a password every time. Then the command from your laptop is:

ssh pi@raspberrypi.local 'cat > /tmp/FK.jed && sudo xc3sprog -c sysfsgpio_creator -v -p0 /tmp/FK.jed && rm -f /tmp/FK.jed' < FLASH_KICKSTART.jed

This basically reads the local FLASH_KICKSTART.jed file, copies it to /tmp on the Pi, runs xc3sprog on the Pi and then deletes the file. Unfortunately xc3sprog can’t read from STDIN, tricking it to do so will cause the verification step to fail.

Makefile

Finally I’ve created a small Makefile which can compile the the Xilinx Verilog and also use the remote programming step above as the “make install” step. You’ll need Xilinx ISE WebPACK installed and the /opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64 in your path (assuming that is where you install it).

The Makefile is as follows, adjust for your chip and verilog file accordingly:

PROJECT=FLASH_KICKSTART
DEVICE=xc9572xl
PART=XC9572XL-10-VQ44

all: $(PROJECT).jed

%.xst:
 @printf "run\n-ifn $(PROJECT).v\n-ifmt verilog\n-ofn $(PROJECT).ngc\n-p $(DEVICE)" > $@
 @xst -ifn $@

$(PROJECT).jed: $(PROJECT).xst
 @ngdbuild -uc $(PROJECT).ucf $(PROJECT).ngc -p $(DEVICE)
 @cpldfit  -p $(PART) -ofmt vhdl -optimize speed $(PROJECT)
 @hprep6 -s IEEE1149 -n $(PROJECT) -i $(PROJECT)
 @hprep6 -s IEEE1532 -n $(PROJECT) -i $(PROJECT)

clean:
 @rm -rf xst
 @rm -f $(PROJECT).bld
 @rm -f $(PROJECT)_build.xml
 @rm -f $(PROJECT).gyd
 @rm -f $(PROJECT).isc
 @rm -f $(PROJECT).jed
 @rm -f $(PROJECT).mfd
 @rm -f $(PROJECT).ngc
 @rm -f $(PROJECT).ngc_xst.xrpt
 @rm -f $(PROJECT).ngd
 @rm -f $(PROJECT)_ngdbuild.xrpt
 @rm -f $(PROJECT).pad
 @rm -f $(PROJECT)_pad.csv
 @rm -f $(PROJECT).pnx
 @rm -f $(PROJECT).rpt
 @rm -f $(PROJECT).srp
 @rm -f $(PROJECT).xml
 @rm -f $(PROJECT).xst

install:
 @ssh pi@raspberrypi.local 'cat > /tmp/firmware.jed && sudo xc3sprog -c sysfsgpio_creator -v -p0 /tmp/firmware.jed && rm -f /tmp/firmware.jed' < $(PROJECT).jed

You can now run make to build the Verilog and make install to install via SSH:

LinuxJedi

View Comments

  • Thanks for the great writeup! Have you run into any chips that you can't erase? I'm working on repairing a board from a device that I damaged (fried) and have managed to solder on replacements for the two xc9572xl chips. I'm able to probe them successfully with -j but can not erase them. Some googling around has turned up suggestions that my replacement chips have write protect enabled and that it may only be possible to clear the protection using Xilinx ISE and a "real" JTAG programmer. BTW - where did you get your chips? If I can buy ones that I know are unprotected I might just do that.

    • Unfortunately I do not know of a way of clearing the write protect bit without using the ISE. My Digilent HS2 can probably do it, but I've not come across a write protected one before.

      My Xilinx chips came from Mouser, DigiKey RS or Farnell. Back when they had stock. I still have a small stock of them for my projects, but that is dwindling fast. I'm looking at switching to ATF15xx for many things in the future, since the AMD acquisition Xilinx chips have doubled in price.

  • With latest Pi Imager you can select all configs. Activate SSH, set Pi Account, set Password for Account. Set WLAN AP Point and enter PW for WLAN.

    • That is true. I don't like using the Pi Imager though for several reasons. Including their website assumption that all desktop Linux is Ubuntu. Internally it likely does the steps in this post. Really it is whatever works best for you :)

  • Hi, i build 3 RGBtoHDMI Rev 2.0 PCB's.

    None of them is working.
    I found this page and followed your instructions step by step. I tried to edit sysfscreator.cpp and it already contained "IOSysFsGPIO(4, 17, 22, 27)".
    So i hooked up the RGBtoHDMI to the PI Zero W and did "sudo xc3sprog -c sysfsgpio_creator -j"
    All 3 PCB's showed the same result.

    XC3SPROG (c) 2004-2011 xc3sprog project $Rev: 774 $ OS: Linux
    Free software: If you contribute nothing, expect nothing!
    Feedback on success/failure/enhancement requests:
    http://sourceforge.net/mail/?group_id=170565
    Check Sourceforge for updates:
    http://sourceforge.net/projects/xc3sprog/develop

    No JTAG Chain found

    My Amiga 500 Rev. 5 is starting up with a black screen. I found this page and hoped
    external programming the chips might solve the problem.
    What am i doing wrong?

  • Hi,
    thanks for your fast reply.
    I recompiled with `(24, 20, 0, 1)`
    Same result. I don't know if i recompiled correct.
    I always get 'No JTAG Chain found'.
    I had the all components to solder one more RGBtoHDMI REV 2.0 PCB.
    Formated a new SdCard with all apropiate changes out in my Amiga 500 and
    after 5 seconds a picture came up as it should be.
    I was able to program the Xilinx Chip and it worked like a charm.
    Wow, what a crisp clear picture!
    Anyway, thanks for trying out helping me.

    • Glad it all worked in the end. Even if the xc3sprog didn't work out for you.

  • Got myself a Raspberry Pi 1 and installed Raspberry OS Lite. Did all like in the guide. Connected the leads (except 3v3) to TF1230 and powered the TF1230 card from Amiga.

    sudo xc3sprog -c sysfsgpio_creator -jXC3SPROG (c) 2004-2011 xc3sprog project $Rev: 774 $ OS: LinuxFree software: If you contribute nothing, expect nothing!Feedback on success/failure/enhancement requests:http://sourceforge.net/mail/?group_id=170565Check Sourceforge for updates:http://sourceforge.net/projects/xc3sprog/develop

    ERROR: Couldn’t export gpio 22ERROR: Couldn’t export gpio 4ERROR: Couldn’t export gpio 17ERROR: Couldn’t export gpio 27011101110111011101110010101110101010100001

    Dont understand a thing 🙂

    • Is it a Raspberry Pi 1B or 1B+? I ask because I don't think this will work with the original 1B.
      Also, what version of Pi OS were you using?

  • It's early 2011.12 1B with fewer GPIO pins. I did understand it still has enough for this operation. RPi Low-level peripherals - eLinux.org. I used newest so Bookworm Lite, next I was going to try Bullseye Lite. Almost bought a new RPi but then friend gave me this for a lunch and hoped it'll do the job :)

    • We are in uncharted territory for me here. I did happen to receive a Pi 1B last weekend as a gift. But I won't get a chance to try it out for a couple of weeks.

      Technically I think it has all the GPIO required, but the pinout for GPIO is very different, I think all the required GPIO lines are there on a rev 1 1B, a rev 2 has a different pinout again and I think some of it would need remapping.

      If you are using Bookworm, you might be better off using the older Wiring Pi instructions instead, I doubt the sysfs is going to be compatible.

      Or, of course, try a more modern Pi :)

  • Yeah, thanks for help! I actually just bought RPi 3B+ because this 1B is quite slow anyway :D And maybe I can use 3B+ for something else too. But until that comes I can play with this a little and try to make it work. I'm learning all the time...

  • Epic win!

    Bullseye did the trick and actually those pins on 1B are actually the same so this guide worked straight.

    sudo xc3sprog -c sysfsgpio_creator -v -p 0 tf1230r1_main_top_288.jedXC3SPROG (c) 2004-2011 xc3sprog project $Rev: 774 $ OS: LinuxFree software: If you contribute nothing, expect nothing!Feedback on success/failure/enhancement requests:http://sourceforge.net/mail/?group_id=170565Check Sourceforge for updates:http://sourceforge.net/projects/xc3sprog/develop

    Using devlist.txtUsing cablelist.txtJTAG chainpos: 0 Device IDCODE = 0x59616093 Desc: XC95288XLDevice is blankProgramming Sector 107.Programming time 21202.2 msVerify Sector 107Success! Verify time 7150.6 ms

  • Hi,

    Hoping to get some help with the CMAKE step please. I am getting a warning that libftd2xx cannot be found, but I have downloaded and installed it using the instructions over at FTDI.

    The first warning is:

    CMake Warning (dev) at /usr/share/cmake-3.25/Modules/FindPackageHandleStandardArgs.cmake:438 (message):

      The package name passed to `find_package_handle_standard_args` (PkgConfig)

      does not match the name of the calling package (libftdi). 

    and then later:

    -- Checking for module 'libftd2xx'

    --   Package 'libftd2xx', required by 'virtual:world', not found

    and:

    -- Could NOT find LIBFTD2XX (missing: LIBFTD2XX_INCLUDE_DIR) 

    I can proceed to the MAKE step, that completes without warnings, but sudo make install shows a number of warnings about things being deprecated. Is that normal?

    Anyway, if I then run

    sudo xc3sprog -c sysfsgpio_creator -j

    I get the following errors, on a Pi 3A and a PiZero2W:

    XC3SPROG (c) 2004-2011 xc3sprog project $Rev: 774 $ OS: Linux

    Free software: If you contribute nothing, expect nothing!

    Feedback on success/failure/enhancement requests:

    http://sourceforge.net/mail/?group_id=170565 

    Check Sourceforge for updates:

    http://sourceforge.net/projects/xc3sprog/develop

    ERROR: Couldn't export gpio 22

    ERROR: Couldn't export gpio 4

    ERROR: Couldn't export gpio 17

    ERROR: Couldn't export gpio 27

    011101110111011101110010101110101010100001

    Any help appreciated.

    • Hi,
      Are you using Bullseye or Bookworm version of Pi OS? I believe Bookworm might have removed SysFS, but I think the old WiringPi now might be back again.

      • I think it is using bookworm. IS it better to just make a new bullseye build?

        Thanks!

        • I think so, I haven't tested Bookworm yet, but it seems I need to do another update blog

Share
Published by
LinuxJedi

Recent Posts

Diagnosing an Amiga 1200 Data Path Fault

I recently acquired an Amiga 1200 motherboard in a spares/repairs condition for about £100 recently.…

2 days ago

Bare Metal “Hello World” on an STM32MP135F-DK

Whilst I do like working with STM32 development boards, some basic information I need can…

3 days ago

Two special Amiga 4000s: Diagnosing Jops

When I last left this blog series, the first of Stoo Cambridge's A4000s had gone…

6 days ago

Joining wolfSSL

At the beginning of November, I started working for wolfSSL. Now that I'm a week…

1 week ago

Two special Amiga 4000s: Rebuilding Jools

In my previous post, I had the Amiga 4000 known as Jools mostly repaired, there…

4 weeks ago

Two special Amiga 4000s: Repairing Jools

In my last post, I created a list of things I needed to repair on…

4 weeks ago