VHDL · Chapter 1.4 · Foundation
VHDL Design Units
A design unit is the smallest piece of VHDL the compiler analyses on its own. There are five of them, the entity, architecture, package, package body, and configuration, and understanding them is what turns writing a single file into structuring a real design. This lesson separates the source file, a text file on disk, from the design units inside it, which are the compile-time building blocks the language actually cares about. It shows how those units land in a library called work, explains the primary and secondary unit relationship that decides compile order, and makes clear why this structure drives organisation and reuse across a project.
Foundation13 min readVHDLDesign Unitswork libraryPackagesCompilation
1. Intuition — files vs building blocks
You write VHDL into a file (counter.vhd). But the VHDL language does not care
about files — it cares about design units. A file is just a container; the
compiler reaches inside and analyses each design unit it finds.
A useful analogy: a .vhd file is a shipping box, and the design units are the
labelled parts inside it. You can put one part per box or several parts in one
box — the factory (the compiler) unpacks them and files each part on a shelf in a
library. From then on, the rest of the design refers to parts on shelves, not
to boxes.
2. The five design units
| Design unit | What it is | Primary / secondary |
|---|---|---|
| entity | The external interface of a block (its ports and generics). | Primary |
| architecture | An implementation of an entity — the logic inside. | Secondary (belongs to an entity) |
| package | A shared header: types, constants, and subprogram declarations. | Primary |
| package body | The implementations for a package's subprograms. | Secondary (belongs to a package) |
| configuration | A unit that binds an entity to a specific architecture. | Primary |
Primary units stand alone. Secondary units depend on a primary one: an architecture cannot exist without its entity, and a package body cannot exist without its package. That dependency is the whole reason compile order matters (§4).
3. What each looks like
Compact skeletons — just enough to recognise each unit by shape. (Packages get their own full lesson later; here we only need their silhouette.)
library ieee;
use ieee.std_logic_1164.all;
-- PRIMARY: entity — the interface
entity reg8 is
port (
clk : in std_logic;
d : in std_logic_vector(7 downto 0);
q : out std_logic_vector(7 downto 0)
);
end entity reg8;
-- SECONDARY: architecture — an implementation OF reg8
architecture rtl of reg8 is
begin
process (clk)
begin
if rising_edge(clk) then
q <= d;
end if;
end process;
end architecture rtl;-- PRIMARY: package — shared declarations (the "header")
package types_pkg is
constant WORD_W : integer := 8;
function parity (v : std_logic_vector) return std_logic;
end package types_pkg;
-- SECONDARY: package body — the implementations (the "source")
package body types_pkg is
function parity (v : std_logic_vector) return std_logic is
variable r : std_logic := '0';
begin
for i in v'range loop
r := r xor v(i);
end loop;
return r;
end function;
end package body types_pkg;A configuration (the fifth unit) names which architecture an entity should use when more than one exists. It is rare in everyday RTL, so we only name it here and return to it when it earns its place.
4. How units relate — file, library, and binding
Here is the relationship that actually matters in practice: a source file
contains design units; the compiler analyses each unit into a library (the
default one is called work); an architecture binds to its entity; and any unit
can pull in a package with a use clause.
That work library is why you write use work.types_pkg.all; to reach your own
package, and use ieee.std_logic_1164.all; to reach the standard one: ieee and
work are just two libraries, one provided, one yours.
5. Why no waveform here — a compile-time flow instead
Design units are a compile-time, structural concept. They have no signal values and no timing — there is literally nothing for a waveform to plot, because a waveform shows how signals change over simulated time, and design units exist before simulation even begins. Forcing a waveform onto this topic would teach nothing.
The artifact that does illuminate design units is the build flow — the order in which the tool processes them:
6. Why design units matter
- Organisation — splitting a chip into entities (one job each) keeps every unit small and testable.
- Reuse — a package compiled once into a library is shared by every design that imports it; a verified entity is dropped into many designs.
- Separate compilation — change one architecture and only its unit (and its dependents) need re-analysing, not the whole project.
- Clear contracts — the entity/package declaration is the public face; the architecture/package body is the private implementation behind it.
7. Common mistakes & what to watch for
- Confusing files with units. "It's in the file" is not the same as "it's compiled into the library." Tools track units, not filenames.
- Compile order. A secondary unit cannot be analysed before its primary: compile
the entity before its architecture, the package before its body, and a
package before anything that
uses it. Out-of-order analysis is a classic first-day error. - Forgetting the package body. A package that declares a function but has no body will compile yet fail to elaborate — the implementation is missing.
- Trying to put an entity + architecture inside a package. A package holds declarations (constants, types, subprograms, component declarations) — not whole design entities.
8. Summary & next step
A design unit is the smallest thing VHDL compiles on its own. There are five —
entity, architecture, package, package body, configuration — split into primary
units and the secondary units that depend on them. Source files merely contain
units; the compiler files them into a library (work), and compile order follows
the primary-before-secondary rule. Because all of this is compile-time and
structural, the right artifact is a build flow, not a waveform.
The most important pair of units is the entity and its architecture. The next lesson opens them fully: interface versus implementation, ports and their directions, and how one entity can have more than one architecture.