What is VHDL design?
VHDL (VHSIC Hardware Description Language) is a language for describing digital hardware. It was developed for the US Department of Defense in the 1980s and is standardised as IEEE 1076, most recently revised in 2019. VHDL design means writing that description, verifying it in simulation, and synthesising it into real logic on an FPGA or ASIC.
The most important thing to understand is that VHDL is not a programming language in the usual sense. You are not writing instructions that run one after another; you are describing a circuit. Every concurrent statement is a piece of hardware that exists and operates at the same time as all the others. Good VHDL design starts from a picture of the hardware you want, then writes the code that describes it.
VHDL design is one part of the wider FPGA design flow, alongside architecture, synthesis, timing closure and bring-up. Our FPGA design guide covers that full flow; this guide focuses on the VHDL itself.
Anatomy of a VHDL design
Every VHDL design unit has the same basic structure:
- Library and use clauses bring in standard types, most importantly
ieee.std_logic_1164forstd_logicandieee.numeric_stdfor arithmetic. - The entity is the block's interface: its generics (parameters) and ports (inputs and outputs). It is the equivalent of a chip's pinout.
- The architecture is what the block does. It contains signal declarations and concurrent statements: processes, signal assignments and instances of other entities.
Inside an architecture, statements are concurrent: order does not matter, because they all describe hardware operating at once. Inside a process, statements are sequential and read top to bottom, but the process as a whole is still one piece of hardware running in parallel with everything else.
Signals vs variables
This is the concept that causes the most confusion for engineers coming from software.
- Signals represent wires and registers. An assignment inside a process (
<=) does not take effect immediately; the new value is scheduled and becomes visible only after the process suspends. - Variables exist only inside a process. An assignment (
:=) takes effect immediately, like a software variable.
process (clk)
variable v : unsigned(7 downto 0);
begin
if rising_edge(clk) then
a <= a + 1; -- signal: new value visible on the next clock
b <= a; -- b gets the OLD value of a, so b lags a by one cycle
v := x + 1; -- variable: updated immediately
c <= v; -- c gets x + 1 on this clock edge
end if;
end process;
a and b become two registers in a chain. The variable
v is just an intermediate value inside the logic feeding c.
A practical rule: use signals for anything that is a register or crosses between processes, and use variables sparingly for intermediate calculations inside a single process.
Writing synthesisable VHDL
Only a subset of VHDL can be turned into hardware. Synthesis tools recognise specific coding patterns and map them to flip-flops, look-up tables, block RAM and DSP slices. Code that does not follow those patterns either fails to synthesise or, worse, synthesises into something different from what you simulated.
- Use one clocked process template. A process sensitive only to the clock, with everything inside
if rising_edge(clk) then, produces registers predictably. - Use
numeric_stdfor arithmetic. Declare values asunsignedorsigned. Avoid the non-standardstd_logic_arithandstd_logic_unsignedpackages. - Assign every output on every path in combinational logic. Missing an assignment infers a latch.
- Keep simulation-only constructs out of RTL.
wait for 10 ns,afterdelays, file I/O andreportstatements are for testbenches. Synthesis ignores or rejects them. - Be deliberate about initial values. Most FPGAs honour signal initial values at configuration; ASICs do not. If the design may move to an ASIC, use an explicit reset.
State machines in VHDL
Finite state machines control almost every non-trivial design: protocol handlers, sequencers, and the control logic around datapaths. VHDL's enumerated types make them readable:
library ieee;
use ieee.std_logic_1164.all;
entity pulse_ctrl is
port (
clk : in std_logic;
rst : in std_logic;
start : in std_logic;
done : in std_logic;
busy : out std_logic
);
end entity pulse_ctrl;
architecture rtl of pulse_ctrl is
type state_t is (IDLE, RUN, FINISH);
signal state : state_t := IDLE;
begin
process (clk)
begin
if rising_edge(clk) then
if rst = '1' then
state <= IDLE;
else
case state is
when IDLE => if start = '1' then state <= RUN; end if;
when RUN => if done = '1' then state <= FINISH; end if;
when FINISH => state <= IDLE;
end case;
end if;
end if;
end process;
busy <= '1' when state = RUN else '0';
end architecture rtl;
Verifying VHDL with a self-checking testbench
A testbench is VHDL that is never synthesised. It generates a clock, drives inputs into the design under test (DUT), and checks the outputs automatically. The example below tests the parameterised counter from our FPGA design guide:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter_tb is
end entity counter_tb;
architecture sim of counter_tb is
signal clk : std_logic := '0';
signal rst : std_logic := '1';
signal en : std_logic := '0';
signal count : unsigned(7 downto 0);
begin
clk <= not clk after 5 ns; -- 100 MHz clock
dut : entity work.counter
generic map (WIDTH => 8)
port map (clk => clk, rst => rst, en => en, count => count);
stimulus : process
begin
wait until rising_edge(clk);
rst <= '0';
en <= '1';
for i in 1 to 10 loop
wait until rising_edge(clk);
end loop;
en <= '0';
wait until rising_edge(clk);
assert count = 10
report "Counter mismatch: expected 10, got " & integer'image(to_integer(count))
severity error;
report "Test finished";
std.env.stop; -- VHDL-2008
end process;
end architecture sim;
assert. It passes or fails on its own, with no waveform inspection needed.
For larger designs, hand-written checks quickly become unmanageable. OSVVM, a free, open-source VHDL verification library, adds transaction-level models, scoreboards, constrained-random stimulus and functional coverage, so VHDL teams get the same verification power that SystemVerilog teams get from UVM. Our own communications IP work relies on it.
VHDL-2008 features worth using
VHDL-2008 removed many of the language's old frustrations and is supported by current FPGA tools. Features that make everyday VHDL design easier:
process (all)builds the sensitivity list automatically, eliminating a whole class of simulation/synthesis mismatches in combinational logic.- Reading output ports is allowed, so you no longer need an internal copy of every output just to read it back.
- Conditional assignments inside processes (
x <= a when sel = '1' else b;) make sequential code more compact. ieee.fixed_pkgprovides synthesisable fixed-point types, which is valuable for DSP.std.env.stopends a simulation cleanly from the testbench.
Check your synthesis tool's settings: some default to an older VHDL standard until VHDL-2008 is enabled.
Common VHDL mistakes
- Incomplete sensitivity lists. Simulation and synthesis disagree: the simulator only re-evaluates on listed signals, while synthesis builds the logic regardless. Use
process (all)for combinational processes. - Unintended latches. A combinational process that does not assign a signal on every path infers a latch. Assign defaults at the top of the process.
- Multiple drivers. Assigning the same signal from two processes creates conflicting drivers. Each signal should be driven from one place.
- Mixing arithmetic packages. Using
std_logic_arithalongsidenumeric_stdcauses ambiguous types and subtle errors. Usenumeric_stdonly. - Doing arithmetic on
std_logic_vector. A vector has no numeric meaning on its own. Convert tounsignedorsignedso the intent is explicit. - Expecting
afterdelays in RTL to mean anything. Synthesis ignores them. Timing comes from registers and constraints, not delay statements. - Treating variables like registers. A variable read before it is written in a clocked process can infer a register unintentionally; one written before it is read cannot. Be deliberate about which you mean.
VHDL or Verilog?
Both describe the same hardware and every major FPGA toolchain supports both. VHDL's strong typing catches many mistakes at compile time that Verilog accepts silently, at the cost of more verbose code. In practice the right choice is usually the language your team, customer or existing codebase already uses. We compare them in more detail in our FPGA design guide.
Learn VHDL design, or have it done for you
Learn it: VHDL courses
LogikHaus Academy teaches VHDL hands-on, from VHDL for synthesis and simulations and testbenches to VHDL subprograms, with classes in Penang and Kuala Lumpur.
Browse VHDL coursesHire it: VHDL design services
Our VHDL experts design and verify FPGA and ASIC hardware for video processing, DSP, communications and cryptography, with OSVVM and UVM verification built in.
Discuss your VHDL projectFrequently asked questions
What is VHDL design used for?
VHDL design is used to describe digital hardware such as FPGA designs, ASICs and IP cores. The VHDL description is simulated to verify it, then synthesised into real logic. It is common in video and signal processing, communications, and aerospace, defence and industrial systems.
Is VHDL hard to learn?
The syntax is verbose but learnable in a short time. The harder part is thinking in hardware: understanding that statements run in parallel, that signals update at the end of a process, and that every line describes a circuit. Hands-on practice with simulation and a real FPGA is the fastest way to build that intuition.
Is VHDL still used?
Yes. VHDL is an actively maintained IEEE standard, most recently revised as IEEE 1076-2019, and is supported by every major FPGA toolchain. It remains widely used in FPGA design, in Europe, and in aerospace, defence and safety-related industries.
What software do I need to write and simulate VHDL?
You need a simulator and, to target hardware, an FPGA vendor toolchain. GHDL is a free open-source VHDL simulator; vendor tools such as AMD Vivado, Altera Quartus Prime, Microchip Libero SoC and Gowin EDA include their own simulators and synthesis.