Open-source project
nickg/nvc avatar
nickg/nvc

NVC: a VHDL simulator that compiles to native code through LLVM

VHDL compiler and simulator

900 stars123 forksCGPL-3.0

At a glance

What is it?
NVC is a C implementation of a VHDL compiler and simulator that uses LLVM to turn VHDL into native machine code, with a workflow that maps closely onto analyse, elaborate and run. It supports almost all of VHDL-2008 apart from PSL, plugs into OSVVM, UVVM, VUnit and cocotb, and is explicitly not a synthesizer.
Who is it for?
Adopt NVC if you simulate VHDL and want a fast simulator that fits into an existing verification flow, particularly if your testbenches already use OSVVM, UVVM, VUnit or cocotb. Do not adopt it if you need synthesis, because NVC deliberately does not produce anything you can program into an FPGA or an ASIC, and do not adopt it if you need PSL.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem: verification without a device

Writing a hardware design in VHDL is only half the work. Before anything reaches an FPGA, somebody has to check that the design behaves, and the tool that does the checking is a simulator: a program that reads a design, runs it against a testbench in event time, and reports what happened.

NVC is a VHDL compiler and simulator, written in C. The project states that it supports almost all of VHDL-2008 with the exception of PSL, and that it has been successfully used to simulate several real-world designs. Experimental support for Verilog and VHDL-2019 is under development.

The important boundary is stated in the same breath, and it is worth reading carefully before you build anything on the tool. NVC is not a synthesizer. It does not output something that could be used to program an FPGA or ASIC, and it implements only the simulation behaviour of the language as described by the IEEE 1076 standard.

That is a common source of confusion in hardware toolchains, where the same file is fed to a simulator and to a synthesizer and the two are expected to agree. NVC is on one side of that line only. If your flow needs synthesis output, you need a different tool for that half, and NVC handles the verification half.

The audience is hardware engineers who write VHDL and verify it, and the project's emphasis is explicit: NVC has a particular emphasis on simulation performance, and it uses LLVM to compile VHDL to native machine code. The licence is GPL-3.0, the homepage is at nickg.me.uk, and the last push was on 2026-10-16.

The workflow: analyse, elaborate, run

The command line is the clearest description of the tool. Simulating a VHDL design involves three steps, analysing the source files, elaborating the design, and running the simulation, and the documentation points out that this is analogous to compiling, linking and executing a software program.

NVC maps those three steps onto three flags:

code
$ nvc -a my_design.vhd my_tb.vhd
$ nvc -e my_tb
$ nvc -r my_tb

The names are the top-level testbench entity, my_tb in this example, and the analyse step takes the design and the testbench as separate files. The elaboration step produces a simulation model for that entity, and the run step executes it.

For a quick run there is a single command form that does all three:

code
$ nvc -a my_design.vhd my_tb.vhd -e my_tb -r

Two things follow from this design. First, the intermediate steps are addressable, so a design that is analysed once and elaborated several times does not pay the analysis cost repeatedly, which matters in a regression run over hundreds of testbenches. Second, the model is named after the entity, which keeps the artefacts of one testbench separate from those of another, so parallel test execution does not collide.

The full manual is available after installation with man nvc, and the repository also ships the manual source as nvc.1, so the documentation is part of the source tree rather than a separate website.

The performance argument: LLVM instead of an interpreter

Most simulators choose one of two designs. An interpreter reads the design and executes it in a virtual machine, which is easy to write and slow to run. A compiler translates the design ahead of time into something the machine can execute directly, which is more work and much faster.

NVC takes the second route and uses LLVM to compile VHDL to native machine code. The project states the emphasis on simulation performance directly, and the choice of LLVM is the reason: you get a mature optimising backend, a mature just-in-time compiler, and target support for a dozen architectures without writing any of it.

There is a second, less obvious benefit. A design compiled to native code behaves like compiled software, which means the usual profiling tools work on it. When a simulation is slow, you can find out which part of the design is slow with the same tooling you would use on a program, instead of guessing.

The price is a dependency on LLVM and a minimum supported version. The documentation states that the minimum supported LLVM version is 8.0 and that versions between 8 and 21 have all been tested, and the configure script accepts --with-llvm=/path/to/llvm-config to select a particular installation. For a system with several LLVM versions installed, that flag is the thing to reach for, because the default is whatever the system provides.

The design also depends on Flex, which is used to generate the lexical analyser, so Flex is a build-time requirement rather than something you can skip.

Language coverage, and the two places it stops

The coverage claim is that NVC supports almost all of VHDL-2008, with the exception of PSL. PSL is the property specification language that sits alongside VHDL for formal assertions, and its absence is the first limit to check against your testbench.

The second limit is the pair of experimental areas: Verilog and VHDL-2019 are under development. Experimental is the operative word. If your design depends on a VHDL-2019 feature, or if your testbench mixes in Verilog, the honest position is that you are testing the tool's future, not its current behaviour.

There is a third boundary, which is the same one that separates every simulator from a synthesizer, and it is the one most likely to cause confusion: NVC implements only the simulation behaviour of the language as described by the IEEE 1076 standard. A design that simulates correctly under NVC is not thereby a design that will synthesise, because the two use different interpretations of constructs whose behaviour is implementation defined.

The supporting libraries are also worth knowing about. The source files for the IEEE standard libraries are included in the repository. They were originally provided under a proprietary licence that forbade distribution of modifications, but in 2019 they were relicensed under Apache 2.0. Freely redistributable versions of the 1993 libraries were made by editing and removing declarations from the 2019 libraries, and are Apache 2.0 as well. Certain libraries developed specifically for NVC under lib/nvc and lib/std are also Apache 2.0, with the details in the individual files.

Verification frameworks: OSVVM, UVVM, VUnit and cocotb

A simulator is rarely used on its own. Real VHDL verification runs on a framework, and the frameworks have opinions about how a testbench is written, how assertions are reported and how a regression is driven. NVC supports the popular ones: OSVVM, UVVM, VUnit and cocotb.

The difference in approach between them is worth understanding, because it decides which one you can use with an existing codebase.

OSVVM and UVVM are self-contained VHDL libraries. They give you a testbench framework written in VHDL itself, with assertion and severity reporting, coverage collection and stimulus generation, and they run inside the simulator, so the whole testbench is VHDL. VUnit is a Python harness that drives a VHDL testbench, runs the simulation and reports results, so the test logic around the design is Python while the design and its checks stay in VHDL. cocotb goes further and writes the testbench itself in Python, driving the design through a VPI or a similar interface.

The practical point is that NVC sits below all of them. It provides the analyse, elaborate and run model that these frameworks drive, and the documentation points to vendor library instructions for installing each one. If your team already has a testbench in OSVVM or a regression in VUnit, the framework is not the thing you have to change.

For looking at the results, the documentation names GTKWave and Surfer as waveform viewers, with GTKWave version 3.3.79 or later required for the default FST format.

Installing: packages, the Windows installer, and building from source

NVC is developed under GNU/Linux and regularly tested on macOS and Windows under MSYS2.

The quickest install on macOS is:

code
brew install nvc

There are packages for FreeBSD, Gentoo, the Arch Linux AUR and several other distributions, listed through repology. On Windows there is an installer on the releases page that can be installed with:

code
winget install NickGasson.NVC

For CI, there is a setup-nvc action for GitHub Actions and a container image at ghcr.io/nickg/nvc for other environments. Systems without an existing package should build from source.

Building from a git clone needs the configure script generated first:

code
./autogen.sh

In-tree builds are not supported, so the build happens in a separate directory:

code
mkdir build && cd build

followed by the standard autotools steps:

code
../configure
make
sudo make install

The dependency list is spelled out per distribution family. On a Debian derivative:

code
sudo apt-get install build-essential automake autoconf \
  flex check llvm-dev pkg-config zlib1g-dev libdw-dev \
  libffi-dev libzstd-dev

and on rpm based distributions:

code
sudo dnf install autoconf automake flex check llvm-devel libffi-devel \
  zlib-ng-compat-devel libzstd-devel elfutils-devel

On Windows only the MSYS2 environment is supported, and the Clang x64 environment should be used because it supports native Windows thread-local storage unlike the GCC based environments.

The regression suite runs with make check, and the unit tests need the check library. For testing your own change, that is the command that matters, and the project ships a coverage badge so you can see whether the tests are actually reaching the code.

The VITAL libraries, the release branch, and who to trust with the tool

The licence section of the documentation contains the most practically important paragraph in the whole project, and it is easy to skim.

The library collection under that directory was derived from draft copies of packages freely available on the internet, and its licence status is unclear because the final text is part of a standard that must be purchased from the IEEE. The guidance is direct: if you are packaging the program for a distribution with strict free software requirements, you should strip these files from the tarball and configure with at configure time.

That is a real obligation on redistributors, and it is unusual for a project to state it so plainly. The rest of the tree is clean: the program itself is GPL-3.0 or later, and the libraries that came with it are Apache 2.0. Only that corner of the tree is unresolved, and the resolution is to remove it.

The release structure is the other thing to understand. NVC has both a release branch and a development master branch. The master branch should be stable enough for day-to-day use and has comprehensive regression tests, but the release branch is more suitable for third party packaging. The latest released version is 1.23.0, and significant changes since the last release are detailed in NEWS.md. The recent tags follow the same pattern, with r1.23.0 from 2026-09-19, r1.22.1 from 2026-08-01 and r1.22.0 from 2026-07-22.

The project is not archived and the last push was on 2026-10-16, so the work is current. For a team evaluating the tool, the sensible split is to develop against master, where the regression suite runs on every change, and to package from the release branch, where the tree matches a published version and the question of what to strip has an answer.

The support position is stated just as plainly: the software is provided with no warranty and no expectation of support, though the maintainer says he will do his best to help with issues. Bugs go to the maintainer's address or the GitHub issue tracker, and the documentation asks for a small VHDL test case with the report, pointing at an existing issue as a model of a good one.

Editorial conclusion

Adopt NVC if you simulate VHDL and want a fast simulator that fits into an existing verification flow, particularly if your testbenches already use OSVVM, UVVM, VUnit or cocotb. Do not adopt it if you need synthesis, because NVC deliberately does not produce anything you can program into an FPGA or an ASIC, and do not adopt it if you need PSL. Before you package it for a distribution with strict free software requirements, read the licence section: those libraries cannot be redistributed freely and have to be stripped with --disable-vital.

Frequently asked questions

How do I compile and run a VHDL design with NVC?

Use three commands that mirror compiling, linking and executing: nvc -a with the design and testbench files, nvc -e with the top-level testbench entity name, and nvc -r with the same name to run it. They can also be combined into a single nvc -a my_design.vhd my_tb.vhd -e my_tb -r invocation.

Is NVC a synthesizer?

No. The documentation is explicit that NVC is not a synthesizer and does not output anything that could be used to program an FPGA or ASIC. It implements only the simulation behaviour of the language as described by the IEEE 1076 standard.

Which VHDL version does NVC support?

Almost all of VHDL-2008, with the exception of PSL. Experimental support for Verilog and VHDL-2019 is under development, so those areas are not something to depend on yet.

What are the build dependencies for NVC?

You need LLVM, with a minimum supported version of 8.0 and versions 8 through 21 tested, and Flex to generate the lexical analyser. The documentation lists the full package sets for Debian derivatives, rpm based distributions and MSYS2 on Windows, and the configure script accepts --with-llvm=/path/to/llvm-config.

Can I redistribute NVC?

The program is GPL-3.0 or later, so you may use, modify and redistribute it provided you keep the licence text and copyright notices and make the modified source available to your users. The exception is the collection under that directory, whose licence status is unclear, so for a distribution with strict free software requirements you should strip those files and configure with at configure time.

Official sources

  1. License: GPL-3.0
  2. nickg/nvc on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nickg-nvc.svg)](https://hysenlabs.com/projects/nickg-nvc)

Was this useful?