A screenshot of the VHDL template in action

VHDL project template for open-source projects

written on November 18, 2020

VHDL development is often associated with old and bloated (mostly proprietary) software, installations that take forever and take up a huge amount of space… what if there were a simple open-source alternative?

I do work on some VHDL projects (like this one, or this one) from time to time, so I wanted a simple, Makefile-based project template I could build upon, which would be supported at least on Linux and macOS, and which would be easy to install and setup and yet powerful and scalable. So I rolled my own VHDL open-source project template. In this blogpost I’d like to explore how it works and give a concrete example of building something with it.

It depends on GHDL and GTKWave (installation instructions for Linux and macOS are provided in the repo’s README). GTKWave actually isn’t strictly required, as all building/testing can be achieved with GHDL alone, but it’s fun to have and it sometimes helps to visually debug an IP using a digital timing diagram.

Anyway, let’s say we want to build a simple 3-input AND gate IP. We first have to clone the template repo:

$ shell


As you can see, the project template is laid out as follows:

$ shell









There are three main folders: src, which contains the VHDL sources (like MyIP.vhdl), tb which contains the test benches associated with the sources (like MyIP_tb.vhdl) and finally simu, which contains the simulation files generated based on the test benches. These files can then be opened by GTKWave, but we’ll get to that.

Let’s start by building a simple 2-input AND gate:

src/SimpleAndGate.vhdl


















Very simple, just has two inputs and one output (all std_logic), and the output is equal to the ANDing of the two inputs. Let’s try to compile this IP by running make:

$ shell





No errors! Our simple IP is working. The first command checks the syntax of the .vhdl file, and the second one analyzes it. It should now be ready to be used by other IPs. Speaking of which, let’s code a 3-input AND gate IP based on the one we just implemented:

src/AwesomeTripleAndGate.vhdl





















Let’s also write a simple test bench we can use to verify that it’s working. Note that the test bench file must have exactly the same name as the source IP file, plus "_tb". So in this case, it will be tb/AwesomeTripleAndGate_tb.vhdl:

src/AwesomeTripleAndGate_tb.vhdl











































Once again, very simple: we set up an entity to test, and then we start a “test” process, where we set the inputs of the triple AND gate to various values and assert the output, triggering an error if it’s incorrect.

Let’s make and see if this whole thing works:

$ shell







Whoops, that doesn’t seem right. What happened? Well, I named the IPs on purpose, so that the second one would get picked up by the Makefile before the first one. That way, it tries to compile the second IP without first compiling its dependency. The simplest way to fix this is to declare the dependency in the Makefile, by replacing this:

Makefile



With this:

Makefile



So now that the dependencies issue is fixed, let’s re-run make:

$ shell












Now the SimpleAndGate gets built first, and then when it’s AwesomeTripleAndGate’s turn to be built, it can find the reference to SimpleAndGate and build successfully.

Just to properly test out all of the features of this Makefile, we can open the resulting simulation in GTKWave, by running:

$ shell


A screenshot of GTKWave, showing a simulation of the test bench

Visualizing the simulation of the test bench in GTKWave.

And that’s it! You can now build, debug and run automated tests using this lightweight VHDL project template.