22 Jan 2018

RPi and TPM and DT Part 1 (Background)

The company for which I work put together a daughter-board for the Raspberry Pi that includes a TPM chip (among other things). This series of posts is a recap of what was required to get the TPM chip working with an OE/Yocto-generated image.

More generically, Hitex has also created a daughter-board for the Raspberry Pi that includes the same chip.

The TPM chip is this one from Infineon, the SLB9670. It uses an SPI interface.

Back in the glory days of the PC and the PC clones, the memory locations of a device's configuration registers were known a priori. In other words, given the example of a serial port: a serial port has 8 contiguous configuration registers, if your computer had a serial port, its first register would be at memory location 0x3f8 and it would be known as COM1. If you had a second serial port, its base address would be 0x2f8 and it would be COM2. Nobody would ever dream of putting something else at 0x3f8, and if your PC's OS probed 0x3f8 and didn't find anything, it could assume you didn't have a COM1.

Nowadays, such hard-coding of the I/O space would be considered silly. Some products need no serial ports, and others need dozens; setting aside a large block of I/O space for devices that may or may not be present isn't useful. There's no reason 0x3f8 has to be reserved for the first serial port. Additionally, buses such as PCI and USB allow devices to be placed anywhere in memory and can be configured and probed dynamically. However, not all devices are on such fancy buses. SPI and I2C devices, for example, have simpler buses that don't provide dynamic probing and configuration. But your drivers still need to know where in the memory map they are found.

One solution to map known device addresses for a given product to device drivers, without hard-coding or a priori knowledge, is to use a Device Tree (DT). Given a specific product with a set of devices at specific addresses (for that product) a DT can be created (for that product) to map these known addresses for the relevant drivers. This means every product, potentially, needs its own Device Tree (if DT is the solution being used). Device Trees are stored and maintained alongside the Linux kernel sources, but are usually flashed to a separate location than the kernel itself are not not part of the kernel blob itself (although there are options to make it so). When booted, the kernel is provided with the information it needs to find the Device Tree. In this way, the same kernel build could work among a set of products that have, roughly, the same peripherals but potentially at different addresses, by providing different DTs for each product.

Device Trees are not new technology. Their lineage can be traced back to Sun's OpenFirmware from the late 1980s. The Linux kernel started using OF/DT early on for various PowerPC boards (e.g. the PowerPC-based Apple Macs from the 1990s).

Device Trees are not the only way to solve the kernel's "how can I find my peripherals?" problem. Other solutions include ACPI and UEFI.

This is all well and good for boards whose peripherals are "hard-coded" to the board itself (either because they are part of the MCU, or because they are soldered to the board and their bus IDs are also hard-coded). But most embedded boards come with expansion headers that allow the user to plug in daughter-boards to add features (be they "shields" or "capes" or "hats" etc.). These expansion headers mostly expose a bunch of I2C, SPI, and various GPIO pins to the user. The resulting explosion of DT possibilities would be crazy to try to maintain in any repository if the goal was to try to track every combination of board with every combination of daughter-board. Therefore Device Tree Overlays came into existence.

A Device Tree Overlay is a small snippet of a Device Tree that can be maintained and loaded separately, but is processed and merged with the base Device Tree by the kernel when it boots. DT Overlays are not dynamic. The assumption is that in order to change a product's daughter-board, the product would have to be powered down, and while the power is applied the wiring is not being changed. Some daughter-boards are even getting so fancy as to include a discoverable ID that can be used by the kernel to find and load the overlay without user intervention!

In my specific case I have a Raspberry Pi 3, with a "dumb" daughter-board which includes a TPM chip that I want the Linux kernel to be able to find and use. The Linux kernel already includes a driver for this specific TPM chip [drivers/char/tpm/tpm_tis_spi.c], all I need to do is to help it find the chip by providing a correct DT Overlay telling the driver where to look (i.e. which SPI bus and chip select to use) for the hardware. I also need to adjust my kernel configuration to make sure the relevant parts were compiled and included to support this hardware.

25 Oct 2017

Running ModelSim-Altera from the Quartus Prime Lite IDE under Linux

For reference I'm running:
  • Quartus Prime Lite version
  • ModelSim-Altera (i.e. the "free" one)
  • openSUSE 42.2 (kernel: 4.4.90-18.32-default)

Simulation is an important step when working with FPGAs. Unfortunately, out of the box, the ModelSim-Altera simulation tool will not run from either the Quartus Prime Lite IDE nor the cmdline under a modern (post-4.x kernel), 64-bit, Linux.

To get an idea of the problem (and verify it's occurring with your setup) try running the simulator tool by clicking on Tools -> Run Simulation Tool -> RTL Simulation (I'm fairly sure simulation can only be run after a design has been successfully compiled, so you'll need to start with a compiling project. Also I'm pretty sure you'll also need a top-level HDL for simulation, simulation doesn't work with schematic capture only (although getting the IDE to generate HDL from a schematic is fairly straight-forward))

For me this action results in the following error message:

Oddly, the contents of that file (i.e. where the error message says to check for more details) are only populated after you hit OK. Meaning you have to make the dialog box go away before you can open the file it tells you to check for more information. IOW, you can't keep the dialog box open to help find the file, you have to make note of where the file is, close the dialog box, then open the file. For reference mine looks like this:
Info: Start Nativelink Simulation process
Info: NativeLink has detected Verilog design -- Verilog simulation models will be used

========= EDA Simulation Settings =====================

Sim Mode              :  RTL
Family                :  max10
Quartus root          :  /opt/Altera/intelFPGA_lite/17.0/quartus/linux64/
Quartus sim root      :  /opt/Altera/intelFPGA_lite/17.0/quartus/eda/sim_lib
Simulation Tool       :  modelsim-altera
Simulation Language   :  verilog
Simulation Mode       :  GUI
Sim Output File       : 
Sim SDF file          : 
Sim dir               :  simulation/modelsim


Info: Starting NativeLink simulation with ModelSim-Altera software
Sourced NativeLink script /opt/Altera/intelFPGA_lite/17.0/quartus/common/tcl/internal/nativelink/modelsim.tcl
Error: Can't launch ModelSim-Altera Simulation software -- make sure the software is properly installed and the environment variable LM_LICENSE_FILE or MGLS_LICENSE_FILE points to the correct license file.
Error: NativeLink simulation flow was NOT successful

================The following additional information is provided to help identify the cause of error while running nativelink scripts=================
Nativelink TCL script failed with errorCode:  issued_nl_message
Nativelink TCL script failed with errorInfo:  Can't launch ModelSim-Altera Simulation software -- make sure the software is properly installed and the environment variable LM_LICENSE_FILE or MGLS_LICENSE_FILE points to the correct license file.
    while executing
"error "$emsg" "" "issued_nl_message""
    invoked from within
"if [ catch {exec $vsim_cmd -version} version_str] {
                set emsg "Can't launch $tool Simulation software -- make sure the software is properly installed..."
    (procedure "launch_sim" line 88)
    invoked from within
"launch_sim launch_args_hash"
    ("eval" body line 1)
    invoked from within
"eval launch_sim launch_args_hash"
    invoked from within
"if [ info exists ::errorCode ] {
                set savedCode $::errorCode
                set savedInfo $::errorInfo
                error $result $..."
    invoked from within
"if [catch {eval launch_sim launch_args_hash} result ] {
            set status 1
            if [ info exists ::errorCode ] {
                set save..."
    (procedure "run_sim" line 74)
    invoked from within
"run_sim run_sim_args_hash"
    invoked from within
"if [ info exists ::errorCode ] {
            set savedCode $::errorCode
            set savedInfo $::errorInfo
            error "$result" $savedInfo ..."
    (procedure "run_eda_simulation_tool" line 334)
    invoked from within
"run_eda_simulation_tool eda_opts_hash"
Note that this error message location, /home/trevor/devel/fpga/de10-lite/rapid_verilog, is the directory that I created for this project. Also note that orgate is the name of this project's top-level entity. Therefore the location and filename of your error message will be different, but should follow the same pattern. For future reference I'll refer to /home/trevor/devel/fpga/de10-lite/rapid_verilog as ${PROJECT_DIR}.

What's really bad about the error messages that show up in the GUI dialog box and in the rpt file is that they imply there's some sort of problem with a license file. There isn't. No license (not even a "free" one) is required to run ModelSim-Altera. This is a red herring. There are a bunch of things that are wrong and need fixing. But none of those have anything to do with licensing. So please resist the urge to log into the Altera website, generate a license, download, and install it. There will be no change to your predicament and hopefully I've saved you from going down that path and wasting a few hours.

If, at Altera's Quartus Prime Lite download page, you selected Combined Files then the simulation software, ModelSim-Altera, would have been installed along with the entire Quartus Prime Lite package.

During installation, the Quartus Prime Lite installer will ask you for an install location. I'm going to call that location ${QUARTUS_INSTALL_DIR} throughout this post (which for me is /opt/Altera/intelFPGA_lite/17.0). At ${QUARTUS_INSTALL_DIR} we find the modelsim_ase directory, which is the directory that contains the ModelSim-Altera Simulation software.

To start investigating what's going wrong, we need to start with where the Quartus Prime Lite IDE looks for the simulation tool. Under Tools -> Options

 Select General -> EDA Tool Options

If we look look into this ${QUARTUS_INSTALL_DIR}/modelsim_ase/bin directory, we see that it is filled with symlinks:

Looking carefully, we see that all these links point to just one file!

Looking through this vco file we see it's a shell script. Its job appears to be a multiplexer: the calling program tries to run one of the programs in this bin directory. Based on a bunch of things the vco script finds, it figures out which "real" program to run and where to find this "real" program. The script appears to have support for being run on AIX, Cygwin, Win*, SunOS, HP-UX, and Linux. As you can tell by this list, vco is probably in need of an update!

In the case of Linux, the script first tries to determine which "mode" it should use. The possible modes are "32" and "64". But it doesn't make its determination based on the processor on which it is run, it makes this determination based on a combination of what specific program the caller is requesting, and what directory names it finds in ${QUARTUS_INSTALL_DIR}/modelsim_ase. In most cases, even when running on 64-bit hardware, when run on Linux it will set the "mode" to 32.

Next the vco script tries to define the directory in which to find the actual Linux programs to run. It does this by looking at what kernel is running. The script has support for kernels starting with 2.4.x and running up to 3.x. If the current kernel is something that it can match in this range, it sets the run directory to "linux". Any kernel it finds outside this range is assumed to be something ancient, so it sets the run directory to "linux_rh60". For reference, RedHat Linux 6.0 came out in 1999 with a 2.2.5 kernel. Therefore, when run on a modern system with a post 3.x kernel, it will want to find the programs to run in a directory named ${QUARTUS_INSTALL_DIR}/modelsim_ase/linux_rh60. If we look in the ${QUARTUS_INSTALL_DIR}/modelsim_ase directory, we find a linuxaloem directory and we find a linux symlink to linuxaloem. But we don't find any linux_rh60 directory nor symlink. So it appears that support for early systems has been removed from Quartus Prime Lite, but the vco script still tries to use that directory when it doesn't know what to make of the kernel version.

There are a couple ways to solve this issue. On the one hand you could dig into the vco script and try to fix some of its shortcomings. You could create a linux_rh60 symlink that simply points to either linuxaloem or linux. But at the end of the day, the easiest thing to do is to completely bypass the vco script altogether by editing the directory path in the EDA Tool Options to point to ${QUARTUS_INSTALL_DIR/modelsim_ase/linuxaloem instead! This way when Quartus Prime Lite wants to run the simulator, it will simply invoke the correct Linux binary directly instead of going through the multiplexing script first.

Now that we've routed around this problem, we can try running the simulator again... nope, not fixed.
Looking in the ${QUARTUS_INSTALL_DIR}/modelsim_ase/linuxaloem directory, we find a bunch of actual executables (i.e. not more scripts). If we try to run, for example, the vsim program we get:

 $ ./vsim
./vish: error while loading shared libraries: libX11.so.6: cannot open shared object file: No such file or directory

Why is it running the vish program? In any case, this error makes a little bit of sense. We noted above that the vco script decides to set the mode to "32", despite running on the 64-bit machine. If we look at these programs (in ${QUARTUS_INSTALL_DIR/modelsim_ase/linuxaloem) we find:

 $ ldd vsim
        linux-gate.so.1 (0xf7783000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xf773e000)
        libdl.so.2 => /lib/libdl.so.2 (0xf7739000)
        libm.so.6 => /lib/libm.so.6 (0xf76f2000)
        libc.so.6 => /lib/libc.so.6 (0xf7549000)
        /lib/ld-linux.so.2 (0xf7785000)

 $ ldd vish
        linux-gate.so.1 (0xf76f6000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xf76b1000)
        libdl.so.2 => /lib/libdl.so.2 (0xf76ac000)
        libm.so.6 => /lib/libm.so.6 (0xf7665000)
        libX11.so.6 => not found
        libXext.so.6 => not found
        libXft.so.2 => not found
        libXrender.so.1 => not found
        libfontconfig.so.1 => /usr/lib/libfontconfig.so.1 (0xf7626000)
        librt.so.1 => /lib/librt.so.1 (0xf761d000)
        libncurses.so.5 => /lib/libncurses.so.5 (0xf75f2000)
        libc.so.6 => /lib/libc.so.6 (0xf7449000)
        /lib/ld-linux.so.2 (0xf76f8000)
        libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0xf73b1000)
        libexpat.so.1 => /usr/lib/libexpat.so.1 (0xf7388000)
        libtinfo.so.5 => /lib/libtinfo.so.5 (0xf735e000)
        libz.so.1 => /lib/libz.so.1 (0xf7346000)
        libbz2.so.1 => /usr/lib/libbz2.so.1 (0xf7337000)
        libpng16.so.16 => /usr/lib/libpng16.so.16 (0xf72fb000)

Obviously my openSUSE install already has libX11 (and friends) installed, why does ldd claim to not find them? If you look at the libraries it does find, you'll notice that ldd is finding them in /lib/... not /lib64/.... This means these binaries are looking for 32-bit libraries, not 64-bit ones. Therefore, we need to install some 32-bit packages. Also, as it turns out, my system already has a bunch of 32-bit compatibility libraries installed, otherwise the ldd outputs wouldn't have even been this good. If your ldd tests on these binaries doesn't come out as well, you may need to find and install even more 32-bit libraries than were needed on my system. On my openSUSE 42.2 system the following helps get past this "thanks for the 32-bit binaries" issue:

# zypper install libX11-6-32bit libXext6-32bit libXft2-32bit libXrender1-32bit

Now that we've routed around this problem, we can try running the simulator again... nope, not fixed. However, this time we get no error dialog. I do see some sort of dialog pop up then quickly disappear before I can read anything, but the simulator doesn't start.

If we start the Quartus software from the cmdline, when we try to run the simulator we'll see the following error message on the cmdline from which we invoked the IDE:

$ ./quartus
Info: *******************************************************************
Info: Running Quartus Prime Shell
    Info: Version 17.0.2 Build 602 07/19/2017 SJ Lite Edition
    Info: Copyright (C) 2017  Intel Corporation. All rights reserved.
    Info: Your use of Intel Corporation's design tools, logic functions
    Info: and other software and tools, and its AMPP partner logic
    Info: functions, and any output files from any of the foregoing
    Info: (including device programming or simulation files), and any
    Info: associated documentation or information are expressly subject
    Info: to the terms and conditions of the Intel Program License
    Info: Subscription Agreement, the Intel Quartus Prime License Agreement,
    Info: the Intel MegaCore Function License Agreement, or other
    Info: applicable license agreement, including, without limitation,
    Info: that your use is for the sole purpose of programming logic
    Info: devices manufactured by Intel and sold by Intel or its
    Info: authorized distributors.  Please refer to the applicable
    Info: agreement for further details.
    Info: Processing started: Wed Oct 25 02:55:26 2017
Info: Command: quartus_sh -t /opt/Altera/intelFPGA_lite/17.0/quartus/common/tcl/internal/tivelink/qnativesim.tcl --rtl_sim orgate orgate
Info: Quartus(args): --rtl_sim orgate orgate
Info: Info: Start Nativelink Simulation process
Info: Info: NativeLink has detected Verilog design -- Verilog simulation models will be ud
Info: Info: Starting NativeLink simulation with ModelSim-Altera software
Warning: Warning: File orgate_run_msim_rtl_verilog.do already exists - backing up currentile as orgate_run_msim_rtl_verilog.do.bak2
Info: Info: Generated ModelSim-Altera script file /home/trevor/devel/fpga/de10-lite/rapiderilog/simulation/modelsim/orgate_run_msim_rtl_verilog.do File: /home/trevor/devel/fpga/d0-lite/rapid_verilog/simulation/modelsim/orgate_run_msim_rtl_verilog.do Line: 0
Info: Info: Spawning ModelSim-Altera Simulation software
Info: Info: Successfully spawned ModelSim-Altera Simulation software
Info: Info: NativeLink simulation flow was successful
Info: Info: For messages from NativeLink scripts, check the file /home/trevor/devel/fpga/10-lite/rapid_verilog/orgate_nativelink_simulation.rpt File: /home/trevor/devel/fpga/de10ite/rapid_verilog/orgate_nativelink_simulation.rpt Line: 0
Info (23030): Evaluation of Tcl script /opt/Altera/intelFPGA_lite/17.0/quartus/common/tclnternal/nativelink/qnativesim.tcl was successful
Info: Quartus Prime Shell was successful. 0 errors, 1 warning
    Info: Peak virtual memory: 796 megabytes
    Info: Processing ended: Wed Oct 25 02:55:26 2017
    Info: Elapsed time: 00:00:00
    Info: Total CPU time (on all processors): 00:00:00
Failed to obtain lock: couldn't open "/home/trevor/.modelsim_lock": file already exists
Error in startup script:
Initialization problem, exiting.

Initialization problem, exiting.

Initialization problem, exiting.

    while executing
"Transcript::action_log "PROPREAD \"$key\" \"$value\"""
    (procedure "VsimProperties::Init" line 59)
    invoked from within
"VsimProperties::Init $MTIKeypath"
    (procedure "PropertiesInit" line 18)
    invoked from within
    invoked from within
"ncFyP12 -+"
    (file "/mtitcl/vsim/vsim" line 1)
** Fatal: Read failure in vlm process (0,0)

Note: if we try running vsim (from ${QUARTUS_INSTALL_DIR}/modelsim_ase/linuxaloem) directly we also get:

 $ ./vsim
Failed to obtain lock: couldn't open "/home/trevor/.modelsim_lock": file already exists
Error in startup script:
Initialization problem, exiting.

Initialization problem, exiting.

Initialization problem, exiting.

    while executing
"Transcript::action_log "PROPREAD \"$key\" \"$value\"""
    (procedure "VsimProperties::Init" line 59)
    invoked from within
"VsimProperties::Init $MTIKeypath"
    (procedure "PropertiesInit" line 18)
    invoked from within
    invoked from within
"ncFyP12 -+"
    (file "/mtitcl/vsim/vsim" line 1)
** Fatal: Read failure in vlm process (0,0)

If we google some of these messages, we find that it's a very strange way of saying that the program is unhappy with our system's version of freetype. The solution to this issue is to download, compile, and install an older version of freetype. We don't, however, want to install this older version to any system locations (and therefore mess up our system's package manager). Therefore, we will simply provide an alternate install-to directory, and use some tricks to make sure these Quartus programs use the alternate library. In my case I downloaded freetype-2.4.7, built, and installed it. But hold on: by default my system will compile everything to 64-bit code. That won't work in this case because, as we've established, these binaries are 32-bit and are looking for 32-bit libraries. Therefore in order to build for 32-bit on a 64-bit system:

$ CFLAGS=-m32 ./configure --prefix=/home/trevor/local/packages/freetype-2.4.7-32bit/

FreeType build system -- automatic system detection

The following settings are used:

  platform                    unix
  compiler                    cc
  configuration directory     ./builds/unix
  configuration rules         ./builds/unix/unix.mk

If this does not correspond to your system or settings please remove the file
`config.mk' from this directory then read the INSTALL file for help.

Otherwise, simply type `make' again to build the library,
or `make refdoc' to build the API reference (the latter needs python).

cd builds/unix; ./configure  '--prefix=/home/trevor/local/packages/freetype-2.4.7-32bit/'
configure: loading site script /usr/share/site/x86_64-unknown-linux-gnu
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking for gcc... gcc
checking whether the C compiler works... no
configure: error: in `/home/trevor/devel/extern/freetype-2.4.7/builds/unix':
configure: error: C compiler cannot create executables
See `config.log' for more details
builds/unix/detect.mk:84: recipe for target 'setup' failed
make: *** [setup] Error 77

That's not good. If we look at the builds/unix/config.log file we find:

configure:2904: checking whether the C compiler works
configure:2926: gcc -m32   conftest.c  >&5
/usr/lib64/gcc/x86_64-suse-linux/6/../../../../x86_64-suse-linux/bin/ld: skipping incompatible /usr/lib64/gcc/x86_64-suse-linux/6/libgcc.a when searching for -lgcc
/usr/lib64/gcc/x86_64-suse-linux/6/../../../../x86_64-suse-linux/bin/ld: cannot find -lgcc
/usr/lib64/gcc/x86_64-suse-linux/6/../../../../x86_64-suse-linux/bin/ld: skipping incompatible /usr/lib64/gcc/x86_64-suse-linux/6/libgcc.a when searching for -lgcc
/usr/lib64/gcc/x86_64-suse-linux/6/../../../../x86_64-suse-linux/bin/ld: cannot find -lgcc
collect2: error: ld returned 1 exit status

That's a classic problem that happens when one tries to build 32-bit software on a 64-bit system. The 32-bit versions of more build infrastructure needs to be added:

# zypper install gcc-32bit

Now the build should work:

$ CFLAGS=-m32 ./configure --prefix=/home/trevor/local/packages/freetype-2.4.7-32bit
$ make install

If we then try to run the vsim program by hand from the cmdline we (still) get:

Error in startup script:
Initialization problem, exiting.

Initialization problem, exiting.

Initialization problem, exiting.

    while executing
"Transcript::action_log "PROPREAD \"$key\" \"$value\"""
    (procedure "VsimProperties::Init" line 59)
    invoked from within
"VsimProperties::Init $MTIKeypath"
    (procedure "PropertiesInit" line 18)
    invoked from within
    invoked from within
"ncFyP12 -+"
    (file "/mtitcl/vsim/vsim" line 1)
** Fatal: Read failure in vlm process (0,0)

That's because we're still using the system's freetype. In order to use the freetype we've just built and installed:

$ LD_LIBRARY_PATH=/home/trevor/local/packages/freetype-2.4.7-32bit/lib:$LD_LIBRARY_PATH ./vsim
Failed to obtain lock: couldn't open "/home/trevor/.modelsim_lock": file already exists
Reading pref.tcl


But what can we do to make sure this recently-compiled freetype is used automatically?

If we look carefully at the full log that we get from when we ran Quartus Prime Lite from the cmdline and tried to run the simulator from the resulting IDE, we see that one of the first things the IDE does is to run quartus_sh. This file is located in ${QUARTUS_INSTALL_DIR}/quartus/bin. If we look into this file we see that it is a script which is very similar in function to the vco script we found in the modelsim_ase directory [in fact, if we look at everything in that directory we see that the contents of every file is exactly the same as every other file in that directory with actual copies instead of symlinking to just one script!]. Most of the script determines what to do, then at the end the actual program is invoked. Just before invoking the actual program a qenv.sh file is sourced. The qenv.sh file is found in ${QUARTUS_INSTALL_DIR}/quartus/adm directory. If we edit this qenv.sh file and, very close to the top, add the following line (adjust it so it matches your specific situation):

export LD_LIBRARY_PATH=/home/trevor/local/packages/freetype-2.4.7-32bit/lib:$LD_LIBRARY_PATH

then we'll find that we can invoke the simulator from within the IDE and it will come up with the work folder that we need to simulate our design!!


Now we can simulate our design by right-clicking on orgate and selecting Simulate


One webpage that was immensely helpful was this one from the Arch community, thanks!!

18 Oct 2017

email PSA

(the following is meant to be humourous, with just a teensy bit of seriousness. anyone who is incapable of reading/understanding humour on the internet is kindly asked to please go back to facebook)

To all the Toms, Traceys, Tims, Todds, Tamaras, Tonys, Tinas, Troys, Taylors, (and others whose first name starts with "T").... of the world whose last name is "Woerner": please stop telling everyone your email address is twoerner at gmail dot com! It's not. That's my email address. I'm tired of receiving your pay stubs, flight itineraries, baby pictures, academic reports, "lady" pics, resumes, etc.

Recently someone asked me for my email address. What's funny is how confused and condescending she was when it didn't include numbers.

    "Are you sure?"
    "It's not 'twoerner' and then a year or some other numbers at gmail dot com?"
    No. Just 'twoerner' with no numbers at gmail dot com.
    "Uh huh".

I guess I come from the only generation whose gmail addresses don't need numbers. Apparently in my lifetime that's already becoming dated. Centuries from now historians will be able to tell my age and roughly what years I was alive based on the fact my email address is composed of: my first initial, plus last name, with no numbers, at gmail dot com. Thousands of years from now nobody will still be able to use twoerner @ gmail because some guy who died decades ago chose it.

That's me!
(You're welcome)

17 Oct 2017

FPGAs: Altera/Intel Tool on Linux

Altera/Intel provides "free" tools (Quartus Prime Lite) in very much the same way as Xilinx (ISE/Vivado). They're "free" in the sense no money is exchanged. But you do need to register; you need to be logged into their website in order to download the installer; and, when run, these tools do communicate details back to the "mother ship". For Xilinx this "feature" is called WebTalk, for Altera/Intel this "feature" is called TalkBack. Unlike Xilinx, Altera/Intel doesn't seem to provide a FAQ or website with information or details about TalkBack (or, at least, my google-foo wasn't strong enough to find it).

The download for Quartus Prime Lite is just a simple tar (it is not compressed). The download for version (the latest as of this writing) is 6.1GB. At first it seems odd that the tar is not compressed, but when I compress it with xz, the resulting file is 8.1GB! In any case, this large download causes me the same issues I had with Xilinx's ISE. Since a registration is required, and I have to be logged in to download the installer, and the webpage likes to automatically log me out after a period of inactivity, and my internet download speed is slow, I ended up having to make several attempts to download the complete 6.1GB file.

On the plus side, however, installing Quartus Prime Lite doesn't involve any license shenanigans. If you download the correct flavour (i.e. the "lite" version) there's no need to mess around with obtaining, installing, and managing a license file. Presumably, this would make it easier to install the software on a different machine and continue development. In contrast, the required license file for ISE/Vivado is locked to an ethernet MAC, so if you move the software or the MAC goes away, you'd be locked out of your Xilinx tools until you rectify the situation.

Another plus for the Quartus Prime Lite software is that this one tool handles all the Altera products. There's no need for one tool to do one set of products, and another tool for newer products.

One of the ironic things about the install is that at one point it asks me if I want to enable the TalkBack "feature". Of course I don't want to enable TalkBack, but the install likes to tease me into thinking that I might be able to install the product without this feature. I can, of course, not install/enable TalkBack, but then I'd need a paid license/subscription. To use the "free" tool, TalkBack must be enabled. By default this "Do you want to enable TalkBack?" button is not checked, forcing me to explicitly turn it on (because I so very much want to enable this "feature"!!).

Other than the above, the install is pretty straight-forward. No libraries need to be deleted (as is required with the Xilinx ISE install), no other "gotchas". Just give it a place to install itself, tell it which products you intend to use, enable TalkBack (yay!), and it does the rest.

16 Oct 2017

FPGAs: Papilio One

One of the first FPGA boards I bought is the Papilio One from Gadget Factory. What I like about the Papilio project is its creator's (Jack Gassett) focus on learning and openness. In addition to Jack's guides and tutorials, a fellow named Mike Field (aka Hamster) wrote a free "Introduction to Spartan FPGA" book based around the Papilio and the LogicStart MegaWing (also from Gadget Factory). Then, along came Álvaro Lopes who created the ZPUino which is a 32-bit Arduino-type soft CPU for the Papilio, complete with Wishbone peripherals and an Arduino-style library and IDE. Also, Make's FPGA book uses the Papilio (among other boards) for some of its projects.

After you've installed Xilinx's ISE, Jack provides a great guide to creating your first VHDL project for the Papilio One. His guide uses a slightly older version of ISE so there are some differences between his guide and what you'll find in ISE 14.7, but nothing that can't be figured out. Generating the bitfile completes successfully for me. Now to upload it to the device.

To upload a bitfile to the Papilio One requires the use of the Papilio-Loader program. Clone the project to your local machine. The cmdline version of the loader program (which is all I'm interested in) is found in the papilio-prog subdirectory; therefore move to that location. Since the papilio uses an FTDI chip for serial communications (via USB), you'll need to install the FTDI devel package; on openSUSE its name is "libftdi1-devel". The build system for papilio-prog is the autotools, and it requires pkg-config to be installed (you'll need to figure out how to do that on your system). After the pkg-config package is installed, you'll need to find where it installed its pkg.m4 file. For me this file was installed to /usr/share/aclocal/pkg.m4. With this information I need to edit the top-level Makefile.am to include the path leading up to the pkg.m4 file:

diff --git a/papilio-prog/Makefile.am b/papilio-prog/Makefile.am
index a0ef45a..a31e9c3 100644
--- a/papilio-prog/Makefile.am
+++ b/papilio-prog/Makefile.am

@@ -1,3 +1,4 @@
+ACLOCAL_AMFLAGS = -I /usr/share/aclocal
 bin_PROGRAMS = papilio-prog

 papilio_prog_SOURCES = butterfly.cpp \

I also modified the top-level configure.ac as follows:
diff --git a/papilio-prog/configure.ac b/papilio-prog/configure.ac
index 230add6..35b428a 100644
--- a/papilio-prog/configure.ac
+++ b/papilio-prog/configure.ac

@@ -14,7 +14,7 @@ if test -n "$host_alias" ; then
        AC_DEFINE([WINDOWS], 1, [Cross-compiling for windows])
        LIBS="$LIBS -L. -lftd2xx -static-libgcc -static-libstdc++"
-       PKG_CHECK_MODULES([libftdi1], [libftdi >= 0.19],
+       PKG_CHECK_MODULES([libftdi1], [libftdi1 >= 0.19],
                [CPPFLAGS="$CPPFLAGS $libftdi1_CFLAGS";
                LIBS="$LIBS $libftdi1_LIBS"])

With those adjustments in place, building was a simple matter of:

$ ./autogen.sh
Generating build system...
$ ./configure
$ make

Install the resulting papilio-prog to someplace in your $PATH. Plug the Papilio-One into your computer via a USB cable (you only need to connect the USB cable for both communication and power, no need to plug anything into the power barrel jack).

When the papilio is plugged in, you should find an extra USB device on your system:
$ lsusb
Bus 001 Device 067: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC

Then, once you've located your bitfile, you can perform the following to upload it to your device:
# papilio-prog -f Webpack_Quickstart.bit
Using built-in device list
JTAG chainpos: 0 Device IDCODE = 0x41c22093     Desc: XC3S500E
Created from NCD file: Webpack_Quickstart.ncd;UserID=0xFFFFFFFF
Target device: 3s500evq100
Created: 2017/09/30 00:55:28
Bitstream length: 2270208 bits

Uploading "Webpack_Quickstart.bit".

Note that I'm running papilio-prog as root. If I wanted to get fancy I could create a udev rule to set this device's file mode to 0666.

When I plug my papilio into my machine, the following shows up in my system logs:
kernel: usb 1-4.4.4: new full-speed USB device number 69 using xhci_hcd
kernel: usb 1-4.4.4: New USB device found, idVendor=0403, idProduct=6010
kernel: usb 1-4.4.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
kernel: usb 1-4.4.4: Product: Dual RS232
kernel: usb 1-4.4.4: Manufacturer: FTDI
kernel: ftdi_sio 1-4.4.4:1.0: FTDI USB Serial Device converter detected
kernel: usb 1-4.4.4: Detected FT2232C
kernel: usb 1-4.4.4: FTDI USB Serial Device converter now attached to ttyUSB1
kernel: ftdi_sio 1-4.4.4:1.1: FTDI USB Serial Device converter detected
kernel: usb 1-4.4.4: Detected FT2232C
kernel: usb 1-4.4.4: FTDI USB Serial Device converter now attached to ttyUSB2
mtp-probe[24662]: checking bus 1, device 69: "/sys/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4.4/1-4.4.4"
mtp-probe[24662]: bus: 1, device: 69 was not an MTP device
As you can see, two USB devices get created. The second one can be used for serial logging. The test bitfile provided for the Papilio One demonstrates this feature: Papilio One 500K QuickStart bit file. Opening up a terminal emulator (e.g. minicom) on the second USB device (9600 8N1) will show what is being logged over the serial port.

My final verdict for this board is positive! The Spartan 3E is an older chip, but there is a 500k version (which is a pretty good size for a beginner). The tools install and work on Linux. It's possible to upload bitfiles to the board using Linux. The price of the board is reasonable. Plus, there are lots of learning materials targeted at this board specifically.

FPGAs: Xilinx Tools on Linux

Historically the "free" tool from Xilinx to work with Xilinx FPGAs is ISE Webpack (or just ISE). That tool is still around, is still "free", and still works in Linux (I'll explain later why I write "free" in quotes). For the past few years, however, Xilinx has created a newer tool, Vivado, for working with Xilinx products. Although ISE is still available, it hasn't received any updates for the past couple years (since 2013). But here's the funny part: Vivado doesn't support the older chips. So if you're working with older Xilinx chips (Spartan 3 or Spartan 6) you have to use the old, hasn't been updated since 2013, ISE. If you want to play with any of Xilinx's newer chips (Zynq, Artix, or UltraScale) you'll need to use Vivado. So if you happen to have projects involving both chips, you'll need to download and install two separate tools.

One small issue that messed me up occurred while I was trying to download the install package for ISE. The 14.7 version of the ISE Linux installer is 6.1GB. I live way out in a rural area, so my internet connection is slow. In order to download the installer, I had to be logged into the Xilinx site for the entire duration of the download. After a period of inactivity, Xilinx's site will log out out automatically. Since my download hadn't completed before the website automatically logged me out, my download would fail. One solution is to start the download early in the morning and to make sure you play around on the Xilinx website throughout the day to keep yourself from getting logged out automatically. Another possibility is to just let it download as long as possible, when it fails, re-login to Xilinx's site, then restart the download. Firefox's downloader is smart enough to continue the download (as opposed to requiring the entire download to be started again from scratch).

In contrast, the download for installing Vivado is only about 85MB which is easier to download over a slow connection before getting logged out. However, during the installation you'll need to make sure you stay logged in because the remainder of the download occurs during the installation itself, which could cause it to fail if you get automatically logged out.

Whether you're installing ISE or Vivado, one of the biggest headaches is the licensing. If you want to unlock features above-and-beyond the base, "free" features you'll need to pay for a license. This gives you a file you need to install, which unlocks the features for which you've paid. That all makes sense. However, even if you don't want any of those fancy paid features and are only using the "free" things, you still need to generate a license file and install it. In theory the installer is supposed to handle all the licensing for you. In practice it doesn't seem to work that well on Linux. Therefore a special trip to Xilinx's website is required to create the license file and download it. Then it has to be installed manually after the install itself has completed before you can hope to run the application.

Installing and running ISE can succeed, but only with a fair amount of work. Rob Landley has an excellent, detailed, step-by-step post on how to get ISE installed and running on a Linux host. I won't bother reproducing it here, but simply point you to it.

Installing and running Vivado on Linux follows, roughly, the same steps. Once you've done one, the other will be familiar. It appears as though there are no issues having both installed and running on the same host at the same time. The Vivado install also didn't require any libc files to be manually deleted, so that's a good thing. But all the same license shenanigans are still required to unlock the "free" features.

So why do I keep writing "free" in quotes? Xilinx's definition of "free" means "no money exchanged". But in exchange for not paying money Xilinx does want to collect information about you and your projects... lots of information.

First off, in order to download ISE or Vivado, you need to register an account on their website. I know that many (most?) people don't consider providing a name and such other information as much of a "cost". But data is worth a lot of money, and I wish more people would stop thinking that providing information doesn't have an associated cost. I've downloaded the Linux kernel, Linux-based distributions, and other GNU/Linux software thousands of times in the past and never needed a registration in order to do so. Besides, the fact Xilinx requires a registration has been the cause of my download headaches (as I've pointed out above).

Secondly, and more to the point, whenever you use their "free" tools, those tools communicate information about your machine and your project back to the "mother ship". Although Xilinx tries to provide full information about this feature (called WebTalk), it does seem rather insidious to me. They have a page that answers most questions about WebTalk, but since the communication is all proprietary, I guess we'll just have to take their word when they say they're not being evil.

Finally, all this license nonsense requires a lot of fiddling and so forth should you ever want to move to a different machine.

All this effort wasted on handling and managing licensing, plus all the gobs of data that is provided to Xilinx (both explicitly and implicitly) does not feel "free" to me!

Oh well, I guess I should be grateful I can work with Xilinx parts using an all-Linux environment. Yay!

Starting FPGAs

Learning FPGAs has been on my "TODO" list for a while.

Many years ago I had the opportunity to work on a new project that involved embedded Linux and FPGAs. As the "Linux software person" I worked entirely on the Linux software. But I had the good fortune to work with some brilliant FPGA people. I was blown away. It was amazing to sit down with these people and say "I could really use a register that works like <this>" and a couple hours later be emailed a new bitfile, load it in, and find a register that did exactly as I wanted! Brand new, custom designed hardware... on a whim! The development of the product progressed hand-in-hand in this way, and it was a very successful endeavour!

It didn't take long, however, for me to wish that I could work both sides of the coin: I can do the Linux stuff (user-space apps, device drivers, creating images, etc) but it would be great to also be able to "play" with the FPGA side as well. Although I wasn't able to find the time to learn FPGAs back then, I did make sure to ask lots of questions of these experts while I was around them. The two most basic questions that quickly come up are: What hardware (vendor) should I use? Should I learn VHDL or verilog (or something else)?

What I found interesting about their answers is that they readily admitted that their choice of vendor and language today was based entirely on whatever technology they were taught at university. It's not about vendor lock-in per se, it's about the tendency to learn a tool, becoming proficient at it, then developing a reluctance to want to build the same proficiency in another tool (or language) for no apparent gain. The same things can be done, roughly, in both languages. The capabilities of the hardware from the various vendors is, roughly, on par. There is no clear winner in either category (or so is my understanding).

At this point I have no idea how proficient (or not) I might become in actually developing my own projects. My point, for now, is to know enough to be able to play with existing things I find (e.g. OpenCores). For my purposes, in terms of VHDL vs verilog, I see lots of interesting projects that are done using both; both languages seem to be equally popular. Ideally it would be nice to have some familiarity of both. There are also a couple projects that try to bring things like C or Python to the world of digital development. Those might be interesting to explore as well.

My thoughts regarding hardware are similar to how I feel about HDLs. I would rather become somewhat knowledgeable on a bunch of them rather than to be good at only one. Also, since I do all my development work on a Linux machine, one thing that will be important for me is how well the development workflow of the various vendors supports Linux. How easy (or hard) is it to develop for vendor A's product in Linux (including getting the result into real hardware) versus vendor B, C, or D?

FPGAs have always been an interesting and fascinating technology. Coupling them with Linux in an embedded environment, I think, is an amazing partnership. Linux is great, and real-time Linux is amazing. But, let's face it, nobody can realistically promise absolute strict timing as long as a software scheduler is involved. When done well, using an FPGA can cover those things that absolutely need very strict timings. FPGAs also provide a decent place to "hide" the magic sauce of your project. Also, with good profiling, it's possible to find those processing-intensive parts of your design and potentially move them out to hardware.

I think FPGA companies have sold as many FPGAs to EEs as they're going to. Their next wave is going to come from software developers :-)