A technical knowledge portal by eVision Systems GmbH

EDA Praxis / Practical knowledge

Libraries and structure for reproducible HDL projects

How source lists, logical libraries and separate build directories make HDL project setup traceable.

An HDL project consists of more than its source files. Language settings, library mappings, dependencies, generated sources and tool versions also determine which design is actually analysed. When a project runs only on its original developer’s computer, this knowledge is often hidden in local settings. Reproducibility means that another workstation can perform an explainable build from the same approved revision.

Distinguish a logical library from a directory

A VHDL library is a logical namespace for analysed design units. The physical directory where a simulator stores its data is an implementation choice made by the tool. A folder named common does not therefore automatically become a library named common. Likewise, the existence of a file does not mean that its entity or package is available in the correct library. This distinction helps identify many apparent language problems as configuration issues.

The special name work denotes the current working library of the particular analysis context. It is not a good substitute for a deliberately named shared IP namespace. When sources are analysed into different libraries, references must match that arrangement. For a missing design-unit diagnostic, examine the name, target library, analysis order and architecture actually selected together.

A simple structure with clear boundaries

project/
  rtl/              # eigene synthetisierbare Quellen
  tb/               # Testbenches und Referenzmodelle
  scripts/          # Build- und Testeinstiege
  config/           # Quelllisten und Spracheinstellungen
  docs/             # Anforderungen und Bedienhinweise
  vendor/           # freigegebene Fremdquellen oder Verweise
  build/            # erzeugte Bibliotheken, Logs, Ergebnisse

These names are a suggestion, not a mandatory standard. The separation of inputs from generated results matters more. A fresh build should recreate only directories whose contents can be generated again. Sources and manually maintained constraints therefore do not belong among simulator artefacts. Even a quickly created diagnostic file should be moved to a safe, clearly named location before the next cleanup step.

Version the small text files that explain the build. Large downloaded libraries and protected IP should not be copied into a repository without checking. Instead, document the source, approved version, checksum where available and required usage rights. A download link without version information is insufficient for traceable long-term recovery.

Keep dependencies explicit

A package declaration must be analysed before its users. In larger projects, an alphabetical file list is not enough. Either the project maintains the correct sequence or a suitable tool derives it from a complete project model. Both approaches need an authoritative source of configuration. If the IDE and simulation script process different sets of files, contradictory diagnostics are inevitable.

VUnit documents Python-driven project setup and source-to-library assignment. Sigasi documents external compiler tasks based on the selected project target. These mechanisms can help keep the relationship between the development environment and simulation visible. Their concrete configuration belongs to the project and must be checked against the versions actually used. VUnit user guide; Sigasi: Integrating with external tools.

Source file, library and build are different thingsProject configuration connects versioned inputs to logical namespaces and generated working data.
Example of explicit source mapping; names are illustrative
Versioned sourceLogical target libraryRole in this example
rtl/types_pkg.vhdcommonDeclare shared types.
rtl/counter.vhddesign_libAnalyse the module; required packages must be available.
tb/tb_counter.vhdtest_libAnalyse the testbench; references must match the libraries.

On narrow screens, the table can be scrolled horizontally.

Order follows dependenciesPackage declaration → users. An alphabetical file list does not guarantee this.
The build directory is physicalThe simulator stores generated working data. A directory name alone does not map a source to a logical library.

work denotes the current working library of the analysis context. A source list must explicitly describe target libraries and dependencies.

Generated sources and FPGA libraries

Generated files need an explicit decision: can they be recreated reproducibly from versioned inputs, or must they be archived as an approved result? A generator may need to be the same version used for the previous release. Record its inputs, parameters and tool version. Otherwise, an apparently unchanged HDL build can receive different sources after an update.

FPGA vendor libraries are often prepared for a particular simulator and tool combination. Treat them as versioned dependencies and avoid a single writable library directory that changes continuously for every project. Concurrent builds must not accidentally overwrite the same artefacts. An immutable prepared library revision combined with a project-specific working library is easier to control.

Actually verify a clean build

An incremental run can conceal missing build steps because previously analysed units are still available. Regularly add a build into a new output directory. Use a clearly bounded project path; a broadly constructed recursive deletion command creates unnecessary risk. The fresh build should locate every required input and fail clearly when a dependency is missing.

Every result needs at least the source revision, tool version, test selection, settings and a timestamp. When randomness is involved, include the seed. Environment variables may also matter, for example for include directories or licence servers. Do not let secrets enter a build log through an unfiltered environment dump. Document what a setting means without publishing the entire environment.

Handover is the strongest everyday test

Ask a second person to start a small test using only the project instructions. Every additional verbal explanation reveals a documentation gap. Improve the instructions and repeat the exercise in a separate working directory. The goal is not a particularly complicated build architecture, but an understandable entry point that reliably supports small changes and later reruns.

The application note on reproducible regressions adds executable test control and error handling to this structure. The article on syntax checking, linting and simulation explains which results should be retained separately.

Sources and date

Research checked on 19 October 2026. VUnit user guide, Sigasi: Integrating with external tools.

Would you like to apply this approach to your project?

Review your development workflow with us

EDA PRAXIS / NEWSLETTER

Fresh perspectives.
Straight to your inbox.

Practical knowledge about HDL, simulation and verification. New articles, application notes and insights into useful tools.