A month ago I ordered a pair of Numato Mimas v2 Spartan 6 FPGA Development boards, after hearing about them at Linux.Conf.Au 2017.

This past weekend, after finally getting free of the project that ate my life for the last six months, I got a chance to start installing the tools necessary to start exploring FPGA programming. I am doing this on the Dell XPS 13 running Ubuntu 16.04 LTS I bought late last year to help with such development. While it can dual boot Microsoft Windows 10, ideally I would like to do everything under Ubuntu Linux 16.04 LTS.

As there were quite a few setup steps, and some dead ends, I am mostly recording this process for my own reference.

Xilinux ISE WebPACK install on Linux

The first step was to get the Xilinx ISE WebPACK installed, which is a FPGA synthesis tool for the Spartan 6 available with a no-cost license; it runs under Linux and (older versions of) Windows. The Xilinx ISE WebPACK has been effectively end of lifed (the download page lists final update as October 2013), but still functions at present.

I basically followed the J-Core Open Processor instructions to install the Xilinx ISE WebPACK, but with fewer frustrating steps. There is now both a "Multi-File Download", and also a "Full Product Installation". I chose to download the "Full Installer for Linux" (6GB), which took two attempts, but worked successfully on the second attempt (the first failed quite early). As far as I could tell the download was just a regular browser download, not a "javascript downloader". (I also had to create a Xilinx account even to download the software, and it needed a physical address -- not a Post Box -- before it would allow the account to be created. Apparently there is due to ITAR restrictions...)

After downloading the Xilinx ISE WebPACK installer the next steps are:

cd /var/tmp
mkdir xilinx
cd xilinx
tar -xvf ~/Downloads/Xilinx_ISE_DS_Lin_14.7_1015_1.tar

The tarfile now extracts into a subdirectory, so to start the installer do:

cd Xilinx_ISE_DS_Lin_14.7_1015_1
./xsetup

At that point a GUI installer (eg, common OS X or Windows style) starts up. The first couple of steps have you accept the Xilinx ISE WebPACK license, and then a huge list third party licenses (mostly for Open Source Software AFAICT). There's two checkboxes to tick on the first page (the second to acknowldge the "WebTalk" spyware), and one on the second page. (The third party licenses appear to be in idata/usenglish/idata/licenses/unified_3rd_party_eulas.txt, which is easier to review in a file viewer than within the GUI.)

When you reach the point to choose what software to install, select "ISE WebPACK", then disable installing the other features (ie, the ones covered by other licenses). The "WebTalk" spyware is mandatory to install (and can only be disabled with a paid license), but the J-Core WebPACK install instructions imply that it runs only in the ise GUI tool, not the command line tools. I left the "use multiple cores during install" option selected, and let it create the environment files, but did skip trying to get a ISE WebPACK license during the install.

On the destination screen I paused and did:

cd /usr/local/
mkdir xilinx
sudo chown $USER:$USER xilinx

in a terminal, and then told the Xilinx installer to use /usr/local/xilinx as its install location. For completeness after the install I also did:

cd /opt
ln -s /usr/local/xilinx Xilinx

just in case anything tried to use the default.

The install process itself ran relatively quickly (eg, just a few minutes at least on a modern laptop with SSD), so that part seemed fine.

To actually be able to use the Xilinx ISE WebPACK I followed the J-Core ISE WebPACK install guide hints and created a script to "enter the ISE WebPACK environment". I created /usr/local/bin/xilinx with:

#!/bin/bash -i
# Wrapper script to enter Xilinx environment
#
# From http://j-core.org/bitcomp.html
#----------------------------------------------------------------------

source /usr/local/xilinx/*/ISE_DS/settings64.sh
export PS1="[Xilinx] $PS1"
exec /bin/bash --noprofile --norc

and made that executable. Then I can enter a shell in the Xilinx ISE WebPACK runtime environment with:

xilinx

I also followed the lead of the J-Core ISE WebPACK install guide and pre-emptively moved the libstdc++.so.6 files in the Xilinx ISE WebPACK install out of the way (apparently their build is incompatible with, eg, Firefox on modern Linux):

cd /usr/local/xilinx/14.7/ISE_DS/ISE/lib/lin64
mv libstdc++.so.6 libstdc++.so.6-disabled
mv libstdc++.so libstdc++.so-disabled
cd /usr/local/xilinx/14.7/ISE_DS/common/lib/lin64
mv libstdc++.so.6 libstdc++.so.6-disabled
mv libstdc++.so libstdc++.so-disabled

I use Firefox as my default browser so I did not need the step to make that my default browser.

The Xilinx ISE WebPACK GUI is started with:

ise

run from within the Xilinx ISE WebPACK environment (ie, xilinx script above has been run, the prompt includes [Xilinx]).

On first launch there will be a license error -- click "OK" on the error, and the license manager will pop up. Within the license manager select "Get Free Vivado/ISE WebPack License", and then click "Next". The popup window will then show what will be in the license key. Within that window click on "connect now" to open a browser window and request the no-cost license. (In my case the NIC it was tied to seemed to be 000000000000; not sure if that is a more recent relaxation of the licensing terms for the end of life software, or due to only having Wifi and a VPN connected at the time. Hopefully it does not become an issue later.)

When the browser window pops up, log in with your Xilinx account (noting that the Username field wants the short username that you used when creating the account not the email address...), and then select "ISE WebPack License" as the one you want. Click on "Generate Node-Locked license" to get a popup confirmation window, and then "Next" on the next two popup windows to actually generate the license file.

An email should arrive, with a Xilinx.lic attachement. Save that attachment. Then go back to the "Xilinx License Configuration Manager" windo, in the "Manage license" tab. Click the "Load License" button and browse to the license file you saved, and click Open. You should get a popup that the license installation was successful.

At this point the Xilinx ISE WebPACK software should be ready for use.

Numato Mimas v2 programming tools

At this point I started trying to follow the Numato Beginners Guide to learning FPGA, which uses the Numato Mimas v2 as an example board.

Pretty quickly I ran into the problem that the guide said I needed the "Mimas V2 Configuration downloader software". That software, available from the Downloads tab of the Numato Mimas v2 page, is only available for Microsoft Windows ("Configuration Tool (Windows)"). At first glance when looking at the Numato Mimas v2 Documentation, I wondered if I could work without the "configuration tool". But some more research clarified that this "configuration tool" was in fact the "software download tool", and without an equivalent tool the Field Programmable Gate Array was not going to be very Field Programmable...

After quite a bit of searching I turned up a discussion on the Numato Labs Community forum about programming the Mimas v2 from Linux, which showed people using a python script (MimasV2Config.py). Originally it looked like a dead end, as the svn.numato.cc server given in the link to the software turned out to be dead -- but going to the third page of the discussion thread turned up the fact that Numato moved to GitHub in late 2015, and that the MimasV2Config tool could now be found within their Numato samplecode repository (specifically in FPGA/MimasV2/tools/configuration/python).

So as my next setup steps I did:

cd /usr/local
sudo mkdir numato
sudo chown $USER:$USER numato
cd numato
git clone https://github.com/numato/samplecode.git

According to the dicussion forum that script needs (a) Python 3, and (b) the Python3 serial library. So I did:

sudo apt-get install python3 python3-serial

which (on Ubuntu Linux 16.04 LTS) installed Python 3.5.2, and python3-serial version 3.0.1.

The discussion forum also identified that Ubuntu Linux installs modemmanager which really wants any serial device, including USB serial device, that appears to be a modem -- and automatically sends AT commands to them on connect. This obviously confuses various devices which are not modems, apparently including the Numato Mimas v2.

To be safe, since I do not use modems on this laptop, I explicitly uninstalled modemmanager:

sudo apt-get purge modemmanager

(if you do use modems, including 3G/4G modems, on the system you will need to be quite a bit more subtle about keeping modemmanager away from the Numato Mimas v2 serial port).

Then to make the tool easier to run I created a symlink to it:

cd /usr/local/bin
sudo ln -s ../numato/samplecode/FPGA/MimasV2/tools/configuration/python/MimasV2Config.py MimasV2Config
chmod +x ../numato/samplecode/FPGA/MimasV2/tools/configuration/python/MimasV2Config.py

and tested that would run well enough to produce help text with:

cd
MimasV2Config

which should report an invalid number of arguments, and the usage:

MimasV2Config PORT BINARY_FILE

For ease of use, you probably also want to add your user to the dialout group, which udev auto-assigns to modem-like/serial-like devices, so that you can run the programming tool without running as root (eg, use vigr).

Putting it all together

At this point I went back to the Numato Beginners Guide to Learning FPGA, and started following the examples for the Mimas V2. If it is not already running, then do:

xilinx
ise

to start up the Xilinx ISE WebPACK environment.

I created a project following the example in the [Mimas-V2-Debug-Probe] (https://github.com/cyrozap/Mimas-V2-Debug-Probe):

  • Top-level source type: HDL

and then on the second page:

  • Family: Spartan 6

  • Device: XC6SLX9

  • Package: CSG324

  • Speed: -2

  • Preferred language: Verilog

(which are also shown in screenshots in part 3 of the Numato Beginners Guide to Learning FPGA).

Simulation

Then right click on the project, and choose "New Source..." to add a Verilog Module. I then cut'n'paste in the example from part 3 of the Numato Beginners Guide to Learning FPGA):

module myModule_tb();
wire out;
reg clock;

always begin
 #1 clock =!clock;
end

initial begin
 //Initialize clock
 clock = 0;

 //End simulation
 #10
 $finish;
end

myModule notGate(clock, out);
endmodule

module myModule(A, B);
input wire A;
output wire B;
assign B = !A;
endmodule

replacing of the auto-generated boilerplate, saved that file, and then went to "Simulation" mode (radio button at top left). From there, highlight the "myModule_sim" file in the project hierachy, and then go down to "ISim Simulator" and expand that, then right click on "Simulate Behavioural Model" and choose "Run". ISim will launch, and then very rapidly finish (since it is configure to run for only #10).

To see the waveform, click on the Default.wcfg tab, and then zoom out a lot so that 10 ns fits on the screen (instead of ps), which should show the expected "not gate" behaviour. (If you are too far zoomed in, all you will see are very straight lines...)

Implementation for actual hardware

To implement this simple example on actual hardware, we need the "User Constraints File" (ucf) which maps functions (eg, switches, LEDs, etc), to actual hardware. There is a reference User Constraints File for the Numato Mimas v2", which gives the mappings available -- with everything commented out, and given generic names. It is linked from the Numato Mimas v2 downloads page.

Part 4 of the tutorial also includes the relevant snippets for the test project. These seem to be:

# User Constraint File for NOT gate implementation on Mimas V2

# Onboard LEDs
NET "B" LOC = T18;

# Push Button Switches.
# Internal pull-ups need to be enabled since
# there is no pull-up resistor available on board
NET "A" PULLUP;

NET "A" LOC = M16;

which can be created in a new file by changing to "Implementation mode" (radio boxes at the top level), and then right click on the project and choosing "New Source" to add an "Implementation Constraints File" called notgate.ucf. Then cut'n'paste the text above into the file (if copying from the Numato tutorial, beware it has smart quotes, and you will need to allow those to be converted to regular quotes for it to work).

Then update the Verilog code to be just:

module myModule(A, B);
   input wire A;
   output wire B;
   assign B = !A;
endmodule

without the simulation framework code used in part 3.

Save the file, and right click on the module and select "Implement Top Module". That runs a whole series of steps to build the binary image to upload to the FPGA (you can watch the progress in the output section at the bottom). It will hopefully finish with "Process ... completed successfully", and no warnings or errors.

To get a file to download to the Numato Mimas v2, it is necessary to go to right click on "Generate Programming File" and choose "Process Properties...", then tick the box "Create Binary Configuration File" and "Apply" that change and click "OK" to close the dialog box. Then right click on "Generate Programming File" again and choose "Run", and it should successfully generate a bitstream file myModule.bin in the project directory.

Loading onto the Numato Mimas v2 board

Connect the computer up the Numato Mimas v2 board via a USB A to USB Mini B cable. To my surprise this is a different cable than the ESP8266 and IoTuz used (slightly taller connector), but fortunately I did have one sitting around, from an unpowered hub which is otherwise not very useful. (It is also useful to ensure that the supplied standoffs for the board have been installed so it is not just a bare board sitting on something which may result in shorts.)

The Numato Mimas v2 board should power up (it is USB powered by default), and if it is fresh from the factory will probably be running some sort of test routine -- mine had the 7-segment displays cycling from 111 through 999, and a LED chaser on D1 to D8.

Running "dmesg | tail" should show a newly discovered device "Numato Labs Mimas V2 Spartan6 FPGA Development Board", and /dev/ttyACM0 should now exist. Check the permissions on /dev/ttyACM0 and your groups:

ls -l /dev/ttyACM0
id

to make sure that /dev/ttyACM0 is writable by a group you are in (by default "dialout, which hopefully you are in as described above).

Then change to the project directory that the Xilinx ISE WebPACK was using, and run:

MimasV2Config /dev/ttyACM0 myModule.bin

it should connect, detect the flash (Micron M25P16 SPI Flash in my case), erase the flash, write the flash, verify the flash, and then rebooting the FPGA. (The steps should be similar to Configurating Mimas V2 Using Configuration Tool, but with the output to the console.)

The FPGA should start up without the factory test pattern (since it should be running new code). And following the Numato Learning FPGA Part 4 example instructions, pressing SW3 on the board should cause LED D8 to light up. Sadly in my case the factory test pattern was no longer running, but neither did pressing SW3 or any of the other buttons do anything :-( And power cycling the board (by unplugging the USB) did not make it work.

To test the programming alone, I downloaded the mimasv2_sample_bin_file.bin, and tried programming that instead:

MimasV2Config /dev/ttyACM0 mimasv2_sample_bin_file.bin

which also appeared to flash correctly, and the board restarted with the factory test routing running. From this I concluded that the programming interface works, and I have some other issue.

The next most obvious issue was that I set something up wrong in the Xilinx ISE WebPACK, so to eliminate that possibility I downloaded the example Xilinx ISE implementation project for Mimas v2, unpacked that and opened that, and then followed through the "Implement Top Module" and "Generate Programming File" steps again, giving me a new myModule.bin (the zip also had a mymodule.bin -- note case difference which was identical to what I rebuilt; but both were different from the one I had built myself).

When I uploaded the one built from the downloaded project it worked:

MimasV2Config /dev/ttyACM0 myModule.bin

with pressing switch SW3 causing LED D8 to turn on while the switch is held down.

Doing a diff between the ucf file in the downloaded project, and the ucf in my test project turned up the difference -- when I cut'n'paste the User Constraints File snipped from the example 4 website, I accidentally copied the first one instead of the second one. The first one has the Mimas v2 default names for things, and the second one has "LED" changed to "B" and "SW" changed "A" to match the names used in the code.

Fixing that difference, then doing "Implement Top Module" and "Generate Programming File" in the project I had created gave me an updated myModule.bin, which was bit-for-bit identical with the downloaded one. When I downloaded that one to the Mimas v2 it also worked. To be sure that it was not just running the downloaded example, I wrote the Mimas v2 factory sample code in, and then my own built example:

MimasV2Config /dev/ttyACM0 mimasv2_sample_bin_file.bin
MimasV2Config /dev/ttyACM0 myModule.bin

and both worked.

So now I have a Linux-only programming environment for the Numato Mimas v2 set up. And have learnt that at least the Xilinx ISE WebPACK will GUI will happily continue on if it cannot match up the named inputs and outputs -- so that is definitely an issue to look out for in future use.

ETA, 2017-03-07: Useful Getting Starting with Numato Mimas v2 blog post, with lots of reference pictures and a slightly different small example (linked from the Knowledgebase tab of the Numato Mimas v2). Also of interest, FPGArduino (also on GitHub) which creates an Arduino-compatible microcontroller on the FPGA (via blog post describing how to install it on the Mimas v2 -- including an updated serial loader, etc; possibly some of those steps are no longer required; see also FPGArduino guide to JTAG programming on Linux, which points to a WiFi JTAG project based on an ESP8266!). Nearby is the f32c softcore, available under a BSD license. There is also a way to run PacMan on the Mimas v2!

ETA 2017-03-11: Corrected typo in programming device ID (should be XC6SLX9, for which there is a Xilinx Spartan 6 BSDL Model for use with a JTAG interface (Xilinx login required); BSDL (Boundary Scan Description Language) is a VHDL subset to describe pin maps; see also bsdl.info for a collection of BSDL files found from vendors).