VHDL using GHDL
Overview
This tutorial covers how to get started with the gHDL simulator, using a simple counter example.
Software
This tutorial uses the following software and versions, but should work with out any problems on both older an newer versions:
Gedit 2.28, Text editor,
gHDL 0.28, VHDL compiler and simulator
GTKWave 3.2.0, Waveform viewer
make, to run helper script (optional)
To install the software needed for this tutorial click the box below or see the Getting Started page.
|
Install the software for this Tutorial ghdl, gtkwave,make |
Setup
For this tutorial we will use Gedit, the default text editor in Gnome, to edit the VHDL code. Ubuntu has a number of different text editors available as shown on the HDL Editors page.
To make Gedit easier to use we will use a number of plugins. Plugins are small extensions to Gedit to allow Gedit to do some extra tricks. Alternatively use external programs instead of the plugins if desired.
Start Gedit (Accessories -> Text Editor) and select Edit -> Preferences and click the Plugins Tab. Click the box next to Code Comment, File Browser Pane and Embedded Terminal and Code Comment to active these plugins.
In the Left side panel of Gedit click the File Browser tab, this usually has a filing cabinet icon. Use the file browser (or if you wish use another file browser) to create a directory for this project and create three sub-directories: src, testbench and simulation.
To make using GHDL easier to use copy the following Makefile into Gedit and save it to the project directory and as a file named Makefile.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | # vhdl files
FILES = src/*
VHDLEX = .vhd
# testbench
TESTBENCHPATH = testbench/${TESTBENCH}$(VHDLEX)
#GHDL CONFIG
GHDL_CMD = ghdl
GHDL_FLAGS = --ieee=synopsys --warn-no-vital-generic
SIMDIR = simulation
# Simulation break condition
#GHDL_SIM_OPT = --assert-level=error
GHDL_SIM_OPT = --stop-time=500ns
WAVEFORM_VIEWER = gtkwave
all: compile run view
new :
echo "Setting up project ${PROJECT}"
mkdir src testbench simulation
compile :
ifeq ($(strip $(TESTBENCH)),)
@echo "TESTBENCH not set. Use TESTBENCH=value to set it."
@exit 2
endif
mkdir -p simulation
$(GHDL_CMD) -i $(GHDL_FLAGS) --workdir=simulation --work=work $(TESTBENCHPATH) $(FILES)
$(GHDL_CMD) -m $(GHDL_FLAGS) --workdir=simulation --work=work $(TESTBENCH)
@mv $(TESTBENCH) simulation/$(TESTBENCH)
run :
@$(SIMDIR)/$(TESTBENCH) $(GHDL_SIM_OPT) --vcdgz=$(SIMDIR)/$(TESTBENCH).vcdgz
view :
gunzip --stdout $(SIMDIR)/$(TESTBENCH).vcdgz | $(WAVEFORM_VIEWER) --vcd
clean :
$(GHDL_CMD) --clean --workdir=simulation |
Writing Code
Create a new file and save it in the the src directory as counter.vhd in and copy the following VHDL code into the file and save the file. This file describes a simple 8-bit counter with a up / down selection, input, output and reset.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity up_down_counter is port ( cout :out std_logic_vector (7 downto 0); up_down :in std_logic; -- up_down control for counter clk :in std_logic; -- Input clock reset :in std_logic -- Input reset ); end entity; architecture rtl of up_down_counter is signal count :std_logic_vector (7 downto 0); begin process (clk, reset) begin if (reset = '1') then count <= (others=>'0'); elsif (rising_edge(clk)) then if (up_down = '1') then count <= count + 1; else count <= count - 1; end if; end if; end process; cout <= count; end architecture; |
Create another new file and save it in the testbench directory as counter_tb.vhd and copy the code below into the file and save the file. This file is a simple test bench to test the counter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity counter_tb is end entity; architecture TB of counter_tb is component up_down_counter port( cout: out std_logic_vector(7 downto 0); up_down: in std_logic; reset: in std_logic; clk: in std_logic ); end component; signal cout: std_logic_vector(7 downto 0); signal up_down: std_logic; signal reset: std_logic; signal clk: std_logic; begin dut: up_down_counter port map (cout, up_down, reset, clk); process begin clk <= '0'; wait for 5 ns; clk <= '1'; wait for 5 ns; end process; process begin up_down <= '1'; reset <= '1'; wait for 10 ns; reset <= '0'; wait for 100 ns; up_down <= '0'; wait for 100 ns; end process; end; |
Simulation and Viewing the result
Now we have created a simple counter and testbench it is time to simulate the design.
Select the terminal tab at the bottom of the Gedit window. To simulate the design first change to the top level project directory using the cd command, as shown below.
cd /path/to/project/dir
To simulate a design with gHDL three steps are needed, these are included in the Makefile given above, shown below, as we are using the make file don’t run GHDL directly use the make commands shown below.
ghdl -i FILES ghdl -m TESTBENCH_NAME ghdl -r TESTBENCH_NAME
First GHDL is ran with the -i option and a list of all files in the design. This analysis all units in the design in the correct order, and will check for and errors in the VHDL code. Next GHDL is ran with the -m option and the name of the top unit which will usually be a testbench. This analysis and elaborates the design and creates an executable to run the simulation. The simulation is ran executing ghdl with the -r option.
The above flow is included in the Makefile to make it easier to simulate designs and view the result, as shown below. The first line runs the Ghdl twice once with -i and then with -m, the second line runs Ghdl -r and the final line shows results in the waveform viewer GTKWave.
make compile TESTBENCH=counter_tb make run TESTBENCH=counter_tb make view TESTBENCH=counter_tb
All three steps above can be ran with the command
make all TESTBENCH=counter_tb
The Makefile is designed to make your life easier. But to do this it makes some assumptions, which are
These assumptions are met in the above example, so if you have done everything right you should have no trouble. |
After running the above commands GTKWave should open. To view signals from the design select the design from the top left side pane and select a signal from the bottom left side pane and click Insert at the bottom left of the GTKWave window.
Further Information
For more information on using GHDL and GTKWave see the project websites.

about 2 years ago
Great tutorial. Here are a few corrections:
1- VHDL source code in both windows is malformed ( appear as their html codes)
2- The command “make view” also requires TESTBENCH=counter_tb as argument
3- Package gedit-plugins is required for the “Code Comment” plugin.
about 2 years ago
Hi, Thanks for your comments. Points 2 and 3 are fixed. I don’t see the problem described in 1. It maybe a browser related. I’ll try to look into it.
about 2 years ago
Seems the characters appear improperly, as in:
count <= (others=>’0′);
which should be:
count ’0′);
I am using Firefox 3.6.2pre
about 2 years ago
Please ignore comment #3. The problem seems to be with the “less than” and “greater than” characters.
about 2 years ago
The errors should be fixed. I think WordPress did some automatic conversion moving between the HTML and Visual editor.
about 1 year ago
Hi I didn’t notice the scroll bar in GTKWave.
For beginners (like me) it might help if you just add a quick sentence on the end like
go Time->Zoom->Zoom Best Fit.
Then you can instantly see the result in perspective.
Thanks for the tutorial though. I aim to try prototyping my own VHDL code with these tools before I try putting them into Xilinx (very slow process) and programing an FPGA.
Also I have tried other counter tutorials that were ghdl/freehdl especially with regards to library pitfalls but none of them compiled properly.
Since your code actually does compile and it works. I wonder if you have any tips on which libraries to include and which not to include if you actually want to be able to compile your code?
Thanks.
From Russell.
about 1 year ago
Hello,
great tutorial ! thanks a lot
just a question, is this solution the overall best solution for VHDL development using open-source software? also, is there an equivalent (that use gedit and terminal) for Verilog?
I would be quite happy to contribiute in making this tools better. Any idea on which direction to go? I am thinking of a gedit plugin similar to the one for Latex…
cheers
vincent
about 1 year ago
Great makefile. Thanks.
about 1 year ago
So how can I generate a .bit file for encoding on my FPGA board? I bought a Digilence BASYS 2 board and downloaded the Adept software with instruction on how to encode a .bit file… But how do I get a .bit file?
about 1 year ago
No, you need the tools from the FPGA manufacture to generate the .bit file.