FPGA Development in Elphel cameras

From ElphelWiki
Jump to: navigation, search
This is a legacy page. Information may not reflect the current state of the products or code. See current FPGA project here: X393, VDT

Introduction

Much of the performance and flexibility of the Elphel cameras are provided by the reconfigurable FPGA chips. FPGA is used on the main camera board (currently it is 10353) and on some of the extension ones (10347, 10359, 10357). On the main board the FPGA chip complements CPU to perform video processing and compression - it does this nearly 100 times faster than the CPU alone, but generally it is significantly more difficult to implement some functionality in the FPGA than it can be done in the software. And so the camera (like many other modern devices) combines the strong features of both: FPGA performs computationally intensive but algorithmically relatively simple operations (working with the images on the pixel level, providing image compression) and the CPU is responsible for the higher level functions, interface and overall control of the camera.

Elphel does not make secrets of the FPGA code, all the source code is available under GNU GPL v 3.0 license, the same one as used for the camera software. Elphel software distribution (available both on Sourceforge project page and inside each camera file system) includes both binary FPGA image ("bit file") and the source code (*.v files in \elphel_tree\fpga) needed to re-create the FPGA image and/or simulate the design. Also included are the log files generated by the FPGA "compiler" during creation of the provided bit file so you may look inside even if you do not have the necessary FPGA tools, you may also find these files useful to compare with the output that you get from those tools.

FPGA design flow

There are two main activities during development of the FPGA code: synthesis and simulation.

  • Synthesis (the whole process involves more steps in addition to just strictly "synthesis" itself) is needed to translate the source code into the "executable" and
  • Simulation - software emulation of the FPGA functionality. Simulation runs about million times slower than the real thing, but it allows easy analysis of what is going inside the design, provides ability to test and troubleshoot project as a whole or individual modules.

Software required for FPGA development with Elphel products

Software for synthesis

Elphel cameras use 1200K gates Xilinx Spartan(R) 3e FPGA (XC3S1200E-5FT256C) that are supported (among others) by free for download (but non-free software) ISE WebPACK (R) tools (registration required for download).

That software package is really good for "compiling" your design into silicon, but the simulator provided with the free for download tools has reduced functionality.

Software for simulation

Luckily there are really free (GNU GPL) tools available for simulation and Elphel provides scripts for simulation of the design using these tools. Simulation software we use consists of two parts (that require separate installation), provided are the links to the current (as of January,28 2008) releases:

Note:You will still need to download and install Xilinx ISE WebPACK (R) even for simulation only. That package includes Verilog source code library that describes the FPGA device primitives used in the design and the current license does not allow to distribute this library with the design.

Installation of the Xilinx ISE WebPACK

For ISE versions 9.2-11.1 - no problems in Ubuntu on 32-bit platforms.

To install WebPACK on 64-bit platform 32-bit libraries are needed:

sudo apt-get install ia32-libs ia32-libs-gtk ia32-libs-sdl dpkg-dev


When was installing WebPACK 9.2 on Kubuntu 9.10, 64-bit got:

error while loading shared libraries: libstdc++.so.5: cannot open shared object file: No such file or directory

Solution - this is the bug#431091


To install WebPack 10.1 on 64-bit - launch ./bin/lin/setup


Current versions of Xilinx ISE WebPACK install on Linux rather smoothly (Last time I used WebPACK 9.2 and Kubuntu 7.04) but minor tweaking was needed to launch programs like Timing Analyzer or FPGA Editor. They needed additional package to be installed (don't remember - will put here when find out) and "export DISPLAY=:0" to run correctly (without that ISE "as if" launches those programs, but nothing really happens). I just created a small startup script launch_ise.sh in the WebPACK installation directory (it was /usr/local/Xilinx92 in my case) with the following content:

#!/bin/sh
cd $(dirname $0)
export DISPLAY=:0
./bin/lin/ise

Importing Elphel project into Xilinx ISE WebPack

All the FPGA code for Elphel products is located in the fpga directory of the top installation directory that will be created when you run "./install_elphel" script inside the directory created when you inflate the Elphel software distribution. The project files for the main board (10353) FPGA is included in the fpga/x3x3 subdirectory.

When you start the ISE WebPack you need to select (from the top menu)"

Project -> Source Control -> Import

And then for the "Project file to import" navigate to the fpga/x3x3 subdirectory of you project and select file x353_import.tcl. For the "Directory to import to" select the same directory (you may just click on "..." button and then on "OK").

That should conclude importing of the project, the x353.ise will be created and you should be able to view/edit project files and run synthesis and implementation tools.

Simulating 10353 board FPGA with Icarus Verilog and GTKWave

The first step is to create a library of the Xilinx primitives that can be processed by Icarus Verilog. Unfortunately the library as provided with WebPACK is not immediately compatible with the Icarus Verilog simulator and we do not have a license to distribute the modified for Icarus version of the primitives source code.

The library in question is installed as verilg/src/unisims directory of the top installation directory of Xilinx WebPACK (in my case it is /usr/local/Xilinx92). The Makefile (together with the unisims_patch.sh script) in the fpga subdirectory of the Elphel product source tree looks for the Xilinx WebPACK installation on the computer, copies unisims library directory to the fpga directory and patches the files for compatibility with Icarus Verilog. Some modifications (like removing of qualifiers "integer" an "real" after the keywords "parameter" and "localparam" currently not supported by Icarus) are applied to all files, other are specific patches to the files used so far in the project. That means that if you use some other unisims primitives in addition to those already used in the x3x3 project they may also need some patching.

We do not know when any of the files we used will be modified by Xilinx, but we'll try to maintain the patches current. Please notify Elphel developers if you will have incompatibility problems.

If the script can not locate the Xilinx WebPACK installation during software build, the empty "unisims" directory is created under "fpga" and during next runs of "make" it will skip searching for the unisims library. In the case you installed WebPACK after the first run of "make" or have several different versions of WebPACK you may want to navigate to fpga directory and run

make; make install

there (if you did not build Elphel software in the current session you may need to run . ./init_env (dot-space-dot-slash-init_env) in the top installation directory (called "elphel353" by default), one level above "fpga" one.

When the unisims library is ready you may try the simulation itself. Navigate to the fpga/x3x3 and run ./x353_sim.sh As a result you will see some output (it may make sense to set console history to "unlimited"), there should be no errors (at least until until the "Runnig ..."):

removed `x353.lxt'
Using UNISIM library ../unisims
Icarus Verilog version 0.8.6 ($Name:  $)
Copyright 1998-2003 Stephen Williams
 This program 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 2 of the License, or
 (at your option) any later version.
 This program 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.
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
translate: /usr/local/lib/ivl/ivlpp  -v -L -D__ICARUS__=1 -f/tmp/ivrlg60f03525  -Dlegacy_model | /usr/local/lib/ivl/ivl -v -C/tmp/ivrlh60f03525 -C/usr/local/lib/ivl/vvp.conf -- -
Icarus Verilog Preprocessor version $Name:  $ $State: Exp $
Copyright (c) 1999 Stephen Williams (steve@icarus.com)
 This program 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 2 of the License, or
 (at your option) any later version.
 This program 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.
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Indexing library: ../unisims
/usr/local/lib/ivl/system.sft: Processing System Function Table file.
Using language generation: SystemVerilog 3.0
PARSING INPUT
... done, 0.08 seconds.
ELABORATING DESIGN
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/PULLDOWN.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/FD.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/FD_1.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/IOBUF.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/FDDRCPE.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/FDCPE.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/FDCPE_1.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/OBUF.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/KEEPER.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/IBUF.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/LD.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/BUFG.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/FDCE.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/LUT4.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/BUF.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/FDE_1.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/FDCE_1.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/IBUFDS.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/IBUFG.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/DCM.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/BUFGMUX.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/OBUFDS.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/SRL16.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/FDE.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/PULLUP.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/RAMB16_S18_S36.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/RAMB16_S9_S36.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/RAMB16_S36_S36.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/SRL16_1.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/MULT18X18.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/RAMB16_S18_S18.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/FDC_1.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/FDC.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/RAMB16_S9_S9.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/RAM16X1D.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/RAMB4_S8_S8.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/ROM32X1.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/MULT18X18SIO.v
Executing: /usr/local/lib/ivl/ivlpp -D__ICARUS__ -L   -Dlegacy_model ../unisims/LD_1.v
 ... done, 0.64 seconds.
RUNNING FUNCTORS
-F cprop ...
-F nodangle ...
... 1 iterations deleted 3265 dangling signals and 1210 events. (count=3067)
... 2 iterations deleted 3265 dangling signals and 1210 events. (count=0)
... done, 0.06 seconds.
CODE GENERATION -t dll
... invoking target_design
... done, 0.93 seconds.
STATISTICS
lex_string: add_count=15385 hit_count=41544
Compiling VVP ...
Compile cleanup...
... Linking
... Removing symbol tables
...   347402 functors
              9435 table
               177 bufif
               859 resolv
            328086 variable
...   222122 opcodes (5357568 bytes)
...    12573 nets
...       28 memories
...     1290 scopes
... 1.47609 seconds, 57292.0/38120.0/1356.0 KBytes size/rss/shared
Running ...

After the simulation itself will start that generates "x353.lxt" (older version if any of that file was removed at the start of the script). It will take some time to simulate a fraction of a millisecond (as simulation is about a million times slower than the real time) and then the

gtkwave x353.lxt x353_1.sav &

command will be executed that should open the waveform viewer. In addition to the simulation result "x353.lxt" the viewer uses "x353_1.sav" - file that contains viewer state with some signals selected and grouped. GTKWave allows you to create, save and read back such files.

You may change the simulation sequence by modifying the file fpga/x3x3/x353_1.tf or creating a new simulation sequence and modifying the fpga/x3x3/x353_sim.sh script to use that file instead of the fpga/x3x3/x353_1.tf.