First Documentation release

parent fa76945d
*~
*.aux
*.cp
*.cps
*.fn
*.html
*.info
*.ky
*.log
*.pdf
*.pg
*.texi
*.toc
*.tp
/*.txt
*.vr
#
# Makefile for the documentation directory
#
# Copyright 1994,2000,2010,2011 Alessandro Rubini <rubini@linux.it>
#
#################
# There is not basenames here, all *.in are considered input
INPUT = $(wildcard *.in)
TEXI = $(INPUT:.in=.texi)
INFO = $(INPUT:.in=.info)
HTML = $(INPUT:.in=.html)
TXT = $(INPUT:.in=.txt)
PDF = $(INPUT:.in=.pdf)
ALL = $(INFO) $(HTML) $(TXT) $(PDF)
MAKEINFO ?= makeinfo
%.texi: %.in
@rm -f $@
sed -f ./infofilter $< > $@
emacs -batch --no-site-file -l fixinfo $@
chmod -w $@
%.pdf: %.texi
texi2pdf --batch $<
%.info: %.texi
$(MAKEINFO) $< -o $@
%.html: %.texi
$(MAKEINFO) --html --no-split -o $@ $<
%.txt: %.texi
$(MAKEINFO) --no-headers $< > $@
##############################################
.PHONY: all images check terse clean install
.INTERMEDIATE: $(TEXI)
all: images $(ALL)
$(MAKE) terse
images::
if [ -d images ]; then $(MAKE) -C images || exit 1; fi
check: _err.ps
gs -sDEVICE=linux -r320x200x16 $<
terse:
for n in cp fn ky pg toc tp vr aux log; do rm -f *.$$n; done
rm -f *~
clean: terse
rm -f $(ALL) $(TEXI)
install:
# add the other unused targets, so the rule in ../Makefile works
modules modules_install:
;; use:
;; emacs -batch -l ./fixinfo.el <file>
;; or, better:
;; emacs -batch --no-site-file -l ./fixinfo.el <file>
(defun fixinfo (file)
(find-file-other-window file)
(message (concat "Maxing texinfo tree in " file))
(texinfo-all-menus-update)
(texinfo-every-node-update)
(save-buffer)
(kill-buffer (current-buffer))
)
;; loop over command line arguments
(mapcar 'fixinfo command-line-args-left)
(kill-emacs)
#! /usr/bin/sed -f
# allow "%" as a comment char, but only at the beginning of the line
s/^%/@c /
#s/[^\\]%.*$//
s/^\\%/%/
#preserve blanks and braces in @example blocks
/^@example/,/^@end example/ s/{/@{/g
/^@example/,/^@end example/ s/}/@}/g
/^@example/,/^@end example/ p
/^@example/,/^@end example/ d
/^@smallexample/,/^@end smallexample/ s/{/@{/g
/^@smallexample/,/^@end smallexample/ s/}/@}/g
/^@smallexample/,/^@end smallexample/ p
/^@smallexample/,/^@end smallexample/ d
# remove leading blanks
s/^[ ]*//
\input texinfo @c -*-texinfo-*-
%
% spec-sw.in - main file for the documentation
%
%%%%
%------------------------------------------------------------------------------
%
% NOTE FOR THE UNAWARE USER
% =========================
%
% This file is a texinfo source. It isn't the binary file of some strange
% editor of mine. If you want ASCII, you should "make spec-getting-started.txt".
%
%------------------------------------------------------------------------------
%
% This is not a conventional info file...
% I use three extra features:
% - The '%' as a comment marker, if at beginning of line ("\%" -> "%")
% - leading blanks are allowed (this is something I can't live without)
% - braces are automatically escaped when they appear in example blocks
%
@comment %**start of header
@documentlanguage en
@setfilename spec-getting-started.info
@settitle spec-getting-started
@iftex
@afourpaper
@end iftex
@comment %**end of header
@setchapternewpage on
@set update-month Feb 2014
@finalout
@titlepage
@title Getting Started with the SPEC
@c @subtitle Version 0.1 (@value{update-month})
@subtitle A tutorial for the Simple PCI Express Carrier project newcomers
@author Javier D. Garcia-Lasheras for CERN (BE-CO-HT)
@end titlepage
@headings single
@c ##########################################################################
@iftex
@contents
@end iftex
@paragraphindent 0
@c ##########################################################################
@node Top
@c ##########################################################################
@node Introduction
@chapter Introduction
The @i{Getting started with the SPEC} project provides a detailed
tutorial on how to get ready to work with the @i{Simple PCI Express Carrier}
@url{http://www.ohwr.org/projects/spec/wiki}.
@sp 1
The @i{Getting started with the SPEC} project is hosted at
@url{http://www.ohwr.org/projects/spec-getting-started} and is composed
by two main parts:
@itemize @bullet
@item Document covering the process of building a full SPEC design,
from designing the gateware to handling the board from a user-space
application running on a Linux Host PC.
@item Companion step-by-step demos, demonstrating how to use the different
development tools that are required for bringing up a new project in
the SPEC board from the ground up.
@end itemize
@sp 1
The document and demos assume that the user has no previous or very little
experience inside the @i{Open Hardware Repository} initiative. For this
reason, the tutorial introduces different resources from @i{OHR} while
covering the next design issues:
@itemize @bullet
@item An in depth explanation of the SPEC hardware board, exposing its
main features, introducing the PCB design and the FMC standard and
available modules and explaining the different operation modes.
@item How to design a FPGA gateware for the SPEC board, from introducing
the Wishbone bus and its associated OHR tools to building a bitstream
from the included HDL demos.
@item How to handle the SPEC board from a Linux Host, including the use
of the official user-space C software support, direct access to the PCI
bus and the interactive control of the board from a Python shell.
@end itemize
@sp 1
@c ==========================================================================
@node Prerequisites
@section Prerequisites
In order to follow the @i{Getting Started with the SPEC} tutorial, the
next prerequisites must be accomplished (note that some application
specific tools will be installed later):
@sp 1
@b{Commercial hardware}
@itemize @bullet
@item Simple PCI Express Carrier (mandatory)
@item fmc-dio-5chttla (optional)
@end itemize
@sp 1
@b{32/64-bits Linux Host PC with a free PCI Express slot}
Designed to be Kernel independent for a maximum compatibility, the tutorial
has been successfully performed in every Linux distribution in which has been
tested. (e.g. Debian 6, Debian 7, Ubuntu 12.04LTS, Ubuntu 14.04LTS(testing),
Scientific Linux 6).
@sp 1
@b{Clone the Getting Started with the SPEC git repository}
@example
user$ git clone git://ohwr.org/fmc-projects/spec/spec-getting-started.git
@end example
@sp 1
@b{Python environment}
Minimum Python 2.x and optional Python 3.x
(tested on Python 2.6.6, Python 2.7.6 and Python 3.3.3)
@sp 1
@b{Packages dependencies for building the code:}
Debian derivatives:
@example
user$ sudo apt-get install git gcc make
@end example
RHEL derivatives:
@example
root# yum install git gcc make
@end example
@sp 1
@b{Package dependencies for building the documentation:}
Debian derivatives:
@example
user$ sudo apt-get install emacs texinfo texlive texi2html
user$ sudo apt-get install libpng-dev libjpeg-dev libgif-dev
@end example
RHEL derivatives:
@example
root# yum install emacs texinfo texlive texinfo-tex texi2html
root# yum install libpng-devel libjpeg-devel giflib-devel
@end example
@sp 1
@c ==========================================================================
@node License and Copyright
@section License and Copyright
This document is licensed under the Creative Commons Attribution-ShareAlike 4.0
International License. To view a copy of this license, visit
@url{http://creativecommons.org/licenses/by-sa/4.0/deed.en_US}.
@sp 1
@center @image{pictures/by-sa, 6cm}
The licenses for the associated source code and demos can be found as a
companion of the code itself and are specified in the delivered works.
@sp 1
@b{Copyright Notice}: CERN, the European Organization for Nuclear Research,
is the first and sole owner of all copyright of both this document and
the associated source code deliverables.
@sp 1
@c ##########################################################################
@node The SPEC hardware architecture
@chapter The SPEC hardware architecture
The Simple PCI Express Carrier is an FMC carrier that can hold one FMC card
and an SFP connector. On the PCIe side it has a 4-lane interface, while the
FMC mezzanine slot uses a low-pin count connector. This board is optimised
for cost and is usable with most of the FMC cards designed within the OHR
project (e.g. ADC cards, Fine Delay). The board is commercially available.
@sp 1
@center @image{pictures/spec_v1.1_top, 10cm}
@center @i{Top view of the SPEC 1.1 first prototype}
@center @image{pictures/spec_v1.1_bottom, 10cm}
@center @i{Bottom view of the SPEC 1.1 first prototype}
@c ==========================================================================
@node Main features
@section Main features
@b{PCIe Support}:
The SPEC includes a 4-lane PCIe interface based in the Gennum GN4124. This
chip is designed to work as a companion for FPGA devices to provide a complete
bridging solution for general applications.
@b{Programmable Logic}:
The SPEC is powered by a Xilinx Spartan6 FPGA (XC6SLX45T-3FGG484C).
As a member of the Spartan-6 LXT family this device is intended for
High-speed serial connectivity and the main resources that can be used by the
user in order to build custom gateware designs are:
@itemize @bullet
@item 43,661 equivalent Logic Cells.
@item 401 Kb of maximum distributed RAM.
@item 58 DSP48A1 slices (each slice contains an 18x18 multiplier,
an adder and an accumulator).
@item 4x Clock Management Tiles (each CMT contains two DCM and one PLL).
@end itemize
@b{FMC Slot}:
The SPEC mounts a low pin count (LPC) connector which main features are:
@itemize @bullet
@item Vadj fixed to 2.5V.
@item FMC connectivity: all 34 differential pairs connected, 1 GTP
transceiver with clock, 2 clock pairs, JTAG.
@item No dedicated clock signals from Carrier to FMC
(only available on HPC pins).
@end itemize
@b{Clocking Resources}:
The SPEC design includes a plethora of clocking sources that can be used
to develop highly precise applications:
@itemize @bullet
@item 1x 10-280 MHz I2C Programmable XO Oscillator, starts up at 100 MHz
(Silicon Labs Si570).
@item 1x 25 MHz TCXO controlled by a DAC with SPI interface (AD5662).
@item 1x 20 MHz VCXO controlled by a DAC with SPI interface (AD5662).
@item 1x low-jitter frequency synthesizer
(TI CDCM61004, fixed configuration, Fout=125 MHz).
@end itemize
@b{On-board Memory}:
The SPEC mounts both volatile and non volatile memory ICs:
@itemize @bullet
@item 1x 2Gbit (256 MByte) DDR3 (MT41J128M16HA-15E).
@item 1x SPI 32Mbit flash PROM for multiboot FPGA powerup configuration,
storage of the FPGA firmware or of critical data.
@end itemize
@b{Miscellaneous}:
The SPEC includes the next extra functionalities:
@itemize @bullet
@item on-board thermometer IC (DS18B20U+).
@item unique 64-bit identifier (DS18B20U+).
@end itemize
@b{Front Panel}:
The mechanical design features a front panel that fits in standard
PCI slots and contains the next items:
@itemize @bullet
@item 1x Small Formfactor Pluggable (SFP) cage for fibre-optic transceiver.
@item Programmable Red and Green LEDs.
@item FMC front panel.
@end itemize
@b{Internal Connectors}:
The next interfaces are available in the SPEC's PCB out of the front panel:
@itemize @bullet
@item 1x JTAG header for Xilinx programming during debugging.
@item 2x SATA connector.
@item 1x mini USB AB (USB-UART bridge).
@end itemize
@b{FPGA configuration}:
The Spartan-6 device can optionally be programmed in different ways that
can be selected by using the GN4124 configurable GPIO:
@itemize @bullet
@item GN4124 SPRIO interface (bitstream loaded by software).
@item JTAG header (bitstream loaded using specific programming hardware).
@item SPI 32Mbit flash PROM.
@end itemize
@b{Stand-alone Features}:
The SPEC board includes different features intended for a better
stand-alone operation:
@itemize @bullet
@item External 12V power supply connector.
@item mini USB connector (USB-UART bridge).
@item 4x auxiliar user LEDs.
@item 2x auxiliar user buttons.
@end itemize
@b{Power Consumption}:
The SPEC board power consumption ranges from 5 to 12 Watt depending on
both the application and the operation mode (stand-alone vs PCIe slave).
@b{Optimised for cost}:
The SPEC's PCB uses a 6-layer stack-up for a cheaper production cost.
@sp 1
@c ==========================================================================
@node PCB Design files
@section PCB Design files
The SPEC design is licensed under the terms of CERN Open Hardware License
(CERN-OHL). In this way, when a SPEC unit is purchased, the user is granted
with full access to all the design files, including:
@itemize @bullet
@item Schematics.
@item PCB layout.
@item Assembly.
@item Manufacturing.
@item Mechanical parts.
@end itemize
The specific version of the CERN-OHL covering the design must be
indicated by the licensor/manufacturer. In order to check the different rights
and responsibilities that CERN-OHL implies for both the licensor and the
licensee, more information can be found in
@url{http://www.ohwr.org/projects/cernohl/wiki}.
@sp 1
The SPEC design files are placed online in the file tab of the official
project website (@url{http://www.ohwr.org/projects/spec/files}).Current SPEC
version is 4.0 and the associated design files can be downloaded by using any
of the next links:
@itemize @bullet
@item @url{http://www.ohwr.org/attachments/download/918/SPEC_V4.tar.bz2}.
@item @url{http://www.ohwr.org/attachments/download/919/SPEC_V4.zip}.
@end itemize
@sp 1
In order to open and modify the SPEC design project, Altium Designer schematic
capture and layout editor tool packages are required. In any case, a complete
documentation set for the design is released in pdf format too.
@center @image{pictures/spec_v2_altium, 10cm}
@center @i{3D view of the SPEC design in Altium Designer}
@sp 1
@b{Note:} in the SPEC project site hosted on OHR you may find a SVN
repository in which some outdated SPEC design files are hosted. If you have
any doubts about the specific design version and associated documentation
that matches your SPEC unit, contact with your SPEC board provider
in order to get more information as granted by CERN-OHL.
@c ==========================================================================
@node FMC interface
@section FMC interface
The SPEC board is designed to act as a carrier for a low pin count (LPC)
FPGA Mezzanine Card (VITA 57).
In order to get more information about the VITA 57.1 FPGA Mezzanine Card
(FMC) standard, visit FMC Projects in the Open Hardware Repository
(@url{http://www.ohwr.org/projects/fmc-projects}). Here, you'll find
which FMC Mezzanines and Carriers are developed in the context of the
Open Hardware Repository project. Furthermore it gives practical info that
can help you in designing custom FMC modules.
@sp 1
In this getting started guide for the SPEC board, two different FMC use
cases will be considered in the demo examples:
@itemize @bullet
@item No FMC module is plugged in.
@item fmc-dio-5chttla (@url{http://www.ohwr.org/projects/fmc-dio-5chttla})
@end itemize
The fmc-dio-5chttla 5-channel digital I/O module has been selected
because its flexibility as a demonstrative platform and because it is
commercially available from different hardware providers. In addition, this
FMC module is licensed under CERN-OHL too.
@center @image{pictures/fmc-dio-5chttla_v2_small, 10cm}
@center @i{Front and top view of the fmc-dio-5chttla module}
@sp 1
@c ==========================================================================
@node Operation Modes
@section Operation Modes
The SPEC board is designed to allow the operation in both stand-alone and
PCIe slave modes. In this getting started guide, we will consider only
the case in which the SPEC board is attached to a PC through the
PCI Express port. This option has been chosed because it doesn't require
additional third-party hardware tools to handle the SPEC and because it
makes the things easier for a newcomer, i.e. the control is on the Host PC
side and the gateware designs can be simplified.
@sp 1
@b{Stand-alone}
The SPEC board can be deployed as an independent stand-alone unit. In order
to enable this operation mode, the Simple PCI Express Carrier includes the
next functionalities:
@itemize @bullet
@item External 12V power supply connector.
@item mini USB connector (USB-UART bridge).
@item 4x auxiliar user LEDs.
@item 2x auxiliar user buttons.
@end itemize
By embedding a soft processor in the Spartan-6 FPGA, the SPEC unit can be
used as a FMC enabled Single Board Computer (SBC). This topic is not
covered in this guide, but the mainstream choice for the most of the projects
in the Open Hardware Repository is deploying a Wishbone bus enabled
LM32 processor. You can find more info about this IP-core and its companion
Wishbone peripherals in the @i{Platform Independent Core Collection} project
on the Open Hardware Repository
@url{http://www.ohwr.org/projects/general-cores/wiki}
In order to program and debug the SPEC board when operating in stand-alone
mode, the recommended third-party tool is Xilinx's @i{Platform Cable USB}
@url{http://www.xilinx.com/products/boards-and-kits/HW-USB-II-G.htm}
@center @image{pictures/xilinx_platform_cable_usb_ii, 10cm}
@center @i{Xilinx Platform Cable USB II}
@sp 1
@b{PCI Express Slave}
The @i{Simple PCI Express Carrier} can act as a PCI Express slave. In order
to do that, the SPEC includes a 4-lane PCIe interface based in the
Gennum GN4124. In this way, you can plug your SPEC board in any PCIe compliant
standard port with x4 lane width or greater (x4, x8, x16 or x32). If the slot
lane width is greater than x4, the Gennum GN4124 and the PC host will
automatically negotiate the highest mutually supported lane count, i.e. x4.
Note that multiple SPEC boards can be attached to a single Host if this sports
multiple x4 compatible PCIe slots. In this getting started guide, only one
available PCIe port will be required as only one SPEC board is used in the
demonstration.
In the next picture, a SPEC board mounting a fmc-dio-5chttla module is
shown while attached to a standard desktop PC PCIe slot. This is
the full hardware setup required to go through all the getting started guide.
@center @image{pictures/spec_pcie_slave, 10cm}
@center @i{SPEC board attached to a PC PCIe port}
@sp 1
@c ##########################################################################
@node Designing your own SPEC Gateware
@chapter Designing your own SPEC Gateware
In this chapter, we will cover the topic of building some simple gateware
examples to be loaded on the SPEC's Spartan-6 FPGA. In order to do that,
we will learn how to design and synthesize a simple Wishbone based embedded
system by using standard and custom HDL cores and specific tools hosted in the
@i{Open Hardware Repository}.
@sp 1
@c ==========================================================================
@node The Wishbone Bus and the OHR Core libraries
@section The Wishbone Bus and the OHR Core libraries
The @b{Wishbone Bus} is an open source hardware computer bus intended to let
the parts of an integrated circuit communicate with each other. The aim is to
allow the connection of differing cores to each other inside of a chip/FPGA.
Initially designed for being used as the standard bus in the OpenCores project,
the @b{Wishbone Bus} is the mainstream bus used in most of the Open Hardware
Repository projects too. In this way, Wishbone provides a standard way for
designers to combine already available generic hardware logic designs
(called "cores") with custom ones designed for application specific purposes.
While Wishbone is defined to have 8, 16, 32, and 64-bit buses, the most of
the cores used in the Open Hardware Repository projects use a 32-bit bus.
This is because the reference processor used in OHR flagship projects is the
LM32 (LatticeMico32), an Open Source 32-bit RISC processor that has been
designed for efficient FPGA implementation.
For an in-depth description of the Wishbone bus internals, you can get the
full Wishbone specification by following the next links:
@itemize @bullet
@item @b{Version B3:} @url{http://cdn.opencores.org/downloads/wbspec_b3.pdf}.
@item @b{Version B4:} @url{http://cdn.opencores.org/downloads/wbspec_b4.pdf}.
@end itemize
@sp 1
In the demos covered by this tutorials, different already available cores from
the Open Hardware Repository are used for building the HDL embedded system
examples. In order to fetch the code of this required core libraries, the
@code{git submodule} mechanism is used.
In order to do that, once the @code{spec-getting-started} repository has been
cloned, we must jump to the main folder inside a shell and execute the next
git command sequence:
@example
user$ cd spec-getting-started
user$ git submodule init
user$ git submodule update
@end example
Once the @code{update} command has finished, two new folders are created in
@code{hdl/ip_cores} directory. These are @code{general-cores} and
@code{gn4124-core}, and their contents are described in the next sections.
@sp 1
@c --------------------------------------------------------------------------
@node The Gennum GN4124 Core
@subsection The Gennum GN4124 Core
When designing a gateware intended to run in the SPEC board while working as
a PCIe slave, deploying an interface between the Gennum GN4124 device and the
FPGA embedded system is a mandatory task.
For this purpose, the @i{gn4124-core} project is included in the
@i{Open Hardware repository}. This project aims to provide a Wishbone master
generic interface for FMC projects controlled by a PCI express access.
The @i{gn4124-core} is used in the @i{Getting Started with the SPEC} demos
in order to communicate from the Host PC to the SPEC board. This is the case
too for all the projects included in the OHR that make use of the Gennum
GN4124 device for building the hardware bridge.
A more detailed description of the @i{gn4124-core} project can be found in
its official OHR project site:
@itemize @bullet
@item @url{http://www.ohwr.org/projects/gn4124-core/wiki}
@end itemize
@sp 1
The @code{git} repository in which the stable code is hosted, can be accessed
by using the next Git Read-Only URL:
@itemize @bullet
@item @url{git://ohwr.org/hdl-core-lib/gn4124-core.git}
@end itemize
@sp 1
@c --------------------------------------------------------------------------
@node The General Cores library
@subsection The General Cores library
The @code{general-cores} project, A.K.A. @i{Platform-Independent Core
Library}, @i{Generic Cores Library} or @i{GenCores} provides a number of
common VHDL components used in various projects hosted in the OHR.
The library comprises 3 different packages:
@itemize @bullet
@item @b{gencores_pkg:} simple cores (synchronizer chain, delay generator,
pulse extender, PI controller, CRC generator, etc.)
@item @b{genrams_pkg:} collection of platform-independent wrappers for RAMs
and FIFOs provided by the FPGA vendors (currently supported: Altera
Cyclone3, Arria 2 GX and Xilinx Spartan6/Virtex6)
@item @b{wishbone_pkg:} set of commonly used Wishbone modules (UART, SPI, I2C,
Onewire, GPIO, Timer, Interrupt controller, LM32 CPU,
Pipelined WB Interconnect)
@end itemize
@sp 1
In the @i{Getting Started with the SPEC} project demos, both
@code{gencores_pkg} and @code{wishbone_pkg}, the first for getting some
simple standard HDL building blocks and the later for a cleaner Wishbone bus
signals handling.
The official project site for @i{general-cores} can be found in the
next OHR link:
@itemize @bullet
@item @url{www.ohwr.org/projects/general-cores/wiki}
@end itemize
@sp 1
The @code{git} repository in which the stable code is hosted, can be accessed
by using the next Git Read-Only URL:
@itemize @bullet
@item @url{git://ohwr.org/hdl-core-lib/general-cores.git}
@end itemize
@sp 1
@c ==========================================================================
@node Building a simple Wishbone Slave
@section Building a simple Wishbone Slave
After reviewing the different HDL core libraries from OHR that are used in the
@i{Getting Started with the SPEC} gateware demos, we must face the issue of
building a new Wishbone compatible custom core from the ground up. While
designing an application specific HDL core is a task that worths the design
effort (e.g. when a new FMC module is going to be handled), linking this core
by hand to the Wishbone bus supposes a non-recurring engineering cost that
should be avoided.
@sp 1
@c --------------------------------------------------------------------------
@node Introducing the Wishbone Slave Generator project
@subsection Introducing the Wishbone Slave Generator project
In order to solve this issue, the @i{Wishbone Slave Generator} project has
been developed inside the @i{Open Hardware Repository} initiative. Current
version of this tool, A.K.A. @code{wbgen2}, allows for generating VHDL/Verilog
cores which implement Wishbone bus slaves with certain registers,
memory blocks, FIFOs and interrupts. The input is a C-like syntax file with
an abstract description of what do we want to have in the slave.
As a result, we get:
@itemize @bullet
@item Customisable register types, with multiple access options and multiple
clocking schemes
@item Configurable memory blocks
@item Peripheral-level interrupts via Embedded Interrupt Controller
@item Generation of VHDL/Verilog synthesizable code
@item Automatic address space layout generation
@item Generation of C header files containing memory map consistent with the
HDL core
@item Support for popular synthesizable VHDL data types
@end itemize
@sp 1
In this way, when a slave core is generated we get an HDL black-box in which
the primitives are accessible from outside as VHDL/Verilog signals, both the
Wishbone bus interface and the user defined ones.
@center @image{pictures/slavecore, 14cm}
@center @i{General tructure for a slave core generated by wbgen2}
@sp 1
More information about the @i{Wishbone Slave Generator} can be found in the
official OHR project site:
@itemize @bullet
@item @url{http://www.ohwr.org/projects/wishbone-gen/wiki}
@end itemize
@sp 1
@code{wbgen2} is actively used accross the OHR repository, and this is the
case for the custom demo cores in the Getting Started with the SPEC examples.
In the next sections, the Wishbone generator descriptions for the different
demo slave cores will be introduced, but we must learn how to install this
tool as a previous step.
@sp 1
@c --------------------------------------------------------------------------
@node Installing the Wishbone Slave Generator wbgen2 tool
@subsection Installing the Wishbone Slave Generator wbgen2 tool
The stable code for the @code{wbgen2} can found in the @code{git} repository
tab in the @i{Wishbone Slave Generator} project. In this section, we will
download, build and deploy the tool.
First of all, we need to install the @code{wbgen2} dependencies. This tool
is written in @i{lua} language, so we need to install the appropriated
software packages for our Linux distribution.
In the current Ubuntu Linux and other Debian derivatives, this can be made
by issuing the next apt command in a shell:
@example
user$ sudo apt-get install lua5.1
@end example
In Red Hat Enterprise Linux derivatives, such as Scientific Linux,
this can be made by issuing the next yum command in a shell:
@example
root$ yum install lua
@end example
Once we have this package installed, we can clone and build the @code{wbgen2}.
For this purpose, we place ourselves in the workspace folder in which we
want to deploy the tool and execute:
@example
user$ git clone git://ohwr.org/hdl-core-lib/wishbone-gen.git
user$ cd wishbone-gen
user$ make
@end example
After building the tool, the @code{wbgen2} binary is available inside the
@code{wishbone-gen} folder. Next step is including it inside the user
shell path. For this purpose, and being the tag @i{<wishbone-gen dir>} the
absolute path to the @code{wishbone-gen} folder, we will need to export
the directory with the next command:
@example
user$ export PATH=$PATH:<wishbone-gen dir>
@end example
This must be exported everytime we are going to use the @code{wbgen2} tool or,
alternatively, can be appended at the end of the @code{.bashrc} file for
every user in the system that is going to run the tool.
@c ==========================================================================
@node Code overview of the SPEC Demo HDL examples
@section Code overview of the SPEC Demo HDL examples
In this section, we will review the code structure for the @i{Getting Started
with the SPEC} HDL examples. First of all, we must note that the HDL code
includes two different examples:
@itemize @bullet
@item @b{Demo User:} this demo makes basic SPEC features accessible throughout
the Wishbone to GN4124 bridge.
@item @b{Demo User + DIO:} this demo expands the Demo User functionality by
providing a very simple interface to the FMC DIO 5Ch TTL module.
@end itemize
In this way, the @i{Getting Started with the SPEC} allows both the use of a
standalone SPEC board and the handling of the Digital I/O FMC when available.
@sp 1
The directory layout for the provided HDL code is shown in the next scheme:
@itemize @minus
@item @code{spec-getting-started/}.
@itemize @minus
@item @code{hdl/}
@itemize @minus
@item @code{ip_cores/}
@itemize @minus
@item @code{general-cores/}
@item @code{gn4124-core/}
@end itemize
@item @code{modules/}
@itemize @minus
@item @code{reset_generator/}
@item @code{spec_user_interface/}
@item @code{fmc_dio_ch5_ttl/}
@end itemize
@item @code{syn/}
@itemize @minus
@item @code{spec/}
@itemize @minus
@item @code{demo_user/}
@item @code{demo_user+dio/}
@end itemize
@end itemize
@item @code{top/}
@itemize @minus
@item @code{spec/}
@itemize @minus
@item @code{demo_user/}
@item @code{demo_user+dio/}
@end itemize
@end itemize
@end itemize
@end itemize
@end itemize
@sp 1
The purpose for each of these folders is:
@table @file
@item ip_cores/
The directory hosts the cores that are fetched from already
available OHR libraries. In both of the demos, the @code{gn4124-core}
and some elements from @code{general-cores} are required, as
previously explained when the Wishbone architecture has been presented.
@item modules/
The directory hosts the custom cores that has been specifically
designed for being used in the @i{Getting Started with the SPEC}
demos. Both @code{reset_generator} and @code{spec_user_interface} are
used in the two different demos, but @code{fmc_dio_ch5_ttl} is only
required by the demo supporting the Digital I/O FMC module.
@item top/
The directory hosts the top level design files for both of the demo
designs, that are placed in independent folders. In each of the demo
specific folders, we will find a VHDL @code{spec_top.vhd} file that
specifies the top level entity architecture, and a Xilinx user
constraints @code{spec_top.ucf} file that properly assigns the
top port signals to the physical pins in the Spartan-6 FPGA.
@item syn/
This directory is intended to host the full bitstream synthesis
process, including an independent folder for each of the demos.
In the demo specific folders we can find the information that is
required for running an automated synthesis, as will be explained
later when introducing the gateware building process.
@end table
@sp 1
@c --------------------------------------------------------------------------
@node The SPEC Demo User gateware
@subsection The SPEC Demo User gateware
The Demo User gateware exposes basic SPEC board functions throughout the
Gennum GN4124 bridge by mapping some custom registers in the Wishbone bus.
By using this HDL design, we can control the Green/Red LEDs in the SPEC front
panel, read the SPEC PCB version or access to the internal pushbuttons and
LEDs.
In order to do this, the Demo User includes the @code{spec_user_interface}
custom core, that has been implemented by using the
@i{Wishbone Slave Generator} tool. The most important files that can be found
inside this module directory are:
@table @file
@item build_wb.sh
A simple shell script including the @code{wbgen2} commands for
generating both the VHDL Wishbone slave core and its documentation
in texinfo and html format from the @i{Wishbone Slave Generator}
description file.
@item spec_user_interface.wb
The @i{Wishbone Slave Generator} description file in which the
different register primitives for handling the basic SPEC board
functions are indicated.
@item spec_user_interface.vhd
The actual Wishbone slave VHDL code that is automatically generated
by @code{wbgen2} from the @i{Wishbone Slave Generator} description
file.
@end table
@sp 1
In the rest of this subsection, the memory map summary and the role of each of
the Wishbone registers that @code{spec_user_interface} exposes are detailed.
@sp 1
@b{Memory map summary}
@multitable @columnfractions .10 .15 .15 .55
@headitem Address @tab Type @tab Prefix @tab Name
@item @code{0x0} @tab
REG @tab
@code{ctrl} @tab
Control register
@item @code{0x4} @tab
REG @tab
@code{aux} @tab
Auxiliar interface
@end multitable
@sp 1
@b{@code{ctrl} - Control register}
A register containing basic SPEC controls
@multitable @columnfractions .10 .10 .15 .10 .55
@headitem Bits @tab Access @tab Prefix @tab Default @tab Name
@item @code{3...0}
@tab R/O @tab
@code{VER}
@tab @code{X} @tab
PCB Version
@item @code{4}
@tab R/W @tab
@code{LED_GREEN}
@tab @code{0} @tab
Front panel green LED
@item @code{5}
@tab R/W @tab
@code{LED_RED}
@tab @code{0} @tab
Front panel red LED
@end multitable
@multitable @columnfractions 0.15 0.85
@headitem Field @tab Description
@item @code{ver} @tab This field accesses to the hard-wired 4 bits that
indicate the PCB version
@item @code{led_green} @tab Control bit for the green LED placed on the SPEC
front panel
@item @code{led_red} @tab Control bit for the red LED placed on the SPEC front
panel
@end multitable
@sp 1
@b{@code{aux} - Auxiliar interface}
A register mapping the SPEC internal auxiliar interface
@multitable @columnfractions .10 .10 .15 .10 .55
@headitem Bits @tab Access @tab Prefix @tab Default @tab Name
@item @code{0}
@tab R/O @tab
@code{BUTTON1}
@tab @code{X} @tab
User Push-button 1
@item @code{1}
@tab R/O @tab
@code{BUTTON2}
@tab @code{X} @tab
User Push-button 2
@item @code{5...2}
@tab R/W @tab
@code{LEDS}
@tab @code{0} @tab
User Leds
@end multitable
@multitable @columnfractions 0.15 0.85
@headitem Field @tab Description
@item @code{button1} @tab Status bit for the internal push-button 1
@item @code{button2} @tab Status bit for the internal push-button 2
@item @code{leds} @tab Control field for the 4 internal auxiliar LEDs
@end multitable
@sp 1
@c --------------------------------------------------------------------------
@node The SPEC Demo User + DIO gateware
@subsection The SPEC Demo User + DIO gateware
The SPEC Demo User + DIO demo expands the Demo User functionality by
providing a very simple interface to the FMC DIO 5Ch TTL module. In this
way, in addition to the basic SPEC controls provided by Demo User, a set
of registers handling the Digital I/O module are exposed in the Wishbone bus.
By accessing to these registers, we can configure the DIO pin direction,
read/write each pin value or configure the termination resistor. In addition,
the Top/Bottom LEDs in the FMC DIO front panel can be controlled too.
In order to do this, the Demo User + DIO adds to the previous demo Wishbone bus
a new @code{fmc_dio_ch5_ttl} custom core that has been implemented by using
the @i{Wishbone Slave Generator} tool. The most important files that can be
found inside this module directory are:
@table @file
@item build_wb.sh
A simple shell script including the @code{wbgen2} commands for
generating both the VHDL Wishbone slave core and its documentation
in texinfo and html format from the @i{Wishbone Slave Generator}
description file.
@item wb_slave_fmc_dio_ch5_ttl.wb
The @i{Wishbone Slave Generator} description file in which the
different register primitives for handling the basic DIO FMC
functions are indicated.
@item wb_slave_fmc_dio_ch5_ttl.vhd
The actual Wishbone slave VHDL code that is automatically generated
by @code{wbgen2} from the @i{Wishbone Slave Generator} description
file.
@item fmc_dio_ch5_ttl.vhd
A VHDL interface that connects the Wishbone slave registers to the
FPGA pinout. This code includes the Wishbone slave as a component
and is the file that is actually instantiated from the top level
design VHDL description.
@end table
@sp 1
In the rest of this subsection, the memory map summary and the role of each of
the Wishbone registers that @code{fmc_dio_ch5_ttl} exposes are detailed.
Note that in the Demo User + DIO, a basic Wishbone bus multiplexor is
implemented in order to allow the access to both the @code{fmc_dio_ch5_ttl}
and the @code{spec_user_interface} cores from the GN4124 bridge. In this, way
the DIO FMC registers are placed at the @code{0x100} base address, while
the SPEC user interface remains at @code{0x000} base address.
@sp 1
@b{Memory map summary}
@b{Base Address:} @code{0x100}
@multitable @columnfractions .10 .15 .15 .55
@headitem Address @tab Type @tab Prefix @tab Name
@item @code{0x0} @tab
REG @tab
@code{ddr} @tab
Pin direction register
@item @code{0x4} @tab
REG @tab
@code{psr} @tab
Pin state register
@item @code{0x8} @tab
REG @tab
@code{pdr} @tab
Pin output register
@item @code{0xc} @tab
REG @tab
@code{term} @tab
Pin termination register
@item @code{0x10} @tab
REG @tab
@code{sopr} @tab
Set output pin register
@item @code{0x14} @tab
REG @tab
@code{copr} @tab
Clear output pin register
@item @code{0x20} @tab
REG @tab
@code{leds} @tab
LED signaling interface
@end multitable
@sp 1
@b{@code{ddr} - Pin direction register}
A register defining the direction of the DIO pins.
@multitable @columnfractions .10 .10 .15 .10 .55
@headitem Bits @tab Access @tab Prefix @tab Default @tab Name
@item @code{4...0}
@tab R/W @tab
@code{DDR}
@tab @code{0} @tab
Pin directions
@end multitable
@multitable @columnfractions 0.15 0.85
@headitem Field @tab Description
@item @code{ddr} @tab Each bit in this register defines the direction of the
corresponding pin in the DIO. 1 means the pin is an OUTPUT, 0 means the pin
is an INPUT
@end multitable
@sp 1
@b{@code{psr} - Pin state register}
A register containing the current state of the DIO pins.
@multitable @columnfractions .10 .10 .15 .10 .55
@headitem Bits @tab Access @tab Prefix @tab Default @tab Name
@item @code{4...0}
@tab R/O @tab
@code{PSR}
@tab @code{X} @tab
Pin input state
@end multitable
@multitable @columnfractions 0.15 0.85
@headitem Field @tab Description
@item @code{psr} @tab Each bit in this register reflects the state of the
corresponding pin in the DIO. 1 means the pin is HIGH, 0 means the pin is LOW
@end multitable
@sp 1
@b{@code{pdr} - Pin output register}
A register that allows changing the value of the DIO pins by means of a
direct write access
@multitable @columnfractions .10 .10 .15 .10 .55
@headitem Bits @tab Access @tab Prefix @tab Default @tab Name
@item @code{4...0}
@tab W/O @tab
@code{PDR}
@tab @code{0} @tab
Pin output value
@end multitable
@sp 1
@b{@code{term} - Pin termination register}
A register defining the use of the 50 Ohm termination
@multitable @columnfractions .10 .10 .15 .10 .55
@headitem Bits @tab Access @tab Prefix @tab Default @tab Name
@item @code{4...0}
@tab R/W @tab
@code{TERM}
@tab @code{0} @tab
Pin terminations
@end multitable
@multitable @columnfractions 0.15 0.85
@headitem Field @tab Description
@item @code{term} @tab Writing '1' activates the termination resistor
@end multitable
@sp 1
@b{@code{sopr} - Set output pin register}
Writing '1' sets the corresponding DIO pin to '1'
@multitable @columnfractions .10 .10 .15 .10 .55
@headitem Bits @tab Access @tab Prefix @tab Default @tab Name
@item @code{4...0}
@tab W/O @tab
@code{SOPR}
@tab @code{0} @tab
Set output pin register
@end multitable
@sp 1
@b{@code{copr} - Clear output pin register}
Writing '1' clears the corresponding DIO pin
@multitable @columnfractions .10 .10 .15 .10 .55
@headitem Bits @tab Access @tab Prefix @tab Default @tab Name
@item @code{4...0}
@tab W/O @tab
@code{COPR}
@tab @code{0} @tab
Clear output pin register
@end multitable
@sp 1
@b{@code{leds} - LED signaling interface}
Writing '1' activates the corresponding LED
@multitable @columnfractions .10 .10 .15 .10 .55
@headitem Bits @tab Access @tab Prefix @tab Default @tab Name
@item @code{0}
@tab R/W @tab
@code{BOT}
@tab @code{0} @tab
FMC DIO Bottom LED
@item @code{1}
@tab R/W @tab
@code{TOP}
@tab @code{0} @tab
FMC DIO Top LED
@end multitable
@multitable @columnfractions 0.15 0.85
@headitem Field @tab Description
@item @code{bot} @tab Control bit for the bottom LED placed on the FMC DIO
front panel
@item @code{top} @tab Control bit for the top LED placed on the FMC DIO
front panel
@end multitable
@sp 1
@c ==========================================================================
@node Compiling the HDL demos
@section Compiling the HDL demos
In this section, the process of building a bitstream from the HDL code is
explained. In order to do this, we are going to use two different tools,
the @i{Xilinx ISE Design Software} and the OHR's @i{HDLMake}.
@sp 1
@c --------------------------------------------------------------------------
@node Installing the Xilinx ISE Design Software
@subsection Installing the Xilinx ISE Design Software
In order to synthesize, map, place & route and generate the bitstream
for the Xilinx Spartan-6 FPGA, we need the Xilinx ISE proprietary
toolchain. The good news are that the specific Spartan-6 XC6SLX45T-3FGG484C
device mounted by the SPEC board is supported by the @i{ISE WebPACK} edition,
a free, fully featured front-to-back FPGA design solution for Linux and
Windows.
In this way, before building our gateware desigs, we need to download and
install the @i{ISE WebPACK Design Software for Linux}, that can be found in
the next link:
@url{www.xilinx.com/products/design-tools/ise-design-suite/ise-webpack.htm}.
The install binary for Linux supports both 32 and 64 bits Operating Systems,
and is compatible with mainstream Linux distributions right out-of-the-box.
This include both Debian derivatives such as Ubuntu and RHEL derivatives
such as Scientific Linux.
Note that, once the ISE software has been installed, pointing to a valid
WebPACK license file is mandatory before running any of the Xilinx tools.
You can request a WebPACK license by using a valid Xilinx registration
account in the next link: @url{http://www.xilinx.com/getlicense}
@sp 1
When working in Linux environments, we need to update the shell configuration
with the appropriated Xilinx toolchain information before using any of the
tools included in the Xilinx ISE Design Software. In order to do this, we
need to @code{source} the ISE settings file that matches with our
Operating System shell and processor architecture.
As an example, when the ISE Design Software had been installed in the default
path and the ISE version was 14.7, the command required to load the settings
in a 32 bits Operating System would be:
@example
user$ source /opt/Xilinx/14.7/ISE_DS/settings.sh
@end example
while in a 64 bits Operating System this would be:
@example
user$ source /opt/Xilinx/14.7/ISE_DS/settings64.sh
@end example
If we want to avoid launching this command everytime we start a shell
terminal, we can append it to the end of the @code{.bashrc} file placed in
our user home directory.
@sp 1
@c --------------------------------------------------------------------------
@node Automated synthesis with HDLMake
@subsection Automated synthesis with HDLMake
Despite the fact that Xilinx ISE includes very powerful graphic user interface
tools, sometimes we feel that working with HDL code just in the way we do
with software code will be very handy. For this purpose, the @i{HDLMake}
project has been created inside the @i{Open Hardware Repository} initiative.
Hdlmake generates multi-purpose makefiles for FPGA projects. It supports local
and remote synthesis, simulation, fetching module dependencies from
repositories, creating Quartus/ISE project files. All of this can be done
with a makefile command or with Hdlmake directly. It supports modularity,
scalability, use of revision control systems and code reuse.
In order to get more information about Hdlmake, you can visit the official
project site hosted on the @i{Open Hardware Repository}.
@itemize @bullet
@item @url{http://www.ohwr.org/projects/hdl-make/wiki}
@end itemize
@sp 1
@b{NOTE}: Current Hdlmake version is under heavy development. For this reason,
we will use an older but stable Hdlmake release for synthesizing our demos.
@sp 1
As Hdlmake is written as a Python application, before installing and running
Hdlmake, a valid Python distribution must be available on the Operating System.
Python is included as an off-the-shelf basic package in almost all of the
mainstream Linux distribution, so this shouldn't be a problem.
Once this requisite is met, we can clone and build @code{Hdlmake}.
For this purpose, we place ourselves in the workspace folder in which we
want to deploy the tool and execute:
@example
user$ git clone -b isyp git://ohwr.org/misc/hdl-make.git
user$ cd hdl-make
user$ make
@end example
After building, the @code{hdlmake} Python app is available inside the
@code{hdl-make} folder. Next step is including it inside the user
shell path. For this purpose, and being the tag @i{<hdl-make dir>} the
absolute path to the @code{hdl-make} folder, we will need to export
the directory with the next command:
@example
user$ export PATH=$PATH:<hdl-make dir>
@end example
This must be exported everytime we are going to use the @code{wbgen2} tool or,
alternatively, can be appended at the end of the @code{.bashrc} file for
every user in the system that is going to run the tool.
@sp 1
@c --------------------------------------------------------------------------
@node FPGA bitstream generation
@subsection FPGA bitstream generation
Once both the Xilinx ISE and Hdlmake tools are available from a user shell,
we are ready to run the automated synthesis process. For this purpose, we
should go to the specific @code{syn/} folder associated to the demo that is
going to be synthesized.
In order to exemplify this, we are going to detail the steps for building
the Demo User gateware. For building the Demo User + DIO, the process is
exactly the same.
@example
user$ cd spec-getting-started/hdl/syn/spec/demo_user
@end example
@sp 1
Inside this folder, we can see that a @file{Manifest.py} file is placed.
Similar files can be found across the whole @file{hdl/} directory, as these
are used by Hdlmake in order to get information about the synthesis process,
from pointing to the HDL packages/files that must be included to specifying
the parameters of the target hardware.
The @file{Manifest.py} placed in the @file{syn} folder contains all the
required information for generating a new @file{spec_top.xise} Xilinx ISE
project and a companion @file{Makefile} from the ground up. In order to do
this, we must execute:
@example
user$ hdlmake --make-ise --ise-proj
@end example
@sp 1
If we open the @file{spec_top.xise} with a text editor, we will check that
this contains only very basic information (Note that we could open this
project with the Xilinx ISE graphic interface, but this is not necessary when
working with Hdlmake).
Once we have a valid @file{Makefile} and @file{spec_top.xise} ISE project,
we are ready to generate the bitstream by just launching a @file{make}
command:
@example
user$ make
@end example
@sp 1
This process can take some minutes depending on the Host CPU speed and the
complexity of the HDL design synthesized. Once the synthesis, map, P&R...
processes have finished, we have a lot of new files in our folder, including
a @file{spec_top.bit} bitstream that can be loaded into the SPEC board
by using Xilinx programmer.
@sp 1
In order to generate an additional @file{spec_top.bin} bitstream file that
can be loaded to the FPGA throughout the PCI Express bridge, we need to open
the @file{spec_top.xise} project file in a text editor. By doing this, we can
check that a lot of new configuration parameters have been added to the
project file in the first synthesis run.
Once the @file{spec_top.xise} is opened, we must search the @code{Create Binary
Configuration File} property and change its value from @code{false} to
@code{true}. Then, by just executing @code{make} again, the @file{spec_top.bin}
will be generated too.
Now that we have a valid @file{spec_top.bin} file, we can jump to the software
side in order to program and control the SPEC board from the Host user space.
@sp 1
@c ##########################################################################
@node SPEC control from the Host user-space
@chapter SPEC control from the Host user-space
In this chapter we will learn how to control a SPEC board attached to the
PCIe slot of the a Linux Host PC. For this purpose, we will introduce the
official OHR software support for the SPEC project and the user-space tools
it provides, will learn how to get direct access to the SPEC address space
by using the Sysfs PCI bus interface and will interactively handle the SPEC
board from a Python environment.
@sp 1
@c ==========================================================================
@node Software support for the SPEC board
@section Software support for the SPEC board
The software companion of the @i{Simple PCI Express Carrier} in the OHR is the
@i{Software support for the SPEC board} project, A.K.A. @i{spec-sw}. This
software package is a complete solution including kernel and user-space Linux
code, and is actively used by the most important SPEC based projects hosted
in the @i{Open Hardware Repository}.
In the @i{Getting Started with the SPEC} project demos, we will use the
user-space Linux code side of the @i{spec-sw} package, as the kernel support
is not mandatory for basic SPEC handling and is intended for most advanced
designs. In addition, by not using the kernel code, we can deploy and run
the SPEC demos in a wider spectrum of Linux distributions, as building
the kernel modules in the @i{spec-sw} package requires kernel versions
greater than 2.6.36 (e.g. current version of Red Hat Enterprise Linux and
its derivatives include kernel 2.6.32 by default).
In order to get more information about the @i{Software support for the SPEC
board} project, you can visit its official site in the OHR:
@itemize @bullet
@item @url{http://www.ohwr.org/projects/spec-sw/wiki}
@end itemize
@sp 1
@c --------------------------------------------------------------------------
@node Accessing the SPEC from sysfs
@subsection Accessing the SPEC from sysfs
Before going deeper into how we can handle the SPEC board from a Linux Host,
we must clarify the mechanism in which the SPEC is identified by the PCI
system. In a Linux Operating System, this task is performed by the @i{Sysfs}
virtual filesystem, which exports information about devices and drivers from
the kernel device model to user space.
In order to access a SPEC board attached to a PCI Express slot of a Host, we
must check the devices that are present in the PCI bus. This is an example of
what we can expect to find inside the @i{Sysfs} path in which the PCI bus
devices are exported:
@example
user$ ls /sys/bus/pci/devices/
0000:00:00.0 0000:00:1c.0 0000:00:1d.0 0000:01:00.0 0000:06:00.0
0000:00:01.0 0000:00:1c.4 0000:00:1f.0 0000:01:00.1
0000:00:16.0 0000:00:1c.5 0000:00:1f.2 0000:02:00.0
0000:00:1a.0 0000:00:1c.6 0000:00:1f.3 0000:04:00.0
0000:00:1b.0 0000:00:1c.7 0000:00:1f.5 0000:05:00.0
@end example
Each one of the PCI devices listed, can be pointed in the PCI system by the
@i{bus} and @i{devfn} numbers. e.g. if we knew that our SPEC board is in the
@code{0000:02:00.0} folder, the associated values would be @i{bus}=0x02 and
@i{devfn}=0x00.
@sp 1
The only way of checking if a PCI device at the @i{Sysfs} PCI system is a
SPEC board, is checking the content of its associated @file{device} and
@file{vendor} files. If these values match with the known identifiers for
the SPEC board, then we know that the PCI device is actually a SPEC board.
e.g.:
@example
user$ cat /sys/bus/pci/devices/0000\:02\:00.0/device
0x018d
user$ cat /sys/bus/pci/devices/0000\:02\:00.0/vendor
0x10dc
@end example
@sp 1
There are two different sets of identifiers associated to the SPEC board,
so we must note that we can potentially find any of them for a given SPEC.
@itemize @bullet
@item @b{Newer SPEC PCB Versions:}
@itemize @minus
@item @code{PCI_VENDOR_ID_CERN = 0x10dc}
@item @code{PCI_DEVICE_ID_SPEC = 0x018d}
@end itemize
@item @b{Older SPEC PCB Versions:}
@itemize @minus
@item @code{PCI_VENDOR_ID_GENNUM = 0x1a39}
@item @code{PCI_DEVICE_ID_GN4124 = 0x0004}
@end itemize
@end itemize
@sp 1
So, in our example, we would have verified that the PCI device at
@code{0000:02:00.0} folder is one of the newer SPEC boards.
@sp 1
Finally, once we have identified a SPEC board in the @i{Sysfs} PCI bus,
we can explore the content of its interface:
@example
user$ ls /sys/bus/pci/devices/0000\:02\:00.0
broken_parity_status enable power subsystem
class fmc-0200 remove subsystem_device
config irq rescan subsystem_vendor
consistent_dma_mask_bits local_cpulist reset uevent
d3cold_allowed local_cpus resource vendor
device modalias resource0
dma_mask_bits msi_bus resource2
driver numa_node resource4
@end example
@sp 1
From the user-space point of view, the most important files in the exported
@i{Sysfs} folder for the SPEC board are the @file{resource0} and
@file{resource4} files.
@table @file
@item resource0
This is the Base Address Register 0 area (BAR0). In this resource,
the FPGA Wishbone bus registers are mapped. By accessing to this
area, we can control the internal FPGA embedded system from the
gn4124-core Wishbone master.
@item resource4
This is the Base Address Register 4 area (BAR4). In this resource,
the internal Gennum GN4124 control registers are mapped. By accessing
to this area, we can perform system control tasks such as choosing
the boot mode or loading a new bitstream in the FPGA.
@end table
@sp 1
In this way, by memory mapping this files in any programming language,
e.g. C, Python, we can control any SPEC board functionality by performing
low level acesses to the different mapped registers. In the next sections,
we will introduce how we can use the @i{spec-sw} user-space code for a
higher level operation.
@sp 1
@b{NOTE:} by default, the access to the @i{Sysfs} devices, including
@file{resource0} and @file{resource4} files, requires super user privileges.
@sp 1
@c --------------------------------------------------------------------------
@node Installing the SPEC-SW package
@subsection Installing the SPEC-SW package
In order to install the @i{spec-sw} user-space tools, we need to clone the full
repository, but then we only need to build the user-space code placed in the
@file{spec-sw/tools} folder.
@sp 1
@b{NOTE}: As part of the @i{Getting Started with the SPEC} development, the
@i{spec-sw} code has been upgraded in order to support a fully kernel
independent operation. In addition, the building process has been modified
in order to generate a @file{libspec.so} shared object library from the
standard and already available @file{libspec.a} static library. Both of this
new features are required in the @i{Getting Started with the SPEC} demos, so
until being merged into main @i{spec-sw} git repository, we will point to the
development branch in which these have been introduced and tested.
@sp 1
@example
user$ git clone -b jdgl-140206 git://ohwr.org/fmc-projects/spec/spec-sw.git
user$ cd spec-sw/tools
user$ make
@end example
@sp 1
Once the build process has finished, the user-space tools and libraries
can be found inside the @file{spec-sw/tools} folder. Now, if we want to
execute some of these applications, we must remember that @b{super user
privileges} are required by default in order to access to the SPEC resources.
In this way, if the @i{Sysfs} SPEC device permissions are not changed, we
can use both the @i{root} account or the @code{sudo} command for direct access
from inside the @file{spec-sw/tools} folder. e.g.
@example
user$ cd spec-sw/tools
user$ sudo ./specmem 0x04
user$ su
root# ./specmem 0x04 0xff
@end example
@sp 1
If we want to add the @file{spec-sw/tools} folder to the execution path,
we must issue the next command, considering that the tag
@i{<spec-sw/tools dir>} is the absolute path to this folder.
@example
user$ export PATH=$PATH:<spec-sw/tools dir>
root# export PATH=$PATH:<spec-sw/tools dir>
@end example
If we want this path to be included everytime a new shell instance is created,
we must append the export command to the end of the @file{.bashrc} file in the
user folder and, if desired, to the root one.
@sp 1
@b{Note}: in some Linux distributions, in order to make the extended user path
available when using a sudo command, we need to edit the @file{/etc/sudoers}
file by using @file{visudo} and comment out the next line if present:
@example
Defaults secure_path="..."
@end example
@sp 1
@c --------------------------------------------------------------------------
@node The SPEC-SW user-space tools
@subsection The SPEC-SW user-space tools
The @i{tools} subdirectory of the @file{spec-sw} includes a few host-side
programs that may be useful while working with the SPEC device.
They are all based on the same @i{speclib}, part of the same directory,
so all of them accept some parameters in common, in order to identify
one specific SPEC card if you have more than one:
@table @code
@item -b <bus>
This option specifies the bus number
@item -d <devfn>
This is used to specify the device and function number, but it
is expected to be 0 on most if not all the computers. You won't
generally need to specify the @i{devfn} value.
@end table
If no arguments are supplied, the tools act on the @i{first} device
if more than one is plugged. The meaning of @i{first} is actually undefined
and system-dependent.
From the set of userspace tools, these are the most interesting ones when
working in simple gateware designs such as the included in the @i{Getting
Started with the SPEC} project:
@table @i
@item specmem
The program acts like @i{devmem} or @i{devmem2} but in a
simplified way. It receives one or two command line arguments:
one for reading and two for writing. Both arguments are used
as hex numbers, whether or not the leading @code{0x} is
specified. The program makes a single 32-bit
access to BAR0 of the Gennum PCI bridge; the first argument is
the address, and the second argument is the value to be written.
The @code{VERBOSE} environment variable makes the tool slightly
more verbose. If you pass @code{-g} you will access the Gennum
registers (for example, for GPIO access).
@item spec-fwloader
This is a user-space loader for the gateware file. It simply
receives a file name argument (after the optional bus number for
the device).
@end table
@sp 1
In this way, by using these tools, we can take the previously generated
@file{spec_top.bin} bitstream files and load it to the FPGA from the
shell. Then, we can perform direct Read/Write access to the mapped Wishbone
registers in order to control the internal registers of our design.
@c ==========================================================================
@node Interactive control of the SPEC board from Python
@section Interactive control of the SPEC board from Python
The @i{Getting Started with the SPEC} project includes a set of Python
files that has been designed for demonstrating how a SPEC board can be handled
in an interactive way from a Python shell. In order to do that, the code
includes a collection of @i{Python classes} that can be used to create SPEC
objects in which different high level methods has been defined.
@sp 1
The directory layout for the provided Python code is shown in the next scheme:
@itemize @minus
@item @code{spec-getting-started/}.
@itemize @minus
@item @code{sw/}
@itemize @minus
@item @code{python/}
@itemize @minus
@item @code{spec_libc.py}
@item @code{spec_demo_user.py}
@item @code{spec_user_user_dio.py}
@end itemize
@end itemize
@end itemize
@end itemize
@sp 1
The specific role for each of these Python files is the next.
@table @file
@item spec_libc.py
This Python package defines a general purpose Spec() Python class.
The Spec() class requires the @file{spec-sw/tools/libspec.so} dynamic
shared library and imports the basic @i{speclib} library methods
from C to Python Language. This class provides general methods for
both loading a bitstream into the FPGA and accessing the user Wishbone
registers by using 32-bit and bitwise operations.
@item spec_demo_user.py
This Python package defines the SpecDemoUser() Python class, which
inherits the Spec() class and includes specific methods for handling
the functionalities included in the user interface defined by the
@i{Spec Demo User gateware}.
@item spec_demo_user_dio.py
This Python package defines the SpecDemoUserDIO() Python class, which
inherits the Spec() and SpecDemoUser() classes and adds specific
methods for handling the Digital I/O functionalities exposed in the
@i{Spec Demo User+DIO gateware}.
@end table
@sp 1
The Python code in @i{Getting Started with the SPEC} project has been designed
for being @b{compatible with both Python 2.x and Python 3.x}. In this way, the
Python classes has been heavily tested on Python 2.7.6 and Python 3.3.3.
@sp 1
Note that, in order to run the demos, we must open a shell inside the
@file{spec-getting-started/sw/python} folder. Once placed in this folder, we
must run a Python 2.x or 3.x interactive session with
@b{super-user privileges}. For doing this, we can alternatively run:
@example
user$ sudo python
user$ sudo python3
@end example
@sp 1
As being a key component of the base Spec() Python class, from which the other
demo classes inherit, we must provide a valid @file{libspec.so} library
when creating any of the objects included in the
@i{Getting Started with the SPEC} project. In order to do this, we can specify
the path to a valid @file{libspec.so} as a parameter every time a new object
is created or we can just copy the @file{libspec.so} into the @file{/usr/lib/}
folder, in which the Spec() class searchs for the library by default.
@example
user$ sudo cp spec-sw/tools/libspec.so /usr/lib/
@end example
@sp 1
@b{Note}: in the next demos, we will assume that a valid @file{libspec.so}
library is placed into the @file{/usr/lib/} folder.
@sp 1
@c --------------------------------------------------------------------------
@node The Spec() Python class
@subsection The Spec() Python class
In this section, we are going to explain by example how the Spec() Python
class must be used from the interactive Python 2/3 shell. In this way, we
will create a new Spec() object, then we will load the bitstream binary
for the Spec Demo User gateware, toggle the Red and Green LEDs in the SPEC
front panel and finally destroy the Spec() object.
@sp 1
Note that we have included a @code{help(spec)} in our example. By doing this,
we get printed in the Python shell the help for all the methods included on
Spec() class (push 'q' for exit).
@sp 1
@example
>>> from spec_libc import *
>>> spec = Spec()
a new SPEC object has been created
>>> spec.specLoadBitstream('../../hdl/syn/spec/demo_user/spec_top.bin')
the bitstream has been found...
the bitstream has been successfully loaded
>>> spec.specToggleBit(0x0, 5)
>>> spec.specToggleBit(0x0, 5)
>>> spec.specToggleBit(0x0, 4)
>>> spec.specToggleBit(0x0, 4)
>>> help(spec)
>>> del(spec)
The SPEC object has been destroyed
@end example
@sp 1
@code{@b{Help on Spec in module spec_libc object:}}
@example
class Spec(builtins.object)
| A Class that creates SPEC objects. This includes basic controls
| and methods in order to handle a PCIe attached SPEC board.
| Access to a valid libspec.so is mandatory for a proper operation.
| NOTE: user write/access permission to the SPEC dev is mandatory.
|
| Attributes:
| bus, dev bus and device for the requested SPEC device.
| If one (or both) parameters are < 0,
| takes first available card.
| libc Path to a valid libspec.so shared library.
| If empty, it points to /usr/lib/libspec.so
|
| Methods defined here:
|
| __del__(self)
| Destroying the SPEC card object
|
| __init__(self, bus=-1, dev=-1, libc='/usr/lib/libspec.so')
|
| specClearBit(self, address, offset)
| Clear to 0 the bit placed at offset in the register at address
|
| specLoadBitstream(self, bitstream)
| Load a new bitstream into the SPEC throughout GN4124 interface.
| bitstream is the path to the .bin bitstream that must be loaded.
|
| specReadL(self, address, hexformat=True)
| Read a 32 bit integer data from the register at address.
| Return an hex string if hexformat=True, an integer otherwise
|
| specSetBit(self, address, offset)
| Set to 1 the bit placed at offset in the register at address
|
| specTestBit(self, address, offset)
| Test the bit placed at offset in the register at address.
| returns a nonzero result, 2**offset, if the bit is 1
|
| specToggleBit(self, address, offset)
| Toggle/invert the bit placed at offset in the register at address
|
| specWriteL(self, address, data)
| Write a 32 bit integer data into the register at address
|
@end example
@sp 1
@c --------------------------------------------------------------------------
@node The SpecDemoUser() Python class
@subsection The SpecDemoUser() Python class
In this section, we are going to explain by example how the SpecDemoUser()
Python class must be used from the interactive Python 2/3 shell. In this way,
we will create a new SpecDemoUser() object, then we will load the bitstream
binary for the Spec Demo User gateware, read the PCB version, toggle the Red
and Green LEDs in the SPEC front panel, write/read the 4x internal LEDs and
finally destroy the object.
@sp 1
Note that we have included a @code{help(spec)} in our example. By doing this,
we get printed in the Python shell the help for all the methods included on
the SpecDemoUser() class and those inherited from the Spec() class. In this
section, we have only included the SpecDemoUser() specific help.
(push 'q' for exit).
@sp 1
@example
>>> from spec_demo_user import *
>>> spec = SpecDemoUser()
a new SPEC object has been created
>>> spec.specLoadBitstream('../../hdl/syn/spec/demo_user/spec_top.bin')
the bitstream has been found...
the bitstream has been successfully loaded
>>> spec.specGetPCBVersion()
3
>>> spec.specToggleGreenLED()
>>> spec.specToggleRedLED()
>>> spec.specGetAuxLEDs()
'0x0'
>>> spec.specSetAuxLEDs(0xf)
>>> spec.specGetAuxLEDs(0xf)
'0xf'
>>> help(spec)
>>> del(spec)
The SPEC object has been destroyed
@end example
@sp 1
@b{@code{Help on SpecDemoUser in module spec_demo_user object:}}
@example
class SpecDemoUser(spec_libc.Spec)
| Simple demo application demonstrating the use of Spec class.
| This is part of the getting started with the SPEC project.
| By creating a SpecDemoUser object, access to the basic functions
| covered in the gateware HDL Spec Demo User is granted.
| In this way, the SPEC FPGA must be programmed with the specific bitstream.
| For this purpose, use the specLoadBitstream() method inherited from Spec.
|
| Method resolution order:
| SpecDemoUser
| spec_libc.Spec
| builtins.object
|
| Methods defined here:
|
| __init__(self, bus=-1, dev=-1, libc='/usr/lib/libspec.so')
|
| specClearGreenLED(self)
| Clear to OFF the SPEC Front Panel Green LED.
|
| specClearRedLED(self)
| Clear to OFF the SPEC Front Panel Red LED.
|
| specGetAuxLEDs(self, hexformat=True)
| Return the hex value corresponding to the four auxiliar LEDs.
| If hexformat=True, the returned value is a string in hex format.
| Note that the Auxiliar LEDs are active low.
|
| specGetButton1(self)
| Test the state of the internal auxiliar Button1.
| Return 0 when pressed and nonzero when released.
|
| specGetButton2(self)
| Test the state of the internal auxiliar Button2.
| Return 0 when pressed and nonzero when released.
|
| specGetGreenLED(self)
| Test the status of the SPEC Front Panel Green LED.
| returns a nonzero result if the LED is ON, 0 if the LED is OFF.
|
| specGetPCBVersion(self)
| Return the SPEC PCB version as an integer value.
|
| specGetRedLED(self)
| Test the status of the SPEC Front Panel Red LED.
| returns a nonzero result if the LED is ON, 0 if the LED is OFF.
|
| specSetAuxLEDs(self, value)
| Set the hex value corresponding to the four auxiliar LEDs.
| Note that the Auxiliar LEDs are active low.
|
| specSetGreenLED(self)
| Set to ON the SPEC Front Panel Green LED.
|
| specToggleRedLED(self)
| Toggle/change the SPEC Front Panel Red LED.
|
@end example
@sp 1
@c --------------------------------------------------------------------------
@node The SpecDemoUserDIO() Python class
@subsection The SpecDemoUserDIO() Python class
In this section, we are going to explain by example how the SpecDemoUserDIO()
Python class must be used from the interactive Python 2/3 shell. In this way,
we will create a new SpecDemoUserDIO() object, then we will load the bitstream
binary for the Spec Demo User+DIO gateware, toggle the top led in the DIO
module front panel, configure the pin4 direction as output and then set pin4
to '1' and finally destroy the object.
@sp 1
Note that we have included a @code{help(spec)} in our example. By doing this,
we get printed in the Python shell the help for all the methods included on
the SpecDemoUserDIO() class and those inherited from the Spec() and the
SpecDemoUser() classes. In this section, we have only included the
SpecDemoUseDIOr() specific help. (push 'q' for exit).
@sp 1
@example
>>> from spec_demo_user_dio import *
>>> spec = SpecDemoUserDIO()
a new SPEC object has been created
>>> spec.specLoadBitstream('../../hdl/syn/spec/demo_user+dio/spec_top.bin')
the bitstream has been found...
the bitstream has been successfully loaded
>>> spec.dioToggleTopLED()
>>> spec.dioWriteDirection('01000')
>>> spec.dioReadDirection()
'01000'
>>> spec.dioReadValue()
'00000'
>>> spec.dioSetOutput('01000')
>>> spec.dioReadValue()
'01000'
>>> help(spec)
>>> del(spec)
The SPEC object has been destroyed
@end example
@sp 1
@b{@code{Help on SpecDemoUserDIO in module spec_demo_user_dio object:}}
@example
class SpecDemoUserDIO(spec_demo_user.SpecDemoUser)
| Simple demo application demonstrating the use of Spec class.
| This is part of the getting started with the SPEC project.
| By creating a SpecDemoUserDIO object, access to the basic functions
| covered in the gateware HDL Spec Demo User DIO is granted.
| In this way, the SPEC FPGA must be programmed with the specific bitstream.
| For this purpose, use the specLoadBitstream() method inherited from Spec.
|
| Method resolution order:
| SpecDemoUserDIO
| spec_demo_user.SpecDemoUser
| spec_libc.Spec
| builtins.object
|
| Methods defined here:
|
| __init__(self, bus=-1, dev=-1, libc='/usr/lib/libspec.so')
|
| dioClearBottomLED(self)
| Clear to OFF the DIO Front Panel Bottom LED.
|
| dioClearOutput(self, value)
| Clear to 0 the selected DIO pins as a 5 chars string.
| Write char 1 for selected and 0 for unchanged.
| e.g. Pin 5 clear, others unchanged: value = '10000'.
|
| dioClearTopLED(self)
| Clear to OFF the DIO Front Panel Top LED.
|
| dioGetBottomLED(self)
| Test the status of the DIO Front Panel Bottom LED.
| returns a nonzero result if the LED is ON, 0 if the LED is OFF.
|
| dioGetTopLED(self)
| Test the status of the DIO Front Panel Top LED.
| returns a nonzero result if the LED is ON, 0 if the LED is OFF.
|
| dioReadDirection(self)
| Return the DIO pin directions as a 5 chars string.
| Read char 1 for output and 0 for input.
| e.g. Pin 5 output, others input: return '10000'.
|
| dioReadTermination(self)
| Return the DIO pin termination resistor as a 5 chars string.
| Read char 1 for termination ON and 0 for termination OFF.
| e.g. Pin 5 termination ON, others termination OFF: return '10000'.
|
| dioReadValue(self)
| Return the DIO pin values as a 5 chars string.
| Read char 1 for HIGH and 0 for LOW.
| e.g. Pin 5 HIGH, others LOW: return '10000'.
|
| dioSetBottomLED(self)
| Set to ON the DIO Front Panel Bottom LED.
|
| dioSetOutput(self, value)
| Set to 1 the selected DIO pins as a 5 chars string.
| Write char 1 for selected and 0 for unchanged.
| e.g. Pin 5 set, others unchanged: value = '10000'.
|
| dioSetTopLED(self)
| Set to ON the DIO Front Panel Top LED.
|
| dioToggleBottomLED(self)
| Toggle/change the DIO Front Panel Bottom LED.
|
| dioToggleTopLED(self)
| Toggle/change the DIO Front Panel Top LED.
|
| dioWriteDirection(self, value)
| Set the DIO pin directions as a 5 chars string.
| Write char 1 for output and 0 for input.
| e.g. Pin 5 output, others input: value = '10000'.
|
| dioWriteTermination(self, value)
| Set the DIO pin termination resistor as a 5 chars string.
| Write char 1 for termination ON and 0 for termination OFF.
| e.g. Pin 5 termination ON, others termination OFF: value = '10000'.
|
| dioWriteValue(self, value)
| Set the DIO pin values as a 5 chars string.
| Write char 1 for HIGH and 0 for LOW.
| e.g. Pin 5 HIGH, others LOW: value = '10000'.
|
@end example
@bye
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment