# FAQ/Frequently Asked Questions

## 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 `--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 Hierarchical Verilation.

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

See also the next question for tracing in SystemC mode.

1. Pass the `--trace` option to Verilator, and in your top-level C code, call `Verilated::traceEverOn(true)`. Then you may use `$dumpfile` and `$dumpvars` to enable traces, the same as with any Verilog simulator. See `examples/make_tracing_c` in the distribution.

2. 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()`.

       #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 `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 `--binary` or `--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?

1. Pass the `--trace` 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 `examples/make_tracing_c`. This will trace only the module containing the `$dumpvar`.

2. 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 `examples/make_tracing_sc/sc_main.cpp` file of the distribution, and below.

3. 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.

       #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 `verilated_vcd_sc.cpp` and `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 `--binary` or `--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 `--trace-fst` option to Verilator and either A. use `$dumpfile & $dumpvars` in Verilog as described in the VCD example above,

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

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

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

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

Currently, supporting FST and VCD in a single simulation is impossible, but such requirement should be rare. 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 (recommended), or Dinotrace (legacy) programs, or any of the many closed-source offerings; FST is supported only by GTKWave.

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

1. 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.

2. Add the `/*verilator tracing_off*/` metacomment to any very low-level modules you never want to trace (such as perhaps library cells).

3. Use the `--trace-depth` option to limit the tracing depth, for example `--trace-depth 1` to see only the top-level signals.

4. 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.

5. 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:

>     `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.

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

If you want the whole design parsed as Verilog 2001, see the `--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 controlled by `--assert` 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 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 `--exe` or `--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 Connecting to Verilated Models 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 `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 `--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 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 `--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 `/*verilator 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 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 `/*verilator 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:

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

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

>     #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.)