Libraries
A VHDL design lives in libraries: std and ieee for the standard packages, work for your own units by default, and named libraries for anything you want to keep apart. This chapter describes what is built into JanusHDL, how to make libraries of your own, and how to use the verification libraries UVVM, OSVVM and VUnit.
How JanusHDL handles libraries
JanusHDL analyzes from source. There is no separate step that compiles a library into a folder on disk: each run analyzes the files you name, into the libraries you name, and then elaborates and runs. A library is simply the name you give a group of files, with --work, a library line in a file list, or a library statement in a project.
What makes this fast enough for large libraries is the cache: --cache FILE keeps the analysis and loads it on the next run while no file changed (Caching the analysis).
The front ends for existing scripts are the exception: they keep a record of each library's files on disk, as the commands they stand in for are expected to (Running existing scripts).
Built-in libraries
These libraries are built in. You use them as you always would, with library ieee; and use clauses, and you never analyze them yourself. Their sources are in the vhdl folder of the download, to read (The VHDL sources folder).
STD
| Package | Contents |
|---|---|
std.standard |
The predefined types and operations |
std.textio |
Text input and output, with the VHDL-2008 and VHDL-2019 additions (sread, hwrite, justify, flush, tee, ...) |
std.env |
stop, finish, resolution_limit, and the VHDL-2019 additions: environment variables, date and time, directories, the call path, file name and line, and the assertion API |
std.reflection |
VHDL-2019 type reflection ('reflect) |
IEEE
From IEEE's official sources of the IEEE 1076-2019 packages, unmodified:
| Package | Contents |
|---|---|
std_logic_1164 |
std_ulogic, std_logic and their vectors |
numeric_std, numeric_bit |
signed and unsigned arithmetic |
numeric_std_unsigned, numeric_bit_unsigned |
Arithmetic on std_ulogic_vector and bit_vector as unsigned numbers |
math_real, math_complex |
Real and complex mathematics |
fixed_pkg, fixed_generic_pkg, fixed_float_types |
Fixed-point types sfixed and ufixed |
float_pkg, float_generic_pkg |
Floating-point types |
std_logic_textio |
Kept for designs that use it; in VHDL-2008 its routines are part of std_logic_1164 |
ieee_std_context, ieee_bit_context |
The standard contexts |
vital_timing, vital_primitives |
VITAL (IEEE 1076.4), for simulation libraries of FPGA and ASIC cells that use it |
Designs analyzed as VHDL-1993 or VHDL-2002 get the VHDL-93 forms of std_logic_1164, numeric_std and numeric_bit, made from the same sources with the interface of those versions: in them, std_logic_vector, unsigned and signed are types of their own, as designs of that time expect. Their sources are in vhdl/ieee93.
The functions of math_real give exact results where the result is representable: 10.0 ** 2.0 is 100.0 and log(1000.0, 10.0) is 3.0.
Legacy arithmetic packages
Many existing designs use packages that are not IEEE standards but that tools have long placed in library ieee. They are built in too, unchanged, under their own notice (vhdl/legacy/NOTICE.txt):
| Package | Contents |
|---|---|
ieee.std_logic_arith |
signed and unsigned arithmetic of its own, conv_integer, conv_std_logic_vector, ... |
ieee.std_logic_unsigned, ieee.std_logic_signed |
Arithmetic on std_logic_vector as an unsigned or a signed number |
ieee.std_logic_misc |
Reduction functions such as and_reduce and or_reduce |
ieee.std_logic_textio |
The VHDL-93 text routines for std_logic (read, hread, hwrite, ...), for VHDL-1993 and VHDL-2002 designs |
A design that uses them from library ieee runs as it is, in any VHDL version:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all; -- built in: nothing to compile
For new code, ieee.numeric_std (or numeric_std_unsigned) is the standard way.
Your own libraries
Give a library a name in any of three ways:
- on the command line:
--work util src/util_pkg.vhd(Libraries); - in a file list: a line
library utilbefore the files (File lists); - in a project:
library util, with an optional VHDL version for the whole library (Projects).
Then use it as VHDL does:
library util;
use util.util_pkg.all;
Inside the files of a library, work means that library. Library names are not case-sensitive.
If a design uses a library into which nothing was analyzed, the error says so, and what to do:
error[undeclared]: `uvvm_util_context` is not declared in `uvvm_util`
--> tb.vhd:2:9
|
2 | context uvvm_util.uvvm_util_context;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: library `uvvm_util` has no design units yet: analyze its sources into it first, before the files that use it
= LRM 8.3
UVVM
UVVM is not part of JanusHDL: you get it from its own project, so you have the version you choose, and analyze its sources with your design. All of UVVM analyzes in compatibility mode, and UVVM's demo testbenches run and pass.
UVVM needs --compat. UVVM keeps a few settings in shared variables whose types are not protected, which VHDL-2002 and later forbid. Without compatibility mode each is an error, and the analysis stops; with --compat each is a warning, and UVVM runs as written (What to expect). Every command below therefore has --compat; in a project, write compat on.
Getting UVVM
git clone https://github.com/UVVM/UVVM.git
or download a release from the UVVM project and unpack it.
UVVM's libraries
UVVM is a set of libraries, each in a folder of its own: uvvm_util (the utility library: logging, alerts, checks, randomization, coverage), uvvm_vvc_framework (the framework for verification components), bitvis_vip_scoreboard, and one library per verification component, such as bitvis_vip_uart or bitvis_vip_axistream. Analyze them in this order, each with the libraries it needs before it:
uvvm_utiluvvm_vvc_framework(for verification components, VVCs)bitvis_vip_scoreboard(the VVCs use it)- the verification components you use
- your design and testbench
The file script/component_list.txt in the UVVM folder lists every component in an order that works.
File lists from UVVM's compile orders
Each UVVM component has a file script/compile_order.txt that lists its files in analysis order, relative to that script folder, under a first line # library NAME. With that first line made into a library line, it is a JanusHDL file list. In the UVVM folder, on Linux or in Git Bash:
for c in $(tr -d '\r' < script/component_list.txt | grep -v '^#'); do
sed 's/^# *library/library/' $c/script/compile_order.txt > $c/script/$c.f
done
or in PowerShell:
foreach ($c in Get-Content script\component_list.txt) {
(Get-Content "$c\script\compile_order.txt") -replace '^# *library', 'library' |
Set-Content "$c\script\$c.f"
}
This writes uvvm_util/script/uvvm_util.f and the others. A testbench that uses only the utility library then runs with:
jhdl --compat -f UVVM/uvvm_util/script/uvvm_util.f -f my_tb.f --top work.my_tb
and one that uses verification components with all the libraries it needs, in order. For example, UVVM's interrupt controller demo, from the UVVM folder (its testbench is in the component's tb folder, which its compile order does not list, so a one-line list adds it):
printf 'library bitvis_irqc\n../tb/irqc_demo_tb.vhd\n' > bitvis_irqc/script/demo.f
jhdl --compat \
-f uvvm_util/script/uvvm_util.f \
-f uvvm_vvc_framework/script/uvvm_vvc_framework.f \
-f bitvis_vip_scoreboard/script/bitvis_vip_scoreboard.f \
-f bitvis_vip_sbi/script/bitvis_vip_sbi.f \
-f bitvis_irqc/script/bitvis_irqc.f \
-f bitvis_irqc/script/demo.f \
--top bitvis_irqc.irqc_demo_tb
It ends with UVVM's verdict, and JanusHDL's summary with the time each phase took:
UVVM: >> Simulation SUCCESS: No mismatch between counted and expected serious alerts
simulation of bitvis_irqc.irqc_demo_tb ended at 3.4325 µs (stopped); analysis ...
These commands were tried with the UVVM release of April 2026.
The verification components' compile orders also list a few files of uvvm_vvc_framework/src_target_dependent: those files are analyzed into each component's own library, as UVVM intends. Keep them where the compile order puts them.
UVVM in a project
In a project, list the same files under library statements, before your own:
jhdl-project 1
std 2008
library uvvm_util
source ../UVVM/uvvm_util/src/types_pkg.vhd
source ../UVVM/uvvm_util/src/adaptations_pkg.vhd
# ... the rest of uvvm_util's compile order
library work
source src/my_design.vhd
source tb/my_tb.vhd
top work.my_tb
compat on
The easy way to write it: make a file list of everything, then File → Import a file list (.f) as a project… in the window.
What to expect
- Compatibility mode. UVVM keeps a few settings in shared variables that are not of a protected type. VHDL-2002 and later allow only protected types there (LRM 6.4.2.4), so without
--compateach is an error, and the help says what to do:
text
error[unprotected-shared-variable]: a shared variable must be of a protected type, not T_LOG_DESTINATION
--> uvvm_util/src/string_methods_pkg.vhd:31:3
|
31 | shared variable shared_default_log_destination : t_log_destination := C_DEFAULT_LOG_DESTINATION;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: wrap the value in a protected type, or analyze the file as VHDL-93 (--std 93); or run with --compat, which accepts it and simulates it as written
= LRM 6.4.2.4
The packages with such variables then fail to analyze, and everything that uses them reports that; the first error is the one to read. With --compat, each is a warning (42 of them for the UART demo), and the run is not affected. To leave the warnings out as well, add --allow unprotected-shared-variable (or allow unprotected-shared-variable in a project).
- In the window and in editors. Tick Compatibility mode in the Run dialog for a UVVM file list, or set compat on in the project. For the language server, set its compat option (Options).
- Logs. UVVM prints its log as text output, which appears in the terminal and on the standard output, and also writes UVVM_Log.txt and UVVM_Alert.txt into the current folder. Run each testbench in a folder of its own if you run several at once.
- Speed. Analysis of UVVM takes a moment on every run. Use --cache with a file per testbench (Caching the analysis).
- Errors on purpose. A testbench that checks error handling may make its design report errors on purpose. UVVM then says SUCCESS, because it expected them, while jhdl exits with 1, because a report of severity error came up. Raise the exit level for such a testbench: --exit-level failure.
OSVVM
OSVVM is not part of JanusHDL either: get it from its own project and analyze its sources with your design. OSVVM's own regression suite passes on JanusHDL: 314 of 314 tests. OSVVM needs no compatibility mode.
git clone --recursive https://github.com/OSVVM/OsvvmLibraries.git
OSVVM's build scripts (.pro files) choose some files by simulator and VHDL version. For JanusHDL with VHDL-2008, the osvvm library is these files, in this order (paths relative to the OsvvmLibraries folder):
library osvvm
osvvm/IfElsePkg.vhd
osvvm/OsvvmTypesPkg.vhd
osvvm/SetGetBoundedGenericPkg.vhd
osvvm/SetGetBoundedPkg_Instances.vhd
osvvm/OsvvmScriptSettingsPkg.vhd
osvvm/OsvvmScriptSettingsPkg_default.vhd
osvvm/OsvvmSettingsPkg.vhd
osvvm/OsvvmSettingsPkg_default.vhd
osvvm/TextUtilPkg.vhd
osvvm/FileUtilPkg.vhd
osvvm/ResolutionPkg.vhd
osvvm/NamePkg.vhd
osvvm/OsvvmGlobalPkg.vhd
osvvm/CoverageVendorApiPkg_default.vhd
osvvm/NameStorePkg.vhd
osvvm/TranscriptBasePkg.vhd
osvvm/deprecated/LanguageSupport2019Pkg_c.vhd
osvvm/deprecated/FileLinePathPkg_c.vhd
osvvm/deprecated/AssertApiPkg_c.vhd
osvvm/AlertLogPkg.vhd
osvvm/IdFifoPtPkg.vhd
osvvm/TbUtilPkg.vhd
osvvm/MessageListPkg.vhd
osvvm/SortListPkg_int.vhd
osvvm/RandomBasePkg.vhd
osvvm/RandomPkg.vhd
osvvm/RandomProcedurePkg.vhd
osvvm/CoveragePkg.vhd
osvvm/CoveragePtPkg.vhd
osvvm/DelayCoveragePkg.vhd
osvvm/ResizePkg.vhd
osvvm/deprecated/DynamicVectorPkg_IntV_c.vhd
osvvm/deprecated/DynamicVectorPkg_slv_c.vhd
osvvm/ScoreboardGenericPkg.vhd
osvvm/ScoreboardPkg_IntV.vhd
osvvm/ScoreboardPkg_slv.vhd
osvvm/ScoreboardPkg_int.vhd
osvvm/ScoreboardPkg_signed.vhd
osvvm/ScoreboardPkg_unsigned.vhd
osvvm/MemorySupportPkg.vhd
osvvm/MemoryGenericPkg.vhd
osvvm/MemoryPkg.vhd
osvvm/TranscriptPkg.vhd
osvvm/ReportPkg.vhd
osvvm/deprecated/RandomPkg2019_c.vhd
osvvm/ClockResetPkg.vhd
osvvm/OsvvmContext.vhd
Save it as osvvm.f in the OsvvmLibraries folder. The _default package bodies are the ones OSVVM's scripts use when they do not generate their own. The list was made from OSVVM as of October 2026; if your version has added or moved a file, its osvvm/osvvm.pro script shows where (and the error for a missing file names it). OSVVM's verification component libraries (osvvm_common, osvvm_uart, osvvm_axi4 and the others) follow in the same way, each from its own build.pro.
A testbench then uses the context as usual:
library osvvm;
context osvvm.OsvvmContext;
jhdl -f OsvvmLibraries/osvvm.f -f my_tb.f --top work.my_tb
OSVVM writes its reports (.yml files and others) into the current folder.
VUnit
VUnit is a Python test runner with VHDL libraries of its own. Its run.py scripts run on JanusHDL unchanged, through one of the front ends in the compat folder: you put that folder first on your PATH and select it in VUnit as you would select a simulator. VUnit then analyzes its own libraries (vunit_lib and the rest) with your sources, and runs each test case in a simulation of its own.
VUnit in the chapter on existing scripts gives the exact settings.
Libraries from other tools
Simulation libraries delivered as VHDL sources, such as the cell and primitive libraries of FPGA and ASIC tools, are analyzed like any other library: name the library and list its files. Those that use VITAL find ieee.vital_timing and ieee.vital_primitives built in.
Libraries delivered only in a tool's own compiled form, or as encrypted (IEEE 1735) sources, cannot be used: JanusHDL needs the VHDL text, and does not decrypt protected code yet.