VHDL Paper

Download as pdf or txt
Download as pdf or txt
You are on page 1of 32

FPGALink User Manual

(VHDL Edition)
c 2012 Chris McClelland/MakeStu.eu

HOST COMPUTER (Linux, Windows or MacOSX)


FPGALink DLL
flWriteChannel(
uint8 channel,
uint32 count,
const uint8 *buffer)
Host
Application
Logic

flReadChannel(
uint8 channel,
uint32 count,
uint8 *buffer)

USB

flPlayXSVF(
const char *svfFile)

FPGA (Xilinx or Altera)


CommFPGA Module
h2fData_out[7:0]
h2fValid_out
FPGA
Application
Logic

h2fReady_in

FPGA < Host


Pipe

chanAddr_out[6:0]
f2hData_in[7:0]
f2hValid_in
f2hReady_out

Cypress FX2LP
or Atmel AVR
CommFPGA

FPGA > Host


Pipe

NeroJTAG

JTAG (TCK, TMS, TDI, TDO)

This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License

Contents
1 Introduction

1.1

Justication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.2

Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.3

Document Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.4

How to Get Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.5

Licences & Disclaimers . . . . . . . . . . . . . . . . . . . . . . . . . . .

2 Getting Started

2.1

Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.2

Supported Boards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.2.1

Cypress FX2LP-Based Boards . . . . . . . . . . . . . . . . . . .

2.2.2

Atmel AVR-Based Boards . . . . . . . . . . . . . . . . . . . . .

2.3

The flcli Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.4

Programming the FPGA . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.5

Interacting with the FPGA (Part 1) . . . . . . . . . . . . . . . . . . . . 14

2.6

Interacting with the FPGA (Part 2) . . . . . . . . . . . . . . . . . . . . 16

2.7

Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

3 Host Application Development


3.1

19

Language Bindings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.1.1
3.1.2

Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3.1.3
3.2

C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

Excel/VBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

API Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.2.1

Firmware Operations [FX2LP-Specic] . . . . . . . . . . . . . . 21

3.2.2

Connection Lifecycle Operations . . . . . . . . . . . . . . . . . . 21


2

3.2.3

Device Capabilities and Status Operations . . . . . . . . . . . . 22

3.2.4

NeroJTAG Operations . . . . . . . . . . . . . . . . . . . . . . . 22

3.2.5

CommFPGA Operations . . . . . . . . . . . . . . . . . . . . . . 22

3.2.6

Miscellaneous Operations . . . . . . . . . . . . . . . . . . . . . . 23

4 FPGA Application Development

24

4.1

Internal Port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

4.2

FX2 External Port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

4.3

EPP External Port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

4.4

Build Infrastructure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.4.1

MacOSX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.4.2

Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.4.3

Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

4.4.4

Specifying the JTAG Chain . . . . . . . . . . . . . . . . . . . . 28

4.4.5

Location Constraints . . . . . . . . . . . . . . . . . . . . . . . . 28

4.4.6

The xsvf2csvf Utility . . . . . . . . . . . . . . . . . . . . . . . 28

A Custom Boards

30

A.1 Minimus/EP2C5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
A.2 Minimus/Nexys2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

1
1.1

Introduction

Justication

Development kits for Field Programmable Gate Arrays (FPGAs) are ubiquitous, with
oerings from a plethora of manufacturers, with prices ranging from the tens of dollars
to well into the thousands, and featured FPGAs ranging from a few thousand logic
cells to a few million. Whereas the high-end boards tend to be PCIx plug-in cards, the
cheaper boards tend either to be designed around a USB interface chip (e.g Cypress
FX2LP, Atmel AVR, Microchip PIC or FTDI chip), or lack direct host interfacing
altogether, requiring a standalone JTAG cable for programming.
Unfortunately, even for those boards designed around a USB interface, there is a
general lack of good integrated solutions for exchanging arbitrary data between the
host computer and the FPGA, once it has been programmed.

1.2

Overview

FPGALink is an end-to-end, open-source, cross-platform solution designed to do a


couple of simple jobs, and do them well:
Program an FPGA with JTAG, either from an onboard conguration source or
over USB.
Allow the host and/or microcontroller to exchange arbitrary binary data with
the FPGA.
It provides a host-side API, rmware for several USB interface microcontrollers, and
128 addressable eight-bit read/write FIFOs on the FPGA side.
On the host side there is a dynamic-link library with a straightforward API.
Library and example application binaries are provided for MacOSX (x86 64 &
i386), Windows (i686) and Linux (x86 64, i686, ARM & PowerPC). Bindings
are provided for C/C++, Python and Excel/VBA, but binding other languages
is straightforward.
For the USB interface there are rmwares for the Cypress FX2LP (used on most
Digilent, KNJN, ZTEX and Opal Kelly boards) and Atmel AVR (used by some
AVNet and Digilent boards). Support for the FTDI chips is planned.
The Cypress FX2LP rmware supports a synchronous FIFO interface with a
sustained bandwidth of around 26MiB/s. The Atmel AVR rmware supports
4

an asynchronous interface1 with a sustained bandwidth of around 1.2MiB/s.


Other microcontroller-to-FPGA protocols such as SPI would be straightforward
to implement.
For the FPGA there is a simple interface module which when instantiated in
your design gives the host a FIFO-style read/write interface, supporting up to
128 separate logical channels into your design. A couple of fully-functional
example designs are provided to get you started.
Everything is licensed under the GNU Lesser General Public Licence2 ; you are therefore free to distribute unmodied copies of FPGALink with your products. The
library has no commercial or hardware platform usage restrictions, so you can prototype your design with an inexpensive devkit, and then use the same software tools on
your custom-built PCBs. In this way you can easily distribute updated FPGA designs
to your customers just as you would with regular rmware updates, with no special
programming cables required, making your FPGA truly eld-programmable.

1.3

Document Conventions

Whilst describing interactive console sessions, I will use monospace bold for characters entered by a human and monospace regular for the computers responses.
Remember:
1MB = 1 megabyte = 106 bytes.
1MiB = 1 mebibyte = 220 bytes.
1Mb = 1 megabit = 106 bits.
1Mib = 1 mebibit = 220 bits.

1.4

How to Get Help

The only place youre guaranteed to get a response to FPGALink-related queries is the
FPGALink Users Group at http://groups.google.com/group/fpgalink-users.

1
2

Actually IEEE 1284 in Enhanced Parallel Port mode.


http://www.gnu.org/copyleft/lesser.html

1.5

Licences & Disclaimers

The FPGALink library, rmware & VHDL code is licensed under the LGPLv33 :
Copyright c 2009-2012 Chris McClelland
FPGALink is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
FPGALink is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU Lesser General Public License for more details.
The FLCLI utility is licensed under the GPLv34 :
Copyright c 2009-2012 Chris McClelland
FLCLI is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
FLCLI is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.

3
4

http://www.gnu.org/copyleft/lesser.html
http://www.gnu.org/copyleft/gpl.html

2
2.1

Getting Started

Installation

First, download the FPGALink binary distribution. This manual assumes youre
using libfpgalink-20121106.tar.gz.
Linux:
Just download the binary distribution and unpack it into your home directory.
Things will work out-of-the-box on most modern distributions.
Separate sets of binaries for x86 64, i686, ARM and PowerPC architectures are
provided in the linux.* directories.
To grant regular users permission to access the USB devices youll be using,
you will need to add udev rules. First check which groups youre in by running
groups, choose a group (I chose users) and then for each USB device, add
a line to /etc/udev/rules.d/10-local.rules:
wotan$ sudo tee -a /etc/udev/rules.d/10-local.rules > /dev/null <<EOF
> ACTION=="add", SUBSYSTEM=="usb", \
> ATTR{idVendor}=="1443", ATTR{idProduct}=="0005", \
> GROUP="users", MODE="0660"
> EOF
wotan$

You may need to restart the udev service with sudo service udev restart,
but you will denitely need to unplug and reconnect the device(s) before the
new permissions will be in eect.
Windows:
You will need to install the VC++ 2010 redistributable package and a USB
driver for your board:
Be sure to uninstall any existing driver for your board before you start.
Download LibUSB-Win32 and run bin/inf-wizard.exe.
Click Next, select your FPGA board, make a note of the vendor and
product IDs and click Next twice.
Choose a location for the driver and click Save.
Click Install Now.
Also, although its not strictly required, all the command-line examples in this
manual assume youre using the MakeStu Build Infrastructure. Its also the
7

only supported build platform on Windows, so whilst youre free to use something
else, youre on your own if you do.
One set of binaries for the i386 architecture is supplied in the win32 directory.
MacOSX:
You just need to install LibUSB5 and youre good to go.
One set of universal binaries for x86 64 and i386 architectures is provided in the
darwin directory.

2.2

Supported Boards

By providing multiple board support packages (BSPs), FPGALink is able to support


several dierent FPGA development kits, based on Xilinx or Altera FPGAs and Atmel
AVR or Cypress FX2LP USB microcontrollers6 .
A pair of fully-functional examples is provided, with ready-to-go programming les
for each of the supported FPGA boards. The rst example is ex cksum, which we
will play with in the next section, and the second is ex fifo. Both use various bits
of board I/O to provide some interaction and visual feedback:
Eight slider-switches, providing eight bits of input data.
Eight LEDs, providing visual feedback of an eight-bit binary value.
Four seven-segment displays, wired with common cathodes and an anode for
each digit, providing visual feedback of a sixteen-bit hexadecimal value (and an
additional four-bit binary value via the four decimal point LEDs).
Obviously, not all of the supported FPGA boards include all of these I/O features,
and may have other special requirements before the supplied examples will work.
2.2.1

Cypress FX2LP-Based Boards

The Cypress FX2LP is a Hi-Speed (480Mb/s) USB interface. It is capable of transferring data between an FPGA and the host at 26MiB/s, using an eight-bit synchronous
FIFO interface. Although fast and fairly cheap, it has a rather eccentric internal
architecture, so custom rmware development is not recommended.
5

See http://www.makestuff.eu/wordpress/?p=1760
Porting to other boards based on these components is usually fairly trivial; if you have such a
board, ask on the mailing list.
6

Digilent Nexys3:
There are no special considerations for the Nexys3.
Digilent Nexys2 (500K & 1200K versions):
Separate BSPs are provided for the 500K and 1200K gate versions. Also, when
the Nexys2 power select jumper is set to USB, the FPGA is supplied with
power via a little FET on the board which is under software control. Therefore
before programming the FPGA its necessary to turn this FET on.
Digilent Atlys:
The Atlys has the requisite LEDs and switches, but does not have a display
of any kind, so on Atlys the provided examples map the seven-segment display
signals to the rst twelve pins on the boards VHDCI connector. Unless you
know exactly what youre doing, please ensure you have nothing connected to
the VHDCI port before you begin.
KNJN Xylo-L:
Since the Xylo-L has no onboard peripherals, the provided examples map the
switches, LEDs and seven-segment displays to the boards expansion connector
marked H4. Unless you know exactly what youre doing, please ensure you have
nothing connected to the H4 port before you begin.
Digilent S3BOARD:
There is only partial support for the S3BOARD, because it does not include
a USB interface of any kind; instead, it is supplied with a parallel-port JTAG
cable. To use the S3BOARD with FPGALink, you will need an external FX2LP
board with the appropriate connections7 .
Hypothetical LX9 Board:
I have provided the LX9 BSP for a custom board based on the Spartan-6 LX9
FPGA. Since I dont even have a schematic for it, its purely hypothetical, but
may be of use to someone.

FX2FPGA serves as a reference design, but suitable commercial boards are also available.

2.2.2

Atmel AVR-Based Boards

The USB-capable Atmel AVR8 microcontrollers (AT90USB* & ATmega*U*) are very
cheap, and they incorporate a Full-Speed (12Mb/s) USB interface. They are capable
of transferring data between an FPGA and the host at between 330KiB/s and about
1.2MiB/s, using an eight-bit asynchronous EPP-style interface. Although slower than
the FX2LP, they are much more popular as general-purpose microcontrollers, and
much easier to program, making custom rmware development fairly straightforward.
Minimus/EP2C5 Board:
You can buy8 a Minimus AT90USB162 board for 4, and an EP2C5 Mini Board
for 17. With suitable interconnects, the pair make up by far the cheapest
FPGALink-capable hardware solution.
Minimus/Nexys2 Board:
There is also a BSP for a Minimus board attached to a Nexys2-1200. It is
unlikely to be of interest because the Nexys2-1200 already has a superior FX2LPbased USB interface.
Both of these boards require custom wiring, which is described in Appendix A.

2.3

The flcli Utility

Since FPGALink is a library, you would normally just embed it into your application,
but in order to get you started, the FPGALink binary distribution includes flcli9 ,
a small command-line utility which provides access to some of the librarys features.
wotan$ linux.x86_64/rel/flcli --help
FPGALink Command-Line Interface Copyright (C) 2012 Chris McClelland
Usage: flcli [-psch] [-i <VID:PID>] -v <VID:PID> [-j <portSpec>] [-x <fileName>]
[-a <actionString>]
Interact with an FPGALink device.
-i,
-v,
-j,
-x,
-p,
-s,

--ivp=<VID:PID>
--vp=<VID:PID>
--jtag=<portSpec>
--xsvf=<fileName>
--power
--scan

vendor ID and product ID (e.g 04B4:8613)


vendor ID and product ID (e.g 04B4:8613)
JTAG port config (e.g D0234)
SVF, XSVF or CSVF file to load
FPGA is powered from USB (Nexys2 only!)
scan the JTAG chain

e.g from ModTraders and eBay, respectively


Unlike the rest of FPGALink, the flcli utility is licensed under the terms of the GNU General
Public License. See http://www.gnu.org/copyleft/gpl.html
9

10

-a, --action=<actionString>
-c, --cli
-h, --help

a series of CommFPGA actions


start up an interactive CommFPGA session
print this help and exit

--ivp=<VID:PID> [FX2LP-specific]
The FX2LP microcontroller has no onchip nonvolatile storage, so it loads its
rmware from an external EEPROM and/or has its rmware loaded over USB.
The flcli utility rst tries to connect to the device specied by --vp; if it fails,
it tries to load rmware into the device specied by --ivp.
--jtag=<portSpec> [FX2LP-specific]
By default the FX2LP rmwares JTAG interface is compatible with the wiring
on Digilent boards (TDO, TDI, TMS & TCK connected to port D bits 0, 2, 3 & 4
respectively.) If your board has dierent connections, you will need to specify
which port lines to use along with --ivp. The port specication is the port
(C or D) followed by four digits for the port bits to use for TDO, TDI, TMS
& TCK. For example, the Xylo-L board uses a JTAG port of D1240.
--vp=<VID:PID>
The FPGALink device to connect.
--power [Nexys2-specific]
If your Nexys2s power jumper is set to USB, its necessary to switch on the
FPGAs power manually using this option.
--scan
Print an IDCODE for each device in the JTAG chain.
--xsvf
Play the specied .svf, .xsvf or .csvf le into the JTAG chain. This is
typically (but not necessarily) used for FPGA programming.
--action=<actionString>
Execute the semicolon-separated list of CommFPGA commands, for reading
and writing FPGA channels.
--cli
Start a command-line interface for executing CommFPGA commands.

11

The --cli and --action=<actionString> options support three commands, r


(read), w (write) and q (quit). The syntax of the read command is as follows:
r<channel> [<count> [<fileName>]]
channel:
The FPGA channel, 0-7f.
count:
How many bytes to read from the FPGA channel, default 1.
fileName:
A binary le (in quotes) to write the FPGAs data to.
If you dont specify a fileName, the FPGAs data is printed to stdout as a hex dump.
The syntax of the write command is as follows:
w<channel> <byteSeq | fileName>
channel:
The FPGA channel, 0-7f.
byteSeq:
A sequence of bytes to be written to the FPGA channel,
e.g 0123456789abcdef.
fileName:
An existing binary le (in quotes) to dump into the FPGA.
All numbers are in hexadecimal. Since a byte is two hex digits, the byteSeq must have
an even number of digits. Filenames must be quoted using double-quotes ("). You
may put several read and/or write commands on one line, separated by semicolons
(;).

12

2.4

Programming the FPGA

Using the flcli utility, we can now program the FPGA for the rst time. Programming is done by playing a scripted set of JTAG operations into the FPGAs JTAG
port.
TDO

Host
Computer

USB

USB
Interface

TDI
TMS

FPGA

TCK

You can program the FPGA like this:


wotan$ ./<PLATFORM>/rel/flcli -v <VID:PID> -i <VID:PID> \
-s -x gen_csvf/ex_cksum_<BOARD>_<PROTOCOL>_vhdl.csvf
Attempting to open connection to FPGALink device 04B4:8613...
Loading firmware into 04B4:8613...
Awaiting renumeration......
Attempting to open connection to FPGLink device 04B4:8613 again...
The FPGALink device at 04B4:8613 scanned its JTAG chain, yielding:
0x01414093
0x05045093
Playing "gen_csvf/ex_cksum_s3board_fx2_vhdl.csvf" into the JTAG chain on FPGALink device 04B4:8613...
wotan$

You will need to replace <PLATFORM>, <VID:PID>, <BOARD> and <PROTOCOL> in the
above command-line with values appropriate for your specic host platform and
FPGA board:
<PLATFORM>
Your host platform. This will be one of win32, darwin, linux.x86 64,
linux.i686, linux.armel or linux.ppc.
<VID:PID>
The correct vendor and product IDs for your board. This will be:
1443:0005 for Nexys2
1443:0007 for Nexys3 & Atlys
04B4:8613 for Xylo-L
<BOARD>
The name of your board, which will be one of nexys2-500, nexys2-1200,
13

nexys3, atlys, xylo-l, s3board, ep2c5 or lx9.


<PROTOCOL>
The protocol to use to talk to the FPGA, which will be one of fx2 or epp.
There are some caveats:
Nexys2 Users:
If your boards power select jumper is set to USB, it will be necessary
to switch on the FPGAs power by supplying an additional -p command-line
option.
Xylo-L Users:
The FX2LP port lines used for JTAG dier from the default, so you will need
to pass an additional -j D1240 command-line option.
AVR-Based Boards:
The -i <VID:PID> option is only needed for FX2LP-based boards. It is not
needed for AVR-based boards.
If successful, you should see the Done light on your board switch on, and 0000
appear on your boards seven-segment display. If your board does not have either of
these, dont worry; as long as the flcli command completed without error, you can
proceed to the next section.
So what just happened? Well, flcli loads new rmware if necessary (FX2LP-based
boards only), then powers up the FPGA (Nexys2 only), then scans the boards JTAG
chain for attached devices, and nally loads a pre-built design le for the ex cksum
example into the FPGA.
In this case we used a .csvf le10 to program the FPGA, but FPGALink directly
supports the .svf les generated by the Xilinx and Altera tools, as well as the Xilinxspecic .xsvf format.

10
The CSVF format is similar to Xilinxs XSVF, but its better suited for playback by small
microcontrollers, and is much more space-ecient.

14

2.5

Interacting with the FPGA (Part 1)

A couple of interface modules are supplied, comm fpga fx211 and comm fpga epp12
for you to instantiate in your applications VHDL code. The former has an external
interface compatible with the Cypress FX2LPs slave FIFO signals and the latter has
an external interface compatible with the EPP signals provided by the Atmel AVR
rmware. However, both have identical internal interfaces, each providing a read
pipe, a write pipe and a seven-bit address specifying which of 128 logical channels is
to be read or written.
FPGA
CommFPGA Module
FPGA < Host
Pipe
USB
Interface

h2fData_out[7:0]
h2fValid_out
h2fReady_in
chanAddr_out[6:0]

FPGA > Host


Pipe

f2hData_in[7:0]

FPGA
Application
Logic

f2hValid_in
f2hReady_out

Each channel is eight bits wide. Each channel may be read from or written to by the
host. Each read or write operation can deal with single bytes or many hundreds of
megabytes. Applications are free to choose how these channels are implemented in
their VHDL code. Two such implementations are given in the ex cksum and ex fifo
examples.
In the previous section, we loaded the ex cksum example into the FPGA. The ex cksum
example implements the FPGA channels using ordinary registers, meaning that writes
to channel N update regN, and reads from channel N typically return the current value
of regN.
You can see this by using flclis command-line mode (triggered by the -c option):
wotan$ ./<PLATFORM>/rel/flcli -v <VID:PID> -c
Attempting to open connection to FPGALink device 04B4:8613...
Entering CommFPGA command-line mode:
> w1 12;w2 34;w3 abcdef56;r1;r2;r3 04
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 12 34 56 56 56 56
.4VVVV
> w0 01
> w0 02
> w0 04
> w0 08
11
12

hdl/fx2/vhdl/comm fpga/comm fpga fx2.vhdl.


hdl/epp/vhdl/comm fpga/comm fpga epp.vhdl.

15

> r0 10
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 35 5555555555555555
> q
wotan$

The instructions accepted by the command-line are terse, but simple. The w1 12;w2
34;w3 abcdef56;r1;r2;r3 04 command line performs six operations sequentially:
Write single byte 0x12 to channel 1.
Write single byte 0x34 to channel 2.
Write four bytes 0xAB, 0xCD, 0xEF, 0x56 to channel 3.
Read one byte from channel 1.
Read one byte from channel 2.
Read four bytes from channel 3.
The output shows 12 34 56 56 56 56 because in the ex cksum example, the data
channels inside the FPGA are implemented with simple registers, so although four
distinct bytes are written to channel 3, the four bytes that are later read back from
channel 3 are just four copies of the last value written.
You can see how this is implemented in the FPGA by taking a look at the VHDL13 :
1
2
3
4
5
6
7
8
9
10
11

-- Infer registers
process(fx2Clk_in)
begin
if ( rising_edge(fx2Clk_in) ) then
checksum <= checksum_next;
reg0 <= reg0_next;
reg1 <= reg1_next;
reg2 <= reg2_next;
reg3 <= reg3_next;
end if;
end process;

12
13
14
15
16
17
18
19
20

-- Drive register inputs for each channel when the host is writing
checksum_next <=
std_logic_vector(unsigned(checksum) + unsigned(h2fData))
when chanAddr = "0000000" and h2fValid = 1
else x"0000"
when chanAddr = "0000001" and h2fValid = 1 and h2fData(0) = 1
else checksum;
reg0_next <= h2fData when chanAddr = "0000000" and h2fValid = 1 else reg0;
13

See hdl/{fx2,epp}/vhdl/ex cksum/top level.vhdl for the complete VHDL module.

16

21
22
23

reg1_next <= h2fData when chanAddr = "0000001" and h2fValid = 1 else reg1;
reg2_next <= h2fData when chanAddr = "0000010" and h2fValid = 1 else reg2;
reg3_next <= h2fData when chanAddr = "0000011" and h2fValid = 1 else reg3;

24
25
26
27
28
29
30
31

-- Select values to return for each channel when the host is reading
with chanAddr select f2hData <=
sw_in when "0000000",
reg1 when "0000001",
reg2 when "0000010",
reg3 when "0000011",
x"00" when others;

32
33
34
35

-- Assert that theres always data for reading, and always room for writing
f2hValid <= 1;
h2fReady <= 1;

So when you enter w1 12, a single byte is written to channel 1, which sets chanAddr=
0x01 and h2fData=0x12, and drives h2fValid high for one clock cycle, updating
register reg1 with the value 0x12.
Similarly when you enter r1, it initiates a single byte read of channel 1, which sets
chanAddr=0x01 and drives f2hReady14 high for one clock cycle, which samples the
current value of register reg1 and returns it to the host.
Register reg0 is a little more interesting. Any value written to it (e.g w0 aa) is
displayed on the eight board LEDs, and is added to a running sixteen-bit checksum
which is displayed on the seven-segment display. Reads from register reg0 return the
current state of the eight switches. You can clear the reg0 checksum by writing a 1
to reg1.
Notice that reads and writes never block: there is always data available in the read
pipe and there is always room available in the write pipe.

2.6

Interacting with the FPGA (Part 2)

In the previous section, we used the flcli utility to read and write simple registers
implemented in the FPGA by the ex cksum example. The ex fifo example is more
interesting. You can load it like this:
wotan$ ./<PLATFORM>/rel/flcli -v <VID:PID> -i <VID:PID> -s \
-x gen_csvf/ex_fifo_<BOARD>_<PROTOCOL>_vhdl.csvf
Attempting to open connection to FPGALink device 04B4:8614...
Loading firmware into 04B4:8614...
Awaiting renumeration.......
14

The value stored in a simple register like this is unaected by a read operation, so its not
necessary for this code to consider f2hReady - it need only select the correct register value with
which to drive f2hData, and do so continuously.

17

Attempting to open connection to FPGLink device 04B4:8614 again...


Connecting USB power to FPGA...
The FPGALink device at 04B4:8614 scanned its JTAG chain, yielding:
0x01414093
0x05045093
Playing "gen_csvf/ex_fifo_s3board_fx2_vhdl.csvf" into the JTAG chain on FPGALink device 04B4:8614...
wotan$ ./<PLATFORM>/rel/flcli -v 04B4:8614 -c
Attempting to open connection to FPGALink device 04B4:8614...
Entering CommFPGA command-line mode:
> r0 10;w0 01020408102040804020100804020100
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ................
> q
wotan$

Now, channel 0 is connected to a pair of FIFOs inside the FPGA, a read FIFO and
a write FIFO. Separate producer and consumer processes periodically insert upcount
data into the read FIFO and drain data from the write FIFO, respectively. The speed
at which these processes work is selectable by setting dierent values on the eight
switches: sw[7:4] control the speed of the consumer and sw[3:0] control the speed
of the producer.
Heres the code15 :
1
2
3
4
5
6
7

-- Infer registers
process(fx2Clk_in)
begin
if ( rising_edge(fx2Clk_in) ) then
count <= count_next;
end if;
end process;

8
9
10
11
12
13
14
15
16
17
18
19

-- Wire up write FIFO to channel 0 writes:


-flags(2) driven by writeFifoOutputValid
-writeFifoOutputReady driven by consumer_timer
-LEDs driven by writeFifoOutputData
writeFifoInputData <= h2fData;
writeFifoInputValid <=
1 when h2fValid = 1 and chanAddr = "0000000"
else 0;
h2fReady <=
0 when writeFifoInputReady = 0 and chanAddr = "0000000"
else 1;

20
21
22
23
24

-- Wire up read FIFO to channel 0 reads:


-readFifoInputValid driven by producer_timer
-flags(0) driven by readFifoInputReady
count_next <=
15

See hdl/{fx2,epp}/vhdl/ex fifo/top level.vhdl for the complete VHDL module.

18

25
26
27
28
29
30
31
32
33

std_logic_vector(unsigned(count) + 1) when readFifoInputValid = 1


else count;
readFifoInputData <= count;
f2hValid <=
0 when readFifoOutputValid = 0 and chanAddr = "0000000"
else 1;
readFifoOutputReady <=
1 when f2hReady = 1 and chanAddr = "0000000"
else 0;

34
35
36
37
38
39
40

-- Select values to return for each channel when the host is reading
with chanAddr select f2hData <=
readFifoOutputData
when "0000000", -- get data from read FIFO
fifoCount(15 downto 8) when "0000001", -- read the depth of the write FIFO
fifoCount(7 downto 0) when "0000010", -- read the depth of the read FIFO
x"00"
when others;

When the host writes to channel 0, each byte is clocked into the write FIFO. When
the write FIFO lls up, h2fReady is deasserted which tells the host to stop sending
until the consumer process has freed up some room for more data.
When the host reads from channel 0, each byte is clocked out of the read FIFO. When
the read FIFO empties, f2hValid is deasserted to stop sending data to the host until
the producer process has inserted some more data into the FIFO.
When the example is rst loaded, you will see the leftmost pair of digits on the sevensegment display incrementing, telling you how many bytes there are in the read FIFO.
When you issue the command r0 10, the host reads sixteen bytes from the read FIFO,
causing the count to decrement by sixteen. If there are as yet insucient bytes in the
read FIFO to fulll the request, the host blocks until bytes become available.
Similarly, the rightmost pair of digits on the seven-segment display tells you how many
bytes there are in the write FIFO. When you issue the command w0 010204081020408
04020100804020100, sixteen bytes are written to the write FIFO. The consumer process then begins to drain the data, displaying each byte in turn on the eight LEDs.
If there is as yet insucient room in the write FIFO to fulll the request, the host
blocks until enough room is available. This is not always noticeable because the
microcontrollers have additional bytes of FIFO space.
If your board does not have a seven-segment display, you can read the current depth
of the write FIFO by reading from channel 1, and you can read the current depth of
the read FIFO by reading from channel 2.

2.7

Summary

In this chapter we used the flcli utility to program an FPGA with a couple of
pre-built examples, and to communicate with the data channels in the FPGA.
19

Host Application Development

The flcli utility is a great way to get started with FPGALink, and for simple testing
of the behaviour of your VHDL code, but sooner or later you will want to dive in and
write your own host-side applications. There is out-of-the-box support for C/C++,
Python and Excel/VBA, but the core library itself is just a C DLL, so calling into it
from other languages is straightforward16 .
In order to enable an application to communicate with potentially many FPGALink
devices, the library uses the concept of a handle to refer to an FPGALink device.
An opaque handle is returned when a connection is rst established to a device, and
that handle is supplied for all subsequent operations on that device.

3.1

Language Bindings

There is obviously a signicant cross-language semantic overlap in the API; the only
dierences are those imposed by the languages themselves.
3.1.1

Because C has no concept of exceptions, wherever a function can fail, its return
value is just a status code; the actual result (if any) is provided in an out parameter
instead. An optional error message is also provided in an out parameter. Conversely,
wherever a function cannot fail, its return value (if any) is actually the result.
Each function that can fail will return FL SUCCESS on success, or something else on
failure. Each will also accept a pointer to a const char* which will be set to a
more or less meaningful message if an error occurs. The memory for this message is
dynamically allocated and must subsequently be deallocated by application code with
flFreeError(). If you do not wish to receive error messages you can just set this
parameter to NULL.
Its useful to dene a macro to handle this:
1
2
3
4
5
6
7
8
9
10

#define CHECK(x)
\
if ( status != FL_SUCCESS ) {
\
returnCode = x;
\
fprintf(stderr, "%s\n", error); \
flFreeError(error);
\
goto cleanup;
\
}
:
status = flWriteChannel(handle, 1000, 0x01, 1, &byte, &error);
CHECK(21);
16

Or at least it ought to be straightforward!

20

To get you started, there is an example in C for you to study in the examples/c
subdirectory. See examples/c/README for details of how to compile the code on your
platform.
3.1.2

Python

Python has exceptions, so the API in Python is written such that each functions
return value (if any) is actually its result, with an exception thrown when an error
occurs.
Separate bindings are provided for Python2.x and Python3.x. These reside in the
examples/python subdirectory. The bindings are themselves executable, and oer
similar functionality to the C example. The Python binding may be imported into
your own code, or used from an interactive Python session. For more details, see
examples/python/README.
3.1.3

Excel/VBA

VBA has exceptions, so the API in VBA is written such that each functions return
value (if any) is actually its result, with an exception thrown when an error occurs.
The examples/excel/fpgalink.xls spreadsheet incorporates the VBA binding, and
exposes a simple graphical user interface. Before opening it, please ensure you have
unpacked the FPGALink distribution to a local drive, not a network drive, otherwise
Excel will consider the FPGALink DLL to be untrusted and will refuse to load it.

3.2

API Overview

See http://www.swaton.ukfsn.org/apidocs/libfpgalink_8h.html for more detailed API documentation.


The library consists of ve classes of functions:
Firmware operations (FX2LP-specic)
Connection lifecycle operations
NeroJTAG operations (programming the FPGA)
CommFPGA operations (interacting with the FPGA)
Miscellaneous operations
Each will now be covered in turn; please refer also to the detailed API docs.
21

3.2.1

Firmware Operations [FX2LP-Specic]

The Cypress FX2LP USB interface has no internal nonvolatile storage for rmware.
On startup it typically loads rmware from an external serial EEPROM, which is
probably how your board works. You can easily load new rmware over USB, or
write your new rmware to the external EEPROM using these operations.
flLoadStandardFirmware():
Load standard FPGALink rmware into the FX2s RAM.
flFlashStandardFirmware():
Flash standard FPGALink rmware into the FX2s EEPROM, optionally appending an SVF, XSVF or CSVF initialisation stream and an FPGA initialisation stream.
flLoadCustomFirmware():
Load custom rmware from a .hex le into the FX2s RAM.
flFlashCustomFirmware():
Flash a custom rmware from a .hex or .iic le into the FX2s EEPROM.
flSaveFirmware():
Save existing EEPROM data to an .iic le.
3.2.2

Connection Lifecycle Operations

These two operations enable you to actually establish a connection to an FPGALink


device over USB.
flOpen():
Open a connection to the FPGALink device at the specied VID & PID.
flClose():
Close the connection to the FPGALink device.

22

3.2.3

Device Capabilities and Status Operations

These operations enable you to query the FPGALink device to nd out what features it supports. Currently there are only two features: NeroJTAG for JTAGprogramming, and CommFPGA, for communicating with an already-programmed
FPGA.
flIsDeviceAvailable():
Check if a given device is actually connected to the system.
flIsNeroCapable():
Check to see if the device supports NeroJTAG.
flIsCommCapable():
Check to see if the device supports CommFPGA.
3.2.4

NeroJTAG Operations

The NeroJTAG operations enable you to examine the JTAG chain and program devices in the chain.
flScanChain():
Scan the JTAG chain and return an array of IDCODEs.
flPlayXSVF():
Play an SVF, XSVF or CSVF le into the JTAG chain.
3.2.5

CommFPGA Operations

The CommFPGA operations enable you to read from and write to up to 128 logical
channels implemented in the FPGA.
flIsFPGARunning():
Check to see whether or not the FPGA has been programmed.
flReadChannel():
Read bytes from the specied channel into the supplied buer.
flWriteChannel():
Write bytes from the the supplied read-only buer to the specied channel.

23

flAppendWriteChannelCommand():
Append a write command to the end of the write buer.
flPlayWriteBuffer():
Play the write buer into the FPGALink device immediately.
flCleanWriteBuffer():
Clean the write buer (if any).
3.2.6

Miscellaneous Operations

Some operations are useful or just necessary, but dont t into the other four categories:
flInitialise():
Initialise the library. You must call this before any of the other functions.
flFreeError():
Free an error allocated when one of the other functions fails.
flSleep():
Sleep for the specied number of milliseconds.
flLoadFile():
Return a newly-allocated buer with the specied binary le loaded into it.
flFreeFile():
Free a buer previously returned by flLoadFile().
flPortAccess():
Access port lines on the USB interface microcontroller.

24

FPGA Application Development

FPGALink supports several dierent CommFPGA protocols for data transfer between
the USB microcontroller and the FPGA, with varying throughputs, FPGA pin utilisations and component costs. Note that even though their internal implementation
diers, the various CommFPGA implementations present exactly the same host-side
API and exactly the same FPGA-side FIFO interfaces.
Whilst it is of course possible to implement one or more of the CommFPGA protocols
yourself, there would be little point in doing so, because included in the FPGALink
distribution are a couple (with more to follow) of ready-made infrastructure modules
for this purpose, comm fpga fx2 and comm fpga epp, which you can instantiate in
your designs. The modules each have two ports, an external port which is typically
wired directly to external pins on the FPGA, and an internal port which is connected
to application logic. The external port signals of the fx2 and epp avours dier, but
the internal ports are identical.

4.1

Internal Port

The internal port is common to both fx2 and epp implementations. All signals are
synchronous to the comm fpga * modules clock.
comm_fpga_* modules
h2fData_out[7:0]

Host > FPGA


Pipe

h2fValid_out
h2fReady_in
chanAddr_out[6:0]

Host < FPGA


Pipe

f2hData_in[7:0]
f2hValid_in
f2hReady_out

The comm fpga * modules provide:


A host-to-FPGA data pipe (h2fData out, h2fValid out & h2fReady in)
An FPGA-to-host data pipe (f2hData in, f2hValid in & f2hReady out)
A 7-bit channel address (chanAddr out)
Each data pipe has a standard FIFO interface17 where the sender drives some data
lines xxxData[7:0] and a xxxValid line, and the receiver asserts xxxReady (where
17

See http://inst.eecs.berkeley.edu/cs150/Documents/Interfaces.pdf

25

xxx is either h2f for host-to-FPGA transfers or f2h for FPGA-to-host transfers). If
and only if both the xxxValid and xxxReady signals are asserted when a clock rising
edge arrives, the data is registered by the receiver and the next data byte is made
available by the sender.

4.2

FX2 External Port

The comm fpga fx2 modules external port clocks data synchronously on every rising
edge of fx2Clk in, which is driven at 48MHz by the FX2LP. The internal port is
synchronous to the same clock. The interface comprises most of the signals in the
FX2LP Slave FIFO Interface18 with the following changes:
The data bus is only eight bits wide.
Only one FIFOADR line is supplied, called fx2FifoSel out.
The other FIFOADR line is connected (internally or externally) to Vcc.
Only FLAGB and FLAGC are used.
One signal is supplied for driving both /SLOE and /SLRD.
The result is nine signals for control and eight signals for data; most FX2LP-based
FPGA devkits just connect all 17 directly to the FPGA:
FPGA
FX2LP

comm_fpga_fx2

IFCLK
FIFOADR[0]
FIFOADR[1]
FD[7:0]
/SLRD
/SLOE
FLAGC
/SLWR
FLAGB
PKTEND

'1'

fx2Clk_in
fx2FifoSel_out
fx2Data_io
fx2Read_out
fx2GotData_in
fx2Write_out
fx2GotRoom_in
fx2PktEnd_out

Notice that the FPGA continuously drives FIFOADR[1] high, and that the fx2Read out
signal drives two external pins, /SLOE and /SLRD. This is the wiring used by the
ex cksum and ex fifo examples.

18

See EZ-USB TRM Chapter 9.

26

If youre designing your own PCB, you can save two FPGA I/O pins by doing the
same thing on the PCB rather than in the FPGA:
FPGA
FX2LP

comm_fpga_fx2

IFCLK
FIFOADR[0]
FIFOADR[1]
FD[7:0]
/SLRD
/SLOE
FLAGC
/SLWR
FLAGB
PKTEND

Vcc

fx2Clk_in
fx2FifoSel_out
fx2Data_io
fx2Read_out
fx2GotData_in
fx2Write_out
fx2GotRoom_in
fx2PktEnd_out

In this case we use eight pins for data as before, but only seven pins for control. Notice
that the result is logically the same: fx2Read out signal drives /SLOE and /SLRD, and
fx2FifoSel out drives FIFOADR[0], with FIFOADR[1] tied high.
Since the FX2 Slave FIFO interface clocks data synchronously at the end of every
48MHz clock cycle, the theoretical maximum throughput is 48MB/s (45.8MiB/s). In
real-world tests with FPGALink, the actual observed throughput is typically about
26MiB/s. The achievable throughput is limited by the speed of the host-side USB
code.

4.3

EPP External Port

The Atmel AVR rmware implements the IEEE 1284 Enhanced Parallel Port protocol19 .
FPGA
AT90USB162

50MHz

comm_fpga_epp
eppClk_in
eppData_io
eppAddrStb_in
eppDataStb_in
eppWrite_in
eppWait_out

PD[7:0]
PC4
PC5
PC6
PC7

The EPP protocol is asynchronous (i.e the control signals are not synchronised to
any particular clock). Since FPGAs tend to be synchronous, the EPP signals are
internally synchronised to the comm fpga epp modules eppClk in. The internal port
is synchronous to the same clock. The frequency of eppClk in is not important,
19

See http://www.fapo.com/eppmode.htm

27

and neither is its source; the ex cksum and ex fifo examples just use the devkits
onboard 50MHz cystal oscillators.
The EPP protocol is not as ecient as the synchronous FIFO interface of the FX2LP,
but in any case the overall throughput of a system based on an Atmel AVR is limited
by the USB throughput (unlike the 480Mb/s Hi-Speed FX2LP, the AVRs are FullSpeed 12Mb/s devices) and not the EPP interface. Observed throughput is about
330KiB/s for the AVR rmware running single-buered on an AT90USB162, ATmega16U2, ATmega32U2 or similar, and about 1.2MiB/s for the rmware running
double-buered on an AT90USB647, ATmega32U4 or similar.

4.4

Build Infrastructure

In the hdl directory is a build infrastructure capable of synthesising VHDL code into
SVF les suitable for loading into an FPGA with FPGALink. Xilinx and Altera
FPGA toolchains are supported. The build infrastructure uses command-line tools
rather than the vendors Integrated Development Environments, but if you prefer to
work in an IDE, setting up a project is straightforward.
For Xilinx FPGAs, its necessary to install ISE WebPACK20 . For Altera FPGAs, its
necessary to install Quartus II Web Edition21 .
4.4.1

MacOSX

Unfortunately, neither Alteras Quartus nor Xilinxs ISE run on MacOSX, so you
will need to run either Windows or Linux in a virtual machine under VirtualBox or
Parallels.
4.4.2

Windows

The FPGA build infrastructure relies on some UNIX tools like make. Whilst it may
be possible to get builds working with 3rd-party UNIX tools for Windows, the only
ocially supported set of tools are those available on the MakeStu website22 .
For Xilinx FPGAs, you will need to create a XILINX environment variable, and set
it to the location of the ISE installation (e.g C:/Xilinx/13.2/ISE DS/ISE). No
further installation tasks are needed for Altera FPGAs.

20

From http://www.xilinx.com/support/download/index.htm
From https://www.altera.com/download/software/software/quartus-ii-we
22
See http://www.makestuff.eu/wordpress/?page_id=1489
21

28

Then from within a Console2 window, you can build the ex cksum example for the
Digilent Atlys like this:
chris@win7 echo $XILINX
C:/Xilinx/13.2/ISE_DS/ISE
chris@win7$ cd hdl/fx2/vhdl/ex_cksum
chris@win7$ ls ../../platforms
atlys lx9 nexys2-1200 nexys2-500 nexys3
chris@win7$ make PLATFORM=atlys

4.4.3

s3board

xylo-l

Linux

For Xilinx FPGAs, you will need to create a XILINX environment variable, and set
it to the location of the ISE installation (e.g /opt/Xilinx/13.2/ISE DS/ISE). No
further installation tasks are needed for Altera FPGAs.
Then from within a terminal window, you can build the ex cksum example for the
Digilent Atlys like this:
chris@wotan echo $XILINX
/opt/Xilinx/13.2/ISE_DS/ISE
chris@wotan$ cd hdl/fx2/vhdl/ex_cksum
chris@wotan$ ls ../../platforms
atlys lx9 nexys2-1200 nexys2-500 nexys3
chris@wotan$ make PLATFORM=atlys

4.4.4

s3board

xylo-l

Specifying the JTAG Chain

The Altera tools will only generate SVF les for a single-device JTAG chain, but
the Xilinx tools support JTAG chains with multiple devices. The JTAG chain and
the actual device to program is specied in the platforms/*/platform.batch les.
All devices except the one being programmed need BSDL descriptions so that the
programming algorithm can bypass them.
A future release of FPGALink will simplify this, and provide support for multi-device
chains with Altera FPGAs.
4.4.5

Location Constraints

For boards based on Xilinx FPGAs, the location constraints are specied in the
platforms/*/platform.ucf les. For boards based on Altera FPGAs, the location
constraints are specied in the platforms/*/platform.qsf les.
4.4.6

The xsvf2csvf Utility

The CSVF format is very similar to Xilinxs XSVF, except that it has a few simplications and the JTAG bitmaps have been been reversed, making it better suited
29

for playback on small microcontrollers. It also has a simple run-length compression


scheme making the programming les smaller. You can generate a CSVF le from an
XSVF or SVF le using the xsvf2csvf utility.

30

Custom Boards

Most of the FPGA boards supported by FPGALink are ready-made, but in some
cases its useful to be able to wire an existing microcontroller board to an existing
FPGA board, or even design a composite board from scratch.

A.1

Minimus/EP2C5

By far the cheapest hardware solution for FPGALink-based applications, this is an


EP2C5 Mini Board attached to a Minimus AVR USB board:

To make one you will need an EP2C5 Mini Board and a Minimus AVR USB board.
The only modication necessary is to the Minimus board to allow it to draw power
from the EP2C5 board. To do this you must sever the USB +5V line, which is the
fourth one down on the USB connector in the picture above. Since the Minimuss
connector is a Type A plug, the result is physically quite awkward if you dont have a
Type A extension cable. Another option is to remove the plug altogether and replace
it with a cable with a Type A plug on one end and the other end soldered to the
Minimus. Thus, it becomes straightforward to connect the USB +5V power to the
P8 connector in the bottom left of the EP2C5 board, to make the whole thing draw
its power from USB, eliminating the need for an external +5V supply.
31

A.2

Minimus/Nexys2

Although the Digilent Nexys2 has a built-in FX2LP USB interface, in some circumstances it might be necessary to have two channels into the FPGA, either both to the
same PC, or to dierent PCs. Heres how to wire a Minimus AVR USB board to a
couple of the expansion ports of a Nexys2:

The JTAG connections are TMS to PB0, TCK to PB1, TDI to PB2 and TDO to PB3.
The CommFPGA connections should be fairly clear from the photo: the eight data
lines go from the Minimuss Port D to the top and bottom rows of the Nexys2s JC1
connector, and the four control lines go to the top row of JD1. As before, the Minimus
needs to draw power from the Nexys2, so you will need to sever the USB +5V line,
which is the fourth one down on the USB connector in the picture above.

32

You might also like