A VHDL program can be simulated or synthesized. Simulation is what resembles most the execution in other programming languages. Synthesis translates a VHDL program into a network of logic gates. Many VHDL simulation and synthesis tools are parts of commercial Electronic Design Automation (EDA) suites. They frequently also handle other Hardware Description Languages (HDL), like Verilog, SystemVerilog or SystemC. Some free and open source applications exist.
GHDL is probably the most mature free and open source VHDL simulator. It comes in three different flavours depending on the backend used: gcc
, llvm
or mcode
. The following examples show how to use GHDL (mcode
version) and Modelsim, the commercial HDL simulator by Mentor Graphics, under a GNU/Linux operating system. Things would be very similar with other tools and other operating systems.
Create a file hello_world.vhd
containing:
-- File hello_world.vhd
entity hello_world is
end entity hello_world;
architecture arc of hello_world is
begin
assert false report "Hello world!" severity note;
end architecture arc;
A VHDL compilation unit is a complete VHDL program that can be compiled alone. Entities are VHDL compilation units that are used to describe the external interface of a digital circuit, that is, its input and output ports. In our example, the entity
is named hello_world
and is empty. The circuit we are modeling is a black box, it has no inputs and no outputs. Architectures are another type of compilation unit. They are always associated to an entity
and they are used to describe the behaviour of the digital circuit. One entity may have one or more architectures to describe the behavior of the entity. In our example the entity is associated to only one architecture named arc
that contains only one VHDL statement:
assert false report "Hello world!" severity note;
The statement will be executed at the beginning of the simulation and print the Hello world!
message on the standard output. The simulation will then end because there is nothing more to be done. The VHDL source file we wrote contains two compilation units. We could have separated them in two different files but we could not have split any of them in different files: a compilation unit must be entirely contained in one source file. Note that this architecture cannot be synthesized because it does not describe a function which can be directly translated to logic gates.
Analyse and run the program with GHDL:
$ mkdir gh_work
$ ghdl -a --workdir=gh_work hello_world.vhd
$ ghdl -r --workdir=gh_work hello_world
hello_world.vhd:6:8:@0ms:(assertion note): Hello world!
The gh_work
directory is where GHDL stores the files it generates. This is what the --workdir=gh_work
option says. The analysis phase checks the syntax correctness and produces a text file describing the compilation units found in the source file. The run phase actually compiles, links and executes the program. Note that, in the mcode
version of GHDL, no binary files are generated. The program is recompiled each time we simulate it. The gcc
or llvm
versions behave differently. Note also that ghdl -r
does not take the name of a VHDL source file, like ghdl -a
does, but the name of a compilation unit. In our case we pass it the name of the entity
. As it has only one architecture
associated, there is no need to specify which one to simulate.
With Modelsim:
$ vlib ms_work
$ vmap work ms_work
$ vcom hello_world.vhd
$ vsim -c hello_world -do 'run -all; quit'
...
# ** Note: Hello world!
# Time: 0 ns Iteration: 0 Instance: /hello_world
...
vlib
, vmap
, vcom
and vsim
are four commands that Modelsim provides. vlib
creates a directory (ms_work
) where the generated files will be stored. vmap
associates a directory created by vlib
with a logical name (work
). vcom
compiles a VHDL source file and, by default, stores the result in the directory associated to the work
logical name. Finally, vsim
simulates the program and produces the same kind of output as GHDL. Note again that what vsim
asks for is not a source file but the name of an already compiled compilation unit. The -c
option tells the simulator to run in command line mode instead of the default Graphical User Interface (GUI) mode. The -do
option is used to pass a TCL script to execute after loading the design. TCL is a scripting language very frequently used in EDA tools. The value of the -do
option can be the name of a file or, like in our example, a string of TCL commands. run -all; quit
instruct the simulator to run the simulation until it naturally ends - or forever if it lasts forever - and then to quit.