Language Extensions

The following additional constructs are the extensions Verilator supports on top of standard Verilog code. Using these features outside of comments or “ifdef“‘s may break other tools.

`__FILE__

The `__FILE__ define expands to the current filename as a string, like C++’s __FILE__. This Verilator feature added in 2006 was incorporated into the IEEE 1800-2009 standard.

`__LINE__

The `__LINE__ define expands to the current filename as a string, like C++’s __LINE__. This Verilator feature added in 2006 was incorporated into the IEEE 1800-2009 standard.

`error [string]

This will report an error when encountered, like C++’s #error.

$c([string], ...);

The string will be embedded directly in the output C++ code at the point where the surrounding Verilog code is compiled. It may either be a standalone statement (with a trailing ; in the string), or a function that returns up to a 32-bit number (without a trailing ;). This can be used to call C++ functions from your Verilog code.

String arguments will be put directly into the output C++ code, except the word ‘this’ (i.e.: the object pointer) might be replaced with a different pointer as Verilator might implement logic with non-member functions. For this reason, any references to class members must be made via an explicit ‘this->’ pointer dereference.

Expression arguments will have the code to evaluate the expression inserted. Thus to call a C++ function, $c("func(",a,")") will result in func(a) in the output C++ code. For input arguments, rather than hard-coding variable names in the string $c("func(a)"), instead pass the variable as an expression :$c("func(",a,")"). This will allow the call to work inside Verilog functions where the variable is flattened out, and also enable other optimizations.

If you will be reading or writing any Verilog variables inside the C++ functions, the Verilog signals must be declared with /*verilator public*/ metacomments.

You may also append an arbitrary number to $c, generally the width of the output; signal_32_bits = $c32("...");. This allows for compatibility with other simulators which require a differently named PLI function name for each different output width.

$display, $write, $fdisplay, $fwrite, $sformat, $swrite

Format arguments may use C fprintf sizes after the % escape. Per the Verilog standard, %x prints a number with the natural width, and %0x prints a number with minimum width. Verilator extends this so %5x prints 5 digits per the C standard (this is unspecified in Verilog, but was incorporated into the 1800-2009).

`coverage_block_off

Specifies the entire begin/end block should be ignored for coverage analysis. Must be inside a code block, e.g. within a begin/end pair. Same as coverage_block_off in Configuration Files.

`systemc_header

Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the output .h file’s header. Must be placed as a module item, e.g. directly inside a module/endmodule pair. Despite the name of this macro, this also works in pure C++ code.

`systemc_ctor

Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the C++ class constructor. Must be placed as a module item, e.g. directly inside a module/endmodule pair. Despite the name of this macro, this also works in pure C++ code.

`systemc_dtor

Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the C++ class destructor. Must be placed as a module item, e.g. directly inside a module/endmodule pair. Despite the name of this macro, this also works in pure C++ code.

`systemc_interface

Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the C++ class interface. Must be placed as a module item, e.g. directly inside a module/endmodule pair. Despite the name of this macro, this also works in pure C++ code.

`systemc_imp_header

Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into the header of all files for this C++ class implementation. Must be placed as a module item, e.g. directly inside a module/endmodule pair. Despite the name of this macro, this also works in pure C++ code.

`systemc_implementation

Take remaining text up to the next `verilog or `systemc_... mode switch and place it verbatim into a single file of the C++ class implementation. Must be placed as a module item, e.g. directly inside a module/endmodule pair. Despite the name of this macro, this also works in pure C++ code.

If you will be reading or writing any Verilog variables in the C++ functions, the Verilog signals must be declared with a /*verilator public*/ metacomment. See also the public task feature; writing an accessor may result in cleaner code.

`SYSTEMVERILOG

The SYSTEMVERILOG, SV_COV_START and related standard defines are set by default when --language is “1800-*”.

`VERILATOR
`verilator
`verilator3

The VERILATOR, verilator and verilator3 defines are set by default so you may “`ifdef” around tool specific constructs.

`verilator_config

Take remaining text up to the next `verilog mode switch and treat it as Verilator configuration commands. See Configuration Files.

`verilog

Switch back to processing Verilog code after a `systemc_... mode switch. The Verilog code returns to the last language mode specified with “`begin_keywords”, or SystemVerilog if none was specified.

/*verilator clock_enable*/

Used after a signal declaration to indicate the signal is used to gate a clock, and the user takes responsibility for insuring there are no races related to it. (Typically by adding a latch, and running static timing analysis.) For example:

reg enable_r /*verilator clock_enable*/;
wire gated_clk = clk & enable_r;
always_ff @(posedge clk)
   enable_r <= enable_early;

The clock_enable attribute will cause the clock gate to be ignored in the scheduling algorithm, sometimes required for correct clock behavior, and always improving performance. It’s also a good idea to enable the IMPERFECTSCH warning, to ensure all clock enables are properly recognized.

Same as clock_enable configuration file option.

/*verilator clocker*/
/*verilator no_clocker*/

Used after a signal declaration to indicate the signal is used as clock or not. This information is used by Verilator to mark the signal as clocker and propagate the clocker attribute automatically to derived signals. See --clk.

Same as clocker and no_clocker in configuration files.

/*verilator coverage_block_off*/

Specifies the entire begin/end block should be ignored for coverage analysis purposes.

Same as coverage_block_off configuration file option.

/*verilator coverage_off*/

Specifies that following lines of code should have coverage disabled. Often used to ignore an entire module for coverage analysis purposes.

/*verilator coverage_on*/

Specifies that following lines of code should have coverage re-enabled (if appropriate --coverage flags are passed) after being disabled earlier with /*verilator coverage_off*/.

/*verilator hier_block*/

Specifies that the module is a unit of hierarchical Verilation. This metacomment must be between module module_name(...); and endmodule. The module will not be inlined nor uniquified for each instance in hierarchical Verilation. Note that the metacomment is ignored unless the --hierarchical option is specified.

See Hierarchical Verilation.

/*verilator inline_module*/

Specifies the module the comment appears in may be inlined into any modules that use this module. This is useful to speed up simulation runtime. Note if using --public that signals under inlined submodules will be named {submodule}__DOT__{subsignal} as C++ does not allow “.” in signal names.

Same as inline configuration file option.

/*verilator isolate_assignments*/

Used after a signal declaration to indicate the assignments to this signal in any blocks should be isolated into new blocks. When there is a large combinatorial block that is resulting in an UNOPTFLAT warning, attaching this to the signal causing a false loop may clear up the problem.

IE, with the following:

reg splitme /* verilator isolate_assignments*/;
// Note the placement of the semicolon above
always_comb begin
  if (....) begin
     splitme = ....;
     other assignments
  end
end

Verilator will internally split the block that assigns to “splitme” into two blocks:

It would then internally break it into (sort of):

// All assignments excluding those to splitme
always_comb begin
  if (....) begin
     other assignments
  end
end
// All assignments to splitme
always_comb begin
  if (....) begin
     splitme = ....;
  end
end

Same as isolate_assignments configuration file option.

/*verilator lint_off <msg>*/

Disable the specified warning message for any warnings following the comment.

/*verilator lint_on <msg>*/

Re-enable the specified warning message for any warnings following the comment.

/*verilator lint_restore*/

After a /*verilator lint_save*/, pop the stack containing lint message state. Often this is useful at the bottom of include files.

/*verilator lint_save*/

Push the current state of what lint messages are turned on or turned off to a stack. Later meta-comments may then lint_on or lint_off specific messages, then return to the earlier message state by using /*verilator lint_restore*/. For example:

// verilator lint_save
// verilator lint_off WIDTH
...  // code needing WIDTH turned off
// verilator lint_restore

If WIDTH was on before the lint_off, it will now be restored to on, and if it was off before the lint_off it will remain off.

/*verilator no_inline_module*/

Specifies the module the comment appears in should not be inlined into any modules that use this module.

Same as no_inline configuration file option.

/*verilator no_inline_task*/

Used in a function or task variable definition section to specify the function or task should not be inlined into where it is used. This may reduce the size of the final executable when a task is used a very large number of times. For this flag to work, the task and tasks below it must be pure; they cannot reference any variables outside the task itself.

Same as no_inline configuration file option.

/*verilator public*/ (on parameter)

Used after a parameter declaration to indicate the emitted C code should have the parameter values visible. Due to C++ language restrictions, this may only be used on 64-bit or narrower integral enumerations.

parameter [2:0] PARAM /*verilator public*/ = 2'b0;
/*verilator public*/ (on typedef enum)

Used after an enum typedef declaration to indicate the emitted C code should have the enum values visible. Due to C++ language restrictions, this may only be used on 64-bit or narrower integral enumerations.

typedef enum logic [2:0] { ZERO = 3'b0 } pub_t /*verilator public*/;
/*verilator public*/ (on variable)

Used after an input, output, register, or wire declaration to indicate the signal should be declared so that C code may read or write the value of the signal. This will also declare this module public, otherwise use /*verilator public_flat*/.

Instead of using public variables, consider instead making a DPI or public function that accesses the variable. This is nicer as it provides an obvious entry point that is also compatible across simulators.

Same as public configuration file option.

/*verilator public*/ (on task/function)

Used inside the declaration section of a function or task declaration to indicate the function or task should be made into a C++ function, public to outside callers. Public tasks will be declared as a void C++ function, public functions will get the appropriate non-void (bool, uint32_t, etc) return type. Any input arguments will become C++ arguments to the function. Any output arguments will become C++ reference arguments. Any local registers/integers will become function automatic variables on the stack.

Wide variables over 64 bits cannot be function returns, to avoid exposing complexities. However, wide variables can be input/outputs; they will be passed as references to an array of 32-bit numbers.

Generally, only the values of stored state (flops) should be written, as the model will NOT notice changes made to variables in these functions. (Same as when a signal is declared public.)

You may want to use DPI exports instead, as it’s compatible with other simulators.

Same as public configuration file option.

/*verilator public_flat*/ (on variable)

Used after an input, output, register, or wire declaration to indicate the signal should be declared so that C code may read or write the value of the signal. This will not declare this module public, which means the name of the signal or path to it may change based upon the module inlining which takes place.

Same as public_flat configuration file option.

/*verilator public_flat_rd*/ (on variable)

Used after an input, output, register, or wire declaration to indicate the signal should be declared public_flat (see above), but read-only.

Same as public_flat_rd configuration file option.

/*verilator public_flat_rw @(<edge_list>)*/ (on variable)

Used after an input, output, register, or wire declaration to indicate the signal should be declared public_flat_rd (see above), and also writable, where writes should be considered to have the timing specified by the given sensitivity edge list. Set for all variables, ports and wires using the --public-flat-rw option.

Same as public_flat_rw configuration file option.

/*verilator public_module*/

Used after a module statement to indicate the module should not be inlined (unless specifically requested) so that C code may access the module. Verilator automatically sets this attribute when the module contains any public signals or `systemc_ directives. Also set for all modules when using the --public option.

Same as public configuration file option.

/*verilator sc_clock*/

Deprecated and ignored. Previously used after an input declaration to indicate the signal should be declared in SystemC as a sc_clock instead of a bool. This was needed in SystemC 1.1 and 1.2 only; versions 2.0 and later do not require clock pins to be sc_clocks and this is no longer needed and is ignored.

/*verilator sc_bv*/

Used after a port declaration. It sets the port to be of sc_bv<{width}> type, instead of bool, vluint32_t or vluint64_t. This may be useful if the port width is parameterized and the instantiating C++ code wants to always have a sc_bv so it can accept any width. In general you should avoid using this attribute when not necessary as with increasing usage of sc_bv the performance decreases significantly.

Same as sc_bv configuration file option.

/*verilator sformat*/

Attached to the final argument of type “input string” of a function or task to indicate the function or task should pass all remaining arguments through $sformatf. This allows creation of DPI functions with $display like behavior. See the test_regress/t/t_dpi_display.v file for an example.

Same as sformat configuration file option.

/*verilator split_var*/

Attached to a variable or a net declaration to break the variable into multiple pieces typically to resolve UNOPTFLAT performance issues. Typically the variables to attach this to are recommended by Verilator itself, see UNOPTFLAT.

For example, Verilator will internally convert a variable with the metacomment such as:

logic [7:0] x [0:1]  /*verilator split_var*/;

To:

logic [7:0] x__BRA__0__KET__ /*verilator split_var*/;
logic [7:0] x__BRA__1__KET__ /*verilator split_var*/;

Note that the generated packed variables retain the split_var metacomment because they may be split into further smaller pieces according to the access patterns.

This only supports unpacked arrays, packed arrays, and packed structs of integer types (reg, logic, bit, byte, int…); otherwise if a split was requested but cannot occur a SPLITVAR warning is issued. Splitting large arrays may slow down the Verilation speed, so use this only on variables that require it.

Same as split_var configuration file option.

/*verilator tag <text...>*/

Attached after a variable or structure member to indicate opaque (to Verilator) text that should be passed through to the XML output as a tag, for use by downstream applications.

/*verilator tracing_off*/

Disable waveform tracing for all future signals that are declared in this module, or instances below this module. Often this is placed just after a primitive’s module statement, so that the entire module and instances below it are not traced.

/*verilator tracing_on*/

Re-enable waveform tracing for all future signals or instances that are declared.