How can an open-source HDL project automatically be tested?

Benedek Rácz
5 min readJun 9, 2019

The following study is based on my travis-hdl repository.

Introduction

Fortunately, there are more and more open-source FPGA projects. There are some open testing frameworks, testing libraries. There are open simulators for hardware descriptor languages. There are several hosted continuous integration service. But none of them supports HDL codes natively. The following paragraphs will show how to use them for integrating and test your FPGA designs.

Pre-requirements

However general my methodology is, I will show a concrete, working implementation basing on some particular tools. To understand the later paragraphs, I recommend to be familiar with the following tools:

  1. VHDL language
  2. UVVM open-source VHDL testbench infrastructure (optional)
  3. GHDL open-source simulator for the VHDL language
  4. Docker virtualization software
  5. Travis-CI continuous integration service
  6. Github to store your open source project.

Working principles

As I mentioned in the introduction, there isn’t any continuous integration service with native HDL support. Our goal is to “install” an HDL simulator to one of these servers. I chose Travis-CI and ghdl simulator.

Despite the lack of the official release of ghdl-docker, I suggest using this (in contrast with native binary variant), because of the advantages of the Docker. What’s more, it will be simpler when we want using on Travis-CI.

Using Docker requires no installation on Travis-CI, just a run of the ghdl Docker image is necessary, which is supported on Travis-CI.

ghdl compiler script

All testcases need to be written, and both the DUT and the testbench/testcases all construct must be supported by the ghdl simulator. So pure VHDL simulation is required. Note that fortunately, ghdl supports a wide range of VHDL-2008 constructs.

Now the compiler script can be created, which calls ghdl. The detailed usage of the ghdl can be found in its documentation. The following example will compile and run the ghdl’s hello world VHDL file.

# The directori of HDL source files
srcdir=/mnt/data/hello_world
# Test GHDL itself
ghdl --version
# List the files (validating the fileshare/mount, it will be handy later)
ls $srcdir
# Analyse the source
ghdl -a $srcdir/hello_world.vhd
# Elaborate the top-level
ghdl -e hello_world
# Run the simulation
ghdl -r hello_world

Calling from ghdl-docker

The installation of the Docker and the ghdl container can be tested using the following command, which should print out the version of the ghdl simulator.

docker run -t ghdl/ghdl:stretch-mcode ghdl — version

Now, the compiler script above can be run. Note that hdl sources and script files have to be shared/mounted with the Docker using the -v/mount switch. The compiler call will be the following command¹.

docker run -t -v `pwd`:/mnt/data ghdl/ghdl:stretch-mcode  /bin/bash -c  "chmod u+x /mnt/data/hello_world/hello_world.sh; /mnt/data/hello_world/hello_world.sh"

Using Travis for continuous integration

At this point, everything can be integrated with Travis-ci, which requires a GitHub (or any other supported provider) repository of the project.

Setting up Travis-ci builds up to two steps (after sign up).

  1. Activate and select the repositories you want to use with Travis CI.
  2. Add a .travis.yml configuration file to your repository to tell Travis CI what to do.

My travis-hdl sample repository uses the following directory structure.

├── .travis.yml           <- Setting up travis-ci
├── adder <- source folder
│ ├── adder.sh <- compile script
│ ├── adder.vhd <- vhdl sources
│ └── adder_tb.vhd
└── hello_world <- source folder
├── hello_word.vhd
└── hello_world.sh

The following bare-minimal .travis.yml file uses the docker-caller commands, which were demonstrated above.

# Specify, that we want to use docker in the docker :)
services:
- docker
# Here are the list of run scripts of different DUTs/testcases
script:
# Testing the installation of the ghdl
- docker run -t ghdl/ghdl:stretch-mcode ghdl --version

# Mount the repo to docker, and run the hello world example
- >
docker run -t -v `pwd`:/mnt/data ghdl/ghdl:stretch-mcode
/bin/bash -c "chmod u+x /mnt/data/hello_world/hello_world.sh;
/mnt/data/hello_world/hello_world.sh"

# Mount the repo to docker, and run the adder example
- >
docker run -t -v `pwd`:/mnt/data ghdl/ghdl:stretch-mcode
/bin/bash -c "chmod u+x /mnt/data/adder/adder.sh;
/mnt/data/adder/adder.sh"

Using UVVM (extra)

I recommend to use some simulation framework, BFM, VIP, or any other higher-level abstraction while writing an HDL simulation. I used UVVM, which is a maintained, open-source, pure VHDL-2008 verification framework.

I used git submodule capability to add UVVM to my example project:

$ git submodule add https://github/UVVM/UVVM

The ghdl supports UVVM, but --std=08 and -frelaxed-rules switches must be added:

ghdl -a --work=<library> --std=08 -frelaxed-rules <source_file>

The same switches are needed to start elaboration and running. For more details see scripts directory.

Summary

This study has shown an example of a continuous-integration of a VHDL project. Next, I plan to show a similar example using Verilog language. And I will try to add code coverage stats to the current implementation.

The continuous-integration improves the quality of all projects. The FPGA/ASIC project requires a high-quality code because of the complicated debugging. This study shows that a VHDL project can be integrated continuously, online, simply. So, I encourage anybody to use some similar methodology for his/her HDL project.

[1] Using Dockerfiles is a more elegant way, but this inline call is enough for this simple example.

--

--

Benedek Rácz
Benedek Rácz

Written by Benedek Rácz

Open heart, open source. I’m FPGA developer.

No responses yet