Merge branch 'verilator:master' into fix/broken-varscope-linkable

This commit is contained in:
Matthew Ballance 2025-12-21 14:03:43 -08:00 committed by GitHub
commit 52ae3d0767
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
316 changed files with 2666 additions and 1745 deletions

View File

@ -1,3 +1,4 @@
---
# See https://citation-file-format.github.io/
cff-version: 1.2.0
title: Verilator
@ -14,14 +15,14 @@ authors:
family-names: Wasson
- given-names: Duane
family-names: Galbi
- given-names: Geza
family-names: Lore
- name: 'et al'
repository-code: 'https://github.com/verilator/verilator'
url: 'https://verilator.org'
abstract: >-
The Verilator package converts Verilog and SystemVerilog hardware
description language (HDL) designs into a fast C++ or SystemC model
that, after compiling, can be executed. Verilator is not a
that, after compiling, can be executed. Verilator is not only a
traditional simulator but a compiler.
license:
- LGPL-3.0-only
- Artistic-2.0
license: [LGPL-3.0-only, Artistic-2.0]

13
Changes
View File

@ -44,6 +44,7 @@ Verilator 5.043 devel
* Support general global constraints (#6709) (#6711). [Yilou Wang]
* Support complex std::randomize patterns (#6736) (#6737). [Yilou Wang]
* Support `rand_mode` in global constraint gathering (#6740) (#6752). [Yilou Wang]
* Support reduction or in constraints (#6840). [Pawel Kojma, Antmicro Ltd.]
* Optimize away calls to empty functions (#6626). [Geza Lore]
* Optimize redundant headers in Syms implementation files. [Geza Lore, Fractile Ltd.]
* Optimize constructor/destructor VerilatedModules (#6660). [Geza Lore, Fractile Ltd.]
@ -56,6 +57,7 @@ Verilator 5.043 devel
* Fix generate function(s) inside of generate blocks (#1011) (#6789). [em2machine]
* Fix typedef derived from type defined inside interface (#3441) (#6776). [em2machine]
* Fix extern function that returns parameterized class (#4924).
* Fix type deduction for variable parameterized classes (#6281) (#6813). [em2machine]
* Fix randomize called within func/task (#6144) (#6753). [Yilou Wang]
* Fix pre/post_randomize on extended classes (#6467). [Alex Solomatnikov]
* Fix expression short circuiting (#6483). [Todd Strader]
@ -92,7 +94,8 @@ Verilator 5.043 devel
* Fix fork scheduling semantics (#6730). [Artur Bieniek, Antmicro Ltd.]
* Fix internal fault when cross-class calling with DPI (#6735) (#6742). [Matthew Ballance]
* Fix write variable placement for global constraints (#6740) (#6750) (#6797). [Yilou Wang]
* Fix resolution of specialized typedefs (#6754) (#6808). [em2machine]
* Fix JSON dump missing output ports (#6751) (#6831). [Oleh Maksymenko]
* Fix resolution of specialized typedefs (#6754) (#6808) (#6834). [em2machine]
* Fix UNSUPPORTED on force / release with complex selects (#6755). [Ryszard Rozak, Antmicro Ltd.]
* Fix select assignment expansion (#6757). [Geza Lore]
* Fix `--lib-create` with multi-bit clocks (#6759). [Geza Lore]
@ -108,9 +111,14 @@ Verilator 5.043 devel
* Fix `disable iff` in simple properties (#6783). [Ryszard Rozak, Antmicro Ltd.]
* Fix input sampling of clocking block signals (#6788). [Pawel Kojma, Antmicro Ltd.]
* Fix O(n*2) analysis in const-bit-op-tree (#6791). [Geza Lore]
* Fix nested struct within parameter port list (#6818) (#6824). [Luca Colagrande]
* Fix member select of variable without randmode (#6800) (#6833). [Yilou Wang]
* Fix duplicate name error with interface initial blocks (#6804) (#6805). [Thomas Dybdahl Ahle]
* Fix nested struct within parameter port list (#6818) (#6824). [Luca Colagrande]
* Fix setting thread count in VerilatedContext (#6826 partial) (#6841). [Yangyu Chen]
* Fix firing array selects of events (#6829). [Amal Araweelo Almis]
* Fix false IMPLICITSTATIC on localparam (#6835). [Geza Lore]
* Fix randcase under fork (#6843). [Amal Araweelo Almis]
* Fix JSON missing `signed` indication (#6845).
Verilator 5.042 2025-11-02
@ -551,6 +559,7 @@ Verilator 5.034 2025-02-24
* Optimize labels as final `if` block statements (#5744).
* Optimize empty function definition bodies (#5750).
* Optimize splitting trigger computation and dump (#5798). [Geza Lore]
* Optimize some DFG multiplexers (#6822). [Yangyu Chen]
* Fix error message when call task as a function (#3089). [Matthew Ballance]
* Fix force VPI public signal visibility (#5225). [Frédéric Requin]
* Fix VPI iteration over hierarchy (#5314) (#5731). [Natan Kreimer]

View File

@ -541,6 +541,7 @@ YAML_FILES = \
.*.yml \
.github/*.yml \
.github/*/*.yml \
CITATION.cff \
######################################################################
# Format

View File

@ -408,6 +408,8 @@ detailed descriptions of these arguments.
-I<dir> Directory to search for includes
--if-depth <value> Tune IFDEPTH warning
+incdir+<dir> Directory to search for includes
--inline-cfuncs <value> Inline CFuncs with <=value nodes (0=off)
--inline-cfuncs-product <value> Inline CFuncs if size*calls <= value
--inline-mult <value> Tune module inlining
--instr-count-dpi <value> Assumed dynamic instruction count of DPI imports
-j <jobs> Parallelism for --build-jobs/--verilate-jobs

View File

@ -125,6 +125,7 @@ John Wehle
Jonathan Drolet
Jonathan Schröter
Jordan McConnon
Jose Drowne
Jose Loyola
Josep Sans
Joseph Nwabueze
@ -233,6 +234,7 @@ Steven Hugg
Szymon Gizler
Sören Tempel
Teng Huang
Thomas Aldrian
Thomas Dybdahl Ahle
Tim Hutt
Tim Snyder

View File

@ -1,9 +1,8 @@
.. comment: generated by t_lint_assigneqexpr_bad
.. code-block:: sv
:linenos:
:emphasize-lines: 3
assign d_o = // Note = not == below
(
c_o = 1 // <--- Warning: ASSIGNEQEXPR
) ? 1 : (
output logic c_o,
output logic d_o
);
assign c_o = (a_i != 0) ? 1 : 0;

View File

@ -4,4 +4,4 @@
:emphasize-lines: 2
function void calls_timing_ctl;
@e; // <--- Bad IEEE 1800-2023 13.4 time-controlling
@e; // <--- Bad IEEE 1800-2023 13.4 time-controlling

View File

@ -502,16 +502,16 @@ described above is just a wrapper which calls these two functions.
3. If using delays and :vlopt:`--timing`, there are two additional methods
the user should call:
* ``designp->eventsPending()``, which returns ``true`` if there are
any delayed events pending,
* ``designp->eventsPending()``, which returns ``true`` if there are any
delayed events pending,
* ``designp->nextTimeSlot()``, which returns the simulation time of the
next delayed event. This method can only be called if
``designp->eventsPending()`` returned ``true``.
Call ``eventsPending()`` to check if you should continue with the
simulation, and then ``nextTimeSlot()`` to move simulation time forward.
:vlopt:`--main` can be used with :vlopt:`--timing` to generate a basic example
of a timing-enabled eval loop.
:vlopt:`--main` can be used with :vlopt:`--timing` to generate a basic
example of a timing-enabled eval loop.
When ``eval()`` (or ``eval_step()``) is called Verilator looks for changes
in clock signals and evaluates related sequential always blocks, such as

View File

@ -29,9 +29,10 @@ Alliance <https://chipsalliance.org>`_, and `Antmicro Ltd
Previous major corporate sponsors of Verilator, by providing significant
contributions of time or funds include: Antmicro Ltd., Atmel Corporation,
Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd., Fractile
Ltd., Hicamp Systems, Intel Corporation, Marvell Inc., Mindspeed Technologies
Inc., MicroTune Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus
Networks Inc., SiCortex Inc, Shunyao CAD, and Western Digital Inc.
Ltd., Hicamp Systems, Intel Corporation, Marvell Inc., Mindspeed
Technologies Inc., MicroTune Inc., picoChip Designs Ltd., Sun Microsystems
Inc., Nauticus Networks Inc., SiCortex Inc, Shunyao CAD, and Western
Digital Inc.
The contributors of major functionality are: Jeremy Bennett, Krzysztof
Bieganski, Byron Bradley, Lane Brooks, John Coiner, Duane Galbi, Arkadiusz

View File

@ -39,8 +39,7 @@ Breaking this command down:
#. :vlopt:`-j` `0` to Verilate using use as many CPU threads as the machine
has.
#. :vlopt:`-Wall` so Verilator has stronger lint warnings
enabled.
#. :vlopt:`-Wall` so Verilator has stronger lint warnings enabled.
#. An finally, :command:`our.v`, which is our SystemVerilog design file.

View File

@ -60,8 +60,7 @@ Breaking this command down:
#. :vlopt:`-j 0 <-j>` to Verilate using use as many CPU threads as the
machine has.
#. :vlopt:`-Wall` so Verilator has stronger lint warnings
enabled.
#. :vlopt:`-Wall` so Verilator has stronger lint warnings enabled.
#. And finally, :command:`our.v` which is our SystemVerilog design file.

View File

@ -867,6 +867,29 @@ Summary:
compatibility and is not recommended usage as this is not supported by
some third-party tools.
.. option:: --inline-cfuncs <value>
Inline small CFunc calls directly into their callers when the function
has at most <value> nodes. This reduces function call overhead when
:vlopt:`--output-split-cfuncs` places functions in separate compilation
units that the C++ compiler cannot inline.
Set to 0 to disable this optimization. The default is 20.
This optimization is automatically disabled when :vlopt:`--prof-cfuncs`
or :vlopt:`--trace` is used.
.. option:: --inline-cfuncs-product <value>
Tune the inlining of CFunc calls for larger functions. When a function
is too large to always inline (exceeds :vlopt:`--inline-cfuncs` threshold),
it may still be inlined if the function size multiplied by the number of
call sites is at most <value>.
This allows functions that are called only once or twice to be inlined
even if they exceed the small function threshold. Set to 0 to only inline
functions below the :vlopt:`--inline-cfuncs` threshold. The default is 200.
.. option:: --inline-mult <value>
Tune the inlining of modules. The default value of 2000 specifies that
@ -2495,8 +2518,8 @@ The grammar of control commands is as follows:
converted into ``begin``/``end`` blocks.
Similar to :option:`/*verilator&32;timing_on*/`,
:option:`/*verilator&32;timing_off*/` metacomments, but interpreted
independtly. If either a control file, or metacommets disable timing
:option:`/*verilator&32;timing_off*/` meta-comments, but interpreted
independently. If either a control file, or meta-comments disable timing
constructs, they will be disabled.
.. t_dist_docs_style ignore tracing_on

View File

@ -1,9 +1,9 @@
.. Copyright 2003-2025 by Wilson Snyder.
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
=====================
Language Extensions
=====================
===================
Language Extensions
===================
The following additional constructs are the extensions Verilator supports
on top of standard Verilog code. Using these features outside of comments

View File

@ -403,8 +403,8 @@ How do I get faster build times?
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
* 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,

View File

@ -163,10 +163,10 @@ packages (see internals.rst), and a Python virtual environment:
cpan install Pod::Perldoc
The Python virtual environment is only required for running the whole test
suite, and for additional development steps like linting and formatting. It is
not required for building Verilator itself. To install the python virtual
environment and all dependencies automatically, run the following once, after
``configure``:
suite, and for additional development steps like linting and formatting. It
is not required for building Verilator itself. To install the python
virtual environment and all dependencies automatically, run the following
once, after ``configure``:
.. code-block:: bash

View File

@ -143,8 +143,8 @@ error, except:
* delay statements - they are ignored (as they are in synthesis), though they
do issue a :option:`STMTDLY` warning,
* intra-assignment timing controls - they are ignored, though they do issue an
:option:`ASSIGNDLY` warning,
* intra-assignment timing controls - they are ignored, though they do issue
an :option:`ASSIGNDLY` warning,
* net delays - they are ignored,
* event controls at the top of the procedure,

View File

@ -22,8 +22,8 @@ Verilator may be used in five major ways:
that may be used to feed into other user-designed tools.
* With the :vlopt:`-E` option, Verilator will preprocess the code according
to IEEE preprocessing rules and write the output to standard out. This
is useful to feed other tools and to debug how "\`define" statements are
to IEEE preprocessing rules and write the output to standard out. This is
useful to feed other tools and to debug how "\`define" statements are
expanded.
@ -80,8 +80,9 @@ Verilator first reads all files provided on the command line and
:vlopt:`-f` files, and parses all modules within. Each module is assigned
to the most recent library specified with :vlopt:`-work`, thus `-work liba
a.v -work libb b.v` will assign modules in `a.v` to `liba` and modules in
`b.v` to `libb`. In the absence of a `-work` mapping, each module is optionally
assigned to a library based on mappings provided by :vlopt:`-libmap`.
`b.v` to `libb`. In the absence of a `-work` mapping, each module is
optionally assigned to a library based on mappings provided by
:vlopt:`-libmap`.
If a module is not defined from a file on the command-line, Verilator
attempts to find a filename constructed from the module name using

View File

@ -1,9 +1,9 @@
.. Copyright 2003-2025 by Wilson Snyder.
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
=====================
Errors and Warnings
=====================
===================
Errors and Warnings
===================
.. _disabling warnings:
@ -46,8 +46,8 @@ Warnings may be disabled in multiple ways:
lint_off -rule UNSIGNED -file "*/example.v" -lines 1
Metacomments and control file directives do not interact. If a warning is
disabled by either metacomments, or a directive in a control file, it will not
be emitted.
disabled by either metacomments, or a directive in a control file, it will
not be emitted.
Error And Warning Format
========================

View File

@ -1,8 +1,8 @@
|Logo|
=====================
Verilator Internals
=====================
===================
Verilator Internals
===================
.. contents::
:depth: 3
@ -1771,8 +1771,8 @@ files that were read, filtered by preprocessing. This file can be fed back
into Verilator, replacing on the command line all of the previous input
files, to enable simplification of test cases. This file also contains most
command line arguments Verilator was invoked as `// verilator fargs``
metacomments, with and can be parsed by ``-f`. So to reproduce the run that
created the file, run:
metacomments, with and can be parsed by `\`-f`. So to reproduce the run
that created the file, run:
::
verilator -f <prefix>__inputs.vpp <prefix>__inputs.vpp
@ -2095,11 +2095,18 @@ To print a node:
``src/.gdbinit`` and ``src/.gdbinit.py`` define handy utilities for working
with JSON AST dumps. For example:
* ``jstash nodep`` - Perform a JSON AST dump and save it into GDB value history (e.g. ``$1``)
* ``jtree nodep`` - Perform a JSON AST dump and pretty print it using ``astsee_verilator``.
* ``jtree $1`` - Pretty print a dump that was previously saved by ``jstash``.
* ``jtree nodep -d '.file, .timeunit'`` - Perform a JSON AST dump, filter out some fields and pretty print it.
* ``jtree 0x55555613dca0`` - Pretty print using address literal (rather than actual pointer).
* ``jstash nodep`` - Perform a JSON AST dump and save it into GDB value
history (e.g. ``$1``)
* ``jtree nodep`` - Perform a JSON AST dump and pretty print it using
``astsee_verilator``.
* ``jtree $1`` - Pretty print a dump that was previously saved by
``jstash``.
* ``jtree nodep -d '.file, .timeunit'`` - Perform a JSON AST dump, filter
out some fields and pretty print it.
* ``jtree 0x55555613dca0`` - Pretty print using address literal (rather
than actual pointer).
* ``jtree $1 nodep`` - Diff ``nodep`` against an older dump.
A detailed description of ``jstash`` and ``jtree`` can be displayed using

View File

@ -4,6 +4,8 @@ Accellera
Affe
Aleksander
Alexandre
Almis
Amal
Ami
Amir
Anastasiadis
@ -13,6 +15,7 @@ Antmicro
Antonin
Antwerpen
Arasanipalai
Araweelo
Arjen
Arshid
Asciidoc
@ -986,6 +989,7 @@ qrqiuren
radix
randc
randcase
randmode
randsequence
randstate
raphmaster

View File

@ -5,12 +5,12 @@
// SPDX-License-Identifier: CC0-1.0
// ======================================================================
module sub
#(parameter type TYPE_t = logic)
(
input TYPE_t in,
output TYPE_t out
);
module sub #(
parameter type TYPE_t = logic
) (
input TYPE_t in,
output TYPE_t out
);
// Some simple logic
always_comb out = ~in;

View File

@ -5,29 +5,37 @@
// SPDX-License-Identifier: CC0-1.0
// ======================================================================
module top
(
input clk,
input fastclk,
input reset_l,
module top (
input clk,
input fastclk,
input reset_l,
output wire [1:0] out_small,
output wire [39:0] out_quad,
output wire [69:0] out_wide,
input [1:0] in_small,
input [39:0] in_quad,
input [69:0] in_wide
);
output wire [1:0] out_small,
output wire [39:0] out_quad,
output wire [69:0] out_wide,
input [1:0] in_small,
input [39:0] in_quad,
input [69:0] in_wide
);
sub #(.TYPE_t(logic [1:0])) sub_small
(.in(in_small),
.out(out_small));
sub #(
.TYPE_t(logic [1:0])
) sub_small (
.in(in_small),
.out(out_small)
);
sub #(.TYPE_t(logic [39:0])) sub_quad
(.in(in_quad),
.out(out_quad));
sub #(
.TYPE_t(logic [39:0])
) sub_quad (
.in(in_quad),
.out(out_quad)
);
sub #(.TYPE_t(logic [69:0])) sub_wide
(.in(in_wide),
.out(out_wide));
sub #(
.TYPE_t(logic [69:0])
) sub_wide (
.in(in_wide),
.out(out_wide)
);
endmodule

View File

@ -7,13 +7,13 @@
// This module will be used as libsecret.a or libsecret.so without
// exposing the source.
module secret_impl
(
input [31:0] a,
input [31:0] b,
output logic [31:0] x,
input clk,
input reset_l);
module secret_impl (
input [31:0] a,
input [31:0] b,
output logic [31:0] x,
input clk,
input reset_l
);
logic [31:0] accum_q;
logic [31:0] secret_value;
@ -27,10 +27,8 @@ module secret_impl
end
else begin
accum_q <= accum_q + a;
if (accum_q > 10)
x <= b;
else
x <= a + b + secret_value;
if (accum_q > 10) x <= b;
else x <= a + b + secret_value;
end
end

View File

@ -6,7 +6,9 @@
// See also https://verilator.org/guide/latest/examples.html"
module top (input clk);
module top (
input clk
);
int cyc;
logic reset_l;
@ -14,7 +16,13 @@ module top (input clk);
logic [31:0] b;
logic [31:0] x;
verilated_secret secret (.a, .b, .x, .clk, .reset_l);
verilated_secret secret (
.a,
.b,
.x,
.clk,
.reset_l
);
always @(posedge clk) begin
$display("[%0t] cyc=%0d a=%0d b=%0d x=%0d", $time, cyc, a, b, x);

View File

@ -5,11 +5,10 @@
// SPDX-License-Identifier: CC0-1.0
// ======================================================================
module sub
(
input clk,
input reset_l
);
module sub (
input clk,
input reset_l
);
// Example counter/flop
reg [31:0] count_c;

View File

@ -8,24 +8,23 @@
// This is intended to be a complex example of several features, please also
// see the simpler examples/make_hello_c.
module top
(
// Declare some signals so we can see how I/O works
input clk,
input reset_l,
module top (
// Declare some signals so we can see how I/O works
input clk,
input reset_l,
output wire [1:0] out_small,
output wire [39:0] out_quad,
output wire [69:0] out_wide,
input [1:0] in_small,
input [39:0] in_quad,
input [69:0] in_wide
);
output wire [1:0] out_small,
output wire [39:0] out_quad,
output wire [69:0] out_wide,
input [1:0] in_small,
input [39:0] in_quad,
input [69:0] in_wide
);
// Connect up the outputs, using some trivial logic
assign out_small = ~reset_l ? '0 : (in_small + 2'b1);
assign out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
assign out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
assign out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
assign out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
// And an example sub module. The submodule will print stuff.
sub sub (/*AUTOINST*/

View File

@ -5,12 +5,11 @@
// SPDX-License-Identifier: CC0-1.0
// ======================================================================
module sub
(
input clk,
input fastclk,
input reset_l
);
module sub (
input clk,
input fastclk,
input reset_l
);
// Example counter/flop
reg [31:0] count_f;

View File

@ -8,25 +8,24 @@
// This is intended to be a complex example of several features, please also
// see the simpler examples/make_hello_c.
module top
(
// Declare some signals so we can see how I/O works
input clk,
input fastclk,
input reset_l,
module top (
// Declare some signals so we can see how I/O works
input clk,
input fastclk,
input reset_l,
output wire [1:0] out_small,
output wire [39:0] out_quad,
output wire [69:0] out_wide,
input [1:0] in_small,
input [39:0] in_quad,
input [69:0] in_wide
);
output wire [1:0] out_small,
output wire [39:0] out_quad,
output wire [69:0] out_wide,
input [1:0] in_small,
input [39:0] in_quad,
input [69:0] in_wide
);
// Connect up the outputs, using some trivial logic
assign out_small = ~reset_l ? '0 : (in_small + 2'b1);
assign out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
assign out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
assign out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
assign out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
// And an example sub module. The submodule will print stuff.
sub sub (/*AUTOINST*/

View File

@ -114,6 +114,7 @@ set(HEADERS
V3Hasher.h
V3HierBlock.h
V3Inline.h
V3InlineCFuncs.h
V3Inst.h
V3InstrCount.h
V3Interface.h
@ -287,6 +288,7 @@ set(COMMON_SOURCES
V3Hasher.cpp
V3HierBlock.cpp
V3Inline.cpp
V3InlineCFuncs.cpp
V3Inst.cpp
V3InstrCount.cpp
V3Interface.cpp

View File

@ -284,6 +284,7 @@ RAW_OBJS_PCH_ASTNOMT = \
V3Gate.o \
V3HierBlock.o \
V3Inline.o \
V3InlineCFuncs.o \
V3Inst.o \
V3InstrCount.o \
V3Interface.o \

View File

@ -1203,6 +1203,7 @@ class AstModportVarRef final : public AstNode {
// A input/output/etc variable referenced under a modport
// The storage for the variable itself is inside the interface, thus this is a reference
// PARENT: AstModport
// @astgen op1 := exprp : Optional[AstNodeExpr]
//
// @astgen ptr := m_varp : Optional[AstVar] // Link to the actual Var
string m_name; // Name of the variable referenced
@ -1212,6 +1213,13 @@ public:
: ASTGEN_SUPER_ModportVarRef(fl)
, m_name{name}
, m_direction{direction} {}
AstModportVarRef(FileLine* fl, const string& name, AstNodeExpr* exprp,
VDirection::en direction)
: ASTGEN_SUPER_ModportVarRef(fl)
, m_name{name}
, m_direction{direction} {
this->exprp(exprp);
};
ASTGEN_MEMBERS_AstModportVarRef;
void dump(std::ostream& str) const override;
void dumpJson(std::ostream& str) const override;

View File

@ -2378,6 +2378,7 @@ void AstNodeDType::dump(std::ostream& str) const {
}
void AstNodeDType::dumpJson(std::ostream& str) const {
dumpJsonBoolFunc(str, generic);
if (isSigned() && !isDouble()) dumpJsonBool(str, "signed", 1);
dumpJsonGen(str);
}
void AstNodeDType::dumpSmall(std::ostream& str) const VL_MT_STABLE {

View File

@ -673,8 +673,8 @@ class ForkVisitor final : public VNVisitor {
if (nodep->access().isWriteOrRW() && (!nodep->isClassHandleValue() || nodep->user2())) {
nodep->v3warn(
E_LIFETIME,
"Invalid reference: Process might outlive variable `"
<< varp->name() << "`.\n"
"Invalid reference: Process might outlive variable "
<< varp->prettyNameQ() << ".\n"
<< varp->warnMore()
<< "... Suggest use it as read-only to initialize a local copy at the "
"beginning of the process, or declare it as static. It is also "

269
src/V3InlineCFuncs.cpp Normal file
View File

@ -0,0 +1,269 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Inline small CFuncs into their callers
//
// Code available from: https://verilator.org
//
//*************************************************************************
//
// Copyright 2003-2025 by Wilson Snyder. This program is free software; you
// can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
//
//*************************************************************************
// V3InlineCFuncs's Transformations:
//
// For each CCall to a small CFunc:
// - Check if function is eligible for inlining (small enough, same scope)
// - Clone local variables with unique names to avoid collisions
// - Replace CCall with cloned function body statements
//
// Two tunables control inlining:
// --inline-cfuncs <n> : Always inline if size <= n (default 20)
// --inline-cfuncs-product <n> : Also inline if size * call_count <= n (default 200)
//
//*************************************************************************
#include "V3PchAstNoMT.h" // VL_MT_DISABLED_CODE_UNIT
#include "V3InlineCFuncs.h"
#include "V3AstUserAllocator.h"
#include "V3Stats.h"
#include <map>
#include <vector>
VL_DEFINE_DEBUG_FUNCTIONS;
//######################################################################
// Helper visitor to check if a CFunc contains C statements
// Uses clearOptimizable pattern for debugging
class CFuncInlineCheckVisitor final : public VNVisitorConst {
// STATE
bool m_optimizable = true; // True if function can be inlined
string m_whyNot; // Reason why not optimizable
AstNode* m_whyNotNodep = nullptr; // Node that caused non-optimizable
// METHODS
void clearOptimizable(AstNode* nodep, const string& why) {
if (m_optimizable) {
m_optimizable = false;
m_whyNot = why;
m_whyNotNodep = nodep;
UINFO(9, "CFunc not inlineable: " << why);
if (nodep) UINFO(9, ": " << nodep);
UINFO(9, endl);
}
}
// VISITORS
void visit(AstCStmt* nodep) override { clearOptimizable(nodep, "contains AstCStmt"); }
void visit(AstCExpr* nodep) override { clearOptimizable(nodep, "contains AstCExpr"); }
void visit(AstCStmtUser* nodep) override { clearOptimizable(nodep, "contains AstCStmtUser"); }
void visit(AstCExprUser* nodep) override { clearOptimizable(nodep, "contains AstCExprUser"); }
void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
public:
// CONSTRUCTORS
explicit CFuncInlineCheckVisitor(AstCFunc* cfuncp) { iterateConst(cfuncp); }
// ACCESSORS
bool optimizable() const { return m_optimizable; }
string whyNot() const { return m_whyNot; }
AstNode* whyNotNodep() const { return m_whyNotNodep; }
};
//######################################################################
class InlineCFuncsVisitor final : public VNVisitor {
// NODE STATE
// AstCFunc::user1() -> vector of AstCCall* pointing to this function
// AstCFunc::user2() -> bool: true if checked for C statements
// AstCFunc::user3() -> bool: true if contains C statements (not inlineable)
const VNUser1InUse m_user1InUse;
const VNUser2InUse m_user2InUse;
const VNUser3InUse m_user3InUse;
AstUser1Allocator<AstCFunc, std::vector<AstCCall*>> m_callSites;
// STATE
VDouble0 m_statInlined; // Statistic tracking
const int m_threshold1; // Size threshold: always inline if size <= this
const int m_threshold2; // Product threshold: inline if size * calls <= this
AstCFunc* m_callerFuncp = nullptr; // Current caller function
// Tuples of (StmtExpr to replace, CFunc to inline from, caller func for vars)
std::vector<std::tuple<AstStmtExpr*, AstCFunc*, AstCFunc*>> m_toInline;
// METHODS
// Check if a function contains any $c() calls (user or internal)
// Results are cached in user2/user3 for efficiency
bool containsCStatements(AstCFunc* cfuncp) {
if (!cfuncp->user2()) {
// Not yet checked - run the check visitor
cfuncp->user2(true); // Mark as checked
const CFuncInlineCheckVisitor checker{cfuncp};
cfuncp->user3(!checker.optimizable()); // Store result (true = contains C stmts)
}
return cfuncp->user3();
}
// Check if a function is eligible for inlining into caller
bool isInlineable(AstCFunc* callerp, AstCFunc* cfuncp) {
// Must be in the same scope (same class) to access the same members
if (callerp->scopep() != cfuncp->scopep()) return false;
// Check for $c() calls that might use 'this'
if (containsCStatements(cfuncp)) return false;
// Check it's a void function (not a coroutine)
if (cfuncp->rtnTypeVoid() != "void") return false;
// Don't inline functions marked dontCombine (e.g. trace, entryPoint)
if (cfuncp->dontCombine()) return false;
// Don't inline entry point functions
if (cfuncp->entryPoint()) return false;
// Must have statements to inline
if (!cfuncp->stmtsp()) return false;
// Check size thresholds
const size_t funcSize = cfuncp->nodeCount();
// Always inline if small enough
if (funcSize <= static_cast<size_t>(m_threshold1)) return true;
// Also inline if size * call_count is reasonable
const size_t callCount = m_callSites(cfuncp).size();
if (callCount > 0 && funcSize * callCount <= static_cast<size_t>(m_threshold2)) {
return true;
}
return false;
}
// VISITORS
void visit(AstCCall* nodep) override {
iterateChildren(nodep);
AstCFunc* const cfuncp = nodep->funcp();
if (!cfuncp) return;
// Track call site for call counting
m_callSites(cfuncp).emplace_back(nodep);
}
void visit(AstCFunc* nodep) override {
VL_RESTORER(m_callerFuncp);
m_callerFuncp = nodep;
iterateChildren(nodep);
}
void visit(AstNodeModule* nodep) override {
// Process per module for better cache behavior
m_toInline.clear();
// Phase 1: Collect call sites within this module
iterateChildren(nodep);
// Phase 2: Determine which calls to inline
collectInlineCandidates(nodep);
// Phase 3: Perform inlining for this module
doInlining();
}
void visit(AstNode* nodep) override { iterateChildren(nodep); }
// Collect calls that should be inlined within this module
void collectInlineCandidates(AstNodeModule* modp) {
for (AstNode* stmtp = modp->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
AstCFunc* const callerp = VN_CAST(stmtp, CFunc);
if (!callerp) continue;
callerp->foreach([&](AstCCall* callp) {
AstCFunc* const cfuncp = callp->funcp();
if (!cfuncp) return;
if (!isInlineable(callerp, cfuncp)) return;
// Walk up to find the containing StmtExpr
AstNode* stmtNodep = callp;
while (stmtNodep && !VN_IS(stmtNodep, StmtExpr) && !VN_IS(stmtNodep, CFunc)) {
stmtNodep = stmtNodep->backp();
}
AstStmtExpr* const stmtExprp = VN_CAST(stmtNodep, StmtExpr);
if (!stmtExprp) return;
m_toInline.emplace_back(stmtExprp, cfuncp, callerp);
});
}
}
// Perform the actual inlining after iteration is complete
void doInlining() {
for (const auto& tuple : m_toInline) {
AstStmtExpr* const stmtExprp = std::get<0>(tuple);
AstCFunc* const cfuncp = std::get<1>(tuple);
AstCFunc* const callerp = std::get<2>(tuple);
UINFO(6, "Inlining CFunc " << cfuncp->name() << " into " << callerp->name() << endl);
++m_statInlined;
// Clone local variables with unique names to avoid collisions
std::map<AstVar*, AstVar*> varMap;
for (AstVar* varp = cfuncp->varsp(); varp; varp = VN_AS(varp->nextp(), Var)) {
const string newName = "__Vinline_" + cfuncp->name() + "_" + varp->name();
AstVar* const newVarp = varp->cloneTree(false);
newVarp->name(newName);
callerp->addVarsp(newVarp);
varMap[varp] = newVarp;
}
// Clone the function body
AstNode* const bodyp = cfuncp->stmtsp()->cloneTree(true);
// Retarget variable references to the cloned variables
// Must iterate all sibling statements, not just the first
if (!varMap.empty()) {
for (AstNode* stmtp = bodyp; stmtp; stmtp = stmtp->nextp()) {
stmtp->foreach([&](AstVarRef* refp) {
auto it = varMap.find(refp->varp());
if (it != varMap.end()) refp->varp(it->second);
});
}
}
// Replace the statement with the inlined body
stmtExprp->addNextHere(bodyp);
VL_DO_DANGLING(stmtExprp->unlinkFrBack()->deleteTree(), stmtExprp);
}
}
public:
// CONSTRUCTORS
explicit InlineCFuncsVisitor(AstNetlist* nodep)
: m_threshold1{v3Global.opt.inlineCFuncs()}
, m_threshold2{v3Global.opt.inlineCFuncsProduct()} {
// Don't inline when profiling or tracing
if (v3Global.opt.profCFuncs() || v3Global.opt.trace()) return;
// Process modules one at a time for better cache behavior
iterateAndNextNull(nodep->modulesp());
}
~InlineCFuncsVisitor() override {
V3Stats::addStat("Optimizations, Inlined CFuncs", m_statInlined);
}
};
//######################################################################
// InlineCFuncs class functions
void V3InlineCFuncs::inlineAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ":");
{ InlineCFuncsVisitor{nodep}; } // Destruct before checking
V3Global::dumpCheckGlobalTree("inlinecfuncs", 0, dumpTreeEitherLevel() >= 6);
}

30
src/V3InlineCFuncs.h Normal file
View File

@ -0,0 +1,30 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Inline small CFuncs into their callers
//
// Code available from: https://verilator.org
//
//*************************************************************************
//
// Copyright 2003-2025 by Wilson Snyder. This program is free software; you
// can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
//
//*************************************************************************
#ifndef VERILATOR_V3INLINECFUNCS_H_
#define VERILATOR_V3INLINECFUNCS_H_
#include "config_build.h"
#include "verilatedos.h"
class AstNetlist;
class V3InlineCFuncs final {
public:
static void inlineAll(AstNetlist* nodep) VL_MT_DISABLED;
};
#endif // Guard

View File

@ -2529,7 +2529,13 @@ class LinkDotIfaceVisitor final : public VNVisitor {
void visit(AstModportVarRef* nodep) override { // IfaceVisitor::
UINFO(5, " fiv: " << nodep);
iterateChildren(nodep);
VSymEnt* const symp = m_curSymp->findIdFallback(nodep->name());
VSymEnt* symp = nullptr;
if (nodep->exprp()) {
nodep->v3warn(E_UNSUPPORTED,
"Unsupported: Modport expressions (IEEE 1800-2023 25.5.4)");
} else {
symp = m_curSymp->findIdFallback(nodep->name());
}
if (!symp) {
nodep->v3error("Modport item not found: " << nodep->prettyNameQ());
} else if (AstVar* const varp = VN_CAST(symp->nodep(), Var)) {

View File

@ -1528,6 +1528,8 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
}).notForRerun();
DECL_OPTION("-if-depth", Set, &m_ifDepth);
DECL_OPTION("-ignc", OnOff, &m_ignc).undocumented();
DECL_OPTION("-inline-cfuncs", Set, &m_inlineCFuncs);
DECL_OPTION("-inline-cfuncs-product", Set, &m_inlineCFuncsProduct);
DECL_OPTION("-inline-mult", Set, &m_inlineMult);
DECL_OPTION("-instr-count-dpi", CbVal, [this, fl](int val) {
m_instrCountDpi = val;

View File

@ -319,6 +319,8 @@ private:
int m_hierChild = 0; // main switch: --hierarchical-child
int m_hierThreads = 0; // main switch: --hierarchical-threads
int m_ifDepth = 0; // main switch: --if-depth
int m_inlineCFuncs = 20; // main switch: --inline-cfuncs
int m_inlineCFuncsProduct = 200; // main switch: --inline-cfuncs-product
int m_inlineMult = 2000; // main switch: --inline-mult
int m_instrCountDpi = 200; // main switch: --instr-count-dpi
bool m_jsonEditNums = true; // main switch: --no-json-edit-nums
@ -595,6 +597,8 @@ public:
int expandLimit() const { return m_expandLimit; }
int gateStmts() const { return m_gateStmts; }
int ifDepth() const { return m_ifDepth; }
int inlineCFuncs() const { return m_inlineCFuncs; }
int inlineCFuncsProduct() const { return m_inlineCFuncsProduct; }
int inlineMult() const { return m_inlineMult; }
int instrCountDpi() const { return m_instrCountDpi; }
int localizeMaxSize() const { return m_localizeMaxSize; }

View File

@ -2634,6 +2634,7 @@ class RandomizeVisitor final : public VNVisitor {
const std::string name = "__Vrandcase" + cvtToStr(m_randCaseNum++);
AstVar* const randVarp = new AstVar{fl, VVarType::BLOCKTEMP, name, sumDTypep};
randVarp->noSubst(true);
randVarp->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
if (m_ftaskp) randVarp->funcLocal(true);
AstNodeExpr* sump = new AstConst{fl, AstConst::WidthedValue{}, 64, 0};
AstNodeIf* const firstIfsp

View File

@ -126,9 +126,12 @@ private:
// Add post update if it does not exist yet
if (m_hasPostUpdate.emplace(*exprp).second) {
if (!isSupportedDType(exprp->dtypep())) {
exprp->v3warn(E_UNSUPPORTED,
"Unsupported: Cannot detect changes on expression of complex type"
" (see combinational cycles reported by UNOPTFLAT)");
exprp->v3warn(
E_UNSUPPORTED,
"Unsupported: Cannot detect changes on expression of complex type "
<< exprp->dtypep()->prettyDTypeNameQ() << "\n"
<< exprp->warnMore()
<< "... May be caused by combinational cycles reported with UNOPTFLAT");
return prevp;
}

View File

@ -63,6 +63,7 @@
#include "V3Graph.h"
#include "V3HierBlock.h"
#include "V3Inline.h"
#include "V3InlineCFuncs.h"
#include "V3Inst.h"
#include "V3Interface.h"
#include "V3LibMap.h"
@ -565,6 +566,11 @@ static void process() {
V3Reloop::reloopAll(v3Global.rootp());
}
if (v3Global.opt.inlineCFuncs()) {
// Inline small CFuncs to reduce function call overhead
V3InlineCFuncs::inlineAll(v3Global.rootp());
}
// Fix very deep expressions
// Mark evaluation functions as member functions, if needed.
V3Depth::depthAll(v3Global.rootp());

View File

@ -1679,8 +1679,7 @@ modportPortsDeclList<nodep>:
// We track the type as with the V2k series of defines, then create as each ID is seen.
modportPortsDecl<nodep>:
// // IEEE: modport_simple_ports_declaration
port_direction modportSimplePortOrTFPort { $$ = new AstModportVarRef{$<fl>2, *$2, GRAMMARP->m_varIO};
GRAMMARP->m_modportImpExpActive = false;}
port_direction { GRAMMARP->m_modportImpExpActive = false; } modportSimplePortOrTFPort { $$ = $3; }
// // IEEE: modport_clocking_declaration
| yCLOCKING idAny/*clocking_identifier*/ { $$ = new AstModportClockingRef{$1, *$2}; }
// // IEEE: yIMPORT modport_tf_port
@ -1700,19 +1699,20 @@ modportPortsDecl<nodep>:
{ $$ = nullptr; BBUNSUP($<fl>1, "Unsupported: Modport export with prototype"); DEL($2); }
// Continuations of above after a comma.
// // IEEE: modport_simple_ports_declaration
| modportSimplePortOrTFPort { $$ = GRAMMARP->m_modportImpExpActive ?
| modportSimplePortOrTFPort { $$ = $1; }
;
modportSimplePortOrTFPort<nodep>:// IEEE: modport_simple_port or modport_tf_port, depending what keyword was earlier
idAny { $$ = GRAMMARP->m_modportImpExpActive ?
static_cast<AstNode*>(
new AstModportFTaskRef{
$<fl>1, *$1, GRAMMARP->m_modportImpExpLastIsExport} ) :
static_cast<AstNode*>(
new AstModportVarRef{
$<fl>1, *$1, GRAMMARP->m_varIO} ); }
;
modportSimplePortOrTFPort<strp>:// IEEE: modport_simple_port or modport_tf_port, depending what keyword was earlier
idAny { $$ = $1; }
| '.' idAny '(' ')' { $$ = $2; BBUNSUP($<fl>1, "Unsupported: Modport dotted port name"); }
| '.' idAny '(' expr ')' { $$ = $2; BBUNSUP($<fl>1, "Unsupported: Modport dotted port name"); }
| '.' idAny '(' ')' { $$ = new AstModportVarRef{$<fl>2, *$2, GRAMMARP->m_varIO};
BBUNSUP($<fl>4, "Unsupported: Modport empty expression"); }
| '.' idAny '(' expr ')' { $$ = new AstModportVarRef{$<fl>2, *$2, $4, GRAMMARP->m_varIO}; }
;
//************************************************

View File

@ -22,11 +22,13 @@ module t ( /*AUTOARG*/
force a = 16'h1234;
if (a != 16'h1234 || a != b) $stop;
release a;
end else if (cyc == 2) begin
end
else if (cyc == 2) begin
force b = 16'h5678;
if (a != 16'h5678 || a != b) $stop;
release b;
end else if (cyc == 3) begin
end
else if (cyc == 3) begin
$write("*-* All Finished *-*\n");
$finish;
end

View File

@ -12,7 +12,7 @@ module t ( /*AUTOARG*/
);
input clk;
reg [15:0] out;
reg [15:0] out;
wire [15:0] a;
alias a = sub_i.btw;
@ -29,7 +29,7 @@ module sub (
output wire [15:0] out
);
reg [31:0] counter = 32'h0;
reg [31:0] counter = 32'h0;
wire [15:0] btw;
assign btw = {counter[15:0]};

View File

@ -4,8 +4,10 @@
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define check(got ,exp) do if ((got) !== (exp)) begin $write("%%Error: %s:%0d: $time=%0t got='h%x exp='h%x\n", `__FILE__,`__LINE__, $time, (got), (exp)); `stop; end while(0)
// verilog_format: on
module t;
@ -18,15 +20,16 @@ module t;
// Constant 1 set in initial block, but not known at compile time
logic enable = 1'b0;
int array [32];
int array[32];
function automatic int get(logic en, logic [4:0] idx);
if (en) begin // Always taken, but need the 'if' to show bug
if (en) begin // Always taken, but need the 'if' to show bug
int tmp;
idx = ~idx;
tmp = array[~idx];
return tmp;
end else begin
end
else begin
return 0;
end
endfunction

View File

@ -5,13 +5,16 @@
// SPDX-License-Identifier: CC0-1.0
module top;
sub inst(
sub inst (
.a({128{1'b1}}),
.b({128{1'b1}})
);
endmodule
module sub(a, b);
module sub (
a,
b
);
input [127:0] a;
input [127:0] b;
always @(a or b) begin

View File

@ -4,8 +4,10 @@
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
// verilog_format: on
class Cls;
int m_index;

View File

@ -1,11 +1,11 @@
%Error-UNSUPPORTED: t/t_array_method_map.v:17:15: Unsupported: Array 'map' method (IEEE 1800-2023 7.12.5)
%Error-UNSUPPORTED: t/t_array_method_map.v:19:15: Unsupported: Array 'map' method (IEEE 1800-2023 7.12.5)
: ... note: In instance 't'
17 | res = a.map(el) with (el == 200);
19 | res = a.map(el) with (el == 200);
| ^~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: t/t_array_method_map.v:17:15: Unknown built-in array method 'map'
%Error: t/t_array_method_map.v:19:15: Unknown built-in array method 'map'
: ... note: In instance 't'
17 | res = a.map(el) with (el == 200);
19 | res = a.map(el) with (el == 200);
| ^~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to

View File

@ -4,8 +4,10 @@
// any use, without warranty, 2024 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
module t;

View File

@ -25,7 +25,8 @@ module t #(
.ID_T(ID_T),
.STAGE_IDS(STAGE_IDS)
) pipe (
.*);
.*
);
initial $finish;

View File

@ -10,11 +10,8 @@
// verilog_format: on
module t (
/*AUTOARG*/
// Inputs
clk
);
input clk;
input clk
);
global clocking @(posedge clk);
endclocking

View File

@ -1,22 +1,22 @@
%Error: t/t_assert_future_bad.v:18:31: Future sampled value function called outside property or sequence expression (IEEE 16.9.4)
%Error: t/t_assert_future_bad.v:16:31: Future sampled value function called outside property or sequence expression (IEEE 16.9.4)
: ... note: In instance 't'
18 | else $display("Future=%0d", $future_gclk(a));
16 | else $display("Future=%0d", $future_gclk(a));
| ^~~~~~~~~~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: t/t_assert_future_bad.v:21:31: Future sampled value function called outside property or sequence expression (IEEE 16.9.4)
%Error: t/t_assert_future_bad.v:19:31: Future sampled value function called outside property or sequence expression (IEEE 16.9.4)
: ... note: In instance 't'
21 | else $display("Future=%0d", $rising_gclk(a));
19 | else $display("Future=%0d", $rising_gclk(a));
| ^~~~~~~~~~~~
%Error: t/t_assert_future_bad.v:24:31: Future sampled value function called outside property or sequence expression (IEEE 16.9.4)
%Error: t/t_assert_future_bad.v:22:31: Future sampled value function called outside property or sequence expression (IEEE 16.9.4)
: ... note: In instance 't'
24 | else $display("Future=%0d", $falling_gclk(a));
22 | else $display("Future=%0d", $falling_gclk(a));
| ^~~~~~~~~~~~~
%Error: t/t_assert_future_bad.v:27:31: Future sampled value function called outside property or sequence expression (IEEE 16.9.4)
%Error: t/t_assert_future_bad.v:25:31: Future sampled value function called outside property or sequence expression (IEEE 16.9.4)
: ... note: In instance 't'
27 | else $display("Future=%0d", $steady_gclk(a));
25 | else $display("Future=%0d", $steady_gclk(a));
| ^~~~~~~~~~~~
%Error: t/t_assert_future_bad.v:30:31: Future sampled value function called outside property or sequence expression (IEEE 16.9.4)
%Error: t/t_assert_future_bad.v:28:31: Future sampled value function called outside property or sequence expression (IEEE 16.9.4)
: ... note: In instance 't'
30 | else $display("Future=%0d", $changing_gclk(a));
28 | else $display("Future=%0d", $changing_gclk(a));
| ^~~~~~~~~~~~~~
%Error: Exiting due to

View File

@ -4,12 +4,10 @@
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t ( /*AUTOARG*/
// Inputs
a, clk
);
input a;
input clk;
module t (
input a,
input clk
);
global clocking @(posedge clk);
endclocking

View File

@ -1,6 +1,6 @@
%Error-UNSUPPORTED: t/t_assert_future_unsup.v:21:54: Unsupported/illegal: Future value function used with expression with operator FUNCREF 'func'
%Error-UNSUPPORTED: t/t_assert_future_unsup.v:19:54: Unsupported/illegal: Future value function used with expression with operator FUNCREF 'func'
: ... note: In instance 't'
21 | assert property (@(posedge clk) $future_gclk(a) == func(a));
19 | assert property (@(posedge clk) $future_gclk(a) == func(a));
| ^~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to

View File

@ -4,12 +4,10 @@
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t ( /*AUTOARG*/
// Inputs
a, clk
);
input a;
input clk;
module t (
input a,
input clk
);
function logic func(input logic i);
return i;

View File

@ -4,13 +4,12 @@
// without warranty, 2025 by Wilson Snyder
// SPDX-License-Identifier: CC0-1.0
module t (/*AUTOARG*/
// Inputs
clk
module t (
input clk
);
input clk;
integer cyc; initial cyc=1;
integer cyc;
initial cyc = 1;
Test test (
/*AUTOINST*/
@ -19,13 +18,13 @@ module t (/*AUTOARG*/
.cyc(cyc)
);
always @ (posedge clk) begin
if (cyc!=0) begin
always @(posedge clk) begin
if (cyc != 0) begin
cyc <= cyc + 1;
`ifdef TEST_VERBOSE
$display("cyc=%0d", cyc);
`endif
if (cyc==10) begin
if (cyc == 10) begin
$write("*-* All Finished *-*\n");
$finish;
end
@ -35,7 +34,9 @@ module t (/*AUTOARG*/
endmodule
// Interface for data validation with coverage
interface data_valid_if (input logic clk);
interface data_valid_if (
input logic clk
);
logic enable_invalid_data_checks;
logic valid;
logic [7:0] data;
@ -49,16 +50,15 @@ interface data_valid_if (input logic clk);
endinterface
module Test
(
input clk,
input integer cyc
);
module Test (
input clk,
input integer cyc
);
logic rst_n;
// Instantiate the interface
data_valid_if dv_if(clk);
data_valid_if dv_if (clk);
// Reset logic
initial begin

View File

@ -4,15 +4,14 @@
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkh(gotv,
expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0x exp=%0x (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
`define checkh(gotv, expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0x exp=%0x (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
// verilog_format: on
module t ( /*AUTOARG*/
// Inputs
clk
module t (
input clk
);
input clk;
bit toggle = 0;
int inc = 0;
@ -49,7 +48,8 @@ module t ( /*AUTOARG*/
`endif
if (cyc % 3 == 0) begin
toggle <= 1;
end else begin
end
else begin
toggle <= 0;
end

View File

@ -1,34 +1,34 @@
%Error: t/t_assign_automatic_bad.v:35:10: Dynamically-sized variable not allowed in continuous assignment (IEEE 1800-2023 6.21): 'bad_dyn5'
%Error: t/t_assign_automatic_bad.v:36:10: Dynamically-sized variable not allowed in continuous assignment (IEEE 1800-2023 6.21): 'bad_dyn5'
: ... note: In instance 't'
35 | assign bad_dyn5[0] = empty_dyn;
36 | assign bad_dyn5[0] = empty_dyn;
| ^~~~~~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: t/t_assign_automatic_bad.v:37:12: Automatic lifetime variable not allowed in continuous assignment (IEEE 1800-2023 6.21): 'm_bad1'
%Error: t/t_assign_automatic_bad.v:38:12: Automatic lifetime variable not allowed in continuous assignment (IEEE 1800-2023 6.21): 'm_bad1'
: ... note: In instance 't'
37 | assign c.m_bad1 = 2;
38 | assign c.m_bad1 = 2;
| ^~~~~~
%Error: t/t_assign_automatic_bad.v:47:5: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'bad_dyn6'
%Error: t/t_assign_automatic_bad.v:48:5: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'bad_dyn6'
: ... note: In instance 't'
47 | bad_dyn6[0] <= 2;
48 | bad_dyn6[0] <= 2;
| ^~~~~~~~
%Error: t/t_assign_automatic_bad.v:49:5: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'bad_queue'
%Error: t/t_assign_automatic_bad.v:50:5: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'bad_queue'
: ... note: In instance 't'
49 | bad_queue[0] <= 2;
50 | bad_queue[0] <= 2;
| ^~~~~~~~~
%Error: t/t_assign_automatic_bad.v:51:5: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'bad_assoc'
%Error: t/t_assign_automatic_bad.v:52:5: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'bad_assoc'
: ... note: In instance 't'
51 | bad_assoc[0] <= 2;
52 | bad_assoc[0] <= 2;
| ^~~~~~~~~
%Error: t/t_assign_automatic_bad.v:54:7: Automatic lifetime variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'm_bad2'
%Error: t/t_assign_automatic_bad.v:55:7: Automatic lifetime variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 'm_bad2'
: ... note: In instance 't'
54 | c.m_bad2 <= 2;
55 | c.m_bad2 <= 2;
| ^~~~~~
%Error: t/t_assign_automatic_bad.v:56:10: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 's_dyn'
%Error: t/t_assign_automatic_bad.v:57:10: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 's_dyn'
: ... note: In instance 't'
56 | Cls::s_dyn[0] <= 2;
57 | Cls::s_dyn[0] <= 2;
| ^~~~~
%Error: t/t_assign_automatic_bad.v:58:26: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 's_dyn'
: ... note: In instance 't'
58 | clist[bad_dyn6[0]++].s_dyn[0] <= '1;
| ^~~~~
%Error: t/t_assign_automatic_bad.v:63:7: Dynamically-sized variable not allowed in nonblocking assignment (IEEE 1800-2023 6.21): 's_dyn'
: ... note: In instance 't'
63 | ].s_dyn[0] <= '1;
| ^~~~~
%Error: Exiting due to

View File

@ -18,8 +18,9 @@ class Cls;
int m_bad2;
endclass
module t(clk);
input clk;
module t (
input clk
);
Cls c;
@ -46,16 +47,20 @@ module t(clk);
always @(posedge clk) begin
bad_dyn6[0] <= 2; // <--- Error: nonblocking dynarray element
bad_dyn6 <= empty_dyn; // <--- OK: nonblocking dynarray assignment, not to its element
bad_queue[0] <= 2; // Error: nonblocking queue element assignment
bad_queue <= empty_queue; // OK: nonblocking assignment to queue itself, not to its element
bad_assoc[0] <= 2; // Error: nonblocking associative array element assignment
bad_queue[0] <= 2; // Error: nonblocking queue element assignment
bad_queue <= empty_queue; // OK: nonblocking assignment to queue itself, not to its element
bad_assoc[0] <= 2; // Error: nonblocking associative array element assignment
bad_assoc <= empty_assoc; // OK: nonblocking assignment to associative array itself, not to its element
Cls::s_ok2 <= 2; // OK: nonblocking class static
c.m_bad2 <= 2; // <--- Error: nonblocking class automatic
Cls::s_dyn <= 2; // OK: nonblocking class static dynarray assignment, not to its element
Cls::s_dyn[0] <= 2; // Error: nonblocking class static dynarray element
clist[bad_dyn6[0]++].s_dyn <= '1; // OK: direct nonblocking assignment to dynamically-sized array
clist[bad_dyn6[0]++].s_dyn[0] <= '1; // Error: nonblocking assigment to dynamically-sized array element
clist[
bad_dyn6[0]++
].s_dyn <= '1; // OK: direct nonblocking assignment to dynamically-sized array
clist[
bad_dyn6[0]++
].s_dyn[0] <= '1; // Error: nonblocking assigment to dynamically-sized array element
mt(ok_7);
$stop;
end

View File

@ -38,8 +38,8 @@ class Bar;
endclass
module t;
Iface iface();
Iface iface2();
Iface iface ();
Iface iface2 ();
task clockSome();
#2;

View File

@ -5,13 +5,13 @@
// SPDX-License-Identifier: CC0-1.0
interface Iface;
bit clk;
int x[2:0];
bit clk;
int x[2:0];
clocking cb @(posedge clk);
default input #0 output #0;
inout x;
endclocking
clocking cb @(posedge clk);
default input #0 output #0;
inout x;
endclocking
endinterface
class Foo;
@ -42,8 +42,8 @@ class Bar;
endclass
module t;
Iface iface();
Iface iface2();
Iface iface ();
Iface iface2 ();
task clockSome();
#2;

View File

@ -4,9 +4,11 @@
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0x exp=%0x (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
`define checks(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
class X;
typedef enum int {
@ -31,14 +33,11 @@ class X;
endclass
module t;/*AUTOARG*/
initial begin
X x = new;
$finish;
end
module t;
initial begin
X x = new;
$finish;
end
endmodule

View File

@ -5,7 +5,7 @@
// SPDX-License-Identifier: CC0-1.0
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
module t;

View File

@ -1,6 +1,6 @@
%Error-UNSUPPORTED: t/t_assoc_wildcard_map.v:17:15: Unsupported: Wildcard array 'map' method (IEEE 1800-2023 7.12.5)
%Error-UNSUPPORTED: t/t_assoc_wildcard_map.v:19:15: Unsupported: Wildcard array 'map' method (IEEE 1800-2023 7.12.5)
: ... note: In instance 't'
17 | res = a.map(el) with (el == 2);
19 | res = a.map(el) with (el == 2);
| ^~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to

View File

@ -4,8 +4,10 @@
// any use, without warranty, 2023 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
module t;

View File

@ -9,7 +9,10 @@
// warranty, 2024 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
// verilog_format: off
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
// Test IEEE 1800-2023 concat bit selects, function bit selects, method bit selects

View File

@ -4,17 +4,16 @@
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t
(
input wire [ 31:0] foo,
output reg [144:0] bar,
output reg [144:0] bar2,
output reg [144:0] bar3,
output reg [144:0] bar4
);
// verilator lint_off SELRANGE
assign bar[159:128] = foo;
assign bar2[159] = foo[1];
assign bar3[159 -: 32] = foo;
assign bar4[128 +: 32] = foo;
module t (
input wire [31:0] foo,
output reg [144:0] bar,
output reg [144:0] bar2,
output reg [144:0] bar3,
output reg [144:0] bar4
);
// verilator lint_off SELRANGE
assign bar[159:128] = foo;
assign bar2[159] = foo[1];
assign bar3[159-:32] = foo;
assign bar4[128+:32] = foo;
endmodule

View File

@ -1,6 +1,6 @@
%Error-UNSUPPORTED: t/t_c_width_bad.v:9:22: Unsupported: $c can't generate wider than 64 bits
%Error-UNSUPPORTED: t/t_c_width_bad.v:9:21: Unsupported: $c can't generate wider than 64 bits
: ... note: In instance 't'
9 | bit [99:0] wide = $c100("0");
| ^~~~~
9 | bit [99:0] wide = $c100("0");
| ^~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to

View File

@ -6,8 +6,8 @@
module t;
bit [99:0] wide = $c100("0");
bit [99:0] wide = $c100("0");
initial $display("%d", wide);
initial $display("%d", wide);
endmodule

View File

@ -4,8 +4,10 @@
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
typedef enum {
UVM_TLM_READ_COMMAND,

View File

@ -5,8 +5,11 @@
// SPDX-License-Identifier: CC0-1.0
package foo;
class bar#(type T=int);
endclass
endpackage;
class bar #(
type T = int
);
endclass
endpackage
;
import foo::bar;

View File

@ -4,7 +4,9 @@
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
class uvm_process_guard#(type T=int);
class uvm_process_guard #(
type T = int
);
T m_context;
extern function T get_context();
extern function new(T ctxt);

View File

@ -4,9 +4,11 @@
// any use, without warranty, 2025 by Petr Nohavica
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
`define checks(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
interface class IBottomMid;
pure virtual function void moo(int i);
@ -48,7 +50,7 @@ class middle_class extends bottom_class implements IMid, IBottom;
endfunction
virtual function string bar();
return name;
return name;
endfunction
endclass
@ -75,10 +77,10 @@ module t;
top_class t = s;
IMid im;
`checks( b.name, "middle ahoj 42" );
`checks( s.name, "middle ahoj 42" );
`checks( t.name, "middle ahoj 42" );
`checkh( t.i, 42);
`checks(b.name, "middle ahoj 42");
`checks(s.name, "middle ahoj 42");
`checks(t.name, "middle ahoj 42");
`checkh(t.i, 42);
`checks(s.bar(), "middle ahoj 42");
im = s;
im.moo(42);

View File

@ -4,10 +4,12 @@
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
module m();
module m ();
class c;
static function void fstatic();
`checkh(v, 42);
@ -23,7 +25,7 @@ module m();
int v;
initial begin
v=42;
v = 42;
`checkh(v, 42);
c::fstatic();
classinst = new();

View File

@ -4,16 +4,20 @@
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
class Class1 #(type T);
class Class1 #(
type T
);
static function int get_p();
return 7;
endfunction
endclass
class Class2 #(type T) extends Class1 #(T);
static function int get_p2;
return T::get_p();
endfunction
class Class2 #(
type T
) extends Class1 #(T);
static function int get_p2;
return T::get_p();
endfunction
endclass
module t;

View File

@ -5,14 +5,14 @@
// SPDX-License-Identifier: CC0-1.0
class base #(
type T = int
type T = int
);
function void fbase();
endfunction
function void fbase();
endfunction
endclass
class ext extends base;
function void fext();
super.fbase();
endfunction
function void fext();
super.fbase();
endfunction
endclass

View File

@ -4,40 +4,44 @@
// without warranty.
// SPDX-License-Identifier: CC0-1.0
class func_c #(parameter p_width=4);
static function logic[p_width-1:0] func(
input logic[p_width-1:0] inb
);
func = inb;
endfunction
class func_c #(
parameter p_width = 4
);
static function logic [p_width-1:0] func(input logic [p_width-1:0] inb);
func = inb;
endfunction
endclass
module modA #(parameter p_width = 7)(
input logic [p_width-1:0] sig_a
,output logic [p_width-1:0] sig_b
module modA #(
parameter p_width = 7
) (
input logic [p_width-1:0] sig_a,
output logic [p_width-1:0] sig_b
);
assign sig_b = func_c#(p_width)::func(sig_a);
assign sig_b = func_c#(p_width)::func(sig_a);
endmodule
module the_top();
localparam int Size = 3;
module the_top ();
localparam int Size = 3;
logic [Size-1:0] sig_a;
logic [Size-1:0] sig_b;
logic [Size-1:0] sig_a;
logic [Size-1:0] sig_b;
modA #(.p_width(Size)) modA(
.sig_a(sig_a)
,.sig_b(sig_b)
);
modA #(
.p_width(Size)
) modA (
.sig_a(sig_a),
.sig_b(sig_b)
);
//assign sig_b = func_c#(p_width)::func(inb_i);
//assign sig_b = func_c#(p_width)::func(inb_i);
initial begin
sig_a = 'h3;
#1;
$display("sig_a=%d, sig_b=%d", sig_a, sig_b);
if(sig_b != 'h3) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
initial begin
sig_a = 'h3;
#1;
$display("sig_a=%d, sig_b=%d", sig_a, sig_b);
if (sig_b != 'h3) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -4,39 +4,43 @@
// without warranty.
// SPDX-License-Identifier: CC0-1.0
class func_c #(parameter p_width=4);
static function logic[p_width-1:0] func(
input logic[p_width-1:0] inb
);
class func_c #(
parameter p_width = 4
);
static function logic [p_width-1:0] func(input logic [p_width-1:0] inb);
func = inb;
endfunction
endclass
module modA #(parameter p_width = 7)(
input logic [p_width-1:0] sig_a
,output logic [p_width-1:0] sig_b
module modA #(
parameter p_width = 7
) (
input logic [p_width-1:0] sig_a,
output logic [p_width-1:0] sig_b
);
assign sig_b = func_c#(p_width)::func(sig_a);
endmodule
module the_top();
module the_top ();
localparam int Size = 3;
logic [Size-1:0] sig_a;
logic [Size-1:0] sig_b;
logic [Size-1:0] sig_c;
modA #(.p_width(Size)) modA(
.sig_a(sig_a)
,.sig_b(sig_b)
modA #(
.p_width(Size)
) modA (
.sig_a(sig_a),
.sig_b(sig_b)
);
initial begin
sig_a = 'h3;
sig_c = func_c#(Size)::func('h5);
#1;
if(sig_b != 'h3) $stop;
if(sig_c != 'h5) $stop;
if (sig_b != 'h3) $stop;
if (sig_c != 'h5) $stop;
$write("*-* All Finished *-*\n");
$finish;
end

View File

@ -4,40 +4,42 @@
// without warranty.
// SPDX-License-Identifier: CC0-1.0
class func_c #(parameter p_width=4);
typedef struct packed {
logic[p_width-1:0] data;
} my_type_t;
static function my_type_t func(
input logic[p_width-1:0] inb
);
class func_c #(
parameter p_width = 4
);
typedef struct packed {logic [p_width-1:0] data;} my_type_t;
static function my_type_t func(input logic [p_width-1:0] inb);
func.data = inb;
endfunction
endclass
module modA #(parameter p_width = 7)(
input func_c#(p_width)::my_type_t sig_a,
output func_c#(p_width)::my_type_t sig_b
module modA #(
parameter p_width = 7
) (
input func_c#(p_width)::my_type_t sig_a,
output func_c#(p_width)::my_type_t sig_b
);
assign sig_b.data = func_c#(p_width)::func(sig_a);
endmodule
module the_top();
module the_top ();
localparam int Size = 3;
func_c#(Size)::my_type_t sig_a, sig_b, sig_c;
func_c #(Size)::my_type_t sig_a, sig_b, sig_c;
modA #(.p_width(Size)) modA(
.sig_a(sig_a),
.sig_b(sig_b)
modA #(
.p_width(Size)
) modA (
.sig_a(sig_a),
.sig_b(sig_b)
);
initial begin
sig_a.data = 'h3;
sig_c.data = func_c#(Size)::func('h5);
#1;
if(sig_b.data != 'h3) $stop;
if(sig_c.data != 'h5) $stop;
if (sig_b.data != 'h3) $stop;
if (sig_c.data != 'h5) $stop;
$write("*-* All Finished *-*\n");
$finish;
end

View File

@ -4,28 +4,22 @@
// without warranty.
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkd(gotv,expv) \
do if ((gotv) !== (expv)) begin \
$write("%%Error: %s:%0d: got=%0d exp=%0d\n", \
`__FILE__,`__LINE__, (gotv), (expv)); \
`stop; \
end while(0);
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
class pipeline_class #(
parameter type XWORD = logic
parameter type XWORD = logic
);
typedef struct packed {
XWORD pc;
} if_id_t;
typedef struct packed {XWORD pc;} if_id_t;
endclass
module pipe_reg #(
parameter type T = logic
)();
parameter type T = logic
) ();
initial begin
#1;
`checkd($bits(T), 8);
@ -35,9 +29,9 @@ endmodule
module the_top #() ();
typedef logic [7:0] my_t;
typedef pipeline_class #(my_t)::if_id_t if_id2_t;
typedef pipeline_class#(my_t)::if_id_t if_id2_t;
typedef if_id2_t if_id_t;
pipe_reg #(if_id_t) if_id_reg();
pipe_reg #(if_id_t) if_id_reg ();
initial begin
#1;

View File

@ -4,7 +4,9 @@
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
class factory #(type T);
class factory #(
type T
);
static function T create;
T obj = new;
return obj;
@ -24,10 +26,9 @@ endclass
module t;
initial begin
foo f;
if (bit'($random))
f = bar::create;
else
f = factory#(foo)::create();
if (bit'($random)) f = bar::create;
else f = factory#(foo)::create();
$finish;
end
endmodule;
endmodule
;

View File

@ -1,5 +1,5 @@
%Error: t/t_class_scope_import_bad.v:11:11: Import statement directly within a class scope is illegal
11 | import pkg::*;
| ^~~
%Error: t/t_class_scope_import_bad.v:11:10: Import statement directly within a class scope is illegal
11 | import pkg::*;
| ^~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to

View File

@ -8,8 +8,8 @@ package pkg;
endpackage
class genericClass;
import pkg::*;
import pkg::*;
endclass
module tb_top();
module tb_top ();
endmodule

View File

@ -1,5 +1,5 @@
%Error: t/t_class_super_new_noextend_bad.v:10:12: 'super' used on non-extended class (IEEE 1800-2023 8.15)
10 | super.new();
| ^
%Error: t/t_class_super_new_noextend_bad.v:10:10: 'super' used on non-extended class (IEEE 1800-2023 8.15)
10 | super.new();
| ^
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to

View File

@ -6,7 +6,7 @@
//
class Cls;
function new();
super.new(); // Bad - no extends
endfunction
function new();
super.new(); // Bad - no extends
endfunction
endclass

View File

@ -1,5 +1,5 @@
%Error: t/t_class_to_basic_assignment_bad.v:26:29: Assign RHS 'class{}Foo' cannot be assigned to non-class 'int'
26 | new_node.phase_done = get();
| ^
%Error: t/t_class_to_basic_assignment_bad.v:26:27: Assign RHS 'class{}Foo' cannot be assigned to non-class 'int'
26 | new_node.phase_done = get();
| ^
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to

View File

@ -12,21 +12,21 @@ class Foo;
return ans;
endfunction
static function int create ();
static function int create();
return 3;
endfunction
function string get_name ();
function string get_name();
return "bar";
endfunction
function void add(Foo phase);
Foo new_node;
if (new_node.get_name() == "run") begin
new_node.phase_done = get();
new_node.phase_done = get();
end
else begin
new_node.phase_done = create();
new_node.phase_done = create();
end
endfunction
endclass

View File

@ -4,7 +4,7 @@
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
`timescale 1ms/1ns
`timescale 1ms / 1ns
module t;
bit clk = 0;
bit data = 1;
@ -21,12 +21,11 @@ module t;
end
initial begin
#4
if (data != 1) $stop;
#4 if (data != 1) $stop;
if (cb.data != 0) $stop;
#1;
#1step;
if(cb.data != 0) $stop;
if (cb.data != 0) $stop;
$write("*-* All Finished *-*\n");
$finish;
end

View File

@ -4,7 +4,7 @@
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
`timescale 1ms/1ns
`timescale 1ms / 1ns
module t;
bit clk = 0;
bit data = 1;
@ -21,12 +21,11 @@ module t;
end
initial begin
#4
if(data != 1 ) $stop;
if(cb.data != 0) $stop;
#4 if (data != 1) $stop;
if (cb.data != 0) $stop;
#1;
#1step;
if(cb.data != 1) $stop;
if (cb.data != 1) $stop;
$write("*-* All Finished *-*\n");
$finish;
end

View File

@ -6,7 +6,7 @@
module t;
// Test --work allows selecting two different libraries for these instances
m1 u_1();
m2 u_2();
m1 u_1 ();
m2 u_2 ();
final $write("*-* All Finished *-*\n");
endmodule

View File

@ -5,7 +5,7 @@
// SPDX-License-Identifier: CC0-1.0
module m1;
m3 u_13();
m3 u_13 ();
initial $display("liba:m1 %%m=%m %%l=%l");
endmodule

View File

@ -5,7 +5,7 @@
// SPDX-License-Identifier: CC0-1.0
module m2;
m3 u_23();
m3 u_23 ();
initial $display("libb:m2 %%m=%m %%l=%l");
endmodule

View File

@ -73,11 +73,13 @@ module t_constraint_global_arr_unsup;
o.m_mid_arr[1].m_arr[2].m_y == 400) begin
$display("*-* All Finished *-*");
$finish;
end else begin
end
else begin
$display("*-* FAILED *-*");
$stop;
end
end else begin
end
else begin
$display("*-* FAILED: randomize() returned 0 *-*");
$stop;
end

View File

@ -6,9 +6,7 @@
class RandomValue;
rand int value;
constraint small_int_c {
value < 10;
}
constraint small_int_c {value < 10;}
task disable_val();
value.rand_mode(0);
endtask

View File

@ -59,9 +59,9 @@
{"type":"BASICDTYPE","name":"logic","addr":"(GB)","loc":"d,22:14,22:15","dtypep":"(GB)","keyword":"logic","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"logic","addr":"(OB)","loc":"d,25:21,25:22","dtypep":"(OB)","keyword":"logic","range":"31:0","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"string","addr":"(M)","loc":"d,73:7,73:13","dtypep":"(M)","keyword":"string","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"int","addr":"(Q)","loc":"d,8:9,8:12","dtypep":"(Q)","keyword":"int","range":"31:0","generic":true,"rangep": []},
{"type":"BASICDTYPE","name":"int","addr":"(Q)","loc":"d,8:9,8:12","dtypep":"(Q)","keyword":"int","range":"31:0","generic":true,"signed":true,"rangep": []},
{"type":"BASICDTYPE","name":"bit","addr":"(U)","loc":"d,11:9,11:12","dtypep":"(U)","keyword":"bit","generic":true,"rangep": []},
{"type":"UNPACKARRAYDTYPE","name":"","addr":"(Y)","loc":"d,15:18,15:19","dtypep":"(Y)","isCompound":false,"declRange":"[0:1]","generic":false,"refDTypep":"(Q)","childDTypep": [],
{"type":"UNPACKARRAYDTYPE","name":"","addr":"(Y)","loc":"d,15:18,15:19","dtypep":"(Y)","isCompound":false,"declRange":"[0:1]","generic":false,"signed":true,"refDTypep":"(Q)","childDTypep": [],
"rangep": [
{"type":"RANGE","name":"","addr":"(PB)","loc":"d,15:18,15:19","ascending":true,"fromBracket":true,
"leftp": [

View File

@ -5,12 +5,9 @@
// any use, without warranty, 2024 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
module t (
input clk
);
int cyc, bump, result;
logic foo;
@ -326,7 +323,7 @@
-000000 point: comment=else hier=top.t
000010 cyc <= cyc + 1;
+000010 point: comment=block hier=top.t
%000009 if (cyc==9) begin
%000009 if (cyc == 9) begin
-000001 point: comment=if hier=top.t
-000009 point: comment=else hier=top.t
%000001 $write("*-* All Finished *-*\n");
@ -334,6 +331,6 @@
%000001 $finish;
-000001 point: comment=if hier=top.t
end
end
end
endmodule

View File

@ -4,12 +4,9 @@
// any use, without warranty, 2024 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
module t (
input clk
);
int cyc, bump, result;
logic foo;
@ -73,9 +70,9 @@ module t (/*AUTOARG*/
if (($sformatf("abc") != "abc") && foo) bump <= bump + 1;
if (foo && foo) bump <= bump + 1;
cyc <= cyc + 1;
if (cyc==9) begin
if (cyc == 9) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
end
endmodule

View File

@ -1,8 +1,8 @@
%Error: t/t_covergroup_in_class_duplicate_bad.v:13:16: Duplicate declaration of CLASS '__vlAnonCG_embeddedCg': '__vlAnonCG_embeddedCg'
13 | covergroup embeddedCg;
| ^~~~~~~~~~
t/t_covergroup_in_class_duplicate_bad.v:9:16: ... Location of original declaration
9 | covergroup embeddedCg;
| ^~~~~~~~~~
%Error: t/t_covergroup_in_class_duplicate_bad.v:13:14: Duplicate declaration of CLASS '__vlAnonCG_embeddedCg': '__vlAnonCG_embeddedCg'
13 | covergroup embeddedCg;
| ^~~~~~~~~~
t/t_covergroup_in_class_duplicate_bad.v:9:14: ... Location of original declaration
9 | covergroup embeddedCg;
| ^~~~~~~~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to

View File

@ -6,11 +6,11 @@
/* verilator lint_off COVERIGN */
class myClass;
covergroup embeddedCg;
covergroup embeddedCg;
endgroup
endgroup
covergroup embeddedCg;
covergroup embeddedCg;
endgroup
endgroup
endclass

View File

@ -10,11 +10,10 @@
`define STRINGIFY(x) `"x`"
module test (
);
initial begin
$display("TEST_MACRO %s", `STRINGIFY(`TEST_MACRO));
$finish;
end
module test ();
initial begin
$display("TEST_MACRO %s", `STRINGIFY(`TEST_MACRO));
$finish;
end
endmodule

Some files were not shown because too many files have changed in this diff Show More