VHDL with GHDL
This tutorial shows how to generate waveforms from VHDL using GHDL and view them in NovyWave.
Prerequisites
Section titled “Prerequisites”- GHDL installed
- NovyWave installed (Installation Guide)
Installing GHDL
Section titled “Installing GHDL”Ubuntu/Debian:
sudo apt-get install ghdlmacOS:
brew install ghdlOSS CAD Suite (recommended): Download from YosysHQ/oss-cad-suite-build — includes GHDL and many other tools.
Step 1: Create a Simple Design
Section titled “Step 1: Create a Simple Design”Create counter.vhd — an 8-bit counter with enable and overflow detection:
library ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;
entity counter is port ( clk : in std_logic; reset : in std_logic; enable : in std_logic; count : out std_logic_vector(7 downto 0); overflow : out std_logic );end entity counter;
architecture rtl of counter is signal count_reg : unsigned(7 downto 0) := (others => '0');begin process(clk, reset) begin if reset = '1' then count_reg <= (others => '0'); overflow <= '0'; elsif rising_edge(clk) then if enable = '1' then if count_reg = 255 then count_reg <= (others => '0'); overflow <= '1'; else count_reg <= count_reg + 1; overflow <= '0'; end if; end if; end if; end process;
count <= std_logic_vector(count_reg);end architecture rtl;Step 2: Create a Testbench
Section titled “Step 2: Create a Testbench”Create counter_tb.vhd:
library ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;
entity counter_tb isend entity counter_tb;
architecture sim of counter_tb is constant CLK_PERIOD : time := 10 ns;
signal clk : std_logic := '0'; signal reset : std_logic := '0'; signal enable : std_logic := '0'; signal count : std_logic_vector(7 downto 0); signal overflow : std_logic;
signal sim_done : boolean := false;begin uut: entity work.counter port map ( clk => clk, reset => reset, enable => enable, count => count, overflow => overflow );
-- Clock generation clk_process: process begin while not sim_done loop clk <= '0'; wait for CLK_PERIOD / 2; clk <= '1'; wait for CLK_PERIOD / 2; end loop; wait; end process;
-- Stimulus stimulus: process begin reset <= '1'; enable <= '0'; wait for 50 ns;
reset <= '0'; enable <= '1'; wait for 300 ns;
-- Disable counting briefly enable <= '0'; wait for 50 ns;
-- Resume counting enable <= '1'; wait for 200 ns;
-- Apply reset while counting reset <= '1'; wait for 30 ns; reset <= '0'; wait for 200 ns;
-- Continue until overflow wait for 3000 ns;
sim_done <= true; wait; end process;end architecture sim;Step 3: Build and Run
Section titled “Step 3: Build and Run”# Analyze VHDL filesghdl -a counter.vhdghdl -a counter_tb.vhd
# Elaborate the testbenchghdl -e counter_tb
# Run with GHW waveform outputghdl -r counter_tb --wave=counter.ghw --stop-time=4000nsThis creates counter.ghw with all signal transitions.
Step 4: View in NovyWave
Section titled “Step 4: View in NovyWave”- Open NovyWave
- Click Load Files
- Select
counter.ghw - Click Load
The file appears in Files & Scopes:
counter.ghw (0-4us) └── counter_tb └── uutStep 5: Explore the Waveform
Section titled “Step 5: Explore the Waveform”- Click the checkbox next to
counter_tbto select the scope - In the Variables panel, click
clk,reset,enable,count, andoverflow - Press
Rfor full view - Press
Wto zoom into the reset release at 50ns - Use
Shift+Eto jump between counter transitions - Watch the counter increment on each clock edge when enabled
GHDL Waveform Options
Section titled “GHDL Waveform Options”Output Formats
Section titled “Output Formats”# GHW format (recommended for NovyWave)ghdl -r testbench --wave=output.ghw
# VCD format (alternative, larger files)ghdl -r testbench --vcd=output.vcdSimulation Time
Section titled “Simulation Time”# Run for specific timeghdl -r testbench --wave=output.ghw --stop-time=1ms
# Run until simulation ends naturallyghdl -r testbench --wave=output.ghwNext Steps
Section titled “Next Steps”- Try modifying the counter to count by 2
- Add more signals to observe (internal registers)
- Compare multiple simulation runs using the multi-file tutorial
- Explore the complete example project in examples/vhdl/counter/
Troubleshooting
Section titled “Troubleshooting””cannot find entity”
Section titled “”cannot find entity””Ensure files are analyzed in dependency order — design first, then testbench.
Empty waveform file
Section titled “Empty waveform file”Verify the simulation actually runs (check for assertion errors) and that the testbench has signal transitions.
Large file sizes
Section titled “Large file sizes”Use GHW instead of VCD, limit simulation time with --stop-time, or use GHDL’s signal selection options.