nvc
—
VHDL Compiler and Simulator
nvc
is an implementation of the VHDL language as defined
by IEEE standard 1076-1993 and later revisions.
Simulating a design typically involves three steps: analysing one
or more source files into the work library; elaborating a top-level design
unit; and finally running the elaborated design.
nvc
accepts three kinds of options: global
options; commands; and options specific to the command. Global options must
be placed before the command and specific options must be placed after the
command.
-a
file ...
- Analyse one or more files into the work library.
-e
unit
- Elaborate a previously analysed top level design unit.
-r
unit
- Execute a previously elaborated top level design unit.
--dump
unit
- Print out a pseudo-VHDL representation of an analysed unit. This is
usually only useful for debugging the compiler.
--list
- Print all analysed and elaborated units in the work library.
--make
unit ...
- Generate a makefile for already analysed units.
--syntax
file ...
- Check input files for syntax errors only.
Commands can be chained together. For example to analyse a file
foo.vhd and then elaborate and run a top-level entity
bar:
$ nvc -a foo.vhd -e bar -r
Note that the unit argument for the
-r
run command is taken from the earlier
-e
elaborate command.
--force-init
- Initialise a library work directory even if it already exists and is
non-empty.
-h
,
--help
- Display usage summary.
--ignore-time
- Do not check the timestamps of source files when the corresponding design
unit is loaded from a library.
-L
path
- Add path to the list of directories to search for
libraries. See the LIBRARIES section
below for details.
-M
size
- Set the maximum amount of memory in bytes used for the internal
representations of design units. The default is 16 megabytes but this may
be insufficient when elaborating a large design. The
size parameter takes an optional k, m, or g suffix
to indicate kilobytes, megabytes, and gigabytes respectively. For example
-M64m
for 64 megabytes.
--map
=name:path
- Specify exactly the location of the logical library
name. Libraries mapped in this way will not use the
normal search path.
--messages
=[full
|compact
]
- Select the format used for printing error and informational messages. The
default full message format is designed for readability whereas the
compact messages can be easily parsed by tools.
--std
=rev
- Select the VHDL standard revision to use. VHDL standard revisions are
commonly referred to by the year they were published. For example IEEE
1076-1993 is known as VHDL-93. Specify either the full year such as 1993
or just the last two digits such as 93. The accepted revisions are 1993,
2000, 2002, and 2008. Note there is very limited supported for any
features beyond those in VHDL-2002. VHDL-87 is not supported.
-v
,
--version
- Display version and copyright information.
--work
=name,
--work
=name:path
- Use name as the work library. The second variant
explicitly specifies the location of the library. See the
LIBRARIES section below for
details.
--bootstrap
- Allow compilation of the ‘
STANDARD
’
package. Not useful in any other circumstances.
--error-limit
=num
- Stop after reporting num errors. The default is 20.
Zero allows unlimited errors.
--relax
=rules
- Disable certain pedantic rule checks specified in the comma-separated list
rules. See the
RELAXING RULES section below for
the full list.
--cover
- Enable code coverage reporting (see the
CODE COVERAGE section below).
--dump-llvm
- Write generated LLVM IR to the work library directory before and after
optimisation.
--dump-vcode
- Print generated intermediate code. This is only useful for debugging the
compiler.
-g
name=value
- Override top-level generic name with
value. Integers, enumeration literals, and string
literals are supported. For example
-gI=5
,
-gINIT='1'
, and
-gSTR="hello"
.
-O0
,
-01
, -02
,
-O3
- Set LLVM optimisation level. Default is
-O2
.
-V
,
--verbose
- Prints resource usage information after each elaboration step.
--dump-arrays
- Include memories and nested arrays in the waveform data. This is disabled
by default as it can have significant performance, memory, and disk space
overhead.
--exit-severity
=level
- Terminate the simulation after an assertion failures of severity greater
than or equal to level. Valid levels are
note
, warning
,
error
, and failure
. The
default is error
.
--format=
fmt
- Generate waveform data in format fmt. Currently
supported formats are:
fst
and
vcd
. The FST format is native to
gtkwave(1).
FST is preferred over VCD due its smaller size and better performance. VCD
is a very widely used format but has limited ability to represent VHDL
types and the performance is poor: select this only if you must use the
output with a tool that does not support FST. The default format is FST if
this option is not provided. Note that GtkWave 3.3.79 or later is required
to view the FST output.
--ieee-warnings=
[on
|off
]
- Enable or disable warning messages from the standard IEEE packages. The
default is warnings enabled.
--include=
glob,
--exclude=
glob
- Signals that match glob are included in or excluded
from the waveform dump. See section
SELECTING SIGNALS for details
on how to select particular signals. These options can be given multiple
times.
--load=
plugin
- Loads a VHPI plugin from the shared library plugin.
See section VHPI for details on the VHPI
implementation.
--profile
- Print various internal statistics about the simulation at the end of the
run. This is mostly useful for tuning the runtime itself.
--stats
- Print a summary of the time taken and memory used at the end of the
run.
--stop-delta
=N
- Stop after N delta cycles. This can be used to
detect zero-time loops in your model. The default is 1000 if not
specified. Setting this to zero disables the delta cycle limit.
--stop-time
=T
- Stop the simulation after the given time has elapsed. Format of
T is an integer followed by a time unit in lower
case. For example
5ns
or
20ms
.
--trace
- Trace simulation events. This is usually only useful for debugging the
simulator.
--vhpi-trace
- Trace VHPI calls and events. This can be useful for debugging VHPI
plugins.
-w
,
--wave
=file
- Write waveform data to file. The file name is
optional and if not specified will default to the name of the top-level
unit with the appropriate extension for the waveform format. The waveform
format can be specified with the
--format
option.
By default all signals in the design will be dumped: see the
SELECTING SIGNALS section
below for how to control this.
--deps-only
- Generate rules that only contain dependencies without actions. These can
be useful for inclusion in a hand written makefile.
--posix
- The generated makefile will work with any POSIX compliant make. Otherwise
the output may use extensions specific to GNU make.
A library is a directory containing analysed design units and other files
generated by nvc
. The default library is called
"work" and is placed in a directory also called
work. Note that VHDL also has a concept of the "work
library" where the current library can be referred to by the alias
work. This confusing behaviour is an unfortunate hangover
from the proprietary tools the author used prior to writing
nvc
.
The name and physical location of the work library is controlled
by the --work
global option. In the simple case of
--work
=name the library name
is ‘name
’ and the physical location is
a directory name relative to the current working
directory. The physical location can be specified explicitly using
--work
=name:path
where path is the directory name.
The following examples should make this behaviour clear:
The work library is named
‘mylib
’ and is mapped to a directory
with the same name in the current working directory.
$ nvc --work=mylib:somedir ...
The work library is named
‘mylib
’ and is mapped to a directory
somedir in the current working directory.
$ nvc --work=mylib:/foo/bar ...
The work library is named
‘mylib
’ and is mapped to the absolute
path /foo/bar.
The following can be specified as a comma-separated list to the
--relax
option to disable certain semantic rule
checks.
prefer-explict
- Any visible explicitly declared operator always hides an implicit operator
regardless of the region in which it is declared. This is required to
analyse code that uses the non-standard Synopsys
std_logic_arith package.
locally-static
- References to generics and array slices are allowed in locally static
expressions using the VHDL-2008 rules.
universal-bound
- Prior to VHDL-2000 when range bounds have universal integer type the
expressions must be either numeric literals or attributes. This option
allows ranges such as ‘
-1 to 1
’ in
VHDL-1993 which otherwise must be written
‘integer'(-1) to 1
’.
pure-files
- Pure functions are allowed to declare file objects.
impure
- Pure functions may call impure functions.
Every signal object in an elaborated design has a unique hierarchical path name.
In VHDL this can be accessed using the
‘PATH_NAME
’ attribute.
A signal can be referred to using its full path name, for example
‘:top:sub:x
’, and
‘:top:other:x
’ are two different
signals named ‘x
’ in the design. The
character ‘:
’ is a hierarchy
separator. The special character ‘*
’
is a wildcard that matches zero or more characters and may be used refer to
a group of signals. For example
‘:top:*:x
’,
‘*:x
’, and
‘:top:sub:*
’, all select both of the
previous signals.
Path names and globs can be used to exclude or explicitly include signals in a
waveform dump. For simple cases this can be done using the
--include
and --exclude
arguments. For example
--exclude=
“:top:sub:*”
will exclude all matching signals from the waveform dump. Multiple inclusion
and exclusion patterns can be provided.
Specifying large numbers of patterns on the command line quickly
becomes cumbersome. Instead inclusion and exclusion patterns can be read
from a text file. If the top-level unit name is
‘top
’ then inclusion patterns should
be placed in a file called top.include and exclusion
patterns in a file called top.exclude. These files
should be in the working directory where the ‘nvc
-r
’ command is executed. The format is one glob per line, with
comments preceded by a ‘#
’
character.
When both inclusion and exclusion patterns are present, exclusions
have precedence over inclusions. If no inclusion patterns are present then
all signals are implicitly included.
nvc
supports a subset of VHPI allowing access to signal
values and events at runtime. The standard VHPI header file
<vhpi_user.h>
will be placed
in the system include directory as part of the installation process. VHPI
plugins should be compiled as shared libraries; for example:
$ cc -shared -fPIC my_plugin.c -o my_plugin.so
$ nvc -r --load my_plugin.so my_tb
The plugin should define a global
vhpi_startup_routines which is a NULL-terminated list
of functions to call when the plugin is loaded:
void (*vhpi_startup_routines[])() = {
startup_1,
startup_2,
NULL
};
Functions defined in VHPI plugin libraries may be called from VHDL
using the VHPIDIRECT protocol. The VHDL function should be declared with the
‘FOREIGN
’ attribute giving the name of
the function symbol exported from the plugin. For example:
function my_func (x : integer; y : bit_vector; z : std_logic) return integer;
attribute foreign of my_func : function is "VHPIDIRECT my_func";
Where ‘my_func
’ is a global
function defined in the plugin library as follows.
int32_t my_func(int32_t x, const uint8_t *y, uint8_t z) { ... }
Foreign procedures may be defined similarly:
function my_proc (x : out integer; y : out bit_vector; z : std_logic);
attribute foreign of my_proc : function is "VHPIDIRECT my_proc";
void my_proc(int32_t *x, uint8_t *y, uint8_t z) { ... }
Note that scalar ‘out
’
parameters are passed by pointer.
There is a simple mapping between VHDL and C types.
- Integers
- The smallest C integer type that holds the full range of the VHDL
type.
- Reals
- C double regardless of the range of the VHDL
type.
- Enumerated types
- The smallest unsigned integer type that holds the full range of the VHDL
type.
- Constrained arrays
- Pointer to the element type.
- Unconstrained arrays
- Pointer to the element type. Note that the length and bounds are not
available and must be passed explicitly as separate arguments.
- Records
- Not yet supported.
Here are several examples for common types:
Foreign functions should not modify arrays passed as
‘in
’ arguments, although this is not
enforced. Additionally foreign subprograms should not retain any pointers
passed as arguments after the subprogram returns.
NVC_COLORS
- Controls whether
nvc
uses ANSI colour escape
sequences to print diagnostic messages. The possible values are
never
, always
, and
auto
which enables colour if stdout is connected
to a terminal. The default is auto
.
Written by Nick Gasson ⟨nick@nickg.me.uk⟩