Skip navigation

FPGA Group

12 Posts authored by: John Beetem Top Member

Here is the new release 0.0r of XXICC.  I've been horrifically busy with work and family obligations over the last two years so I wasn't able to keep up with XXICC.  Also, 0.0r is a major release since it adds integer nets and operators to GCHD, and can now program Lattice iCE40 FPGAs using the open-source IceStorm tools.  So there was lots of testing and documentation updates.

 

XXICC (21st Century Co-design) is a not-for-profit research project which attempts to bring digital hardware/software co-design into the 21st Century using an improved programming language and a Reduced Software Complexity philosophy.  Its goal is to make it easier and more enjoyable to write and maintain digital hardware and software. XXICC is pronounced "Chicken Coop", so-called because it has so many layers.

 

For an overview of XXICC, see XXICC: 21st Century Co-design.  For details on the GalaxC programming language, XXICC Object Editor, and GalaxC extensions for Hardware Design (GCHD), here are the latest documents and source code:

 

Release notes for XXICC rev 0.0r

Programming in the GalaxC Language rev 0.0r: reference and user guide for the GalaxC programming language.

The XXICC Anthology rev 0.0r : collection of miscellaneous XXICC topics, including user guides for the XXICC Object Editor, GCHD, Flavia, and IceStorm.

XXICC code release 0.0r : source code for XXICC.

XXICC source code listing rev 0.0r: source code listing as PDF.

XXICC executable binary for Windows rev 0.0r : XXICC executable binary for Microsoft Windows.

GalaxC sample/demo programs rev 0.0r: sample GalaxC programs and GCHD logic libraries.

GalaxC sample/demo program listings rev 0.0r: PDF listing of the sample GalaxC programs and GCHD examples.

Installing and Running XXICC rev 0.0q: Document describing how to install and run XXICC, unchanged for 0.0r.

Compiling and Running GalaxC Programs rev 0.0k: Document describing how to compile and run your own GalaxC programs, unchanged for 0.0r.

Editable XXICC documentation files rev 0.0r: editable XOE files for XXICC documentation.

GCHD examples for IceStorm rev 0.0r: these are for generating Lattice iCE40 FPGAs using IceStorm, using either a Lattice iCEstick or Nandland Go Board as the target.

Data files for FlaviaP40 release 0.0r for Papilio One 250K: Data files for the FlaviaP40 implementation of the Free Logic Array.

Data files for FlaviaP60 release 0.0r for Papilio One 500K: Data files for the FlaviaP60 implementation of the Free Logic Array.

Data files for FlaviaPD59 release 0.0r: Data files for the FlaviaPD59 implementation of the Free Logic Array for Papilio DUO.

Data files for FlaviaLP60 release 0.0r for LOGI-Pi: Data files for the FlaviaLP60 implementation of the Free Logic Array for the ValentF(x) LOGI-Pi.

Data files for FlaviaLB60 release 0.0r for LOGI-Bone: Data files for the FlaviaLB60 implementation of the Free Logic Array for the ValentF(x) LOGI-Bone.

Taming the Wild Bitstream (unchanged for 0.0r): Supplement to Flavia: the Free Logic Array.

 

I've tested XXICC 0.0r on GNU/Linux (Ubuntu on x86 PCs and ODROID-C1 Ubuntu).  I haven't tested it yet on Raspberry Pi Raspbian or BeagleBone Debian.  I tested it on Windows 2000 and 7.  My main machine is Ubuntu, so the others are more likely to have anomalies.  Constructive comments and suggestions are most welcome.  I'd especially like to find out how to reproduce some of the bugs that have been eluding me.

 

The previous version of XXICC is: XXICC (21st Century Co-design) release 0.0q

The earliest versions of XXICC are at Google Code: https://code.google.com/archive/p/xxicc/

 

XXICC is a FLOSS (Free as in Liberty Open Source Software) project.  Software is licensed under GPLv3 and other content is licensed under Creative Commons CC-BY-SA 3.0.

This is the summary page for the XXICC (21st Century Co-design) project. XXICC was previously hosted at Google Code, which no longer accepts new projects or edits to existing projects.  xxicc.org now links to this page.

 

The latest XXICC release is XXICC (21st Century Co-design) release 0.0r 

 

XXICC (21st Century Co-design) is a not-for-profit research project which attempts to bring digital hardware/software co-design into the 21st Century using an improved programming language and a Reduced Software Complexity philosophy. Its goal is to make it easier and more enjoyable to write and maintain digital hardware and software. XXICC is pronounced “Chicken Coop”, so-called because it has so many layers.

 

XXICC’s GalaxC programming language narrows the gap between problem domain and language by allowing programmers to extend GalaxC by adding problem domain notations. Instead of adapting the task to the language, they adapt GalaxC to the task. The key extension mechanism in GalaxC is separation of syntax from semantics, a simple yet powerful way to add new notations. This is directly adapted from the Galaxy programming language developed in the late 1980s.

 

GalaxC programs may consist of ordinary ASCII characters and white space, like C. However, GalaxC programs may also have executable tables, schematic diagrams, comment blocks containing formatted text and figures (not yet implemented), variable names in different fonts, special symbols, string literals containing formatting, and WYSIWYG dialog boxes. This eliminates the need for separate documentation files (which are very hard to keep synchronized with a program) as well as a separate “resource editor”.

 

These are all edited using the XXICC Object Editor, a unified program and document editor which combines the features of a document editor, spreadsheet program, figure/schematic editor, dialog box editor, and more into a small, easy-to-use program with a consistent user interface. The XXICC Object Editor is written entirely in GalaxC and is used for editing all XXICC software and documentation. XXICC believes in the “take your own medicine” approach to software engineering.

 

Why GalaxC?

 

I created GalaxC to address my dissatisfaction with available programming languages.  I found that I spent a great deal of time “encrypting” ideas into restrictive programming languages, and felt it might be more efficient (and certainly more fun) to have a language that can be taught new notations so that the resulting code would be easier to write, understand, and debug.  GalaxC is an attempt to make this possible, or at least blaze a path in the right direction.

 

If you are perfectly happy with the programming language(s) you are using then you probably shouldn’t waste time learning about GalaxC, except perhaps out of morbid curiosity.  While it is possible that GalaxC’s ideas will revolutionize computer programming and you’ll need to know it to be competitive, it’s unlikely to happen any time soon with the present experimental versions of GalaxC.  OTOH, if you’re adventurous and dissatisfied with current language offerings, read on.

 

Getting Started

 

As with any new project, RTFM.  I try to write good documentation and keep it reasonably up to date.  For an overview of GalaxC, read Chapter 1 (Introduction) of Programming in the GalaxC Language.  GalaxC and XXICC try to follow the Reduced Software Complexity philosophy described in Chapter 1 of The XXICC Anthology.  You might find this interesting.

 

Programming in the GalaxC Language is primarily the reference for the GalaxC language, but tries to provide enough tutorial examples so you can get started. But it also provides considerable detail of how GalaxC’s compiler is implemented.  This is often TMI on a first reading and can be skimmed.  You’ll probably find Chapters 2 and 3 (Tokens and Expressions) to be pretty much the same as C and will go quickly.  Chapter 4 (Types and Variables) diverges quickly from C and gets into how GalaxC’s type inheritance mechanism implements many program features such as variables.  Some parts are TMI on first reading, but are there for the curious.

 

Chapter 5 (Functions and Macros) is a lot of fun since GalaxC allows them to have any legal syntax.  Here you will really see the power of the language.  Chapter 6 (The Postfix Stack Interpreter, PSI) describes the intermediate interpretive code which GalaxC executes.  What’s remarkable here is how much of GalaxC is implemented using macros and inline functions instead of building these features into the compiler.

 

Chapter 7 (Control Statements) looks a lot like C, though more like Pascal.  It’s interesting to see how GalaxC implements looping constructs as macros.  Chapter 8 (Programmer-Defined Types) is primarily concerned with data structures, arrays, and pointers.  These mechanisms are similar to C.

 

Chapters 9 (Generic Macros and Inline Functions) and 10 (Introduction to Special Functions) go deep into how GalaxC is implemented and are TMI for most users.  However, if you are curious as to how GalaxC is constructed, check out Section 10.1 (A Brief Tour of the GalaxC Compiler).

 

To compile and/or install XXICC on your computer, look at Installing and Running XXICC.  Then look at Compiling and Running GalaxC Programs to learn how to compile and run GalaxC programs.

 

When you’re ready to try some user interface programming, look at Chapters 3 and 4 of The XXICC Anthology.  They describe the GalaxC Simplified Window Manager (G-SWIM), an easy way to create portable GUI applications.

 

We have included some sample programs in demo00k.zip.  These include many of the sample programs in The XXICC Anthology.

 

Help!

 

For help with XXICC and GalaxC, please ask in the comments section.  This is much better than sending e-mail to the author as he may be too busy to get back to you quickly and others may be able to help you sooner.  Plus, by writing comments you’ll help future users with similar questions.

 

XXICC is a not-for-profit research project.  If you find XXICC useful or potentially useful, we can use help.

 

Reproducible Bugs

 

The single most useful thing we need is ways to reproduce bugs.  There are some known bugs that are maddening difficult to reproduce, so if you are able to reproduce strange behavior we’d really like to learn how so we can fix the bug.  My motto is “a reproducible bug is half fixed”, because once it is reproducible you can instrument the code and quickly figure out where and why.

 

For now, describe issues in the comments.  If there's anough activity I’ll make a separate issues list.

 

I’d also like to know about typos and other problems with the documents.

 

Regression Testing

 

This is a nasty problem with all software projects: you make a change and suddenly something that used to work is now broken.  There’s even a song about this:

 

99 little bugs in the code,

99 bugs in the code...

take one out, compile again,

100 little bugs in the code.

[Repeat until bug count goes to zero.]

 

The reason GNU/Linux is so stable is that there are so many people all over the world testing all sorts of versions on all sorts of platforms.  We’ll take all the help we can get for XXICC.

 

Funding

 

Currently XXICC does not have a mechanism for accepting donations.  We suggest instead supporting not-for-profit organizations that help Free Software and the free exchange of ideas such as the Free Software Foundation, Electronic Frontier Foundation, Wikimedia Foundation, and Software Freedom Law Center.

 

Acknowledgements

 

The author would like to renew thanks to the talented individuals who helped make the original version of Galaxy circa 1988.  Foremost he wishes to thank Anne Beetem for her ideas, inspiration, support, and scholarly collaborations.  He would also like to thank Jong-Min Park and Jim Rose for their contributions to the original implementation of the Galaxy compiler and its environment, and Monty Denneau for asking The Question which led to the original conception of Galaxy.

 

The author would also like to thank his family and friends for their support and encouragement over the years which led to GalaxC and XXICC reaching this point.  He would also like to acknowledge the literary inspirations of Miguel de Cervantes and Edmond Rostand towards putting Quixotic idealism ahead of practicality, Kurt Vonnegut for Cat’s Cradle, and Jan Potocki’s The Saragossa Manuscript which celebrates performing vast projects by oneself.

 

This text is © 2011 John F. Beetem and licensed under the Creative Commons Attribution-!ShareAlike 3.0 Unported License (CC BY-SA 3.0).  To view a copy of this license, visit creativecommons.org/licenses/by-sa/3.0/.  No warranty is expressed or implied.

Arachne-pnr by Cotton Seed (who also uses pseudonyms cseed and mian2zi3) is an open-source FPGA placement and routing tool for Lattice iCE40 FPGAs.  It's a companion to the open-source Project IceStorm by Clifford Wolf and Mathias Lasser, which has reverse-engineered the iCE40 bitstream.


The usual design flow for IceStorm is to synthesize Verilog source code using Clifford Wolf's Yosys to produce a netlist in the form of a Berkeley Logic Interchange Format (BLIF) file.  Arachne-pnr performs physical placement and routing of the BLIF netlist and produces a text file for IceStorm's icepack tool.  Icepack in turn produces a binary bitstream that can be downloaded to an iCE40 FPGA or SPI Flash memory using IceStorm's iceprog tool.  Here's a typical command sequence:


$ yosys -p "synth_ice40 -blif rot.blif" rot.v

$ arachne-pnr -d 1k -p rot.pcf rot.blif -o rot.txt

$ icepack rot.txt rot.bin

$ [sudo] iceprog rot.bin


I'm going to add IceStorm as a synthesis target for my XXICC (21st Century Co-design) project.  Since XXICC already has rudimentary synthesis, I will skip the Yosys step and go directly to arachne-pnr and IceStorm.  This means I need to produce BLIF files from scratch, which isn't described in the arachne-pnr documentation as far as I can tell.  However, BLIF itself is documented and it's fairly easy to figure out how arachne-pnr uses BLIF from arachne-pnr's example files and others produced by Yosys.  This 'blog documents my experience so others can benefit.  I will be adding to it as I learn more.  This content is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License so others can share it.

 

Arachne-pnr's source code and documentation are at GitHib: cseed/arachne-pnr

 

Here is my original IceStorm discussion here at element14: Project IceStorm: fully open-source FPGA tools for Lattice iCE40 and my IceStorm notes: John Beetem's IceStorm Notes


IceStorm uses a Lattice iCEstick as a development board.  It's available for US$21 in the USA:Lattice Semiconductor: ICE40HX1K-STICK-EVN iCEstick Evaluation Kit.


Here are instructions for installing IceStorm and its companion tools: Projet IceStorm: le FPGA libéré! [the FPGA set free!].  The instructions are a combination of French and GNU/Linux.  The IceStorm steps are out of date, since IceStorm is now at GitHub.  The arachne-pnr steps are accurate:


1.  Install IceStorm first.  Arachne-pnr needs IceStorm's textual chip database files which it converts to a faster binary form as part of the make process.  For IceStorm installation instructions, see John Beetem's IceStorm Notes


2.  You can install arachne-pnr anywhere, but the standard place is in "/opt".  You'll probably need to change permissions on "/opt" so you can write to it.


$ cd /opt/

 

3.  Clone arachne-pnr from GitHub:


$ git clone https://github.com/cseed/arachne-pnr.git

 

4.  Compile arachne-pnr.  It's in C++11, so your GCC will need to support it (GCC 4.8.1 or later).


$ cd arachne-pnr

$ make

$ sudo make install


That's it!  Arachne-pnr is ready to go.  There are sample files in /opt/arachne-pnr/examples/rot and /opt/arachne-pnr/tests.


Like many open-source projects, arachne-pnr doesn't have a lot of documentation.  GitHub is your best starting point.  The arachne-pnr program prints usage and options with the "-h" (help) option:


$ arachne-pnr -h


The usual command for arachne-pnr looks like this:


$ arachne-pnr -d 1k -p rot.pcf rot.blif -o rot.txt

 

"-d 1k" is the target device, in this case the iCE40 HX1K with 1280 logic cells.  You can also specify "-d 8k" for the HX8K with 7,680 logic cells.  If you leave out "-d", you get 1k by default.  It's the FPGA on the Lattice iCEstick.


"-p rot.pcf" is the physical constraint file (PCF).  It specifies the pinout, i.e., how your top-level signals attach to pins, and has lines like this:


set_io a 78

set_io b 87

set_io LED1 99


HX1K pin numbers assume the TQ144 FPGA used by the Lattice iCEstick.  You can specify a different package with the "-P" option.


If present, "rot.blif" is the input BLIF file.  If absent, I think arachne-pnr reads from standard input.

 

If present, "-o rot.txt" is the output text file for icepack.  If absent, I think arachne-pnr writes to standard output.


Here are some other useful options:


Like many physical design tools, arachne-pnr uses simulated annealing (SA) for placement.  SA is a pseudo-random algorithm and requires a seed for the pseudo-random number generator.  As of 8 August 2015, arachne-pnr uses 1 as the default seed or you can use the "-r" option to get a random seed, which arachne-pnr prints out.  Earlier arachne-pnr releases always generated a random seed, which meant that each time you ran it you got different results even with the same BLIF and PCF.  You can specify a different fixed seed with the "-s" option.


As we will see shortly, arachne-pnr may pack multiple components -- e.g., a look-up table (LUT) and a flip-flop -- into a single iCE40 logic cell.  The "-B" option creates a post-pack BLIF file to show you what arachne-pnr did.  There's also a "-V" option that creates a post-pack netlist as Verilog.


BLIF and the Silicon Blue Library


BLIF is a general-purpose logic format and I believe it was originally created for specifying logic functions for logic minimization tools.  As such, if you look at the BLIF document you will see logic truth tables and "don't cares" -- all that good stuff you learned about in logic design class.  Remember Karnaugh Maps?


Arachne-pnr doesn't need any of that Boolean stuff.  It assumes all the logic minimization was already done by Yosys or another synthesis tool and logic functions have already been combined into LUTs.  The "gates" used by arachne-pnr are the iCE primitive blocks in Lattice's iCE Technology Library document.  This document is rather hard to find by browsing at the Lattice site: it's hiding at the iCEcube2 Design Software page.  Scroll to the bottom, find "Software Downloads & Documentation", and click "Technical Briefs".  Click on iCE 2015-04 (or whatever) Technology Library.  You'll also need the iCE40 LP/HX Family Data Sheet, especially the Architecture Overview section.


The most important iCE primitives are SB_LUT4 (4-input LUT), SB_CARRY (fast carry logic), SB_DFFxx (D flip-flops with various clock enable and set/reset options) and SB_IO (I/O block with all the options).  "SB" stands for Silicon Blue Technologies, the company that created the iCE40 FPGA and was bought by Lattice Semiconductor.


Here is a diagram showing how SB_LUT4, SB_CARRY, and SB_DFFxx combine to make an iCE40 Logic Cell (LC):

iCE40LogicCell.png

SB_LUT4 has four inputs I0-I3 and output O, which can be the logic cell output O and/or the input to a D flip-flop.  SB_DFFxx is a DFF with various clock-enable and set/reset options, which are listed in the iCE Technology Library document.  For example, SB_DFF has EN=1 and no set/reset, SB_DFFR has asynchronous reset, SB_DFFSS has synchronous set, and SB_DFFESR has a clock-enable input and synchronous reset.  There are also versions with inverted clocks.  LC output O is either the LUT output or the DFF state Q, selected by a configurable multiplexer.


Logic cells are stacked into Programmable Logic Blocks (PLBs), each of which has 8 LCs.  The EN and SR signals and clock polarity must be the same for all LCs in a PLB.  (SR options may be different for each LC.)


Each LC also has carry logic for building high-speed adder, subtracters, comparators, binary counters, etc.  SB_CARRY is the majority function, i.e., the carry-out function of a full adder.  SB_LUT4 calculates the sum output of a full adder and similar functions, setting the configurable mux for LUT input I3 to be the carry in (CI) from the LC below this one.  CI may also be 0 or 1 if this is the lowest LC in a PLB.  The carry out (CO) from SB_CARRY goes to the LC above this one.


Arachne-pnr tries to combine SB_LUT4, SB_CARRY, and SB_DFFxx whenever possible.  In some cases, the logic cannot be combined and arachne-pnr uses SB_LUT4 as a "pass-through" for carry in/out or a DFF input.  Combining SB_LUT4 and SB_CARRY requires the SB_CARRY I0, I1, and CI input signals to be the same as the SB_LUT4 I1, I2, and I3 inputs.


Here's a BLIF example from a binary counter.  Given the current state p5 of the counter,  it calculates the next state np5:

 

.gate SB_LUT4  I0=clr I1=$0 I2=p5 I3=pc5 O=np5  # np5 = next p5

.param LUT_INIT 0000010101010000

.gate SB_DFF  C=clk D=np5 Q=p5

.gate SB_CARRY CI=pc5 I0=$0 I1=p5 CO=pc6        # pc6 = carry to p6


SB_LUT4 calculates np5 given p5 and carry-in pc5 from the next lower bit of the counter.  np5 is clocked into SB_DFF to update p5 at the next rising edge of clk.  SB_CARRY calculates carry-out pc6 for the next higher bit of the counter.  Note that SB_CARRY's I0, I1, and CI inputs match SB_LUT4's I1, I2, and I3.  SB_LUT4 I0 is set to signal clr which synchronously resets the counter, and I1 is not used so I set it to the constant 0.  (Yosys uses $true and $false for 1 and 0, but BLIF lets you define them to be something else.)


SB_LUT4 has a LUT_INIT parameter that specifies the binary truth table for the LUT.  Each bit i (numbered from LSb = 0) is the LUT value if I[3:0] = i.  If I0 = clr = 1, the LUT output np5 is 0.  If I0 = 0, the LUT output is I2⊕I3 = p5⊕pc5.


Arachne-pnr combines SB_LUT4, SB_DFFxx, and SB_CARRY into an ICESTORM_LC, which includes parameters for DFF and carry chain options.  You can see how it did this using the "-B" option.  I think arachne-pnr understands ICESTORM_LC blocks in its BLIF input if you want to combine LUTs, DFFs, and carry logic yourself before running arachne-pnr.


Finally, let's take a quick look at SB_IO, the I/O block.  The iCE40 I/O block has many options including built-in flip-flops for DDR, tri-state output enable, and pull-up resistor.  See the iCE Technology Library document for details.  If your design has simple inputs and outputs, you can let arachne-pnr generate SB_IO blocks automatically.  However, if you want to use some options like pull-up you may need to include an SB_IO explicitly.


Here's the BLIF for an input pin "en" that has a pull-up:


.gate SB_IO PACKAGE_PIN=en D_IN_0=en.d0

.param PINTYPE  000001000001

.param PULLUP 1


This SB_IO has two of its pins connected: PACKAGE_PIN is the external pin "en" and D_IN_0 is the internal data-in signal, which may be latched or registered.  There's also a D_IN_1 registered on a falling clock edge for DDR.  I've named the internal signal "en.d0" and connect it to internal logic elsewhere in the BLIF file.


The PIN_TYPE parameter specifies whether SB_IO input is registered, latched, or combinational, and whether the SB_IO output is disabled, combinational, registered, inverted, DDR, etc.  The PULLUP parameter enables the I/O pin's pull-up resistor.


OK, that's all for now.  I'll add more as needed.

Project IceStorm, by Clifford Wolf and Mathias Lasser, is an amazing project that has reverse-engineered the Lattice iCE40 FPGA's bitstream so that it's finally possible to write open-source FPGA design tools for a real FPGA.  I've been playing with IceStorm and its companion tool arachne-pnr (place & route) over the last few days and it's been loads of fun with very few problems.  I'm going to add IceStorm as a synthesis target for my XXICC (21st Century Co-design) project.  That will give me a complete open-source FPGA design system, something I've been wanting for decades.

 

This 'blog is for collecting links and notes for IceStorm so that others can find them quickly and easily.  I will be adding to it as I learn more.  This content is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License so others can share it.

 

Here is the official Project IceStorm wiki: Project IceStorm

 

Here is my original IceStorm discussion here at element14: Project IceStorm: fully open-source FPGA tools for Lattice iCE40


IceStorm uses a Lattice iCEstick as a development board.  It's available for US$21 in the USA: Lattice Semiconductor: ICE40HX1K-STICK-EVN iCEstick Evaluation Kit.


Here are instructions for installing IceStorm and its companion tools: Projet IceStorm: le FPGA libéré! [the FPGA set free!].  The instructions are a combination of French and GNU/Linux.  The IceStorm steps are out of date, since IceStorm is now at GitHub.  Here are the specific steps for IceStorm:


1.  Install "libftdi-dev" so IceStorm can talk to iCEstick's FT2232H:


$ sudo apt-get install libftdi-dev


2.  You can install IceStorm anywhere, but the standard place is in "/opt".  You'll probably need to change permissions on "/opt" so you can write to it.


$ cd /opt/

 

3.  Clone IceStorm from GitHub:


$ git clone https://github.com/cliffordwolf/icestorm.git icestorm

 

4.  Make the IceStorm software.  Some of it is in C++11, so your GCC will need to support it (GCC 4.8.1 or later).  The "make" step builds textual chip databases using a Python program, which takes a while on a slow computer.


$ cd icestorm

$ make

$ sudo make install


That's it!  IceStorm is ready to go.


Here is a partial list of IceStorm programs.  Like many open-source projects, IceStorm does not have a lot of documentation.  The IceStorm wiki is your best starting point.  However, each program does have a way to print help.


icepack takes a FPGA configuration data in text form (usually from arachne-pnr) and packs it into a binary file for downloading.  Here is a typical icepack command:


$ icepack moebius.txt moebius.bin


To list icepack options, give the command "icepack -h".


iceprog downloads a bitstream to an iCE40 FPGA or to a serial flash.  Here is a typical iceprog command:


$ sudo iceprog moebius.bin


If you don't want to use sudo, you can add a "rules" file to "/etc/udev/rules.d": see udev rules file for FTDI FT2232D/H, FT232H, and Papilio DUO.


To list iceprog options, give the "iceprog" command with no arguments.  For an iCEstick, iceprog programs the serial flash and then resets the FPGA so that it programs itself from the serial flash.  You can't program the FPGA's internal SRAM directly because of the way the SPI interfaces are wired together.  It is possible to modify iCEstick to program SRAM directly, but you lose the serial flash chip.  The "iceprog" command with no arguments tells you how to do this.

Release 0.0q has been replaced by: XXICC (21st Century Co-design) release 0.0r

 

Here is the new release 0.0q of XXICC.  0.0q adds logic capacity to Flavia implementation and allows you to specify pull-up, pull-down, and keeper circuits for FPGA I/Os in all implementations.  The Flavia architecture is now more consistent across all implementations: see the Flavia chapter of The XXICC Anthology rev 0.0q which has an updated version of Flavia: the Free Logic Array.


XXICC (21st Century Co-design) is a not-for-profit research project which attempts to bring digital hardware/software co-design into the 21st Century using an improved programming language and a Reduced Software Complexity philosophy.  Its goal is to make it easier and more enjoyable to write and maintain digital hardware and software. XXICC is pronounced "Chicken Coop", so-called because it has so many layers.

 

For an overview of XXICC, see XXICC: 21st Century Co-design.  For details on the GalaxC programming language, XXICC Object Editor, and GalaxC extensions for Hardware Design (GCHD), here are the latest documents and source code:

 

Release notes for XXICC rev 0.0q

Programming in the GalaxC Language rev 0.0j: reference and user guide for the GalaxC programming language, unchanged for 0.0q.

The XXICC Anthology rev 0.0q: collection of miscellaneous XXICC topics, including user guides for the XXICC Object Editor, GCHD and Flavia.  0.0q has a major rewrite of the Flavia chapter (12).

XXICC code release 0.0q: all source code for XXICC.

XXICC source code listing rev 0.0q: source code listing as PDF.

XXICC executable binary for Windows rev 0.0q: XXICC executable binary for Microsoft Windows.

GalaxC sample/demo programs rev 0.0k: sample GalaxC programs and GCHD logic libraries, unchanged for 0.0q.

GalaxC sample/demo program listings rev 0.0k: PDF listing of the sample GalaxC programs and GCHD examples, unchanged for 0.0q.

Installing and Running XXICC rev 0.0q: Document describing how to install and run XXICC.

Compiling and Running GalaxC Programs rev 0.0k: Document describing how to compile and run your own GalaxC programs, unchanged for 0.0q.

Editable XXICC documentation files rev 0.0q: editable XOE files for XXICC documentation.

Data files for FlaviaP40 release 0.0q for Papilio One 250K: Data files for the FlaviaP40 implementation of the Free Logic Array.

Data files for FlaviaP60 release 0.0q for Papilio One 500K: Data files for the FlaviaP60 implementation of the Free Logic Array.

Data files for FlaviaPD59 release 0.0p: Data files for the FlaviaPD59 implementation of the Free Logic Array for the Papilio DUO, unchanged for 0.0q.

Data files for FlaviaLP60 release 0.0q for LOGI-Pi: Data files for the FlaviaLP60 implementation of the Free Logic Array for the ValentF(x) LOGI-Pi.

Data files for FlaviaLB60 release 0.0q for LOGI-Bone: Data files for the FlaviaLB60 implementation of the Free Logic Array for the ValentF(x) LOGI-Bone.

Taming the Wild Bitstream (unchanged for 0.0q): Supplement to Flavia: the Free Logic Array.

 

I've tested XXICC 0.0q on GNU/Linux (Ubuntu on x86 PCs, Raspberry Pi Raspbian, BeagleBone Debian, and ODROID-C1 Ubuntu) and Windows (2000 and 7).  My main machine is Ubuntu, so the others are more likely to have anomalies.  Constructive comments and suggestions are most welcome.  I'd especially like to find out how to reproduce some of the bugs that have been eluding me.

 

The previous version of XXICC is: XXICC (21st Century Co-design) release 0.0p

The earliest versions of XXICC are at Google Code: code.google.com/p/xxicc/

 

XXICC is a FLOSS (Free as in Liberty Open Source Software) project.  Software is licensed under GPLv3 and other content is licensed under Creative Commons CC-BY-SA 3.0.

Update 28 June 2015: XXICC has been updated to XXICC (21st Century Co-design) release 0.0q


Here is the release 0.0p of XXICC.  There is no rev 0.0o since the letter O looks too much like the digit 0.  0.0p adds a Flavia implementation for the Gadget Factory Papilio DUO board, which has a Xilinx Spartan-6 LX9 FPGA and an Arduino-compatible Atmel ATmega32U4.  Flavia 0.0p also adds pinout tables to map top-level ports and signal names to FPGA pins.  You can also specify pull-up, pull-down, and keeper circuits for FPGA I/Os.

 

0.0p is a “partial” release specifically intended to support the author’s element14 ’blog Raspberry Pi 2 meets Papilio DUO.  To get this ’blog published in a timely fashion, we chose to defer some features to next release: see the release notes.

 

XXICC (21st Century Co-design) is a not-for-profit research project which attempts to bring digital hardware/software co-design into the 21st Century using an improved programming language and a Reduced Software Complexity philosophy.  Its goal is to make it easier and more enjoyable to write and maintain digital hardware and software. XXICC is pronounced "Chicken Coop", so-called because it has so many layers.

 

For an overview of XXICC, see the xxicc.org home page and wiki.  For details on the GalaxC programming language, XXICC Object Editor, and GalaxC extensions for Hardware Design (GCHD), here are the latest documents and source code.

 

Release notes for XXICC rev 0.0p

Programming in the GalaxC Language rev 0.0j: reference and user guide for the GalaxC programming language, unchanged for 0.0p.

The XXICC Anthology rev 0.0n: collection of miscellaneous XXICC topics, including user guides for the XXICC Object Editor, GCHD and Flavia.  No changes for 0.0p: see Raspberry Pi 2 meets Papilio DUO for Papilio DUO and synthesis pinout table.

Data files for FlaviaPD59 release 0.0p: Data files for the FlaviaPD59 implementation of the Free Logic Array for the Papilio DUO.

Data files for FlaviaLP56 release 0.0p: Data files for the FlaviaLP56 implementation for the ValentF(x) LOGI-Pi.

Data files for FlaviaLB56 release 0.0p:  Data files for the FlaviaLB56 implementation for the ValentF(x) LOGI-Bone.

Taming the Wild Bitstream (unchanged for 0.0p): Supplement to Flavia: the Free Logic Array.

XXICC code release 0.0p: all source code for XXICC.

XXICC source code listing rev 0.0p: source code listing as PDF.

Release 0.0p does not including XXICC executable binaries: you must build the executable from source code.

GalaxC sample/demo programs rev 0.0k: sample GalaxC programs and GCHD logic libraries, unchanged for 0.0p.

GalaxC sample/demo program listings rev 0.0k: PDF listing of the sample GalaxC programs and GCHD examples, unchanged for 0.0p.

Installing and Running XXICC rev 0.0p: Document describing how to install and run XXICC.

Compiling and Running GalaxC Programs rev 0.0k: Document describing how to compile and run your own GalaxC programs, unchanged for 0.0p.

 

I've tested XXICC 0.0p on GNU/Linux (Ubuntu on x86 PC, Raspberry Pi Debian "Wheezy", and ODROID-C1 Ubuntu).  My main machine is Ubuntu, so the others are more likely to have anomalies.  Constructive comments and suggestions are most welcome.  I'd especially like to find out how to reproduce some of the bugs that have been eluding me.

 

XXICC is a FLOSS (Free as in Liberty Open Source Software) project.  Software is licensed under GPLv3 and other content is licensed under Creative Commons CC-BY-SA 3.0.

Here is the new release 0.0n of XXICC, which adds Xilinx Spartan-6 Flavia implementations for the ValentF(x) LOGI-Pi board and LOGI-Bone.

 

XXICC (21st Century Co-design) is a not-for-profit research project which attempts to bring digital hardware/software co-design into the 21st Century using an improved programming language and a Reduced Software Complexity philosophy.  Its goal is to make it easier and more enjoyable to write and maintain digital hardware and software. XXICC is pronounced "Chicken Coop", so-called because it has so many layers.

 

For an overview of XXICC, see the xxicc.org home page and wiki.  For details on the GalaxC programming language, XXICC Object Editor, and GalaxC extensions for Hardware Design (GCHD), here are the latest documents and complete code.

 

Release notes for XXICC rev 0.0n

Programming in the GalaxC Language rev 0.0j: reference and user guide for the GalaxC programming language, unchanged for 0.0n.

The XXICC Anthology rev 0.0n: collection of miscellaneous XXICC topics, including user guides for the XXICC Object Editor, GCHD and Flavia.

Data files for FlaviaP32 release 0.0n: Data files for the FlaviaP32 implementation of the Free Logic Array for the Papilio One 250K.

Data files for FlaviaP48 release 0.0n: Data files for the FlaviaP48 implementation for the Papilio One 500K.

Data files for FlaviaLP56 release 0.0n: Data files for the FlaviaLP56 implementation for the ValentF(x) LOGI-Pi.

Data files for FlaviaLB56 release 0.0n:  Data files for the FlaviaLB56 implementation for the ValentF(x) LOGI-Bone.

Taming the Wild Bitstream (unchanged for 0.0n): Supplement to Flavia: the Free Logic Array.

XXICC executable binaries rev 0.0n:executable XXICC binaries if you don't want to build from source code.

GalaxC sample/demo programs rev 0.0k: sample GalaxC programs and GCHD logic libraries, unchanged for 0.0n.

GalaxC sample/demo program listings rev 0.0k: PDF listing of the sample GalaxC programs and GCHD examples, unchanged for 0.0n.

Editable XXICC documentation files rev 0.0n: editable XOE files for XXICC documentation.

Installing and Running XXICC rev 0.0n: Document describing how to install and run XXICC.

Compiling and Running GalaxC Programs rev 0.0k: Document describing how to compile and run your own GalaxC programs, unchanged for 0.0n.

 

I've tested XXICC 0.0n on GNU/Linux (Ubuntu, Raspberry Pi Debian "Wheezy", BeagleBone Debian, and BeagleBoard Ångström) and Windows (2000 and 7).  My main machine is Ubuntu, so the others are more likely to have anomalies.  Constructive comments and suggestions are most welcome.  I'd especially like to find out how to reproduce some of the bugs that have been eluding me.

 

XXICC is a FLOSS (Free as in Liberty Open Source Software) project.  Software is licensed under GPLv3 and other content is licensed under Creative Commons CC-BY-SA 3.0.

Here is the new release 0.0m of XXICC.  There is no rev 0.0l since lower-case L looks like digit 1.  0.0m is primarily a maintenance release with bug fixes and improvements to usability.  In addition, Flavia: the Free Logic Array has a new implementation FlaviaP48 for the Papilio One 500K.  FlaviaP32 for the Papilio One 250K now lets you change the default 2 Hz "proof of concept" clock to whatever you like between 1 Hz and 32 MHz.

 

XXICC (21st Century Co-design) is a not-for-profit research project which attempts to bring digital hardware/software co-design into the 21st Century using an improved programming language and a Reduced Software Complexity philosophy.  Its goal is to make it easier and more enjoyable to write and maintain digital hardware and software. XXICC is pronounced "Chicken Coop", so-called because it has so many layers.

 

For an overview of XXICC, see the xxicc.org home page and wiki.  For details on the GalaxC programming language, XXICC Object Editor, and GalaxC extensions for Hardware Design (GCHD), here are the latest documents and complete code.

 

Release notes for XXICC rev 0.0m

Programming in the GalaxC Language rev 0.0j: reference and user guide for the GalaxC programming language, unchanged for 0.0m.

The XXICC Anthology rev 0.0m: collection of miscellaneous XXICC topics, including user guides for the XXICC Object Editor, GCHD and Flavia.

Data files for FlaviaP32 release 0.0m: Data files for the FlaviaP32 implementation of the Free Logic Array for the Papilio One 250K.

Data files for FlaviaP48 release 0.0m: Data files for the FlaviaP48 implementation of the Free Logic Array for the Papilio One 500K.

Taming the Wild Bitstream (unchanged for 0.0m): Supplement to Flavia: the Free Logic Array.

XXICC source code listing rev 0.0m: source code listing in PDF.

XXICC executable binaries rev 0.0m: executable XXICC binaries if you don't want to build from source code.

GalaxC sample/demo programs rev 0.0k: sample GalaxC programs and GCHD logic libraries, unchanged for 0.0m.

GalaxC sample/demo program listings rev 0.0k: PDF listing of the sample GalaxC programs and GCHD examples, unchanged for 0.0m.

Editable XXICC documentation files rev 0.0m: editable XOE files for XXICC documentation.

Installing and Running XXICC rev 0.0m: Document describing how to install and run XXICC.

Compiling and Running GalaxC Programs rev 0.0k: Document describing how to compile and run your own GalaxC programs, unchanged for 0.0m.

 

I've tested XXICC 0.0m on GNU/Linux (Ubuntu, Raspberry Pi Debian "Wheezy", BeagleBone Debian, and BeagleBoard Ångström) and Windows (2000 and 7).  My main machine is Ubuntu, so the others are more likely to have anomalies.  Constructive comments and suggestions are most welcome.  I'd especially like to find out how to reproduce some of the bugs that have been eluding me.

 

XXICC is a FLOSS (Free as in Liberty Open Source Software) project.  Software is licensed under GPLv3 and other content is licensed under Creative Commons CC-BY-SA 3.0.

Abstract: This ’blog describes using a ValentF(x) LOGI-EDU board to make a 4-digit BCD (binary-coded decimal) counter using LOGI-EDU’s 4-digit seven-segment LED module.  I used both LOGI-Pi and LOGI-Bone FPGA boards to implement the BCD counter logic.

 

Disclaimer: This ’blog is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.  Incorrect board connections and/or an incorrect FPGA bitstream could cause damage to an FPGA and/or its connected circuitry, or cause a system to malfunction.  Users must agree that the author has NO LIABILITY for any damages.

 

This is my third ’blog about ValentF(x) LOGI boards.  To get started using LOGI FPGA boards, see my first two LOGI ’blogs First Experiments with the ValentF(x) LOGI-Bone and First Experiments with the ValentF(x) LOGI-Pi, and also the ValentF(x) Logi-Bone Quick Start Guide and LOGI-Pi Quick Start Guide.

 

The ValentF(x) LOGI-EDU is an educational expansion card for LOGI-Pi, though it can also be used with LOGI-Bone if you don’t need multiple features simultaneously.  LOGI-EDU has a number of useful I/O devices including a VGA output with up to 512 colors, a multiplexed 4-digit seven-segment display, two PS/2 ports, two Nintendo NES controller ports, and an audio output using PWM or sigma-delta modulation.  There’s also a small prototyping area.  Here’s a picture of the board from the ValentF(x) wiki, copied with permission:

LOGI-EDUsmall.jpg

LOGI-EDU is primarily for LOGI-Pi, and element14 currently only sells it as a package with a LOGI-Pi.  LOGI-EDU plugs into LOGI-Pi’s four Digilent Pmod™sockets:

LOGI-Pi-EDUsmall.jpg

The Pmods are numbered 1-4 from left to right in the photos and connect to LOGI-EDU resources as follows:

 

  • Pmod 1: VGA and +3.3V power from LOGI-Pi.
  • Pmod 2: Seven-segment display.
  • Pmod 3: Seven-segment display plus PS/2 #2 and VGA LSbs.
  • Pmod 4: PS/2 #1, NES, and PWM.

 

All four Pmods provide two ground pins.  For details on how the Pmods are connected, see the LOGI-EDU schematic.

 

You can use LOGI-EDU with LOGI-Bone, but since LOGI-Bone only has two Pmod sockets you can only use two adjacent LOGI-EDU plugs.  In this ’blog, we use the seven-segment display so we need LOGI-EDU Pmods 2 and 3.  They plug very nicely into the two LOGI-Bone sockets:

BoneEDU.jpg

All power for the LEDs comes from FPGA I/Os so we don’t need the LOGI-EDU Pmod 1 +3.3V pins.

 

The seven-segment display is a fairly common LITEON LTC-4727JS: here’s the data sheet.  The digits are numbered 1-4 from left to right, and the segments of each digit are numbered A-G in the usual way (see Wikipedia):

LEDdisplay.png

Here is part of the LOGI-EDU schematic, which shows how the display is wired up:

LEDschem.png

The LTS-4727JS is a multiplexed display [Wikipedia] to save pins, both on the display and the FPGA.  Only one digit is turned on at a time, but they are refreshed quickly enough that normal eyes see all digits displayed at once.

 

The LTS-4727JS is a common cathode display, which means that the LEDs of a digit (including decimal point DP) have their cathodes wired together.  To turn on a digit, the FPGA pulls a combination of anode signals SSEG0-A, SSEG1-B, ..., SSEG7-DP to +3.3V and also drives one digit select SEG_CTRL_A1, SEG_CTRL_A2, ..., SEG_CTRL_L high as well, setting the rest low.  The selected SEG_CTRL turns on one transistor Q1-Q5, which pulls one common cathode pin A1-A4 or L low.  This creates a current path from each high SSEG line to ground, turning on the selected segments of the selected digit.

 

Each SSEG line has a 100Ω resistor to limit current to about 10 mA.  This would usually be too bright, but in normal operation each digit is only on 1/4 of the time so 10 mA gives good brightness.  Since the selected digit’s segments including decimal point could all be on simultaneously, the combined cathode current could be as high as 80 mA.  This is why a transistor pulls the common cathode down.  An FPGA pin cannot sink that much current.

 

4-Digit BCD Counter

 

Now that we’re familiar with the display, let’s use it to make a 4-digit BCD counter with these features:

 

  • Increment every tenth of a second.
  • Display seconds and tenths of seconds in decimal from 0.0 to 999.9, wrapping every 1000 seconds.
  • Display decimal point and suppress leading zeros.
  • PB0 resets the counter to 0.0.
  • PB1 holds the counter at its current value.

 

PB0 and PB1 have the same behavior as the 4-bit binary counter in First Experiments with the ValentF(x) LOGI-Bone and First Experiments with the ValentF(x) LOGI-Pi.

 

The Verilog code for the BCD counter is in LOGIdemo.v (part of LOGIdemo.zip) along with other sample code.  Let’s take a look the Verilog modules that make up the counter, starting with SevenSeg which converts a BCD digit to its seven-segment representation:

LEDdisplay.png

module SevenSeg(X, Y);

input  [3:0] X;    // BCD digit.

output [6:0] Y;    // Seven-segment code "ABCDEFG".

 

    assign Y = X == 0? 7'b1111110: X == 1? 7'b0110000:

        X == 2? 7'b1101101: X == 3? 7'b1111001:

        X == 4? 7'b0110011: X == 5? 7'b1011011:

        X == 6? 7'b1011111: X == 7? 7'b1110000:

        X == 8? 7'b1111111: X == 9? 7'b1110011: 7'h00;

endmodule

 

Input X is a 4-bit BCD digit from 0000 to 1001.  Output Y is a 7-bit seven-segment display code ABCDEFG with MSb A and LSb G.  The body is simply a multiplexer.  Xilinx logic synthesis converts it into a ROM look-up table.

 

Module DigitCounter is a divide-by-10 counter:

 

module DigitCounter(Mclk, reset, Cin, Cout, D);

input  Mclk;       // 50 MHz master clock.

input  reset;      // Asynchronous reset.

input  Cin;        // Carry in pulse.

output Cout;       // Carry out if carry in and D = 9.

output [3:0] D;    // Current value of digit.

 

    reg        [3:0] D;    // Digit counter from 0 to 9.

 

    assign Cout = Cin && D >= 9;

    always @(posedge Mclk or posedge reset)

    if (reset) D <= 0; else if (Cin) D <= Cout? 0: D+1;

endmodule

 

Mclk is the LOGI-Pi or LOGI-Bone 50 MHz master clock.  It runs continuously.  Cin is a “carry in” pulse that is high for one 20 ns clock cycle to increment the 4-bit counter.  Cout is a “carry out” pulse that occurs when Cin is high and the current count D is 9 or more: Cout clears D to 0.  D should never exceed 9, but “D >= 9” gets us out of a bad state quicker if D is ever reset to 10-15.  D is a module output so we can display it.  Finally, there’s an asynchronous reset to force D to zero immediately if you press PB0.

 

Module ClockDiv2K generates a single-cycle LEDclk pulse every 500 ms (2 KHz):

 

// Divide 50 MHz master clock by 25,000 to get 2 KHz LED

// multiplexer clock.

module ClockDiv2K(Mclk, LEDclk);

input  Mclk;        // 50 MHz master clock.

output LEDclk;      // 2 KHz LED mux clock (clock-enable pulses).

reg    LEDclk;

 

    reg  [14:0] Q;            // Divide by 25,000 counter.

    wire [15:0] nextQ = Q + 1;

    wire Qcarry = nextQ[15];  // Carry out, pulses at 2 KHz.

 

    always @(posedge Mclk)

    begin

        // Divide by 25,000: when nextQ has carry out,

        // set Q = -25,000 = 32,768-25,000 = 7,768.

        // Qcarry is sync reset.

        if (Qcarry) Q <= 15'd7768; else Q <= nextQ[14:0];

        LEDclk <= Qcarry;

    end

endmodule

 

This counter uses the same technique as module ClockDiv in First Experiments with the ValentF(x) LOGI-Bone and First Experiments with the ValentF(x) LOGI-Pi.  This is a rather unusual way to express a counter, but it maps well to Xilinx logic.  People usually make a divide-by-n counter by resetting it to 0 and then detecting when it reaches n−1, as we did with DigitCounter.  However, this requires logic to compare to n−1.  So instead we preset the counter to −n and increment it until it reaches all ones, which we detect using the carry out of the counter’s adder chain.

 

Now that we have all the submodules, here’s the root module SevenSegDemo.  First let’s take care of declaring the I/O pins and converting active-low PB0 to active-high reset:

 

module SevenSegDemo(Mclk, PB0, PB1, Y, dp, en1, en2, en3, en4);

input  Mclk;      // 50 MHz master clock.

input  PB0;       // Press to reset = active-low.

input  PB1;       // Press to hold = active-high enable.

output [6:0] Y;   // Seven-segment code "ABCDEFG".

output dp;        // Turn on decimal point for digit 3.

output en1, en2;  // Enables for digits 1-4 (left to right).

output en3, en4;

 

    wire reset = !PB0;    // PB0 is active-low.

 

Next we need a divide-by-200 counter JK to convert the 2 KHz LEDclk produced by ClockDiv2K into a 10 Hz carry into the tenths digit.

 

wire LEDclk;      // 2 KHz LED mux clock (clock-enable pulses).

reg  [1:0] K;     // Counter LSbs;

reg  [5:0] J;     // Counter MSbs.

wire [6:0] nextJ = J + (LEDclk && K == 3 && PB1);

wire resetJ = reset || nextJ[6];   // Synchronous reset.

 

Counter JK comes in two parts.  The MSbs J[5:0] are a divide-by-50 counter which is reset by PB0 and held if you press PB1.  The LSbs K[1:0] select a digit for LED multiplexing.  K must increment continuously since multiplexing still needs to occur when pressing PB0 or PB1.  K simply increments whenever LEDclk occurs (see below).  J increments when K overflows and PB1 is not pressed, i.e., counting is enabled.  J uses the same divide-by-n logic style as ClockDiv2K.

 

Here are the rest of the signal declarations.  c1-c4 are the carries into digits 1 (MSD) through 4 (LSD).  c4 is the carry out from counter JK.

 

wire c4 = nextJ[6];  // Carry into digit 4 (tenths).

wire c1, c2, c3;     // Carry into digit 1-3.

wire dummy;          // Carry out of digit 1 (unused).

wire [15:0] D;       // Values of digits 1-4.

wire [3:0] Dsel;     // Digit selected by K.

 

Here the instance of ClockDiv2K, followed by the logic to update counter JK:

 

ClockDiv2K cd(Mclk, LEDclk);

 

always @(posedge Mclk)

begin

    // Always increment JK counter LSbs since they multiplex the digits.

    if (LEDclk) K <= K+1;

    // Reset JK counter MSbs if PB0 to get 500us reset response.

    // Divide J by 50: when nextJ has carry out, set J = -50 = 64-50 = 14.

    if (resetJ) J <= 6'd14; else J <= nextJ[5:0];

end

 

Next we have four instances of DigitCounter, one for each digit.  The carry out of each digit is the carry in of the next higher digit.  The four 4-bit digit values are combined into a 16-bit signal D[15:0].

 

// Digit counters for digits 1-4, starting with digit 4.

DigitCounter dc4(Mclk, reset, c4, c3, D[3:0]);       // tenths

DigitCounter dc3(Mclk, reset, c3, c2, D[7:4]);       // seconds

DigitCounter dc2(Mclk, reset, c2, c1, D[11:8]);      // tens

DigitCounter dc1(Mclk, reset, c1, dummy, D[15:12]);  // hundreds

 

// Select a digit using K.

assign Dsel = K == 0? D[3:0]: K == 1? D[7:4]: K == 2? D[11:8]: D[15:12];

 

Dsel is the digit of D[15:0] selected by K using a multiplexer.  Module SevenSeg converts it to seven-segment code Y:

 

SevenSeg ss(Dsel, Y);

 

The decimal point is a special case: it’s turned on if we’re doing digit 3 (K = 1):

 

assign dp = K == 1;

 

The final logic enables each digit, according to the value of K.  Digits 3 and 4 are always shown, so we just need to check K.  Digits 1 and 2 are more interesting because we suppress leading zeros:

 

assign en4 = K == 0;    // Always show digit 4.

assign en3 = K == 1;    // Always show digit 3.

// Do not show d2 if digits 1 and 2 are both 0.

assign en2 = K == 2 && D[15:8] != 0;

// Do not show d1 if it's 0.

assign en1 = K == 3 && D[15:12] != 0;

endmodule

 

Running Xilinx ISE

 

Now that we have the Verilog code, we can compile it using Xilinx ISE (Integrated Software Environment).  I’m using the ISE 12.4 free-as-in-beer WebPACK Editon on Ubuntu 12.04 LTS, which mostly works except for some graphical tools I don’t need.  I’ve created an ISE project named LOGIdemo in directory LOGI, so the many files ISE generates -- including the bitstream -- will be in LOGI/LOGIdemo.

 

I’m not going to tell you how to install or use the Xilinx tools since that’s a long procedure and can be found elsewhere, for example Logi-Pi Quick Start Guide.  Gadget Factory also has some tutorials: Install ISE WebPack and Papilio Xilinx ISE WebPack VHDL Getting Started.

 

SevenSegDemo synthesizes without any errors on ISE 12.4 and the warnings are reasonable.  One of the hardest tasks for a new ISE user is learning which warnings can be ignored and which are important.

 

Now, before implementing the design you need to tell ISE how to assign signals to pins.  This is fairly tedious for LOGI-EDU, because you must figure out how seven-segment display pins connect to LOGI-EDU Pmod pins using the LOGI-EDU schematic, and then use the LOGI-Pi and/or LOGI-Bone schematics to see how their Pmod pins connect to their FPGA pins.  LOGI-Bone has the added complication that we’re plugging LOGI-EDU Pmods 2 and 3 into LOGI-Bone Pmods 1 and 2.

 

There’s a graphical tool for assigning pins in ISE, but IMO it’s a lot easier to create and edit a User Constraint File (UCF).  For this ’blog I created two versions of the UCF, one for LOGI-Pi and one for LOGI-Bone.  Here’s SevenSegPi.ucf for LOGI-Pi:

 

NET Mclk  LOC="P85"  | PERIOD=20ns;

NET PB0   LOC="P102";    # PB0 = press to reset

NET PB1   LOC="P101";    # PB1 = press to hold

# PMOD2

NET en2   LOC="P142";    # PMOD2-1

#NET enL  LOC="P141";    # PMOD2-2

NET en3   LOC="P15";     # PMOD2-3

NET en4   LOC="P14";     # PMOD2-4

NET en1   LOC="P144";    # PMOD2-7

NET Y<3>  LOC="P143";    # PMOD2-8

NET Y<2>  LOC="P140";    # PMOD2-9

NET dp    LOC="P139";    # PMOD2-10

# PMOD3

NET Y<0>  LOC="P138";    # PMOD3-1

NET Y<4>  LOC="P137";    # PMOD3-2

#NET xxx  LOC="P124";    # PMOD3-3

#NET xxx  LOC="P123";    # PMOD3-4

NET Y<5>  LOC="P119";    # PMOD3-7

NET Y<6>  LOC="P118";    # PMOD3-8

NET Y<1>  LOC="P117";    # PMOD3-9

#NET xxx  LOC="P116";    # PMOD3-10

 

Here’s SevenSegBone.ucf for LOGI-Bone:

 

NET Mclk  LOC="P85"  | PERIOD=20ns;

# Note: PB0 and PB1 are swapped in the R1.0 schematics, sheet 6.

NET PB0   LOC="P59";     # PB0 = press to reset

NET PB1   LOC="P83";     # PB1 = press to hold

# Use LOGI-Bone PMOD1 to talk to LOGI-EDU PMOD2.

NET en2   LOC="P112";    # PMOD1-1

#NET enL  LOC="P111";    # PMOD1-2

NET en3   LOC="P67";     # PMOD1-3

NET en4   LOC="P66";     # PMOD1-4

NET en1   LOC="P62";     # PMOD1-7

NET Y<3>  LOC="P61";     # PMOD1-8

NET Y<2>  LOC="P58";     # PMOD1-9

NET dp    LOC="P57";     # PMOD1-10

# Use LOGI-Bone PMOD2 to talk to LOGI-EDU PMOD3.

NET Y<0>  LOC="P56";     # PMOD2-1

NET Y<4>  LOC="P55";     # PMOD2-2

#NET xxx  LOC="P46";     # PMOD2-3

#NET xxx  LOC="P45";     # PMOD2-4

NET Y<5>  LOC="P48";     # PMOD2-7

NET Y<6>  LOC="P47";     # PMOD2-8

NET Y<1>  LOC="P44";     # PMOD2-9

#NET xxx  LOC="P43";     # PMOD2-10

 

Note that the pin numbers are completely different from LOGI-Pi except for Mclk.

 

Attach SevenSegPi.ucf or SevenSegBone.ucf -- whichever matches your LOGI FPGA board -- to root module SevenSegDemo using ISE’s Add Source command.  Then run the ISE Implementation tools.  This takes about a minute on my PC.  There should be no errors and no significant warnings.

 

When placement and routing is done, I recommend checking the Pinout Report to make sure the pins agree with the UCF file.

 

The last step is to generate the bitstream.  The default options are mostly OK, but we’re going to set the Drive Done option so the Done LED is more visible.  Watch the ISE console log to see when it’s done generating the bitstream.

 

When ISE is done, copy SevenSegDemo.bit to Raspberry Pi and LOGI-Pi, or to BeagleBone and LOGI-Bone.  This is described in First Experiments with the ValentF(x) LOGI-Bone and First Experiments with the ValentF(x) LOGI-Pi.  When the transfer is successful, you’ll see the LED display start counting merrily from 0.0 to 999.9, and repeat.  If you push PB0, the counter resets to 0.0.  If you push PB1, the counter holds its current value.

 

The Seven-Segment BCD Counter source files LOGIdemo.v and UCFs are available in LOGIdemo.zip, along with SevenSegPi.bit and SevenSegBone.bit which are renamed copies of SevenSegDemo.bit implemented for LOGI-Pi and LOGI-Bone.

 

Conclusion

 

This was my first experience with LOGI-EDU and it went very smoothly.  The board is well-designed and well-made, and provides many useful capabilities.  I did have to cut a small notch in the front panel of my home-made open-frame RasPi case so that I could plug in LOGI-EDU.  With four Pmod connectors it’s hard to push LOGI-EDU and LOGI-Pi together and even harder to pull them apart.  Using various size screwdrivers as levers worked well.  It’s much easier with the LOGI-Bone since there are only two Pmod connectors.

 

This is a simple introduction to using LOGI-EDU, and only plays with the seven-segment LED display.  There are lots of other interesting projects, especially with the VGA output.  I’m looking forward to playing with VGA when I get a chance.

 

[This document is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.  To view a copy of this license, visit creativecommons.org/licenses/by-sa/3.0/.  No warranty is expressed or implied.  Raspberry Pi is a trademark of the Raspberry Pi Foundation.]

Abstract:  This ’blog describes my first experiments using a ValentF(x) LOGI-Pi FPGA board.  After a short overview of LOGI-Pi and its Xilinx Spartan-6 FPGA, we show how to download two examples.  The first is a pre-tested LED demo from ValentF(x) and the second is created from Verilog source code using Xilinx tools.

 

Disclaimer: This ’blog is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.  Incorrect board connections and/or an incorrect FPGA bitstream could cause damage to an FPGA and/or its connected circuitry, or cause a system to malfunction.  Users must agree that the author has NO LIABILITY for any damages.


For a LOGI-Bone version of this ’blog, see First Experiments with the ValentF(x) LOGI-Bone.


The ValentF(x) LOGI-Pi is a new FPGA development board for the Raspberry Pi Models A, B, and B+.  Its chief advantage over other FPGA boards is that RasPi GPIO pins connect directly to the FPGA so you have a flexible high-speed, low-latency connection.  LOGI-Pi also has expansion sockets compatible with 3.3V Arduino UNO, DUE, and DUEM shields as well as four Digilent Pmod™ sockets.  These connectors provide many options for add-on boards with all sorts of analog and digital capabilities.  By going with standard connectors ValentF(x) doesn’t have to design and support those add-on boards themselves.


Here is the annotated layout of LOGI-Pi, from ValentF(x)’s LOGI-Pi User Guide, copied with permission:

 

LOGI-PiPCBrev1.png

In addition to the FPGA and expansion sockets LOGI-Pi has a 32 MB SDRAM, two LEDs, two push buttons, and two DIP switches, all of which are connected to FPGA pins for your use.

 

The heart of LOGI-Pi is a Xilinx Spartan-6 LX9 FPGA in a TQ144 package.  This is a modern, high-performance FPGA which is currently the Xilinx price/performance “sweet spot”.  Here are the main features of the LX9:

 

  • Programmable array of logic cells with 5720 6-input Look-Up Tables (LUTs), 11,440 flip-flops, and carry-chain logic.  Each 6-input LUT can be treated as two 5-input LUTs with shared inputs, and 1/4 of them can be used as high-speed 64-bit distributed RAM cells with various single- and multi-port configurations.
  • 32 Block RAMs, each 18Kb for a total of 576 Kb (64KB with 9-bit bytes).  Each Block RAM has two independing read/write ports which can have different data widths.
  • 16 DSP slices, each with an 18x18 multiplier, adder, and accumulator.
  • 2 clock managers with PLLs.
  • 16 fast low-skew global clock distribution networks.

 

This same FPGA is used by a number of other FPGA development boards including Gadget Factory’s Papilio Pro and their upcoming Papilio DUO, Embedded Micro’s Mojo V3, XESS Xula2-LX9 (1.0mm pitch BGA), and Scarab Hardware’s upcoming miniSpartan6+ (also BGA).  These boards have prices similar to LOGI-Pi but do not plug into RasPi headers.

 

Spartan-6 Configuration Options

 

Spartan-6 is an SRAM-based FPGA, which means that when you first turn on power the FPGA is unconfigured and remains so until you write a configuration bitstream into it.  A bitstream is a 340KB file that defines the configuration of logic cells, routing, I/O pads, clocks, and block memory contents.  Each of the 2.7 million bits in the file sets an SRAM bit in the FPGA -- some people describe an SRAM FPGA as an large SRAM with some logic attached to it.

 

There are several ways to write a bitstream to LOGI-Pi’s FPGA.  By default, RasPi writes the bitstream by running logi_loader, which uses SPI to transfer the bitstream’s data bits and some GPIO pins for various FPGA control signals that don’t need to be fast.  Xilinx calls this Slave Serial mode since an external master -- in this case RasPi -- is treating the FPGA as a slave device.

 

You can modify LOGI-Pi to configure itself from a serial Flash chip that’s included on the board.  This is called Master Serial/SPI mode because the FPGA is in control of its own configuration.  You would typically use this mode for a stand-alone LOGI-Pi application that only uses RasPi for development.

 

But wait!  There’s more!  You can also use JTAG to configure the FPGA if you solder a 6-pin header onto LOGI-Pi.  JTAG can overwrite the bitstream configured by either of the other two modes.  For JTAG you need an external JTAG module that typically plugs into a PC USB port.  You can use the JTAG port to program LOGI-Pi if you don’t have a RasPi.

 

In this ’blog we will be using the default Slave Serial mode with RasPi writing the bitstream.

 

Installing and Powering LOGI-Pi

 

LOGI-Pi is designed to plug directly onto a RasPi Model A or B Expansion header P1, as shown in this photo from FPGA Development Board for the RASPBERRY PI.


5ddff50ca289a4954a4b508a95780218.png


The two boards are aligned except for a small LOGI-Pi overhang on the RasPi HDMI side.

 

LOGI-Pi is best suited to the RasPi Model A/B rev 2.0 PCB which has alignment holes in the same positions as LOGI-Pi mounting holes so you can screw the two boards together with nylon standoffs and screws (provided).  LOGI-Pi also plugs into a RasPi 1.0 PCB just fine, but the 1.0 PCB doesn’t have alignment holes so you don’t get the standoffs’ mechanical security.  LOGI-Pi has a rubber bumper to keep its pins from shorting into RasPi’s Ethernet jack, but they’re still pretty close and I recommend sticking electrical tape on RasPi’s Ethernet and USB connectors to make sure they don’t short to LOGI-Pi.

 

LOGI-Pi should also plug onto a RasPi Model B+ Expansion header J8, but the boards won’t be aligned as well and the RasPi B+ mounting holes aren’t compatible with LOGI-Pi.

 

The exact procedure for installing a LOGI-Pi is described in Logi-Pi - Out-Of-Box - Step by StepWhen you plug LOGI-Pi into RasPi, do so with the power off and make sure the connectors are aligned correctly.  If they aren’t, you could damage one or both boards.  For the RasPi Model B+, I think the proper way to align it is to plug LOGI-Pi into pins 1-26 of B+ Expansion header J8, i.e., the end labeled “J8”.  However, I’ve never tried it myself so I recommend checking that it’s correct before turning on power.

 

Once LOGI-Pi is installed, it can be difficult to view and probe RasPi, depending on what case you have.  In particular, the RasPi Status LEDs are covered up unless you can peek in from the side.  I use a home-made open-frame chassis with an opaque faceplate, so I can only see the glow of LEDs through a LOGI-Pi mounting hole.  (I have a 1.0 PCB so I can’t use LOGI-Pi’s standoffs.)

VertMount3a.jpg

Another consideration with RasPi is heat distribution.  The RasPi BCM2835 SoC and LAN9512/14 USB/Ethernet chips both get warm with normal use, and if they don’t have some airflow they can get quite hot, especially with some Model B 1.0 PCBs.  My vertical-mount chassis gets airflow across both sides of RasPi, which keeps the two chips from overheating.  LOGI-Pi leaves quite a bit of space between the two boards, so you probably won’t have problems.  My vertical-mount chassis works beautifully.

 

Alternatively, you can plug a 26-pin cable between RasPi and LOGI-Pi.  This allows you to use many standard RasPi cases.  I don’t know how long the cable can be before it causes signal integrity problems, especially with SPI.

 

By default, LOGI-Pi is powered from RasPi’s 5V rail, which usually comes from RasPi’s Micro USB power jack.  For small to medium experiments, RasPi provides enough power for LOGI-Pi without causing 5V to drop to the point that it causes RasPi power issues as described in the RasPi Hardware Wiki.  If you run into problems, power all your attached USB devices from an externally-powered USB hub so RasPi has more current available for LOGI-Pi.  Replacing the Micro USB power cable may also help: see Raspberry PI:- USB power cables, crashing and other problems.  If you don’t mind modifying your RasPi, you can replace its polyfuse with a single-blow fuse, which has lower resistance and therefore a lower voltage drop.

 

Your primary tool for diagnosing power problems is to measure the 5V level as described in the RasPi Troubleshooting Wiki.  You may need to probe LOGI-Pi instead of TP1 and TP2 on RasPi.  Be very careful probing the GPIO connector, because if you accidentally short 5V to 3.3V or to a signal you can kill your RasPi and/or LOGI-Pi.

 

Some RasPi Model B users back-power RasPi from an externally-powered USB hub.  This may provide higher 5V than going through the Micro USB cable.  I back-power my modified 1.0 Model B from a Motorola Atrix Lapdock which provides solid 5V power.

 

LOGI-Pi also has holes for optional headers if you want to provide it with its own power, e.g., for stand-alone applications.  If RasPi is also powered, don’t power LOGI-Pi separately unless you know what you’re doing.  In particular, make sure that if only one of the boards is powered this is not going to damage unpowered chips on the other.  You could use one of these headers to provide power to both LOGI-Pi and RasPi.  Be careful doing this, because it bypasses all of RasPi’s 5V protection circuits.  Be sure to check both the RasPi and LOGI-Pi schematics first.

 

For this ’blog I’m powering LOGI-Pi from RasPi’s Expansion header as usual.

 

LOGI-Pi has linear regulators to convert 5V to 3.3V for FPGA I/O and from 3.3V to 1.2V for FPGA core logic.  These regulators could get hot if the FPGA is doing a lot.  Some newer FPGA boards like Papilio Pro and DUO have switching regulators for these voltages which can save a lot of power.

 

Preparing Raspbian GNU/Linux for LOGI-Pi

 

To develop FPGA designs using LOGI-Pi, you will need two computers: an x86 PC to run Xilinx FPGA software, and your RasPi with LOGI-Pi installed.  The Xilinx software generates bitstreams, which you then transfer from the PC to your RasPi, and then you’ll run a program on RasPi to write bitstreams to LOGI-Pi.  There are various ways to do this, but for this ’blog I’ll concentrate on what I do with my RasPi setup.

 

I have a 256MB RasPi Model B running 2014-09-09 Raspbian Wheezy, downloaded from raspberrypi.org.  I use a Motorola Atrix Lapdock as my keyboard, mouse, and display.  I can also use a GNU/Linux PC running Ubuntu 12.04 LTS to talk to RasPi over Ethernet using a Terminal window with ssh (secure shell).  The Terminal window is convenient for LOGI-Pi development since I can use the PC’s display, keyboard, and mouse for everything once RasPi has booted.  The Lapdock display is useful for seeing if RasPi is booting and shutting down properly.

 

To talk to RasPi from the PC, you need to know the user name and password of a RasPi user who has superuser privileges.  I’m going to call this user george.  You can also use the default user pi if you don’t want to create a separate user.

 

You also need to know RasPi’s IP address. It’s normally assigned automatically using DHCP by a router or the PC.  My RasPi’s IP address is 192.168.0.106, which I found by giving the ifconfig command on RasPi using Lapdock.  For various ways to connect to RasPi so you can get its IP address, see Logi-Pi Quick Start Guide,

raspberrypi.org,  and RasPi Beginners Wiki.

 

Next, george needs a subdirectory for storing LOGI-Pi bitstreams.  I’ll assume this subdirectory is called LOGI with full RasPi path /home/george/LOGI or ~george/LOGI.

 

Finally, you need to enable RasPi’s SPI (Serial Peripheral Interconnect) device drivers and obtain or build LOGI-Pi’s FPGA loader logi_loader.  One way to do this is to load a pre-configured RasPi OS image from ValentF(x), as described in LOGI-Pi Quick Start Guide

 

If you prefer to use an official RasPi release from raspberrypi.org, you will need to do a fairly simple procedure to enable SPI and build logi_loader.  It’s described in another section of LOGI-Pi Quick Start Guide.

 

I found that with 2014-09-09 Raspbian Wheezy I could leave out a few steps.  First, check whether the SPI device drivers are already present.  You can tell by listing /dev on a RasPi terminal:

 

ls /dev

 

See if there are device drivers /dev/spidev0.0 and /dev/spidev0.1.  If not, SPI is “blacklisted” and you will need to enable it by editing /etc/modprobe.d/raspi-blacklist.conf.  First, change to the system directory /etc/modprobe.d and make a backup copy of raspi-blacklist.conf:

 

cd /etc/modprobe.d

sudo cp -p raspi-blacklist.conf raspi-blacklist.orig

 

Next, edit raspi-blacklist.conf using nano or a different text editor.  You’ll need to use sudo.  The original file looks something like this:

 

# blacklist spi and i2c by default (many users don't need them)

 

blacklist spi-bcm2708

blacklist i2c-bcm2708

blacklist snd-soc-pcm512x

blacklist snd-soc-wm8804

 

Comment out the bcm2708 lines so that SPI and I²C will be enabled next time you reboot:

 

# blacklist spi and i2c by default (many users don't need them)

 

#blacklist spi-bcm2708

#blacklist i2c-bcm2708

blacklist snd-soc-pcm512x

blacklist snd-soc-wm8804

 

Then save the file (ctl-X on nano).  Finally, reboot RasPi to apply the changed raspi-blacklist.conf:

 

sudo reboot

 

After RasPi reboots, /dev/spidev0.0 and /dev/spidev0.1 should be present.

 

Next we need to build logi_loader.  First see if it’s already in /usr/bin.  Otherwise you need to rebuild it from source code at GitHub.  2014-09-09 Raspbian Wheezy already has gcc, make, and git so you don’t need to install them.

 

First, decide where you want to build logi-tools, e.g., in your LOGI directory created earlier.  With the Internet attached to your RasPi via Ethernet, enter these commands on a RasPi terminal:

 

cd ~/LOGI

git clone https://github.com/fpga-logi/logi-tools.git

 

This downloads the source code and makefiles for all LOGI tools.  Next, build logi_loader:

 

cd logi-tools/logipi_loader

make

 

This compiles logi_loader from C source code.  Finally, copy logi_loader to /usr/bin:

 

sudo make install

 

The executable file /usr/bin/logi_loader should now exist.  You are now ready to write FPGA bitstreams to your LOGI-Pi.


Experiment 1:  Writing a Pre-tested Bitstream to LOGI-Pi

 

Now let’s try writing a bitstream to LOGI-Pi.  ValentF(x) has a nice blinking LED demo which they describe in the ValentF(x) Wiki.  However, they don’t provide a LOGI-Pi bitstream file for it.  You can build the bitstream using the instructions in LOGI-Pi Quick Start Guide but this is pretty complex for a first exercise.  So I’ve compiled the example and put the bitstream file logipi_blink.bit in LOGIdemo.zip.

 

The procedure in this section uses GNU commands entered in two PC Terminal windows, one for the PC and one for RasPi.  If you prefer GUIs and/or your PC is running Windows, ValentF(x) has other procedures with GUI equivalents for ssh and scp: SSH Guide, SCP Guide.  You can also enter RasPi commands on your attached RasPi keyboard and display instead of using ssh.

 

Here are the commands I use on my RasPi setup.  The commands should be similar on other setups.  If you need help, please ask questions in the comments.  As with most GNU/Linux commands, use man to get reference information.  For example, the command “man ssh” describes how to use ssh.

 

To keep things clear, I will prefix commands entered on the PC with “PC$” and those entered on RasPi with “RasPi$”.  I’ll use 192.168.0.106 as my RasPi IP address and george as my user name -- you’ll need to substitute your own.

 

  1. With power off, plug LOGI-Pi onto your RasPi as described earlier.

  2. Plug in your RasPi.  The RasPi and LOGI-Pi power LEDs should turn on and you should see lots of flashing on the RasPi Activity LED as the operating system boots (assuming the LED is visible with LOGI-Pi installed).

  3. Connect an Ethernet cable between RasPi and your router or Ethernet switch, or directly to your PC.  Once RasPi has booted the RasPi Link LED should come on.

  4. After giving RasPi time to boot, open a Terminal window on your PC and ping RasPi so you know you can talk to it:

        PC$ ping 192.168.0.106

    ping should show a series of successful data transfers and you should see RasPi’s Ethernet activity LED blink as the pings occur.

  5. Log onto RasPi using ssh and the IP address you verified in the last step.  On your PC, give the command:

        PC$ ssh george@192.168.0.106

    The first time I did this ssh asked me to confirm that this was correct.  Then ssh asks for george’s RasPi password.  If the RasPi user name is the same as your PC user name you can simply write:

        PC$ ssh 192.168.0.106

    Once ssh has accepted the password, you’re in a command shell on RasPi and you can enter GNU commands exactly as if you were on a RasPi serial port or directly-attached display and keyboard.

  6. You are now in george’s home directory on RasPi.  Let’s change to the LOGI directory:

        RasPi$ cd LOGI

  7. Back on the PC, open another Terminal for PC commands.  Let’s assume the PC also has a subdirectory LOGI and that we’ve downloaded logipi_blink.bit to that directory.  Let’s change to the PC’s LOGI directory:

        PC$ cd ~/LOGI

  8. You are now ready to transfer logipi_blink.bit from the PC to RasPi.  Use scp (secure copy) which in turn uses ssh for data transfers and authentication.  Here’s the PC command:

        PC$ scp logipi_blink.bit george@192.168.0.106:LOGI/.

    This copies logipi_blink.bit from the current PC directory to ~george/LOGI on RasPi, keeping the same file name.  scp will ask for george’s password to authenticate the transfer.

  9. On RasPi, make sure the file arrived by listing LOGI’s .bit files:

        RasPi$ ls -l *.bit

    Spartan-6 LX9 .bit files are approximately 340KB.

  10. The last step is to write logipi_blink.bit to LOGI-Pi’s FPGA:

        RasPi$ sudo logi_loader logipi_blink.bit

  11. If the transfer is successful, you should see a pretty blinking pattern on LOGI-Pi’s LED1 and LED0.

    If you look carefully, you will also see that LOGI-Pi’s Done LED is on.  It’s near pins 23 and 25 of the RasPi expansion connector.  The LED turns on very faintly for logipi_blink.bit.  This is because it’s pulled up by a weak FPGA resistor instead of being driven high by a transistor.

  12. When you are done playing with RasPi, be sure to shut it down properly so you don’t corrupt the file system:

        RasPi$ sudo shutdown -h now

Experiment 2:  Creating and Downloading a New Bitstream

 

In this experiment, I create a new bitstream using Xilinx tools and download it to LOGI-Pi using the same procedure as Experiment 1.  I’m not going to tell you how to install or use the Xilinx tools since that’s a long procedure and can be found elsewhere, for example Logi-Pi Quick Start Guide.  Gadget Factory also has some tutorials: Install ISE WebPack and Papilio Xilinx ISE WebPack VHDL Getting Started.

 

Experiment 2 creates a 4-bit binary counter that displays its two LSbs using LOGI-Pi LEDs and its two MSbs using external LEDs driven by two Pmod pins.  The 4-bit counter is easy.  The difficult part is dividing LOGI-Pi’s 50 MHz oscillator down to a value visible by humans, in this case 4 Hz.

 

Here’s the Verilog code for the clock generator.  Instead of dividing by 12,500,000 using a single 24-bit counter, I first divide by 1000 using a 10-bit counter and then divide by 12,500 using a 14-bit counter.

 

module ClockDiv(Mclk, clk4Hz);

input  Mclk;           // 50 MHz master clock.

output clk4Hz;         // 4 Hz clock-enable pulse.

reg    clk4Hz;

 

    reg   [9:0] P;             // Divide by 1000 prescaler.

    wire [10:0] nextP = P + 1;

    wire Pcarry = nextP[10];   // Prescaler carry out, pulses at 50 KHz.

    reg  clk50KHz;             // Glitch-free 50 KHz clock enable pulse.

    reg  [13:0] Q;             // Divide by 12,500 counter.

    wire [14:0] nextQ = Q + clk50KHz;

    wire Qcarry = nextQ[14];   // Low-freq carry out, pulses at 4 Hz.

 

    always @(posedge Mclk)

    begin

        // Divide by 1000: when nextP has carry out, set

        // P = -1000 = 1024-1000 = 24.  Pcarry is sync reset.

        if (Pcarry) P <= 10'd24; else P <= nextP[9:0];

        clk50KHz <= Pcarry;

        // Divide by 12,500: when nextQ has carry out, set

        // Q = -12,500 = 16,384-12,500 = 3,884.  Qcarry is sync reset.

        if (Qcarry) Q <= 14'd3884; else Q <= nextQ[13:0];   

        clk4Hz <= Qcarry;

    end

endmodule

 

This is a rather unusual way to express counters, but maps well to Xilinx logic.  People usually make a divide-by-n counter by resetting it to 0 and then detecting when it reaches n-1.  However, this requires logic to compare to n-1.  So instead, we preset the counter to −n and increment it until it reaches all ones, which we detect using the carry out of the counter’s adder chain.

 

Now that we have a 4 Hz pulse stream, it’s easy to make the 4-bit counter:

 

module UpCounter(Mclk, reset, up, K);

input  Mclk;         // 50 MHz master clock.

input  reset;        // Asynchronous reset.

input  up;           // Counter enable.

output [3:0] K;      // 4-bit counter;

reg    [3:0] K;

 

    wire clk4Hz;     // 4 Hz demo clock enable pulse.

    wire [4:0] nextK = K + up;

 

    ClockDiv cd(Mclk, clk4Hz);  // Instance of ClockDiv module.

    always @(posedge Mclk or posedge reset)

    if (reset) K <= 0; else if (clk4Hz) K <= nextK[3:0];

endmodule   

 

The counter includes asynchronous reset which we’ll connect to LOGI-Pi’s PB0, and an enable input which we’ll connect to PB1.  Normally the counter increments at 4 Hz.  If you press PB0, the counter resets to 0 and stays there.  If you press PB1, the counter holds its current value.

 

Finally, here’s the root module that connects counter bits K[3:0] to the LEDs and connects PB0 and PB1 with the proper polarities:

 

module UpCountPi(Mclk, PB0, PB1, LED0, LED1, LED2, LED3);

input  Mclk;           // 50 MHz master clock.

input  PB0;            // Press to reset = active-low.

input  PB1;            // Press to hold = active-high enable.

output LED0, LED1;     // LSbs are active high.

output LED3, LED2;     // MSbs are active low.

 

    wire    [3:0] K;        // 4-bit counter;

 

    UpCounter uc(Mclk, !PB0 /*reset*/, PB1 /*up*/, K);

 

    assign LED0 =  K[0];

    assign LED1 =  K[1];

    assign LED2 = !K[2];

    assign LED3 = !K[3];

endmodule   

 

Now that we have the Verilog code for Experiment 2, we can compile it using Xilinx ISE (Integrated Software Environment).  I’m using the ISE 12.4 free-as-in-beer WebPACK Editon on Ubuntu 12.04 LTS, which mostly works except for some graphical tools I don’t need.  I’ve created an ISE project named LOGIdemo in LOGI, so the many files ISE generates -- including the bitstream -- will be in LOGI/LOGIdemo.

 

The design synthesizes without any errors or warnings on ISE 12.4.  It may generate warnings in other versions.

 

Now, before implementing the design you need to tell ISE how to assign signals to pins.  There’s a graphical tool to do this in ISE, but IMO it’s a lot easier to create and edit a User Constraint File.  The name of the UCF normally matches the root module’s name, so here’s UpCountPi.ucf:

 

NET Mclk LOC="P85"  | IOSTANDARD=LVTTL | PERIOD=20ns;

NET PB0  LOC="P102" | IOSTANDARD=LVTTL;  # PB0 = press to reset

NET PB1  LOC="P101" | IOSTANDARD=LVTTL;  # PB1 = press to hold

NET LED0 LOC="P105" | IOSTANDARD=LVTTL;  # LED0

NET LED1 LOC="P104" | IOSTANDARD=LVTTL;  # LED1

NET LED2 LOC="P5"   | IOSTANDARD=LVTTL;  # PMOD1-1

NET LED3 LOC="P2"   | IOSTANDARD=LVTTL;  # PMOD1-2

 

I found the pin numbers in the LOGI-Pi R1.0 schematics.  The LOGI-Pi Quick Start Guide shows you how to find them.  In the 4/23/2014 LOGI-Pi R1.1 schematics the PMOD1 and PMOD2 connections appear to be exchanged on sheet 4.  That’s OK because they’re also exchanged on sheet 6 so the errors cancel out.

 

Once I have added UpCountPi.ucf to root module UpCountPi using ISE’s Add Source command, I can run the ISE implementation tools.  This takes less than a minute on my PC.  There should be no errors and no significant warnings.

 

When placement and routing is done, I recommend checking the Pinout Report to make sure the pins agree with UpCountPi.ucf.

 

The last step is to generate the bitstream.  The default options are mostly OK, but we’re going to set the Drive Done option so the Done LED is more visible.  Watch the ISE console log to see when it’s done generating the bitstream.

 

When ISE is done, we can copy UpCountPi.bit to RasPi and LOGI-Pi.  This is basically the same as steps 7-11 in Experiment 1:

 

  1. On the PC, change to the directory that contains UpCountPi.bit, in my case LOGI/LOGIdemo.

        PC$ cd ~/LOGI/LOGIdemo

  2. Transfer UpCountPi.bit from the PC to RasPi using scp:

        PC$ scp UpCountPi.bit george@192.168.0.106:LOGI/.

  3. On RasPi, make sure the file arrived by listing LOGI’s .bit files:

        RasPi$ ls -l *.bit

  4. Write UpCountPi.bit to LOGI-Pi’s FPGA using logi_loader:

        RasPi$ sudo logi_loader UpCountPi.bit

  5. If the transfer is successful, you should see a binary counting pattern on LED1 and LED0.  If you attach LEDs to PMOD1 pins 1 and 2 you get the two MSbs of the 4-bit counter.  These are active-low LEDs, so connect their cathodes to PMOD1 pins and their anodes to +3.3V (PMOD1 pin 6) through suitable resistors, e.g., 560Ω.

    If you push PB0, the counter resets to 0000.  If you push PB1, the counter holds its current value.

    You should also clearly see the Done LED, since it’s now driven high by an FPGA transistor.

The Experiment 2 source files LOGIdemo.v and UpCountPi.ucf are available in LOGIdemo.zip, along with UpCountPi.bit.

 

Conclusion

 

This was my first experience with LOGI-Pi and it went very smoothly.  The board is well-designed and well-made, and provides many useful capabilities.  Since I’ve done a lot of designs with other FPGAs and I’ve used ISE a lot, I had more trouble learning about device driver blacklists and git than the FPGA-specific tasks.

 

This is a simple introduction to using LOGI-Pi, intended to help you see results with minimal effort and frustration.  LOGI-Pi is a very powerful board, capable of myriad interesting projects.  I plan to show a few of these in upcoming ’blogs in this series.


[This document is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.  To view a copy of this license, visit creativecommons.org/licenses/by-sa/3.0/.  No warranty is expressed or implied.  Raspberry Pi is a trademark of the Raspberry Pi Foundation.]

Abstract:  This ’blog describes my first experiments using a ValentF(x) LOGI-Bone FPGA board.  After a short overview of LOGI-Bone and its Xilinx Spartan-6 FPGA, we show how to download two examples.  The first is a pre-tested LED demo from ValentF(x) and the second is created from Verilog source code using Xilinx tools.

 

Disclaimer: This ’blog is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.  Incorrect board connections and/or an incorrect FPGA bitstream could cause damage to an FPGA and/or its connected circuitry, or cause a system to malfunction.  Users must agree that the author has NO LIABILITY for any damages.


For a LOGI-Pi version of this ’blog, see First Experiments with the ValentF(x) LOGI-Pi.


The ValentF(x) LOGI-Bone is a new FPGA development board for the BeagleBone, both White and Black.  Its chief advantage over other FPGA boards is that 27 (optionally 29) BBone pins connect directly to the FPGA so you have a flexible high-speed, low-latency connection.  LOGI-Bone also has expansion sockets compatible with 3.3V Arduino UNO, DUE, and DUEM shields as well as two Digilent Pmod™ sockets.  These connectors provide many options for add-on boards with all sorts of analog and digital capabilities.  By going with standard connectors ValentF(x) doesn’t have to design and support those add-on boards themselves.

 

Here is the annotated layout of LOGI-Bone, from ValentF(x)’s LOGI-Bone User Guide, copied with permission:

 

LOGI-BonePCBrev1.png

In addition to the FPGA and expansion sockets LOGI-Bone has a 32 MB SDRAM, two LEDs, two push buttons, and two DIP switches, all of which are connected to FPGA pins for your use.

 

The heart of LOGI-Bone is a Xilinx Spartan-6 LX9 FPGA in a TQ144 package.  This is a modern, high-performance FPGA which is currently the Xilinx price/performance “sweet spot”.  Here are the main features of the LX9:

 

  • Programmable array of logic cells with 5720 6-input Look-Up Tables (LUTs), 11,440 flip-flops, and carry-chain logic.  Each 6-input LUT can be treated as two 5-input LUTs with shared inputs, and 1/4 of them can be used as high-speed 64-bit distributed RAM cells with various single- and multi-port configurations.
  • 32 Block RAMs, each 18Kb for a total of 576 Kb (64KB with 9-bit bytes).  Each Block RAM has two independing read/write ports which can have different data widths.
  • 16 DSP slices, each with an 18x18 multiplier, adder, and accumulator.
  • 2 clock managers with PLLs.
  • 16 fast low-skew global clock distribution networks.

 

This same FPGA is used by a number of other FPGA development boards including Gadget Factory’s Papilio Pro and their upcoming Papilio DUO, Embedded Micro’s Mojo V3, XESS Xula2-LX9 (1.0mm pitch BGA), and Scarab Hardware’s upcoming miniSpartan6+ (also BGA).  These boards have prices similar to LOGI-Bone but do not plug into BeagleBone headers.

 

Spartan-6 Configuration Options

 

Spartan-6 is an SRAM-based FPGA, which means that when you first turn on power the FPGA is unconfigured and remains so until you write a configuration bitstream into it.  A bitstream is a 340KB file that defines the configuration of logic cells, routing, I/O pads, clocks, and block memory contents.  Each of the 2.7 million bits in the file sets an SRAM bit in the FPGA -- some people describe an SRAM FPGA as an large SRAM with some logic attached to it.

 

There are several ways to write a bitstream to LOGI-Bone’s FPGA.  By default, BBone writes the bitstream by running an FPGA loader program or simply copying a bitstream file to /dev/logibone.  The LOGI-Bone device driver uses SPI to transfer the bitstream’s data bits, plus I²C for various FPGA control signals that don’t need to be fast.  Xilinx calls this Slave Serial mode since an external master -- in this case BBone -- is treating the FPGA as a slave device.

 

You can modify LOGI-Bone to configure itself from a serial Flash chip that’s included on the board.  This is called Master Serial/SPI mode because the FPGA is in control of its own configuration.  You would typically use this mode for a stand-alone LOGI-Bone application that only uses BBone for development.

 

But wait!  There’s more!  You can also use JTAG to configure the FPGA if you solder a 6-pin header onto LOGI-Bone.  JTAG can overwrite the bitstream configured by either of the other two modes.  For JTAG you need an external JTAG module that typically plugs into a PC USB port.  You can use the JTAG port to program LOGI-Bone if you don’t have a BeagleBone.

 

In this ’blog we will be using the default Slave Serial mode with BBone writing the bitstream.

 

Powering LOGI-Bone

 

By default, LOGI-Bone is powered from BBone’s “System 5V” rail.  SYS-5V can come from either BBone’s Mini USB device port or BBone’s 5V power jack.  Using the USB port for power is generally not the best idea, because by default it’s limited to 500 mA which may not be enough for both BBone and LOGI-Bone (plus any plugged-in interfaces) depending on what each board is doing.  It’s a lot safer to plug an external power supply into BBone’s 5V power jack, which can accept up to 2A (perhaps more).  Be sure your power supply provides regulated 5V (+/-5%) and has the proper plug polarity, as specified in BBone documentation.

 

LOGI-Bone also has holes for a two-pin header if you want to provide it with its own power, e.g., for stand-alone applications.  If BBone is also powered, don’t use the LOGI-Bone header unless you know what you’re doing.  In particular, make sure that if only one of the boards is powered this is not going to damage unpowered chips on the other.

 

For this ’blog I’m powering BBone using the 5V power jack and letting BBone’s SYS-5V provide power to LOGI-Bone as usual.

 

LOGI-Bone has linear regulators to convert SYS-5V to 3.3V for FPGA I/O and from 3.3V to 1.2V for FPGA core logic.  These regulators could get hot if the FPGA is doing a lot.  Some newer FPGA boards like Papilio Pro and DUO have switching regulators for these voltages which can save a lot of power.

 

Preparing BeagleBone GNU/Linux for LOGI-Bone

 

Before using LOGI-Bone, make sure your BBone’s operating system has the necessary device drivers.  My BBone is running BBone Debian 7.5 2014-05-14 downloaded from BeagleBoard.org Latest Firmware Images.  It has Linux kernel 3.8.13-bone50 and includes LOGI-Bone drivers /dev/logibone and /dev/logibone_mem.  ValentF(x) has other images that work with LOGI-Bone: see Logi-Bone Quick Start Guide.

 

You will need to use an x86 PC to run Xilinx software to generate bitstreams.  The PC needs to transfer those bitstream files to your BBone and you need a way to tell your BBone to write bitstreams to LOGI-Bone.  There are various ways to do this, but for this ’blog I’ll concentrate on what I do with my BBone setup.

 

I have a minimal BeagleBone configuration with a 256MB BBone White, no capes installed other than the LOGI-Bone, and no attached keyboard, mouse, or display.  I use a GNU/Linux PC running Ubuntu 12.04 LTS to talk to BBone over Ethernet, using either a Terminal window with ssh (secure shell) or X Windows to run BBone programs that have GUIs.  This minimal configuration works well for LOGI-Bone development since you can use the PC’s display, keyboard, and mouse for everything.

 

To talk to the BBone from the PC, you need to know the user name and password of a BBone user who has superuser privileges.  I’m going to call this user george.  You can also use the default user debian if you don’t want to create a separate user.

 

You also need to know BBone’s IP address. It’s normally assigned automatically using DHCP by a router or the PC.  My BBone’s IP address is 192.168.0.106, which I found by giving the ifconfig command on BBone when talking to it as a serial terminal over USB (this requires a BBone White).  You can also talk to BBone using Network over USB at 192.168.7.2 provided that your PC OS has the correct drivers.  For various ways to connect to BBone so you can get its IP address, see Logi-Bone Quick Start Guide, Getting Started with BeagleBone & BeagleBone Black, Adafruit’s SSH to BeagleBone Black over USB, or BeagleBone: Getting Started.

 

Finally, george needs a subdirectory for storing LOGI-Bone bitstreams.  I’ll assume this subdirectory is called LOGI with full BBone path /home/george/LOGI or ~george/LOGI.

 

Experiment 1:  Writing a Pre-tested Bitstream to LOGI-Bone

 

Now let’s try writing a bitstream to LOGI-Bone.  ValentF(x) has a nice blinking LED demo which they describe at the ValentF(x) Wiki.  You can download the bit file logibone_r1_blink.bit from GitHub.

 

The procedure in this section uses GNU commands entered in two PC Terminal windows, one for the PC and one for BBone.  If you prefer GUIs and/or your PC is running Windows, ValentF(x) has other procedures with a GUI equivalent for scp and an alternative to dd:  see Logi-Bone Quick Start Guide.

 

Here are the commands I use on my BeagleBone setup.  The commands should be similar on other setups.  If you need help, please ask questions in the comments.  As with most GNU/Linux commands, use man to get reference information.  For example, the command “man ssh” describes how to use ssh.

 

To keep things clear, I will prefix commands entered on the PC with “PC$” and those entered on BBone with “BBone$”.  I’ll use 192.168.0.106 as my BBone IP address and george as my user name -- you’ll need to substitute your own.

 

  1. With power off, plug LOGI-Bone onto your BBone.  Be sure the two 46-pin connectors are lined up and that the BBone Ethernet jack is in LOGI-Bone’s notch.  Carefully squeeze the boards together until the LOGI-Bone pins are fully inserted in the BBone sockets.

  2. Plug 5V power into the BBone’s power jack and connect an Ethernet cable between BBone and your router or Ethernet switch, or directly to your PC.

    Alternatively, you can connect a USB cable between BBone and your PC and use Network over USB.  In this case plug 5V power in before connecting the USB cable, or else BBone will try to power itself from USB which may not provide enough current.

  3. The BBone and LOGI-Bone power LEDs should turn on and you should see lots of activity on the other BBone LEDs as the operating system boots.  One of the BBone LEDs is a “heartbeat” that tells you the OS is running OK.

  4. After giving BBone time to boot, open a Terminal window on your PC and ping BBone so you know you can talk to it:

        PC$ ping 192.168.0.106

    ping should show a series of successful data transfers and you should see BBone’s Ethernet activity LED blink as the pings occur.

  5. Log onto BBone using ssh and the IP address you verified in the last step.  On your PC, give the command:

        PC$ ssh george@192.168.0.106

    The first time I did this ssh asked me to confirm that this was correct.  Then ssh asks for george’s BBone password.  If the BBone user name is the same as your PC user name you can simply write:

        PC$ ssh 192.168.0.106

    Once ssh has accepted the password, you’re in a command shell on BBone and you can enter GNU commands exactly as if you were on a BBone serial port or directly-attached display and keyboard.

  6. You are now in george’s home directory on BBone.  Let’s change to the LOGI directory:

        BBone$ cd LOGI

  7. Back on the PC, open another Terminal for PC commands.  Let’s assume the PC also has a subdirectory LOGI and that we’ve downloaded logibone_r1_blink.bit to that directory.  Let’s change to the PC’s LOGI directory:

        PC$ cd ~/LOGI

  8. You are now ready to transfer logibone_r1_blink.bit from the PC to BBone.  Use scp (secure copy) which in turn uses ssh for data transfers and authentication.  Here’s the PC command:

        PC$ scp logibone_r1_blink.bit george@192.168.0.106:LOGI/.

    This copies logibone_r1_blink.bit from the current PC directory to ~george/LOGI on BBone, keeping the same file name.  scp will ask for george’s password to authenticate the transfer.

  9. On BBone, make sure the file arrived by listing LOGI’s .bit files:

        BBone$ ls -l *.bit

    Spartan-6 LX9 .bit files are approximately 340KB.

  10. The last step is to write logibone_r1_blink.bit to LOGI-Bone’s FPGA.  One simple way to do this is using dd on BBone:

        BBone$ sudo dd if=logibone_r1_blink.bit of=/dev/logibone bs=4M

    The output file is LOGI-Bone’s device driver from ValentF(x), and bs=4M makes sure the bitstream is written as a single block transfer.  The permissions on /dev/logibone require superuser privileges.  sudo may ask you to enter george’s password.

  11. If the transfer is successful, you should see a pretty blinking pattern on LOGI-Bone’s LED1 and LED0.

    If you look carefully, you will also see that LOGI-Bone’s Done LED is on.  It’s between the Pmod™ connectors.  The LED turns on very faintly for logibone_r1_blink.bit.  This is because it’s pulled up by a weak FPGA resistor instead of being driven high by a transistor.

  12. When you are done playing with BBone, be sure to shut it down properly so you don’t corrupt the file system:

        BBone$ sudo shutdown -h now

Experiment 2:  Creating and Downloading a New Bitstream

 

In this experiment, I create a new bitstream using Xilinx tools and download it to LOGI-Bone using the same procedure as Experiment 1.  I’m not going to tell you how to install or use the Xilinx tools since that’s a long procedure and can be found elsewhere, for example at the Logi-Bone Quick Start Guide.

 

Experiment 2 creates a 4-bit binary counter that displays its two LSbs using LOGI-Bone LEDs and its two MSbs using external LEDs driven by two Pmod pins.  The 4-bit counter is easy.  The difficult part is dividing LOGI-Bone’s 50 MHz oscillator down to a value visible by humans, in this case 4 Hz.

 

Here’s the Verilog code for the clock generator.  Instead of dividing by 12,500,000 using a single 24-bit counter, I first divide by 1000 using a 10-bit counter and then divide by 12,500 using a 14-bit counter.

 

module ClockDiv(Mclk, clk4Hz);

input  Mclk;           // 50 MHz master clock.

output clk4Hz;         // 4 Hz clock-enable pulse.

reg    clk4Hz;

 

    reg   [9:0] P;             // Divide by 1000 prescaler.

    wire [10:0] nextP = P + 1;

    wire Pcarry = nextP[10];   // Prescaler carry out, pulses at 50 KHz.

    reg  clk50KHz;             // Glitch-free 50 KHz clock enable pulse.

    reg  [13:0] Q;             // Divide by 12,500 counter.

    wire [14:0] nextQ = Q + clk50KHz;

    wire Qcarry = nextQ[14];   // Low-freq carry out, pulses at 4 Hz.

 

    always @(posedge Mclk)

    begin

        // Divide by 1000: when nextP has carry out, set

        // P = -1000 = 1024-1000 = 24.  Pcarry is sync reset.

        if (Pcarry) P <= 10'd24; else P <= nextP[9:0];

        clk50KHz <= Pcarry;

        // Divide by 12,500: when nextQ has carry out, set

        // Q = -12,500 = 16,384-12,500 = 3,884.  Qcarry is sync reset.

        if (Qcarry) Q <= 14'd3884; else Q <= nextQ[13:0];   

        clk4Hz <= Qcarry;

    end

endmodule

 

This is a rather unusual way to express counters, but maps well to Xilinx logic.  People usually make a divide-by-n counter by resetting it to 0 and then detecting when it reaches n-1.  However, this requires logic to compare to n-1.  So instead, we preset the counter to −n and increment it until it reaches all ones, which we detect using the carry out of the counter’s adder chain.

 

Now that we have a 4 Hz pulse stream, it’s easy to make the 4-bit counter:

 

module UpCounter(Mclk, reset, up, K);

input  Mclk;         // 50 MHz master clock.

input  reset;        // Asynchronous reset.

input  up;           // Counter enable.

output [3:0] K;      // 4-bit counter;

reg    [3:0] K;

 

    wire clk4Hz;     // 4 Hz demo clock enable pulse.

    wire [4:0] nextK = K + up;

 

    ClockDiv cd(Mclk, clk4Hz);  // Instance of ClockDiv module.

    always @(posedge Mclk or posedge reset)

    if (reset) K <= 0; else if (clk4Hz) K <= nextK[3:0];

endmodule   

 

The counter includes asynchronous reset which we’ll connect to LOGI-Bone’s PB0, and an enable input which we’ll connect to PB1.  Normally the counter increments at 4 Hz.  If you press PB0, the counter resets to 0 and stays there.  If you press PB1, the counter holds its current value.

 

Finally, here’s the root module that connects counter bits K[3:0] to the LEDs and connects PB0 and PB1 with the proper polarities:

 

module UpCountBone(Mclk, PB0, PB1, LED0, LED1, LED2, LED3);

input  Mclk;           // 50 MHz master clock.

input  PB0;            // Press to reset = active-low.

input  PB1;            // Press to hold = active-high enable.

output LED0, LED1;     // LSbs are active high.

output LED3, LED2;     // MSbs are active low.

 

    wire    [3:0] K;        // 4-bit counter;

 

    UpCounter uc(Mclk, !PB0 /*reset*/, PB1 /*up*/, K);

 

    assign LED0 =  K[0];

    assign LED1 =  K[1];

    assign LED2 = !K[2];

    assign LED3 = !K[3];

endmodule   

 

Now that we have the Verilog code for Experiment 2, we can compile it using Xilinx ISE (Integrated Software Environment).  I’m using the ISE 12.4 free-as-in-beer WebPACK Editon on Ubuntu 12.04 LTS, which mostly works except for some graphical tools I don’t need.  I’ve created an ISE project named LOGIdemo in LOGI, so the many files ISE generates -- including the bitstream -- will be in LOGI/LOGIdemo.

 

The design synthesizes without any errors or warnings on ISE 12.4.  It may generate warnings in other versions.

 

Now, before implementing the design you need to tell ISE how to assign signals to pins.  There’s a graphical tool to do this in ISE, but IMO it’s a lot easier to create and edit a User Constraint File.  The name of the UCF normally matches the root module’s name, so here’s UpCountBone.ucf:

 

NET Mclk LOC="P85"  | IOSTANDARD=LVTTL | PERIOD=20ns;

# Note: PB0 and PB1 are swapped in the R1.0 schematics, sheet 6.

NET PB0  LOC="P59"  | IOSTANDARD=LVTTL;  # PB0 = press to reset

NET PB1  LOC="P83"  | IOSTANDARD=LVTTL;  # PB1 = press to hold

NET LED0 LOC="P74"  | IOSTANDARD=LVTTL;  # LED0

NET LED1 LOC="P140" | IOSTANDARD=LVTTL;  # LED1

NET LED2 LOC="P112" | IOSTANDARD=LVTTL;  # PMOD1-1

NET LED3 LOC="P111" | IOSTANDARD=LVTTL;  # PMOD1-2

 

I found the pin numbers in the LOGI-Bone R1.0 schematics.  The LOGI-Bone Quick Start Guide shows you how to find them.  I had to swap PB0 and PB1 pin numbers due to a minor error in the 5/27/2014 LOGI-Bone R1.0 schematics.

 

Once I have added UpCountBone.ucf to root module UpCountBone using ISE’s Add Source command, I can run the ISE Implementation tools.  This takes less than a minute on my PC.  There should be no errors and no significant warnings.

 

When placement and routing is done, I recommend checking the Pinout Report to make sure the pins agree with UpCountBone.ucf.

 

The last step is to generate the bitstream.  The default options are mostly OK, but we’re going to set the Drive Done option so the Done LED is more visible.  Watch the ISE console log to see when it’s done generating the bitstream.

 

When ISE is done, we can copy UpCountBone.bit to BBone and LOGI-Bone.  This is basically the same as steps 7-11 in Experiment 1:

 

  1. On the PC, change to the directory that contains UpCountBone.bit, in my case LOGI/LOGIdemo.

        PC$ cd ~/LOGI/LOGIdemo

  2. Transfer UpCountBone.bit from the PC to BBone using scp:

        PC$ scp UpCountBone.bit george@192.168.0.106:LOGI/.

  3. On BBone, make sure the file arrived by listing LOGI’s .bit files:

        BBone$ ls -l *.bit

  4. Write UpCountBone.bit to LOGI-Bone’s FPGA using dd:

        BBone$ sudo dd if=UpCountBone.bit of=/dev/logibone bs=4M

  5. If the transfer is successful, you should see a binary counting pattern on LED1 and LED0.  If you attach LEDs to PMOD1 pins 1 and 2 you get the two MSbs of the 4-bit counter.  These are active-low LEDs, so connect their cathodes to PMOD1 pins and their anodes to +3.3V (PMOD1 pin 6) through suitable resistors, e.g., 560Ω.

    If you push PB0, the counter resets to 0000.  If you push PB1, the counter holds its current value.

    You should also clearly see the Done LED, since it’s now driven high by an FPGA transistor.

The Experiment 2 source files LOGIdemo.v and UpCountBone.ucf are available in LOGIdemo.zip, along with UpCountBone.bit.

 

Conclusion

 

This was my first experience with LOGI-Bone and it went very smoothly.  The board is well-designed and well-made, and provides many useful capabilities.  Since I’ve done a lot of designs with other FPGAs and I’ve used ISE a lot, I had more trouble learning to use ssh and scp than the FPGA-specific tasks.

 

This is a simple introduction to using LOGI-Bone, intended to help you see results with minimal effort and frustration.  LOGI-Bone is a very powerful board, capable of myriad interesting projects.  I plan to show a few of these in upcoming ’blogs in this series.


[This document is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.  To view a copy of this license, visit creativecommons.org/licenses/by-sa/3.0/.  No warranty is expressed or implied.]

This ’blog is the first part of Chapter 12 of The XXICC Anthology rev 0.0k.  For more information on XXICC, see the blog post XXICC (21st Century Co-design) release 0.0m and XXICCs home page: xxicc.org.

 

Update 15 November 2014:  XXICC release 0.0m adds a second Flavia implementation: FlaviaP48 for the Papilio One 500K.  Rev 0.0m also allows the user to set the Flavia clock frequency values from 1 Hz to 32 MHz instead being fixed at the 2 Hz "proof of concept" frequency.  See Section 12.5 of The XXICC Anthology rev 0.0m for details.

 

Update 20 January 2015:  XXICC release 0.0n adds two Xilinx Spartan-6 implementations: FlaviaLP56 for the ValentF(x) LOGI-Pi board and FlaviaLB56 for the ValentF(x) LOGI-Bone.  Both boards have a Spartan-6 LX9 FPGA.  See Sections 12.6 and 12.7 of The XXICC Anthology rev 0.0n for details.

 

Update 15 May 2015:  XXICC release 0.0p adds a Flavia implementation for the Gadget Factory Papilio DUO.  This board has a Xilinx Spartan-6 LX9 FPGA.  See Raspberry Pi 2 meets Papilio DUO for details.

 

Update 26 June 2015:  The author is now aware of IceStorm, a wonderful project to reverse-engineer the Lattice iCE40 FPGA internal architecture and bitstream so we can write FaiF tools.  IceStorm was first released in March 2015.  For more information, see these Hackaday articles: Reverse-Engineering Lattice's iCE40 FPGA bitstream and An Open-Source Toolchain for iCE40 FPGAs.

 

Update 29 June 2015:  XXICC rev 0.0q has improved the Papilio One Flavia implementations.  They are now FlaviaP40 for the 250K and FlaviaP60 for the 500K.  See Chapter 12 of The XXICC Anthology rev 0.0q.

 

Update 1 September 2017:  XXICC rev 0.0r has added integer operators and nets so you don't have to express exterything as Boolean expressions.  Rev 0.0r also adds Flavia capability for Lattice iCE40 FPGAs using the open-source IceStorm tools.   See Chapters 10 and 15 of The XXICC Anthology rev 0.0r.

 

Abstract: Flavia is a family of logic arrays that can be designed and programmed entirely using free-as-in-freedom (FaiF) software.  This is in contrast to standard FPGA (Field-Programmable Gate Array) tools from vendors such as Xilinx, Altera, Lattice, Cypress, and MicroSemi (formerly Actel) where you must use the vendor’s software to design the FPGA.  Except for a part from Atmel that never caught on [and now IceStorm: see above], the author is not aware of any commercial FPGA or CPLD (Complex Programmable Logic Device) that can be designed without running its vendor’s tools.

Disclaimers: The Flavia and XXICC software described in this chapter or article are 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 details.

 

An incorrect FPGA bitstream could cause damage to an FPGA and/or its connected circuitry, or cause a system to malfunction.  Users must agree that the author(s) and copyright holder(s) of  Flavia and XXICC software have NO LIABILITY for any damages.  See the GNU General Public License for details.

 

Flavia is not associated in any way with Xilinx Inc.  If you have problems with Flavia, please do not blame Xilinx and please don’t ask them for Flavia support.  Instead, go to xxicc.org and follow the links you find there.

 

Flavia does not reverse-engineer secret parts of Xilinx bitstreams and does not provide a way to reverse-engineer other Xilinx-based products.  The locations of FPGA look-up tables and flip-flops used by Flavia are from files openly documented by Xilinx, supplemented with suggestions provided by Xilinx engineering at forums.xilinx.com.  They are only useful for Flavia and do not endanger the security of other Xilinx-based designs.  This is described in detail in Taming the Wild Bitstream.

 

This ’blog references XXICC, XOE, and GCHD.  For details on those topics see The XXICC Anthology rev 0.0k.

 

Flavia’s Origin

 

Flavia was inspired by a great discussion on element14 called: “Role for FPGA or CPLD with Raspberry Pi”.  The discussion was mostly about how to use Raspberry Pi for teaching programmable logic, which is a challenge because vendor FPGA/CPLD design tools do not run on ARM computers like Raspberry Pi.

 

On 27 October 2012, Morgaine Dinova asked the question that inspired Flavia:

What is the most complex programmable logic device (in the most generic sense of the phrase but not including CPUs) on the market today (old is OK as long as the device is still sold) that can be fully examined and programmed with open-source EDA tools?  Since no modern CPLDs let alone FPGAs are open enough for that, what’s the best that can be done?

I thought about Morgaine’s question for a day and I came up with this:

In terms of what can be done right now, there’s always Wheeler’s Law: “All problems in computer science can be solved by another level of indirection.”  It’s an awful way to do it, but you could take a large FPGA and dedicate 80-90% of its LUTs* to form a routing matrix implemented as an array of multiplexers implemented using distributed RAM cells.  The remaining LUTs would be RAMs for implementing n-input logic functions.  I believe you can update the contents of distributed RAM cells over JTAG using Xilinx documentation, so you can update both the logic function and the routing.  Since all routing would be through RAM cells instead of pass transistors, it would be way slower than using an FPGA properly, but as a teaching tool it’s “something that can be done now”.

 

I think I heard of this being done some decades ago, but I thought it sounded too silly to remember the details.  Actually, it was I who was silly, thinking FPGA vendors would see the wisdom of opening up their configuration formats.

 

* LUT = Look-Up Table.  Most FPGAs implement logic functions with small RAMs, each of which implements an n-input arbitrary logic function using brute-force table lookup, where n is 3 to 6 depending on the FPGA.

After thinking about it more, I decided that such an array could be a terrific resource for learning about programmable logic.  I did some preliminary design and estimated that an array of 32 6-input arbitrary functions could fit into a 200K-gate Xilinx Spartan-3A or 250K-gate Spartan-3E.  This is a terribly inefficient use of FPGA logic, but a 32-block PLD is large enough for learning about programmable logic.  The free logic array would also be be a fine addition to XXICC, maybe even a “killer application” (well, one can dream, right?)

 

Before I could do this yet-unnamed free logic array, I first needed to complete workable versions of XXICC’s hardware design tools like its figure editor and GCHD (GalaxC for Hardware Design).  Workable versions were released on USA π Day 3.14.2014.  After that, I turned my attention to the free logic array, hoping to have a first release on European π Day 22/7/2014.

 

The result is Flavia, which was completely inspired by Morgaine’s question for which I am extremely grateful.  The name Flavia is short for “Free Logic Array via ”, where “” identifies the FPGA chip or board used for a particular Flavia implementation.  For example, the first Flavia implementation is FlaviaP32, where P stands for the Gadget Factory Papilio One 250K and 32 is the number of function blocks implemented.  The name Flavia may refer to the project’s hardware or software.

 

Flavia Advantages

 

Flavia is designed for new FPGA designers who want to play with FPGA technology without having to climb the steep learning curve associated with an FPGA vendor’s tool suite.  Flavia arrays are fairly small, with the capabilities of a CPLD (Complex Programmable Logic Device) rather than a large FPGA.  Flavia is intended to be an easy and fun way to learn basic programmable logic design so that learning vendor tools won’t be as daunting.

 

Here are Flavia’s key advantages:

 

  1. Flavia tools can run on non-Intel architectures.  Specifically, they can run on ARM-based single-board computers like Raspberry Pi and BeagleBoard/Bone.  Vendor tools usually only run on Intel x86 PCs.  Most vendors offer both Microsoft Windows and GNU/Linux versions, but they don’t provide a version of the tool suite for ARM or other non-Intel processors.

    You can download an FPGA configuration bitstream using any processor, but vendor tools for compiling your design and producing that bitstream usually only run on x86 PCs.

  2. Flavia tools are fast.  Compiling a small design and downloading it to an FPGA using the Xilinx ISE tools generally takes around a minute on a reasonably fast PC.  Flavia can compile and download a small design in less than a second.

  3. Flavia tools are FLOSS (Free-as-in-Liberty Open-Source Software).  This means that you and the community can improve Flavia tools and adapt them to other purposes.  Tools are not limited to the capabilities provided by FPGA vendors.  Most vendors do provide a “free-as-in-beer” version of their tools, but you cannot modify the vendor tools and if there are bugs you cannot fix them yourself.

    Flavia is licensed under GPLv3.  Basically, this means you can use Flavia for any purpose -- commericial or non-commercial -- with the understanding that Flavia has no warranty and limits liability.  If you redistribute Flavia, you must include source code, along with other requirements listed in GPLv3 [www.gnu.org/licenses/gpl.html].

  4. Flavia tools are small.  The entire source code -- which includes all of XXICC -- is about a megabyte.  In contrast, the Xilinx tools are gigabytes that must be downloaded from the Internet or loaded from a DVD-ROM.

  5. Vendor tools generally require designs to be written in Verilog or VHDL.  Many people have found the languages difficult to learn and to use, though many people like one or both.  Chacun a son goût (YMMV).  There are books available to learn either language.

    Flavia uses the much simpler GalaxC extensions for Hardware Design (GCHD).  GCHD is similar to Verilog, but has (in the opinion of the author) cleaner syntax and semantics.

    Flavia tools also include XOE’s figure editor so small designs can be drawn as logic diagrams, simulated using cartoon simulation, and then downloaded into an FPGA.  Many vendor tool suites also include schematic editing.  Logic diagrams can be a great tool for learning about logic design, but once designs get complex most designers find an HDL is more useful.

    Since Flavia tools are FLOSS, you are not limited to GCHD as the only HDL.  You or the community can create or adapt compilers for any hardware description language or other scheme to create designs and then interface them into the Flavia tools.

Flavia does have disadvantages, which pretty much limits its use to learning about FPGAs and small projects with loose performance requirements.

 

  1. Flavia designs are small: Flavia provides the capabilities of a CPLD, not an FPGA.  This is because the multiplexers that route signals between logic functions consume most of the FPGA’s LUTs.  If you need lots of gates, use vendor tools.

  2. Flavia designs are much slower than FPGA implementations.  Again, this is because the routing is implemented using multiplexers, but also because the outputs of function blocks need to be routed throughout the FPGA.  If you need to meet specific timing requirements, use vendor tools.

  3. While you can use Flavia for any purpose, Flavia designs are not intended for final products.  They make very inefficient use of FPGA LUTs, and do not provide bitstream security if that’s important to you.  For products, use smaller, cheaper FPGAs or CPLDs, and vendor tools.

  4. Flavia designs have functional limitations.  For example, Flavia does not currently support bidirectional pins.  FlaviaP32, the first Flavia implementation restricts I/Os pins to 3.3V LVTTL with pull-ups, and only has a single 2 Hz clock for flip-flops.

  5. XXICC 0.0k is the first release of Flavia software and there are plenty of rough edges and probably undetected bugs.  Some capabilities are preliminary.  For example, logic synthesis does not detect common sub-expressions so it’s up to the designer to enter efficient designs.

 

Even with these restrictions, you should find Flavia to be a good platform for learning about FPGAs.  0.0k is the “proof of concept” release.  Later releases will have improved capabilities.

 

FlaviaP32 Architecture

 

We will now look at a specific Flavia implementation: FlaviaP32 for the Gadget Factory Papilio One 250K.  We chose this board because at US$38 it’s the cheapest FPGA development board we could find that’s readily available in the USA and provides capabilities needed for a reasonably-sized Flavia, specifically:

 

  1. Xilinx XC3S250E Spartan-3E FPGA with 250K gates, which is large enough for 32 6-input arbitrary function blocks (AFBs) with full input multiplexing.  This can probably be expanded to 40 AFBs, which will be the FlaviaP40.

  2. 48 I/Os on 0.1" sockets, which are easy to interface with external circuits.  Papilio also has a nice collection of inexpensive “wings” such as the Button/LED Wing with 4 LEDs and 4 push-buttons, and a solderless Breadboard Wing for adding external ICs.

  3. FTDI FT2232D full-speed USB controller for programming the FPGA.  FTDI is supported by the FLOSS library libftdi.so which provides I/O for sending bitstreams and other messages over USB.  Reprogramming the XC3S250E takes a few tenths of a second and is done directly from the Flavia tools without having to run a separate program.

    There’s also a free-as-in-beer Microsoft Windows driver, provided by FTDI.  Flavia software dynamically links to the appropriate driver for the host operating system.

 

In the author’s opinion, Gadget Factory has a nice business model with open-source hardware and a friendly forum for answering questions.

 

Here is the high-level block diagram for FlaviaP32:

FlaP32.png

FlaviaP32 consists of 32 identical AFBs, each connected to an FPGA pin which can be either an input or an output.  (Flavia software does not support bidirectional pins in release 0.0k, though the FlaviaP32 hardware does.)  Each AFB implements an arbitrary 6-input Boolean function and has a D flip-flop (DFF).  Each of the six inputs can come from any of the FPGA pins: each of the horizontal lines on the left side of the diagram represents a 32:1 (32-to-1) multiplexer, with each possible input shown as ‘x’.

 

In addition, each AFB has a set/reset (sr) input which is the asynchronous init signal for the AFB’s DFF, and an output enable (oe) input which controls whether the AFB’s pin is an input or an output.  All FlaviaP32 I/O pins have 2.4 to 10.8 KW pull-up resistors, so unconnected inputs are pulled high.

 

Each AFB needs eight 32:1 multiplexers, which must be implemented using LUTs.  Here is the block diagram for one of these multiplexers:

Mux32.png

 

Each of the eight LUTs selects one of four inputs.  Flavia can program a LUT with a single-input logic function that passes one of the inputs -- perhaps inverted -- and ignores the rest.  Alternatively, Flavia can program a LUT with all zeros or all ones to produce a 0 or 1 output and ignore all inputs.  The eight LUT outputs are combined using 2:1 multiplexers built into the Spartan-3E logic blocks.  These 2:1 muxes are in addition to the LUTs and have very fast local connections that add minimal delay to the 32:1 mux.

 

The select lines for the 2:1 muxes (cfg0-cfg2) are FFs that are in the same logic cells as the LUTs.  The FF states are also programmed by Flavia.  Basically, to program a 32:1 multiplexer to select one of the 32 inputs, Flavia sets one of the LUTs to a single-input function and the rest to all zeroes, and then sets the FFs to select that LUT.

 

So, how does Flavia program these LUTs and FFs?  Well, each LUT and FF is in a well-defined location in the Xilinx bitstream.  Normally, Xilinx does not give you the bitstream format, but they make an exception for LUTs and FFs.  This is primarily so you can read back the FPGA bitstream and get the current values of LUTs (which can be used as RAMs) and FFs, but the information provided by Xilinx lets you write your own values into those locations.  Flavia simply takes a generic Flavia bitstream (FlaviaP32.bit), writes the LUT and FF values required for each 32:1 mux into the proper locations in the bitstream, calculates a new checksum, and downloads the result into Papilio over the USB connection.  All this takes less than a second on a reasonable PC.

 

Now that we have 32:1 muxes worked out, let’s take a look at the 6-input AFB.  Here’s the block diagram:

AFB6x32.png

The four LUTs on the left and their 2:1 muxes calculate an arbitrary 6-input Boolean function of the six inputs p0-p5.  Here we make use of the Shannon expansion -- called development by George Boole -- which states that any n-input function can be decomposed by multiplexing two (n-1)-input functions as follows:

Shannon.png

Applying this expansion twice, we can calculate any Boolean function of 6 inputs by multiplexing the outputs of four 4-input functions.  We implement the 4-input functions using LUTs, all of which use the same inputs p0-p3.  The remaining inputs p4 and p5 are the select inputs for the multiplexers.

 

An AFB’s output can be the output of the 6-input function – i.e, combinational logic (C/L) or the value of the DFF which is updated by the rising edge of a shared 2 Hz FlaviaP32 clock.  We use a LUT as a multiplexer to support future applications.  The DFF has an asynchronous init signal sr which sets the DFF to 1 or 0, configured by Flavia software.  Xilinx FFs have clock enable inputs, but FlaviaP32 doesn’t use them: AFB FF clocks are always enabled.

 

As you can see, FlaviaP32 has a very simple architecture which means that synthesis tools can be simple.  All AFBs are identical, and there are no routing restrictions so Flavia software can assign any 6-input function to any AFB, restricted only by how the user wants to assign pins to Papilio I/O sockets.

 

There are a number of improvements planned for future releases, and we hope others will be suggested by the community.  For example, the AFB output LUT can implement some logic functions like detecting a state change.  A major improvement is to replace each 32:1 multiplexer with a 32-input AND gate or OR gate with invertible inputs, i.e., a minterm or maxterm.  This can significantly improve Flavia’s logic capacity with a modest increase in software complexity.

 

Using FlaviaP32

 

You can create FlaviaP32 designs using GCHD (GalaxC for Hardware Design) text, logic diagrams, or a combination.  This section shows several example designs.

 

XXICC supports hierarchical design, where a large design is partitioned into smaller modules in the same way that a large program is partitioned into smaller functions.  The top-level or root module shows how signals are connected to Papilio One I/O sockets.  In a future release you will be able to create a table to show how your root signals are mapped to Papilio I/O, but in 0.0k the root module must use Papilio One signal names.

 

Papilio One has 48 I/Os arranged in three rows each with 16 I/Os.  Paplio One I/Os are numbered A0-A15, B15-B0, and C15-C0 from bottom to top.  Each group of 8 I/Os has four terminals for power and ground.  These are for powering Papilio add-on boards called “wings”.PapilioOne.pngFlaviaP32 has 32 I/Os, which are assigned to A0-A15 and C15-C0.  Each I/O can be an input or an output.  FlaviaP32 has pull-ups on all pins.  Xilinx does not document where the bits are that control whether an I/O has a pull-up or pull-down, so we had to make a choice and pull-ups let you do open-drain I/Os.

 

Example 1: Majority/Minority Circuit

 

Here is a simple GCHD example that produces the majority and minority functions.  The inputs are A0, A2, and A4.  Output A1 is high if a majority of A0, A2, and A4 are high.  Output A3 is the opposite.

 

include "gchd.gi";            // This line is needed for GCHD designs.

 

digital hardware (synthesize)

{   // Boolean equations for majority and minority functions.

    net {A0, A2, A4, A6};            // Undriven nets are inputs.

    net A1 = A0 & A2 | A0 & A4 | A2 & A4;

    net A3 = ~A1;

    net {A5 = FALSE, A7 = FALSE};    // Turn off extra LEDs.

};

 

GCHD consists of extensions to the GalaxC programming language, so the above example is actually a GalaxC program.  The first line includes the gchd.gi library, which is needed for GCHD programs.  The “digital hardware” construct creates a root module for the logic.  The net statements declare signals and optionally give them values.  If a net does not have a value, Flavia software treats it as an input.  If a net is assigned a value, it’s an output.  We named the signals A0-A7 to assign them to specific Papilio One pins.

 

In the example, we set A1 to the majority function maj(a, b, c) = a b + a c + b c.  A3 is the minority function, which is simply the complement of the majority function.  A5 and A7 are FALSE to turn off extra LEDs.

 

To run this example, start up XXICC with the fla option, e.g.,

 

xxicc fla

 

where “xxicc” is the XXICC executable on your system – see Installing and Running XXICC rev 0.0k for details.

 

XXICC will compile and/or load the XXICC source code needed for Flavia and link in the run-time library to talk to Papilio’s FT2232D chip: libftdi.so on GNU/Linux or ftd2xx.dll on MS Windows.  If the library is not present, you will get an error message.  See Installing and Running XXICC rev 0.0k for how to deal with this.

 

When XXICC completes loading, it will bring up a file selection dialog.  Open “majmin.gal” which contains the above example.  You are now in the XXICC Object Editor, or XOE.  Compile the example by pressing F6.  GalaxC should compile the example, do Flavia logic synthesis (trivial in this case), and download the resulting bitmap to your Papilio One board, all in less than a second.

 

To see if the FPGA is programmed correctly, hook up LEDs to A1 and A3 through suitable current-limiting resistors.  One or the other LED should be on.  Then ground A0, A2, and A4 in various combinations.  Since A0, A2, and A4 have pull-ups, if you don’t connect them to anything they’ll have the value 1 and the majority output A1 will be high and minority A3 will be low.  If you ground one of A0, A2, and A4, you still have a majority high so A1 should still be high.  If you ground two of them, then A1 should go low and A3 should go high.

 

Using Button/LED Wings

 

The easiest way to connect LEDs and manual inputs is Gadget Factory’s Button/LED Wing, currently US$8.  FlaviaP32 uses B15-B0 for Button/LED Wings.  The LEDs observe adjacent A1-A15 pins and the buttons invert adjacent A0-A14 inputs.  For LED pins, FlaviaP32 simply connects odd-numbered A pins to adjacent B pins according to this table:

 

LED1LED2LED3LED4LED1LED2LED3LED4
B14B12B10B8B6B4B2B0
A1A3A5A7A9A11A13A15

 

For button pins, odd-numbered B pins invert the input values of adjacent A pins:

 

PB1PB2PB3PB4PB1PB2PB3PB4
B15B13B11B9B7B5B3B1
A0A2A4A6A8A10A12A14

 

A pins have pull-ups, so an unconnected A input has value 1.  Odd-numbered B input pins for buttons have pull-downs.  For example, if you press the PB1 next to A0, that inverts A0.  If A0 is unconnected, PB1 inverts its 1 value to produce 0.  If A0 is grounded, PB1 inverts that 0 to produce 1.

 

The LED and PB connections via B0-B15 are built into FlaviaP32 and do not appear in Flavia designs. 

 

Example 2: Binary Counter

 

Here’s a more interesting example, a 4-bit binary counter:

 

include "gchd.gi";            // This line is needed for GCHD designs.

 

digital hardware (synthesize)

{   // 4-bit binary up-counter.

    clock net clk;           // 2 Hz FlaviaP32 clock.

    net reset;               // Reset counter if high, otherwise enable counter.

    net up;                   // Count up if !reset and up, otherwise hold.

    reg {s3, s2, s1, s0};   // Counter state.

    // If reset, asynchronously reset s3-s0.

    if reset then s3 = s2 = s1 = s0 = FALSE else

    if clk rises then

    {   // On rising clk, increment s3-s0 if up, otherwise hold s3-s0.

        s3 ^= up & s2 & s1 & s0;

        s2 ^= up & s1 & s0;

        s1 ^= up & s0;

        s0 ^= up;

    };

    // Assign counter I/Os to Papilio One pins.

    net {A0, A2}; reset = !A0; up = A2;           // PB inputs.

    net {A1 = s3, A3 = s2, A5 = s1, A7 = s0};   // LED outputs.

};

 

In this case we have used meaningful net names.  “reset” is an asynchronous reset signal that connects to AFB sr inputs.  “clk” is the clock signal: FlaviaP32 only has a single 2 Hz “proof of concept” clock.  It is built in and does not use any of the 32 I/Os.

 

The last lines of the example connect the reset and up signals to push-button inputs, and the counter state s3-s0 to LEDs.  If A0 and A2 are not connected, they are pulled up to 1 and reset = 0 and up = 1.  This makes s3-s0 begin counting immediately.  If you ground A0 or press PB1, s3-s0 resets to 0000 and counts from 0000 when you release A0 or PB1.  If you ground A2 or press PB2, s3-s0 stops at its current state and resumes counting when you release A2 or PB2.

 

To run this example, open “Bcount4.gal” in XOE and compile it using F6.  If it compiles correctly, Flavia will download the bitstream and it will begin counting.

 

Example 3: Möbius Counter

 

The third example describes the design as a logic diagram instead of text.  This is a four-bit Möbius or Johnson counter that counts in the sequence 0000, 1000, 1100,  1110,  1111,  0111,  0011, 0001, and back to 0000.

Moebius4.png

To run this example, open “Moebius4.xoe” in XOE, but don’t compile using F6.  Since this design only uses standard gates and flip-flops from gchd.gi, you compile it by clicking in the figure and then pressing F to issue the Flavia command.  If it compiles correctly, Flavia will download the bitstream and it will begin counting.  Ground A0 or press PB1 to reset to 0000.

 

Basically, that’s all there is to using Flavia.  In rev 0.0k, Flavia is particularly easy because there's only one implementation – FlaviaP32 – so you don’t need to select an implementation, and there’s no pinout table.  If you want to play with Flavia, you’ll need to read the relevant chapters of The XXICC Anthology rev 0.0k to learn more about XOE and GCHD.

 

This ’blog is the first part of Chapter 12 of The XXICC Anthology rev 0.0k.  The rest of that chapter describes how Flavia synthesizes logic and configures FPGAs.  It ends with a Hints section with various suggestions for using Flavia, and an Issues section that lists known problems with the current revision.

Filter Blog

By date: By tag: