iverilog(1)

πŸ“¦
version 13.0 Β· 4 versions
, in alpine 3.24, arch rolling, epel 10, fedora 44, nixos 26.05, nixpkgs unstable, ubuntu stonking

πŸ’– iverilog β€” Icarus Verilog compiler πŸ’–

okay bestie, welcome to iverilog(1), Version 13.0 (stable) ✨ β€” this is the Icarus Verilog compiler, and honestly? she's a whole queen πŸ‘‘. Sit down, grab a strawberry πŸ“, and let's get into it.


✨ NAME ✨

iverilog β€” the Icarus Verilog compiler, aka the thing that turns your Verilog into something that actually runs πŸ¦‹


🌸 SYNOPSIS 🌸

iverilog [-EiRSuVv] [-Bpath] [-ccmdfile|-fcmdfile] [-Dmacro[=defn]]
[-Pparameter=value] [-pflag=value] [-dname] [-g1995|-g2001|-g2005
|-g2005-sv|-g2009|-g2012|-g<feature>] [-Iincludedir] [-Lmoduledir]
[-mmodule] [-M[mode=]file] [-Nfile] [-ooutputfilename] [-stopmodule]
[-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] [-lfile] sourcefile

πŸŽ€ DESCRIPTION πŸŽ€

okay so here's the tea β˜• β€” iverilog is a compiler that takes Verilog source code and translates it into executable programs for simulation, or into other netlist formats so you can keep processing it later. The main target is vvp for simulation. That's the vibe. That's the whole point. slay πŸ’…


πŸ‘‘ OPTIONS πŸ‘‘

iverilog accepts the following options β€” and yes bestie, we're going through ALL of them, no skipping, no cap 🫢

  • -Bbase β€” so the iverilog program leans on external programs and config files to preprocess and compile your Verilog. Normally the path it uses to find those tools is baked right into the iverilog program itself. BUT ✨ the -B switch lets you pick a whole different set of programs. The path you give is what it uses to locate ivlpp, ivl, the code generators, and the VPI modules.
  • -cfile, -ffile β€” these flags specify an input file that holds a list of Verilog source files. It's giving very much "command file of other Verilog simulators" energy β€” instead of passing file names on the command line, you put them in a file. See Command Files below πŸ‘‡
  • -Dmacro β€” defines macro with the string `1` as its definition. This form is normally only used to trigger ifdef conditionals in the Verilog source. simple, iconic, does the job πŸŽ€
  • -Dmacro=defn β€” defines macro as defn. that's it. that's the option πŸ’–
  • -Pparameter=value β€” overrides (i.e. defparam) a parameter in a root module. This lets you override, at compile time (defparam), a parameter in a root module instance. For example, -Pmain.foo=2 overrides the parameter foo in the root instance main with the value 2, and -Pmain.foos='"New string value"' will override the parameter foos in the root instance main with the value "New string value". look at her go 😭✨
  • -dname β€” activates a class of compiler debugging messages. You can use the -d switch as many times as you need to activate all the messages your heart desires. Supported names are scopes, eval_tree, elaborate, and synth2; any other names are just ignored. not me ignoring your typos πŸ’€
  • -E β€” preprocesses the Verilog source but does NOT compile it. The output file is the Verilog input, except with file inclusions and macro references expanded and removed. Super useful, like, for preprocessing Verilog source so other compilers can use it. ate πŸ’…
  • -g1995 | -g2001 | -g2001-noconfig | -g2005 | -g2005-sv | -g2009 | -g2012 β€” selects which Verilog language generation the compiler should support. This picks between IEEE1364-1995, IEEE1364-2001, IEEE1364-2005, IEEE1800-2005, IEEE1800-2009, or IEEE1800-2012. Icarus Verilog currently defaults to the IEEE1364-2005 generation of the language. This flag restricts the language to a set of keywords/features, which lets you simulate older Verilog code that might be using newer keywords, and keeps you compatible with other tools. Lowkey important: a lot of the IEEE1800 generations' functionality is not currently supported. The IEEE1800 generations do parse all the keywords though, so you can use them to verify that IEEE1364 compliant Verilog code isn't sneaking in any of the new IEEE1800 keywords. vibe check passed βœ…
  • -gverilog-ams | -gno-verilog-ams β€” enables or disables (default is disabled) support for Verilog-AMS. Heads up bestie: very little Verilog-AMS specific functionality is currently supported. πŸ™ˆ
  • -gassertions | -gsupported-assertions | -gno-assertions β€” enables (default) or disables SystemVerilog assertions. When enabled, assertion statements are elaborated. When disabled, assertion statements are parsed but ignored. The -gsupported-assertions option only enables assertions that are currently supported by the compiler. no fake promises, only supported ones πŸ’–
  • -gspecify | -gno-specify β€” enables or disables (default is disabled) specify block support. When enabled, specify block code is elaborated. When disabled, specify blocks are parsed but ignored. specify blocks are commonly not needed for RTL simulation, and in fact can hurt simulation performance. BUT β€” disabling specify blocks reduces the accuracy of full-timing simulations. so, like, pick your struggle 😭
  • -ginterconnect | -gno-interconnect β€” enables or disables (default is disabled) SDF interconnect support. When enabled, input and output buffers get added to modules so that VVP can add interconnection delays. This option is commonly not needed for RTL simulation, and in fact can hurt simulation performance. However, disabling interconnection delays reduces the accuracy of full-timing simulations. same energy as above fr fr 🌸
  • -gstd-include | -gno-std-include β€” enables (default) or disables the search of a standard installation include directory after all other explicit include directories. This standard include directory is a convenient place to install standard header files that a Verilog program might include. cute πŸŽ€
  • -grelative-include | -gno-relative-include β€” enables or disables (default is disabled) adding the local file's directory to the beginning of the include file search path. This lets files be included relative to the current file rather than the more common behaviour where files are only found in the working directory or in the specified include file search path. ✨
  • -gxtypes | -gno-xtypes β€” enables (default) or disables support for extended types. Enabling extended types allows for new types that Icarus Verilog supports as extensions beyond the baseline Verilog. You might need to disable extended types if you're compiling code that clashes with the few new keywords used to implement the type system. awkward 😬
  • -gio-range-error | -gno-io-range-error β€” the standards require that a vectored port have matching ranges for its port declaration as well as for any net/register declaration. It used to be common practice to only specify the range on the net/register declaration, and some tools still allow that. By default, any mismatch is reported as an error. Using -gno-io-range-error produces a warning instead of a fatal error for the case of a vectored net/register with a scalar port declaration. This warning is included in the anachronisms category. nostalgic but illegal, we love her 🫢
  • -gstrict-ca-eval | -gno-strict-ca-eval β€” the standard requires that if any input to a continuous assignment expression changes value, the entire expression is re-evaluated. By default, parts of the expression that don't depend on the changed input value(s) are not re-evaluated. If an expression contains a call to a function that doesn't depend solely on its input values, or that has side effects, the resulting behaviour will differ from what the standard requires. Using -gstrict-ca-eval forces standard compliant behaviour (with some loss in performance). performance vs correctness, the eternal battle πŸ’€
  • -gstrict-expr-width | -gno-strict-expr-width β€” enables or disables (default is disabled) strict compliance with the standard rules for determining expression bit lengths. When disabled, the RHS of a parameter assignment is evaluated as a lossless expression, as is any expression containing an unsized constant number, and unsized constant numbers are not truncated to integer width. iykyk πŸ’…
  • -gshared-loop-index | -gno-shared-loop-index β€” enables (default) or disables the exclusion of for-loop control variables from implicit event_expression lists. When enabled, if a for-loop control variable (loop index) is only used inside the for-loop statement, the compiler will not include it in an implicit event_expression list it calculates for that statement or for any enclosing statement. This lets the same control variable be used in multiple processes without the risk of an infinite loop caused by each process triggering all the other processes that use the same variable. For strict compliance with the standards, this behaviour should be disabled. not the infinite loop 😭
  • -gicarus-misc | -gno-icarus-misc β€” enables (default) or disables support for miscellaneous Icarus Verilog extensions. This includes the binary bitwise NAND and NOR operators, and allowing the binary arithmetic modulus operator to operate on real operands. quirky and valid 🌈
  • -Iincludedir β€” appends the directory includedir to the list of directories searched for Verilog include files. You can use the -I switch many times to specify several directories to search β€” the directories are searched in the order they appear on the command line. order matters bestie, always πŸŽ€
  • -i β€” ignores missing modules. Normally it's an error if a module instantiation refers to an undefined module. This option makes the compiler skip over that instantiation. It will also stop the compiler from returning an error if there are no top level modules. This lets the compiler be used to check incomplete designs for errors. wip designs deserve love too πŸ’–
  • -Lpath β€” this flag adds a directory to the path list used to locate VPI modules. The default path includes only the install directory for the system.vpi module, but this flag can add other directories. Multiple paths are allowed, and the paths will be searched in order. ✨
  • -lfile β€” adds the specified file to the list of source files to be compiled, but marks it as a library file. All modules contained within that file are treated as library modules, and only get elaborated if they're instantiated by other modules in the design. lazy elaboration, we respect it πŸ’…
  • -Mpath β€” this is equivalent to -Mall=path. Preserved for backwards compatibility. old but iconic πŸ‘‘

and bestie… we are SO not done, there's more coming πŸ¦‹βœ¨

  • -Mmode=path β€” bestie, this one writes a whole guest list πŸ“ into the file named by path: every file that contributes to compiling your design. What goes on the list depends on mode:
    • all or prefix β€” everything, the files pulled in by include directives, the ones library support auto-loads, and the ones you explicitly named yourself.
    • include β€” only the files that came in via include directives.
    • module β€” only the files you named yourself or that library support auto-loaded. The output is one file name per line, no leading or trailing space, so it's giving very tidy. And if mode is prefix, files from include directives get prefixed with "I " while the others get "M ". ✨
  • -mmodule β€” adds this module to the list of VPI modules that the simulation loads. You can stack as many as you want and they all load, in the exact order you specified. The system module is implicit, always included, and loaded last (she's the final boss πŸ‘‘). Now, if the name you give has at least one directory character in it, it's assumed to be prefixed by the path to the module; otherwise the compiler hunts for the module in the paths given by preceding -L options, and if it's not there, in the iverilog base directory.
  • -Npath β€” lowkey a compiler-internals thing, this one's for debugging the compiler proper. It dumps the final netlist form of your design to the specified file. Otherwise it does not affect how the compiler operates at all. The dump happens after the design is elaborated and optimized.
  • -o filename β€” puts the output in filename. If you don't say where, iverilog defaults to the name a.out. πŸ’…
  • -pflag=value β€” assigns a value to a target specific flag. You can use -p as many times as you need to set all the flags you want. Which flags exist depends on the target you picked, and they're documented in target specific docs. Any flag that isn't used just gets ignored, no drama. πŸ™ˆ
  • -S β€” Synthesize. Normally, if the target can accept behavioral descriptions, the compiler leaves processes in behavioral form. -S makes the compiler perform synthesis even when it isn't necessary for the target. But if the target type is a netlist format, -S is unnecessary and has zero effect, so don't bother.
  • -s topmodule β€” tells the compiler the top level module to elaborate. By default Icarus Verilog picks modules that aren't instantiated in any other modules, but sometimes that's not enough, or it grabs too many modules. If you specify one or more root modules with -s flags, those get used as the root modules instead. Periodt.
  • -Tmin|typ|max β€” use this to pick min, typ or max times out of min:typ:max expressions. Normally the compiler just uses the typ value from these expressions (and prints a warning for the first ten it finds 😭), but this switch tells the compiler explicitly which value to use. It also suppresses that "the compiler is making a choice" warning. Slay.
  • -ttarget β€” use this to specify the target output format. Peep the TARGETS section below for the list of valid output formats. πŸ”₯
  • -u β€” treats each source file as a separate compilation unit (as defined in SystemVerilog). If you're compiling for an IEEE1364 generation, this just resets all compiler directives (macro definitions included) before each new file gets processed.
  • -v β€” turns on verbose messages. It prints the command lines that get executed to do the actual compilation, along with version info from the various components and the version of the product as a whole. You'll notice those command lines include a reference to a key temporary file that passes info to the compiler proper. To stop that file from getting deleted at the end of the process, hand over a file name of your own in the environment variable IVERILOG_ICONFIG. Also, if the selected target is vvp, the -v switch gets appended to the shebang line in the compiler output file β€” so directly executing the compiler output file turns on verbose messages in vvp. You can dodge that extra verbosity by using the vvp command to indirectly execute the compiler output file. 🫢
  • -V β€” prints the version of the compiler, then exits. Short and iconic.
  • -R β€” prints the runtime paths of the compiler, then exits. πŸ’–
  • -Wclass β€” turns on different classes of warnings. See the WARNING TYPES section below for what each group means. If you use multiple -W switches, the warning set is the union of all the requested classes.
  • -ylibdir β€” appends the directory to the library module search path. When the compiler hits an undefined module, it looks in these directories for files with the right name. πŸ”
  • -Ysuffix β€” adds suffix to the list of accepted file name suffixes used when searching a library for cells. That list defaults to the single entry .v.

πŸ“š MODULE LIBRARIES πŸ“š

The Icarus Verilog compiler supports module libraries as directories that contain Verilog source files. During elaboration, the compiler notices when you instantiate undefined module types. If you've specified library search directories, the compiler searches the directory for files with the name of the missing module type. Find one? It loads it as a Verilog source file, then tries to elaborate the module again. Second time's the charm. ✨

Library module files should contain only a single module, but that's not a requirement. Library modules can reference other modules in the library or in the main design.


🎯 TARGETS 🎯

The Icarus Verilog compiler supports a whole variety of targets for different purposes, and the -t switch is how you select the one you want. The two fully supported targets are:

  • null β€” the null target generates no code at all. It's useful for checking the syntax of your Verilog source. Vibe check only, no output. πŸ’…
  • vvp β€” this is the default. The vvp target generates code for the vvp runtime. The output is a complete program that simulates the design but must be run by the vvp command. The -pfileline=1 option can be used to add procedural statement debugging opcodes to the generated code. Those opcodes are also used to generate file and line information for procedural warning/error messages. To enable the debug command tracing, use the trace command (trace on) from the vvp interactive prompt. πŸ”₯

For other available targets, see <https://steveicarus.github.io/iverilog/targets>


⚠️ WARNING TYPES ⚠️

These are the types of warnings that can be selected by the -W switch. All the warning types (other than all) can also be prefixed with no- to turn off that warning. This is most useful after a -Wall argument to suppress isolated warning types.

  • all β€” this enables the anachronisms, implicit, macro-replacement, portbind, select-range, timescale, and sensitivity-entire-array warning categories. The whole squad. πŸ‘‘
  • anachronisms β€” enables warnings for use of features that have been deprecated or removed in the selected generation of the Verilog language.
  • implicit β€” enables warnings for creation of implicit declarations. For example, if a scalar wire X is used but not declared in the Verilog source, this prints a warning at its first use. Not me finding out X was never declared 😭
  • macro-redefinition | macro-replacement β€” enables preprocessor warnings when a macro is being redefined. The first variant prints a warning any time a macro is redefined. The second variant only prints a warning if the macro text changes. Use no-macro-redefinition to turn off all warnings of this type.
  • portbind β€” enables warnings for ports of module instantiations that are not connected but probably should be. Dangling input ports, for example, will generate a warning. 🫢
  • select-range β€” enables warnings for constant out of bound selects. This includes partial or fully out of bound selects as well as a select containing a 'bx or 'bz in the index.
  • timescale β€” enables warnings for inconsistent use of the timescale directive. It detects if some modules have no timescale, or if modules inherit timescale from another file. Both probably mean timescales are inconsistent, and simulation timing can be confusing and dependent on compilation order. πŸŒ€
  • infloop β€” enables warnings for always statements that may have runtime infinite loops (has paths with no or zero delay). This class of warnings is not included in -Wall and hence does not have a no- variant. A fatal error message will always be printed when the compiler can determine that there will definitely be an infinite loop (all paths have no or zero delay).
When you suspect an always statement is producing a runtime infinite loop, use this flag to find the always statements that need their logic verified. It's expected that many of the warnings will be false positives, since the code treats the value of all variables and signals as indeterminate. πŸ’€
  • sensitivity-entire-vector β€” enables warnings for when a part select within an "always @*" statement results in the entire vector being added to the implicit sensitivity list. Although this behaviour is prescribed by the IEEE standard, it is not what might be expected and can have performance implications if the vector is large.
  • sensitivity-entire-array β€” enables warnings for when a word select within an "always @*" statement results in the entire array being added to the implicit sensitivity list. Although this behaviour is prescribed by the IEEE standard, it is not what might be expected and can have performance implications if the array is large. 🌈

✨ VPI MODULES ✨

okay so bestie, if a source file name ends in .vpi or .vpl, iverilog is like "oh that's not Verilog, that's a VPI module πŸ’…" and treats it accordingly. The user-supplied VPI modules get scanned so the compiler can figure out the return types of any system functions they provide β€” and that's literally required, because the compiler needs that info to elaborate expressions that have those system functions in them. The module path/name then gets passed along to the target, so the VPI module can be automatically loaded right at the start of simulation. ✨

VPI modules can also be handed over using the -L and -m options. 🫢


πŸŽ€ SYSTEM FUNCTION TABLE FILES [deprecated] πŸŽ€

if the source file name ends in .sft, it's taken to be a system function table file. This is the old way of telling the compiler the return types for system functions β€” like, the vintage method. Users are encouraged to switch to the new method, which is just… supplying the VPI module. Slay, honestly. 🌸

The format of the table is ASCII, one function per line. Empty lines are ignored, and any line that starts with the # character is a comment line. Every non-comment line starts with the function name, then the vpi type (i.e. vpiSysFuncReal). These are the supported types:

  • vpiSysFuncReal β€” the function returns a real/realtime value.
  • vpiSysFuncInt β€” the function returns an integer.
  • vpiSysFuncSized <wid> <signed|unsigned> β€” the function returns a vector with the given width, and it's signed or unsigned according to the flag.
  • vpiSysFuncString β€” the function returns a string. This one is an Icarus-specific extension, not available in the VPI standard. πŸ‘‘

πŸ“œ COMMAND FILES πŸ“œ

A command file is the vibe where you shove source file names and certain command line switches into a text file instead of dragging out one extremely long command line. Command files can include C or C++ style comments, plus # comments if the # starts the line. iconic.

  • file name β€” a simple file name or file path is taken to be the name of a Verilog source file. The path starts with the first non-whitespace character. Variables are substituted in file names.
  • -c cmdfile -f cmdfile β€” a -c or -f token prefixes a command file, exactly like it does on the command line. The cmdfile may be on the same line or the next non-comment line.
  • -l file -v file β€” a -l token prefixes a library file in the command file, exactly like it does on the command line. The parameter to the -l flag may be on the same line or the next non-comment line. -v is an alias for -l, provided for compatibility with other simulators. Variables in the file are substituted.
  • -y libdir β€” a -y token prefixes a library directory in the command file, exactly like it does on the command line. The parameter to the -y flag may be on the same line or the next non-comment line. Variables in the libdir are substituted.
  • +incdir+includedir β€” the +incdir+ token in command files gives directories to search for include files, in much the same way that -I flags work on the command line. The difference? Multiple +includedir directories are valid parameters to a single +incdir+ token β€” although you can also just have multiple +incdir+ lines. Variables in the includedir are substituted.
  • +libext+ext β€” the +libext token in command files lists file extensions to try when looking for a library file. This is useful in conjunction with -y flags, to list suffixes to try in each directory before moving on to the next library directory.
  • +libdir+dir β€” another way to specify library directories. See the -y flag.
  • +libdir-nocase+dir β€” this is like the +libdir statement, but file names inside the directories declared here are case insensitive. The missing module name in a lookup need not match the file name case, as long as the letters are correct. For example, "foo" matches "Foo.v" but not "bar.v".
  • +define+NAME=value β€” the +define+ token is the same as the -D option on the command line. The value part of the token is optional.
  • +parameter+NAME=value β€” the +parameter+ token is the same as the -P option on the command line.
  • +timescale+value β€” the +timescale+ token is used to set the default timescale for the simulation. This is the time units and precision before any `timescale directive, or after a `resetall directive. The default is 1s/1s.
  • +toupper-filename β€” this token causes file names after this point in the command file to be translated to uppercase. It helps with situations where a directory has passed through a DOS machine and, in the process, the file names become munged. πŸ’€
  • +tolower-filename β€” similar to the +toupper-filename hack described above.
  • +integer-width+value β€” this lets the programmer select the width for integer variables in the Verilog source. The default is 32, and the value can be any desired integer value.
  • +width-cap+value β€” this lets the programmer select the width cap for unsized expressions. If the calculated width for an unsized expression exceeds this value, the compiler will issue a warning and limit the expression width to this value.

πŸ¦‹ VARIABLES IN COMMAND FILES πŸ¦‹

In certain cases, iverilog supports variables in command files. These are strings of the form "$(varname)" or "${varname}", where varname is the name of the environment variable to read. The entire string gets replaced with the contents of that variable. Variables are only substituted in contexts that explicitly support them, including file and directory strings. ✨

ngl bestie, important detail: variable values come from the operating system environment, and not from preprocessor defines elsewhere in the file or the command line. 🫢

πŸ‘‘ PREDEFINED MACROS πŸ‘‘

The compiler predefines these macros for you:

  • __ICARUS__ = 1 β€” this is always defined when compiling with Icarus Verilog.
  • __ICARUS_SYNTH__ = 1 β€” this is defined when synthesis is enabled.
  • __VAMS_ENABLE__ = 1 β€” this is defined when Verilog-AMS is enabled.

🌈 ENVIRONMENT 🌈

iverilog also accepts some environment variables that control its behavior. These can be used to make semi-permanent changes β€” lowkey set it and forget it.

  • IVERILOG_ICONFIG=file-name β€” this sets the name used for the temporary file that passes parameters to the compiler proper, and prevents that file from being deleted after the compiler has exited.
  • IVERILOG_VPI_MODULE_PATH=/some/path:/some/other/path β€” this adds additional components to the VPI module search path. Paths specified this way are searched after paths specified with -L, but before the default search path. Multiple paths can be separated with colons (semicolons if you're on Windows).

⭐ EXAMPLES ⭐

These examples assume you have a Verilog source file called hello.v in the current directory.

To compile hello.v to an executable file called a.out:

iverilog hello.v

To compile hello.v to an executable file called hello:

iverilog -o hello hello.v

To compile and run explicitly using the vvp runtime:

iverilog -ohello.vvp -tvvp hello.v

πŸ’– AUTHOR πŸ’–

Steve Williams (steve@icarus.com) β€” the icon, the legend. 🫢


πŸŽ€ SEE ALSO πŸŽ€

vvp(1)

Tips on using, debugging, and developing the compiler can be found at:

https://steveicarus.github.io/iverilog/

Copyright Β© 2002-2026 Stephen Williams

This document can be freely redistributed according to the terms of the GNU General Public License version 2.0. periodt. πŸ’…


and that's the whole page bestie, no cap. this one's from Jan 13th, 2026 and it's the iverilog(1) manual β€” go compile something iconic βœ¨πŸ¦‹πŸ’œ