Skip to content

VHDL · Chapter 10.4 · Packages and Reuse

Libraries, work, and Compilation Order

VHDL does not just compile files, it analyses design units into libraries, and the order matters. Your own units land in the work library by default, the ieee library holds the standard packages every file imports, and tool vendors provide their own. The iron rule is dependency order: a unit must be analysed before anything that references it, so a package comes before the modules that use it, an entity comes before the architecture that instantiates it, and a package declaration comes before any code that needs it. Get the order wrong and you hit the classic used-before-analysed error. This lesson explains what libraries are, why compilation order is really a dependency graph you walk from leaves to roots, and how to organise a project so it builds cleanly every time.

Foundation13 min readVHDLLibrariesworkCompilation OrderAnalysisProject

1. Engineering intuition — you cannot use what is not yet known

Compiling VHDL is like reading a book where every reference must point to something already written. When the analyser reaches a module that says use work.bus_pkg.all, that package must already be in the library — if it has not been analysed yet, the reference dangles and analysis fails. So the order in which you analyse units is not arbitrary: each unit must come after everything it depends on. Think of it as a dependency graph that you must walk from the leaves (no dependencies) up to the roots (the top level) — packages first, then the modules that use them, then the things that instantiate those.

2. Formal explanation — libraries and the order rules

libraries_and_order.txt
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- LIBRARIES:
--   work    : your current design's units land here by default (no 'library work;' needed to compile into it).
--   ieee    : standard packages — std_logic_1164, numeric_std (you 'library ieee; use ieee....').
--   vendor  : tool/FPGA primitive libraries (e.g. unisim), referenced as needed.
--
-- COMPILATION (ANALYSIS) ORDER — each unit AFTER what it depends on:
--   1. packages (declarations) before any unit that uses them
--   2. a package body after its package declaration (and before users needing its subprograms)
--   3. an entity before the architecture(s) of it
--   4. an entity before any unit that instantiates it
--   5. lower-level modules before the top level that instantiates them

Units are analysed into a library (yours into work, standards from ieee). The order is governed by dependencies: analyse a unit only after everything it references. Packages come first (everyone uses them), then leaf modules, then higher-level modules, then the top — a topological order of the design's dependency graph. (Build tools and make/project files automate this, but the rule is what they are enforcing.)

3. Production usage — a correctly-ordered build

build_order.txt
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- A clean analysis order for a small design:
--   1. cfg_pkg        (package: constants/types)        ← leaf, no dependencies
--   2. cfg_pkg body   (if it has subprograms)
--   3. adder.vhd      (entity + arch, uses cfg_pkg)
--   4. fifo.vhd       (entity + arch, uses cfg_pkg)
--   5. datapath.vhd   (instantiates adder, fifo)
--   6. top.vhd        (instantiates datapath)
-- Each line depends only on lines ABOVE it, so analysis never references an un-analysed unit.

What hardware does this become? Compilation order is a build concern, not hardware — it does not change the synthesised result, only whether analysis succeeds. But it is essential: the same source set fails or succeeds depending on order. Organising files so dependencies are analysed first (packages, then leaves, then roots) is what makes a project build reliably.

4. Structural interpretation — the dependency graph

compilation dependency order from packages through leaf modules to the topbeforebeforebefore1. packagesleaf — analysed first2. leaf modulesuse packages3. mid modulesinstantiate leaves4. top levelanalysed last12
Compilation order is a dependency graph (a DAG) that must be analysed leaves-first. Packages have no design dependencies, so they are analysed first; modules that use a package are analysed after it; higher-level modules that instantiate other modules come after those; the top level is last. Each unit must be analysed only after everything it references, or analysis fails with a used-before-analysed error. Libraries (work for your units, ieee for standards) are where the analysed units are stored. This is a build/source structure, captured by a dependency diagram rather than a waveform.

5. Why this is structural, not timing

Compilation order has no run-time behaviour — it is purely about analysing source units into libraries in dependency order, so a dependency diagram (above), not a waveform, is the right picture. The only observable effect is binary: with the correct order, analysis succeeds and you proceed to elaboration and simulation; with the wrong order, analysis stops at the first unresolved reference. Get the order right once (or let a build tool derive it from dependencies) and it disappears as a concern.

6. Debugging example — used before analysed

Expected: the design compiles. Observed: analysis fails with an error that a package, entity, or declaration is unknown / not found / used before analysed, even though the source for it exists. Root cause: the referenced unit was not analysed before the unit that uses it — the package was compiled after a module that imports it, an entity after its instantiation, or a package body in the wrong place. Fix: analyse units in dependency order — packages first, then leaf modules, then higher levels, then the top — or use a project/make file that derives the order from dependencies. Engineering takeaway: a not-found error for a unit whose source exists is almost always a compilation-order problem; analyse dependencies first.

order_fix.txt
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- BUG: analysing 'adder.vhd' (which uses cfg_pkg) BEFORE cfg_pkg → cfg_pkg unknown.
-- FIX: analyse cfg_pkg first, then adder.vhd.
--   analyze cfg_pkg.vhd      # package first
--   analyze adder.vhd        # then its user

7. Common mistakes & what to watch for

  • Analysing a user before its package/entity. The classic used-before-analysed error; analyse dependencies first.
  • Wrong library reference. use work.pkg.all for your own packages; library ieee; use ieee.... for standards — a wrong library means not found.
  • Forgetting library ieee; before use ieee..... You must name the library before using its packages (except std/work, which are implicit).
  • Package body missing or misordered. A package with subprograms needs its body analysed too, after the package declaration.
  • Hand-maintaining order for large projects. Use a build tool/project file to derive order from dependencies; manual ordering does not scale.

8. Engineering insight & continuity

Libraries and compilation order are the build discipline behind reuse: units are analysed into libraries (work, ieee, vendor) in dependency order, packages first and the top level last, so every reference resolves to something already analysed. It changes no hardware, but it is the difference between a project that builds and one that fails at the first unresolved name — and it is why packages, which everyone depends on, are always compiled early. With sharing (constants, types) and the build order understood, the next lesson looks at the packages you already rely on every day — The Standard IEEE Packages (std_logic_1164, numeric_std, and their place in the library) — before the module closes with an overall Reuse Strategy.