March 2011 update: There have been several changes since this page was originally written. Digilent now provides command-line utilities for Linux that can access and program their boards. they also provide a plugin for the Xilinx iMPACT programming tool. So this page is out of date, but I'm leaving it up for now because the information may still be useful to some.
I have 3 Xilinx FPGA boards made by Digilent - www.digilentinc.com. Two of these boards are the Nexys and Nexys II. The third is a Xilinx Spartan-3AN eval board, which is also made by Digilent but sold directly by Xilinx. The two Nexys boards have Cypress CY7C68013A USB interfaces that implement the JTAG interface to the board, and also support data transfer between the FPGA and a host PC. Board schematics are available from Digilent and show the connections between the USB chip and the FPGA.
Digilent supplies software for programming the FPGA via the USB port, and they also supply drivers for data transfer. I would like to use the USB port to access and control my designs that I put in the FPGA, but from a Linux host. I now have data transfers between host and FPGA working for both Nexys boards. The Spartan-3AN board uses an undocumented USB interface that's clearly different, so this software won't work there.
I found a couple of other people have started to work on this sort of thing: hackdaworld.org and braiden.org. I used Braiden's work as a starting point.
The USB chip contains an 80C51 microcontroller core that controls setup, and it has hardware FIFO's that support high-speed data transfers directly from the USB bus to an external device (the FPGA in this case). The chip normally loads its initial firmware from an onboard Flash ROM, but it can also accept firmware downloads over USB. I'm not interested in reverse-engineering the Digilent firmware, so I decided to create my own firmware to support data transfers.
Items needed include
Program usb_main.c
is the firmware for the Cypress USB chip.
It just resets the chip to bring up the default configuration, and then
configures the FIFO's. After that, the internal logic of the chip handles
the transfers.
Program usb_rw.c
is a simple demo program. It sets up the
USB interface, then it copies bytes from the terminal to the USB
output endpoint (EP2) and reads bytes from the USB input endpoint (EP6).
The test firmware reads bytes from FIFO 0 (USB Endpoint 2) and writes bytes to FIFO 2 (USB Endpoint 6). It displays information on the row of 8 LED's, and uses the slide switches and pushbuttons for control.
When slide switch SW2 is high and all others low, the LED's display
the last character received on EP2. So, for example, if you type
an "a" followed by carriage return into usb_rw
, you
should see the bit pattern of an ASCII "a" on the LED's. Other
slide switch settings display byte counts for EP2 and EP6. See the
VHDL code for details.
While pushbutton BTN0 is pressed, the FPGA begins sending dummy data to EP6. The data is just a continuously incrementing value. So, when usb_rw is running, you should see it begin spewing out "read 1024 bytes" messages when you press BTN0.
The firmware is written in VHDL and can be compiled using the Xilinx WebPack software (available for free download from www.xilinx.com).
First step is to get the VHDL code into the FPGA. I include a sample
nexys_usb.mcs
file that can be used with the Nexys 2 with
the 500k FPGA. I use the
Digilent Adept software running under windows. For Linux, I have
an old, otherwise unused, copy of Windows 2000 installed in a
VMWARE virtual machine. Adept runs find via VMWARE. (I also tried
VirtualBox, but its USB support doesn't seem to be good enough yet
for this application).
Next, get the new USB firmware into the Cypress chip. If you want the recompile the USB firmware, go to the cy7c directory and type 'make'. You may need to edit the Makefile to specify the correct location for the fx2regs.h file.
Second step is to download the firmware to the chip. When the Nexys
board is first plugged in, you should see and entry in
/proc/bus/usb/devices
that includes:
Load the new firmware with a command like
T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 9 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=1443 ProdID=0005 Rev= 0.00
S: Manufacturer=Digilent
where 004 and 009 are the Bus and Dev numbers from the T: line.
Depending on how the protections are set up, you may need to be root
to do this.
/sbin/fxload -v -t fx2 -I cy7c/usb_main.ihex -D /dev/bus/usb/004/009
If the firmware loads properly, the device should disconnect from
USB and reconnect as a default Cypress device:
T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 10 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=ff(vend.) Sub=ff Prot=ff MxPS=64 #Cfgs= 1
P: Vendor=0547 ProdID=2131 Rev= 0.00
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
The Adept software will not operate correctly while the Cypress chip is running this custom firmware. The new firmware is in the RAM of the Cypress chip, so you can unplug the USB cable and then plug it back in to revert to the original Digilent firmware.
It's probably possible to store the new USB firmware into the Flash ROM, but I think that's a bad idea because it would render the Adept software permanently unusable.
The JTAG connections are fully documented in the board schematics, so it should be possible to program the USB chip to work as a JTAG dongle. I leave that as an exercise for the student.
To test, run the usb_rw
program (again, you may need to
be root to access the USB device). If you type on the keyboard
you should see the LED's change. The software reads full lines,
so you need to hit carriage return before the LED's will change.
Press Button 0 to get the FPGA to send data back to the PC.
The next step is to put some code into the FPGA that actually does something more useful than blinking lights.
stay tuned ...
All source code is available for download as a single tarball. The FPGA code is set up for the Nexys 2 board with the 500k FPGA. According to the documentation, the Nexys 2 is available with other FPGA sizes, and the pin designations change depending on the size. So you will need to check the schematic for your board and update the ucf file accordingly. Similarly, for the original Nexys 1 board, you will need to update the ucf file for it.