VHDL on Macs

Simulating VHDL on Macs can be difficult. You may want to use a open source(and by extension cross-platform) simulator like GHDL.

gtkwave waveform

My workflow consists of this, - Invoke Make - Refresh Waveform in GTKWave

All this can be done in a quarter of a second for modest designs such as a pipeline CPU - also nice is that a properly written makefile only requires GHDL to re-evaluate changed components.

Here is the source on GitHub https://github.com/BracketMaster/quick-ghdl-toolchain

Simulating With GHDL

You will probably want a makefile to automate your simulations. One is provided below.

Literally name your makefile "makefile". No extension necessary. This should be placed in the same directory that contains all the vhdl source.

#!make
TIME=500ns
GHDL = ghdl
GHDL_SIM_OPT = --stop-time=$(TIME)
GHDL_FLAGS = --ieee=synopsys -fexplicit
WORKDIR = Simulate
TOP_ENTITY = spim_pipe
echoPath = .bash_profile

.PHONY : all compile run
all : ./Simulate compile run

./Simulate :
    mkdir -p $(WORKDIR)
    $(GHDL) -i --workdir=$(WORKDIR) *.vhd

compile :
    $(GHDL) -m $(GHDL_FLAGS) --workdir=$(WORKDIR)/ $(TOP_ENTITY)

run :
    $(GHDL) -r --workdir=$(WORKDIR) $(TOP_ENTITY) --ieee-asserts=disable --stop-time=$(TIME) --wave=$(TOP_ENTITY).ghw --vcd=$(TOP_ENTITY).vcd

clean :
    rm -rf Simulate
    rm -f $(TOP_ENTITY).ghw
    rm -f $(TOP_ENTITY).vcd
    rm -f e~$(TOP_ENTITY).o

install-OSX :
    tar -xzvf ./gtkwave.app.tar
    sudo cp -rf ./gtkwave.app /Applications/
    mkdir -p ~/sources
    tar -xzvf ./GHDL.tar
    cp -rf ./GHDL ~/sources
    printf "export PATH=\"$$(echo ~)/sources/GHDL/bin/:\$${PATH}\"\n" >> ~/$(echoPath)
    source ~/.bash_profile

test :
    printf "export PATH=\"$$(echo ~)/sources/GHDL/bin/:\$${PATH}\"\n" >> ~/$(echoPath)

Software like Modelsim gives you the option to force a signal high and low as a clock and to hold the reset at the beginning of the simulation. Providing inputs to your HDL model is called a testbench. You may need to write a testbench for your code, if one hasn't been provided already.

To determine whether or not your codeset may already have a testbench, you can perform a recursive search over all your vhdl files in the terminal for the ''after'' vhdl keyword which is usually only included is tesbenches because it instructs the simulator to toggle the input after a certain amount of time.

You should see some results perhaps like this.

[macbookPro PS_SPIM_base Original]$ grep -R "after" ./ 
.//ps_clock.vhd:          sys_clock <= '0', '1' after 50 ns;
.//ps_clock.vhd:reset <= '1', '0' after 75 ns;
Binary file .//spim_pipe matches

In this case, the file ''ps_clock.vhd'' is the testbench.

If you are missing a testbench, an example testbench is provided below.

#!verilog
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
use std.textio.all;

entity my_clock is
port ( signal sys_clock, reset : out std_logic);
end entity my_clock;

architecture behavior of my_clock is 
begin
    process
        begin
        -- generate clock
          sys_clock <= '0', '1' after 50 ns;
          wait for 100 ns;
         end process; 
         -- following statement executes only once
reset <= '1', '0' after 75 ns;
end architecture behavior;

Finally change into the directory of your makefile and in the terminal and type ''make''. You might see something like this once GDHL compiles for the first time

terminal

Making Changes

Once you edit your code, you will need to update the simulation. That is as simple as running ''make''.

The time required for subsequent simulations depend on how many files you change between each simulation - each file take half a second to recompile.

IMPORTANT NOTE

If you add a new .vhd file to your vhdl simulation, you will need to run ''make clean'' and then ''make'' again to update your simulation.

Viewing Waveforms

Updating Waveforms

Change Default Simulation Time