Merge branch 'verilator:master' into fix/broken-varscope-linkable
This commit is contained in:
commit
52ae3d0767
|
|
@ -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
13
Changes
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -541,6 +541,7 @@ YAML_FILES = \
|
|||
.*.yml \
|
||||
.github/*.yml \
|
||||
.github/*/*.yml \
|
||||
CITATION.cff \
|
||||
|
||||
######################################################################
|
||||
# Format
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
========================
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -284,6 +284,7 @@ RAW_OBJS_PCH_ASTNOMT = \
|
|||
V3Gate.o \
|
||||
V3HierBlock.o \
|
||||
V3Inline.o \
|
||||
V3InlineCFuncs.o \
|
||||
V3Inst.o \
|
||||
V3InstrCount.o \
|
||||
V3Interface.o \
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 "
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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}; }
|
||||
;
|
||||
|
||||
//************************************************
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ module t #(
|
|||
.ID_T(ID_T),
|
||||
.STAGE_IDS(STAGE_IDS)
|
||||
) pipe (
|
||||
.*);
|
||||
.*
|
||||
);
|
||||
|
||||
initial $finish;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,8 @@
|
|||
// verilog_format: on
|
||||
|
||||
module t (
|
||||
/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
input clk
|
||||
);
|
||||
|
||||
global clocking @(posedge clk);
|
||||
endclocking
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ class Bar;
|
|||
endclass
|
||||
|
||||
module t;
|
||||
Iface iface();
|
||||
Iface iface2();
|
||||
Iface iface ();
|
||||
Iface iface2 ();
|
||||
|
||||
task clockSome();
|
||||
#2;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ package pkg;
|
|||
endpackage
|
||||
|
||||
class genericClass;
|
||||
import pkg::*;
|
||||
import pkg::*;
|
||||
endclass
|
||||
|
||||
module tb_top();
|
||||
module tb_top ();
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
//
|
||||
|
||||
class Cls;
|
||||
function new();
|
||||
super.new(); // Bad - no extends
|
||||
endfunction
|
||||
function new();
|
||||
super.new(); // Bad - no extends
|
||||
endfunction
|
||||
endclass
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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": [
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
/* verilator lint_off COVERIGN */
|
||||
class myClass;
|
||||
covergroup embeddedCg;
|
||||
covergroup embeddedCg;
|
||||
|
||||
endgroup
|
||||
endgroup
|
||||
|
||||
covergroup embeddedCg;
|
||||
covergroup embeddedCg;
|
||||
|
||||
endgroup
|
||||
endgroup
|
||||
endclass
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue