Measuring code coverage with GHDL

I have recently switched to using GHDL as my VHDL simulator of choice. GHDL (currently) supports three different backends: GCC, LLVM and a builtin code generator.

The GCC backend got me thinking… since my VHDL test benches are now native ELF binaries compiled with GCC, I should be able to instrument them with Gcov support – and measure code coverage for each unit under test (UUT).

Turns out to be pretty simple – just a matter of using the right compiler and linker flags, just like building a Gcov-instrumented binary from C code.

Take for instance the full adder example from the GHDL documentation – once the adder.vhdl and adder_tb.vhdl files are saved to disk, it is just a matter of modifying the GHDL commands a bit to instrument the final binary with Gcov support.

First analyze the design files with -fprofile-arcs and -ftest-coverage added to CFLAGS for all the VHDL files, that should be instrumented. Here, I have only instrumented the UUT, not the test bench:

$ ghdl -a  -Wc,-fprofile-arcs -Wc,-ftest-coverage adder.vhdl

$ ghdl -a  adder_tb.vhdl  

Next, elaborate the test bench and link the binary against libgcov:

$ ghdl -e -Wl,-lgcov adder_tb

Run the test bench as usual:

$ ghdl -r adder_tb
adder_tb.vhdl:53:7:@8ns:(assertion note): end of test

Generate a code coverage report using the gcov(1) tool:

$ gcov -s $PWD adder.vhdl 
File 'adder.vhdl'
Lines executed:100.00% of 4
Creating 'adder.vhdl.gcov'

The Gcov code coverage details can be found in the adder.vhdl.gcov file. Details on the file format can be found in the gcov(1) man page:

$ cat adder.vhdl.gcov 
        -:    0:Source:adder.vhdl
        -:    0:Graph:adder.gcno
        -:    0:Data:adder.gcda
        -:    0:Runs:1
        -:    0:Programs:1
       13:    1:entity adder is
        -:    2:  -- `i0`, `i1` and the carry-in `ci` are inputs of the adder.
        -:    3:  -- `s` is the sum output, `co` is the carry-out.
        -:    4:  port (i0, i1 : in bit; ci : in bit; s : out bit; co : out bit);
        -:    5:end adder;
        -:    6:
        2:    7:architecture rtl of adder is
        -:    8:begin
        -:    9:   --  This full-adder architecture contains two concurrent assignment.
        -:   10:   --  Compute the sum.
       17:   11:   s <= i0 xor i1 xor ci;
        -:   12:   --  Compute the carry.
       10:   13:   co <= (i0 and i1) or (i0 and ci) or (i1 and ci);
        -:   14:end rtl;

Another option is to use a tool like Lcov, which can produce nice looking HTML pages with the Gcov code coverage details:

$ lcov -c -d . -o adder_tb.info
Capturing coverage data from .
Found gcov version: 4.9.4
Scanning . for .gcda files ...
Found 1 data files in .
Processing adder.gcda
Finished .info-file creation

$ genhtml -o html adder_tb.info 
Reading data file adder_tb.info
Found 1 entries.
Found common filename prefix "/home/brix/tmp"
Writing .css and .png files.
Generating output.
Processing file adder/adder.vhdl
Writing directory view page.
Overall coverage rate:
  lines......: 100.0% (4 of 4 lines)
  functions..: 100.0% (7 of 7 functions)

The Lcov code coverage details can be found in the html/index.html file:

Linux on the Arty, Part 0: Establishing a build environment

I have long wanted to explore the endless possibilities of soft core CPUs like the Xilinx Microblaze. A few months back, I stumbled across the announcement of the Arty by Digilent/Avnet/Xilinx – an affordable evaluation/development board clearly built for makers and perfect for getting my feet wet with a few Microblaze-based projects.

Part0-Arty-0

I initially wanted to get GNU/Linux up and running on a Microblaze CPU on the Arty to establish a familiar software environment for further tinkering. This proved to be quite a task in itself – a task which required reading through lots of product guides, manuals, blog posts and howtos online. Lots of documentation has been written on the Microblaze subject, but none of it was quite to the point or simple for me to follow.

In the following series of blog posts I will describe my way of accomplishing this goal; Linux on the Arty, with all on-board peripherals up and running and exposed to userland.

In the first posts, post 0, we will establish a build environment for both the hardware and the software. Later posts will span from establishing a bare-minimal, Linux-ready hardware design to getting each on-board peripheral of the Arty included in the hardware design, supported by the Linux kernel and exposed to the GNU/Linux userland.

My main development environment is a Macbook running OS X. I constantly use VMware Fusion for running various other (typically either FreeBSD or GNU/Linux) virtual machines to fulfill my needs for other development platforms. For developing the hardware and building the software for the Arty, I have installed CentOS 7 in a VM. I then use ssh to establish a local connection from OS X to the CentOS VM and forward the X display to OS X, thus allowing my to see e.g. the Xilinx Vivado windows on my OS X desktop through XQuartz.

You could of course use any PC capable of running Xilinx Vivado for the hardware part, but note that you will need a GNU/Linux host for building the Linux kernel and GNU/Linux userland. We will be focusing on Vivado 2015.4 and buildroot 2016.02 for this blog series.

If you plan on using a virtual CentOS 7 for the build environment, as I do, I recommend going with at least 50 GB HDD. The Xilinx Vivado installation itself will take up at least 20 GB and the hardware/software projects will take up another 5 GB. You will need a few packages and customizations on top of the Minimal 64 Bit installation image. Also, make sure you create an administrator user account during the installation.

Part0-CentOS-0

First off, almost all CentOS command-line tools will complain about missing locale settings. Fix this by logging in and setting the locale to e.g. U.S. English with UTF-8 encoding by issuing the following command:
sudo localectl set-locale LANG=en_US.utf-8
Remember to log out and back in for the locale settings to take effect.

Next up, install and start the Open VM Tools (skip this if not running under VMware):
sudo yum -y install open-vm-tools
sudo systemctl enable vmtoolsd
sudo systemctl start vmtoolsd

Before we install the Xilinx Vivado suite, we will need to install a few dependencies and tools:
sudo yum -y update
sudo yum -y groupinstall 'Development Tools'
sudo yum -y groupinstall 'X Window System'
sudo yum -y groupinstall Fonts
sudo yum -y install glibc.i686 libstdc++.i686 fontconfig.i686 libXext.i686 libXrender.i686 glib2.i686 libpng12.i686 libSM.i686
sudo yum -y install evince wget ncurses-devel bc screen
sudo reboot

The *.i686 packages are needed by the Xilinx Vivado Documentation Navigator, which for some reason is still shipped as a 32 bit binary. Evince is a PDF viewer, which we will be using from within the Documentation Navigator.

Download the Vivado HLx Web Install Client for Linux and install it using the following commands:
sudo mkdir /opt/Xilinx
sudo chown $USER:$USER /opt/Xilinx
chmod +x Xilinx_Vivado_SDK_2015.4_1118_2_Lin64.bin
./Xilinx_Vivado_SDK_2015.4_1118_2_Lin64.bin

If you get an error about no X11 DISPLAY variable being set, make sure you’re logged on to the CentOS host using ssh -Y .... The -Y option will enable trusted X11 display forwarding.

Make sure to enable installation of the Software Development Kit, as this will be needed later on. You propably already aquired a license for Xilinx Vivado using the voucher included with the Arty, so you can skip acquiring a licence during the installation.

Part0-Vivado-0

The Xilinx Platform Cable USB Driver/Digilent JTAG Driver are a separate install requiring root access. Install them using the following command:
cd /opt/Xilinx/Vivado/2015.4/data/xicom/cable_drivers/lin64/install_script/install_drivers
sudo ./install_drivers

We also need to make sure that our user account has access to the USB JTAG and serial port devices exposed by the Arty. These will be owned by the dialout group, so add our user to that group:
sudo usermod -G wheel,dialout $USER

To be able to launch the various Xilinx Vivado tools, we also need to set up our shell accordingly.
echo 'source /opt/Xilinx/Vivado/2015.4/settings64.sh' >> ~/.bashrc
source /opt/Xilinx/Vivado/2015.4/settings64.sh

Finally, install the license for Xilinx Vivado obtained by using the voucher included with the Arty:
mkdir -p ~/.Xilinx
mv Xilinx.lic ~/.Xilinx/Xilinx.lic

Finally, launch docnav, open the Settings Dialog and change the PDF Viewer Path to evince.

Part0-Vivado-1

This concludes the first part of this blog series. The next part will describe how to do the basic, Linux-ready hardware design.

Cheap RepRap Cable Guide

I’ve come up with a cheap and easy cable guide hack for use with RepRap 3D printers. The trick is to wrap the electrical wires in sleeving along with a piece of piano wire. I’ve used 0.8 mm piano wire, but anything between 0.5 mm and 1 mm will likely work fine.

The photo below shows a close-up of the wrapped electrical wires and piano wire powering the heated bed of my RepRap Prusa Mendel i2.

As you can see in the following photo, the piano wire keeps the cable arranged in a nice arc at all times, thus making sure it will never touch the heated bed or get in the way of its movement.

The top end of the cable harness is secured to the threaded rod using cable ties. The end near the heated bed is secured using a self adhesive cable tie mount as shown below.

RepRap Thermal Imaging

Ever since I wired up the heated build plate and extruder hot end to my RepRap, I’ve wanted to verify the thermal temperatures and heat distribution. For starters, I have used a cheap infrared thermometer, which is fine for verifying the temperatures, but not very well suited for verifying heat distribution.

Last week, I got my hands on a Fluke Ti25 Thermal Imager – perfect for getting a good look at the heat distribution!

My heat bed is a sandwich with Josef Prusa’s PCB heat bed on the bottom and a 4 mm glass plate covered in kapton on the top. My thermistor for sensing the temperature of the heat bed is taped to the bottom side of the PCB. As shown by the image below, the glass plate does a good job of evening out the heat from the PCB.

Prusa PCB Heat Bed

However, I was surprised to see how much the temperature of the kapton-covered glass surface lacks behind the temperature on the bottom side of the PCB (which, incidentally, is where my thermistor is placed). On the image above, the top is 85.8 C while the heat reflection by the bottom alu plate reads 92.8 C – nearly the same temperature sensed by my thermistor at that time. The top glass surface catches up to the bottom temperure eventually, but it takes as long as 5 minutes for it to become stable. This explains why some of my prints have had a hard time sticking to the heated build plate – it simply wasn’t warm enough, when I started the print.

J-Head MkII Nozzle

The image above is of my extruders hot end, a 0.5 mm J-head MkII (or should that be 0.4572 mm?). Again, I was quite surprised by the thermal imaging – the heater resistor goes as high as 302.3 C when heating the nozzle to 200 C! That’s quite a lot more than I would have expected – good thing I’ve used cement that can withstand 1100 C for gluing in the thermistor and resistor.

RAMPS 1.4

Finally, the image above is of my RAMPS 1.4, which has small EnzoTech MOS-C1 heatsinks mounted on all the Allegro A4988 stepper drivers. Notice how cool the heatsinks are – and notice how hot the PCB gets. Good thing those heatsinks were cheap…

My RepRap Prusa – Iteration 2

In August last year, I was swept away by the idea of the Open Source/Open Hardware Replicating Rapid Prototyper, or RepRap for short. The RepRap project is a community effort to create a 3D printer capable of self-replication.

I first encountered the idea behind the RepRap at our friends at Labitat and shortly thereafter began self-sourcing the materials needed to build a Prusa Mendel v1, which – at that time – was state of the art within the RepRap community.

During the Fall and Winter, I managed to complete my Prusa Mendel build, and shortly before Christmas I had my first working 3D print!

For more photos of some of the items, I have printed on this machine, visit my Thingiverse page…

I have since then begun updating my RepRap to the Prusa Mendel Iteration 2 design, based on linear LM8UU bearings. The conversion is 66% done (X- and Y-axis are done, Z-axis still using printed PLA-bushings).

Stay tuned for posts with the small hints and tips, I have picked up while building this amazing machine!

Downloading Sony GPS Assist Data Manually

After having bought a new Sony DSC-HX5V digital camera, which is equipped with an integrated GPS, I discovered that it comes with windows-only software for downloading and updating the GPS almanac on the camera (the supplied PMB Portable software runs on Apple OS X, but it does not support downloading the GPS almanac).

After tinkering a bit with tcpdump(1) and friends I found out how to perform the download and update manually:

  1. Download assistme.dat
  2. Download assistme.md5
  3. Verify that the MD5 sum of the assistme.dat file matches the one in the assistme.md5 file
  4. Create a top-level folder hierarchy on the memory card for the camera (not the internal memory of the camera) called PRIVATE/SONY/GPS/
  5. Place the downloaded assistme.dat file in the PRIVATE/SONY/GPS/ folder
  6. Place the memory card in the camera and verify that the GPS Assist Data is valid

I have written a small perl script for automating the above tasks. The script takes the mount point of the memory card as argument.

Monitoring Soekris Temperature through SNMP

Here’s a quick tip for monitoring the temperature of your Soekris net4801 through SNMP on FreeBSD:

Install the net-mgmt/bsnmp-ucd and sysutils/env4801 ports and add the following to /etc/snmpd.conf:

begemotSnmpdModulePath."ucd" = "/usr/local/lib/snmp_ucd.so"
%ucd
extNames.0 = "temperature"
extCommand.0 = "/usr/local/sbin/env4801 | /usr/bin/grep ^Temp | /usr/bin/cut -d ' ' -f 6"

Enable and start bsnmpd(1). The temperature of your Soekris net4801 can now be queried through UCD-SNMP-MIB::extOutput.0 OID (1.3.6.1.4.1.2021.8.1.101.0).

Plotting Load Average as Floating Point using MRTG

The web is flooded with examples of how to use the popular MRTG software for plotting more exotic SNMP OIDs than just network traffic.

One of the more popular variables to graph seems to be the load average of a given system, but all of the examples I have stumpled upon online compromise when it comes to plotting the load average as a floating point value.

It is, however, possible to post-process the gathered statistics before plotting the graph and the legend using the YTicsFactor and Factor keywords as shown in the example below:

Options[load]: gauge, nopercent, noo
Target[load]: 1.3.6.1.4.1.2021.10.1.5.2&PseudoZero:public@localhost
MaxBytes[load]: 100
Title[load]: 5 Minute Load Average
PageTop[load]: <h1>5 Minute Load Average</h1>
YLegend[load]: Load Average
ShortLegend[load]: &nbsp;
Legend1[load]: 5 Minute Load Average
Legend3[load]: Maximum Observed Load Average
LegendI[load]: &nbsp;Load Average:
YTicsFactor[load]: 0.01
Factor[load]: 0.01

The above example will gather the 5 minute load average as an integer value (average load x 100) of localhost and use a scaling factor of 0.01 before actually plotting the graph.

Judging from the examples I have found online, the noo option and the PseudoZero pseudo OID used in the example are other, often overlooked features of MRTG. The noo option specifies that no “Output” graph shall be plotted while the PseudoZero pseudo OID always returns 0 (whereas noi disables the “Input” graph and PseudoOne always returns 1).

Terminal.app vs. iTerm, Round II

A lot of water has passed beneath the bridge since I wrote my last entry about Apples Terminal.app vs. iTerm. Apple has released Snow Leopard with, among other things, a much improved version of Terminal.app, which has gotten me to ditch iTerm again.

So, I bring to you a version of the script for opening a new terminal window on the currently active desktop space – the Terminal.app way:

tell application "System Events"
	set TerminalCount to (count (every process whose name is "Terminal"))
end tell

if (TerminalCount is not 0) then
	tell application "Terminal"
		do script
		activate
	end tell
else
	tell application "Terminal"
		activate
	end tell
end if

As usual: Save the script to a .scpt file, open it with Script Editor, save as an Application and place a shortcut in your Dock.

Terminal.app vs. iTerm

Having used Apple’s own Terminal.app for all my terminal emulator needs since I switched to OS X on my primary workstation, I decided to take iTerm for a spin this weekend – it was a pleasant surprise.

Compared to Terminal.app, iTerm seems to suck up a few more system resources, but this is – imho – easily made up for with the added features. Especially tab support is much better in iTerm than in Terminal.app. Being able to set the title of tabs from the running shell (using the XTerm “icon name” escape sequence) along with the tab activity indicators rocks. Copy-on-selection and Cmd-click to launch URLs are also nice additions, that – once you get used to them – are very hard to work without.

There is, however, one missing feature of both Terminal.app and iTerm: The ability to click an icon in the Dock and have a new terminal emulator window open in the currently selected space. I’ve written a small AppleScript to do just that for iTerm:

tell application "System Events"
	set iTermCount to (count (every process whose name is "iTerm"))
end tell

if (iTermCount is not 0) then
	tell application "iTerm"
		set newterm to (make new terminal)
		tell newterm
			launch session "Default"
			activate
		end tell
	end tell
else
	tell application "iTerm"
		activate
	end tell
end if

Save the script to a .scpt file, open it with Script Editor, save as an Application and place a shortcut in your Dock.