Verilating — Verilator Devel 5.031 documentation (2025)

Verilator may be used in five major ways:

  • With the --binary option, Verilator will translate the designinto an executable, via generating C++ and compiling it. SeeBinary, C++ and SystemC Generation.

  • With the --cc or --sc options, Verilator will translatethe design into C++ or SystemC code, respectively. See Binary, C++ and SystemC Generation.

  • With the --lint-only option, Verilator will lint the design tocheck for warnings but will not typically create any output files.

  • With the --xml-only option, Verilator will create XML outputthat may be used to feed into other user-designed tools. Seedocs/xml.rst in the distribution.

  • With the -E option, Verilator will preprocess the code accordingto IEEE preprocessing rules and write the output to standard out. Thisis useful to feed other tools and to debug how “`define” statements areexpanded.

Binary, C++ and SystemC Generation

Verilator will translate a SystemVerilog design into C++ with the--cc option, or into SystemC with the --sc option. Itwill translate into C++ and compile it into an executable binary with the--binary option.

When using these options:

  1. Verilator reads the input Verilog code and determines all “top modules”, thatis, modules or programs that are not used as instances under other cells.If --top-module is used, then that determines the top module, andall other top modules are removed; otherwise a MULTITOP warningis given.

  2. Verilator writes the C++/SystemC code to output files into the--Mdir option-specified directory, or defaults to “obj_dir”.The prefix is set with --prefix, or defaults to the name of thetop module.

  3. If --binary or --main is used, Verilator creates a C++top wrapper to read command line arguments, create the model, andexecute the model.

  4. If --binary or --exe is used, Verilator createsmakefiles to generate a simulation executable, otherwise, it createsmakefiles to generate an archive (.a) containing the objects.

  5. If --binary or --build is used, it calls GNU Make or CMake to build the model.

Once a model is built, the next step is typically for the user to run it,see Simulating (Verilated-Model Runtime).

Hierarchical Verilation

Large designs may take long (e.g., 10+ minutes) and huge memory (e.g., 100+GB) to Verilate. In hierarchical mode, the user manually selects somelarge lower-level hierarchy blocks to separate from the larger design. Forexample, a core may be the hierarchy block separated out of a multi-coreSoC design.

Verilator is run in hierarchical mode on the whole SoC. Verilator willmake two models, one for the CPU hierarchy block and one for the SoC. TheVerilated code for the SoC will automatically call the CPU Verilated model.

The current hierarchical Verilation is based on --lib-create. Eachhierarchy block is Verilated into a library. User modules of the hierarchyblocks will see a tiny wrapper generated by --lib-create.

Usage

Users need to mark one or more moderate-size modules as hierarchy block(s).There are two ways to mark a module:

  • Write /*verilatorhier_block*/ metacomment in HDL code.

  • Add a hier_block line in the Configuration Files.

Then pass the --hierarchical option to Verilator.

The compilation is the same as when not using hierarchical mode.

make -C obj_dir -f Vtop_module_name.mk

Limitations

Hierarchy blocks have some limitations, including:

  • The hierarchy block cannot be accessed using dot (.) from the uppermodule(s) or other hierarchy blocks.

  • Signals in the block cannot be traced.

  • Modport cannot be used at the hierarchical block boundary.

  • The simulation speed is likely not as fast as flat Verilation, in whichall modules are globally scheduled.

  • Generated clocks may not work correctly if generated in the hierarchicalmodel and passed into another hierarchical model or the top module.

  • Delays are not allowed in hierarchy blocks.

But, the following usage is supported:

  • Nested hierarchy blocks. A hierarchy block may instantiate otherhierarchy blocks.

  • Parameterized hierarchy block. Parameters of a hierarchy block can beoverridden using #(.param_name(value)) construct.

Overlapping Verilation and Compilation

Verilator needs to run 2 + N times in hierarchical Verilation, where Nis the number of hierarchy blocks. One of the two is for the top module,which refers to the wrappers of all other hierarchy blocks. The second of thetwo is the initial run that searches modules marked with/*verilatorhier_block*/ metacomment and creates a plan andwrite in prefix_hier.mk. This initial run internally invokesother N + 1 runs, so you don’t have to care about these N + 1 times ofrun. The additional N is the Verilator run for each hierarchical block.

If :-j {jobs} option is specified, Verilation for hierarchyblocks runs in parallel.

If --build option is specified, C++ compilation also runs as soonas a hierarchy block is Verilated. C++ compilation and Verilation for otherhierarchy blocks run simultaneously.

Cross Compilation

Verilator supports cross-compiling Verilated code. This is generally usedto run Verilator on a Linux system and produce C++ code that is then compiledon Windows.

Cross-compilation involves up to three different OSes. The build system iswhere you configure and compile Verilator, the host system is where you runVerilator, and the target system is where you compile the Verilated codeand run the simulation.

Verilator requires the build and host system types to be thesame, though the target system type may be different. To support this,./configure and make Verilator on the build system. Then, runVerilator on the host system. Finally, the output of Verilator may becompiled on the different target system.

To support this, none of the files that Verilator produces will referenceany configure-generated build-system-specific files, such asconfig.h (which is renamed in Verilator to config_package.hto reduce confusion.) The disadvantage of this approach is thatinclude/verilatedos.h must self-detect the requirements of thetarget system, rather than using configure.

The target system may also require edits to the Makefiles, the simpleMakefiles produced by Verilator presume the target system is the same typeas the build system.

Multithreading

Verilator supports multithreaded simulation models.

With --threads 1, the generated model issingle-threaded; however, the support libraries are multithread safe. Thisallows different instantiations of the model(s) to potentially each be rununder a different thread. All threading is the responsibility of the user’sC++ testbench.

With --threads {N}, where N is at least 2, thegenerated model will be designed to run in parallel on N threads. Thethread calling eval() provides one of those threads, and the generatedmodel will create and manage the other N-1 threads. It’s the client’sresponsibility not to oversubscribe the available CPU cores. Under CPUoversubscription, the Verilated model should not livelock nor deadlock;however, you can expect performance to be far worse than it would be withthe proper ratio of threads and CPU cores.

The thread used for constructing a model must be the same thread that callseval() into the model; this is called the “eval thread”. The threadused to perform certain global operations, such as saving and tracing, mustbe done by a “main thread”. In most cases, the eval thread and main threadare the same thread (i.e. the user’s top C++ testbench runs on a singlethread), but this is not required.

When making frequent use of DPI imported functions in a multithreadedmodel, it may be beneficial to performance to adjust the--instr-count-dpi option based on some experimentation. Thisinfluences the partitioning of the model by adjusting the assumed executiontime of DPI imports.

When using --trace to perform VCD tracing, the VCD traceconstruction is parallelized using the same number of threads as specifiedwith --threads, and is executed on the same thread pool as the model.

The --trace-threads options can be used with --trace-fstto offload FST tracing using multiple threads. If --trace-threads isgiven without --threads, then --trace-threads will imply--threads 1, i.e., the support libraries will bethread safe.

With --trace-threads 0, trace dumps are producedon the main thread. This again gives the highest single-thread performance.

With --trace-threads {N}, where N is at least 1,up to N additional threads will be created and managed by the trace files(e.g., VerilatedFstC), to offload construction of the trace dump. The mainthread will be released to proceed with execution as soon as possible, thoughsome main thread blocking is still necessary while capturing thetrace. FST tracing can utilize up to 2 offload threads, so there is no useof setting --trace-threads higher than 2 at the moment.

When running a multithreaded model, the default Linux task scheduler oftenworks against the model by assuming short-lived threads and thusit often schedules threads using multiple hyperthreads within the samephysical core. For best performance, use the numactl program to(when the threading count fits) select unique physical cores on the samesocket. The same applies for --trace-threads as well.

As an example, if a model was Verilated with--threads 4, we consult:

egrep 'processor|physical id|core id' /proc/cpuinfo

To select cores 0, 1, 2, and 3 that are all located on the same socket (0)but have different physical cores. (Also useful isnumactl --hardware, or lscpu, but those don’t showhyperthreading cores.) Then we execute:

numactl -m 0 -C 0,1,2,3 -- verilated_executable_name

This will limit memory to socket 0, and threads to cores 0, 1, 2, 3,(presumably on socket 0), optimizing performance. Of course, this must beadjusted if you want another simulator to use, e.g., socket 1, or if youVerilated with a different number of threads. To see what CPUs areactually used, use --prof-exec.

Multithreaded Verilog and Library Support

$display/$stop/$finish are delayed until the end of an eval() callto maintain ordering between threads. This may result in additional taskscompleting after the $stop or $finish.

If using --coverage, the coverage routines are fully thread-safe.

If using the DPI, Verilator assumes pure DPI imports are thread-safe,balancing performance versus safety. See --threads-dpi.

If using --savable, the save/restore classes are not multithreadedand must be called only by the eval thread.

If using --sc, the SystemC kernel is not thread-safe; therefore,the eval thread and main thread must be the same.

If using --trace, the tracing classes must be constructed andcalled from the main thread.

If using --vpi, since SystemVerilog VPI was not architected byIEEE to be multithreaded, Verilator requires all VPI calls are only madefrom the main thread.

GNU Make

Verilator defaults to creating GNU Make makefiles for the model. Verilatorwill call make automatically when the --build option is used.

If calling Verilator from a makefile, the --MMD option will createa dependency file, allowing Make to only run Verilator if input Verilogfiles change.

CMake

Verilator can be run using CMake, which takes care of both runningVerilator and compiling the output. There is a CMake example in theexamples/ directory. The following is a minimal CMakeLists.txt thatwould build the code listed in Example C++ Execution

project(cmake_example)find_package(verilator HINTS $ENV{VERILATOR_ROOT})add_executable(Vour sim_main.cpp)verilate(Vour SOURCES our.v)

find_package will automatically find an installed copy ofVerilator, or use a local build if VERILATOR_ROOT is set.

Using CMake >= 3.12 and the Ninja generator is recommended, though othercombinations should work. To build with CMake, change to the foldercontaining CMakeLists.txt and run:

mkdir buildcd buildcmake -GNinja ..ninja

Or to build with your system default generator:

mkdir buildcd buildcmake ..cmake --build .

If you’re building the example, you should have an executable to run:

./Vour

The package sets the CMake variables verilator_FOUND, VERILATOR_ROOT,and VERILATOR_BIN to the appropriate values and creates a verilate()function. verilate() will automatically create custom commands to runVerilator and add the generated C++ sources to the target specified.

Verilate in CMake

verilate(target SOURCES source ... [TOP_MODULE top] [PREFIX name] [TRACE] [TRACE_FST] [SYSTEMC] [COVERAGE] [INCLUDE_DIRS dir ...] [OPT_SLOW ...] [OPT_FAST ...] [OPT_GLOBAL ..] [DIRECTORY dir] [THREADS num] [TRACE_THREADS num] [VERILATOR_ARGS ...])

Lowercase and … should be replaced with arguments; the uppercase partsdelimit the arguments and can be passed in any order or left out entirelyif optional.

verilate(target …) can be called multiple times to add other Verilogmodules to an executable or library target.

When generating Verilated SystemC sources, you should list theSystemC include directories and link to the SystemC libraries.

target

Name of a target created by add_executable or add_library.

COVERAGE

Optional. Enables coverage if present, equivalent to “VERILATOR_ARGS–coverage”.

DIRECTORY

Optional. Set the verilator output directory. It is preferable to usethe default, which will avoid collisions with other files.

INCLUDE_DIRS

Optional. Sets directories that Verilator searches (same as -y).

OPT_SLOW

Optional. Set compiler options for the slow path. You may want to reducethe optimization level to improve compile times with large designs.

OPT_FAST

Optional. Set compiler options for the fast path.

OPT_GLOBAL

Optional. Set compiler options for the common runtime library used byVerilated models.

PREFIX

Optional. Sets the Verilator output prefix. Defaults to the name of thefirst source file with a “V” prepended. It must be unique in each callto verilate(), so this is necessary if you build a module multiple timeswith different parameters. It must be a valid C++ identifier, i.e., itcontains no white space and only characters A-Z, a-z, 0-9 or _.

SOURCES

List of Verilog files to Verilate. You must provide at least one file.

SYSTEMC

Optional. Enables SystemC mode, defaults to C++ if not specified.

When using Accellera’s SystemC with CMake support, a CMake target isavailable that simplifies the SystemC steps. This will only work ifCMake can find the SystemC installation, and this can be configured bysetting the CMAKE_PREFIX_PATH variable during CMake configuration.

Don’t forget to set the same C++ standard for the Verilated sources asthe SystemC library. This can be specified using the SYSTEMC_CXX_FLAGSenvironment variable.

THREADS

Optional. Enable a multithreaded model; see --threads.

TRACE_THREADS

Optional. Enable multithreaded FST trace; see --trace-threads.

TOP_MODULE

Optional. Sets the name of the top module. Defaults to the name of thefirst file in the SOURCES array.

TRACE

Optional. Enables VCD tracing if present, equivalent to “VERILATOR_ARGS–trace”.

TRACE_FST

Optional. Enables FST tracing if present, equivalent to “VERILATOR_ARGS–trace-fst”.

VERILATOR_ARGS

Optional. Extra arguments to Verilator. Do not specify --Mdiror --prefix here; use DIRECTORY or PREFIX.

SystemC Link in CMake

Verilator’s CMake support provides a convenience function to automaticallyfind and link to the SystemC library. It can be used as:

verilator_link_systemc(target)

where target is the name of your target.

The search paths can be configured by setting some variables:

SYSTEMC_INCLUDE

Sets the direct path to the SystemC includes.

SYSTEMC_LIBDIR

Sets the direct path to the SystemC libraries.

SYSTEMC_ROOT

Sets the installation prefix of an installed SystemC library.

SYSTEMC

Sets the installation prefix of an installed SystemC library. (Same asSYSTEMC_ROOT).

Verilation Summary Report

When Verilator generates code, unless --quiet-stats is used, itwill print a report to stdout summarizing the build. For example:

- V e r i l a t i o n R e p o r t: Verilator ....- Verilator: Built from 354 MB sources in 247 modules, into 74 MB in 89 C++ files needing 0.192 MB- Verilator: Walltime 26.580 s (elab=2.096, cvt=18.268, bld=2.100); cpu 26.548 s on 1 threads; alloced 2894.672 MB

The information in this report is:

"Verilator ..."

Program version.

"234 MB sources"

Characters of post-preprocessed text in all inputVerilog and Verilator Control files in megabytes.

"247 modules"

Number of interfaces/modules/classes/packages in design beforeelaboration.

"into 74 MB"

Characters of output C++ code, including comments in megabytes.

"89 C++ files"

Number of .cpp files created.

"needing 192MB"

Verilation-time minimum-bound estimate of memory needed to run model inmegabytes. (Expect to need significantly more.)

"Walltime 26.580 s"

Real elapsed wall time for Verilation and build.

"elab=2.096"

Wall time to read in files and complete elaboration.

"cvt=18.268"

Wall time for Verilator to process and write output.

"bld=2.1"

Wall time to compile gcc/clang (if using --build).

"cpu 22.548 s"

CPU time used, total across all CPU threads.

"4 threads"

Number of simultaneous threads used.

"alloced 123 MB"

Total memory used during build by Verilator executable (excludes--build compiler’s usage) in megabytes.

Verilating — Verilator Devel 5.031 documentation (2025)

References

Top Articles
Latest Posts
Recommended Articles
Article information

Author: Trent Wehner

Last Updated:

Views: 5987

Rating: 4.6 / 5 (76 voted)

Reviews: 91% of readers found this page helpful

Author information

Name: Trent Wehner

Birthday: 1993-03-14

Address: 872 Kevin Squares, New Codyville, AK 01785-0416

Phone: +18698800304764

Job: Senior Farming Developer

Hobby: Paintball, Calligraphy, Hunting, Flying disc, Lapidary, Rafting, Inline skating

Introduction: My name is Trent Wehner, I am a talented, brainy, zealous, light, funny, gleaming, attractive person who loves writing and wants to share my knowledge and understanding with you.