Introduction to VHDL
VHDL is a hardware description language used to describe digital hardware for FPGAs and ASICs. It is common in aerospace, industrial, medical, defense, telecom, and other long-lifecycle systems where reviewability matters as much as quick coding.
The most important beginner shift is this: VHDL is not a programming language that runs line by line on the FPGA. Synthesizable VHDL describes registers, lookup-table logic, memories, muxes, and connections that the FPGA tools build as hardware.
Learning Objectives
By the end of this lesson, you should be able to:
- explain what VHDL is used for in an FPGA flow;
- identify the entity, architecture, signal, process, and concurrent-assignment parts of a design;
- distinguish synthesizable RTL from simulation-only testbench code;
- explain why VHDL's strong typing catches real hardware mistakes;
- read a small VHDL module and predict the hardware it creates.
Where VHDL Fits in the FPGA Flow
VHDL source is only one part of the design. A usable FPGA project also needs constraints, testbenches, timing review, pin planning, and board-level checks.
First Synthesizable Example
library ieee;
use ieee.std_logic_1164.all;
entity and_gate is
port (
a : in std_logic;
b : in std_logic;
y : out std_logic
);
end entity and_gate;
architecture rtl of and_gate is
begin
y <= a and b;
end architecture rtl;
The entity is the boundary of the hardware block: it lists the ports visible to the outside. The architecture is the implementation: it describes what hardware exists inside the boundary.
The assignment y <= a and b; is a concurrent assignment. It is active all the time, like a small piece of combinational logic wired between a, b, and y.
VHDL Building Blocks
| VHDL part | Hardware meaning | Review question |
|---|---|---|
entity |
block boundary and port directions | Are the names, widths, and directions correct? |
architecture |
implementation of that block | Is it RTL, behavioral simulation, or structural wiring? |
signal |
internal wire or registered value | Is it driven by exactly the intended logic? |
| concurrent assignment | continuously active combinational logic | Does every input path produce the intended output? |
| clocked process | flip-flops or registers | Is the clock, reset, and enable structure clean? |
| package | shared types, constants, and functions | Is reuse explicit and version controlled? |
Strong Typing Is a Hardware Safety Feature
VHDL makes you say what a signal means. A bus of bits is not automatically a number. For arithmetic, use unsigned or signed from ieee.numeric_std.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
signal raw_count : std_logic_vector(7 downto 0);
signal count_u : unsigned(7 downto 0);
signal next_u : unsigned(7 downto 0);
count_u <= unsigned(raw_count);
next_u <= count_u + 1;
The conversion looks verbose, but it prevents accidental arithmetic on a bus that might actually be an address, control field, or packed status word.
Synthesizable Code vs Testbench Code
| Construct | Typical purpose | Synthesizes into FPGA hardware? |
|---|---|---|
| combinational assignment | LUT logic, muxes, decoders | yes |
if rising_edge(clk) process |
flip-flops and registers | yes |
wait for 10 ns |
simulation delay | no |
assert ... report ... |
simulation and verification checks | usually no |
| file I/O in a testbench | stimulus and logging | no |
| unconstrained time delays | simulation model behavior | no |
Simulation-only code is not bad; it is essential for verification. The mistake is expecting simulation delays or testbench tasks to become physical FPGA timing.
Worked Example: Active-Low Button to LED
Many FPGA boards wire push buttons as active-low signals: unpressed reads 1, pressed reads 0. The following logic turns the LED on when the button is pressed.
library ieee;
use ieee.std_logic_1164.all;
entity button_led is
port (
button_n : in std_logic;
led : out std_logic
);
end entity button_led;
architecture rtl of button_led is
begin
led <= not button_n;
end architecture rtl;
This describes one inverter. It does not wait, poll, or execute instructions. When button_n changes, the combinational path to led changes after real propagation delay.
Timing Mental Model
title "Combinational response, idealized"
time start=0 end=20 unit=ns divisions=10
BUTTON: square label="button_n" low=0 high=1 duty=45 cycles=1 unit=logic color=#2563eb
LED: square label="led = not button_n" low=1 high=0 duty=45 cycles=1 phase=0 unit=logic color=#dc2626
marker PRESS at=9 label="press"
This waveform is explanatory, not a measured simulation. Real boards add switch bounce, synchronizers, clocking, and electrical delay.
Exercise
Write a VHDL entity and architecture named two_switch_led.
Requirements:
- inputs:
sw0,sw1; - output:
led; - behavior:
ledturns on only when both switches are on; - use
std_logicports; - write the Boolean expression in plain English.
Expected hardware: one two-input AND function implemented in FPGA LUT fabric.
Explained Solution
library ieee;
use ieee.std_logic_1164.all;
entity two_switch_led is
port (
sw0 : in std_logic;
sw1 : in std_logic;
led : out std_logic
);
end entity two_switch_led;
architecture rtl of two_switch_led is
begin
led <= sw0 and sw1;
end architecture rtl;
Plain English: the LED is on when switch 0 is on and switch 1 is on. If either input is off, the LED is off.
Common Mistakes
- Treating VHDL statements as software instructions instead of hardware descriptions.
- Using nonstandard arithmetic packages such as
std_logic_unsignedinstead ofnumeric_std. - Expecting
wait for 10 nsto create a hardware delay. - Forgetting
library ieee; use ieee.std_logic_1164.all;. - Mixing
std_logic_vector,unsigned, andsignedwithout explicit conversion. - Ignoring warnings about latches, multiple drivers, or width mismatch.
Summary
VHDL describes hardware structure and behavior for FPGA tools. Start with the entity and architecture split, use std_logic_1164 and numeric_std, and keep simulation-only constructs out of synthesizable RTL. VHDL feels strict because it makes hardware intent explicit.
Next: Entities, Architectures, Signals, and Types.
Further Reading
- GHDL: VHDL simulation quick start
- IEEE
numeric_stdpackage overview - AMD Vivado Design Suite User Guide: Synthesis
- Intel Quartus Prime Pro Edition User Guide: Design Recommendations