.. SPDX-FileCopyrightText: 2003-2026 Wilson Snyder
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0

******************************
FAQ/Frequently Asked Questions
******************************

.. Extra heading level here so sidebar index looks nice

Questions
=========

Can I contribute?
"""""""""""""""""

Please contribute! Just submit a pull request, or raise an issue to discuss
if you are looking for something to help on. For more information see our
contributor agreement.


How widely is Verilator used?
"""""""""""""""""""""""""""""

Verilator is used by many of the largest silicon design companies, large
organizations such as CERN, and even by college student projects.

Verilator is one of the "big 4" simulators, meaning one of the four leading
SystemVerilog simulators available, namely the closed-source products
Synopsys VCS (tm), Mentor Questa/ModelSim (tm), Cadence
Xcelium/Incisive/NC-Verilog/NC-Sim (tm), and the open-source Verilator. The
three closed-source offerings are often collectively called the "big 3"
simulators.


Does Verilator run under Windows?
"""""""""""""""""""""""""""""""""

Yes, ideally, run Ubuntu under Windows Subsystem for Linux (WSL2).
Alternatively, use Cygwin, though this tends to be slower and is not
regularly tested. Verilated output also compiles under Microsoft Visual
C++, but this is also not regularly tested.


Can you provide binaries?
"""""""""""""""""""""""""

You can install Verilator via the system package manager (apt, yum, etc.)
on many Linux distributions, including Debian, Ubuntu, SuSE, Red Hat, and
others. These packages are provided by the Linux distributions and
generally will lag the version of the mainline Verilator repository. If no
binary package is available for your distribution, how about you set one
up?


How can it be faster than (name-a-big-3-closed-source-simulator)?
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

Generally, the implied part of the question is "... with all of the
manpower they can put into developing it."

Most simulators must comply with the complete IEEE 1364 (Verilog) and IEEE
1800 (SystemVerilog) standards, meaning they have to be event-driven. This
prevents them from being able to reorder blocks and make netlist-style
optimizations, which are where most of the gains come from.

You should not be scared by non-compliance. Your synthesis tool isn't
compliant with the whole standard to start with, so your simulator need not
be either. Verilator is closer to the synthesis interpretation, which is a
good thing for getting working silicon.


Will Verilator output remain under my own license/copyright?
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

Your SystemVerilog, VPI/DPI, or main() C++ code remains under your own
license.

It's just like how using GCC on your programs does not change the copyright
of your program; this is why Verilator uses the "GNU **Lesser** Public
License Version 3" instead of the more typical "GNU Public License". See
the licenses for details.

Some examples:

* Any SystemVerilog or other input fed into Verilator remains your own.

* Any of your VPI/DPI C++ routines that Verilator calls remain your own.

* Any of your main() C++ code that calls into Verilator remains your own.

* If you change Verilator itself, for example, changing or adding a file
  under the src/ directory in the repository, you must make the source code
  available under the GNU Lesser Public License.

* If you change a header Verilator provides, for example, under include/ in
  the repository, you must make the source code available under the GNU
  Lesser Public License.

You also have the option of using the Perl Artistic License, which again
does not require you to release your Verilog, C++, or generated code. This
license also allows you to modify Verilator for internal use without
distributing the modified version. But please contribute back to the
community!

Under both licenses, you can offer a commercial product based on Verilator
directly or embedded within. However, under both licenses, any changes you
make to Verilator for such a product must be open-sourced.

As is standard with Open Source, contributions back to Verilator will be
placed under the Verilator copyright and LGPL/Artistic license. Small test
cases will be released into the public domain so they can be used anywhere,
and large tests under the LGPL/Artistic, unless requested otherwise.


Why is running Verilator (to create a model) so slow?
"""""""""""""""""""""""""""""""""""""""""""""""""""""

Verilator may require more memory than the resulting simulation, as
Verilator internally creates all of the state of the resulting generated
simulator to optimize it. If it takes more than a few minutes or so (and
you're not using :vlopt:`--debug` since debug mode is disk bound), see if
your machine is paging; most likely, you need to run it on a machine with
more memory. Very large designs are known to have topped 64 GB resident set
size. Alternatively, see :ref:`Hierarchical Verilation`.


How do I generate waveforms (traces) in C++?
""""""""""""""""""""""""""""""""""""""""""""

See also the next question for tracing in SystemC mode.

A. Pass the :vlopt:`--trace-vcd` option to Verilator. Then you may use
   ``$dumpfile`` and ``$dumpvars`` to enable traces, the same as with any
   Verilog simulator, although Verilator ignores the arguments to
   ``$dumpvars``. See ``examples/make_tracing_c`` in the distribution.

   If writing the top-level C code, call ``Verilated::traceEverOn(true)``;
   this is done for you if using :vlopt:`--binary`.

B. Or, for finer-grained control, or C++ files with multiple Verilated
   modules, you may also create the trace purely from C++. Create a
   VerilatedVcdC object, and in your main loop, right after ``eval()`` call
   ``trace_object->dump(contextp->time())`` every time step, and finally
   call ``trace_object->close()``.

   .. code-block:: C++
      :emphasize-lines: 1,5-8,12

      #include "verilated_vcd_c.h"
      ...
      int main(int argc, char** argv) {
          const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
          ...
          Verilated::traceEverOn(true);
          VerilatedVcdC* tfp = new VerilatedVcdC;
          topp->trace(tfp, 99);  // Trace 99 levels of hierarchy (or see below)
          // tfp->dumpvars(1, "t");  // trace 1 level under "t"
          tfp->open("obj_dir/t_trace_ena_cc/simx.vcd");
          ...
          while (contextp->time() < sim_time && !contextp->gotFinish()) {
              contextp->timeInc(1);
              topp->eval();
              tfp->dump(contextp->time());
          }
          tfp->close();
      }

You also need to compile :file:`verilated_vcd_c.cpp` and add it to your
link, preferably by adding the dependencies in your Makefile's
``$(VK_GLOBAL_OBJS)`` link rule. This is done for you if you are using the
Verilator :vlopt:`--binary` or :vlopt:`--exe` option.

you can call ``trace_object->trace()`` on multiple Verilated objects with
the same trace file if you want all data to land in the same output file.


How do I generate waveforms (traces) in SystemC?
""""""""""""""""""""""""""""""""""""""""""""""""

A. Pass the :vlopt:`--trace-vcd` option to Verilator, and in your top-level
   ``sc_main()``, call ``Verilated::traceEverOn(true)``. Then you may use
   ``$dumpfile`` and code:`$dumpvars` to enable traces, as with any Verilog
   simulator; see the non-SystemC example in
   :file:`examples/make_tracing_c`. This will trace only the module
   containing the ``$dumpvar``.

B. Or, you may create a trace purely from SystemC, which may trace all
   Verilated designs in the SystemC model. Create a VerilatedVcdSc object
   as you would create a standard SystemC trace file. For an example, see
   the call to ``VerilatedVcdSc`` in the
   :file:`examples/make_tracing_sc/sc_main.cpp` file of the distribution,
   and below.

C. Alternatively, you may use the C++ trace mechanism described in the
   previous question; note that the timescale and timeprecision will be
   inherited from your SystemC settings.

   .. code-block:: C++
      :emphasize-lines: 1,5-8

      #include "verilated_vcd_sc.h"
      ...
      int main(int argc, char** argv) {
          ...
          Verilated::traceEverOn(true);
          VerilatedVcdSc* tfp = new VerilatedVcdSc;
          topp->trace(tfp, 99);  // Trace 99 levels of hierarchy
          tfp->open("obj_dir/t_trace_ena_cc/simx.vcd");
          ...
          sc_start(1);
          ...
          tfp->close();
      }

You also need to compile :file:`verilated_vcd_sc.cpp` and
:file:`verilated_vcd_c.cpp` and add them to your link, preferably by adding
the dependencies in your Makefile's ``$(VK_GLOBAL_OBJS)`` link rule. This
is done for you if you are using the Verilator :vlopt:`--binary` or
:vlopt:`--exe` option.

You can call ``->trace()`` on multiple Verilated objects with the same
trace file if you want all data to land in the same output file.


How do I generate FST waveforms (traces) in C++ or SystemC?
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

FST is a trace file format developed by GTKWave. Verilator provides basic
FST support. To dump traces in FST format, add the :vlopt:`--trace-fst`
option to Verilator and either:

Use ``$dumpfile & $dumpvars`` in Verilog as described in the VCD example
above,

Or, in C++ change the include described in the VCD example above:

.. code-block:: C++

   #include "verilated_fst_c.h"
   VerilatedFstC* tfp = new VerilatedFstC;

Or, in SystemC, change the include described in the VCD example above:

.. code-block:: C++

   #include "verilated_fst_sc.h"
   VerilatedFstC* tfp = new VerilatedFstSc;

Currently, supporting FST and VCD in a single simulation is not supported,
but such usage should be unlikely. You can however ifdef around the trace
format in your C++ main loop, and select VCD or FST at compile time.


How do I view waveforms (aka dumps or traces)?
""""""""""""""""""""""""""""""""""""""""""""""

Verilator creates standard VCD (Value Change Dump) and FST files. VCD files
are viewable with the open-source `GTKWave
<https://gtkwave.sourceforge.net/>`_, `Surfer
<https://surfer-project.org/>`_, Dinotrace (legacy), or any of the many
closed-source viewer offerings; FST is supported only by GTKWave and
Surfer.


How do I speed up writing large waveform (trace) files?
"""""""""""""""""""""""""""""""""""""""""""""""""""""""

A. Instead of calling ``VerilatedVcdC->open`` or ``$dumpvars`` at the
   beginning of time, delay calling it until the time stamp where you want
   tracing to begin.

B. Add the :option:`/*verilator&32;tracing_off*/` metacomment to any very
   low-level modules you never want to trace (such as perhaps library
   cells).

C. Use the :vlopt:`--trace-depth` option to limit the tracing depth, for
   example :vlopt:`--trace-depth 1 <--trace-depth>` to see only the
   top-level signals.

D. You can also consider using FST tracing instead of VCD. FST dumps are a
   fraction of the size of the equivalent VCD. FST tracing can be slower
   than VCD tracing, but it might be the only option if the VCD file size
   is prohibitively large.

E. Write your trace files to a machine-local solid-state drive instead of a
   network drive. Network drives are generally far slower.


Where is the translate_off command? (How do I ignore a construct?)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

Translate on/off pragmas are generally a bad idea, as it's easy to have
mismatched pairs, and you can't see what another tool sees by just
preprocessing the code. Instead, use the preprocessor; Verilator defines
the ``\`VERILATOR`` define for you, so just wrap the code in an ifndef
region:

.. code-block:: sv
   :emphasize-lines: 1

   `ifndef VERILATOR
      Something_Verilator_Dislikes;
   `endif

Most synthesis tools similarly define SYNTHESIS for you.


Why do I get "unexpected 'do'" or "unexpected 'bit'" errors?
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

The words ``do``, ``bit``, ``ref``, ``return``, and others are reserved
keywords in SystemVerilog. Older Verilog code might use these as
identifiers, and you should change your code to not use them to ensure it
works with newer tools. Alternatively, surround them by the Verilog
2005/SystemVerilog begin_keywords pragma to indicate Verilog 2001 code.

.. code-block:: sv
   :emphasize-lines: 1

   `begin_keywords "1364-2001"
      integer bit; initial bit = 1;
   `end_keywords

If you want the whole design parsed as Verilog 2001, see the
:vlopt:`--default-language` option.


How do I prevent my assertions from firing during reset?
""""""""""""""""""""""""""""""""""""""""""""""""""""""""

Call ``Verilated::assertOn(false)`` before you first call the model, then
turn it back on after reset. It defaults to true. When false, all
assertions are disabled.


Why do I get "undefined reference to sc_time_stamp()?
"""""""""""""""""""""""""""""""""""""""""""""""""""""

In Verilator 4.200 and later, using the timeInc function is recommended
instead. See the :ref:`Connecting to C++` examples. Some linkers (MSVC++)
still require ``sc_time_stamp()`` to be defined; either define this with
``double sc_time_stamp() { return 0; }`` or compile the Verilated code with
``-CFLAGS -DVL_TIME_CONTEXT``.

Before Verilator 4.200, the ``sc_time_stamp()`` function needs to be
defined in C++ (non SystemC) to return the current simulation time.


Why do I get "undefined reference to \`VL_RAND_RESET_I' or \`Verilated::...'"?
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

You need to link your compiled Verilated code against the ``verilated.cpp``
file found in the include directory of the Verilator kit. This is one
target in the ``$(VK_GLOBAL_OBJS)`` make variable, which should be part of
your Makefile's link rule. If you use :vlopt:`--exe` or :vlopt:`--binary`,
this is done for you.


Is the PLI supported?
"""""""""""""""""""""

Only somewhat. More specifically, the common PLI-ish calls $display,
$finish, $stop, $time, $write are converted to C++ equivalents. You can
also use the "import DPI" SystemVerilog feature to call C code (see the
chapter above). There is also limited VPI access to public signals.

If you want something more complex, since Verilator emits standard C++
code, you can write C++ routines that can access and modify signal values
without needing any PLI interface code, and call it with
$c("{any_c++_statement}").

See the :ref:`Connecting` section.


How do I make a Verilog module that contains a C++ object?
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

You need to add the object to the structure Verilator creates, then use $c
to call a method inside your object. The
:file:`test_regress/t/t_extend_class` files in the distribution show an
example of how to do this.


How do I get faster build times?
""""""""""""""""""""""""""""""""

* When running make, pass the make variable VM_PARALLEL_BUILDS=1, so that
  builds occur in parallel. Note this is now set by default if an output
  file is large enough to be split due to the :vlopt:`--output-split`
  option.

* Verilator emits any infrequently executed "cold" routines into separate
  __Slow.cpp files. This can accelerate compilation as optimization can be
  disabled on these routines. See the OPT_FAST and OPT_SLOW make variables
  and :ref:`Benchmarking & Optimization`.

* Use a recent compiler. Newer compilers tend to be faster.

* Compile in parallel on many machines and use caching; see the web for the
  ccache, sccache, distcc, or icecream packages. ccache will skip GCC runs
  between identical source builds, even across different users. If ccache
  was installed when Verilator was built, it is used, or see OBJCACHE
  environment variable to override this. Also see the
  :vlopt:`--output-split` option and :ref: `Profiling ccache efficiency`.

* To reduce the compile time of classes that use a Verilated module (e.g.,
  a top CPP file) you may wish to add a
  :option:`/*verilator&32;no_inline_module*/` metacomment to your top-level
  module. This will decrease the amount of code in the model's Verilated
  class, improving compile times of any instantiating top-level C++ code,
  at a relatively small cost of execution performance.

* Use :ref:`hierarchical verilation`.


Why do so many files need to recompile when I add a signal?
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

Adding a new signal requires the symbol table to be recompiled. Verilator
uses one large symbol table, resulting in 2-3 fewer assembly instructions
for each signal access. This makes the execution time 10-15% faster, but
can result in more compilations when something changes.


How do I access Verilog functions/tasks in C?
"""""""""""""""""""""""""""""""""""""""""""""

Use the SystemVerilog Direct Programming Interface. You write a Verilog
function or task with input/outputs that match what you want to call in
with C. Then mark that function as a DPI export function. See the DPI
chapter in the IEEE Standard.


How do I access C++ functions/tasks in Verilog?
"""""""""""""""""""""""""""""""""""""""""""""""

Use the SystemVerilog Direct Programming Interface. You write a Verilog
function or task with input/outputs that match what you want to call in
with C. Then mark that function as a DPI import function. See the DPI
chapter in the IEEE Standard.


How do I access signals in C?
"""""""""""""""""""""""""""""

The best thing to do is to make a SystemVerilog "export DPI" task or
function that accesses that signal, as described in the DPI chapter in the
manual and DPI tutorials on the web. This will allow Verilator to optimize
the model better and should be portable across simulators.

If you really want raw access to the signals, declare the signals you will
be accessing with a :option:`/*verilator&32;public*/` metacomment before
the closing semicolon. Then scope into the C++ class to read the value of
the signal, as you would any other member variable.

Signals are the smallest of 8-bit unsigned chars (equivalent to uint8_t),
16-bit unsigned shorts (uint16_t), 32-bit unsigned longs (uint32_t), or
64-bit unsigned long longs (uint64_t) that fit the width of the signal.
Generally, you can use just uint32_t's for 1 to 32 bits, or uint64_t for 1
to 64 bits, and the compiler will properly up-convert smaller entities.
Note that even signed ports are declared as unsigned; you must sign extend
yourself to the appropriate signal width.

Signals wider than 64 bits are stored as an array of 32-bit uint32_t's.
Thus, to read bits 31:0, access signal[0], and for bits 63:32, access
signal[1]. Unused bits (for example, bit numbers 65-96 of a 65-bit vector)
will always be zero. If you change the value, you must pack zeros in the
unused bits, or core-dumps may result because Verilator strips array bound
checks where it believes them to be unnecessary to improve performance.

In the SYSTEMC example above, if you had in our.v:

.. code-block:: sv

   input clk /*verilator public*/;
   // Note the placement of the semicolon above

From the sc_main.cpp file, you'd then:

.. code-block:: C++

   #include "Vour.h"
   #include "Vour_our.h"
   std::cout << "clock is " << top->our->clk << std::endl;


In this example, clk is a bool you can read or set as any other variable.
The value of normal signals may be set, though your code shouldn't change
clocks, or you'll get strange results.


Should a module be in Verilog or SystemC?
"""""""""""""""""""""""""""""""""""""""""

Sometimes there is a block that only interconnects instances, and you have
a choice if you write it in Verilog or SystemC. Everything else being
equal, the best performance is when Verilator sees all of the design. So,
look at the hierarchy of your design, labeling instances as to if they are
SystemC or Verilog. Then:

* A module with only SystemC instances below must be SystemC.

* A module with a mix of Verilog and SystemC instances below must be
  SystemC. (As Verilator cannot connect to lower-level SystemC instances.)

* A module with only Verilog instances below can be either, but for best
  performance should be Verilog. (The exception is if you have a design
  that is instantiated many times; in this case, Verilating one of the
  lower modules and instantiating that Verilated instances multiple times
  into a SystemC module *may* be faster.)
