diff --git a/.codacy.yml b/.codacy.yml index 31a95b117..409c852ee 100644 --- a/.codacy.yml +++ b/.codacy.yml @@ -3,3 +3,4 @@ exclude_paths: - '.github/**' - 'ci/build_verilator.sh' - 'include/vltstd/**' + - 'nodist/fastcov.py' diff --git a/.travis.yml b/.travis.yml index e9cbc4c3b..aeb2146eb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,176 +8,107 @@ version: ~> 1.0 -os: linux language: cpp -cache: ccache - -env: - global: - - VERILATOR_CACHE=$HOME/verilator_cache - - VERILATOR_ROOT=$PWD - - VERILATOR_NUM_JOBS=$(echo `nproc` + 1 | bc) - - VERILATOR_CONFIG_FLAGS="--enable-maintainer-mode --enable-longtests" - - VERILATOR_AUTHOR_SITE=1 cache: directories: - - $VERILATOR_CACHE + - $HOME/.ccache -before_install: -# Perl modules needed for testing -# Not listing Bit::Vector as slow to install, and only skips one test - - touch temp.cpp ; g++ -E -dM -c temp.cpp | sort ; rm -rf temp.cpp - - yes yes | sudo cpan -fi Unix::Processors Parallel::Forker - - sudo apt-get install gdb gtkwave - - sudo apt-get install libgoogle-perftools-dev -before_script: - - bash -x ci/build_vcddiff.sh - - bash -x ci/build_verilator.sh -after_script: - - ccache -s +env: + global: + - VERILATOR_ROOT=$TRAVIS_BUILD_DIR +# The list and order of build stages stages: - - "Build Verilator" - - test + - build # Build Verilator + - test # Run tests +# Dump info about the environment for debugging +before_install: + # To dump the script that Travis itself is executing, add 'cat $0' here + - cd "$TRAVIS_BUILD_DIR" # Skipping the git clone in later stages requires this + - export CCACHE_MAXSIZE=$(ci/travis-ccache-size.bash) # Set here after the 'cd' + - env | sort + - ls -lA . + - ls -lA bin + - g++ -E -dM -c -x c++ /dev/null | sort + - clang++ -E -dM -c -x c++ /dev/null | sort + +# Install all dependencies +install: + - ./ci/travis-install.bash + +before_script: + # ccache maintenance + - ./ci/travis-ccache-maint.bash + # On Focal, set the SystemC installation location + - | + if [ "$TRAVIS_DIST" = "focal" ]; then + export SYSTEMC_INCLUDE=/usr/include + export SYSTEMC_LIBDIR=/usr/lib/x86_64-linux-gnu + fi + +before_cache: + - ccache -s -z + +# All jobs run the same script +script: ./ci/travis-script.bash + +# Enumerate all the jobs jobs: include: - - if: type != cron - stage: "Build Verilator" - name: Build Verilator - compiler: gcc - script: echo "Done building Verilator" -# Non-cron build will just run on whatever linux flavor we get - - if: type != cron - stage: test - name: Dist test - compiler: gcc - script: ci/test.sh dist - - if: type != cron - stage: test - name: Vlt test - compiler: gcc - script: ci/test.sh vlt - - if: type != cron - stage: test - name: Vltmt set 0 test - compiler: gcc - script: ci/test.sh vltmt0 - - if: type != cron - stage: test - name: Vltmt set 1 test - compiler: gcc - script: ci/test.sh vltmt1 -# Cron builds try different OS/compiler combinations - - if: type = cron - stage: "Build Verilator" - name: Build xenial gcc Verilator - os: linux - dist: xenial - compiler: gcc - script: echo "Done building Verilator" - - if: type = cron - stage: test - name: Xenial gcc dist test - os: linux - dist: xenial - compiler: gcc - script: ci/test.sh dist - - if: type = cron - stage: test - name: Xenial gcc vlt test - os: linux - dist: xenial - compiler: gcc - script: ci/test.sh vlt - - if: type = cron - stage: test - name: Xenial gcc vltmt test - os: linux - dist: xenial - compiler: gcc - script: ci/test.sh vltmt - - if: type = cron - stage: "Build Verilator" - name: Build xenial clang Verilator - os: linux - dist: xenial - compiler: clang - script: echo "Done building Verilator" - - if: type = cron - stage: test - name: Xenial clang dist test - os: linux - dist: xenial - compiler: clang - script: ci/test.sh dist - - if: type = cron - stage: test - name: Xenial clang vlt test - os: linux - dist: xenial - compiler: clang - script: ci/test.sh vlt - - if: type = cron - stage: test - name: Xenial clang vltmt test - os: linux - dist: xenial - compiler: clang - script: ci/test.sh vltmt -# - if: type = cron -# stage: "Build Verilator" -# name: Build OSX gcc Verilator -# os: osx -# compiler: gcc -# script: echo "Done building Verilator" -# - if: type = cron -# stage: test -# name: OSX gcc dist test -# os: osx -# compiler: gcc -# script: ci/test.sh dist -# - if: type = cron -# stage: test -# name: OSX gcc vlt test -# os: osx -# compiler: gcc -# script: ci/test.sh vlt -# - if: type = cron -# stage: test -# name: OSX gcc vltmt test -# os: osx -# compiler: gcc -# script: ci/test.sh vltmt - - if: type = cron - stage: "Build Verilator" - name: Build trusty gcc Verilator - os: linux - dist: trusty - compiler: gcc - script: echo "Done building Verilator" - - if: type = cron - stage: test - name: Trusty gcc dist test - os: linux - dist: trusty - compiler: gcc - script: ci/test.sh dist - - if: type = cron - stage: test - name: Trusty gcc vlt test - os: linux - dist: trusty - compiler: gcc - script: ci/test.sh vlt - - if: type = cron - stage: test - os: linux - dist: trusty - name: Trusty gcc vltmt test - compiler: gcc - script: ci/test.sh vltmt + ############################################################################ + # Jobs in the 'build' stage + ############################################################################ + # GCC builds + - {stage: build, if: type = cron, os: linux, dist: trusty, compiler: gcc, workspaces: {create: {name: trusty-gcc, paths: .}}} + - {stage: build, if: type = cron, os: linux, dist: xenial, compiler: gcc, workspaces: {create: {name: xenial-gcc, paths: .}}} + - {stage: build, if: type = cron, os: linux, dist: bionic, compiler: gcc, workspaces: {create: {name: bionic-gcc, paths: .}}} + - {stage: build, os: linux, dist: focal, compiler: gcc, workspaces: {create: {name: focal-gcc, paths: .}}} + # Clang builds + - {stage: build, if: type = cron, os: linux, dist: xenial, compiler: clang, workspaces: {create: {name: xenial-clang, paths: .}}} + - {stage: build, os: linux, dist: focal, compiler: clang, workspaces: {create: {name: focal-clang, paths: .}}} + # Coverage build + - {stage: build, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {create: {name: coverage, paths: .}}, env: COVERAGE=1} + ############################################################################ + # Jobs in the 'test' stage + ############################################################################ + # GCC tests + - {stage: test, if: type = cron, os: linux, dist: trusty, compiler: gcc, workspaces: {use: trusty-gcc}, git: {clone: false}, env: TESTS=dist-vlt-0} + - {stage: test, if: type = cron, os: linux, dist: trusty, compiler: gcc, workspaces: {use: trusty-gcc}, git: {clone: false}, env: TESTS=dist-vlt-1} + - {stage: test, if: type = cron, os: linux, dist: trusty, compiler: gcc, workspaces: {use: trusty-gcc}, git: {clone: false}, env: TESTS=vltmt-0} + - {stage: test, if: type = cron, os: linux, dist: trusty, compiler: gcc, workspaces: {use: trusty-gcc}, git: {clone: false}, env: TESTS=vltmt-1} + - {stage: test, if: type = cron, os: linux, dist: xenial, compiler: gcc, workspaces: {use: xenial-gcc}, git: {clone: false}, env: TESTS=dist-vlt-0} + - {stage: test, if: type = cron, os: linux, dist: xenial, compiler: gcc, workspaces: {use: xenial-gcc}, git: {clone: false}, env: TESTS=dist-vlt-1} + - {stage: test, if: type = cron, os: linux, dist: xenial, compiler: gcc, workspaces: {use: xenial-gcc}, git: {clone: false}, env: TESTS=vltmt-0} + - {stage: test, if: type = cron, os: linux, dist: xenial, compiler: gcc, workspaces: {use: xenial-gcc}, git: {clone: false}, env: TESTS=vltmt-1} + - {stage: test, if: type = cron, os: linux, dist: bionic, compiler: gcc, workspaces: {use: bionic-gcc}, git: {clone: false}, env: TESTS=dist-vlt-0} + - {stage: test, if: type = cron, os: linux, dist: bionic, compiler: gcc, workspaces: {use: bionic-gcc}, git: {clone: false}, env: TESTS=dist-vlt-1} + - {stage: test, if: type = cron, os: linux, dist: bionic, compiler: gcc, workspaces: {use: bionic-gcc}, git: {clone: false}, env: TESTS=vltmt-0} + - {stage: test, if: type = cron, os: linux, dist: bionic, compiler: gcc, workspaces: {use: bionic-gcc}, git: {clone: false}, env: TESTS=vltmt-1} + - {stage: test, if: type != cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: focal-gcc}, git: {clone: false}, env: TESTS=dist-vlt-0} + - {stage: test, if: type != cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: focal-gcc}, git: {clone: false}, env: TESTS=dist-vlt-1} + - {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: focal-gcc}, git: {clone: false}, env: TESTS=vltmt-0} + - {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: focal-gcc}, git: {clone: false}, env: TESTS=vltmt-1} + # Clang tests + - {stage: test, if: type = cron, os: linux, dist: xenial, compiler: clang, workspaces: {use: xenial-clang}, git: {clone: false}, env: TESTS=dist-vlt-0} + - {stage: test, if: type = cron, os: linux, dist: xenial, compiler: clang, workspaces: {use: xenial-clang}, git: {clone: false}, env: TESTS=dist-vlt-1} + - {stage: test, if: type = cron, os: linux, dist: xenial, compiler: clang, workspaces: {use: xenial-clang}, git: {clone: false}, env: TESTS=vltmt-0} + - {stage: test, if: type = cron, os: linux, dist: xenial, compiler: clang, workspaces: {use: xenial-clang}, git: {clone: false}, env: TESTS=vltmt-1} + - {stage: test, if: type = cron, os: linux, dist: focal, compiler: clang, workspaces: {use: focal-clang}, git: {clone: false}, env: TESTS=dist-vlt-0} + - {stage: test, if: type = cron, os: linux, dist: focal, compiler: clang, workspaces: {use: focal-clang}, git: {clone: false}, env: TESTS=dist-vlt-1} + - {stage: test, if: type != cron, os: linux, dist: focal, compiler: clang, workspaces: {use: focal-clang}, git: {clone: false}, env: TESTS=vltmt-0} + - {stage: test, if: type != cron, os: linux, dist: focal, compiler: clang, workspaces: {use: focal-clang}, git: {clone: false}, env: TESTS=vltmt-1} + # Coverage tests + - {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-dist} + - {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vlt-0} + - {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vlt-1} + - {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vlt-2} + - {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vlt-3} + - {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vltmt-0} + - {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vltmt-1} + - {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vltmt-2} + - {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vltmt-3} notifications: email: diff --git a/Changes b/Changes index cfff91f11..f0ab90451 100644 --- a/Changes +++ b/Changes @@ -3,50 +3,92 @@ Revision history for Verilator The contributors that suggested a given feature are shown in []. Thanks! +* Verilator 4.036 2020-06-06 + +** OPT_FAST is now -Os by default. See the BENCHMARKING & OPTIMIZATION part + of the manual if you experience issues with compilation speed. + +*** Configure now enables SystemC if it is installed as a system headers, + e.g. with 'apt-get install systemc-dev'. + +*** Add --waiver-output flag that writes a verilator config file (.vlt) with + waivers to the warnings emitted during a Verilator run. + +*** Support verilator_coverage --write-info for lcov HTML reports. + Line Coverage now tracks all statement lines, not just branch lines. + +*** --output-split is now on by default. VM_PARALLEL_BUILDS is set by + default iff the --output-split caused an actual file split to occur. + --output-split-cfuncs and --output-split-ctrace now default to the + value of --output-split. These changes should improve build times of + medium and large designs with default options. User makefiles may + require changes. + +*** The run-time library is now compiled with -Os by default. (#2369, #2373) + +**** Support multi channel descriptor I/O (#2190) [Stephen Henry] + +**** Support $countbits. (#2287) [Yossi Nivin] + +**** Support $isunbounded and parameter $. (#2104) + +**** Support unpacked array .sum and .product. + +**** Support prefix/postfix increment/decrement. (#2223) [Maciej Sobkowski] + +**** Fix FST tracing of little bit endian signals. [Geza Lore] + +**** Fix +: and -: on unpacked arrays. (#2304) [engr248] + +**** Fix $isunknown with constant Z's. + +**** Fix queues and dynamic array wide ops. (#2352) [Vassilis Papaefstathiou] + + * Verilator 4.034 2020-05-03 -** Add simplistic class support with many restrictions, see manual, #377. +** Add simplistic class support with many restrictions, see manual. (#377) -** Support IEEE time units and time precisions, #234. +** Support IEEE time units and time precisions. (#234) Includes `timescale, $printtimescale, $timeformat. VL_TIME_MULTIPLIER, VL_TIME_PRECISION, VL_TIME_UNIT have been removed - and the time precision must now match the SystemC time precision. To + and the time precision must now match the SystemC time precision. To get closer behavior to older versions, use e.g. --timescale-override "1ps/1ps". -** Add --build to call make automatically, #2249. [Yutetsu TAKATSUKASA] +** Add --build to call make automatically. (#2249) [Yutetsu TAKATSUKASA] ** Configuring with ccache present now defaults to using it; see OBJCACHE. -** Fix DPI import/export to be standard compliant, #2236. [Geza Lore] +** Fix DPI import/export to be standard compliant. (#2236) [Geza Lore] -** Add --trace-threads for general multithreaded tracing, #2269. [Geza Lore] +** Add --trace-threads for general multithreaded tracing. (#2269) [Geza Lore] -*** Add --flatten for use with --xml-only, #2270. [James Hanlon] +*** Add --flatten for use with --xml-only. (#2270) [James Hanlon] -**** Greatly improve FST/VCD dump performance, #2244, #2246, #2250, #2257. [Geza Lore] +**** Greatly improve FST/VCD dump performance (#2244) (#2246) (#2250) (#2257) [Geza Lore] -**** Support $ferror, and $fflush without arguments, #1638. +**** Support $ferror, and $fflush without arguments. (#1638) **** Support event data type (with some restrictions). -**** Support $root, #2150. [Keyi Zhang] +**** Support $root. (#2150) [Keyi Zhang] **** Add error if use SystemC 2.2 and earlier (pre-2011) as is deprecated. -**** Fix build of fast path tracing code to use OPT_FAST, #2245. [Geza Lore] +**** Fix build of fast path tracing code to use OPT_FAST. (#2245) [Geza Lore] -**** Fix arrayed instances connecting to slices, #2263. [Don/engr248] +**** Fix arrayed instances connecting to slices. (#2263) [Don/engr248] -**** Fix error on unpacked connecting to packed, #2288. [Joseph Shaker] +**** Fix error on unpacked connecting to packed. (#2288) [Joseph Shaker] -**** Fix logical not optimization with empty begin, #2291. [Baltazar Ortiz] +**** Fix logical not optimization with empty begin. (#2291) [Baltazar Ortiz] -**** Fix reduction OR on wide data, broke in v4.026, #2300. [Jack Koenig] +**** Fix reduction OR on wide data, broke in v4.026. (#2300) [Jack Koenig] -**** Fix clock enables with bit-extends, #2299. [Marco Widmer] +**** Fix clock enables with bit-extends. (#2299) [Marco Widmer] -**** Fix MacOs Homebrew by removing default LIBS, #2298. [Ryan Clarke] +**** Fix MacOs Homebrew by removing default LIBS. (#2298) [Ryan Clarke] * Verilator 4.032 2020-04-04 @@ -55,50 +97,50 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Add GCC 9-style line number prefix when showing source text for errors. -*** Add setting VM_PARALLEL_BUILDS=1 when using --output-split, #2185. +*** Add setting VM_PARALLEL_BUILDS=1 when using --output-split. (#2185) *** Change --quiet-exit to also suppress 'Exiting due to N errors'. **** Suppress REALCVT for whole real numbers. -**** Support split_var in vlt files, #2219. [Marco Widmer] +**** Support split_var in vlt files. (#2219) [Marco Widmer] -**** Fix parameter type redeclaring a type, #2195. [hdzhangdoc] +**** Fix parameter type redeclaring a type. (#2195) [hdzhangdoc] -**** Fix VCD open with empty filename, #2198. [Julius Baxter] +**** Fix VCD open with empty filename. (#2198) [Julius Baxter] -**** Fix packages as enum base types, #2202. [Driss Hafdi] +**** Fix packages as enum base types. (#2202) [Driss Hafdi] -**** Fix duplicate typedefs in generate for, #2205. [hdzhangdoc] +**** Fix duplicate typedefs in generate for. (#2205) [hdzhangdoc] -**** Fix MinW portability, #2114. [Sean Cross] +**** Fix MinW portability. (#2114) [Sean Cross] -**** Fix assertions with unique case inside, #2199. [hdzhangdoc] +**** Fix assertions with unique case inside. (#2199) [hdzhangdoc] **** Fix implicit conversion of floats to wide integers. * Verilator 4.030 2020-03-08 -** Add split_var metacomment to assist UNOPTFLAT fixes, #2066. [Yutetsu TAKATSUKASA] +** Add split_var metacomment to assist UNOPTFLAT fixes. (#2066) [Yutetsu TAKATSUKASA] -** Add support for $dumpfile and $dumpvars, #2126. [Alexander Grobman] +** Add support for $dumpfile and $dumpvars. (#2126) [Alexander Grobman] -** Add support for dynamic arrays, #379. +** Add support for dynamic arrays. (#379) *** Add +verilator+noassert flag to disable assertion checking. [Tobias Wölfel] -*** Add check for assertOn for asserts, #2162. [Tobias Wölfel] +*** Add check for assertOn for asserts. (#2162) [Tobias Wölfel] *** Add --structs-packed for forward compatibility. -*** Fix genblk naming with directly nested generate blocks, #2176. [Alexander Grobman] +*** Fix genblk naming with directly nested generate blocks. (#2176) [Alexander Grobman] -**** Implement $displayb/o/h, $writeb/o/h, etc, #1637. +**** Implement $displayb/o/h, $writeb/o/h, etc. (#1637) **** Use gcc -Os in examples instead of -O2 for better average performance. -**** Fix undeclared VL_SHIFTR_WWQ, #2114. [Alex Solomatnikov] +**** Fix undeclared VL_SHIFTR_WWQ. (#2114) [Alex Solomatnikov] * Verilator 4.028 2020-02-08 @@ -107,43 +149,43 @@ The contributors that suggested a given feature are shown in []. Thanks! ** Add -match to lint_off to waive warnings. [Philipp Wagner] -*** Link Verilator binary partially statically, #2146. [Geza Lore] +*** Link Verilator binary partially statically. (#2146) [Geza Lore] -*** Verilation speed improvements, #2133, #2138. [Geza Lore] +*** Verilation speed improvements (#2133) (#2138) [Geza Lore] -*** Support libgoogle-perftools-dev's libtcmalloc if available, #2137. [Geza Lore] +*** Support libgoogle-perftools-dev's libtcmalloc if available. (#2137) [Geza Lore] -*** Support $readmem/$writemem with assoc arrarys, #2100. [agrobman] +*** Support $readmem/$writemem with assoc arrarys. (#2100) [agrobman] -**** Support type(expression) operator and $typename, #1650. +**** Support type(expression) operator and $typename. (#1650) -**** Support left justified $display, #2101. [Pieter Kapsenberg] +**** Support left justified $display. (#2101) [Pieter Kapsenberg] **** Support string character access via indexing. -**** Support enum.next(k) with constant k > 1, #2125. [Tobias Rosenkranz] +**** Support enum.next(k) with constant k > 1. (#2125) [Tobias Rosenkranz] -**** Support parameter access from arrays of interfaces, #2155. [Todd Strader] +**** Support parameter access from arrays of interfaces. (#2155) [Todd Strader] **** Add parameter values in XML. #2110. [Pieter Kapsenberg] -**** Add loc column location in XML (replaces fl), #2122. [Pieter Kapsenberg] +**** Add loc column location in XML (replaces fl). (#2122) [Pieter Kapsenberg] **** Add error on misused define. [Topa Tota] -**** Add parameter to set maximum signal width, #2082. [Øyvind Harboe] +**** Add parameter to set maximum signal width. (#2082) [Øyvind Harboe] -**** Add warning on genvar in normal for loop, #2143. [yurivict] +**** Add warning on genvar in normal for loop. (#2143) [yurivict] **** Fix VPI scope naming for public modules. [Nandu Raj] **** Fix FST tracing of enums inside structs. [fsiegle] -**** Fix WIDTH warning on " in assertions, #2069. [Peter Monsson] +*** Support implication operator "|->" in assertions. (#2069) [Peter Monsson] -*** Support string compare, ato*, etc methods, #1606. [Yutetsu TAKATSUKASA] +*** Support string compare, ato*, etc methods. (#1606) [Yutetsu TAKATSUKASA] **** Support immediate cover statements. -**** Ignore `uselib to end-of-line, #1634. [Frederic Antonin] +**** Ignore `uselib to end-of-line. (#1634) [Frederic Antonin] **** Update FST trace API for better performance. -**** Add vpiTimeUnit and allow to specify time as string, #1636. [Stefan Wallentowitz] +**** Add vpiTimeUnit and allow to specify time as string. (#1636) [Stefan Wallentowitz] **** Add error when `resetall inside module (IEEE 2017-22.3). **** Add cleaner error on version control conflicts in sources. -**** Fix little endian cell ranges, #1631. [Julien Margetts] +**** Fix little endian cell ranges. (#1631) [Julien Margetts] -**** Fix queue issues, #1641, #1643. [Peter Monsson, Stefan Wallentowitz] +**** Fix queue issues (#1641) (#1643) [Peter Monsson, Stefan Wallentowitz] -**** Fix strcasecmp for windows, #1651. [Kuba Ober] +**** Fix strcasecmp for windows. (#1651) [Kuba Ober] **** Fix disable iff in assertions. Closes #1404. [Peter Monsson] @@ -189,9 +231,9 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 4.024 2019-12-08 -** Support associative arrays (excluding [*] and pattern assignments), #544. +** Support associative arrays (excluding [*] and pattern assignments). (#544) -** Support queues (excluding {} notation and pattern assignments), #545. +** Support queues (excluding {} notation and pattern assignments). (#545) *** Add +verilator+error+limit to see more assertion errors. [Peter Monsson] @@ -205,42 +247,42 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Add error on redefining preprocessor directives. [Piotr Binkowski] -**** Support $value$plusargs float and shorts, #1592, #1619. [Garrett Smith] +**** Support $value$plusargs float and shorts. (#1592) (#1619) [Garrett Smith] -**** Fix gate lvalue optimization error, #831. [Jonathon Donaldson, Driss Hafdi] +**** Fix gate lvalue optimization error. (#831) [Jonathon Donaldson, Driss Hafdi] -**** Fix color assertion on empty if, #1604. [Andrew Holme] +**** Fix color assertion on empty if. (#1604) [Andrew Holme] -**** Fix for loop missing initializer, #1605. [Andrew Holme] +**** Fix for loop missing initializer. (#1605) [Andrew Holme] -**** Fix hang on concat error, #1608. [Bogdan Vukobratovic] +**** Fix hang on concat error. (#1608) [Bogdan Vukobratovic] **** Fix VPI timed callbacks to be one-shot, pull5. [Matthew Ballance] -**** Fix // in filenames, #1610. [Peter Nelson] +**** Fix // in filenames. (#1610) [Peter Nelson] **** Fix $display("%p") to be closer to IEEE. -**** Fix labels on functions with returns, #1614. [Mitch Hayenga] +**** Fix labels on functions with returns. (#1614) [Mitch Hayenga] -**** Fix false unused message on __Vemumtab, #2061. [Tobias Rosenkranz] +**** Fix false unused message on __Vemumtab. (#2061) [Tobias Rosenkranz] -**** Fix assertion on dotted parameter arrayed function, #1620. [Rich Porter] +**** Fix assertion on dotted parameter arrayed function. (#1620) [Rich Porter] -**** Fix interface reference tracing, #1595. [Todd Strader] +**** Fix interface reference tracing. (#1595) [Todd Strader] -**** Fix error on unpacked concatenations, #1627. [Driss Hafdi] +**** Fix error on unpacked concatenations. (#1627) [Driss Hafdi] * Verilator 4.022 2019-11-10 -** Add --protect-lib, #1490. [Todd Strader] +** Add --protect-lib. (#1490) [Todd Strader] -** Add cmake support, #1363. [Patrick Stewart] +** Add cmake support. (#1363) [Patrick Stewart] *** Examples have been renamed. -*** Add --protect-ids to obscure information in objects, #1521. [Todd Strader] +*** Add --protect-ids to obscure information in objects. (#1521) [Todd Strader] *** Add --trace-coverage. @@ -250,329 +292,329 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Suppress 'command failed' on normal errors. -*** Support some unpacked arrays in parameters, #1315. [Marshal Qiao] +*** Support some unpacked arrays in parameters. (#1315) [Marshal Qiao] -*** Add interface port visibility in traces, #1594. [Todd Strader] +*** Add interface port visibility in traces. (#1594) [Todd Strader] -**** Increase case duplicate/incomplete to 16 bit tables, #1545. [Yossi Nivin] +**** Increase case duplicate/incomplete to 16 bit tables. (#1545) [Yossi Nivin] -**** Support quoted arguments in -f files, #1535. [Yves Mathieu] +**** Support quoted arguments in -f files. (#1535) [Yves Mathieu] **** Optimize modulus by power-of-two constants, and masked conditionals. -**** Fix detecting missing reg types, #1570. [Jacko Dirks] +**** Fix detecting missing reg types. (#1570) [Jacko Dirks] -**** Fix multithreaded yield behavior when no work. [Patrick Stewart] +**** Fix multithreaded yield behavior when no work. [Patrick Stewart] -**** Fix bad-syntax crashes, #1548, #1550-#1553, #1557-#1560, #1563, - #1573-#1577, #1579, #1582-#1591. [Eric Rippey] +**** Fix bad-syntax crashes. (#1548, #1550-#1553, #1557-#1560, #1563, + #1573-#1577, #1579, #1582-#1591) [Eric Rippey] -**** Fix false CMPCONST/UNSIGNED warnings on "inside", #1581. [Mitch Hayenga] +**** Fix false CMPCONST/UNSIGNED warnings on "inside". (#1581) [Mitch Hayenga] * Verilator 4.020 2019-10-06 -*** Add --public-flat-rw, #1511. [Stefan Wallentowitz] +*** Add --public-flat-rw. (#1511) [Stefan Wallentowitz] -*** Support $fseek, $ftell, $frewind, #1496. [Howard Su] +*** Support $fseek, $ftell, $frewind. (#1496) [Howard Su] -*** Support vpiModule, #1469. [Stefan Wallentowitz] +*** Support vpiModule. (#1469) [Stefan Wallentowitz] -**** Make Syms file honor --output-split-cfuncs, #1499. [Todd Strader] +**** Make Syms file honor --output-split-cfuncs. (#1499) [Todd Strader] -**** Fix make test with no VERILATOR_ROOT, #1494. [Ahmed El-Mahmoudy] +**** Fix make test with no VERILATOR_ROOT. (#1494) [Ahmed El-Mahmoudy] -**** Fix error on multidimensional cells, #1505. [Anderson Ignacio Da Silva] +**** Fix error on multidimensional cells. (#1505) [Anderson Ignacio Da Silva] **** Fix config_rev revision detection on old versions. -**** Fix false warning on backward indexing, #1507. [Hao Shi] +**** Fix false warning on backward indexing. (#1507) [Hao Shi] -**** Fix vpiType accessor, #1509, #1510. [Stefan Wallentowitz] +**** Fix vpiType accessor. (#1509) (#1510) [Stefan Wallentowitz] -**** Fix ugly error on interface misuse, #1525. [Bogdan Vukobratovic] +**** Fix ugly error on interface misuse. (#1525) [Bogdan Vukobratovic] -**** Fix misc bad-syntax crashes, #1529, #1530, #1531, #1532, #1533. [Eric Rippey] +**** Fix misc bad-syntax crashes. (#1529) (#1530) (#1531) (#1532) (#1533) [Eric Rippey] -**** Fix case statements with strings, #1536. [Philipp Wagner] +**** Fix case statements with strings. (#1536) [Philipp Wagner] -**** Fix some coverage lost when multithreaded, #2151. +**** Fix some coverage lost when multithreaded. (#2151) * Verilator 4.018 2019-08-29 ** When showing an error, show source code and offer suggestions of replacements. -** When showing an error, show the instance location, #1305. [Todd Strader] +** When showing an error, show the instance location. (#1305) [Todd Strader] -*** Add --rr, #1481. [Todd Strader] +*** Add --rr. (#1481) [Todd Strader] *** Change MULTITOP to warning to help linting, see manual. -*** Add XSim support to driver.pl, #1493. [Todd Strader] +*** Add XSim support to driver.pl. (#1493) [Todd Strader] -**** Show included-from filenames in warnings, #1439. [Todd Strader] +**** Show included-from filenames in warnings. (#1439) [Todd Strader] -**** Fix elaboration time errors, #1429. [Udi Finkelstein] +**** Fix elaboration time errors. (#1429) [Udi Finkelstein] -**** Fix not reporting some duplicate signals/ports, #1462. [Peter Gerst] +**** Fix not reporting some duplicate signals/ports. (#1462) [Peter Gerst] -**** Fix not in array context on non-power-of-two slices, #2027. [Yu Sheng Lin] +**** Fix not in array context on non-power-of-two slices. (#2027) [Yu Sheng Lin] **** Fix system compile flags injection. [Gianfranco Costamagna] -**** Fix enum values not being sized based on parent, #1442. [Dan Petrisko] +**** Fix enum values not being sized based on parent. (#1442) [Dan Petrisko] -**** Fix internal error on gate optimization of assign, #1475. [Oyvind Harboe] +**** Fix internal error on gate optimization of assign. (#1475) [Oyvind Harboe] -**** Add --dpi-hdr-only, #1491. [Todd Strader] +**** Add --dpi-hdr-only. (#1491) [Todd Strader] * Verilator 4.016 2019-06-16 -*** Add --quiet-exit, #1436. [Todd Strader] +*** Add --quiet-exit. (#1436) [Todd Strader] **** Error continuation lines no longer have %Error prefix. **** Support logical equivalence operator <->. -**** Support VerilatedFstC set_time_unit, #1433. [Pieter Kapsenberg] +**** Support VerilatedFstC set_time_unit. (#1433) [Pieter Kapsenberg] -**** Support deferred assertions, #1449. [Charles Eddleston] +**** Support deferred assertions. (#1449) [Charles Eddleston] **** Mark infrequently called functions with GCC cold attribute. -**** Fix sign-compare warning in verilated.cpp, #1437. [Sergey Kvachonok] +**** Fix sign-compare warning in verilated.cpp. (#1437) [Sergey Kvachonok] -**** Fix fault on $realtime with %t, #1443. [Julien Margetts] +**** Fix fault on $realtime with %t. (#1443) [Julien Margetts] -**** Fix $display with string without %s, #1441. [Denis Rystsov] +**** Fix $display with string without %s. (#1441) [Denis Rystsov] -**** Fix parameter function string returns, #1441. [Denis Rystsov] +**** Fix parameter function string returns. (#1441) [Denis Rystsov] -**** Fix invalid XML output due to special chars, #1444. [Kanad Kanhere] +**** Fix invalid XML output due to special chars. (#1444) [Kanad Kanhere] -**** Fix performance when mulithreaded on 1 CPU, #1455. [Stefan Wallentowitz] +**** Fix performance when mulithreaded on 1 CPU. (#1455) [Stefan Wallentowitz] -**** Fix type and real parameter issues, #1427, #1456, #1458. [Todd Strader] +**** Fix type and real parameter issues (#1427) (#1456) (#1458) [Todd Strader] -**** Fix build error on MinGW, #1460. [Richard Myers] +**** Fix build error on MinGW. (#1460) [Richard Myers] -**** Fix not reporting some duplicate signals, #1462. [Peter Gerst] +**** Fix not reporting some duplicate signals. (#1462) [Peter Gerst] -**** Fix --savable invalid C++ on packed arrays, #1465. [Alex Chadwick] +**** Fix --savable invalid C++ on packed arrays. (#1465) [Alex Chadwick] -**** Fix constant function return of function var, #1467. [Roman Popov] +**** Fix constant function return of function var. (#1467) [Roman Popov] * Verilator 4.014 2019-05-08 *** Add --trace-fst-thread. -**** Support '#' comments in $readmem, #1411. [Frederick Requin] +**** Support '#' comments in $readmem. (#1411) [Frederick Requin] -**** Support "'dx" constants, #1423. [Udi Finkelstein] +**** Support "'dx" constants. (#1423) [Udi Finkelstein] **** For FST tracing use LZ4 compression. [Tony Bybell] -**** Add error when use parameters without value, #1424. [Peter Gerst] +**** Add error when use parameters without value. (#1424) [Peter Gerst] -**** Auto-extend and WIDTH warn on unsized X/Zs, #1423. [Udi Finkelstein] +**** Auto-extend and WIDTH warn on unsized X/Zs. (#1423) [Udi Finkelstein] -**** Fix missing VL_SHIFTL_ errors, #1412, #1415. [Larry Lee] +**** Fix missing VL_SHIFTL_ errors. (#1412) (#1415) [Larry Lee] -**** Fix MinGW GCC 6 printf formats, #1413. [Sergey Kvachonok] +**** Fix MinGW GCC 6 printf formats. (#1413) [Sergey Kvachonok] -**** Fix test problems when missing fst2vcd, #1417. [Todd Strader] +**** Fix test problems when missing fst2vcd. (#1417) [Todd Strader] -**** Fix GTKWave register warning, #1421. [Pieter Kapsenberg] +**** Fix GTKWave register warning. (#1421) [Pieter Kapsenberg] -**** Fix FST enums not displaying, #1426. [Danilo Ramos] +**** Fix FST enums not displaying. (#1426) [Danilo Ramos] -**** Fix table compile error with multiinterfaces, #1431. [Bogdan Vukobratovic] +**** Fix table compile error with multiinterfaces. (#1431) [Bogdan Vukobratovic] -* Verilator 4.012 2019-3-23 +* Verilator 4.012 2019-03-23 -*** Add +verilator+seed, #1396. [Stan Sokorac] +*** Add +verilator+seed. (#1396) [Stan Sokorac] -*** Support $fread. [Leendert van Doorn] +*** Support $fread. [Leendert van Doorn] -*** Support void' cast on functions called as tasks, #1383. [Al Grant] +*** Support void' cast on functions called as tasks. (#1383) [Al Grant] -*** Add IGNOREDRETURN warning, #1383. +*** Add IGNOREDRETURN warning. (#1383) -**** Report PORTSHORT errors on concat constants, bug 1400. [Will Korteland] +**** Report PORTSHORT errors on concat constants. (#1400) [Will Korteland] -**** Fix VERILATOR_GDB being ignored, #2017. [Yu Sheng Lin] +**** Fix VERILATOR_GDB being ignored. (#2017) [Yu Sheng Lin] **** Fix $value$plus$args missing verilated_heavy.h. [Yi-Chung Chen] -**** Fix MSVC compile error, #1406. [Benjamin Gartner] +**** Fix MSVC compile error. (#1406) [Benjamin Gartner] -**** Fix maintainer test when no Parallel::Forker, #1977. [Enzo Chi] +**** Fix maintainer test when no Parallel::Forker. (#1977) [Enzo Chi] -**** Fix +1364-1995ext flags applying too late, #1384. [Al Grant] +**** Fix +1364-1995ext flags applying too late. (#1384) [Al Grant] * Verilator 4.010 2019-01-27 *** Removed --trace-lxt2, use --trace-fst instead. -**** For --xml, add additional information, #1372. [Jonathan Kimmitt] +**** For --xml, add additional information. (#1372) [Jonathan Kimmitt] -**** Add circular typedef error, #1388. [Al Grant] +**** Add circular typedef error. (#1388) [Al Grant] -**** Add unsupported for loops error, #1986. [Yu Sheng Lin] +**** Add unsupported for loops error. (#1986) [Yu Sheng Lin] -**** Fix FST tracing of wide arrays, #1376. [Aleksander Osman] +**** Fix FST tracing of wide arrays. (#1376) [Aleksander Osman] -**** Fix error when pattern assignment has too few elements, #1378. [Viktor Tomov] +**** Fix error when pattern assignment has too few elements. (#1378) [Viktor Tomov] -**** Fix error when no modules in $unit, #1381. [Al Grant] +**** Fix error when no modules in $unit. (#1381) [Al Grant] -**** Fix missing too many digits warning, #1380. [Jonathan Kimmitt] +**** Fix missing too many digits warning. (#1380) [Jonathan Kimmitt] -**** Fix uninitialized data in verFiles and unroller, #1385, #1386. [Al Grant] +**** Fix uninitialized data in verFiles and unroller. (#1385) (#1386) [Al Grant] -**** Fix internal error on xrefs into unrolled functions, #1387. [Al Grant] +**** Fix internal error on xrefs into unrolled functions. (#1387) [Al Grant] -**** Fix DPI export void compiler error, #1391. [Stan Sokorac] +**** Fix DPI export void compiler error. (#1391) [Stan Sokorac] * Verilator 4.008 2018-12-01 -*** Support "ref" and "const ref" pins and functions, #1360. [Jake Longo] +*** Support "ref" and "const ref" pins and functions. (#1360) [Jake Longo] *** In --xml-only show the original unmodified names, and add module_files and cells similar to Verilog-Perl, msg2719. [Kanad Kanhere] -**** Add CONTASSREG error on continuous assignments to regs, #1369. [Peter Gerst] +**** Add CONTASSREG error on continuous assignments to regs. (#1369) [Peter Gerst] **** Add PROCASSWIRE error on behavioral assignments to wires, msg2737. [Neil Turton] **** Add IMPORTSTAR warning on import::* inside $unit scope. -**** Fix --trace-lxt2 compile error on MinGW, #1990. [HyungKi Jeong] +**** Fix --trace-lxt2 compile error on MinGW. (#1990) [HyungKi Jeong] -**** Fix hang on bad pattern keys, #1364. [Matt Myers] +**** Fix hang on bad pattern keys. (#1364) [Matt Myers] -**** Fix crash due to cygwin bug in getline, #1349. [Affe Mao] +**** Fix crash due to cygwin bug in getline. (#1349) [Affe Mao] -**** Fix __Slow files getting compiled with OPT_FAST, #1370. [Thomas Watts] +**** Fix __Slow files getting compiled with OPT_FAST. (#1370) [Thomas Watts] * Verilator 4.006 2018-10-27 -** Add --pp-comments, #1988. [Robert Henry] +** Add --pp-comments. (#1988) [Robert Henry] ** Add --dump-defines. -*** For --trace-fst, save enum decoding information, #1358. [Sergi Granell] +*** For --trace-fst, save enum decoding information. (#1358) [Sergi Granell] (To visualize enumeration data you must use GTKwave 3.3.95 or newer.) *** For --trace-fst, instead of *.fst.hier, put data into *.fst. [Tony Bybell] **** Fix --trace-lxt2 compile error on MinGW, msg2667. [HyungKi Jeong] -**** Fix Windows .exe not found, #1361. [Patrick Stewart] +**** Fix Windows .exe not found. (#1361) [Patrick Stewart] -* Verilator 4.004 2018-10-6 +* Verilator 4.004 2018-10-06 -** Add GTKWave FST native tracing, #1356. [Sergi Granell] +** Add GTKWave FST native tracing. (#1356) [Sergi Granell] (Verilator developers need to pull the latest vcddiff.) *** Support $past. [Dan Gisselquist] -*** Support restrict, #1350. [Clifford Wolf] +*** Support restrict. (#1350) [Clifford Wolf] *** Rename include/lxt2 to include/gtkwave. **** Fix replication of 64-bit signal change detects. -**** Fix Mac OSX 10.13.6 / LLVM 9.1 compile issues, #1348. [Kevin Kiningham] +**** Fix Mac OSX 10.13.6 / LLVM 9.1 compile issues. (#1348) [Kevin Kiningham] -**** Fix MinGW compile issues, #1979. [HyungKi Jeong] +**** Fix MinGW compile issues. (#1979) [HyungKi Jeong] * Verilator 4.002 2018-09-16 -** This is a major release. Any patches may require major rework to apply. +** This is a major release. Any patches may require major rework to apply. [Thanks everyone] ** Add multithreaded model generation. ** Add runtime arguments. -** Add GTKWave LXT2 native tracing, #1333. [Yu Sheng Lin] +** Add GTKWave LXT2 native tracing. (#1333) [Yu Sheng Lin] ** Note $random has new algorithm; results may vary vs. previous versions. -*** Better optimize large always block splitting, #1244. [John Coiner] +*** Better optimize large always block splitting. (#1244) [John Coiner] *** Add new reloop optimization for repetitive assignment compression. -*** Support string.atoi and similar methods, #1289. [Joel Holdsworth] +*** Support string.atoi and similar methods. (#1289) [Joel Holdsworth] **** Fix internals to be C++ null-pointer-check clean. **** Fix internals to avoid 'using namespace std'. -**** Fix Verilation performance issues, #1316. [John Coiner] +**** Fix Verilation performance issues. (#1316) [John Coiner] **** Fix clocker attributes to not propagate on concats. [John Coiner] -**** Fix first clock edge and --x-initial-edge, #1327. [Rupert Swarbrick] +**** Fix first clock edge and --x-initial-edge. (#1327) [Rupert Swarbrick] -**** Fix compile error on tracing of string arrays, #1338. [Iztok Jeras] +**** Fix compile error on tracing of string arrays. (#1338) [Iztok Jeras] -**** Fix number parsing with newline after radix, #1340. [George Cuan] +**** Fix number parsing with newline after radix. (#1340) [George Cuan] -**** Fix string ?: conditional type resolution, #1345. [Iztok Jeras] +**** Fix string ?: conditional type resolution. (#1345) [Iztok Jeras] -**** Fix duplicate symbol error on generate tri, #1347. [Tomas Dzetkulic] +**** Fix duplicate symbol error on generate tri. (#1347) [Tomas Dzetkulic] * Verilator 3.926 2018-08-22 **** Add OBJCACHE envvar support to examples and generated Makefiles. -**** Change MODDUP errors to warnings, #1969. [Marshal Qiao] +**** Change MODDUP errors to warnings. (#1969) [Marshal Qiao] **** Fix define argument stringification (`"), broke since 3.914. [Joe DErrico] -**** Fix to ignore Unicode UTF-8 BOM sequences, #1967. [HyungKi Jeong] +**** Fix to ignore Unicode UTF-8 BOM sequences. (#1967) [HyungKi Jeong] -**** Fix std:: build error, #1322. +**** Fix std:: build error. (#1322) -**** Fix function inlining inside certain while loops, #1330. [Julien Margetts] +**** Fix function inlining inside certain while loops. (#1330) [Julien Margetts] * Verilator 3.924 2018-06-12 *** Renamed --profile-cfuncs to --prof-cfuncs. -**** Report interface ports connected to wrong interface, #1294. [Todd Strader] +**** Report interface ports connected to wrong interface. (#1294) [Todd Strader] **** When tracing, use scalars on single bit arrays to appease vcddiff. **** Fix parsing "output signed" in V2K port list, msg2540. [James Jung] -**** Fix parsing error on bad missing #, #1308. [Dan Kirkham] +**** Fix parsing error on bad missing #. (#1308) [Dan Kirkham] -**** Fix $clog2 to be in verilog 2005, #1319. [James Hutchinson] +**** Fix $clog2 to be in verilog 2005. (#1319) [James Hutchinson] * Verilator 3.922 2018-03-17 ** Support IEEE 1800-2017 as default language. -*** Support trig functions ($sin() etc), #1281. [Patrick Stewart] +*** Support trig functions ($sin() etc). (#1281) [Patrick Stewart] -*** Support calling system functions as tasks, #1285. [Joel Holdsworth] +*** Support calling system functions as tasks. (#1285) [Joel Holdsworth] -*** Support assert properties, #785, #1290. [John Coiner, et al] +*** Support assert properties. (#785) (#1290) [John Coiner, et al] *** Support $writememh. [John Coiner] @@ -582,11 +624,11 @@ The contributors that suggested a given feature are shown in []. Thanks! **** On convergence errors, show activity. [John Coiner] -**** Fix GCC 8.0 issues, #1273. +**** Fix GCC 8.0 issues. (#1273) -**** Fix pullup/pulldowns on bit selects, #1274. [Rob Stoddard] +**** Fix pullup/pulldowns on bit selects. (#1274) [Rob Stoddard] -**** Fix verilator_coverage --annotate-min, #1284. [Tymoteusz Blazejczyk] +**** Fix verilator_coverage --annotate-min. (#1284) [Tymoteusz Blazejczyk] **** Fix quoting of quoted arguments. [John Coiner] @@ -596,30 +638,30 @@ The contributors that suggested a given feature are shown in []. Thanks! ** Moving forward, use the git "stable" branch to track the latest release, and git "v#.###" tags for specific releases. -*** Support 'assume' similar to 'assert', #1269. [Dan Gisselquist] +*** Support 'assume' similar to 'assert'. (#1269) [Dan Gisselquist] -**** Fix tracing example file output, #1268. [Enzo Chi] +**** Fix tracing example file output. (#1268) [Enzo Chi] -**** Fix gate optimization out of memory, add --gate-stmts, #1260. [Alex Solomatnikov] +**** Fix gate optimization out of memory, add --gate-stmts. (#1260) [Alex Solomatnikov] -**** Fix compile error on public real parameters by suppressing, #1261. [Alex Solomatnikov] +**** Fix compile error on public real parameters by suppressing. (#1261) [Alex Solomatnikov] -**** Fix input-only tristate comparisons, #1267. [Alexis G] +**** Fix input-only tristate comparisons. (#1267) [Alexis G] -**** Fix missing edge type in xml output, #1955. [Alexis G] +**** Fix missing edge type in xml output. (#1955) [Alexis G] -**** Fix compile error with --public and interface bind, #1264. [Alexis G] +**** Fix compile error with --public and interface bind. (#1264) [Alexis G] -**** Remove c++filt, #1265. [Stefan Wallentowitz] +**** Remove c++filt. (#1265) [Stefan Wallentowitz] * Verilator 3.918 2018-01-02 -*** Workaround GCC/clang bug with huge compile times, #1248. +*** Workaround GCC/clang bug with huge compile times. (#1248) -*** Support DPI open arrays, #909, #1245. [David Pierce, Victor Besyakov] +*** Support DPI open arrays. (#909) (#1245) [David Pierce, Victor Besyakov] -*** Add INFINITELOOP warning, #1254. [Alex Solomatnikov] +*** Add INFINITELOOP warning. (#1254) [Alex Solomatnikov] **** Support > 64 bit decimal $display. @@ -630,40 +672,42 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Add error if always_comb has sensitivity list. [Arjen Roodselaar] -**** Fix SystemC 2.3.2 compile error, #1251. [Tymoteusz Blazejczyk] +**** Fix SystemC 2.3.2 compile error. (#1251) [Tymoteusz Blazejczyk] -**** Fix modport outputs being treated as inputs, #1246. [Jeff Bush] +**** Fix modport outputs being treated as inputs. (#1246) [Jeff Bush] -**** Fix false ALWCOMBORDER on interface references, #1247. [Josh Redford] +**** Fix false ALWCOMBORDER on interface references. (#1247) [Josh Redford] **** Fix constant propagation across DPI imports of inout strings. [Victor Besyakov] -**** Fix resolving inline nested interface names, #1250. [Arjen Roodselaar] +**** Fix resolving inline nested interface names. (#1250) [Arjen Roodselaar] + +**** Fix GCC false warning on array bounds. (#2386) * Verilator 3.916 2017-11-25 -*** Support self-recursive modules, #659. [Sean Moore, et al] +*** Support self-recursive modules. (#659) [Sean Moore, et al] *** Support $error/$warning in elaboration time blocks. *** Support $size/$bits/etc on type references. -*** Add error when driving input-only modport, #1110. [Trevor Elbourne] +*** Add error when driving input-only modport. (#1110) [Trevor Elbourne] *** Add BSSPACE and COLONPLUS lint warnings. -**** Detect MSB overflow when under VL_DEBUG, #1238. [Junyi Xi] +**** Detect MSB overflow when under VL_DEBUG. (#1238) [Junyi Xi] **** Add data types to --xml. [Rui Terra] -**** Fix partial slicing with pattern assignments, #991. [Johan Bjork] +**** Fix partial slicing with pattern assignments. (#991) [Johan Bjork] -**** Fix false unused warning on interfaces, #1241. [Laurens van Dam] +**** Fix false unused warning on interfaces. (#1241) [Laurens van Dam] **** Fix error on "unique case" with no cases. -**** Fix MacOS portability, #1232. [Jeff Bush] +**** Fix MacOS portability. (#1232) [Jeff Bush] * Verilator 3.914 2017-10-14 @@ -675,7 +719,7 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Add --x-initial option for specifying initial value assignment behavior. -*** Add --no-relative-cfuncs and related default optimization, #1224. [John Coiner] +*** Add --no-relative-cfuncs and related default optimization. (#1224) [John Coiner] *** Add /*verilator tag*/ for XML extraction applications. [Chris Randall] @@ -683,25 +727,25 @@ The contributors that suggested a given feature are shown in []. Thanks! **** The experimental VL_THREADED setting (only, not normal mode) now requires C++11. -**** Fix over-aggressive inlining, #1223. [John Coiner] +**** Fix over-aggressive inlining. (#1223) [John Coiner] -**** Fix Ubuntu 17.10 issues, #1223 partial. [John Coiner] +**** Fix Ubuntu 17.10 issues. (#1223 partial). [John Coiner] **** Fix compiler warning when WIDTH warning ignored on large compare. -**** Fix memory leak in VerilatedVcd dumps, #1222 partial. [Shareef Jalloq] +**** Fix memory leak in VerilatedVcd dumps. (#1222 partial) [Shareef Jalloq] -**** Fix unnecessary Vdly variables, #1224 partial. [John Coiner] +**** Fix unnecessary Vdly variables. (#1224 partial) [John Coiner] **** Fix conditional slices and add related optimizations. -**** Fix `` expansion of `defines, #1225, #1227, #1228. [Odd Magne Reitan] +**** Fix `` expansion of `defines. (#1225) (#1227) (#1228) [Odd Magne Reitan] -**** Fix -E duplicating output, #1226. [Odd Magne Reitan] +**** Fix -E duplicating output. (#1226) [Odd Magne Reitan] -**** Fix float-conversion warning, #1229. [Robert Henry] +**** Fix float-conversion warning. (#1229) [Robert Henry] -**** Fix MacOS portability, #1230, #1231. [Jeff Bush] +**** Fix MacOS portability. (#1230) (#1231) [Jeff Bush] * Verilator 3.912 2017-09-23 @@ -709,29 +753,29 @@ The contributors that suggested a given feature are shown in []. Thanks! ** Verilated headers no longer "use namespace std;" User's code without "std::" prefixes may need "use namespace std;" to compile. -*** Support or/and/xor array intrinsic methods, #1210. [Mike Popoloski] +*** Support or/and/xor array intrinsic methods. (#1210) [Mike Popoloski] -*** Support package export, #1217. [Usuario Eda] +*** Support package export. (#1217) [Usuario Eda] -*** Fix ordering of arrayed cell wide connections, #1202 partial. [Mike Popoloski] +*** Fix ordering of arrayed cell wide connections. (#1202 partial) [Mike Popoloski] -**** Support module port parameters without defaults, bug 1213. [Mike Popoloski] +**** Support module port parameters without defaults. (#1213) [Mike Popoloski] **** Add performance information to --stats file. **** Simplify VL_CONST_W macro generation for faster compiles. -**** Fix LITENDIAN warning on arrayed cells, #1202. [Mike Popoloski] +**** Fix LITENDIAN warning on arrayed cells. (#1202) [Mike Popoloski] -**** Fix enum ranges without colons, #1204. [Mike Popoloski] +**** Fix enum ranges without colons. (#1204) [Mike Popoloski] -**** Fix GCC noreturn compile error, #1209. [Mike Popoloski] +**** Fix GCC noreturn compile error. (#1209) [Mike Popoloski] -**** Fix constant function default parameters, #1211. [Mike Popoloski] +**** Fix constant function default parameters. (#1211) [Mike Popoloski] -**** Fix non-colon array of interface modports, #1212. [Mike Popoloski] +**** Fix non-colon array of interface modports. (#1212) [Mike Popoloski] -**** Fix .name connections on interfaces, #1214. [Mike Popoloski] +**** Fix .name connections on interfaces. (#1214) [Mike Popoloski] **** Fix wide array indices causing compile error. @@ -747,368 +791,368 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 3.908 2017-08-28 -**** Support x in $readmem, #1180. [Arthur Kahlich] +**** Support x in $readmem. (#1180) [Arthur Kahlich] -**** Support packed struct DPI imports, #1190. [Rob Stoddard] +**** Support packed struct DPI imports. (#1190) [Rob Stoddard] **** Fix GCC 6 warnings. -**** Fix compile error on unused VL_VALUEPLUSARGS_IW, #1181. [Thomas J Whatson] +**** Fix compile error on unused VL_VALUEPLUSARGS_IW. (#1181) [Thomas J Whatson] **** Fix undefined VL_POW_WWI. [Clifford Wolf] -**** Fix internal error on unconnected inouts, #1187. [Rob Stoddard] +**** Fix internal error on unconnected inouts. (#1187) [Rob Stoddard] * Verilator 3.906 2017-06-22 -*** Support set_time_unit/set_time_precision in C traces, #1937. +*** Support set_time_unit/set_time_precision in C traces. (#1937) -*** Fix extract of packed array with non-zero LSB, #1172. [James Pallister] +*** Fix extract of packed array with non-zero LSB. (#1172) [James Pallister] -*** Fix shifts by more than 32-bit numbers, #1174. [Clifford Wolf] +*** Fix shifts by more than 32-bit numbers. (#1174) [Clifford Wolf] -*** Fix power operator on wide constants, #761. [Clifford Wolf] +*** Fix power operator on wide constants. (#761) [Clifford Wolf] -*** Fix .* on interface pins, #1176. [Maciej Piechotka] +*** Fix .* on interface pins. (#1176) [Maciej Piechotka] * Verilator 3.904 2017-05-30 -*** Fix non-cutable ordering loops on clock arrays, #1009. [Todd Strader] +*** Fix non-cutable ordering loops on clock arrays. (#1009) [Todd Strader] -*** Support ports of array of reals, #1154. [J Briquet] +*** Support ports of array of reals. (#1154) [J Briquet] -*** Support arrayed parameter overrides, #1153. [John Stevenson] +*** Support arrayed parameter overrides. (#1153) [John Stevenson] -*** Support $value$plusargs with variables, #1165. [Wesley Terpstra] +*** Support $value$plusargs with variables. (#1165) [Wesley Terpstra] -**** Support modport access to un-modport objects, #1161. [Todd Strader] +**** Support modport access to un-modport objects. (#1161) [Todd Strader] -**** Add stack trace when can't optimize function, #1158. [Todd Strader] +**** Add stack trace when can't optimize function. (#1158) [Todd Strader] -**** Add warning on mis-sized literal, #1156. [Todd Strader] +**** Add warning on mis-sized literal. (#1156) [Todd Strader] -**** Fix interface functions returning wrong parameters, #996. [Todd Strader] +**** Fix interface functions returning wrong parameters. (#996) [Todd Strader] -**** Fix non-arrayed cells with interface arrays, #1153. [John Stevenson] +**** Fix non-arrayed cells with interface arrays. (#1153) [John Stevenson] -**** Fix --assert with complex case statements, #1164. [Enzo Chi] +**** Fix --assert with complex case statements. (#1164) [Enzo Chi] * Verilator 3.902 2017-04-02 -** Add -FI option to force includes, #1916. [Amir Gonnen] +** Add -FI option to force includes. (#1916) [Amir Gonnen] ** Add --relative-includes. [Rob Stoddard] -*** Add error on duplicate pattern assignments, #1145. [Johan Bjork] +*** Add error on duplicate pattern assignments. (#1145) [Johan Bjork] -**** Fix error on improperly widthed default function, #984. [Todd Strader] +**** Fix error on improperly widthed default function. (#984) [Todd Strader] **** Fix 2009 localparam syntax, msg2139. [Galen Seitz] -**** Fix ugly interface-to-non-interface errors, #1112. [Johan Bjork] +**** Fix ugly interface-to-non-interface errors. (#1112) [Johan Bjork] -**** Fix LDFLAGS and CFLAGS not preserving order, #1130. [Olof Kindgren] +**** Fix LDFLAGS and CFLAGS not preserving order. (#1130) [Olof Kindgren] -**** Fix internal error on initializing parameter array, #1131. [Jie Xu] +**** Fix internal error on initializing parameter array. (#1131) [Jie Xu] -**** Fix internal error on interface arrays, #1135. [John Stevenson] +**** Fix internal error on interface arrays. (#1135) [John Stevenson] -**** Fix calling sformatf to display, and elab $displays, #1139. [Johan Bjork] +**** Fix calling sformatf to display, and elab $displays. (#1139) [Johan Bjork] -**** Fix realpath compile issue on MSVC++, #1141. [Miodrag Milanovic] +**** Fix realpath compile issue on MSVC++. (#1141) [Miodrag Milanovic] -**** Fix missing error on interface size mismatch, #1143. [Johan Bjork] +**** Fix missing error on interface size mismatch. (#1143) [Johan Bjork] -**** Fix error on parameters with dotted references, #1146. [Johan Bjork] +**** Fix error on parameters with dotted references. (#1146) [Johan Bjork] -**** Fix wreal not handling continuous assign, #1150. [J Briquet] +**** Fix wreal not handling continuous assign. (#1150) [J Briquet] -**** Fix nested structure parameter selects, #1150. [J Briquet] +**** Fix nested structure parameter selects. (#1150) [J Briquet] * Verilator 3.900 2017-01-15 ** Internal code changes for improved compatibility and performance. -*** Support old-style $display($time), #467. [John Demme] +*** Support old-style $display($time). (#467) [John Demme] -**** With --bbox-unsup, suppress desassign and mixed edges, #1120. [Galen Seitz] +**** With --bbox-unsup, suppress desassign and mixed edges. (#1120) [Galen Seitz] -**** Fix parsing sensitivity with &&, #934. [Luke Yang] +**** Fix parsing sensitivity with &&. (#934) [Luke Yang] -**** Fix internal error on double-for loop unrolling, #1044. [Jan Egil Ruud] +**** Fix internal error on double-for loop unrolling. (#1044) [Jan Egil Ruud] -**** Fix internal error on unique casez with --assert, #1117. [Enzo Chi] +**** Fix internal error on unique casez with --assert. (#1117) [Enzo Chi] -**** Fix bad code when tracing array of structs, #1122. [Andrew Bardsley] +**** Fix bad code when tracing array of structs. (#1122) [Andrew Bardsley] * Verilator 3.890 2016-11-25 -*** Honor --output-split on coverage constructors, #1098. [Johan Bjork] +*** Honor --output-split on coverage constructors. (#1098) [Johan Bjork] **** Fix various issues when making outside of the kit. -**** Fix flex 2.6.2 bug, #1103. [Sergey Kvachonok] +**** Fix flex 2.6.2 bug. (#1103) [Sergey Kvachonok] -**** Fix error on bad interface name, #1097. [Todd Strader] +**** Fix error on bad interface name. (#1097) [Todd Strader] -**** Fix error on referencing variable in parent, #1099. [Ian Thompson] +**** Fix error on referencing variable in parent. (#1099) [Ian Thompson] -**** Fix type parameters with low optimization, #1101. [Stefan Wallentowitz] +**** Fix type parameters with low optimization. (#1101) [Stefan Wallentowitz] * Verilator 3.888 2016-10-14 -** Support foreach, #1078. [Xuan Guo] +** Support foreach. (#1078) [Xuan Guo] *** Add --no-decoration to remove output comments, msg2015. [Frederic Requin] *** If VM_PARALLEL_BUILDS=1, use OPT_FAST and OPT_SLOW. [Frederic Requin] Set VM_DEFAULT_RULES=0 for old behavior. -**** Add error on DPI functions > 32 bits, #1898. [Elliot Mednick] +**** Add error on DPI functions > 32 bits. (#1898) [Elliot Mednick] -**** Fix SystemC compiles with VPI, #1081. [Arthur Kahlich] +**** Fix SystemC compiles with VPI. (#1081) [Arthur Kahlich] -**** Fix error on wide numbers that represent shifts, msg1991, #1088. [Mandy Xu] +**** Fix error on wide numbers that represent shifts, msg1991. (#1088) [Mandy Xu] -**** Improve Verilation performance on internal strings, #1896. [Johan Bjork] +**** Improve Verilation performance on internal strings. (#1896) [Johan Bjork] -**** Improve Verilation performance on trace duplicates, #1090. [Johan Bjork] +**** Improve Verilation performance on trace duplicates. (#1090) [Johan Bjork] * Verilator 3.886 2016-07-30 -**** Fix enum values of 11-16 bits wide using .next/.prev, #1062. [Brian Flachs] +**** Fix enum values of 11-16 bits wide using .next/.prev. (#1062) [Brian Flachs] **** Fix false warnings on non-power-2 enums using .next/.prev. -**** Fix comparison of unpacked arrays, #1071. [Andrew Bardsley] +**** Fix comparison of unpacked arrays. (#1071) [Andrew Bardsley] **** Fix compiler warning in GCC 6. [David Horton] * Verilator 3.884 2016-05-18 -** Support parameter type, #376. [Alan Hunter, et al] +** Support parameter type. (#376) [Alan Hunter, et al] -** Support command-line -G/+pvalue param overrides, #1045. [Stefan Wallentowitz] +** Support command-line -G/+pvalue param overrides. (#1045) [Stefan Wallentowitz] -*** The default l2 scope name is now the same as the top-level module, #1050. +*** The default l2 scope name is now the same as the top-level module. (#1050) Use "--l2-name v" for the historical behavior. *** Add --l2-name option for controlling "v" naming. -**** Fix --output-split of constructors, #1035. [Johan Bjork] +**** Fix --output-split of constructors. (#1035) [Johan Bjork] -**** Fix removal of empty packages, modules and cells, #1034. [Johan Bjork] +**** Fix removal of empty packages, modules and cells. (#1034) [Johan Bjork] -**** Fix core dump on Arch Linux/GCC 6.1.1, #1058. [Jannis Harder] +**** Fix core dump on Arch Linux/GCC 6.1.1. (#1058) [Jannis Harder] -**** Fix $value$plusargs to string, #1880. [Frederic Requin] +**** Fix $value$plusargs to string. (#1880) [Frederic Requin] * Verilator 3.882 2016-03-01 -**** Internal Verilation-time performance enhancements, #1021. [Johan Bjork] +**** Internal Verilation-time performance enhancements. (#1021) [Johan Bjork] -**** Support inlining interfaces, #1018. [Johan Bjork] +**** Support inlining interfaces. (#1018) [Johan Bjork] -**** Support SV strings to readmemh, #1040. [Stefan Wallentowitz] +**** Support SV strings to readmemh. (#1040) [Stefan Wallentowitz] -**** Fix unrolling complicated for-loop bounds, #677. [Johan Bjork] +**** Fix unrolling complicated for-loop bounds. (#677) [Johan Bjork] -**** Fix stats file containing multiple unroll entries, #1020. [Johan Bjork] +**** Fix stats file containing multiple unroll entries. (#1020) [Johan Bjork] -**** Fix using short parameter names on negative params, #1022. [Duraid Madina] +**** Fix using short parameter names on negative params. (#1022) [Duraid Madina] -**** Fix read-after-free error, #1031. [Johan Bjork] +**** Fix read-after-free error. (#1031) [Johan Bjork] -**** Fix elaboration-time display warnings, #1032. [Johan Bjork] +**** Fix elaboration-time display warnings. (#1032) [Johan Bjork] -**** Fix crash on very deep function trees, #1028. [Jonathan Kimmitt] +**** Fix crash on very deep function trees. (#1028) [Jonathan Kimmitt] -**** Fix slicing mix of big and little-endian, #1033. [Geoff Barrett] +**** Fix slicing mix of big and little-endian. (#1033) [Geoff Barrett] -**** Fix pattern assignment width propagation, #1037. [Johan Bjork] +**** Fix pattern assignment width propagation. (#1037) [Johan Bjork] * Verilator 3.880 2015-12-19 -*** Support display %u, %v, %p, %z, #989. [Johan Bjork] +*** Support display %u, %v, %p, %z. (#989) [Johan Bjork] -**** Fix real parameters causing bad module names, #992. [Johan Bjork] +**** Fix real parameters causing bad module names. (#992) [Johan Bjork] -**** Fix size-changing cast on packed struct, #993. [Johan Bjork] +**** Fix size-changing cast on packed struct. (#993) [Johan Bjork] -**** Fix function calls on arrayed interface, #994. [Johan Bjork] +**** Fix function calls on arrayed interface. (#994) [Johan Bjork] -**** Fix arrayed interfaces, #879, #1001. [Todd Strader] +**** Fix arrayed interfaces. (#879) (#1001) [Todd Strader] -**** Fix constant function assigned to packed structs, #997. [Johan Bjork] +**** Fix constant function assigned to packed structs. (#997) [Johan Bjork] -**** Fix interface inside generate, #998. [Johan Bjork] +**** Fix interface inside generate. (#998) [Johan Bjork] -**** Fix $signed casts under generates, #999. [Clifford Wolf] +**** Fix $signed casts under generates. (#999) [Clifford Wolf] -**** Fix genvar constant propagation, #1003. [Johan Bjork] +**** Fix genvar constant propagation. (#1003) [Johan Bjork] -**** Fix parameter constant propagation from package, #1004. [Johan Bjork] +**** Fix parameter constant propagation from package. (#1004) [Johan Bjork] -**** Fix array slicing of non-const indexes, #1006. [Johan Bjork] +**** Fix array slicing of non-const indexes. (#1006) [Johan Bjork] -**** Fix dotted generated array error, #1005. [Jeff Bush, Johan Bjork] +**** Fix dotted generated array error. (#1005) [Jeff Bush, Johan Bjork] -**** Fix error instead of warning on large concat, #1865. [Paul Rolfe] +**** Fix error instead of warning on large concat. (#1865) [Paul Rolfe] -**** Fix $bitstoreal constant propagation, #1012. [Jonathan Kimmitt] +**** Fix $bitstoreal constant propagation. (#1012) [Jonathan Kimmitt] -**** Fix model restore crash, #1013. [Jason McMullan] +**** Fix model restore crash. (#1013) [Jason McMullan] -**** Fix arrayed instances to unpacked of same size, #1015. [Varun Koyyalagunta] +**** Fix arrayed instances to unpacked of same size. (#1015) [Varun Koyyalagunta] **** Fix slices of unpacked arrays with non-zero LSBs. -**** Fix ternary operation with unpacked array, #1017. [Varun Koyyalagunta]. +**** Fix ternary operation with unpacked array. (#1017) [Varun Koyyalagunta]. * Verilator 3.878 2015-11-01 -** Add --vpi flag, and fix VPI linkage, #969. [Arthur Kahlich] +** Add --vpi flag, and fix VPI linkage. (#969) [Arthur Kahlich] -** Support genvar indexes into arrayed cells, #517. [Todd Strader] +** Support genvar indexes into arrayed cells. (#517) [Todd Strader] -** Support $sformatf, #977. [Johan Bjork] +** Support $sformatf. (#977) [Johan Bjork] -*** Support elaboration assertions, #973. [Johan Bjork] +*** Support elaboration assertions. (#973) [Johan Bjork] -*** Support $display with non-format arguments, #467. [Jamey Hicks] +*** Support $display with non-format arguments. (#467) [Jamey Hicks] -**** Add VerilatedScopeNameMap for introspection, #966. [Todd Strader] +**** Add VerilatedScopeNameMap for introspection. (#966) [Todd Strader] -**** Ignore %l in $display, #983. [Todd Strader] +**** Ignore %l in $display. (#983) [Todd Strader] -**** Fix very long module names, #937. [Todd Strader] +**** Fix very long module names. (#937) [Todd Strader] -**** Fix internal error on dotted refs into generates, #958. [Jie Xu] +**** Fix internal error on dotted refs into generates. (#958) [Jie Xu] -**** Fix structure parameter constant propagation, #968. [Todd Strader] +**** Fix structure parameter constant propagation. (#968) [Todd Strader] -**** Fix enum constant propagation, #970. [Todd Strader] +**** Fix enum constant propagation. (#970) [Todd Strader] -**** Fix mis-optimizing public DPI functions, #963. [Wei Song] +**** Fix mis-optimizing public DPI functions. (#963) [Wei Song] **** Fix package:scope.scope variable references. -**** Fix $fwrite to constant stderr/stdout, #961. [Wei Song] +**** Fix $fwrite to constant stderr/stdout. (#961) [Wei Song] -**** Fix struct.enum.name method calls, #855. [Jonathon Donaldson] +**** Fix struct.enum.name method calls. (#855) [Jonathon Donaldson] -**** Fix dot indexing into arrayed inferfaces, #978. [Johan Bjork] +**** Fix dot indexing into arrayed inferfaces. (#978) [Johan Bjork] -**** Fix crash in commandArgsPlusMatch, #987. [Jamie Iles] +**** Fix crash in commandArgsPlusMatch. (#987) [Jamie Iles] -**** Fix error message on missing interface, #985. [Todd Strader] +**** Fix error message on missing interface. (#985) [Todd Strader] * Verilator 3.876 2015-08-12 -*** Add tracing_on, etc to vlt files, #932. [Frederic Requin] +*** Add tracing_on, etc to vlt files. (#932) [Frederic Requin] -**** Support extraction of enum bits, #951. [Jonathon Donaldson] +**** Support extraction of enum bits. (#951) [Jonathon Donaldson] -**** Fix MinGW compiler error, #927, #929. [Hans Tichelaar] +**** Fix MinGW compiler error. (#927) (#929) [Hans Tichelaar] -**** Fix .c files to be treated as .cpp, #930. [Jonathon Donaldson] +**** Fix .c files to be treated as .cpp. (#930) [Jonathon Donaldson] -**** Fix string-to-int space conversion, #931. [Fabrizio Ferrandi] +**** Fix string-to-int space conversion. (#931) [Fabrizio Ferrandi] **** Fix dpi imports inside generates. [Michael Tresidder] -**** Fix rounding in trace $timescale, #946. [Frederic Requin] +**** Fix rounding in trace $timescale. (#946) [Frederic Requin] -**** Fix $fopen with SV string, #947. [Sven Stucki] +**** Fix $fopen with SV string. (#947) [Sven Stucki] -**** Fix hashed error with typedef inside block, #948. [Sven Stucki] +**** Fix hashed error with typedef inside block. (#948) [Sven Stucki] -**** Fix makefile with --coverage, #953. [Eivind Liland] +**** Fix makefile with --coverage. (#953) [Eivind Liland] -**** Fix coverage documentation, #954. [Thomas J Whatson] +**** Fix coverage documentation. (#954) [Thomas J Whatson] -**** Fix parameters with function parameter arguments, #952. [Jie Xu] +**** Fix parameters with function parameter arguments. (#952) [Jie Xu] -**** Fix size casts as second argument of cast item, #950. [Jonathon Donaldson] +**** Fix size casts as second argument of cast item. (#950) [Jonathon Donaldson] * Verilator 3.874 2015-06-06 -*** Add pkg-config .pc file, #919. [Stefan Wallentowitz] +*** Add pkg-config .pc file. (#919) [Stefan Wallentowitz] -**** Fix installing missing manpages, #908. [Ahmed El-Mahmoudy] +**** Fix installing missing manpages. (#908) [Ahmed El-Mahmoudy] -**** Fix sign extension in large localparams, #910. [Mike Thyer] +**** Fix sign extension in large localparams. (#910) [Mike Thyer] -**** Fix core dump in sync-async warnings, #911. [Sebastian Dressler] +**** Fix core dump in sync-async warnings. (#911) [Sebastian Dressler] -**** Fix truncation warning with -pins-bv, #912. [Alfonso Martinez] +**** Fix truncation warning with -pins-bv. (#912) [Alfonso Martinez] -**** Fix Cygwin uint32 compile, #914. [Matthew Barr] +**** Fix Cygwin uint32 compile. (#914) [Matthew Barr] -**** Fix preprocessing stringified newline escapes, #915. [Anton Rapp] +**** Fix preprocessing stringified newline escapes. (#915) [Anton Rapp] -**** Fix part-select in constant function, #916. [Andrew Bardsley] +**** Fix part-select in constant function. (#916) [Andrew Bardsley] -**** Fix width extension on mis-width ports, #918. [Patrick Maupin] +**** Fix width extension on mis-width ports. (#918) [Patrick Maupin] -**** Fix width propagation on sized casts, #925. [Jonathon Donaldson] +**** Fix width propagation on sized casts. (#925) [Jonathon Donaldson] -**** Fix MSVC++ compiler error, #927. [Hans Tichelaar] +**** Fix MSVC++ compiler error. (#927) [Hans Tichelaar] * Verilator 3.872 2015-04-05 -*** Add VerilatedVcdFile to allow real-time waveforms, #890. [HyungKi Jeong] +*** Add VerilatedVcdFile to allow real-time waveforms. (#890) [HyungKi Jeong] -*** Add --clk and related optimizations, #1840. [Jie Xu] +*** Add --clk and related optimizations. (#1840) [Jie Xu] *** Fix order of C style arrays. [Duraid Madina] -**** Add --dump-treei-, #894. [Jie Xu] +**** Add --dump-treei-. (#894) [Jie Xu] -**** Fix comma-instantiations with parameters, #884. [Franck Jullien] +**** Fix comma-instantiations with parameters. (#884) [Franck Jullien] -**** Fix SystemC arrayed bit vectors, #886. [David Poole] +**** Fix SystemC arrayed bit vectors. (#886) [David Poole] -**** Fix compile error on MinGW, #887. [HyungKi Jeong] +**** Fix compile error on MinGW. (#887) [HyungKi Jeong] * Verilator 3.870 2015-02-12 -**** Suppress COMBDLY when inside always_latch, #864. [Iztok Jeras] +**** Suppress COMBDLY when inside always_latch. (#864) [Iztok Jeras] -**** Support cast operator with expression size, #865. [Iztok Jeras] +**** Support cast operator with expression size. (#865) [Iztok Jeras] -**** Add warning on slice selection out of bounds, #875. [Cong Van Nguyen]. +**** Add warning on slice selection out of bounds. (#875) [Cong Van Nguyen]. -**** Fix member select error broke in 3.868, #867. [Iztok Jeras] +**** Fix member select error broke in 3.868. (#867) [Iztok Jeras] -**** Fix $sccanf from string, #866. [David Pierce] +**** Fix $sccanf from string. (#866) [David Pierce] -**** Fix VM_PARALLEL_BUILDS broke in 3.868, #870. [Hiroki Honda] +**** Fix VM_PARALLEL_BUILDS broke in 3.868. (#870) [Hiroki Honda] -**** Fix non-ANSI modport instantiations, #868. [Kevin Thompson] +**** Fix non-ANSI modport instantiations. (#868) [Kevin Thompson] -**** Fix UNOPTFLAT change detect on multidim arrays, #872. [Andrew Bardsley] +**** Fix UNOPTFLAT change detect on multidim arrays. (#872) [Andrew Bardsley] -**** Fix slice connections of arrays to ports, #880. [Varun Koyyalagunta] +**** Fix slice connections of arrays to ports. (#880) [Varun Koyyalagunta] -**** Fix mis-optimizing gate assignments in unopt blocks, #881. [Mike Thyer] +**** Fix mis-optimizing gate assignments in unopt blocks. (#881) [Mike Thyer] -**** Fix sign extension of pattern members, #882. [Iztok Jeras] +**** Fix sign extension of pattern members. (#882) [Iztok Jeras] **** Fix clang compile warnings. @@ -1121,152 +1165,152 @@ The contributors that suggested a given feature are shown in []. Thanks! ** SystemPerl mode is deprecated and now untested. -*** Support enum.first/name and similar methods, #460, #848. +*** Support enum.first/name and similar methods. (#460) (#848) -*** Add 'string' printing and comparisons, #746, #747, etc. +*** Add 'string' printing and comparisons. (#746) (#747) etc. -*** Inline C functions that are used only once, #1838. [Jie Xu] +*** Inline C functions that are used only once. (#1838) [Jie Xu] -*** Fix tracing SystemC signals with structures, #858. [Eivind Liland] +*** Fix tracing SystemC signals with structures. (#858) [Eivind Liland] Note that SystemC traces will no longer show the signals in the wrapper, they can be seen one level further down. -**** Add --stats-vars, #851. [Jeremy Bennett] +**** Add --stats-vars. (#851) [Jeremy Bennett] -**** Fix bare generates in interfaces, #789. [Bob Newgard] +**** Fix bare generates in interfaces. (#789) [Bob Newgard] -**** Fix underscores in real literals, #863. [Jonathon Donaldson] +**** Fix underscores in real literals. (#863) [Jonathon Donaldson] * Verilator 3.866 2014-11-15 -*** Fix +define+A+B to define A and B to match other simulators, #847. [Adam Krolnik] +*** Fix +define+A+B to define A and B to match other simulators. (#847) [Adam Krolnik] -*** Add optimization of wires from arrayed cells, #1831. [Jie Xu] +*** Add optimization of wires from arrayed cells. (#1831) [Jie Xu] -*** Add optimization of operators between concats, #1831. [Jie Xu] +*** Add optimization of operators between concats. (#1831) [Jie Xu] -*** Add public enums, #833. [Jonathon Donaldson] +*** Add public enums. (#833) [Jonathon Donaldson] -*** Trace_off now operates on cells, #826. [Lane Brooks] +*** Trace_off now operates on cells. (#826) [Lane Brooks] -**** Fix public parameters in unused packages, #804. [Jonathon Donaldson] +**** Fix public parameters in unused packages. (#804) [Jonathon Donaldson] -**** Fix select when partially out-of-bound, #823. [Cliffort Wolf] +**** Fix select when partially out-of-bound. (#823) [Cliffort Wolf] -**** Fix generate unrolling with function call, #830. [Steven Slatter] +**** Fix generate unrolling with function call. (#830) [Steven Slatter] -**** Fix cast-to-size context-determined sizing, #828. [Geoff Barrett] +**** Fix cast-to-size context-determined sizing. (#828) [Geoff Barrett] -**** Fix not tracing modules following primitives, #837. [Jie Xu] +**** Fix not tracing modules following primitives. (#837) [Jie Xu] -**** Fix trace overflow on huge arrays, #834. [Geoff Barrett] +**** Fix trace overflow on huge arrays. (#834) [Geoff Barrett] -**** Fix quoted comment slashes in defines, #845. [Adam Krolnik] +**** Fix quoted comment slashes in defines. (#845) [Adam Krolnik] * Verilator 3.864 2014-09-21 -*** Support power operator with real, #809. [Jonathon Donaldson] +*** Support power operator with real. (#809) [Jonathon Donaldson] **** Improve verilator_profcfunc time attributions. [Jonathon Donaldson] -**** Fix duplicate anonymous structures in $root, #788. [Bob Newgard] +**** Fix duplicate anonymous structures in $root. (#788) [Bob Newgard] -**** Fix mis-optimization of bit-swap in wide signal, #800. [Jie Xu] +**** Fix mis-optimization of bit-swap in wide signal. (#800) [Jie Xu] -**** Fix error when tracing public parameters, #722. [Jonathon Donaldson] +**** Fix error when tracing public parameters. (#722) [Jonathon Donaldson] -**** Fix dpiGetContext in dotted scopes, #740. [Geoff Barrett] +**** Fix dpiGetContext in dotted scopes. (#740) [Geoff Barrett] -**** Fix over-shift structure optimization error, #803. [Jeff Bush] +**** Fix over-shift structure optimization error. (#803) [Jeff Bush] -**** Fix optional parameter keyword in module #(), #810. [Iztok Jeras] +**** Fix optional parameter keyword in module #(). (#810) [Iztok Jeras] -**** Fix $warning/$error multi-argument ordering, #816. [Jonathon Donaldson] +**** Fix $warning/$error multi-argument ordering. (#816) [Jonathon Donaldson] -**** Fix clang warnings, #818. [Iztok Jeras] +**** Fix clang warnings. (#818) [Iztok Jeras] -**** Fix string formats under deep expressions, #820. [Iztok Jeras] +**** Fix string formats under deep expressions. (#820) [Iztok Jeras] * Verilator 3.862 2014-06-10 *** Using command line -Wno-{WARNING} now overrides file-local lint_on. -*** Add -P to suppress `line and blanks with preprocessing, #781. [Derek Lockhart] +*** Add -P to suppress `line and blanks with preprocessing. (#781) [Derek Lockhart] *** Support SV 2012 package import before port list. **** Change SYMRSVDWORD to print as warning rather than error. -**** Fix seg-fault with variable of parameterized interface, #692. [Jie Xu] +**** Fix seg-fault with variable of parameterized interface. (#692) [Jie Xu] -**** Fix false name conflict on cells in generate blocks, #749. [Igor Lesik] +**** Fix false name conflict on cells in generate blocks. (#749) [Igor Lesik] -**** Fix pattern assignment to basic types, #767. [Jie Xu] +**** Fix pattern assignment to basic types. (#767) [Jie Xu] -**** Fix pattern assignment to conditionals, #769. [Jie Xu] +**** Fix pattern assignment to conditionals. (#769) [Jie Xu] -**** Fix shift corner-cases, #765, #766, #768, #772, #774, #776. [Clifford Wolf] +**** Fix shift corner-cases. (#765) (#766) (#768) (#772) (#774) (#776) [Clifford Wolf] -**** Fix C compiler interpreting signing, #773. [Clifford Wolf] +**** Fix C compiler interpreting signing. (#773) [Clifford Wolf] -**** Fix late constant division by zero giving X error, #775. [Clifford Wolf] +**** Fix late constant division by zero giving X error. (#775) [Clifford Wolf] **** Fix gate primitives with arrays and non-arrayed pins. -**** Fix DETECTARRAY error on packed arrays, #770. [Jie Xu] +**** Fix DETECTARRAY error on packed arrays. (#770) [Jie Xu] **** Fix ENDLABEL warnings on escaped identifiers. -**** Fix string corruption, #780. [Derek Lockhart] +**** Fix string corruption. (#780) [Derek Lockhart] * Verilator 3.860 2014-05-11 ** PSL is no longer supported, please use System Verilog assertions. -** Support '{} assignment pattern on arrays, #355. +** Support '{} assignment pattern on arrays. (#355) -** Support streaming operators, #649. [Glen Gibb] +** Support streaming operators. (#649) [Glen Gibb] -** Fix expression problems with -Wno-WIDTH, #729, #736, #737, #759. +** Fix expression problems with -Wno-WIDTH. (#729) (#736) (#737) (#759) Where WIDTH warnings were ignored this might result in different warning messages and results, though it should better match the spec. [Clifford Wolf] *** Add --no-trace-params. -*** Add assertions on 'unique if', #725. [Jeff Bush] +*** Add assertions on 'unique if'. (#725) [Jeff Bush] *** Add PINCONNECTEMPTY warning. [Holger Waechtler] -*** Support parameter arrays, #683. [Jeremy Bennett] +*** Support parameter arrays. (#683) [Jeremy Bennett] -*** Fix begin_keywords "1800+VAMS", #1806. +*** Fix begin_keywords "1800+VAMS". (#1806) -**** Documentation fixes, #723. [Glen Gibb] +**** Documentation fixes. (#723) [Glen Gibb] -**** Support {} in always sensitivity lists, #745. [Igor Lesik] +**** Support {} in always sensitivity lists. (#745) [Igor Lesik] **** Fix tracing of package variables and real arrays. -**** Fix tracing of packed arrays without --trace-structs, #742. [Jie Xu] +**** Fix tracing of packed arrays without --trace-structs. (#742) [Jie Xu] -**** Fix missing coverage line on else-if, #727. [Sharad Bagri] +**** Fix missing coverage line on else-if. (#727) [Sharad Bagri] **** Fix modport function import not-found error. -**** Fix power operator calculation, #730, #735. [Clifford Wolf] +**** Fix power operator calculation. (#730) (#735) [Clifford Wolf] -**** Fix reporting struct members as reserved words, #741. [Chris Randall] +**** Fix reporting struct members as reserved words. (#741) [Chris Randall] -**** Fix change detection error on unions, #758. [Jie Xu] +**** Fix change detection error on unions. (#758) [Jie Xu] -**** Fix -Wno-UNOPTFLAT change detection with 64-bits, #762. [Clifford Wolf] +**** Fix -Wno-UNOPTFLAT change detection with 64-bits. (#762) [Clifford Wolf] -**** Fix shift-right optimization, #763. [Clifford Wolf] +**** Fix shift-right optimization. (#763) [Clifford Wolf] **** Fix Mac OS-X test issues. [Holger Waechtler] @@ -1275,67 +1319,67 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 3.856 2014-03-11 -*** Support case inside, #708. [Jan Egil Ruud] +*** Support case inside. (#708) [Jan Egil Ruud] -*** Add parameters into trace files, #706. [Alex Solomatnikov] +*** Add parameters into trace files. (#706) [Alex Solomatnikov] -**** Fix parsing "#0 'b0", #256. +**** Fix parsing "#0 'b0". (#256) **** Fix array bound checks on real variables. -**** Fix --skip-identical mis-detecting on OS-X, #707. +**** Fix --skip-identical mis-detecting on OS-X. (#707) -**** Fix missing VL_SHIFTRS_IQI with WIDTH warning, #714. [Fabrizio Ferrandi] +**** Fix missing VL_SHIFTRS_IQI with WIDTH warning. (#714) [Fabrizio Ferrandi] -**** Fix signed shift right optimization, #715. [Fabrizio Ferrandi] +**** Fix signed shift right optimization. (#715) [Fabrizio Ferrandi] -**** Fix internal error on "input x =" syntax error, #716. [Lane Brooks] +**** Fix internal error on "input x =" syntax error. (#716) [Lane Brooks] -**** Fix slice extraction from packed array, #717. [Jan Egil Ruud] +**** Fix slice extraction from packed array. (#717) [Jan Egil Ruud] -**** Fix inside statement EQWILD error, #718. [Jan Egil Ruud] +**** Fix inside statement EQWILD error. (#718) [Jan Egil Ruud] * Verilator 3.855 2014-01-18 -*** Support modport import, #696. [Jeremy Bennett] +*** Support modport import. (#696) [Jeremy Bennett] -*** Add --trace-structs to show struct names, #673. [Chris Randall] +*** Add --trace-structs to show struct names. (#673) [Chris Randall] -**** Fix tracing of packed structs, #705. [Jie Xu] +**** Fix tracing of packed structs. (#705) [Jie Xu] -**** Fix --lint-only with MinGW, #1813. [HyungKi Jeong] +**** Fix --lint-only with MinGW. (#1813) [HyungKi Jeong] **** Fix some delayed assignments of typedefed unpacked arrays. -**** Fix wire declarations with size and not range, #466. [Alex Solomatnikov] +**** Fix wire declarations with size and not range. (#466) [Alex Solomatnikov] -**** Fix parameter pin vs. normal pin error, #704. [Alex Solomatnikov] +**** Fix parameter pin vs. normal pin error. (#704) [Alex Solomatnikov] * Verilator 3.854 2013-11-26 *** Add UNPACKED warning to convert unpacked structs. [Jeremy Bennett] -*** Add --compiler clang to work around compiler bug, #694. [Stefan Ludwig] +*** Add --compiler clang to work around compiler bug. (#694) [Stefan Ludwig] -**** Support vpi_get of vpiSuppressVal, #687. [Varun Koyyalagunta] +**** Support vpi_get of vpiSuppressVal. (#687) [Varun Koyyalagunta] -**** Support vpi_get_time, #688. [Varun Koyyalagunta] +**** Support vpi_get_time. (#688) [Varun Koyyalagunta] -**** Fix evaluation of chained parameter functions, #684. [Ted Campbell] +**** Fix evaluation of chained parameter functions. (#684) [Ted Campbell] **** Fix enum value extension of '1. -**** Fix multiple VPI variable callbacks, #679. [Rich Porter] +**** Fix multiple VPI variable callbacks. (#679) [Rich Porter] -**** Fix vpi_get of vpiSize, #680. [Rich Porter] +**** Fix vpi_get of vpiSize. (#680) [Rich Porter] -**** Fix vpi_remove_cb inside callback, #689. [Varun Koyyalagunta] +**** Fix vpi_remove_cb inside callback. (#689) [Varun Koyyalagunta] -**** Fix crash with coverage of structures, #691. [Eivind Liland] +**** Fix crash with coverage of structures. (#691) [Eivind Liland] -**** Fix array assignment from const var, #693. [Jie Xu] +**** Fix array assignment from const var. (#693) [Jie Xu] * Verilator 3.853 2013-09-30 @@ -1347,118 +1391,118 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Support named function and task arguments. [Chris Randall] -*** Report SELRANGE warning for non-generate if, #675. [Roland Kruse] +*** Report SELRANGE warning for non-generate if. (#675) [Roland Kruse] -**** Fix ordering of $fgetc, #1808. [Frederic Requin] +**** Fix ordering of $fgetc. (#1808) [Frederic Requin] **** Fix --output-split-cfunc to count internal functions. [Chris Randall] -**** Fix crash on 32-bit Ubuntu, #670. [Mark Jackson Pulver] +**** Fix crash on 32-bit Ubuntu. (#670) [Mark Jackson Pulver] * Verilator 3.851 2013-08-15 -*** Fix ordering of clock enables with delayed assigns, #613. [Jeremy Bennett] +*** Fix ordering of clock enables with delayed assigns. (#613) [Jeremy Bennett] -*** Fix vpi_iterate on memory words, #655. [Rich Porter] +*** Fix vpi_iterate on memory words. (#655) [Rich Porter] -**** Fix final duplicate declarations when non-inlined, #661. [Charlie Brej] +**** Fix final duplicate declarations when non-inlined. (#661) [Charlie Brej] -**** Fix interface ports with comma lists, #1779. [Ed Lander] +**** Fix interface ports with comma lists. (#1779) [Ed Lander] **** Fix parameter real conversion from integer. -**** Fix clang warnings, #668. [Yutetsu Takatsukasa] +**** Fix clang warnings. (#668) [Yutetsu Takatsukasa] * Verilator 3.850 2013-06-02 -** Support interfaces and modports, #102. [Byron Bradley, Jeremy Bennett] +** Support interfaces and modports. (#102) [Byron Bradley, Jeremy Bennett] -*** Duplicate clock gate optimization on by default, #621. +*** Duplicate clock gate optimization on by default. (#621) -**** Fix arrayed input compile error, #645. [Krzysztof Jankowski] +**** Fix arrayed input compile error. (#645) [Krzysztof Jankowski] -**** Fix GCC version runtime changes, #651. [Jeremy Bennett] +**** Fix GCC version runtime changes. (#651) [Jeremy Bennett] -**** Fix packed array select internal error, #652. [Krzysztof Jankowski] +**** Fix packed array select internal error. (#652) [Krzysztof Jankowski] * Verilator 3.847 2013-05-11 -*** Add ALWCOMBORDER warning. [KC Buckenmaier] +*** Add ALWCOMBORDER warning. [KC Buckenmaier] -*** Add --pins-sc-uint and --pins-sc-biguint, #638. [Alex Hornung] +*** Add --pins-sc-uint and --pins-sc-biguint. (#638) [Alex Hornung] **** Support "signal[vec]++". -**** Fix simulation error when inputs and MULTIDRIVEN, #634. [Ted Campbell] +**** Fix simulation error when inputs and MULTIDRIVEN. (#634) [Ted Campbell] -**** Fix module resolution with __, #631. [Jason McMullan] +**** Fix module resolution with __. (#631) [Jason McMullan] -**** Fix packed array non-zero right index select crash, #642. [Krzysztof Jankowski] +**** Fix packed array non-zero right index select crash. (#642) [Krzysztof Jankowski] -**** Fix nested union crash, #643. [Krzysztof Jankowski] +**** Fix nested union crash. (#643) [Krzysztof Jankowski] * Verilator 3.846 2013-03-09 -** IEEE 1800-2012 is now the default language. This adds 4 new keywords +** IEEE 1800-2012 is now the default language. This adds 4 new keywords and updates the svdpi.h and vpi_user.h header files. -*** Add --report-unoptflat, #611. [Jeremy Bennett] +*** Add --report-unoptflat. (#611) [Jeremy Bennett] -*** Add duplicate clock gate optimization, #1772. [Varun Koyyalagunta] +*** Add duplicate clock gate optimization. (#1772) [Varun Koyyalagunta] Disabled unless -OD or -O3 used, please try it as may get some significant speedups. *** Fix wrong dot resolution under inlining. [Art Stamness] -**** Support pattern assignment features, #616, #617, #618. [Ed Lander] +**** Support pattern assignment features. (#616) (#617) (#618) [Ed Lander] -**** Support bind in $unit, #602. [Ed Lander] +**** Support bind in $unit. (#602) [Ed Lander] -**** Support '() sized casts, #628. [Ed Lander] +**** Support '() sized casts. (#628) [Ed Lander] -**** Fix DETECTARRAY on packed structures, #610. [Jeremy Bennett] +**** Fix DETECTARRAY on packed structures. (#610) [Jeremy Bennett] -**** Fix LITENDIAN on unpacked structures, #614. [Wai Sum Mong] +**** Fix LITENDIAN on unpacked structures. (#614) [Wai Sum Mong] -**** Fix 32-bit OS VPI scan issue, #615. [Jeremy Bennett, Rich Porter] +**** Fix 32-bit OS VPI scan issue. (#615) [Jeremy Bennett, Rich Porter] -**** Fix opening a VerilatedVcdC file multiple times, #1774. [Frederic Requin] +**** Fix opening a VerilatedVcdC file multiple times. (#1774) [Frederic Requin] -**** Fix UNOPTFLAT circular array bounds crossing, #630. [Jie Xu] +**** Fix UNOPTFLAT circular array bounds crossing. (#630) [Jie Xu] * Verilator 3.845 2013-02-04 -*** Fix nested packed arrays and struct, #600. [Jeremy Bennett] +*** Fix nested packed arrays and struct. (#600) [Jeremy Bennett] Packed arrays are now represented as a single linear vector in - Verilated models. This may affect packed arrays that are public or + Verilated models. This may affect packed arrays that are public or accessed via the VPI. -*** Support wires with data types, #608. [Ed Lander] +*** Support wires with data types. (#608) [Ed Lander] -*** Support bind, to module names only, #602. [Ed Lander] +*** Support bind, to module names only. (#602) [Ed Lander] -*** Support VPI product info, warning calls, etc, #588. [Rick Porter] +*** Support VPI product info, warning calls, etc. (#588) [Rick Porter] -*** Support $left, $right and related functions, #448. [Iztok Jeras] +*** Support $left, $right and related functions. (#448) [Iztok Jeras] *** Support inside expressions. *** Define SYSTEMVERILOG, SV_COV_START and other IEEE mandated predefines. -**** Fix pin width mismatch error, #595. [Alex Solomatnikov] +**** Fix pin width mismatch error. (#595) [Alex Solomatnikov] -**** Fix implicit one bit parameter selection, #603. [Jeremy Bennett] +**** Fix implicit one bit parameter selection. (#603) [Jeremy Bennett] -**** Fix signed/unsigned parameter misconversion, #606. [Jeremy Bennett] +**** Fix signed/unsigned parameter misconversion. (#606) [Jeremy Bennett] -**** Fix segfault on multidimensional dotted arrays, #607. [Jie Xu] +**** Fix segfault on multidimensional dotted arrays. (#607) [Jie Xu] -**** Fix per-bit array output connection error, #414. [Jan Egil Ruud] +**** Fix per-bit array output connection error. (#414) [Jan Egil Ruud] **** Fix package logic var compile error. @@ -1467,137 +1511,137 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 3.844 2013-01-09 -*** Support "unsigned int" DPI import functions, #1770. [Alex Lee] +*** Support "unsigned int" DPI import functions. (#1770) [Alex Lee] -*** Fix package resolution of parameters, #586. [Jeremy Bennett] +*** Fix package resolution of parameters. (#586) [Jeremy Bennett] -**** Fix non-integer vpi_get_value, #587. [Rich Porter] +**** Fix non-integer vpi_get_value. (#587) [Rich Porter] -**** Fix task inlining under $display and case, #589, #598. [Holger Waechtler] +**** Fix task inlining under $display and case. (#589) (#598) [Holger Waechtler] -**** Fix package import of non-localparam parameter, #474, #591. [Jeremy Bennett] +**** Fix package import of non-localparam parameter. (#474) (#591) [Jeremy Bennett] -**** Fix package import of package imports, partial #592. [Jeremy Bennett] +**** Fix package import of package imports, partial #592. [Jeremy Bennett] -**** Fix package import preventing local var, #599. [Jeremy Bennett] +**** Fix package import preventing local var. (#599) [Jeremy Bennett] -**** Fix array extraction of implicit vars, #601. [Joe Eiler] +**** Fix array extraction of implicit vars. (#601) [Joe Eiler] * Verilator 3.843 2012-12-01 -*** Add +1364-1995ext and similar language options, #532. [Jeremy Bennett] +*** Add +1364-1995ext and similar language options. (#532) [Jeremy Bennett] -**** Fix mis-optimized identical submodule subtract, #581. [Charlie Brej] +**** Fix mis-optimized identical submodule subtract. (#581) [Charlie Brej] -**** Fix crash on dotted references into dead modules, #583. [Jeremy Bennett] +**** Fix crash on dotted references into dead modules. (#583) [Jeremy Bennett] -**** Fix compile issues on MSVCC, #571, #577. [Amir Gonnen] +**** Fix compile issues on MSVCC. (#571) (#577) [Amir Gonnen] -**** Fix --debug overriding preceding --dump-treei, #580. [Jeremy Bennett] +**** Fix --debug overriding preceding --dump-treei. (#580) [Jeremy Bennett] * Verilator 3.842 2012-11-03 -**** Add -x-initial-edge, #570. [Jeremy Bennett] +**** Add -x-initial-edge. (#570) [Jeremy Bennett] -**** Fix parameter pins interspersed with cells broke in 3.840. [Bernard Deadman] +**** Fix parameter pins interspersed with cells broke in 3.840. [Bernard Deadman] -**** Fix large shift error on large shift constants. [David Welch] +**** Fix large shift error on large shift constants. [David Welch] -**** Fix $display mangling on GCC 4.7 and speed up, #1765, #373, #574. [R Diez] +**** Fix $display mangling on GCC 4.7 and speed up. (#1765) (#373) (#574) [R Diez] -**** Fix array of struct references giving false error, #566. [Julius Baxter] +**** Fix array of struct references giving false error. (#566) [Julius Baxter] -**** Fix missing var access functions when no DPI, #572. [Amir Gonnen] +**** Fix missing var access functions when no DPI. (#572) [Amir Gonnen] -**** Fix name collision on unnamed blocks, #567. [Chandan Egbert] +**** Fix name collision on unnamed blocks. (#567) [Chandan Egbert] -**** Fix name collision on task inputs, #569. [Chandan Egbert] +**** Fix name collision on task inputs. (#569) [Chandan Egbert] * Verilator 3.841 2012-09-03 -*** Add --savable to support model save/restore. [Jeremy Bennett] +*** Add --savable to support model save/restore. [Jeremy Bennett] *** Support '{} assignment pattern on structures, part of #355. -**** Fix double-deep parameter cell WIDTHs, #541. [Hiroki Honda] +**** Fix double-deep parameter cell WIDTHs. (#541) [Hiroki Honda] -**** Fix imports under multiple instantiated cells, #542. [Alex Solomatnikov] +**** Fix imports under multiple instantiated cells. (#542) [Alex Solomatnikov] -**** Fix defparam in generate broke in 3.840, #543. [Alex Solomatnikov] +**** Fix defparam in generate broke in 3.840. (#543) [Alex Solomatnikov] -**** Fix duplicate begin error broke in 3.840, #548. [Alex Solomatnikov] +**** Fix duplicate begin error broke in 3.840. (#548) [Alex Solomatnikov] -**** Fix triangle symbol resolution error broke in 3.840, #550. [Ted Campbell] +**** Fix triangle symbol resolution error broke in 3.840. (#550) [Ted Campbell] * Verilator 3.840 2012-07-31 Beta ** Rewrote tristate handling; supports tri0, tri1, tristate bit selects, - concatenates and pullup/pulldowns, #395, #56, #54, #51. + concatenates and pullup/pulldowns. (#395) (#56) (#54) (#51) [Alex Solomatnikov, Lane Brooks, et al] -** Support packed structures and unions, #181. +** Support packed structures and unions. (#181) Note this was a major internal change that may lead to some instability. -*** Support tri0 and tri1, #462. [Alex Solomatnikov] +*** Support tri0 and tri1. (#462) [Alex Solomatnikov] -*** Support nmos and pmos, #488. [Alex Solomatnikov] +*** Support nmos and pmos. (#488) [Alex Solomatnikov] -*** Add INITIALDLY warning on initial assignments, #478. [Alex Solomatnikov] +*** Add INITIALDLY warning on initial assignments. (#478) [Alex Solomatnikov] *** Add PINMISSING and PINNOCONNECT lint checks. *** Add --converge-limit option. -*** Fix generate operators not short circuiting, #413. [by Jeremy Bennett] +*** Fix generate operators not short circuiting. (#413) [by Jeremy Bennett] -*** Fix parameters not supported in constant functions, #474. [Alex Solomatnikov] +*** Fix parameters not supported in constant functions. (#474) [Alex Solomatnikov] -**** Fix duplicate warnings/errors, #516. [Alex Solomatnikov] +**** Fix duplicate warnings/errors. (#516) [Alex Solomatnikov] -**** Fix signed extending biops with WIDTH warning off, #511. [Junji Hashimoto] +**** Fix signed extending biops with WIDTH warning off. (#511) [Junji Hashimoto] -**** Fix ITOD internal error on real conversions, #491. [Alex Solomatnikov] +**** Fix ITOD internal error on real conversions. (#491) [Alex Solomatnikov] -**** Fix input and real loosing real data type, #501. [Alex Solomatnikov] +**** Fix input and real loosing real data type. (#501) [Alex Solomatnikov] -**** Fix imports causing symbol table error, #490. [Alex Solomatnikov] +**** Fix imports causing symbol table error. (#490) [Alex Solomatnikov] -**** Fix newlines in radix values, #507. [Walter Lavino] +**** Fix newlines in radix values. (#507) [Walter Lavino] -**** Fix loop error message to report line, #513. [Jeremy Bennett] +**** Fix loop error message to report line. (#513) [Jeremy Bennett] **** Fix false UNUSED warning on file system calls. -**** Fix GCC 4.7.0 compile warnings, #530. [Jeremy Bennett] +**** Fix GCC 4.7.0 compile warnings. (#530) [Jeremy Bennett] **** Fix svdpi.h compile error on Apple OS. -**** Fix compile error under git submodules, #534. [Aurelien Francillon] +**** Fix compile error under git submodules. (#534) [Aurelien Francillon] * Verilator 3.833 2012-04-15 -*** Support += and -= in standard for loops, #463. [Alex Solomatnikov] +*** Support += and -= in standard for loops. (#463) [Alex Solomatnikov] -*** Fix processing unused parametrized modules, #469, #470. [Alex Solomatnikov] +*** Fix processing unused parametrized modules. (#469) (#470) [Alex Solomatnikov] -**** Add SELRANGE as warning instead of error, #477. [Alex Solomatnikov] +**** Add SELRANGE as warning instead of error. (#477) [Alex Solomatnikov] -**** Add readme.pdf and internal.pdf and doxygen, #483. [by Jeremy Bennett] +**** Add readme.pdf and internal.pdf and doxygen. (#483) [by Jeremy Bennett] -**** Fix change detections on arrays, #364. [John Stevenson, Alex Solomatnikov] +**** Fix change detections on arrays. (#364) [John Stevenson, Alex Solomatnikov] -**** Fix signed array warning, #456. [Alex Solomatnikov] +**** Fix signed array warning. (#456) [Alex Solomatnikov] -**** Fix genvar and begin under generate, #461. [Alex Solomatnikov] +**** Fix genvar and begin under generate. (#461) [Alex Solomatnikov] -**** Fix real constant parameter functions, #475. [Alex Solomatnikov] +**** Fix real constant parameter functions. (#475) [Alex Solomatnikov] -**** Fix and document --gdb option, #454. [Jeremy Bennett] +**** Fix and document --gdb option. (#454) [Jeremy Bennett] **** Fix OpenSolaris compile error. [Sanjay Singh] @@ -1606,100 +1650,100 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Fix memory delayed assignments from multiple clock domains. [Andrew Ling] -*** Support arrayed SystemC I/O pins. [Christophe Joly] +*** Support arrayed SystemC I/O pins. [Christophe Joly] *** Report MULTIDRIVEN on memories set in multiple clock domains. -*** Report ENDLABEL on mismatching end labels, #450. [Iztok Jeras] +*** Report ENDLABEL on mismatching end labels. (#450) [Iztok Jeras] -**** Fix expansion of back-slashed escaped macros, #441. [Alberto Del Rio] +**** Fix expansion of back-slashed escaped macros. (#441) [Alberto Del Rio] **** Fix inheriting real and signed type across untyped parameters. -**** Fix core dump with over 100 deep UNOPTFLAT, #432. [Joe Eiler] +**** Fix core dump with over 100 deep UNOPTFLAT. (#432) [Joe Eiler] **** Fix false command not found warning in makefiles. [Ruben Diez] **** Fix hang when functions inside begin block. [David Welch] -**** Fix hang on recursive substitution `defines, #443. [Alex Solomatnikov] +**** Fix hang on recursive substitution `defines. (#443) [Alex Solomatnikov] * Verilator 3.831 2012-01-20 -** Support SystemC 2.3.0 prerelease. This requires setting the new +** Support SystemC 2.3.0 prerelease. This requires setting the new SYSTEMC_INCLUDE and SYSTEMC_LIBDIR variables in place of now - deprecated SYSTEMC and SYSTEMC_ARCH. [Iztok Jeras] + deprecated SYSTEMC and SYSTEMC_ARCH. [Iztok Jeras] -**** Suppress VARHIDDEN on dpi import arguments. [Ruben Diez] +**** Suppress VARHIDDEN on dpi import arguments. [Ruben Diez] -**** Support "generate for (genvar i=0; ...". [David Kravitz] +**** Support "generate for (genvar i=0; ...". [David Kravitz] -**** Fix dpi exports with > 32 bit but < 64 bit args, #423. [Chandan Egbert] +**** Fix dpi exports with > 32 bit but < 64 bit args. (#423) [Chandan Egbert] -**** Fix array of instantiations with sub-range output, #414. [Jeremy Bennett] +**** Fix array of instantiations with sub-range output. (#414) [Jeremy Bennett] **** Fix BLKSEQ warnings on variables declared inside always. [Ruben Diez] * Verilator 3.830 2011-11-27 -** With "--language VAMS" support a touch of Verilog AMS. [Holger Waechtler] +** With "--language VAMS" support a touch of Verilog AMS. [Holger Waechtler] -*** Add sc_bv attribute to force bit vectors, #402. [by Stefan Wallentowitz] +*** Add sc_bv attribute to force bit vectors. (#402) [by Stefan Wallentowitz] -**** Search for user -y paths before default current directory. [Ruben Diez] +**** Search for user -y paths before default current directory. [Ruben Diez] -**** Support constants in sensitivity lists, #412. [Jeremy Bennett] +**** Support constants in sensitivity lists. (#412) [Jeremy Bennett] -**** Support $system. [Ruben Diez] +**** Support $system. [Ruben Diez] **** Support $sscanf with %g. [Holger Waechtler] **** Indicate 'exiting due to errors' if errors, not warnings. [Ruben Diez] -**** Fix bad result with if-else-return optimization, #420. [Alex Solomatnikov] +**** Fix bad result with if-else-return optimization. (#420) [Alex Solomatnikov] -**** Fix reporting not found modules if generate-off, #403. [Jeremy Bennett] +**** Fix reporting not found modules if generate-off. (#403) [Jeremy Bennett] **** Fix $display with %d following %g. [Holger Waechtler] * Verilator 3.824 2011-10-25 -*** Fix "always @ (* )", #403, #404. [Walter Lavino] +*** Fix "always @ (* )". (#403) (#404) [Walter Lavino] -*** Add ASSIGNIN as suppressable error. [Jeremy Bennett] +*** Add ASSIGNIN as suppressable error. [Jeremy Bennett] -**** Fix 3.823 constructor core dump on Debian, #401. [Ahmed El-Mahmoudy] +**** Fix 3.823 constructor core dump on Debian. (#401) [Ahmed El-Mahmoudy] * Verilator 3.823 2011-10-20 -*** Support $ceil, $floor, etc. [Alex Solomatnikov] +*** Support $ceil, $floor, etc. [Alex Solomatnikov] -*** Add configure options for cc warnings and extended tests. [Ruben Diez] +*** Add configure options for cc warnings and extended tests. [Ruben Diez] -*** Add -Wall reporting ASSIGNDLY on assignment delays. [Ruben Diez] +*** Add -Wall reporting ASSIGNDLY on assignment delays. [Ruben Diez] -*** Fix UNDRIVEN warnings inside DPI import functions. [Ruben Diez] +*** Fix UNDRIVEN warnings inside DPI import functions. [Ruben Diez] -*** Fix --help output to go to stderr, not stdout, #397. [Ruben Diez] +*** Fix --help output to go to stderr, not stdout. (#397) [Ruben Diez] -**** Fix DPI import output of 64 bits, #398. [Mike Denio] +**** Fix DPI import output of 64 bits. (#398) [Mike Denio] -**** Fix DPI import false BLKSEQ warnings. [Alex Solomatnikov] +**** Fix DPI import false BLKSEQ warnings. [Alex Solomatnikov] -**** Fix MSVC compile warning with trunc/round, #394. [Amir Gonnen] +**** Fix MSVC compile warning with trunc/round. (#394) [Amir Gonnen] -**** Fix autoconf and Makefile warnings, #396. [Ruben Diez] +**** Fix autoconf and Makefile warnings. (#396) [Ruben Diez] * Verilator 3.821 2011-09-14 -**** Fix PowerPC runtime error, #288. [Ahmed El-Mahmoudy] +**** Fix PowerPC runtime error. (#288) [Ahmed El-Mahmoudy] -**** Fix internal error on integer casts, #374. [Chandan Egbert] +**** Fix internal error on integer casts. (#374) [Chandan Egbert] * Verilator 3.820 2011-07-28 @@ -1712,12 +1756,12 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Support $fopen and I/O with integer instead of `verilator_file_descriptor. -*** Support coverage in -cc and -sc output modes. [John Li] +*** Support coverage in -cc and -sc output modes. [John Li] Note this requires SystemPerl 1.338 or newer. -**** Fix vpi_register_cb using bad s_cb_data, #370. [by Thomas Watts] +**** Fix vpi_register_cb using bad s_cb_data. (#370) [by Thomas Watts] -**** Fix $display missing leading zeros in %0d, #367. [Alex Solomatnikov] +**** Fix $display missing leading zeros in %0d. (#367) [Alex Solomatnikov] **** Use 'vluint64_t' for SystemC instead of (same sized) 'uint64' for MSVC++. @@ -1726,68 +1770,68 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Support bit vectors > 64 bits wide in DPI import and exports. -*** Fix out of memory on slice syntax error, #354. [Alex Solomatnikov] +*** Fix out of memory on slice syntax error. (#354) [Alex Solomatnikov] -**** Fix error on enum references to other packages, #339. [Alex Solomatnikov] +**** Fix error on enum references to other packages. (#339) [Alex Solomatnikov] -**** Fix DPI undeclared svBitVecVal compile error, #346. [Chandan Egbert] +**** Fix DPI undeclared svBitVecVal compile error. (#346) [Chandan Egbert] -**** Fix DPI bit vector compile errors, #347, #359. [Chandan Egbert] +**** Fix DPI bit vector compile errors. (#347) (#359) [Chandan Egbert] **** Fix CDCRSTLOGIC report showing endpoint flops without resets. -**** Fix compiler warnings on SPARC, #288. [Ahmed El-Mahmoudy] +**** Fix compiler warnings on SPARC. (#288) [Ahmed El-Mahmoudy] * Verilator 3.812 2011-04-06 -*** Add --trace-max-width and --trace-max-array, #319. [Alex Solomatnikov] +*** Add --trace-max-width and --trace-max-array. (#319) [Alex Solomatnikov] *** Add --Wno-fatal to turn off abort on warnings. [by Stefan Wallentowitz] -**** Support ${...} and $(...) env vars in .vc files. [by Stefan Wallentowitz] +**** Support ${...} and $(...) env vars in .vc files. [by Stefan Wallentowitz] -**** Support $bits(data_type), #327. [Alex Solomatnikov] +**** Support $bits(data_type). (#327) [Alex Solomatnikov] -**** Support loop unrolling on width mismatches, #333. [Joe Eiler] +**** Support loop unrolling on width mismatches. (#333) [Joe Eiler] -**** Support simple cast operators, #335. [Alex Solomatnikov] +**** Support simple cast operators. (#335) [Alex Solomatnikov] **** Accelerate bit-selected inversions. -**** Add error on circular parameter definitions, #329. [Alex Solomatnikov] +**** Add error on circular parameter definitions. (#329) [Alex Solomatnikov] -**** Fix concatenates and vectored bufif1, #326. [Iztok Jeras] +**** Fix concatenates and vectored bufif1. (#326) [Iztok Jeras] * Verilator 3.811 2011-02-14 -**** Report errors on duplicated or empty pins, #321. [Christian Leber] +**** Report errors on duplicated or empty pins. (#321) [Christian Leber] -**** Report error on function call output tied to constant. [Bernard Deadman] +**** Report error on function call output tied to constant. [Bernard Deadman] **** Throw UNUSED/UNDRIVEN only once per net in a parametrized module. -**** Fix internal error on functions called as SV tasks. [Bernard Deadman] +**** Fix internal error on functions called as SV tasks. [Bernard Deadman] -**** Fix internal error on non-inlined inout pins. [Jeff Winston] +**** Fix internal error on non-inlined inout pins. [Jeff Winston] -**** Fix false BLKSEQ on non-unrolled for loop indexes. [Jeff Winston] +**** Fix false BLKSEQ on non-unrolled for loop indexes. [Jeff Winston] -**** Fix block comment not separating identifiers, #311. [Gene Sullivan] +**** Fix block comment not separating identifiers. (#311) [Gene Sullivan] **** Fix warnings to point to lowest net usage, not upper level ports. -**** Fix error on constants connected to outputs, #323. [Christian Leber] +**** Fix error on constants connected to outputs. (#323) [Christian Leber] * Verilator 3.810 2011-01-03 ** Add limited support for VPI access to public signals, see docs. -*** Add -F option to read relative option files, #297. [Neil Hamilton] +*** Add -F option to read relative option files. (#297) [Neil Hamilton] -*** Support ++,--,+= etc as standalone statements. [Alex Solomatnikov] +*** Support ++,--,+= etc as standalone statements. [Alex Solomatnikov] **** When running with VERILATOR_ROOT, optionally find binaries under bin. @@ -1817,22 +1861,22 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 3.805 2010-11-02 -**** Add warning when directory contains spaces, #1705. [Salman Sheikh] +**** Add warning when directory contains spaces. (#1705) [Salman Sheikh] -**** Fix wrong filename on include file errors, #289. [Brad Parker] +**** Fix wrong filename on include file errors. (#289) [Brad Parker] -**** Fix segfault on SystemVerilog "output wire foo=0", #291. [Joshua Wise] +**** Fix segfault on SystemVerilog "output wire foo=0". (#291) [Joshua Wise] -**** Fix DPI export name not found, #1703. [Terry Chen] +**** Fix DPI export name not found. (#1703) [Terry Chen] * Verilator 3.804 2010-09-20 -*** Support tracing/coverage of underscore signals, #280. [by Jason McMullan] +*** Support tracing/coverage of underscore signals. (#280) [by Jason McMullan] -**** Fix preprocessor `` of existing base define, #283. [Usha Priyadharshini] +**** Fix preprocessor `` of existing base define. (#283) [Usha Priyadharshini] -**** Increase define recursions before error. [Paul Liu] +**** Increase define recursions before error. [Paul Liu] **** On core dump, print debug suggestions. @@ -1843,7 +1887,7 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix preprocessor stringification of nested macros. -**** Fix some constant parameter functions causing crash, #253. [Nick Bowler] +**** Fix some constant parameter functions causing crash. (#253) [Nick Bowler] **** Fix do {...} while() not requiring final semicolon. @@ -1854,42 +1898,42 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Add /*verilator public_flat_rw*/ for timing-specific public access. -*** Fix word size to match uint64_t on -m64 systems, #238. [Joe Eiler] +*** Fix word size to match uint64_t on -m64 systems. (#238) [Joe Eiler] -**** Improve error handling on slices of arrays, #226. [by Byron Bradley] +**** Improve error handling on slices of arrays. (#226) [by Byron Bradley] **** Report errors when extra underscores used in meta-comments. -**** Fix bit reductions on multi-packed dimensions, #227. [by Byron Bradley] +**** Fix bit reductions on multi-packed dimensions. (#227) [by Byron Bradley] -**** Fix removing $fscanf if assigned to unused var, #248. [Ashutosh Das] +**** Fix removing $fscanf if assigned to unused var. (#248) [Ashutosh Das] -**** Fix "make install" with configure outside srcdir. [Stefan Wallentowitz] +**** Fix "make install" with configure outside srcdir. [Stefan Wallentowitz] -**** Fix loop unroller out of memory; change --unroll-stmts. [Ashutosh Das] +**** Fix loop unroller out of memory; change --unroll-stmts. [Ashutosh Das] **** Fix trace files with empty modules crashing some viewers. -**** Fix parsing single files > 2GB. [Jeffrey Short] +**** Fix parsing single files > 2GB. [Jeffrey Short] -**** Fix installing data files as non-executable, #168. [by Ahmed El-Mahmoudy] +**** Fix installing data files as non-executable. (#168) [by Ahmed El-Mahmoudy] * Verilator 3.801 2010-03-17 *** Support "break", "continue", "return". -*** Support "`default_nettype none|wire". [Dominic Plunkett] +*** Support "`default_nettype none|wire". [Dominic Plunkett] -**** Skip SystemC tests if not installed. [Iztok Jeras] +**** Skip SystemC tests if not installed. [Iztok Jeras] -**** Fix clock-gates with non-AND complex logic, #220. [Ashutosh Das] +**** Fix clock-gates with non-AND complex logic. (#220) [Ashutosh Das] -**** Fix flushing VCD buffers on $stop. [Ashutosh Das] +**** Fix flushing VCD buffers on $stop. [Ashutosh Das] -**** Fix Mac OS-X compile issues, #217. [Joshua Wise, Trevor Williams] +**** Fix Mac OS-X compile issues. (#217) [Joshua Wise, Trevor Williams] -**** Fix make uninstall, #216. [Iztok Jeras] +**** Fix make uninstall. (#216) [Iztok Jeras] **** Fix parametrized defines with empty arguments. @@ -1902,7 +1946,7 @@ Application visible changes: Applications must use VerilatedVcdC class in place of SpTraceVcdC. ** SystemVerilog 1800-2009 is now the default language. - Thus "global" etc are now keywords. See the --language option. + Thus "global" etc are now keywords. See the --language option. New features: @@ -1911,18 +1955,18 @@ New features: ** Support "program", "package", "import" and $unit. -** Support typedef and enum. [by Donal Casey] +** Support typedef and enum. [by Donal Casey] ** Support direct programming interface (DPI) "import" and "export". Includes an extension to map user $system PLI calls to the DPI. -*** Support assignments of multidimensional slices, #170. [by Byron Bradley] +*** Support assignments of multidimensional slices. (#170) [by Byron Bradley] -*** Support multidimensional inputs/outputs, #171. [by Byron Bradley] +*** Support multidimensional inputs/outputs. (#171) [by Byron Bradley] -*** Support "reg [1:0][1:0][1:0]" and "reg x [3][2]", #176. [Byron Bradley] +*** Support "reg [1:0][1:0][1:0]" and "reg x [3][2]". (#176) [Byron Bradley] -*** Support declarations in loop initializers, #172. [by Byron Bradley] +*** Support declarations in loop initializers. (#172) [by Byron Bradley] *** Support $test$plusargs and $value$plusargs, but see the docs! @@ -1943,9 +1987,9 @@ New features: *** Add VARHIDDEN warning when signal name hides module name. -**** Support optional cell parenthesis, #179. [by Byron Bradley] +**** Support optional cell parenthesis. (#179) [by Byron Bradley] -**** Support for loop i++, ++i, i--, --i, #175. [by Byron Bradley] +**** Support for loop i++, ++i, i--, --i. (#175) [by Byron Bradley] **** Support 1800-2009 /*comments*/ in define values. @@ -1957,21 +2001,21 @@ New features: Bug fixes: -**** Fix implicit variable issues, #196, #201. [Byron Bradley] +**** Fix implicit variable issues. (#196) (#201) [Byron Bradley] -**** Fix 'for' variable typing, #205. [by Byron Bradley] +**** Fix 'for' variable typing. (#205) [by Byron Bradley] -**** Fix tracing with --pins-bv 1, #195. [Michael S] +**** Fix tracing with --pins-bv 1. (#195) [Michael S] -**** Fix MSVC++ 2008 compile issues, #209. [Amir Gonnen] +**** Fix MSVC++ 2008 compile issues. (#209) [Amir Gonnen] -**** Fix MinGW compilation, #184, #214. [by Shankar Giri, Amir Gonnen] +**** Fix MinGW compilation. (#184) (#214) [by Shankar Giri, Amir Gonnen] -**** Fix Cygwin 1.7.x compiler error with uint32_t, #204. [Ivan Djordjevic] +**** Fix Cygwin 1.7.x compiler error with uint32_t. (#204) [Ivan Djordjevic] -**** Fix `define argument mis-replacing system task of same name, #191. +**** Fix `define argument mis-replacing system task of same name. (#191) -**** Fix Verilator core dump on wide integer divides, #178. [Byron Bradley] +**** Fix Verilator core dump on wide integer divides. (#178) [Byron Bradley] **** Fix lint_off/lint_on meta comments on same line as warning. @@ -1980,7 +2024,7 @@ Bug fixes: ** Support little endian bit vectors ("reg [0:2] x;"). -** Support division and modulus of > 64 bit vectors. [Gary Thomas] +** Support division and modulus of > 64 bit vectors. [Gary Thomas] *** Fix writing to out-of-bounds arrays writing element 0. @@ -1990,7 +2034,7 @@ Bug fixes: **** Fix cell port connection to unsized integer causing false width warning. -**** Fix erroring on strings with backslashed newlines, #168. [Pete Nixon] +**** Fix erroring on strings with backslashed newlines. (#168) [Pete Nixon] * Verilator 3.714 2009-09-18 @@ -2007,7 +2051,7 @@ Bug fixes: **** Fix preprocessing commas in deep parameterized macros. [Brad Dobbie] -**** Fix tracing escaped dotted identifiers, #107. +**** Fix tracing escaped dotted identifiers. (#107) **** Fix $display with uppercase %M. @@ -2018,35 +2062,35 @@ Bug fixes: ** Support constant function calls for parameters. [many!] -*** Support SystemVerilog "logic", #101. [by Alex Duller] +*** Support SystemVerilog "logic". (#101) [by Alex Duller] -*** Name SYMRSVDWORD error, and allow disabling it, #103. [Gary Thomas] +*** Name SYMRSVDWORD error, and allow disabling it. (#103) [Gary Thomas] -**** Fix escaped preprocessor identifiers, #106. [Nimrod Gileadi] +**** Fix escaped preprocessor identifiers. (#106) [Nimrod Gileadi] * Verilator 3.712 2009-07-14 ** Patching SystemC is no longer required to trace sc_bvs. -*** Support zero-width constants in concatenations. [Jeff Winston] +*** Support zero-width constants in concatenations. [Jeff Winston] *** Add verilator --pins-uint8 option to use sc_in. *** Add verilator -V option, to show verbose version. -*** On WIDTH warnings, show variable name causing error. [Jeff Winston] +*** On WIDTH warnings, show variable name causing error. [Jeff Winston] -**** Add BLKLOOPINIT error code, and describe --unroll-count. [Jeff Winston] +**** Add BLKLOOPINIT error code, and describe --unroll-count. [Jeff Winston] * Verilator 3.711 2009-06-23 **** Support decimal constants of arbitrary widths. [Mark Marshall] -**** Fix error on case statement with all duplicate items, #99. [Gary Thomas] +**** Fix error on case statement with all duplicate items. (#99) [Gary Thomas] -**** Fix segfault on unrolling for's with bad inits, #90. [Andreas Olofsson] +**** Fix segfault on unrolling for's with bad inits. (#90) [Andreas Olofsson] **** Fix tristates causing "Assigned pin is neither...". [by Lane Brooks] @@ -2062,48 +2106,48 @@ Bug fixes: **** The front end parser has been re-factored to enable more SV parsing. Code should parse the same, but minor parsing bugs may pop up. -**** Verilator_includer is no longer installed twice, #48. [Lane Brooks] +**** Verilator_includer is no longer installed twice. (#48) [Lane Brooks] -**** Fix escaped identifiers with '.' causing conflicts, #83. [J Baxter] +**** Fix escaped identifiers with '.' causing conflicts. (#83) [J Baxter] -**** Fix define formal arguments that contain newlines, #84. [David A] +**** Fix define formal arguments that contain newlines. (#84) [David A] * Verilator 3.703 2009-05-02 -*** Fix $clog2 calculation error with powers-of-2, #81. [Patricio Kaplan] +*** Fix $clog2 calculation error with powers-of-2. (#81) [Patricio Kaplan] -**** Fix error with tasks that have output first, #78. [Andrea Foletto] +**** Fix error with tasks that have output first. (#78) [Andrea Foletto] -**** Fix "cloning" error with -y/--top-module, #76. [Dimitris Nalbantis] +**** Fix "cloning" error with -y/--top-module. (#76) [Dimitris Nalbantis] -**** Fix segfault with error on bad --top-module, #79. [Dimitris Nalbantis] +**** Fix segfault with error on bad --top-module. (#79) [Dimitris Nalbantis] -**** Fix "redefining I" error with complex includes. [Duraid Madina] +**** Fix "redefining I" error with complex includes. [Duraid Madina] **** Fix GCC 4.3.2 compile warnings. * Verilator 3.702 2009-03-28 -*** Add --pins-bv option to use sc_bv for all ports. [Brian Small] +*** Add --pins-bv option to use sc_bv for all ports. [Brian Small] -*** Add SYSTEMPERL_INCLUDE envvar to assist RPM builds. [Chitlesh Goorah] +*** Add SYSTEMPERL_INCLUDE envvar to assist RPM builds. [Chitlesh Goorah] -**** Report errors when duplicate labels are used, #72. [Vasu Kandadi] +**** Report errors when duplicate labels are used. (#72) [Vasu Kandadi] -**** Fix the SC_MODULE name() to not include __PVT__. [Bob Fredieu] +**** Fix the SC_MODULE name() to not include __PVT__. [Bob Fredieu] * Verilator 3.701 2009-02-26 -** Support repeat and forever statements. [Jeremy Bennett] +** Support repeat and forever statements. [Jeremy Bennett] *** Add --debugi- option, for internal debugging. [Dennis Muhlestein] -**** Fix compile issues with GCC 4.3, #47. [Lane Brooks] +**** Fix compile issues with GCC 4.3. (#47) [Lane Brooks] -**** Fix VL_RANDom to better randomize bits. [Art Stamness] +**** Fix VL_RANDom to better randomize bits. [Art Stamness] **** Fix error messages to consistently go to stderr. [Jeremy Bennett] @@ -2112,9 +2156,9 @@ Bug fixes: * Verilator 3.700 2009-01-08 -** Add limited support for tristate inouts. Written by Lane Brooks, - under support by Ubixum Inc. This allows common pad ring and - tristate-mux structures to be Verilated. See the documentation for +** Add limited support for tristate inouts. Written by Lane Brooks, + under support by Ubixum Inc. This allows common pad ring and + tristate-mux structures to be Verilated. See the documentation for more information on supported constructs. ** Add --coverage_toggle for toggle coverage analysis. @@ -2124,7 +2168,7 @@ Bug fixes: *** Optimize two-level shift and and/or trees, +23% on one test. -*** Support posedge of bit-selected signals, #45. [Rodney Sinclair] +*** Support posedge of bit-selected signals. (#45) [Rodney Sinclair] *** Line coverage now aggregates by hierarchy automatically. Previously this would be done inside SystemPerl, which was slower. @@ -2137,15 +2181,15 @@ Bug fixes: **** Fix certain generate-if cells causing "clone" error. [Stephane Laurent] -**** Fix line coverage of public functions. [Soon Koh] +**** Fix line coverage of public functions. [Soon Koh] **** Fix SystemC 2.2 deprecated warnings about sensitive() and sc_start(). -**** Fix arrayed variables under function not compiling, #44. [Ralf Karge] +**** Fix arrayed variables under function not compiling. (#44) [Ralf Karge] **** Fix --output-split-cfuncs to also split trace code. [Niranjan Prabhu] -**** Fix 'bad select range' warning missing some cases, #43. [Lane Brooks] +**** Fix 'bad select range' warning missing some cases. (#43) [Lane Brooks] **** Fix internal signal names containing control characters (broke in 3.680). @@ -2153,7 +2197,7 @@ Bug fixes: **** Fix internal error on "output x; reg x = y;". -**** Fix wrong result for read of delayed FSM signal, #46. [Rodney Sinclair] +**** Fix wrong result for read of delayed FSM signal. (#46) [Rodney Sinclair] * Verilator 3.681 2008-11-12 @@ -2162,13 +2206,13 @@ Bug fixes: **** Include Verilog file's directory name in coverage reports. -**** Fix 'for' under 'generate-for' causing error, #38. [Rafael Shirakawa] +**** Fix 'for' under 'generate-for' causing error. (#38) [Rafael Shirakawa] -**** Fix coverage hierarchy being backwards with inlining. [Vasu Arasanipalai] +**** Fix coverage hierarchy being backwards with inlining. [Vasu Arasanipalai] -**** Fix GCC 4.3 compile error, #35. [Lane Brooks] +**** Fix GCC 4.3 compile error. (#35) [Lane Brooks] -**** Fix MSVC compile error, #42. [John Stroebel] +**** Fix MSVC compile error. (#42) [John Stroebel] * Verilator 3.680 2008-10-08 @@ -2181,11 +2225,11 @@ Bug fixes: **** Ignore SystemVerilog timeunit and timeprecision. -**** Expand environment variables in -f input files. [Lawrence Butcher] +**** Expand environment variables in -f input files. [Lawrence Butcher] -**** Report error if port declaration is missing, #32. [Guy-Armand Kamendje] +**** Report error if port declaration is missing. (#32) [Guy-Armand Kamendje] -**** Fix genvars causing link error when using --public. [Chris Candler] +**** Fix genvars causing link error when using --public. [Chris Candler] * Verilator 3.671 2008-09-19 @@ -2214,9 +2258,9 @@ Bug fixes: * Verilator 3.670 2008-07-23 ** Add --x-assign=fast option, and make it the default. - This chooses performance over reset debugging. See the manual. + This chooses performance over reset debugging. See the manual. -** Add --autoflush, for flushing streams after $display. [Steve Tong] +** Add --autoflush, for flushing streams after $display. [Steve Tong] ** Add CASEWITHX lint warning and if disabled fix handling of casez with Xs. @@ -2228,11 +2272,11 @@ Bug fixes: *** Add --Wfuture-, for improving forward compatibility. -**** Fix verilator_includer not being installed properly. [Holger Waechtler] +**** Fix verilator_includer not being installed properly. [Holger Waechtler] **** Fix IMPURE errors due to X-assignment temporary variables. [Steve Tong] -**** Fix "lvalue" errors with public functions, #25. [CY Wang] +**** Fix "lvalue" errors with public functions. (#25) [CY Wang] **** Add WIDTH warning to $fopen etc file descriptors. @@ -2241,17 +2285,17 @@ Bug fixes: * Verilator 3.665 2008-06-25 -**** Ignore "// verilator" comments alone on endif lines. [Rodney Sinclair] +**** Ignore "// verilator" comments alone on endif lines. [Rodney Sinclair] **** "Make install" now installs verilator_includer and verilator_profcfunc. **** Fix tracing missing changes on undriven public wires. [Rodney Sinclair] -**** Fix syntax error when "`include `defname" is ifdefed. [John Dickol] +**** Fix syntax error when "`include `defname" is ifdefed. [John Dickol] **** Fix error when macro call has commas in concatenate. [John Dickol] -**** Fix compile errors under Fedora 9, GCC 4.3.0. [by Jeremy Bennett] +**** Fix compile errors under Fedora 9, GCC 4.3.0. [by Jeremy Bennett] **** Fix Makefile to find headers/libraries under prefix. [by Holger Waechtler] @@ -2267,11 +2311,11 @@ Bug fixes: **** Fix compiler warnings under GCC 4.2.1. -**** Fix preprocessor `else after series of `elsif. [Mark Nodine] +**** Fix preprocessor `else after series of `elsif. [Mark Nodine] -**** Fix parametrized defines calling define with comma. [Joshua Wise] +**** Fix parametrized defines calling define with comma. [Joshua Wise] -**** Fix comma separated list of primitives. [by Bryan Brady] +**** Fix comma separated list of primitives. [by Bryan Brady] * Verilator 3.662 2008-04-25 @@ -2285,11 +2329,11 @@ Bug fixes: **** Support defines terminated in EOF, though against spec. [Stefan Thiede] -**** Support optional argument to $finish and $stop. [by Stefan Thiede] +**** Support optional argument to $finish and $stop. [by Stefan Thiede] **** Support ranges on gate primitive instantiations. [Stefan Thiede] -**** Ignore old standard(ish) Verilog-XL defines. [by Stefan Thiede] +**** Ignore old standard(ish) Verilog-XL defines. [by Stefan Thiede] **** Fix "always @ ((a) or (b))" syntax error. [by Niranjan Prabhu] @@ -2315,14 +2359,14 @@ Bug fixes: Previously they threw fatal errors, which in most cases is correct according to spec, but can be incorrect in presence of parameter values. -**** Support functions with "input integer". [Johan Wouters] +**** Support functions with "input integer". [Johan Wouters] -**** Ignore delays attached to gate UDPs. [Stefan Thiede] +**** Ignore delays attached to gate UDPs. [Stefan Thiede] **** Fix SystemVerilog parameterized defines with `` expansion, - and fix extra whitespace inserted on substitution. [Vladimir Matveyenko] + and fix extra whitespace inserted on substitution. [Vladimir Matveyenko] -**** Fix no-module include files on command line. [Stefan Thiede] +**** Fix no-module include files on command line. [Stefan Thiede] **** Fix dropping of backslash quoted-quote at end of $display. @@ -2336,39 +2380,39 @@ Bug fixes: * Verilator 3.660 2008-03-23 *** Add support for hard-coding VERILATOR_ROOT etc in the executables, - to enable easier use of Verilator RPMs. [Gunter Dannoritzer] + to enable easier use of Verilator RPMs. [Gunter Dannoritzer] -*** Allow multiple .v files on command line. [Stefan Thiede] +*** Allow multiple .v files on command line. [Stefan Thiede] -*** Convert re-defining macro error to warning. [Stefan Thiede] +*** Convert re-defining macro error to warning. [Stefan Thiede] -*** Add --error-limit option. [Stefan Thiede] +*** Add --error-limit option. [Stefan Thiede] -*** Allow __ in cell names by quoting them in C. [Stefan Thiede] +*** Allow __ in cell names by quoting them in C. [Stefan Thiede] -**** Fix genvar to be signed, so "< 0" works properly. [Niranjan Prabhu] +**** Fix genvar to be signed, so "< 0" works properly. [Niranjan Prabhu] -**** Fix assignments to inputs inside functions/tasks. [Patricio Kaplan] +**** Fix assignments to inputs inside functions/tasks. [Patricio Kaplan] -**** Fix definitions in main file.v, referenced in library. [Stefan Thiede] +**** Fix definitions in main file.v, referenced in library. [Stefan Thiede] **** Fix undefined assigns to be implicit warnings. [Stefan Thiede] * Verilator 3.658 2008-02-25 -**** Fix unistd compile error in 3.657. [Patricio Kaplan, Jonathan Kimmitt] +**** Fix unistd compile error in 3.657. [Patricio Kaplan, Jonathan Kimmitt] * Verilator 3.657 2008-02-20 -**** Fix assignments of {a,b,c} = {c,b,a}. [Jonathan Kimmitt] +**** Fix assignments of {a,b,c} = {c,b,a}. [Jonathan Kimmitt] -**** Fix Perl warning with --lint-only. [by Ding Xiaoliang] +**** Fix Perl warning with --lint-only. [by Ding Xiaoliang] -**** Avoid creating obj_dir with --lint-only. [Ding Xiaoliang] +**** Avoid creating obj_dir with --lint-only. [Ding Xiaoliang] -**** Fix parsing of always @(*). [Patricio Kaplan] +**** Fix parsing of always @(*). [Patricio Kaplan] * Verilator 3.656 2008-01-18 @@ -2376,7 +2420,7 @@ Bug fixes: **** Wide VL_CONST_W_#X functions are now made automatically. [Bernard Deadman] In such cases, a new {prefix}__Inlines.h file will be built and included. -**** Fixed sign error when extracting from signed memory. [Peter Debacker] +**** Fixed sign error when extracting from signed memory. [Peter Debacker] **** Fixed tracing of SystemC w/o SystemPerl. [Bernard Deadman, Johan Wouters] @@ -2403,87 +2447,87 @@ Bug fixes: **** Fixed parsing system functions with empty parens. [Oleg Rodionov] -* Verilator 3.653 2007/8/1 +* Verilator 3.653 2007-08-01 **** Support SystemVerilog ==? and !=? operators. **** Fixed SC_LIBS missing from generated makefiles. [Ding Xiaoliang] -* Verilator 3.652 2007/6/21 +* Verilator 3.652 2007-06-21 **** Report as many warning types as possible before exiting. -**** Support V2K portlists with "input a,b,...". [Mark Nodine] +**** Support V2K portlists with "input a,b,...". [Mark Nodine] **** Support V2K function/task argument lists. **** Optimize constant $display arguments. -**** Fixed Preprocessor dropping some `line directives. [Mark Nodine] +**** Fixed Preprocessor dropping some `line directives. [Mark Nodine] -* Verilator 3.651 2007/5/22 +* Verilator 3.651 2007-05-22 -*** Added verilator_profcfunc utility. [Gene Weber] +*** Added verilator_profcfunc utility. [Gene Weber] *** Treat modules within `celldefine and `endcelldefine as if in library. -*** Support functions which return integers. [Mark Nodine] +*** Support functions which return integers. [Mark Nodine] -**** Warn if flex is not installed. [Ralf Karge] +**** Warn if flex is not installed. [Ralf Karge] **** Ignore `protect and `endprotect. **** Allow empty case/endcase blocks. -* Verilator 3.650 2007/4/20 +* Verilator 3.650 2007-04-20 -** Add --compiler msvc option. This is now required when Verilated code - is to be run through MSVC++. This also enables fixing MSVC++ error - C1061, blocks nested too deeply. [Ralf Karge] +** Add --compiler msvc option. This is now required when Verilated code + is to be run through MSVC++. This also enables fixing MSVC++ error + C1061, blocks nested too deeply. [Ralf Karge] ** Add --lint-only option, to lint without creating other output. *** Add /*verilator lint_save*/ and /*verilator lint_restore*/ to allow - friendly control over re-enabling lint messages. [Gerald Williams] + friendly control over re-enabling lint messages. [Gerald Williams] *** Support SystemVerilog .name and .* interconnect. *** Support while and do-while loops. -*** Use $(LINK) instead of $(CXX) for Makefile link rules. [Gerald Williams] +*** Use $(LINK) instead of $(CXX) for Makefile link rules. [Gerald Williams] -*** Add USER_CPPFLAGS and USER_LDFLAGS to Makefiles. [Gerald Williams] +*** Add USER_CPPFLAGS and USER_LDFLAGS to Makefiles. [Gerald Williams] -**** Fixed compile errors under Windows MINGW compiler. [Gerald Williams] +**** Fixed compile errors under Windows MINGW compiler. [Gerald Williams] -**** Fixed dotted bit reference to local memory. [Eugene Weber] +**** Fixed dotted bit reference to local memory. [Eugene Weber] -**** Fixed 3.640 `verilog forcing IEEE 1364-1995 only. [David Hewson] +**** Fixed 3.640 `verilog forcing IEEE 1364-1995 only. [David Hewson] -* Verilator 3.640 2007/3/12 +* Verilator 3.640 2007-03-12 *** Support Verilog 2005 `begin_keywords and `end_keywords. *** Updated list of SystemVerilog keywords to correspond to IEEE 1800-2005. -*** Add /*verilator public_flat*/. [Eugene Weber] +*** Add /*verilator public_flat*/. [Eugene Weber] -**** Try all +libext's in the exact order given. [Michael Shinkarovsky] +**** Try all +libext's in the exact order given. [Michael Shinkarovsky] -**** Fixed elimination of public signals assigned to constants. [Eugene Weber] +**** Fixed elimination of public signals assigned to constants. [Eugene Weber] -**** Fixed internal error when public for loop has empty body. [David Addison] +**** Fixed internal error when public for loop has empty body. [David Addison] -**** Fixed "Loops detected" assertion when model exceeds 4GB. [David Hewson] +**** Fixed "Loops detected" assertion when model exceeds 4GB. [David Hewson] **** Fixed display %m names inside named blocks. -* Verilator 3.633 2007/2/7 +* Verilator 3.633 2007-02-07 *** Add --trace-depth option for minimizing VCD file size. [Emerson Suguimoto] @@ -2493,37 +2537,37 @@ Bug fixes: **** Fixed isolate_assignments across task/func temporaries. [Mike Shinkarovsky] -**** Fixed $display's with array select followed by wide AND. [David Hewson] +**** Fixed $display's with array select followed by wide AND. [David Hewson] -* Verilator 3.632 2007/1/17 +* Verilator 3.632 2007-01-17 -*** Add /*verilator isolate_assignments*/ attribute. [Mike Shinkarovsky] +*** Add /*verilator isolate_assignments*/ attribute. [Mike Shinkarovsky] -* Verilator 3.631 2007/1/2 +* Verilator 3.631 2007-01-02 ** Support standard NAME[#] for cells created by arraying or generate for. This replaces the non-standard name__# syntax used in earlier versions. -**** Fixed again dotted references into generate cells. [David Hewson] +**** Fixed again dotted references into generate cells. [David Hewson] Verilator no longer accepts duplicated variables inside unique generate blocks as this is illegal according to the specification. -**** Fixed $readmem* with filenames < 8 characters. [Emerson Suguimoto] +**** Fixed $readmem* with filenames < 8 characters. [Emerson Suguimoto] * Verilator 3.630 2006-12-19 -** Support $readmemb and $readmemh. [Eugene Weber, Arthur Kahlich] +** Support $readmemb and $readmemh. [Eugene Weber, Arthur Kahlich] -*** Fixed configure and compiling under Solaris. [Bob Farrell] +*** Fixed configure and compiling under Solaris. [Bob Farrell] *** When dotted signal lookup fails, help the user by showing known scopes. -*** Reduce depth of priority encoded case statements. [Eugene Weber] +*** Reduce depth of priority encoded case statements. [Eugene Weber] -**** Fixed dotted references inside generated cells. [David Hewson] +**** Fixed dotted references inside generated cells. [David Hewson] **** Fixed missed split optimization points underneath other re-split blocks. @@ -2534,12 +2578,12 @@ Bug fixes: **** Fixed $signed mis-extending when input has a WIDTH violation. [Eugene Weber] -**** Add M32 make variable to support -m32 compiles. [Eugene Weber] +**** Add M32 make variable to support -m32 compiles. [Eugene Weber] * Verilator 3.622 2006-10-17 Stable -**** Fixed --skip-identical without --debug, broken in 3.621. [Andy Meier] +**** Fixed --skip-identical without --debug, broken in 3.621. [Andy Meier] * Verilator 3.621 2006-10-11 Beta @@ -2550,18 +2594,18 @@ Bug fixes: **** Remove .vpp intermediate files when not under --debug. -**** Fixed link error when using --exe with --trace. [Eugene Weber] +**** Fixed link error when using --exe with --trace. [Eugene Weber] **** Fixed mis-optimization of wide concats with constants. -**** Fixed core dump on printing error when not under --debug. [Allan Cochrane] +**** Fixed core dump on printing error when not under --debug. [Allan Cochrane] * Verilator 3.620 2006-10-04 Stable -*** Support simple inout task ports. [Eugene Weber] +*** Support simple inout task ports. [Eugene Weber] -*** Allow overriding Perl, Flex and Bison versions. [by Robert Farrell] +*** Allow overriding Perl, Flex and Bison versions. [by Robert Farrell] *** Optimize variables set to constants within basic blocks for ~3%. @@ -2577,40 +2621,40 @@ Bug fixes: * Verilator 3.610 2006-09-20 Stable -*** Verilator now works under DJGPP (Pentium GCC). [John Stroebel] +*** Verilator now works under DJGPP (Pentium GCC). [John Stroebel] -**** Add default define for VL_PRINTF. [John Stroebel] +**** Add default define for VL_PRINTF. [John Stroebel] **** Removed coverage request variable; see Coverage limitations in docs. -**** Fixed DOS carriage returns in multiline defines. [Ralf Karge] +**** Fixed DOS carriage returns in multiline defines. [Ralf Karge] **** Fixed printf format warnings on 64-bit linux. * Verilator 3.602 2006-09-11 Stable -**** Fixed function references under top inlined module. [David Hewson] +**** Fixed function references under top inlined module. [David Hewson] * Verilator 3.601 2006-09-06 Beta *** Added --inhibit-sim flag for environments using old __Vm_inhibitSim. -*** Added `systemc_dtor for destructor extensions. [Allan Cochrane] +*** Added `systemc_dtor for destructor extensions. [Allan Cochrane] *** Added -MP to make phony dependencies, ala GCC's. *** Changed how internal functions are invoked to reduce aliasing. Useful when using GCC's -O2 or -fstrict-aliasing, to gain another ~4%. -**** Fixed memory leak when destroying modules. [John Stroebel] +**** Fixed memory leak when destroying modules. [John Stroebel] -**** Fixed coredump when unused modules have unused cells. [David Hewson] +**** Fixed coredump when unused modules have unused cells. [David Hewson] -**** Fixed 3.600 internal error with arrayed instances. [David Hewson] +**** Fixed 3.600 internal error with arrayed instances. [David Hewson] -**** Fixed 3.600 internal error with non-unrolled function loops. [David Hewson] +**** Fixed 3.600 internal error with non-unrolled function loops. [David Hewson] **** Fixed $display %m name not matching Verilog name inside SystemC modules. @@ -2632,24 +2676,24 @@ Bug fixes: * Verilator 3.542 2006-08-11 Stable -**** Fixed extraneous UNSIGNED warning when comparing genvars. [David Hewson] +**** Fixed extraneous UNSIGNED warning when comparing genvars. [David Hewson] -**** Fixed extra white space in $display %c. [by David Addison] +**** Fixed extra white space in $display %c. [by David Addison] **** vl_finish and vl_fatal now print via VL_PRINTF rather then cerr/cout. -**** Add VL_CONST_W_24X macro. [Bernard Deadman] +**** Add VL_CONST_W_24X macro. [Bernard Deadman] * Verilator 3.541 2006-07-05 Beta -*** Fixed "// verilator lint_on" not re-enabling warnings. [David Hewson] +*** Fixed "// verilator lint_on" not re-enabling warnings. [David Hewson] -*** Fixed 3.540's multiple memory assignments to same block. [David Hewson] +*** Fixed 3.540's multiple memory assignments to same block. [David Hewson] -**** Add warning on changeDetect to arrayed structures. [David Hewson] +**** Add warning on changeDetect to arrayed structures. [David Hewson] -**** Fixed non-zero start number for arrayed instantiations. [Jae Hossell] +**** Fixed non-zero start number for arrayed instantiations. [Jae Hossell] **** Fixed GCC 4.0 header file warnings. @@ -2660,9 +2704,9 @@ Bug fixes: **** Optimize delayed assignments to memories inside loops, ~0-5% faster. -**** Fixed mis-width warning on bit selects of memories. [David Hewson] +**** Fixed mis-width warning on bit selects of memories. [David Hewson] -**** Fixed mis-width warning on dead generate-if branches. [Jae Hossell] +**** Fixed mis-width warning on dead generate-if branches. [Jae Hossell] * Verilator 3.533 2006-06-05 Stable @@ -2671,9 +2715,9 @@ Bug fixes: **** Fixed delayed bit-selected arrayed assignments. [David Hewson] -**** Fixed execution path to Perl. [Shanshan Xu] +**** Fixed execution path to Perl. [Shanshan Xu] -**** Fixed Bison compile errors in verilog.y. [by Ben Jackson] +**** Fixed Bison compile errors in verilog.y. [by Ben Jackson] * Verilator 3.531 2006-05-10 Stable @@ -2687,13 +2731,13 @@ Bug fixes: * Verilator 3.530 2006-04-24 Stable -** $time is now 64 bits. The macro VL_TIME_I is now VL_TIME_Q, but calls +** $time is now 64 bits. The macro VL_TIME_I is now VL_TIME_Q, but calls the same sc_time_stamp() function to get the current time. * Verilator 3.523 2006-03-06 Stable -**** Fixed error line numbers being off due to multi-line defines. [Mat Zeno] +**** Fixed error line numbers being off due to multi-line defines. [Mat Zeno] **** Fixed GCC sign extending (uint64_t)(a>>, $signed, $unsigned. [MANY!] +** Support signed numbers, >>>, $signed, $unsigned. [MANY!] -** Support multi-dimensional arrays. [Eugen Fekete] +** Support multi-dimensional arrays. [Eugen Fekete] ** Add very limited support for the Property Specification Language - (aka PSL or Sugar). The format and keywords are now very limited, but will - grow with future releases. The --assert switch enables this feature. + (aka PSL or Sugar). The format and keywords are now very limited, but will + grow with future releases. The --assert switch enables this feature. ** With --assert, generate assertions for synthesis parallel_case and full_case. -**** Fixed generate if's with empty if/else blocks. [Mat Zeno] +**** Fixed generate if's with empty if/else blocks. [Mat Zeno] -**** Fixed generate for cell instantiations with same name. [Mat Zeno] +**** Fixed generate for cell instantiations with same name. [Mat Zeno] * Verilator 3.481 2005-10-12 Stable @@ -2776,7 +2820,7 @@ Bug fixes: **** Fixed split optimization reordering $display statements. -* Verilator 3.480 2005/9/27 Beta +* Verilator 3.480 2005-09-27 Beta ** Allow coverage of flattened modules, and multiple points per line. Coverage analysis requires SystemPerl 1.230 or newer. @@ -2787,12 +2831,12 @@ Bug fixes: **** Optimize away duplicate lookup tables. -**** Optimize wide concatenates into individual words. [Ralf Karge] +**** Optimize wide concatenates into individual words. [Ralf Karge] **** Optimize local variables from delayed array assignments. -* Verilator 3.470 2005/9/6 Stable +* Verilator 3.470 2005-09-06 Stable *** Optimize staging flops under reset blocks. @@ -2805,7 +2849,7 @@ Bug fixes: **** Fixed preprocessor substitution of quoted parameterized defines. -* Verilator 3.464 2005/8/24 Stable +* Verilator 3.464 2005-08-24 Stable *** Add `systemc_imp_header, for use when using --output-split. @@ -2814,30 +2858,30 @@ Bug fixes: **** Fixed core dump with clock inversion optimizations. -* Verilator 3.463 2005/8/5 Stable +* Verilator 3.463 2005-08-05 Stable *** Fixed case defaults when not last statement in case list. [Wim Michiels] -* Verilator 3.462 2005/8/3 Stable +* Verilator 3.462 2005-08-03 Stable *** Fixed reordering of delayed assignments to same memory index. [Wim Michiels] -**** Fixed compile error with Flex 2.5.1. [Jens Arm] +**** Fixed compile error with Flex 2.5.1. [Jens Arm] **** Fixed multiply-instantiated public tasks generating non-compilable code. -* Verilator 3.461 2005/7/28 Beta +* Verilator 3.461 2005-07-28 Beta -**** Fixed compile error with older versions of bison. [Jeff Dutton] +**** Fixed compile error with older versions of bison. [Jeff Dutton] -* Verilator 3.460 2005/7/27 Beta +* Verilator 3.460 2005-07-27 Beta ** Add -output-split option to enable faster parallel GCC compiles. To support --output-split, the makefiles now split VM_CLASSES - into VM_CLASSES_FAST and VM_CLASSES_SLOW. This may require a + into VM_CLASSES_FAST and VM_CLASSES_SLOW. This may require a change to local makefiles. ** Support -v argument to read library files. @@ -2846,22 +2890,22 @@ Bug fixes: **** Fixed false warning when a clock is constant. -**** Fixed X/Z in decimal numbers. [Wim Michiels] +**** Fixed X/Z in decimal numbers. [Wim Michiels] **** Fixed genvar statements in non-named generate blocks. -**** Fixed core dump when missing newline in `define. [David van der bokke] +**** Fixed core dump when missing newline in `define. [David van der bokke] **** Internal tree dumps now indicate edit number that changed the node. -* Verilator 3.450 2005/7/12 +* Verilator 3.450 2005-07-12 ** $finish will no longer exit, but set Verilated::gotFinish(). This enables support for final statements, and for other cleanup code. - If this is undesired, redefine the vl_user_finish routine. Top level + If this is undesired, redefine the vl_user_finish routine. Top level loops should use Verilated::gotFinish() as a exit condition for their - loop, and then call top->final(). To prevent a infinite loop, a + loop, and then call top->final(). To prevent a infinite loop, a double $finish will still exit; this may be removed in future releases. @@ -2871,38 +2915,38 @@ Bug fixes: **** Fixed "=== 1'bx" to always be false, instead of random. -* Verilator 3.440 2005/6/28 Stable +* Verilator 3.440 2005-06-28 Stable ** Add Verilog 2001 generate for/if/case statements. -* Verilator 3.431 2005/6/24 Stable +* Verilator 3.431 2005-06-24 Stable *** Fixed selection bugs introduced in 3.430 beta. -* Verilator 3.430 2005/6/22 Beta +* Verilator 3.430 2005-06-22 Beta -** Add Verilog 2001 variable part selects [n+:m] and [n-:m]. [Wim Michiels] +** Add Verilog 2001 variable part selects [n+:m] and [n-:m]. [Wim Michiels] -* Verilator 3.422 2005/6/10 Stable +* Verilator 3.422 2005-06-10 Stable -*** Added Verilog 2001 power (**) operator. [Danny Ding] +*** Added Verilog 2001 power (**) operator. [Danny Ding] -**** Fixed crash and added error message when assigning to inputs. [Ralf Karge] +**** Fixed crash and added error message when assigning to inputs. [Ralf Karge] **** Fixed tracing of modules with public functions. -* Verilator 3.421 2005/6/2 Beta +* Verilator 3.421 2005-06-02 Beta **** Fixed error about reserved word on non-public signals. **** Fixed missing initialization compile errors in 3.420 beta. [Ralf Karge] -* Verilator 3.420 2005/6/2 Beta +* Verilator 3.420 2005-06-02 Beta *** Fixed case defaults when not last statement in case list. [Ralf Karge] @@ -2921,12 +2965,12 @@ Bug fixes: **** Fixed gate optimization with top-flattened modules. [Mahesh Kumashikar] -* Verilator 3.411 2005/5/30 Stable +* Verilator 3.411 2005-05-30 Stable -**** Fixed compile error in GCC 2.96. [Jeff Dutton] +**** Fixed compile error in GCC 2.96. [Jeff Dutton] -* Verilator 3.410 2005/5/25 Beta +* Verilator 3.410 2005-05-25 Beta ** Allow functions and tasks to be declared public. They will become public C++ functions, with appropriate C++ types. @@ -2934,21 +2978,21 @@ Bug fixes: of having to use public variables and `systemc_header hacks. *** Skip producing output files if all inputs are identical - This uses timestamps, similar to make. Disable with --no-skip-identical. + This uses timestamps, similar to make. Disable with --no-skip-identical. **** Improved compile performance with large case statements. -**** Fixed internal error in V3Table. [Jeff Dutton] +**** Fixed internal error in V3Table. [Jeff Dutton] -**** Fixed compile error in GCC 2.96, and with SystemC 1.2. [Jeff Dutton] +**** Fixed compile error in GCC 2.96, and with SystemC 1.2. [Jeff Dutton] -* Verilator 3.400 2005/4/29 Beta +* Verilator 3.400 2005-04-29 Beta ** Internal changes to support future clocking features. ** Verilog-Perl and SystemPerl are no longer required for C++ or SystemC - output. If you want tracing or coverage analysis, they are still needed. + output. If you want tracing or coverage analysis, they are still needed. *** Added --sc to create pure SystemC output not requiring SystemPerl. @@ -2958,24 +3002,24 @@ Bug fixes: This was previously the case any time .cpp files were passed on the command line. -*** Added -O3 and --inline-mult for performance tuning. [Ralf Karge] +*** Added -O3 and --inline-mult for performance tuning. [Ralf Karge] One experiment regained 5% performance, at a cost of 300% in compile time. *** Improved performance of large case/always statements with low fanin by converting to internal lookup tables (ROMs). -*** Initialize SystemC port names. [S Shuba] +*** Initialize SystemC port names. [S Shuba] **** Added Doxygen comments to Verilated includes. **** Fixed -cc pins 8 bits wide and less to be uint8_t instead of uint16_t. -**** Fixed crash when Mdir has same name as .v file. [Gernot Koch] +**** Fixed crash when Mdir has same name as .v file. [Gernot Koch] -**** Fixed crash with size mismatches on case items. [Gernot Koch] +**** Fixed crash with size mismatches on case items. [Gernot Koch] -* Verilator 3.340 2005/2/18 Stable +* Verilator 3.340 2005-02-18 Stable *** Report misconnected pins across all modules, instead of just first error. @@ -2986,7 +3030,7 @@ Bug fixes: **** Added additional internal assertions. -* Verilator 3.332 2005/1/27 +* Verilator 3.332 2005-01-27 *** Added -E preprocess only flag, similar to GCC. @@ -2995,7 +3039,7 @@ Bug fixes: **** Fixed loss of first -f file argument, introduced in 3.331. -* Verilator 3.331 2005/1/18 +* Verilator 3.331 2005-01-18 ** The Verilog::Perl preprocessor is now C++ code inside of Verilator. This improves performance, makes compilation easier, and enables @@ -3003,7 +3047,7 @@ Bug fixes: *** Support arrays of instantiations (non-primitives only). [Wim Michiels] -**** Fixed unlinked error with defparam. [Shawn Wang] +**** Fixed unlinked error with defparam. [Shawn Wang] * Verilator 3.320 2004-12-10 @@ -3013,9 +3057,9 @@ Bug fixes: *** If Verilator is passed a C file, create a makefile link rule. This saves several user steps when compiling small projects. -*** Added new COMBDLY warning in place of fatal error. [Shawn Wang] +*** Added new COMBDLY warning in place of fatal error. [Shawn Wang] -*** Fixed mis-simulation with wide-arrays under bit selects. [Ralf Karge] +*** Fixed mis-simulation with wide-arrays under bit selects. [Ralf Karge] **** Added NC Verilog as alternative to VCS for reference tests. @@ -3027,9 +3071,9 @@ Bug fixes: * Verilator 3.311 2004-11-29 -** Support implicit wire declarations (as a warning). [Shawn Wang] +** Support implicit wire declarations (as a warning). [Shawn Wang] -**** Fixed over-shift difference in Verilog vs C++. [Ralf Karge] +**** Fixed over-shift difference in Verilog vs C++. [Ralf Karge] * Verilator 3.310 2004-11-15 @@ -3059,9 +3103,9 @@ Bug fixes: * Verilator 3.301 2004-11-04 -**** Fixed 64 bit [31:0] = {#{}} mis-simulation. [Ralf Karge] +**** Fixed 64 bit [31:0] = {#{}} mis-simulation. [Ralf Karge] -**** Fixed shifts greater then word width mis-simulation. [Ralf Karge] +**** Fixed shifts greater then word width mis-simulation. [Ralf Karge] **** Work around GCC 2.96 negation bug. @@ -3091,7 +3135,7 @@ Bug fixes: **** Faster code to support compilers not inlining all Verilated functions. -* Verilator 3.260 2004-10-7 +* Verilator 3.260 2004-10-07 ** Support Verilog 2001 named parameter instantiation. [Ralf Karge] @@ -3102,32 +3146,32 @@ Bug fixes: **** Fixed incorrect dependency in .d file when setting VERILATOR_BIN. -* Verilator 3.251 2004/9/9 +* Verilator 3.251 2004-09-09 **** Fixed parenthesis overflow in Microsoft Visual C++ [Renga Sundararajan] -* Verilator 3.250 2004/8/30 +* Verilator 3.250 2004-08-30 ** Support Microsoft Visual C++ [Renga Sundararajan] *** SystemPerl 1.161+ is required. -* Verilator 3.241 2004/8/17 +* Verilator 3.241 2004-08-17 ** Support ,'s to separate multiple assignments. [Paul Nitza] **** Fixed shift sign extension problem using non-GCC compilers. -* Verilator 3.240 2004/8/13 +* Verilator 3.240 2004-08-13 ** Verilator now uses 64 bit math where appropriate. Inputs and outputs of 33-64 bits wide to the C++ Verilated model must now be uint64_t's; SystemC has not changed, they will remain sc_bv's. This increases performance by ~ 9% on x86 machines, varying with how - frequently 33-64 bit signals occur. Signals 9-16 bits wide are now + frequently 33-64 bit signals occur. Signals 9-16 bits wide are now stored as 16 bit shorts instead of longs, this aids cache packing. **** Fixed SystemC compile error with feedthrus. [Paul Nitza] @@ -3135,7 +3179,7 @@ Bug fixes: **** Fixed concat value error introduced in 3.230. -* Verilator 3.230 2004/8/10 +* Verilator 3.230 2004-08-10 *** Added coverage output to test_sp example, SystemPerl 1.160+ is required. @@ -3149,7 +3193,7 @@ Bug fixes: Only applies when width mismatch warnings were overridden. -* Verilator 3.220 2004/6/22 +* Verilator 3.220 2004-06-22 ** Many waveform tracing changes: @@ -3159,12 +3203,12 @@ Bug fixes: *** When tracing, Verilator must be called with the --trace switch. -**** Added SystemPerl example to documentation. [John Brownlee] +**** Added SystemPerl example to documentation. [John Brownlee] -**** Various Cygwin compilation fixes. [John Brownlee] +**** Various Cygwin compilation fixes. [John Brownlee] -* Verilator 3.210 2004/4/1 +* Verilator 3.210 2004-04-01 ** Compiler optimization switches have changed See the BENCHMARKING section of the documentation. @@ -3177,18 +3221,18 @@ Bug fixes: *** Added warnings for SystemVerilog reserved words. -* Verilator 3.203 2004/3/10 +* Verilator 3.203 2004-03-10 *** Notes and repairs for Solaris. [Fred Ma] -* Verilator 3.202 2004/1/27 +* Verilator 3.202 2004-01-27 -** The beta version is now the primary release. See below for many changes. +** The beta version is now the primary release. See below for many changes. If you have many problems, you may wish to try release 3.125. *** Verilated::traceEverOn(true) must be called at time 0 if you will ever - turn on tracing (waveform dumping) of signals. Future versions will + turn on tracing (waveform dumping) of signals. Future versions will need this switch to disable trace incompatible optimizations. **** Fixed several tracing bugs @@ -3202,8 +3246,8 @@ Bug fixes: ** Version 3.2XX includes a all new back-end. This includes automatic inlining, flattening of signals between - hierarchy, and complete ordering of statements. This results in - 60-300% execution speedups, though less pretty C++ output. Even + hierarchy, and complete ordering of statements. This results in + 60-300% execution speedups, though less pretty C++ output. Even better results are possible using GCC 3.2.2 (part of Redhat 9.1), as GCC has fixed some optimization problems which Verilator exposes. @@ -3217,7 +3261,7 @@ Bug fixes: distinguish between multiple Verilated modules in a single executable. -* Verilator 3.125 2004/1/27 +* Verilator 3.125 2004-01-27 **** Optimization of bit replications @@ -3225,7 +3269,7 @@ Bug fixes: * Verilator 3.124 2003-12-05 *** A optimized executable will be made by default, in addition to a debug - executable. Invoking Verilator with --debug will pick the debug version. + executable. Invoking Verilator with --debug will pick the debug version. **** Many minor invisible changes to support the next version. @@ -3270,7 +3314,7 @@ Bug fixes: *** Support V2K "integer int = {INITIAL_VALUE};" -*** Ignore floating point delay values. [Robert A. Clark] +*** Ignore floating point delay values. [Robert A. Clark] **** Ignore `celldefine, `endcelldefine, etc. [Robert A. Clark] @@ -3312,7 +3356,7 @@ Bug fixes: ** Added support for functions. *** Signals 8 bits and shorter are now stored as chars - instead of uint32_t's. This improves Dcache packing and + instead of uint32_t's. This improves Dcache packing and improves performance by ~7%. **** $display now usually results in a single VL_PRINT rather then many. @@ -3331,7 +3375,7 @@ Bug fixes: *** Added detection of incomplete case statements, and added related optimizations worth ~4%. -**** Work around flex bug in Redhat 8.0. [Eugene Weber] +**** Work around flex bug in Redhat 8.0. [Eugene Weber] **** Added some additional C++ reserved words. @@ -3345,7 +3389,7 @@ Bug fixes: This makes it easier to pass the values of signals. ** Several changes to support future versions that may have - signal-eliminating optimizations. Users should try to use these switch + signal-eliminating optimizations. Users should try to use these switch on designs, they will become the default in later versions. *** Added --private switch and /*verilator public*/ metacomment. @@ -3354,9 +3398,9 @@ Bug fixes: metacomment. *** With --l2name, the second level cell C++ cell is now named "v". - Previously it was named based on the name of the verilog code. This + Previously it was named based on the name of the verilog code. This means to get to signals, scope to "{topcell} ->v ->{mysignal}" instead - of "{topcell} ->{verilogmod}. {mysignal}". This allows different + of "{topcell} ->{verilogmod}. {mysignal}". This allows different modules to be substituted for the cell without requiring source changes. @@ -3384,13 +3428,13 @@ Bug fixes: **** Promote subcell's combo logic to sequential evaluation when possible. -**** Fixed GCC 3.2 compile errors. [Narayan Bhagavatula] +**** Fixed GCC 3.2 compile errors. [Narayan Bhagavatula] * Verilator 3.103 2003-01-28 **** Fixed missing model evaluation when clock generated several levels of - hierarchy across from where it is used as a clock. [Richard Myers] + hierarchy across from where it is used as a clock. [Richard Myers] **** Fixed sign-extension bug introduced in 3.102. @@ -3409,7 +3453,7 @@ Bug fixes: * Verilator 3.100 2002-12-23 -** Support for simple tasks w/o vars or I/O. [Richard Myers] +** Support for simple tasks w/o vars or I/O. [Richard Myers] **** Ignore DOS carriage returns in Linux files. [Richard Myers] @@ -3423,27 +3467,27 @@ Bug fixes: corrupt memory beyond the size of the array. [Dan Lussier] **** Fixed bug which did not detect UNOPT problems caused by - submodules. See the description in the verilator man page. [John Deroo] + submodules. See the description in the verilator man page. [John Deroo] -**** Fixed compile with threaded Perl. [Ami Keren] +**** Fixed compile with threaded Perl. [Ami Keren] -* Verilator 3.010 2002-11-3 +* Verilator 3.010 2002-11-03 -*** Support SystemC 2.0.1. SystemPerl version 1.130 or newer is required. +*** Support SystemC 2.0.1. SystemPerl version 1.130 or newer is required. -**** Fixed bug with inlined modules under other inlined modules. [Scott +**** Fixed bug with inlined modules under other inlined modules. [Scott Bleiweiss] -* Verilator 3.005 2002-10-21 +* Verilator 3.005 2002-10-21 **** Fixed X's in case (not casex/z) to constant propagate correctly. **** Fixed missing include. [Kurachi] -* Verilator 3.004 2002-10-10 +* Verilator 3.004 2002-10-10 *** Added /* verilator module_inline */ and associated optimizations. @@ -3459,7 +3503,7 @@ Bug fixes: **** Additional concatenation optimizations. -* Verilator 3.003 2002-09-13 +* Verilator 3.003 2002-09-13 *** Now compiles on Windows 2000 with Cygwin. @@ -3468,14 +3512,14 @@ Bug fixes: **** Optimize wire assignments to constants. -* Verilator 3.002 2002-08-19 +* Verilator 3.002 2002-08-19 ** First public release of version 3. -* Verilator 3.000 2002-08-03 +* Verilator 3.000 2002-08-03 -** All new code base. Many changes too numerous to mention. +** All new code base. Many changes too numerous to mention. *** Approximately 4 times faster then Verilator 2. *** Supports initial statements @@ -3501,11 +3545,11 @@ Bug fixes: **** Split evaluation function into clocked and non-clocked, 20% perf gain. -* Verilator 2.1.5 2001-12-1 +* Verilator 2.1.5 2001-12-01 -** Added coverage analysis. In conjunction with SystemC provide line +** Added coverage analysis. In conjunction with SystemC provide line coverage reports, without SystemC, provide a hook to user written - accumulation function. See --coverage option of verilator_make. + accumulation function. See --coverage option of verilator_make. *** Relaxed multiply range checking @@ -3536,7 +3580,7 @@ Bug fixes: *** Support strings in assignments: reg [31:0] foo = "STRG"; -*** Support %m in format strings. Ripped out old $info support, use +*** Support %m in format strings. Ripped out old $info support, use Verilog-Perl's vpm program instead. *** Convert $stop to call of v_stop() which user can define. @@ -3549,14 +3593,14 @@ Bug fixes: * Verilator 2.1.1 2001-05-17 ** New test_sp directory for System-Perl (SystemC) top level instantiation -of the Verilated code, lower modules are still C++ code. (Experimental). +of the Verilated code, lower modules are still C++ code. (Experimental). ** New test_spp directory for Pure System-Perl (SystemC) where every module -is true SystemC code. (Experimental) +is true SystemC code. (Experimental) *** Input ports are now loaded by pointer reference into the sub-cell. This is faster on I-386 machines, as the stack must be used when there are -a large number of parameters. Also, this simplifies debugging as the value +a large number of parameters. Also, this simplifies debugging as the value of input ports exists for tracing. **** Many code cleanups towards standard C++ style conventions. @@ -3611,7 +3655,7 @@ of input ports exists for tracing. ---------------------------------------------------------------------- -This uses outline mode in Emacs. See C-h m [M-x describe-mode]. +This uses outline mode in Emacs. See C-h m [M-x describe-mode]. Copyright 2001-2020 by Wilson Snyder. This program is free software; you can redistribute it and/or modify it under the terms of either the GNU diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP index 97f2a9fa3..1ddb7c5eb 100644 --- a/MANIFEST.SKIP +++ b/MANIFEST.SKIP @@ -45,6 +45,7 @@ src/Makefile$ src/Makefile_obj$ include/verilated.mk$ test_regress/.gdbinit$ +codecov.yml config.cache$ config.status$ verilator\.log diff --git a/README.adoc b/README.adoc index 45f2c7409..a77349e97 100644 --- a/README.adoc +++ b/README.adoc @@ -5,6 +5,7 @@ ifdef::env-github[] image:https://img.shields.io/badge/License-LGPL%20v3-blue.svg[license LGPLv3,link=https://www.gnu.org/licenses/lgpl-3.0] image:https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg[license Artistic-2.0,link=https://opensource.org/licenses/Artistic-2.0] image:https://api.codacy.com/project/badge/Grade/fa78caa433c84a4ab9049c43e9debc6f[Code Quality,link=https://www.codacy.com/gh/verilator/verilator] +image:https://codecov.io/gh/verilator/verilator/branch/master/graph/badge.svg[Coverage,link=https://codecov.io/gh/verilator/verilator] image:https://travis-ci.com/verilator/verilator.svg?branch=master[Build Status (Travis CI),link=https://travis-ci.com/verilator/verilator] endif::[] @@ -20,9 +21,9 @@ endif::[] == Welcome to Verilator -[cols="a,a",indent=0,frame="none"] +[cols="a,a",indent=0,frame="none",grid="rows"] |=== -^.^| *Welcome to Verilator, the fastest Verilog HDL simulator.* +^.^| *Welcome to Verilator, the fastest Verilog/SystemVerilog simulator.* +++
+++ • Accepts synthesizable Verilog or SystemVerilog +++
+++ • Performs lint code-quality checks +++
+++ • Compiles into multithreaded {cpp}, or SystemC @@ -73,15 +74,15 @@ replacement for NC-Verilog, VCS or another commercial Verilog simulator, or if you are looking for a behavioral Verilog simulator e.g. for a quick class project (we recommend http://iverilog.icarus.com[Icarus Verilog] for this.) However, if you are looking for a path to migrate SystemVerilog to -{cpp} or SystemC, and your team is comfortable writing just a -touch of {cpp} code, Verilator is the tool for you. +{cpp} or SystemC, or your team is comfortable writing just a touch of {cpp} +code, Verilator is the tool for you. == Performance Verilator does not simply convert Verilog HDL to {cpp} or SystemC. Rather, Verilator compiles your code into a much faster optimized and optionally thread-partitioned model, which is in turn wrapped inside a -{cpp}/SystemC/{cpp}-under-Python module. The results are a compiled +{cpp}/SystemC module. The results are a compiled Verilog model that executes even on a single-thread over 10x faster than standalone SystemC, and on a single thread is about 100 times faster than interpreted Verilog simulators such as http://iverilog.icarus.com[Icarus @@ -112,9 +113,11 @@ For more information: * https://verilator.org/verilator_doc.html[Verilator manual (HTML)], or https://verilator.org/verilator_doc.pdf[Verilator manual (PDF)] +* https://github.com/verilator/verilator-announce[Subscribe to verilator announcements] + * https://verilator.org/forum[Verilator forum] -* https://verilator.org/issues[Verilator Issues] +* https://verilator.org/issues[Verilator issues] == Support diff --git a/bin/verilator b/bin/verilator index 2d3c6c538..b8d345107 100755 --- a/bin/verilator +++ b/bin/verilator @@ -300,6 +300,7 @@ detailed descriptions in L for more information. --dump-tree Enable dumping .tree files --dump-treei Enable dumping .tree files at a level --dump-treei- Enable dumping .tree file at a source file at a level + --dump-tree-addrids Use short identifiers instead of addresses -E Preprocess, but do not compile --error-limit Abort after this number of errors --exe Link to create executable @@ -399,6 +400,7 @@ detailed descriptions in L for more information. +verilog2001ext+ Synonym for +1364-2001ext+ --version Displays program version and exits --vpi Enable VPI compiles + --waiver-output Create a waiver file based on the linter warnings -Wall Enable all style warnings -Werror- Convert warnings to errors -Wfuture- Disable unknown message warnings @@ -811,6 +813,14 @@ file to the specified tree dumping level (e.g. C<--dump-treei-V3Order 9>). Level 0 disbles dumps and is equivalent to "--no-dump-tree". Level 9 enables dumping of every stage. +=item --dump-tree-addrids + +Rarely needed - for developer use. Replace AST node addresses with short +identifiers in tree dumps to enhance readability. Each unique pointer value +is mapped to a unique identifier, but note that this is not necessarily +unique per node instance as an address might get reused by a newly allocated +node after a node with the same address has been dumped then freed. + =item -E Preprocess the source code, but do not compile, as with 'gcc -E'. Output @@ -881,7 +891,10 @@ octal (0..) or binary (0b..) notation. =item Double literals -Double literals must contain a dot (.) and/or an exponent (e). +Double literals must be one of the following styles: + - contains a dot (.) (e.g. 1.23) + - contains an expornent (e/E) (e.g. 12e3) + - contains p/P for hexadecimal floating point in C99 (e.g. 0x123.ABCp1) =item Strings @@ -1119,17 +1132,15 @@ developers. Enables splitting the output .cpp files into multiple outputs. When a C++ file exceeds the specified number of operations, a new file will be created -at the next function boundary. In addition, any infrequently executed -"cold" routines will be placed into __Slow files. This accelerates -compilation by as optimization can be disabled on the routines in __Slow, -and the remaining files can be compiled on parallel machines. Using ---output-split should have only a trivial impact on performance. On one -design --output-split 20000 resulted in splitting into approximately -one-minute-compile chunks. +at the next function boundary. In addition, if the total output code size +exceeds the specified value, VM_PARALLEL_BUILDS will be set to 1 by default +in the generated make files, making parallel compilation possible. Using +--output-split should have only a trivial impact on model performance. But +can greatly improve C++ compilation speed. The use of I (set for you +if present at configure time) is also more effective with this option. -Typically when using this, make with VM_PARALLEL_BUILDS=1 (set for you if -using the default makefiles), and use I (set for you if present at -configure time). +This option is on by default with a value of 20000. To disable, pass with a +value of 0. =item --output-split-cfuncs I @@ -1141,10 +1152,14 @@ worse with decreasing split values. Note that this option is stronger than --output-split in the sense that --output-split will not split inside a function. +Defaults to the value of --output-split, unless explicitly specified. + =item --output-split-ctrace I -Enables splitting trace functions in the output .cpp files into -multiple functions. Defaults to same setting as --output-split-cfuncs. +Similar to --output-split-cfuncs, enables splitting trace functions in the +output .cpp files into multiple functions. + +Defaults to the value of --output-split, unless explicitly specified. =item -P @@ -1451,7 +1466,7 @@ good value. Sets default timescale, timeunit and timeprecision for when `timescale does not occur in sources. Default is "1ps/1ps" (to match SystemC). This is -overriden by C<--timescale-override>. +overridden by C<--timescale-override>. =item --timescale-override I/I @@ -1539,7 +1554,7 @@ larger trace files. =item --trace-threads I Enable waveform tracing using separate threads. This is typically faster in -simulation runtime but uses more total compute. This option is independend of, +simulation runtime but uses more total compute. This option is independent of, and works with, both C<--trace> and C<--trace-fst>. Different trace formats can take advantage of more trace threads to varying degrees. Currently VCD tracing can utilize at most --trace-threads 1, and FST tracing can utilize at most @@ -1601,6 +1616,17 @@ Displays program version and exits. Enable use of VPI and linking against the verilated_vpi.cpp files. +=item --waiver-output + +Generate a waiver file which contains all waiver statements to suppress the +warnings emitted during this Verilator run. This is in particular useful as +a starting point for solving linter warnings or suppressing them +systematically. + +The generated file is in the Verilator Configuration format, see +L, and can directly be consumed by Verilator. The +standard file extension is .vlt. + =item -Wall Enable all code style warnings, including code style warnings that are @@ -2001,7 +2027,7 @@ depending on the operating system. # Might be needed if SystemC 2.3.0 export SYSTEMC_CXX_FLAGS=-pthread - g++ -L$SYSTEMC_LIBDIR ../sc_main.o Vour__ALL*.o verilated.o \ + g++ -L$SYSTEMC_LIBDIR ../sc_main.o Vour__ALL.a verilated.o \ -o Vour -lsystemc And now we run it @@ -2054,11 +2080,11 @@ distribution. =head1 BENCHMARKING & OPTIMIZATION -For best performance, run Verilator with the "-O3 --x-assign fast ---x-initial fast --noassert" flags. The -O3 flag will require longer -compile times, and "--x-assign fast --x-initial fast" may increase the risk -of reset bugs in trade for performance; see the above documentation for -these flags. +For best performance, run Verilator with the "-O3 --x-assign fast --x-initial +fast --noassert" flags. The -O3 flag will require longer time to run +Verilator, and "--x-assign fast --x-initial fast" may increase the risk of +reset bugs in trade for performance; see the above documentation for these +flags. If using Verilated multithreaded, use C to ensure you are using non-conflicting hardware resources. See L. @@ -2070,49 +2096,69 @@ simple change to a clock latch used to gate clocks and gained a 60% performance improvement. Beyond that, the performance of a Verilated model depends mostly on your -C++ compiler and size of your CPU's caches. +C++ compiler and size of your CPU's caches. Experience shows that large models +are often limited by the size of the instruction cache, and as such reducing +code size if possible can be beneficial. -By default, the lib/verilated.mk file has optimization turned off. This is -for the benefit of new users, as it improves compile times at the cost of -simulation runtimes. To add optimization as the default, set one of three variables, -OPT, OPT_FAST, or OPT_SLOW lib/verilated.mk. Or, use the -CFLAGS and/or --LDFLAGS option on the verilator command line to pass the flags directly to -the compiler or linker. Or, just for one run, pass them on the command -line to make: +The supplied $VERILATOR_ROOT/include/verilated.mk file uses the OPT, OPT_FAST, +OPT_SLOW and OPT_GLOBAL variables to control optimization. You can set these +when compiling the output of Verilator with Make, for example: - make OPT_FAST="-Os -march=native -fno-stack-protector" -f Vour.mk Vour__ALL.a + make OPT_FAST="-Os -march=native" -f Vour.mk Vour__ALL.a -OPT_FAST specifies optimizations for those programs that are part of the -fast path, mostly code that is executed every cycle. OPT_SLOW specifies -optimizations for slow-path files (plus tracing), which execute only -rarely, yet take a long time to compile with optimization on. OPT -specifies overall optimization and affects all compiles, including those -OPT_FAST and OPT_SLOW control. For best results, use OPT="-Os --march=native", and link with "-static". Nearly the same results can be -had with much better compile times with OPT_FAST="-O1 -fstrict-aliasing". -Higher optimization such as "-O2" or "-O3" may help, but gcc compile times -may be excessive under O3 on even medium sized designs. +OPT_FAST specifies optimization flags for those parts of the model that are on +the fast path. This is mostly code that is executed every cycle. OPT_SLOW +applies to slow-path code, which executes rarely, often only once at the +beginning or end of simulation. Note that OPT_SLOW is ignored if +VM_PARALLEL_BUILDS is not 1, in which case all generated code will be compiled +in a single compilation unit using OPT_FAST. See also the C<--output-split> +option. The OPT_GLOBAL variable applies to common code in the run-time library +used by verilated models (shipped in $VERILATOR_ROOT/include). Additional C++ +files passed on the verilator command line use OPT_FAST. The OPT variable +applies to all compilation units in addition to the specific OPT_* variables +described above. -Unfortunately, using the optimizer with SystemC files can result in -compiles taking several minutes. (The SystemC libraries have many little -inlined functions that drive the compiler nuts.) +You can also use the -CFLAGS and/or -LDFLAGS options on the verilator command +line to pass flags directly to the compiler or linker. -For best results, use the latest clang compiler (about 10% faster than -GCC). Note the now fairly old GCC 3.2 and earlier have optimization bugs -around pointer aliasing detection, which can result in 2x performance -losses. +The default values of the OPT_* variables are chosen to yield good simulation +speed with reasonable C++ compilation times. To this end, OPT_FAST is set to +"-Os" by default. Higher optimization such as "-O2" or "-O3" may help (though +often they provide only a very small performance benefit), but compile times +may be excessively large even with medium sized designs. Compilation times can +be improved at the expense of simulation speed by reducing optimization, for +example with OPT_FAST="-O0". Often good simulation speed can be achieved with +OPT_FAST="-O1 -fstrict-aliasing" but with improved compilation times. Files +controlled by OPT_SLOW have little effect on performance and therefore OPT_SLOW +is empty by default (equivalent to "-O0") for improved compilation speed. In +common use-cases there should be little benefit in changing OPT_SLOW. +OPT_GLOBAL is set to "-Os" by default and there should rarely be a need to +change it. As the run-time library is small in comparison to a lot of verilated +models, disabling optimization on the run-time library should not have a +serious effect on overall compilation time, but may have detrimental effect on +simulation speed, especially with tracing. In addition to the above, for best +results use OPT="-march=native", the latest Clang compiler (about 10% faster +than GCC), and link statically. -If you will be running many simulations on a single compile, investigate -feedback driven compilation. With GCC, using -fprofile-arcs, then +Generally the answer to which optimization level gives the best user experience +depends on the use case and some experimentation can pay dividends. For a +speedy debug cycle during development, especially on large designs where C++ +compilation speed can dominate, consider using lower optimization to get to an +executable faster. For throughput oriented use cases, for example regressions, +it is usually worth spending extra compilation time to reduce total CPU time. + +If you will be running many simulations on a single model, you can investigate +profile guided optimization. With GCC, using -fprofile-arcs, then -fbranch-probabilities will yield another 15% or so. Modern compilers also support link-time optimization (LTO), which can help -especially if you link in DPI code. To enable LTO on GCC, pass "-flto" in -both compilation and link. Note LTO may cause excessive compile times on -large designs. +especially if you link in DPI code. To enable LTO on GCC, pass "-flto" in both +compilation and link. Note LTO may cause excessive compile times on large +designs. -Using profile driven compiler optimization, with feedback from a real -design, can yield up to30% improvements. +Unfortunately, using the optimizer with SystemC files can result in compilation +taking several minutes. (The SystemC libraries have many little inlined +functions that drive the compiler nuts.) If you are using your own makefiles, you may want to compile the Verilated code with -DVL_INLINE_OPT=inline. This will inline functions, however this @@ -2184,8 +2230,7 @@ After running Make, the C++ compiler may produce the following: {mod_prefix}{misc}.o // Intermediate objects {prefix} // Final executable (w/--exe argument) {prefix}__ALL.a // Library of all Verilated objects - {prefix}__ALLfast.cpp // Include of hot code for single compile - {prefix}__ALLslow.cpp // Include of slow code for single compile + {prefix}__ALL.cpp // Include of all code for single compile {prefix}{misc}.d // Intermediate dependencies {prefix}{misc}.o // Intermediate objects @@ -2653,7 +2698,7 @@ Verilator and add the generated C++ sources to the target specified. verilate(target SOURCES source ... [TOP_MODULE top] [PREFIX name] [TRACE] [TRACE_FST] [SYSTEMC] [COVERAGE] [INCLUDE_DIRS dir ...] [OPT_SLOW ...] [OPT_FAST ...] - [DIRECTORY dir] [VERILATOR_ARGS ...]) + [OPT_GLOBAL ..] [DIRECTORY dir] [VERILATOR_ARGS ...]) Lowercase and ... should be replaced with arguments, the uppercase parts delimit the arguments and can be passed in any order, or left out entirely @@ -2744,6 +2789,11 @@ optimization level to improve compile times with large designs. Optional. Set compiler flags for the fast path. +=item OPT_GLOBAL + +Optional. Set compiler flags for the common run-time library used by verilated +models. + =item DIRECTORY Optional. Set the verilator output directory. It is preferable to use the @@ -2769,8 +2819,7 @@ underneath NC: cd obj_dir ncsc_run \ sc_main.cpp \ - Vour__ALLfast.cpp \ - Vour__ALLslow.cpp \ + Vour__ALL.cpp \ verilated.cpp For larger designs you'll want to automate this using makefiles, which pull @@ -3076,7 +3125,7 @@ information. Break the variable into multiple pieces typically to resolve UNOPTFLAT performance issues. Typically the variables to attach this to are -recommeded by Verilator itself, see UNOPTFLAT. +recommended by Verilator itself, see UNOPTFLAT. Same as /*verilator split_var*/, see L for more information. @@ -3101,11 +3150,11 @@ uwire keyword. =head2 SystemVerilog 2005 (IEEE 1800-2005) Support Verilator supports ==? and !=? operators, ++ and -- in some contexts, -$bits, $countones, $error, $fatal, $info, $isunknown, $onehot, $onehot0, -$unit, $warning, always_comb, always_ff, always_latch, bit, byte, chandle, -const, do-while, enum, export, final, import, int, interface, logic, -longint, modport, package, program, shortint, struct, time, typedef, union, -var, void, priority case/if, and unique case/if. +$bits, $countbits, $countones, $error, $fatal, $info, $isunknown, $onehot, +$onehot0, $unit, $warning, always_comb, always_ff, always_latch, bit, byte, +chandle, const, do-while, enum, export, final, import, int, interface, +logic, longint, modport, package, program, shortint, struct, time, typedef, +union, var, void, priority case/if, and unique case/if. It also supports .name and .* interconnection. @@ -3571,7 +3620,7 @@ for more information. Attached to a variable or a net declaration to break the variable into multiple pieces typically to resolve UNOPTFLAT performance issues. -Typically the variables to attach this to are recommeded by Verilator +Typically the variables to attach this to are recommended by Verilator itself, see UNOPTFLAT below. For example, Verilator will internally convert a variable with the @@ -3620,29 +3669,24 @@ declared. =head1 LANGUAGE LIMITATIONS -There are some limitations and lack of features relative to a commercial -simulator, by intent. User beware. - -It is strongly recommended you use a lint tool before running this program. -Verilator isn't designed to easily uncover common mistakes that a lint -program will find for you. +There are some limitations and lack of features relative to the major +closed-source simulators, by intent. =head2 Synthesis Subset -Verilator supports only the Synthesis subset with a few minor additions -such as $stop, $finish and $display. That is, you cannot use hierarchical -references, events or similar features of the Verilog language. It also -simulates as Synopsys's Design Compiler would; namely a block of the form: +Verilator supports the Synthesis subset with other verification constructs +being added over time. Verilator also simulates events as Synopsys's Design +Compiler would; namely given a block of the form: always @ (x) y = x & z; This will recompute y when there is even a potential for change in x or a change in z, that is when the flops computing x or z evaluate (which is what Design Compiler will synthesize.) A compliant simulator would only -calculate y if x changes. Use Verilog-Mode's /*AS*/ or Verilog 2001's -always @* to reduce missing activity items. Avoid putting $displays in -combo blocks, as they may print multiple times when not desired, even on -compliant simulators as event ordering is not specified. +calculate y if x changes. We recommend using always_comb to make the code +run the same everywhere. Also avoid putting $displays in combo blocks, as +they may print multiple times when not desired, even on compliant +simulators as event ordering is not specified. =head2 Signal Naming @@ -3659,9 +3703,9 @@ path. =head2 Class -Verilator class support is very limited and in active development. -Verilator supports members, and methods. Verilator doe not support class -static members, class extend, or class parameters. +Verilator class support is limited but in active development. Verilator +supports members, and methods. Verilator doe not support class static +members, class extend, or class parameters. =head2 Dotted cross-hierarchy references @@ -3675,18 +3719,9 @@ specified in the Verilog standard; arrayed instances are named {cellName}[{instanceNumber}] in Verilog, which becomes {cellname}__BRA__{instanceNumber}__KET__ inside the generated C++ code. -Verilator creates numbered "genblk" when a begin: name is not specified -around a block inside a generate statement. These numbers may differ -between other simulators, but the Verilog specification does not allow -users to use these names, so it should not matter. - If you are having trouble determining where a dotted path goes wrong, note that Verilator will print a list of known scopes to help your debugging. -=head2 Floating Point - -Short floating point (shortreal) numbers are converted to real. - =head2 Latches Verilator is optimized for edge sensitive (flop based) designs. It will @@ -3788,12 +3823,6 @@ primary inputs to the model, or wires directly attached to primary inputs. For proper behavior clock enables may also need the /*verilator clock_enable*/ attribute. -=head2 Ranges must be big-bit-endian - -Bit ranges must be numbered with the MSB being numbered greater or the same -as the LSB. Little-bit-endian buses [0:15] are not supported as they -aren't easily made compatible with C++. - =head2 Gate Primitives The 2-state gate primitives (and, buf, nand, nor, not, or, xnor, xor) are @@ -3802,7 +3831,8 @@ primitives are not supported. Tables are not supported. =head2 Specify blocks -All specify blocks and timing checks are ignored. +All specify blocks and timing checks are ignored. All min:typ:max delays +use the typical value. =head2 Array Initialization @@ -3831,7 +3861,6 @@ coverage section. Verilator does not support SEREs yet. All assertion and coverage statements must be simple expressions that complete in one cycle. -(Arguably SEREs are much of the point, but one must start somewhere.) =head2 Encrypted Verilog @@ -3908,41 +3937,26 @@ Interfaces and modports, including with generated data types are supported. Generate blocks around modports are not supported, nor are virtual interfaces nor unnamed interfaces. -=item priority if, unique if +=item shortreal -Priority and unique if's are treated as normal ifs and not asserted to be -full nor unique. +Short floating point (shortreal) numbers are converted to real. Most other +simulators either do not support float, or convert likewise. =item specify specparam All specify blocks and timing checks are ignored. -=item string - -String is supported only to the point that they can be assigned, -concatenated, compared, and passed to DPI imports. Standard method calls -on strings are not supported. - -=item timeunit, timeprecision - -All timing control statements are ignored. - =item uwire Verilator does not perform warning checking on uwires, it treats the uwire keyword as if it were the normal wire keyword. -=item $bits, $countones, $error, $fatal, $finish, $info, $isunknown, -$onehot, $onehot0, $readmemb, $readmemh, $signed, $stime, $stop, $time, -$unsigned, $warning. +=item $bits, $countbits, $countones, $error, $fatal, $finish, $info, +$isunknown, $onehot, $onehot0, $readmemb, $readmemh, $signed, $stime, $stop, +$time, $unsigned, $warning. Generally supported. -=item $displayb, $displayh, $displayo, $writeb, $writeh, $writeo, etc - -The sized display functions are rarely used and so not supported. Replace -them with a $write with the appropriate format specifier. - =item $dump/$dumpports and related $dumpfile or $dumpports will create a VCD or FST file (which is based on @@ -3980,6 +3994,11 @@ $setup, $setuphold, $skew, $timeskew, $width All specify blocks and timing checks are ignored. +=item $monitor, $strobe + +Monitor and strobe are not supported, convert to always_comb $display or +similar. + =item $random $random does not support the optional argument to set the seed. Use the @@ -4049,7 +4068,7 @@ the source line directly above. Warns that an always_comb block has a variable which is set after it is used. This may cause simulation-synthesis mismatches, as not all -commercial simulators allow this ordering. +simulators allow this ordering. always_comb begin a = b; @@ -4797,7 +4816,10 @@ correctly. Warns that unpacked structs and unions are not supported. Ignoring this warning will make Verilator treat the structure as packed, -which may make Verilator simulations differ from other simulators. +which may make Verilator simulations differ from other simulators. This +downgrading may also result what would normally be a legal unpacked +struct/array inside an unpacked struct/array becomming an illegal unpacked +struct/array inside a packed struct/array. =item UNSIGNED @@ -4975,14 +4997,14 @@ Note people sometimes request binaries when they are having problems with their C++ compiler. Alas, binaries won't help this, as in the end a fully working C++ compiler is required to compile the output of Verilator. -=item How can it be faster than (name-the-commercial-simulator)? +=item How can it be faster than (name-a-big-3-closed-source-simulator)? Generally, the implied part is of the question is "... with all of the manpower they can put into developing it." -Most commercial simulators have to be Verilog compliant, meaning event -driven. This prevents them from being able to reorder blocks and make -netlist-style optimizations, which are where most of the gains come from. +Most simulators have to be Verilog compliant, meaning event driven. This +prevents them from being able to reorder blocks and make netlist-style +optimizations, which are where most of the gains come from. Non-compliance shouldn't be scary. Your synthesis program isn't compliant, so your simulator shouldn't have to be -- and Verilator is closer to the @@ -5021,8 +5043,8 @@ simulator in order to optimize it. If it takes more than a minute or so (and you're not using --debug since debug is disk bound), see if your machine is paging; most likely you need to run it on a machine with more memory. Verilator is a full 64-bit application and may use more than 4GB, -but about 1GB is the maximum typically needed, and very large commercial -designs have topped 16GB. +but about 1GB is the maximum typically needed, and very large designs have +topped 16GB. =item How do I generate waveforms (traces) in C++? @@ -5125,10 +5147,10 @@ format instead. =item How do I view waveforms (aka dumps or traces)? -Verilator makes standard VCD (Value Change Dump) and FST files. VCD files are viewable -with the public domain GTKWave (recommended) or Dinotrace (legacy) -programs, or any of the many commercial offerings; -FST is supported by GTKWave only. +Verilator makes standard VCD (Value Change Dump) and FST files. VCD files +are viewable with the public domain GTKWave (recommended) or Dinotrace +(legacy) programs, or any of the many closed-source offerings; FST is +supported by GTKWave only. =item How do I reduce the size of large waveform (trace) files? @@ -5168,6 +5190,10 @@ For an example, after running 'make test' in the Verilator distribution, see the examples/make_tracing_c/logs directory. Grep for lines starting with '%' to see what lines Verilator believes need more coverage. +Info files can be written by verilator_coverage for import to C. +This enables use of C for HTML reports and importing reports to +sites such as L. + =item Where is the translate_off command? (How do I ignore a construct?) Translate on/off pragmas are generally a bad idea, as it's easy to have @@ -5240,10 +5266,15 @@ test_regress/t/t_extend_class files show an example of how to do this. =item How do I get faster build times? When running make pass the make variable VM_PARALLEL_BUILDS=1 so that -builds occur in parallel. +builds occur in parallel. Note this is now set by default if an output +file was large enough to be split due to the --output-split option. -Use a recent compiler. Newer compilers tend do be faster, with the -now relatively old GCC 3.0 to 3.3 being horrible. +Verilator emits any infrequently executed "cold" routines into separate +__Slow.cpp files. This can accelerate compilation as optimization can be +disabled on these routines. See the OPT_FAST and OPT_SLOW make variables +and the BENCHMARKING & OPTIMIZATION section of the manual. + +Use a recent compiler. Newer compilers tend to be faster. Compile in parallel on many machines and use caching; see the web for the ccache, distcc and icecream packages. ccache will skip GCC runs between @@ -5365,7 +5396,7 @@ outputs. Now, the following should fail: cd test_regress t/t_BUG.pl # Run on Verilator t/t_BUG.pl --debug # Run on Verilator, passing --debug to Verilator - t/t_BUG.pl --vcs # Run on a commercial simulator + t/t_BUG.pl --vcs # Run on VCS simulator t/t_BUG.pl --nc|--iv|--ghdl # Likewise on other simulators The test driver accepts a number of options, many of which mirror the main @@ -5408,7 +5439,7 @@ In 2018, Verilator 4.000 was released with multithreaded support. Currently, various language features and performance enhancements are added as the need arises. Verilator is now about 3x faster than in 2002, and is -faster than many popular commercial simulators. +faster than most (if not every) other simulator. =head1 AUTHORS @@ -5424,83 +5455,92 @@ Major concepts by Paul Wasson, Duane Galbi, John Coiner and Jie Xu. Many people have provided ideas and other assistance with Verilator. -The major corporate sponsors of Verilator, by providing significant -contributions of time or funds include include Atmel Corporation, Cavium +Verilator is receiving major development support from the CHIPS Alliance. + +Previous major corporate sponsors of Verilator, by providing significant +contributions of time or funds included include Atmel Corporation, Cavium Inc., Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd., Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus Networks Inc., and SiCortex Inc. The people who have contributed major functionality are Byron Bradley, -Jeremy Bennett, Lane Brooks, John Coiner, Duane Galbi, Todd Strader, Paul -Wasson, Jie Xu, and Wilson Snyder. Major testers included Jeff Dutton, -Jonathon Donaldson, Ralf Karge, David Hewson, Iztok Jeras, Wim Michiels, -Alex Solomatnikov, Sebastien Van Cauwenberghe, Gene Weber, and Clifford -Wolf. +Jeremy Bennett, Lane Brooks, John Coiner, Duane Galbi, Geza Lore, Todd +Strader, Stefan Wallentowitz, Paul Wasson, Jie Xu, and Wilson Snyder. +Major testers included Jeff Dutton, Jonathon Donaldson, Ralf Karge, David +Hewson, Iztok Jeras, Wim Michiels, Alex Solomatnikov, Sebastien Van +Cauwenberghe, Gene Weber, and Clifford Wolf. -Some of the people who have provided ideas and feedback for Verilator +Some of the people who have provided ideas, and feedback for Verilator include: David Addison, Tariq B. Ahmad, Nikana Anastasiadis, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, Sharad Bagri, Matthew Ballance, Andrew Bardsley, Matthew Barr, Geoff Barrett, Julius Baxter, Jeremy -Bennett, Michael Berman, Victor Besyakov, David Binderman, Piotr Binkowski, -Johan Bjork, David Black, Tymoteusz Blazejczyk, Daniel Bone, Gregg -Bouchard, Christopher Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, -Maarten De Braekeleer, Charlie Brej, J Briquet, Lane Brooks, John Brownlee, -Jeff Bush, Lawrence Butcher, Tony Bybell, Ted Campbell, Chris Candler, -Lauren Carlson, Donal Casey, Sebastien Van Cauwenberghe, Alex Chadwick, -Terry Chen, Yi-Chung Chen, Enzo Chi, Robert A. Clark, Allan Cochrane, John -Coiner, Gianfranco Costamagna, George Cuan, Joe DErrico, Lukasz Dalek, -Laurens van Dam, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, John -Demme, Mike Denio, John Deroo, Philip Derrick, John Dickol, Ruben Diez, -Danny Ding, Jacko Dirks, Ivan Djordjevic, Jonathon Donaldson, Leendert van -Doorn, Sebastian Dressler, Alex Duller, Jeff Dutton, Tomas Dzetkulic, -Usuario Eda, Charles Eddleston, Chandan Egbert, Joe Eiler, Ahmed -El-Mahmoudy, Trevor Elbourne, Robert Farrell, Eugen Fekete, Fabrizio -Ferrandi, Udi Finkelstein, Brian Flachs, Andrea Foletto, Bob Fredieu, Duane -Galbi, Benjamin Gartner, Christian Gelinek, Peter Gerst, Glen Gibb, Shankar -Giri, Dan Gisselquist, Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Sergi -Granell, Al Grant, Xuan Guo, Driss Hafdi, Neil Hamilton, Oyvind Harboe, +Bennett, Michael Berman, Victor Besyakov, Moinak Bhattacharyya, David +Binderman, Piotr Binkowski, Johan Bjork, David Black, Tymoteusz Blazejczyk, +Daniel Bone, Gregg Bouchard, Christopher Boumenot, Nick Bowler, Byron +Bradley, Bryan Brady, Maarten De Braekeleer, Charlie Brej, J Briquet, Lane +Brooks, John Brownlee, Jeff Bush, Lawrence Butcher, Tony Bybell, Ted +Campbell, Chris Candler, Lauren Carlson, Donal Casey, Sebastien Van +Cauwenberghe, Alex Chadwick, Terry Chen, Yi-Chung Chen, Enzo Chi, Robert +A. Clark, Allan Cochrane, John Coiner, Gianfranco Costamagna, Sean Cross, +George Cuan, Joe DErrico, Lukasz Dalek, Laurens van Dam, Gunter +Dannoritzer, Ashutosh Das, Bernard Deadman, John Demme, Mike Denio, John +Deroo, Philip Derrick, John Dickol, Ruben Diez, Danny Ding, Jacko Dirks, +Ivan Djordjevic, Jonathon Donaldson, Leendert van Doorn, Sebastian +Dressler, Alex Duller, Jeff Dutton, Tomas Dzetkulic, Usuario Eda, Charles +Eddleston, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Trevor Elbourne, +Mats Engstrom, Robert Farrell, Eugen Fekete, Fabrizio Ferrandi, Udi +Finkelstein, Brian Flachs, Andrea Foletto, Bob Fredieu, Duane Galbi, +Benjamin Gartner, Christian Gelinek, Peter Gerst, Glen Gibb, Michael +Gielda, Shankar Giri, Dan Gisselquist, Petr Gladkikh, Sam Gladstone, Amir +Gonnen, Chitlesh Goorah, Kai Gossner, Sergi Granell, Al Grant, Alexander +Grobman, Xuan Guo, Driss Hafdi, Neil Hamilton, James Hanlon, Oyvind Harboe, Jannis Harder, Junji Hashimoto, Thomas Hawkins, Mitch Hayenga, Robert -Henry, David Hewson, Jamey Hicks, Joel Holdsworth, Andrew Holme, Hiroki -Honda, Alex Hornung, David Horton, Jae Hossell, Alan Hunter, James -Hutchinson, Jamie Iles, Ben Jackson, Shareef Jalloq, Krzysztof Jankowski, -HyungKi Jeong, Iztok Jeras, James Johnson, Christophe Joly, Franck Jullien, -James Jung, Mike Kagen, Arthur Kahlich, Kaalia Kahn, Guy-Armand Kamendje, -Vasu Kandadi, Kanad Kanhere, Patricio Kaplan, Pieter Kapsenberg, Ralf -Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Olof Kindgren, Kevin -Kiningham, Dan Kirkham, Sobhan Klnv, Gernot Koch, Soon Koh, Steve Kolecki, -Brett Koonce, Will Korteland, Wojciech Koszek, Varun Koyyalagunta, David -Kravitz, Roland Kruse, Sergey Kvachonok, Ed Lander, Steve Lang, Stephane -Laurent, Walter Lavino, Christian Leber, Larry Lee, Igor Lesik, John Li, -Eivind Liland, Yu Sheng Lin, Charlie Lind, Andrew Ling, Paul Liu, Derek -Lockhart, Jake Longo, Arthur Low, Stefan Ludwig, Dan Lussier, Fred Ma, -Duraid Madina, Affe Mao, Julien Margetts, Mark Marshall, Alfonso Martinez, -Yves Mathieu, Patrick Maupin, Jason McMullan, Elliot Mednick, Wim Michiels, -Miodrag Milanovic, Wai Sum Mong, Peter Monsson, Sean Moore, Dennis -Muhlestein, John Murphy, Matt Myers, Richard Myers, Dimitris Nalbantis, -Peter Nelson, Bob Newgard, Cong Van Nguyen, Paul Nitza, Yossi Nivin, Pete -Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, Aleksander Osman, James -Pallister, Brad Parker, Dan Petrisko, Maciej Piechotka, David Pierce, -Dominic Plunkett, David Poole, Mike Popoloski, Roman Popov, Rich Porter, -Niranjan Prabhu, Usha Priyadharshini, Mark Jackson Pulver, Prateek Puri, -Marshal Qiao, Danilo Ramos, Chris Randall, Anton Rapp, Josh Redford, Odd -Magne Reitan, Frederic Requin, Frederick Requin, Alberto Del Rio, Eric -Rippey, Oleg Rodionov, Paul Rolfe, Arjen Roodselaar, Tobias Rosenkranz, Jan -Egil Ruud, Denis Rystsov, John Sanguinetti, Galen Seitz, Salman Sheikh, Hao -Shi, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Anderson Ignacio -Da Silva, Rodney Sinclair, Steven Slatter, Brian Small, Garrett Smith, -Wilson Snyder, Stan Sokorac, Alex Solomatnikov, Wei Song, Art Stamness, -John Stevenson, Patrick Stewart, Rob Stoddard, Todd Strader, John Stroebel, -Sven Stucki, Howard Su, Emerson Suguimoto, Gene Sullivan, Renga -Sundararajan, Rupert Swarbrick, Yutetsu Takatsukasa, Peter Tengstrand, -Wesley Terpstra, Rui Terra, Stefan Thiede, Gary Thomas, Ian Thompson, Kevin -Thompson, Mike Thyer, Hans Tichelaar, Viktor Tomov, Steve Tong, Michael -Tresidder, Neil Turton, Bogdan Vukobratovic, Holger Waechtler, Philipp -Wagner, Stefan Wallentowitz, Shawn Wang, Paul Wasson, Greg Waters, Thomas -Watts, Eugene Weber, David Welch, Thomas J Whatson, Leon Wildman, Gerald -Williams, Trevor Williams, Jeff Winston, Joshua Wise, Clifford Wolf, Johan -Wouters, Junyi Xi, Ding Xiaoliang, Jie Xu, Mandy Xu, Luke Yang, and Amir -Yazdanbakhsh. +Henry, Stephen Henry, David Hewson, Jamey Hicks, Joel Holdsworth, Andrew +Holme, Hiroki Honda, Alex Hornung, David Horton, Peter Horvath, Jae +Hossell, Alan Hunter, James Hutchinson, Jamie Iles, Ben Jackson, Shareef +Jalloq, Krzysztof Jankowski, HyungKi Jeong, Iztok Jeras, James Johnson, +Christophe Joly, Franck Jullien, James Jung, Mike Kagen, Arthur Kahlich, +Kaalia Kahn, Guy-Armand Kamendje, Vasu Kandadi, Kanad Kanhere, Patricio +Kaplan, Pieter Kapsenberg, Ralf Karge, Dan Katz, Sol Katzman, Ian Kennedy, +Jonathan Kimmitt, Olof Kindgren, Kevin Kiningham, Dan Kirkham, Sobhan Klnv, +Gernot Koch, Soon Koh, Nathan Kohagen, Steve Kolecki, Brett Koonce, Will +Korteland, Wojciech Koszek, Varun Koyyalagunta, David Kravitz, Roland +Kruse, Sergey Kvachonok, Charles Eric LaForest, Ed Lander, Steve Lang, +Stephane Laurent, Walter Lavino, Christian Leber, Larry Lee, Igor Lesik, +John Li, Eivind Liland, Yu Sheng Lin, Charlie Lind, Andrew Ling, Jiuyang +Liu, Paul Liu, Derek Lockhart, Jake Longo, Geza Lore, Arthur Low, Stefan +Ludwig, Dan Lussier, Fred Ma, Duraid Madina, Affe Mao, Julien Margetts, +Mark Marshall, Alfonso Martinez, Yves Mathieu, Patrick Maupin, Jason +McMullan, Elliot Mednick, Wim Michiels, Miodrag Milanovic, Wai Sum Mong, +Peter Monsson, Sean Moore, Dennis Muhlestein, John Murphy, Matt Myers, +Nathan Myers, Richard Myers, Dimitris Nalbantis, Peter Nelson, Bob Newgard, +Cong Van Nguyen, Paul Nitza, Yossi Nivin, Pete Nixon, Lisa Noack, Mark +Nodine, Kuba Ober, Andreas Olofsson, Aleksander Osman, James Pallister, +Vassilis Papaefstathiou, Brad Parker, Dan Petrisko, Maciej Piechotka, David +Pierce, Dominic Plunkett, David Poole, Mike Popoloski, Roman Popov, Rich +Porter, Niranjan Prabhu, Usha Priyadharshini, Mark Jackson Pulver, Prateek +Puri, Marshal Qiao, Danilo Ramos, Chris Randall, Anton Rapp, Josh Redford, +Odd Magne Reitan, Frederic Requin, Frederick Requin, Dustin Richmond, +Alberto Del Rio, Eric Rippey, Oleg Rodionov, Ludwig Rogiers, Paul Rolfe, +Arjen Roodselaar, Tobias Rosenkranz, Huang Rui, Jan Egil Ruud, Denis +Rystsov, John Sanguinetti, Galen Seitz, Salman Sheikh, Hao Shi, Mike +Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Anderson Ignacio Da Silva, +Rodney Sinclair, Steven Slatter, Brian Small, Garrett Smith, Tim Snyder, +Maciej Sobkowski, Stan Sokorac, Alex Solomatnikov, Wei Song, Art Stamness, +David Stanford, John Stevenson, Pete Stevenson, Patrick Stewart, Rob +Stoddard, Todd Strader, John Stroebel, Sven Stucki, Howard Su, Emerson +Suguimoto, Gene Sullivan, Qingyao Sun, Renga Sundararajan, Rupert +Swarbrick, Yutetsu Takatsukasa, Peter Tengstrand, Wesley Terpstra, Rui +Terra, Stefan Thiede, Gary Thomas, Ian Thompson, Kevin Thompson, Mike +Thyer, Hans Tichelaar, Viktor Tomov, Steve Tong, Michael Tresidder, Neil +Turton, Srini Vemuri, Yuri Victorovich, Bogdan Vukobratovic, Holger +Waechtler, Philipp Wagner, Stefan Wallentowitz, Shawn Wang, Paul Wasson, +Greg Waters, Thomas Watts, Eugene Weber, David Welch, Thomas J Whatson, +Marco Widmer, Leon Wildman, Daniel Wilkerson, Gerald Williams, Trevor +Williams, Jan Van Winkel, Jeff Winston, Joshua Wise, Clifford Wolf, Tobias +Wolfel, Johan Wouters, Junyi Xi, Ding Xiaoliang, Jie Xu, Mandy Xu, +Takatsukasa Y, Luke Yang, and Amir Yazdanbakhsh. Thanks to them, and all those we've missed including above, or wished to remain anonymous. diff --git a/bin/verilator_coverage b/bin/verilator_coverage index 37b931c29..e3d0bf45e 100755 --- a/bin/verilator_coverage +++ b/bin/verilator_coverage @@ -156,6 +156,8 @@ verilator_coverage - Verilator coverage analyzer verilator_coverage -write merged.dat -read ... + verilator_coverage -write-info merged.info -read ... + Verilator_coverage processes Verilator coverage reports. With --anotate, it reads the specified data file and generates annotated @@ -224,8 +226,20 @@ Displays program version and exits. =item --write I Specifies the aggregate coverage results, summed across all the files, -should be written to the given filename. This is useful in scripts to -combine many sequential runs into one master coverage file. +should be written to the given filename in verilator_coverage data format. +This is useful in scripts to combine many sequential runs into one master +coverage file. + +=item --write-info I + +Specifies the aggregate coverage results, summed across all the files, +should be written to the given filename in C .info format. +This may be used to use C to aggregate or generate reports. + +The info format loses data compared to the Verilator coverage data format; +the info will all forms of coverage converted to line style coverage, and +if there are multiple coverage points on a single line, the minimum +coverage across those points will be used to report coverage of the line. =back @@ -277,7 +291,7 @@ Wilson Snyder =head1 SEE ALSO -C +C, C L which is the source for this document. diff --git a/ci/build_vcddiff.sh b/ci/build_vcddiff.sh deleted file mode 100755 index f4eca15fd..000000000 --- a/ci/build_vcddiff.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -# DESCRIPTION: Verilator: Build script for vcddiff -# -# Copyright 2019 by Todd Strader. 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 -set -e - -# NB: it would be better to add this via a PPA - -TMP_DIR=$(mktemp -d) - -git -C "${TMP_DIR}" clone https://github.com/veripool/vcddiff -VCDDIFF_DIR=${TMP_DIR}/vcddiff -git -C "${VCDDIFF_DIR}" checkout 5112f88b7ba8818dce9dfb72619e64a1fc19542c -make -C "${VCDDIFF_DIR}" -sudo cp "${VCDDIFF_DIR}/vcddiff" /usr/local/bin diff --git a/ci/build_verilator.sh b/ci/build_verilator.sh deleted file mode 100755 index 3ae363bf7..000000000 --- a/ci/build_verilator.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -# DESCRIPTION: Verilator: Travis CI build script -# -# Copyright 2019 by Todd Strader. 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 -# -# This script builds and caches the Verilator binaries for Travis CI -# (and possibly other CI platforms). The Verilator CI system uses this -# script, but other CI systems that depend on Verilator may also use -# the script. -# see: https://github.com/verilator/verilator_ext_tests/blob/master/.travis.yml -# To use this script, either checkout Verilator as part of the CI build -# process or add Verilator as a Git submodule. Verilator tarballs can -# not be used as the script relies on Git revisions for caching. -set -e - -if [ -z "${VERILATOR_NUM_JOBS}" ]; then - VERILATOR_NUM_JOBS=$(nproc) -fi - -# Caching would be simpler if we installed without VERILATOR_ROOT, but -# it's needed for driver.pl outside of the repo -if [ -z "${VERILATOR_ROOT}" ]; then - echo "VERILATOR_ROOT not set" - exit -1 -fi - -if [ -z "${VERILATOR_CACHE}" ]; then - echo "VERILATOR_CACHE not set" - exit -1 -fi - -VERILATOR_REV=$(cd "${VERILATOR_ROOT}" && git rev-parse HEAD) -echo "Found Verilator rev ${VERILATOR_REV}" - -CACHED_REV_FILE=${VERILATOR_CACHE}/.rev.txt - -if [[ ! -f "${CACHED_REV_FILE}" || \ - $(< "${CACHED_REV_FILE}") != "${VERILATOR_REV}" ]]; then - echo "Building Verilator" - - # Unsure why Travis monkies with the capitalization of the stage name, but it does - if [[ -n ${TRAVIS_BUILD_STAGE_NAME} && \ - ${TRAVIS_BUILD_STAGE_NAME} != "Build verilator" ]]; then - echo "WARNING: Building Verilator in Travis build stage other than \"Build verilator\": ${TRAVIS_BUILD_STAGE_NAME}" - fi - - cd "${VERILATOR_ROOT}" - autoconf && ./configure ${VERILATOR_CONFIG_FLAGS} && make -j ${VERILATOR_NUM_JOBS} - # Copy the Verilator build artifacts - mkdir -p "${VERILATOR_CACHE}" - rm -rf ${VERILATOR_CACHE}/* - cp bin/*bin* "${VERILATOR_CACHE}" - # Remember the Git revision - echo "${VERILATOR_REV}" > "${CACHED_REV_FILE}" -else - echo "Using cached Verilator" - cd "${VERILATOR_ROOT}" - # Create include/verilated_config.h and maybe other things - autoconf && ./configure ${VERILATOR_CONFIG_FLAGS} - cp ${VERILATOR_CACHE}/* bin -fi diff --git a/ci/docker/buildenv/Dockerfile b/ci/docker/buildenv/Dockerfile index 7243d30d2..f3008bb97 100644 --- a/ci/docker/buildenv/Dockerfile +++ b/ci/docker/buildenv/Dockerfile @@ -6,44 +6,40 @@ # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -FROM ubuntu:18.04 +FROM ubuntu:20.04 RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive \ apt-get install --no-install-recommends -y \ - autoconf=2.69-11 \ - bc=1.07.1-2 \ - bison=2:3.0.4.dfsg-1build1 \ - build-essential=12.4ubuntu1 \ - ca-certificates=20180409 \ - cmake=3.10.2-1ubuntu2.18.04.1 \ - flex=2.6.4-6 \ - gdb=8.1-0ubuntu3.2 \ - gcc-6=6.5.0-2ubuntu1~18.04 \ - gcc-5=5.5.0-12ubuntu1 \ - gcc-4.8=4.8.5-4ubuntu8 \ - git=1:2.17.1-1ubuntu0.5 \ - gtkwave=3.3.86-1 \ - g++-6=6.5.0-2ubuntu1~18.04 \ - g++-5=5.5.0-12ubuntu1 \ - g++-4.8=4.8.5-4ubuntu8 \ - libfl2=2.6.4-6 \ - libfl-dev=2.6.4-6 \ - numactl=2.0.11-2.1ubuntu0.1 \ - perl=5.26.1-6ubuntu0.3 \ - python3=3.6.7-1~18.04 \ - wget=1.19.4-1ubuntu2.2 \ - zlibc=0.9k-4.3 \ - zlib1g=1:1.2.11.dfsg-0ubuntu2 \ - zlib1g-dev=1:1.2.11.dfsg-0ubuntu2 \ + autoconf \ + bc \ + bison \ + build-essential \ + ca-certificates \ + ccache \ + clang \ + cmake \ + flex \ + gdb \ + git \ + gtkwave \ + libfl2 \ + libfl-dev \ + libgoogle-perftools-dev \ + libsystemc \ + libsystemc-dev \ + numactl \ + perl \ + python3 \ + wget \ + zlibc \ + zlib1g \ + zlib1g-dev \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* WORKDIR /tmp -COPY build-systemc.sh /tmp/ -RUN ./build-systemc.sh - RUN cpan install -fi Unix::Processors Parallel::Forker Bit::Vector RUN git clone https://github.com/veripool/vcddiff.git && \ @@ -55,4 +51,6 @@ COPY build.sh /tmp/build.sh ENV VERILATOR_AUTHOR_SITE=1 +WORKDIR /work + ENTRYPOINT [ "/tmp/build.sh" ] diff --git a/ci/docker/buildenv/README.adoc b/ci/docker/buildenv/README.adoc index c4747c890..ed2270eed 100644 --- a/ci/docker/buildenv/README.adoc +++ b/ci/docker/buildenv/README.adoc @@ -5,7 +5,7 @@ build. It uses the following parameters: * Source repository (default: https://github.com/verilator/verilator) * Source revision (default: master) -* GCC version (4.8.5, 5.5.0, 6.5.0, 7.4.0, default: 7.4.0) +* Compiler (GCC 9.3.0, clang 10.0.0, default: 9.3.0) The container is published as `verilator/verilator-buildenv` on https://hub.docker.com/repository/docker/verilator/verilator-buildenv[docker hub]. @@ -20,13 +20,13 @@ To also run tests: To change the compiler: - docker run -ti -e CC=gcc-4.8 -e CXX=g++-4.8 verilator/verilator-buildenv test + docker run -ti -e CC=clang-10 -e CXX=clang++-10 verilator/verilator-buildenv test The tests that involve gdb are not working due to security restrictions. To run those too: .... -docker run -ti -v ${PWD}:/tmp/repo -e REPO=/tmp/repo -e REV=`git rev-parse --short HEAD` -e CC=gcc-4.8 -e CXX=g++-4.8 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined verilator/verilator-buildenv test +docker run -ti -e CC=clang-10 -e CXX=clang++-10 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined verilator/verilator-buildenv test .... Rather then building using a remote git repository you may prefer to use a diff --git a/ci/docker/buildenv/build-systemc.sh b/ci/docker/buildenv/build-systemc.sh deleted file mode 100755 index 0500e8ff3..000000000 --- a/ci/docker/buildenv/build-systemc.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -e -# DESCRIPTION: Build SystemC in Ubuntu 18.04 with different g++/gcc -# -# Copyright 2020 by Stefan Wallentowitz. 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 - -build_variant () { - version=$($1 --version | grep gcc | awk '{print $4}') - mkdir "/usr/local/systemc-2.3.3-gcc$version" - mkdir build - cd build - ../configure --prefix="/usr/local/systemc-2.3.3-gcc$version" CC="$1" CXX="$2" LD="$2" - make -j - make install - cd .. - rm -r build -} - -wget https://www.accellera.org/images/downloads/standards/systemc/systemc-2.3.3.tar.gz -tar -xzf systemc-2.3.3.tar.gz -cd systemc-2.3.3 -build_variant gcc g++ -build_variant gcc-6 g++-6 -build_variant gcc-5 g++-5 -build_variant gcc-4.8 g++-4.8 -cd .. -rm -r systemc-2.3.3* diff --git a/ci/docker/buildenv/build.sh b/ci/docker/buildenv/build.sh index f48c1c80b..1ad342151 100755 --- a/ci/docker/buildenv/build.sh +++ b/ci/docker/buildenv/build.sh @@ -12,12 +12,6 @@ : "${CC:=gcc}" : "${CXX:=g++}" -GCCVERSION=$(${CC} --version | grep gcc | awk '{print $4}') - -export SYSTEMC_INCLUDE="/usr/local/systemc-2.3.3-gcc${GCCVERSION}/include" -export SYSTEMC_LIBDIR="/usr/local/systemc-2.3.3-gcc${GCCVERSION}/lib-linux64" -export LD_LIBRARY_PATH=${SYSTEMC_LIBDIR} - SRCS=$PWD/verilator git clone "$REPO" "$SRCS" diff --git a/ci/docker/run/Dockerfile b/ci/docker/run/Dockerfile index e5e063a13..18c40483f 100644 --- a/ci/docker/run/Dockerfile +++ b/ci/docker/run/Dockerfile @@ -6,19 +6,20 @@ # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -FROM ubuntu:18.04 +FROM ubuntu:20.04 RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive \ && apt-get install --no-install-recommends -y \ - autoconf=2.69-11 \ - bc=1.07.1-2 \ - bison=2:3.0.4.dfsg-1build1 \ - build-essential=12.4ubuntu1 \ - ca-certificates=20180409 \ + autoconf \ + bc \ + bison \ + build-essential \ + ca-certificates \ ccache \ - flex=2.6.4-6 \ + flex \ git \ - libfl-dev=2.6.4-6 \ + libfl-dev \ libgoogle-perftools-dev \ perl \ python3 \ diff --git a/ci/test.sh b/ci/test.sh deleted file mode 100755 index fbac24b6c..000000000 --- a/ci/test.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash -# DESCRIPTION: Verilator: Travis CI test script -# -# Copyright 2019 by Todd Strader. 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 - -set -e - -export DRIVER_FLAGS='-j 0 --quiet --rerun' - -case $1 in - dist) - make -C test_regress SCENARIOS=--dist - ;; - vlt) - make -C test_regress SCENARIOS=--vlt - ;; - vltmt) - make -C test_regress SCENARIOS=--vltmt - ;; - vltmt0) - make -C test_regress SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=0/2 - ;; - vltmt1) - make -C test_regress SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=1/2 - ;; - *) - echo "Usage: test.sh (dist|vlt|vltmt)" - exit -1 - ;; -esac diff --git a/ci/travis-ccache-maint.bash b/ci/travis-ccache-maint.bash new file mode 100755 index 000000000..a8f2ddfc0 --- /dev/null +++ b/ci/travis-ccache-maint.bash @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# DESCRIPTION: Verilator: Travis CI ccache maintenance +# +# Copyright 2020 by Geza Lore. 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 + +################################################################################ +# This script is run in 'before_script', once ccache has been set up. +################################################################################ + +set -e +set -x + +# Show version +ccache --version + +# Flush ccache if requested in commit message +COMMIT="${TRAVIS_PULL_REQUEST_SHA:-$TRAVIS_COMMIT}" +if git log --format=%B -n 1 "$COMMIT" | grep -q -i '\[travis\s\+ccache\s\+clear\]'; then + echo "Flushing ccache due to commit message" + ccache -C +fi + +# Dump stats, then zero stats +ccache -s -z diff --git a/ci/travis-ccache-size.bash b/ci/travis-ccache-size.bash new file mode 100755 index 000000000..60a5b412d --- /dev/null +++ b/ci/travis-ccache-size.bash @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# DESCRIPTION: Verilator: Travis CI ccache sizer +# +# Copyright 2020 by Geza Lore. 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 + +################################################################################ +# This script computes the size of the ccache to be used for a job. We want the +# ccache to be just big enough to be able to hold a whole build so a re-build +# of the same does not miss in the cache due to capacity, but we don't want the +# ccache too big as pulling it down from the network takes time, and it is +# unlikely objects from much earlier builds would be useful. +################################################################################ + +fatal() { + echo "ERROR: $(basename "$0"): $1" >&2; exit 1; +} + +if [ "$TRAVIS_BUILD_STAGE_NAME" = "build" ]; then + if [ "$COVERAGE" == 1 ]; then + echo "1024M" + else + echo "768M" + fi +elif [ "$TRAVIS_BUILD_STAGE_NAME" = "test" ]; then + if [[ $TESTS == coverage-* ]]; then + echo "1536M" + else + echo "256M" + fi +else + fatal "Unknown build stage: '$TRAVIS_BUILD_STAGE_NAME'" +fi diff --git a/ci/travis-install.bash b/ci/travis-install.bash new file mode 100755 index 000000000..6fb552ca5 --- /dev/null +++ b/ci/travis-install.bash @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# DESCRIPTION: Verilator: Travis CI dependency install script +# +# Copyright 2020 by Geza Lore. 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 + +################################################################################ +# This script runs in the 'install' phase of all jobs, in all stages. We try to +# minimize the time spent in this by selectively installing only the components +# required by the particular build stage. +################################################################################ + +# Note that Travis runs "apt-get update" when "apt-get install" is used in the +# .travis.yml file directly, but since we invoke it via this script, we need to +# run it manually where requried, otherwise some packages cannot be found. + +set -e +set -x + +fatal() { + echo "ERROR: $(basename "$0"): $1" >&2; exit 1; +} + +install-vcddiff() { + TMP_DIR="$(mktemp -d)" + git clone https://github.com/veripool/vcddiff "$TMP_DIR" + git -C "${TMP_DIR}" checkout 5112f88b7ba8818dce9dfb72619e64a1fc19542c + make -C "${TMP_DIR}" + sudo cp "${TMP_DIR}/vcddiff" /usr/local/bin +} + +if [ "$TRAVIS_BUILD_STAGE_NAME" = "build" ]; then + ############################################################################## + # Dependencies of jobs in the 'build' stage, i.e.: packages required to + # build Verilator + + if [ "$TRAVIS_OS_NAME" = "linux" ]; then + time sudo apt-get update + sudo apt-get install libfl-dev + sudo apt-get install libgoogle-perftools-dev + if [ "$COVERAGE" = 1 ]; then + yes yes | sudo cpan -fi Unix::Processors Parallel::Forker + fi + else + fatal "Unknown os: '$TRAVIS_OS_NAME'" + fi +elif [ "$TRAVIS_BUILD_STAGE_NAME" = "test" ]; then + ############################################################################## + # Dependencies of jobs in the 'test' stage, i.e.: packages required to + # run the tests + + if [ "$TRAVIS_OS_NAME" = "linux" ]; then + sudo apt-get update + sudo apt-get install gdb gtkwave lcov + if [ "$TRAVIS_DIST" = "focal" ]; then + sudo apt-get install libsystemc-dev + fi + yes yes | sudo cpan -fi Unix::Processors Parallel::Forker + # Not listing Bit::Vector as slow to install, and only skips one test + install-vcddiff + else + fatal "Unknown os: '$TRAVIS_OS_NAME'" + fi +else + ############################################################################## + # Unknown build stage + fatal "Unknown build stage: '$TRAVIS_BUILD_STAGE_NAME'" +fi diff --git a/ci/travis-script.bash b/ci/travis-script.bash new file mode 100755 index 000000000..e87e62429 --- /dev/null +++ b/ci/travis-script.bash @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +# DESCRIPTION: Verilator: Travis CI main job script +# +# Copyright 2020 by Geza Lore. 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 + +################################################################################ +# This is the main script executed in the 'script' phase by all jobs. We use a +# single script to keep the .travis.yml spec simple. We pass job parameters via +# environment variables using 'env' keys. Having different 'env' keys in jobs +# ensures they use different Travis build caches. +################################################################################ + +set -e +set -x + +fatal() { + echo "ERROR: $(basename "$0"): $1" >&2; exit 1; +} + +if [ "$TRAVIS_BUILD_STAGE_NAME" = "build" ]; then + ############################################################################## + # Build verilator + + if [ "$TRAVIS_OS_NAME" = "linux" ]; then + if [ "$COVERAGE" != 1 ]; then + autoconf + ./configure --enable-longtests --enable-ccwarn + make -j $(nproc) + else + nodist/code_coverage --stages 1-2 + fi + else + fatal "Unknown os: '$TRAVIS_OS_NAME'" + fi +elif [ "$TRAVIS_BUILD_STAGE_NAME" = "test" ]; then + ############################################################################## + # Run tests + + if [ "$TRAVIS_OS_NAME" = "linux" ]; then + # Run the specified test + case $TESTS in + dist-vlt-0) + make -C test_regress SCENARIOS="--dist --vlt" DRIVER_HASHSET=--hashset=0/2 + ;; + dist-vlt-1) + make -C test_regress SCENARIOS="--dist --vlt" DRIVER_HASHSET=--hashset=1/2 + ;; + vltmt-0) + make -C test_regress SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=0/2 + ;; + vltmt-1) + make -C test_regress SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=1/2 + ;; + coverage-dist) + nodist/code_coverage --stages 3- --scenarios=--dist + ;; + coverage-vlt-0) + nodist/code_coverage --stages 3- --scenarios=--vlt --hashset=0/4 + ;; + coverage-vlt-1) + nodist/code_coverage --stages 3- --scenarios=--vlt --hashset=1/4 + ;; + coverage-vlt-2) + nodist/code_coverage --stages 3- --scenarios=--vlt --hashset=2/4 + ;; + coverage-vlt-3) + nodist/code_coverage --stages 3- --scenarios=--vlt --hashset=3/4 + ;; + coverage-vltmt-0) + nodist/code_coverage --stages 3- --scenarios=--vltmt --hashset=0/4 + ;; + coverage-vltmt-1) + nodist/code_coverage --stages 3- --scenarios=--vltmt --hashset=1/4 + ;; + coverage-vltmt-2) + nodist/code_coverage --stages 3- --scenarios=--vltmt --hashset=2/4 + ;; + coverage-vltmt-3) + nodist/code_coverage --stages 3- --scenarios=--vltmt --hashset=3/4 + ;; + *) + fatal "Unknown test: $TESTS" + ;; + esac + # Upload coverage data to codecov.io + if [[ $TESTS == coverage-* ]]; then + bash <(curl -s https://codecov.io/bash) -f nodist/obj_dir/coverage/app_total.info + fi + else + fatal "Unknown os: '$TRAVIS_OS_NAME'" + fi +else + ############################################################################## + # Unknown build stage + fatal "Unknown build stage: '$TRAVIS_BUILD_STAGE_NAME'" +fi diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..91e26fb48 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,38 @@ +# DESCRIPTION: codecov.io config +# +# Copyright 2020-2020 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 +#################### +# Validate: +# curl --data-binary @codecov.yml https://codecov.io/validate + +codecov: + require_ci_to_pass: no + +coverage: + precision: 2 + round: down + range: "70...100" + ignore: + - "ci" + - "docs" + - "examples" + - "include/gtkwave" + - "include/vltstd" + - "test_regress" + +parsers: + gcov: + branch_detection: + conditional: yes + loop: yes + method: no + macro: no + +comment: + layout: "reach,diff,flags,tree" + behavior: default + require_changes: yes diff --git a/configure.ac b/configure.ac index b21cc5868..809200482 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ #AC_INIT([Verilator],[#.### YYYY-MM-DD]) #AC_INIT([Verilator],[#.### devel]) -AC_INIT([Verilator],[4.034 2020-05-03], +AC_INIT([Verilator],[4.036 2020-06-06], [https://verilator.org], [verilator],[https://verilator.org]) # When releasing, also update header of Changes file @@ -16,7 +16,10 @@ AC_INIT([Verilator],[4.034 2020-05-03], AC_CONFIG_HEADER(src/config_build.h) AC_CONFIG_FILES(Makefile docs/Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc verilator-config.cmake verilator-config-version.cmake) +# Version AC_MSG_RESULT([configuring for $PACKAGE_STRING]) +PACKAGE_VERSION_NUMBER=`AS_ECHO("$PACKAGE_VERSION") | sed 's/ .*//g'` +AC_SUBST(PACKAGE_VERSION_NUMBER) # Ignore automake flags passed by Ubuntu builds AC_ARG_ENABLE([dependency-tracking], @@ -416,6 +419,7 @@ AC_LINK_IFELSE( CFG_WITH_THREADED=$_my_result AC_SUBST(CFG_WITH_THREADED) AC_MSG_RESULT($CFG_WITH_THREADED) +CXXFLAGS="$ACO_SAVE_CXXFLAGS" # Check compiler flag if test "$CFG_WITH_THREADED" = "no" ; then @@ -438,6 +442,20 @@ AC_CHECK_MEMBER([struct stat.st_mtim.tv_nsec], [AC_DEFINE([HAVE_STAT_NSEC],[1],[Defined if struct stat has st_mtim.tv_nsec])], [], [#include ]) +# HAVE_SYSTEMC +# - If found the default search path has it, so support is always enabled. +# - If not found or not system-wide, user can set SYSTEMC_INCLUDE. +# AC_CHECK_HEADERS seems to not locate on Travis-CI but include does work. +AC_MSG_CHECKING([whether SystemC is found (in system path)]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include + ]],[])], + [_my_result=yes + AC_DEFINE([HAVE_SYSTEMC_H],[1],[Defined if have systemc.h])], + [_my_result=no]) +AC_MSG_RESULT($_my_result) +AC_SUBST(HAVE_SYSTEMC_H) + # Checks for system services # Other install directories diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 9b948c0e6..4426b7e75 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -6,15 +6,22 @@ Please see the Verilator manual for 200+ additional contributors. Thanks to all. Ahmed El-Mahmoudy Alex Chadwick Chris Randall +Dan Petrisko +David Horton David Stanford Driss Hafdi Eric Rippey Garrett Smith Geza Lore Gianfranco Costamagna +Glen Gibb Howard Su +Huang Rui Iztok Jeras James Hanlon +James Hutchinson +Jamey Hicks +Jan Van Winkel Jeremy Bennett John Coiner John Demme @@ -22,11 +29,13 @@ Julien Margetts Kanad Kanhere Kevin Kiningham Kuba Ober +Ludwig Rogiers Lukasz Dalek Maarten De Braekeleer Maciej Sobkowski Marco Widmer Matthew Ballance +Michael Killough Mike Popoloski Nathan Kohagen Nathan Myers @@ -39,11 +48,19 @@ Qingyao Sun Richard Myers Sean Cross Sebastien Van Cauwenberghe +Sergi Granell Stefan Wallentowitz +Stephen Henry +Tim Snyder Tobias Rosenkranz Tobias Wölfel Todd Strader +Tomasz Gorochowik +Tymoteusz Blazejczyk +Vassilis Papaefstathiou Veripool API Bot Wilson Snyder +Yossi Nivin +Yuri Victorovich Yutetsu TAKATSUKASA Yves Mathieu diff --git a/docs/install.adoc b/docs/install.adoc index 094661f3e..a61171896 100644 --- a/docs/install.adoc +++ b/docs/install.adoc @@ -80,8 +80,7 @@ MSVC++. To build or run Verilator you need these standard packages: - sudo apt-get install perl python3 - sudo apt-get install make + sudo apt-get install perl python3 make sudo apt-get install g++ # Alternatively, clang sudo apt-get install libgz # Non-Ubuntu (ignore if gives error) sudo apt-get install libfl2 libfl-dev zlibc zlib1g zlib1g-dev # Ubuntu only (ignore if gives error) @@ -95,12 +94,11 @@ good performance: To build Verilator you will need to install these packages; these do not need to be present to run Verilator: - sudo apt-get install git - sudo apt-get install autoconf flex bison + sudo apt-get install git autoconf flex bison Those developing Verilator itself may also want these (see internals.adoc): - sudo apt-get install gdb asciidoctor graphviz cmake clang-format + sudo apt-get install gdb asciidoctor graphviz cmake clang clang-format gprof lcov cpan install Pod::Perldoc cpan install Unix::Processors cpan install Parallel::Forker @@ -266,10 +264,9 @@ set in your environment; it is built into the executable. == Announcements -To get notified of new releases, login to -https://www.veripool.org[Veripool], and click the "watch" button near the -top right under https://www.veripool.org/projects/verilator/news[Verilator -News]. +To get notified of new releases, go to +https://github.com/verilator/verilator-announce[Verilator announcement +repository] and follow the instructions there. == Directory Structure diff --git a/docs/internals.adoc b/docs/internals.adoc index 0a11bc295..d5c41a954 100644 --- a/docs/internals.adoc +++ b/docs/internals.adoc @@ -786,10 +786,10 @@ better viewers let us know; ZGRViewer isn't great for large graphs. Tree files are dumps of the AST Tree and are produced between every major algorithmic stage. An example: - NETLIST 0x90fb00 {a0} - 1: MODULE 0x912b20 {a8} top L2 [P] - *1:2: VAR 0x91a780 {a22} @dt=0xa2e640(w32) out_wide [O] WIRE - 1:2:1: BASICDTYPE 0xa2e640 {e24} @dt=this(sw32) integer kwd=integer range=[31:0] + NETLIST 0x90fb00 {a0ah} + 1: MODULE 0x912b20 {a8ah} top L2 [P] + *1:2: VAR 0x91a780 {a22ah} @dt=0xa2e640(w32) out_wide [O] WIRE + 1:2:1: BASICDTYPE 0xa2e640 {e24ah} @dt=this(sw32) integer kwd=integer range=[31:0] The following summarizes the above example dump, with more detail on each field in the section below. @@ -807,8 +807,9 @@ the `MODULE`, which in turn is the `op1p` pointer under the `NETLIST` | `` | means the 74th edit to the netlist was the last modification to this node. -| `{a22}` | indicates this node is related to line 22 in the source filename -"a", where "a" is the first file read, "z" the 26th, and "aa" the 27th. +| `{a22ah}` | indicates this node is related to the source filename "a", +where "a" is the first file read, "z" the 26th, and "aa" the 27th. Then +line 22 in that file, then column 8 (aa=0, az=25, ba=26, ...). | `@dt=0x...` | indicates the address of the data type this node contains. @@ -849,7 +850,10 @@ correspond directly to Verilog entities (for example `MODULE` and Address of the node:: A hexadecimal address of the node in memory. Useful for examining with the -debugger. +debugger. If the actual address values are not important, then using the +`--dump-tree-addrids` option will convert address values to short identifiers +of the form `([A-Z]*)`, which is hopefully easier for the reader to cross +reference throughout the dump. Last edit number:: @@ -996,6 +1000,24 @@ function in `src/verilator.cpp`. To get your pass to build you'll need to add its binary filename to the list in `src/Makefile_obj.in` and reconfigure. +=== "Never" features + +Verilator ideally would support all of IEEE, and has the goal to get close +to full support. However the following IEEE sections and features are not +anticipated to be ever implemented for the reasons indicated. + +[horizontal] +IEEE 1800-2017 3.3 recursive modules:: Little/no tool support, and arguably not a good practice. +IEEE 1800-2017 6.12 "shortreal":: Little/no tool support, and easily simply promoted to real. +IEEE 1800-2017 11.11 Min, typ, max:: No SDF support so will always use typical. +IEEE 1800-2017 11.12 "let":: Little/no tool support, makes difficult to implement parsers. +IEEE 1800-2017 20.15 Probabilistic functions:: Little industry use. +IEEE 1800-2017 20.16 Stochastic analysis:: Little industry use. +IEEE 1800-2017 20.17 PLA modeling:: Little industry use and outdated technology. +IEEE 1800-2017 31 Timing checks:: No longer relevant with static timing analysis tools. +IEEE 1800-2017 32 SDF annotation:: No longer relevant with static timing analysis tools. +IEEE 1800-2017 33 Config:: Little/no tool support or industry use. + == Distribution Copyright 2008-2020 by Wilson Snyder. Verilator is free software; you can diff --git a/examples/cmake_hello_c/CMakeLists.txt b/examples/cmake_hello_c/CMakeLists.txt index e657d627b..09abc8016 100644 --- a/examples/cmake_hello_c/CMakeLists.txt +++ b/examples/cmake_hello_c/CMakeLists.txt @@ -5,11 +5,9 @@ # This is an example cmake script to build a verilog to systemc project # using cmake and verilator. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### diff --git a/examples/cmake_hello_c/Makefile b/examples/cmake_hello_c/Makefile index 03740f816..212d264bd 100644 --- a/examples/cmake_hello_c/Makefile +++ b/examples/cmake_hello_c/Makefile @@ -6,11 +6,9 @@ # This makefile is here for testing the examples and should # generally not be added to a CMake project. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### diff --git a/examples/cmake_hello_sc/CMakeLists.txt b/examples/cmake_hello_sc/CMakeLists.txt index 7d89c83bc..211b73170 100644 --- a/examples/cmake_hello_sc/CMakeLists.txt +++ b/examples/cmake_hello_sc/CMakeLists.txt @@ -5,11 +5,9 @@ # This is an example cmake script to build a verilog to SystemC project # using CMake and Verilator. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### diff --git a/examples/cmake_hello_sc/Makefile b/examples/cmake_hello_sc/Makefile index c9405ce09..d368370d5 100644 --- a/examples/cmake_hello_sc/Makefile +++ b/examples/cmake_hello_sc/Makefile @@ -6,11 +6,9 @@ # This makefile is here for testing the examples and should # generally not be added to a CMake project. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### diff --git a/examples/cmake_protect_lib/CMakeLists.txt b/examples/cmake_protect_lib/CMakeLists.txt index 0605b8089..de2de27c2 100644 --- a/examples/cmake_protect_lib/CMakeLists.txt +++ b/examples/cmake_protect_lib/CMakeLists.txt @@ -5,11 +5,9 @@ # This is an example cmake script to build a verilog to systemc project # using cmake and verilator. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### diff --git a/examples/cmake_protect_lib/Makefile b/examples/cmake_protect_lib/Makefile index 6f43eab02..1d8ac603c 100644 --- a/examples/cmake_protect_lib/Makefile +++ b/examples/cmake_protect_lib/Makefile @@ -6,11 +6,9 @@ # This makefile is here for testing the examples and should # generally not be added to a CMake project. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### diff --git a/examples/cmake_tracing_c/CMakeLists.txt b/examples/cmake_tracing_c/CMakeLists.txt index ecfd8f4ed..522c20cc5 100644 --- a/examples/cmake_tracing_c/CMakeLists.txt +++ b/examples/cmake_tracing_c/CMakeLists.txt @@ -5,11 +5,9 @@ # This is an example cmake script to build a verilog to systemc project # using cmake and verilator. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### diff --git a/examples/cmake_tracing_c/Makefile b/examples/cmake_tracing_c/Makefile index 14a518002..a3f0be678 100644 --- a/examples/cmake_tracing_c/Makefile +++ b/examples/cmake_tracing_c/Makefile @@ -6,11 +6,9 @@ # This makefile is here for testing the examples and should # generally not be added to a CMake project. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### diff --git a/examples/cmake_tracing_sc/CMakeLists.txt b/examples/cmake_tracing_sc/CMakeLists.txt index bb81dd3d0..eb785d76a 100644 --- a/examples/cmake_tracing_sc/CMakeLists.txt +++ b/examples/cmake_tracing_sc/CMakeLists.txt @@ -5,11 +5,9 @@ # This is an example cmake script to build a verilog to SystemC project # using CMake and Verilator. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### diff --git a/examples/cmake_tracing_sc/Makefile b/examples/cmake_tracing_sc/Makefile index fe59d8a16..81dcf4b33 100644 --- a/examples/cmake_tracing_sc/Makefile +++ b/examples/cmake_tracing_sc/Makefile @@ -6,11 +6,9 @@ # This makefile is here for testing the examples and should # generally not be added to a CMake project. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### diff --git a/examples/make_hello_c/Makefile b/examples/make_hello_c/Makefile index 2130e9756..cdf8db58a 100644 --- a/examples/make_hello_c/Makefile +++ b/examples/make_hello_c/Makefile @@ -5,11 +5,9 @@ # This calls the object directory makefile. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### # Check for sanity to avoid later confusion diff --git a/examples/make_hello_c/sim_main.cpp b/examples/make_hello_c/sim_main.cpp index fd5003027..17cd87887 100644 --- a/examples/make_hello_c/sim_main.cpp +++ b/examples/make_hello_c/sim_main.cpp @@ -19,7 +19,7 @@ int main(int argc, char** argv, char** env) { // e.g. examples/c_tracing. // Prevent unused variable warnings - if (0 && argc && argv && env) {} + if (false && argc && argv && env) {} // Construct the Verilated model, from Vtop.h generated from Verilating "top.v" Vtop* top = new Vtop; diff --git a/examples/make_hello_sc/Makefile b/examples/make_hello_sc/Makefile index 3a4340017..f406379f0 100644 --- a/examples/make_hello_sc/Makefile +++ b/examples/make_hello_sc/Makefile @@ -5,11 +5,9 @@ # This calls the object directory makefile. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### # Check for sanity to avoid later confusion diff --git a/examples/make_hello_sc/sc_main.cpp b/examples/make_hello_sc/sc_main.cpp index 131527f5f..91f9b49ff 100644 --- a/examples/make_hello_sc/sc_main.cpp +++ b/examples/make_hello_sc/sc_main.cpp @@ -23,7 +23,7 @@ int sc_main(int argc, char* argv[]) { // e.g. examples/c_tracing. // Prevent unused variable warnings - if (0 && argc && argv) {} + if (false && argc && argv) {} // Construct the Verilated model, from Vtop.h generated from Verilating "top.v" Vtop* top = new Vtop("top"); diff --git a/examples/make_protect_lib/Makefile b/examples/make_protect_lib/Makefile index 34f1a58dc..8a82d9372 100644 --- a/examples/make_protect_lib/Makefile +++ b/examples/make_protect_lib/Makefile @@ -5,11 +5,9 @@ # This calls the object directory makefiles. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # -# Copyright 2019 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### # Check for sanity to avoid later confusion diff --git a/examples/make_protect_lib/sim_main.cpp b/examples/make_protect_lib/sim_main.cpp index e329019b5..9850a54ad 100644 --- a/examples/make_protect_lib/sim_main.cpp +++ b/examples/make_protect_lib/sim_main.cpp @@ -20,7 +20,7 @@ vluint64_t main_time = 0; double sc_time_stamp() { return main_time; } int main(int argc, char** argv, char** env) { - if (0 && argc && argv && env) {} + if (false && argc && argv && env) {} Verilated::debug(0); Verilated::randReset(2); diff --git a/examples/make_tracing_c/Makefile b/examples/make_tracing_c/Makefile index bd043c697..e16d285fd 100644 --- a/examples/make_tracing_c/Makefile +++ b/examples/make_tracing_c/Makefile @@ -5,11 +5,9 @@ # This calls the object directory makefile. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### # Check for sanity to avoid later confusion diff --git a/examples/make_tracing_c/Makefile_obj b/examples/make_tracing_c/Makefile_obj index bbea9d940..3177ef188 100644 --- a/examples/make_tracing_c/Makefile_obj +++ b/examples/make_tracing_c/Makefile_obj @@ -5,11 +5,9 @@ # # This is executed in the object directory, and called by ../Makefile # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ####################################################################### diff --git a/examples/make_tracing_c/sim_main.cpp b/examples/make_tracing_c/sim_main.cpp index 8da3fee7a..a934952fd 100644 --- a/examples/make_tracing_c/sim_main.cpp +++ b/examples/make_tracing_c/sim_main.cpp @@ -22,7 +22,7 @@ int main(int argc, char** argv, char** env) { // This is a more complicated example, please also see the simpler examples/make_hello_c. // Prevent unused variable warnings - if (0 && argc && argv && env) {} + if (false && argc && argv && env) {} // Set debug level, 0 is off, 9 is highest presently used // May be overridden by commandArgs diff --git a/examples/make_tracing_sc/Makefile b/examples/make_tracing_sc/Makefile index 149d4238c..80a6221b2 100644 --- a/examples/make_tracing_sc/Makefile +++ b/examples/make_tracing_sc/Makefile @@ -5,11 +5,9 @@ # This calls the object directory makefile. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### # Check for sanity to avoid later confusion diff --git a/examples/make_tracing_sc/Makefile_obj b/examples/make_tracing_sc/Makefile_obj index c997e2788..a2d175a27 100644 --- a/examples/make_tracing_sc/Makefile_obj +++ b/examples/make_tracing_sc/Makefile_obj @@ -5,11 +5,9 @@ # # This is executed in the object directory, and called by ../Makefile # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ####################################################################### @@ -39,8 +37,8 @@ endif # If you build your own rules from scratch, note you need to include # SystemC as follows (Vtop.mk file includes verilated.mk with these # already). -# CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC_INCLUDE) -# LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC_LIBDIR) +# CPPFLAGS += $(SYSTEMC_CXX_FLAGS) $(addprefix -I, $(SYSTEMC_INCLUDE)) +# LDFLAGS += $(SYSTEMC_CXX_FLAGS) $(addprefix -L, $(SYSTEMC_LIBDIR)) # See the benchmarking section of bin/verilator. # Support class optimizations. This includes the tracing and symbol table. diff --git a/examples/make_tracing_sc/sc_main.cpp b/examples/make_tracing_sc/sc_main.cpp index 8ec598d0b..8ab3120d4 100644 --- a/examples/make_tracing_sc/sc_main.cpp +++ b/examples/make_tracing_sc/sc_main.cpp @@ -24,7 +24,7 @@ int sc_main(int argc, char* argv[]) { // This is a more complicated example, please also see the simpler examples/make_hello_c. // Prevent unused variable warnings - if (0 && argc && argv) {} + if (false && argc && argv) {} // Set debug level, 0 is off, 9 is highest presently used // May be overridden by commandArgs diff --git a/examples/xml_py/Makefile b/examples/xml_py/Makefile index c76871650..8180c0650 100644 --- a/examples/xml_py/Makefile +++ b/examples/xml_py/Makefile @@ -2,11 +2,9 @@ # # DESCRIPTION: Verilator Example: XML tests # -# Copyright 2003-2020 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 +# This file ONLY is placed under the Creative Commons Public Domain, for +# any use, without warranty, 2020 by Wilson Snyder. +# SPDX-License-Identifier: CC0-1.0 # ###################################################################### diff --git a/include/verilated.cpp b/include/verilated.cpp index 206e7335b..c8582ab77 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include // mkdir // clang-format off @@ -77,7 +77,7 @@ VerilatedImp VerilatedImp::s_s; #ifndef VL_USER_FINISH ///< Define this to override this function void vl_finish(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE { - if (0 && hier) {} + if (false && hier) {} VL_PRINTF( // Not VL_PRINTF_MT, already on main thread "- %s:%d: Verilog $finish\n", filename, linenum); if (Verilated::gotFinish()) { @@ -100,7 +100,7 @@ void vl_stop(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE { #ifndef VL_USER_FATAL ///< Define this to override this function void vl_fatal(const char* filename, int linenum, const char* hier, const char* msg) VL_MT_UNSAFE { - if (0 && hier) {} + if (false && hier) {} Verilated::gotFinish(true); if (filename && filename[0]) { // Not VL_PRINTF_MT, already on main thread @@ -215,7 +215,7 @@ void VL_DBG_MSGF(const char* formatp, ...) VL_MT_SAFE { // Using VL_PRINTF not VL_PRINTF_MT so that we can call VL_DBG_MSGF // from within the guts of the thread execution machinery (and it goes // to the screen and not into the queues we're debugging) - VL_PRINTF("-V{t%d,%" VL_PRI64 "u}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(), out.c_str()); + VL_PRINTF("-V{t%u,%" VL_PRI64 "u}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(), out.c_str()); } #ifdef VL_THREADED @@ -243,8 +243,8 @@ Verilated::Serialized::Serialized() { s_errorLimit = 1; s_randReset = 0; s_randSeed = 0; - s_timeunit = -VL_TIME_UNIT; // Initial value until overriden by _Vconfigure - s_timeprecision = -VL_TIME_PRECISION; // Initial value until overriden by _Vconfigure + s_timeunit = VL_TIME_UNIT; // Initial value until overriden by _Vconfigure + s_timeprecision = VL_TIME_PRECISION; // Initial value until overriden by _Vconfigure } Verilated::NonSerialized::NonSerialized() { @@ -283,7 +283,7 @@ vluint64_t vl_rand64() VL_MT_SAFE { if (VL_UNLIKELY(!t_seeded)) { t_seeded = true; { - VerilatedLockGuard lock(s_mutex); + const VerilatedLockGuard lock(s_mutex); if (Verilated::randSeed() != 0) { t_state[0] = ((static_cast(Verilated::randSeed()) << 32) ^ (static_cast(Verilated::randSeed()))); @@ -311,7 +311,8 @@ vluint64_t vl_rand64() VL_MT_SAFE { IData VL_RANDOM_I(int obits) VL_MT_SAFE { return vl_rand64() & VL_MASK_I(obits); } QData VL_RANDOM_Q(int obits) VL_MT_SAFE { return vl_rand64() & VL_MASK_Q(obits); } -// VL_RANDOM_W currently unused as $random always 32 bits +// VL_RANDOM_W currently unused as $random always 32 bits, left for backwards compatibility +// LCOV_EXCL_START WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) VL_MT_SAFE { for (int i = 0; i < VL_WORDS_I(obits); ++i) { if (i < (VL_WORDS_I(obits) - 1)) { @@ -322,6 +323,7 @@ WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) VL_MT_SAFE { } return outwp; } +// LCOV_EXCL_STOP IData VL_RAND_RESET_I(int obits) VL_MT_SAFE { if (Verilated::randReset() == 0) return 0; @@ -334,7 +336,7 @@ IData VL_RAND_RESET_I(int obits) VL_MT_SAFE { } QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE { if (Verilated::randReset() == 0) return 0; - QData data = VL_ULL(~0); + QData data = ~0ULL; if (Verilated::randReset() != 1) { // if 2, randomize data = VL_RANDOM_Q(obits); } @@ -391,7 +393,7 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, if (vw == 1) { // Single divisor word breaks rest of algorithm vluint64_t k = 0; for (int j = uw - 1; j >= 0; --j) { - vluint64_t unw64 = ((k << VL_ULL(32)) + static_cast(lwp[j])); + vluint64_t unw64 = ((k << 32ULL) + static_cast(lwp[j])); owp[j] = unw64 / static_cast(rwp[0]); k = unw64 - static_cast(owp[j]) * static_cast(rwp[0]); } @@ -433,26 +435,25 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, // Main loop for (int j = uw - vw; j >= 0; --j) { // Estimate - vluint64_t unw64 = (static_cast(un[j + vw]) << VL_ULL(32) + vluint64_t unw64 = (static_cast(un[j + vw]) << 32ULL | static_cast(un[j + vw - 1])); vluint64_t qhat = unw64 / static_cast(vn[vw - 1]); vluint64_t rhat = unw64 - qhat * static_cast(vn[vw - 1]); again: - if (qhat >= VL_ULL(0x100000000) - || ((qhat * vn[vw - 2]) > ((rhat << VL_ULL(32)) + un[j + vw - 2]))) { + if (qhat >= 0x100000000ULL || ((qhat * vn[vw - 2]) > ((rhat << 32ULL) + un[j + vw - 2]))) { qhat = qhat - 1; rhat = rhat + vn[vw - 1]; - if (rhat < VL_ULL(0x100000000)) goto again; + if (rhat < 0x100000000ULL) goto again; } vlsint64_t t = 0; // Must be signed vluint64_t k = 0; for (int i = 0; i < vw; ++i) { vluint64_t p = qhat * vn[i]; // Multiply by estimate - t = un[i + j] - k - (p & VL_ULL(0xFFFFFFFF)); // Subtract + t = un[i + j] - k - (p & 0xFFFFFFFFULL); // Subtract un[i + j] = t; - k = (p >> VL_ULL(32)) - (t >> VL_ULL(32)); + k = (p >> 32ULL) - (t >> 32ULL); } t = un[j + vw] - k; un[j + vw] = t; @@ -465,7 +466,7 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, for (int i = 0; i < vw; ++i) { t = static_cast(un[i + j]) + static_cast(vn[i]) + k; un[i + j] = t; - k = t >> VL_ULL(32); + k = t >> 32ULL; } un[j + vw] = un[j + vw] + k; } @@ -516,7 +517,7 @@ QData VL_POW_QQW(int, int, int rbits, QData lhs, WDataInP rwp) VL_MT_SAFE { // Skip check for rhs == 0, as short-circuit doesn't save time if (VL_UNLIKELY(lhs == 0)) return 0; QData power = lhs; - QData out = VL_ULL(1); + QData out = 1ULL; for (int bit = 0; bit < rbits; ++bit) { if (bit > 0) power = power * power; if (VL_BITISSET_W(rwp, bit)) out *= power; @@ -630,7 +631,7 @@ std::string _vl_vsformat_time(char* tmp, double ld, bool left, size_t width) { QData fracDiv = static_cast(vl_time_multiplier(fracDigits)); QData whole = static_cast(scaled) / fracDiv; QData fraction = static_cast(scaled) % fracDiv; - int digits; + int digits = 0; if (!fracDigits) { digits = sprintf(tmp, "%" VL_PRI64 "u%s", whole, suffix.c_str()); } else { @@ -678,7 +679,16 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA inPct = false; char fmt = pos[0]; switch (fmt) { - case '0' ... '9': + case '0': // FALLTHRU + case '1': // FALLTHRU + case '2': // FALLTHRU + case '3': // FALLTHRU + case '4': // FALLTHRU + case '5': // FALLTHRU + case '6': // FALLTHRU + case '7': // FALLTHRU + case '8': // FALLTHRU + case '9': inPct = true; // Get more digits widthSet = true; width = width * 10 + (fmt - '0'); @@ -721,20 +731,14 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA const int lbits = va_arg(ap, int); double d = va_arg(ap, double); if (lbits) {} // UNUSED - always 64 - switch (fmt) { - case '^': { // Realtime + if (fmt == '^') { // Realtime if (!widthSet) width = VerilatedImp::timeFormatWidth(); output += _vl_vsformat_time(tmp, d, left, width); - break; - } - default: { + } else { std::string fmt(pctp, pos - pctp + 1); sprintf(tmp, fmt.c_str(), d); output += tmp; - break; - } // - break; - } // switch + } break; } default: { @@ -742,7 +746,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA const int lbits = va_arg(ap, int); QData ld = 0; WData qlwp[VL_WQ_WORDS_E]; - WDataInP lwp; + WDataInP lwp = NULL; if (lbits <= VL_QUADSIZE) { ld = _VL_VA_ARG_Q(ap, lbits); VL_SET_WQ(qlwp, ld); @@ -758,7 +762,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA switch (fmt) { case 'c': { IData charval = ld & 0xff; - output += charval; + output += static_cast(charval); break; } case 's': { @@ -774,7 +778,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA break; } case 'd': { // Signed decimal - int digits; + int digits = 0; std::string append; if (lbits <= VL_QUADSIZE) { digits = sprintf(tmp, "%" VL_PRI64 "d", @@ -803,7 +807,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA break; } case '#': { // Unsigned decimal - int digits; + int digits = 0; std::string append; if (lbits <= VL_QUADSIZE) { digits = sprintf(tmp, "%" VL_PRI64 "u", ld); @@ -838,30 +842,28 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA // Octal numbers may span more than one wide word, // so we need to grab each bit separately and check for overrun // Octal is rare, so we'll do it a slow simple way - output += ('0' + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 0)) ? 1 : 0) - + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 1)) ? 2 : 0) - + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 2)) ? 4 : 0)); + output += static_cast( + '0' + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 0)) ? 1 : 0) + + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 1)) ? 2 : 0) + + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 2)) ? 4 : 0)); } break; - case 'u': // Packed 2-state - output.reserve(output.size() + 4 * VL_WORDS_I(lbits)); - for (int i = 0; i < VL_WORDS_I(lbits); ++i) { - output += static_cast((lwp[i]) & 0xff); - output += static_cast((lwp[i] >> 8) & 0xff); - output += static_cast((lwp[i] >> 16) & 0xff); - output += static_cast((lwp[i] >> 24) & 0xff); - } - break; - case 'z': // Packed 4-state - output.reserve(output.size() + 8 * VL_WORDS_I(lbits)); - for (int i = 0; i < VL_WORDS_I(lbits); ++i) { - output += static_cast((lwp[i]) & 0xff); - output += static_cast((lwp[i] >> 8) & 0xff); - output += static_cast((lwp[i] >> 16) & 0xff); - output += static_cast((lwp[i] >> 24) & 0xff); - output += "\0\0\0\0"; // No tristate + case 'u': + case 'z': { // Packed 4-state + const bool is_4_state = (fmt == 'z'); + output.reserve(output.size() + ((is_4_state ? 2 : 1) * VL_WORDS_I(lbits))); + int bytes_to_go = VL_BYTES_I(lbits); + int bit = 0; + while (bytes_to_go > 0) { + const int wr_bytes = std::min(4, bytes_to_go); + for (int byte = 0; byte < wr_bytes; byte++, bit += 8) + output += static_cast(VL_BITRSHIFT_W(lwp, bit) & 0xff); + output.append(4 - wr_bytes, static_cast(0)); + if (is_4_state) output.append(4, static_cast(0)); + bytes_to_go -= wr_bytes; } break; + } case 'v': // Strength; assume always strong for (lsb = lbits - 1; lsb >= 0; --lsb) { if (VL_BITRSHIFT_W(lwp, lsb) & 1) { @@ -891,7 +893,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA static inline bool _vl_vsss_eof(FILE* fp, int floc) VL_MT_SAFE { if (fp) { - return feof(fp) ? 1 : 0; // 1:0 to prevent MSVC++ warning + return feof(fp) ? true : false; // true : false to prevent MSVC++ warning } else { return floc < 0; } @@ -929,8 +931,8 @@ static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp, _vl_vsss_advance(fp, floc); } } -static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr, - char* tmpp, const char* acceptp) VL_MT_SAFE { +static inline void _vl_vsss_read_str(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr, + char* tmpp, const char* acceptp) VL_MT_SAFE { // Read into tmp, consisting of characters from acceptp list char* cp = tmpp; while (true) { @@ -944,6 +946,19 @@ static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const std: *cp++ = '\0'; // VL_DBG_MSGF(" _read got='"< 0) { + const int c = _vl_vsss_peek(fp, floc, fromp, fstr); + if (c == EOF) return NULL; + if (!inhibit) *beginp++ = c; + _vl_vsss_advance(fp, floc); + } + return beginp; +} static inline void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb, int nbits, IData ld) VL_MT_SAFE { for (; nbits && lsb < obits; nbits--, lsb++, ld >>= 1) { @@ -992,12 +1007,14 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf int floc = fbits - 1; IData got = 0; bool inPct = false; + bool inIgnore = false; const char* pos = formatp; for (; *pos && !_vl_vsss_eof(fp, floc); ++pos) { // VL_DBG_MSGF("_vlscan fmt='"< VL_QUADSIZE) owp = va_arg(ap, WDataOutP); for (int i = 0; i < VL_WORDS_I(obits); ++i) owp[i] = 0; @@ -1036,7 +1057,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf } case 's': { _vl_vsss_skipspace(fp, floc, fromp, fstr); - _vl_vsss_read(fp, floc, fromp, fstr, tmp, NULL); + _vl_vsss_read_str(fp, floc, fromp, fstr, tmp, NULL); if (!tmp[0]) goto done; int lpos = (static_cast(strlen(tmp))) - 1; int lsb = 0; @@ -1048,9 +1069,9 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf } case 'd': { // Signed decimal _vl_vsss_skipspace(fp, floc, fromp, fstr); - _vl_vsss_read(fp, floc, fromp, fstr, tmp, "0123456789+-xXzZ?_"); + _vl_vsss_read_str(fp, floc, fromp, fstr, tmp, "0123456789+-xXzZ?_"); if (!tmp[0]) goto done; - vlsint64_t ld; + vlsint64_t ld = 0; sscanf(tmp, "%30" VL_PRI64 "d", &ld); VL_SET_WQ(owp, ld); break; @@ -1059,7 +1080,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf case 'e': case 'g': { // Real number _vl_vsss_skipspace(fp, floc, fromp, fstr); - _vl_vsss_read(fp, floc, fromp, fstr, tmp, "+-.0123456789eE"); + _vl_vsss_read_str(fp, floc, fromp, fstr, tmp, "+-.0123456789eE"); if (!tmp[0]) goto done; // cppcheck-suppress unusedStructMember // It's used union { @@ -1073,43 +1094,71 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf case 't': // FALLTHRU // Time case '#': { // Unsigned decimal _vl_vsss_skipspace(fp, floc, fromp, fstr); - _vl_vsss_read(fp, floc, fromp, fstr, tmp, "0123456789+-xXzZ?_"); + _vl_vsss_read_str(fp, floc, fromp, fstr, tmp, "0123456789+-xXzZ?_"); if (!tmp[0]) goto done; - QData ld; + QData ld = 0; sscanf(tmp, "%30" VL_PRI64 "u", &ld); VL_SET_WQ(owp, ld); break; } case 'b': { _vl_vsss_skipspace(fp, floc, fromp, fstr); - _vl_vsss_read(fp, floc, fromp, fstr, tmp, "01xXzZ?_"); + _vl_vsss_read_str(fp, floc, fromp, fstr, tmp, "01xXzZ?_"); if (!tmp[0]) goto done; _vl_vsss_based(owp, obits, 1, tmp, 0, strlen(tmp)); break; } case 'o': { _vl_vsss_skipspace(fp, floc, fromp, fstr); - _vl_vsss_read(fp, floc, fromp, fstr, tmp, "01234567xXzZ?_"); + _vl_vsss_read_str(fp, floc, fromp, fstr, tmp, "01234567xXzZ?_"); if (!tmp[0]) goto done; _vl_vsss_based(owp, obits, 3, tmp, 0, strlen(tmp)); break; } case 'x': { _vl_vsss_skipspace(fp, floc, fromp, fstr); - _vl_vsss_read(fp, floc, fromp, fstr, tmp, "0123456789abcdefABCDEFxXzZ?_"); + _vl_vsss_read_str(fp, floc, fromp, fstr, tmp, "0123456789abcdefABCDEFxXzZ?_"); if (!tmp[0]) goto done; _vl_vsss_based(owp, obits, 4, tmp, 0, strlen(tmp)); break; } + case 'u': { + // Read packed 2-value binary data + const int bytes = VL_BYTES_I(obits); + char* out = reinterpret_cast(owp); + if (!_vl_vsss_read_bin(fp, floc, fromp, fstr, out, bytes)) goto done; + const int last = bytes % 4; + if (last != 0 + && !_vl_vsss_read_bin(fp, floc, fromp, fstr, out, 4 - last, true)) + goto done; + break; + } + case 'z': { + // Read packed 4-value binary data + char* out = reinterpret_cast(owp); + int bytes = VL_BYTES_I(obits); + while (bytes > 0) { + const int abytes = std::min(4, bytes); + // aval (4B) read {0, 1} state + out = _vl_vsss_read_bin(fp, floc, fromp, fstr, out, abytes); + if (!out) goto done; + // bval (4B) disregard {X, Z} state and align to new 8B boundary. + out = _vl_vsss_read_bin(fp, floc, fromp, fstr, out, 8 - abytes, true); + if (!out) goto done; + bytes -= abytes; + } + break; + } default: std::string msg = std::string("Unknown _vl_vsscanf code: ") + pos[0]; VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str()); break; } // switch - got++; + if (!inIgnore) ++got; // Reload data if non-wide (if wide, we put it in the right place directly) - if (obits <= VL_BYTESIZE) { + if (obits == 0) { // Due to inIgnore + } else if (obits <= VL_BYTESIZE) { CData* p = va_arg(ap, CData*); *p = owp[0]; } else if (obits <= VL_SHORTSIZE) { @@ -1133,7 +1182,10 @@ done: //=========================================================================== // File I/O -FILE* VL_CVT_I_FP(IData lhs) VL_MT_SAFE { return VerilatedImp::fdToFp(lhs); } +FILE* VL_CVT_I_FP(IData lhs) VL_MT_SAFE { + // Expected non-MCD case; returns null on MCD descriptors. + return VerilatedImp::fdToFp(lhs); +} void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) VL_MT_SAFE { // See also VL_DATA_TO_STRING_NW @@ -1159,7 +1211,7 @@ void _VL_STRING_TO_VINT(int obits, void* destp, size_t srclen, const char* srcp) size_t bytes = VL_BYTES_I(obits); char* op = reinterpret_cast(destp); if (srclen > bytes) srclen = bytes; // Don't overflow destination - size_t i; + size_t i = 0; for (i = 0; i < srclen; ++i) { *op++ = srcp[srclen - 1 - i]; } for (; i < bytes; ++i) { *op++ = 0; } } @@ -1201,38 +1253,21 @@ IData VL_FERROR_IN(IData, std::string& outputr) VL_MT_SAFE { return ret; } -IData VL_FOPEN_NI(const std::string& filename, IData mode) VL_MT_SAFE { - // While threadsafe, each thread can only access different file handles - char modez[5]; - EData modee = mode; - _VL_VINT_TO_STRING(VL_IDATASIZE, modez, &modee); - return VL_FOPEN_S(filename.c_str(), modez); +IData VL_FOPEN_NN(const std::string& filename, const std::string& mode) { + return VerilatedImp::fdNew(filename.c_str(), mode.c_str()); } -IData VL_FOPEN_QI(QData filename, IData mode) VL_MT_SAFE { - // While threadsafe, each thread can only access different file handles - WData fnw[VL_WQ_WORDS_E]; - VL_SET_WQ(fnw, filename); - return VL_FOPEN_WI(VL_WQ_WORDS_E, fnw, mode); -} -IData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) VL_MT_SAFE { - // While threadsafe, each thread can only access different file handles - char filenamez[VL_TO_STRING_MAX_WORDS * VL_EDATASIZE + 1]; - _VL_VINT_TO_STRING(fnwords * VL_EDATASIZE, filenamez, filenamep); - EData modee = mode; - char modez[5]; - _VL_VINT_TO_STRING(4 * sizeof(char), modez, &modee); - return VL_FOPEN_S(filenamez, modez); -} -IData VL_FOPEN_S(const char* filenamep, const char* modep) VL_MT_SAFE { - return VerilatedImp::fdNew(fopen(filenamep, modep)); +IData VL_FOPEN_MCD_N(const std::string& filename) VL_MT_SAFE { + return VerilatedImp::fdNewMcd(filename.c_str()); } +void VL_FFLUSH_I(IData fdi) VL_MT_SAFE { VerilatedImp::fdFlush(fdi); } +IData VL_FSEEK_I(IData fdi, IData offset, IData origin) VL_MT_SAFE { + return VerilatedImp::fdSeek(fdi, offset, origin); +} +IData VL_FTELL_I(IData fdi) VL_MT_SAFE { return VerilatedImp::fdTell(fdi); } void VL_FCLOSE_I(IData fdi) VL_MT_SAFE { // While threadsafe, each thread can only access different file handles - FILE* fp = VL_CVT_I_FP(fdi); - if (VL_UNLIKELY(!fp)) return; - fclose(fp); - VerilatedImp::fdDelete(fdi); + VerilatedImp::fdClose(fdi); } void VL_FFLUSH_ALL() VL_MT_SAFE { fflush(stdout); } @@ -1327,15 +1362,13 @@ void VL_FWRITEF(IData fpi, const char* formatp, ...) VL_MT_SAFE { // While threadsafe, each thread can only access different file handles static VL_THREAD_LOCAL std::string output; // static only for speed output = ""; - FILE* fp = VL_CVT_I_FP(fpi); - if (VL_UNLIKELY(!fp)) return; va_list ap; va_start(ap, formatp); _vl_vsformat(output, formatp, ap); va_end(ap); - fputs(output.c_str(), fp); + VerilatedImp::fdWrite(fpi, output); } IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) VL_MT_SAFE { @@ -1484,36 +1517,38 @@ IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_M VL_ZERO_RESET_W(rbits, rwp); switch (tolower(fmt)) { - case 'd': - vlsint64_t lld; + case 'd': { + vlsint64_t lld = 0; sscanf(dp, "%30" VL_PRI64 "d", &lld); VL_SET_WQ(rwp, lld); break; + } case 'b': _vl_vsss_based(rwp, rbits, 1, dp, 0, strlen(dp)); break; case 'o': _vl_vsss_based(rwp, rbits, 3, dp, 0, strlen(dp)); break; case 'h': // FALLTHRU case 'x': _vl_vsss_based(rwp, rbits, 4, dp, 0, strlen(dp)); break; - case 's': // string/no conversion + case 's': { // string/no conversion for (int i = 0, lsb = 0, posp = static_cast(strlen(dp)) - 1; i < rbits && posp >= 0; --posp) { _vl_vsss_setbit(rwp, rbits, lsb, 8, dp[posp]); lsb += 8; } break; + } case 'e': { - double temp = 0.f; + double temp = 0.F; sscanf(dp, "%le", &temp); VL_SET_WQ(rwp, VL_CVT_Q_D(temp)); break; } case 'f': { - double temp = 0.f; + double temp = 0.F; sscanf(dp, "%lf", &temp); VL_SET_WQ(rwp, VL_CVT_Q_D(temp)); break; } case 'g': { - double temp = 0.f; + double temp = 0.F; sscanf(dp, "%lg", &temp); VL_SET_WQ(rwp, VL_CVT_Q_D(temp)); break; @@ -1761,7 +1796,7 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) { m_addr = (m_addr << 4) + value; } else { indata = true; - valuer += c; + valuer += static_cast(c); // printf(" Value width=%d @%x = %c\n", width, m_addr, c); if (VL_UNLIKELY(value > 1 && !m_hex)) { VL_FATAL_MT(m_filename.c_str(), m_linenum, "", @@ -1775,7 +1810,7 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) { lastc = c; } - if (VL_UNLIKELY(m_end != ~VL_ULL(0) && m_addr <= m_end)) { + if (VL_UNLIKELY(m_end != ~0ULL && m_addr <= m_end)) { VL_FATAL_MT(m_filename.c_str(), m_linenum, "", "$readmem file ended before specified final address (IEEE 2017 21.4)"); } @@ -1783,7 +1818,7 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) { return false; // EOF } void VlReadMem::setData(void* valuep, const std::string& rhs) { - QData shift = m_hex ? VL_ULL(4) : VL_ULL(1); + QData shift = m_hex ? 4ULL : 1ULL; bool innum = false; // Shift value in for (std::string::const_iterator it = rhs.begin(); it != rhs.end(); ++it) { @@ -1906,7 +1941,7 @@ void VL_READMEM_N(bool hex, // Hex format, else binary VlReadMem rmem(hex, bits, filename, start, end); if (VL_UNLIKELY(!rmem.isOpen())) return; while (true) { - QData addr; + QData addr = 0; std::string value; if (rmem.get(addr /*ref*/, value /*ref*/)) { if (VL_UNLIKELY(addr < static_cast(array_lsb) @@ -2006,50 +2041,55 @@ int VL_TIME_STR_CONVERT(const char* strp) { } static const char* vl_time_str(int scale) { static const char* const names[] - = {"1s", "100ms", "10ms", "1ms", "100us", "10us", "1us", "100ns", - "10ns", "1ns", "100ps", "10ps", "1ps", "100fs", "10fs", "1fs"}; - if (scale < 0) scale = -scale; - if (VL_UNLIKELY(scale > 15)) scale = 0; - return names[scale]; + = {"100s", "10s", "1s", "100ms", "10ms", "1ms", "100us", "10us", "1us", + "100ns", "10ns", "1ns", "100ps", "10ps", "1ps", "100fs", "10fs", "1fs"}; + if (VL_UNLIKELY(scale > 2 || scale < -15)) scale = 0; + return names[2 - scale]; } double vl_time_multiplier(int scale) { - // Return timescale multipler -15 to +15 + // Return timescale multipler -18 to +18 // For speed, this does not check for illegal values - static double pow10[] = {1.0, - 10.0, - 100.0, - 1000.0, - 10000.0, - 100000.0, - 1000000.0, - 10000000.0, - 100000000.0, - 1000000000.0, - 10000000000.0, - 100000000000.0, - 1000000000000.0, - 10000000000000.0, - 100000000000000.0, - 1000000000000000.0}; - static double neg10[] = {1.0, - 0.1, - 0.01, - 0.001, - 0.0001, - 0.00001, - 0.000001, - 0.0000001, - 0.00000001, - 0.000000001, - 0.0000000001, - 0.00000000001, - 0.000000000001, - 0.0000000000001, - 0.00000000000001, - 0.000000000000001}; if (scale < 0) { + static const double neg10[] = {1.0, + 0.1, + 0.01, + 0.001, + 0.0001, + 0.00001, + 0.000001, + 0.0000001, + 0.00000001, + 0.000000001, + 0.0000000001, + 0.00000000001, + 0.000000000001, + 0.0000000000001, + 0.00000000000001, + 0.000000000000001, + 0.0000000000000001, + 0.00000000000000001, + 0.000000000000000001}; return neg10[-scale]; } else { + static const double pow10[] = {1.0, + 10.0, + 100.0, + 1000.0, + 10000.0, + 100000.0, + 1000000.0, + 10000000.0, + 100000000.0, + 1000000000.0, + 10000000000.0, + 100000000000.0, + 1000000000000.0, + 10000000000000.0, + 100000000000000.0, + 1000000000000000.0, + 10000000000000000.0, + 100000000000000000.0, + 1000000000000000000.0}; return pow10[scale]; } } @@ -2085,7 +2125,7 @@ Verilated::ThreadLocal::ThreadLocal() Verilated::ThreadLocal::~ThreadLocal() {} void Verilated::debug(int level) VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); s_s.s_debug = level; if (level) { #ifdef VL_DEBUG @@ -2099,49 +2139,49 @@ void Verilated::debug(int level) VL_MT_SAFE { } } void Verilated::randReset(int val) VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); s_s.s_randReset = val; } void Verilated::randSeed(int val) VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); s_s.s_randSeed = val; } void Verilated::calcUnusedSigs(bool flag) VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); s_s.s_calcUnusedSigs = flag; } void Verilated::errorCount(int val) VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); s_s.s_errorCount = val; } void Verilated::errorCountInc() VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); ++s_s.s_errorCount; } void Verilated::errorLimit(int val) VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); s_s.s_errorLimit = val; } void Verilated::gotFinish(bool flag) VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); s_s.s_gotFinish = flag; } void Verilated::assertOn(bool flag) VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); s_s.s_assertOn = flag; } void Verilated::fatalOnVpiError(bool flag) VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); s_s.s_fatalOnVpiError = flag; } void Verilated::timeunit(int value) VL_MT_SAFE { if (value < 0) value = -value; // Stored as 0..15 - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); s_s.s_timeunit = value; } void Verilated::timeprecision(int value) VL_MT_SAFE { if (value < 0) value = -value; // Stored as 0..15 - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); s_s.s_timeprecision = value; #ifdef SYSTEMC_VERSION sc_time sc_res = sc_get_time_resolution(); @@ -2172,15 +2212,15 @@ void Verilated::timeprecision(int value) VL_MT_SAFE { #endif } void Verilated::profThreadsStart(vluint64_t flag) VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); s_ns.s_profThreadsStart = flag; } void Verilated::profThreadsWindow(vluint64_t flag) VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); s_ns.s_profThreadsWindow = flag; } void Verilated::profThreadsFilenamep(const char* flagp) VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); if (s_ns.s_profThreadsFilenamep) free(const_cast(s_ns.s_profThreadsFilenamep)); s_ns.s_profThreadsFilenamep = strdup(flagp); } @@ -2203,7 +2243,7 @@ const char* Verilated::catName(const char* n1, const char* n2, const char* delim } void Verilated::flushCb(VerilatedVoidCb cb) VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); if (s_flushCb == cb) { // Ok - don't duplicate } else if (!s_flushCb) { s_flushCb = cb; @@ -2214,18 +2254,22 @@ void Verilated::flushCb(VerilatedVoidCb cb) VL_MT_SAFE { } } +// When running internal code coverage (gcc --coverage, as opposed to +// verilator --coverage), dump coverage data to properly cover failing +// tests. void Verilated::flushCall() VL_MT_SAFE { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); if (s_flushCb) (*s_flushCb)(); fflush(stderr); fflush(stdout); + VL_GCOV_FLUSH(); } const char* Verilated::productName() VL_PURE { return VERILATOR_PRODUCT; } const char* Verilated::productVersion() VL_PURE { return VERILATOR_VERSION; } void Verilated::commandArgs(int argc, const char** argv) VL_MT_SAFE { - VerilatedLockGuard lock(s_args.m_argMutex); + const VerilatedLockGuard lock(s_args.m_argMutex); s_args.argc = argc; s_args.argv = argv; VerilatedImp::commandArgs(argc, argv); @@ -2301,11 +2345,11 @@ void Verilated::endOfEvalGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE { // VerilatedImp:: Methods std::string VerilatedImp::timeFormatSuffix() VL_MT_SAFE { - VerilatedLockGuard lock(s_s.m_sergMutex); + const VerilatedLockGuard lock(s_s.m_sergMutex); return s_s.m_serg.m_timeFormatSuffix; } void VerilatedImp::timeFormatSuffix(const std::string& value) VL_MT_SAFE { - VerilatedLockGuard lock(s_s.m_sergMutex); + const VerilatedLockGuard lock(s_s.m_sergMutex); s_s.m_serg.m_timeFormatSuffix = value; } void VerilatedImp::timeFormatUnits(int value) VL_MT_SAFE { s_s.m_ser.m_timeFormatUnits = value; } @@ -2315,7 +2359,7 @@ void VerilatedImp::timeFormatPrecision(int value) VL_MT_SAFE { void VerilatedImp::timeFormatWidth(int value) VL_MT_SAFE { s_s.m_ser.m_timeFormatWidth = value; } void VerilatedImp::internalsDump() VL_MT_SAFE { - VerilatedLockGuard lock(s_s.m_argMutex); + const VerilatedLockGuard lock(s_s.m_argMutex); VL_PRINTF_MT("internalsDump:\n"); versionDump(); VL_PRINTF_MT(" Argv:"); @@ -2332,12 +2376,12 @@ void VerilatedImp::versionDump() VL_MT_SAFE { } void VerilatedImp::commandArgs(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex) { - VerilatedLockGuard lock(s_s.m_argMutex); + const VerilatedLockGuard lock(s_s.m_argMutex); s_s.m_argVec.clear(); // Always clear commandArgsAddGuts(argc, argv); } void VerilatedImp::commandArgsAdd(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex) { - VerilatedLockGuard lock(s_s.m_argMutex); + const VerilatedLockGuard lock(s_s.m_argMutex); commandArgsAddGuts(argc, argv); } void VerilatedImp::commandArgsAddGuts(int argc, const char** argv) VL_REQUIRES(s_s.m_argMutex) { @@ -2444,12 +2488,12 @@ vluint32_t VerilatedVarProps::entSize() const { size_t VerilatedVarProps::totalSize() const { size_t size = entSize(); - for (int dim = 0; dim <= dims(); ++dim) size *= m_unpacked[dim].elements(); + for (int udim = 0; udim <= udims(); ++udim) size *= m_unpacked[udim].elements(); return size; } void* VerilatedVarProps::datapAdjustIndex(void* datap, int dim, int indx) const { - if (VL_UNLIKELY(dim <= 0 || dim > m_udims || dim > 3)) return NULL; + if (VL_UNLIKELY(dim <= 0 || dim > udims())) return NULL; if (VL_UNLIKELY(indx < low(dim) || indx > high(dim))) return NULL; int indxAdj = indx - low(dim); vluint8_t* bytep = reinterpret_cast(datap); @@ -2470,6 +2514,7 @@ VerilatedScope::VerilatedScope() { m_funcnumMax = 0; m_symsp = NULL; m_varsp = NULL; + m_timeunit = 0; m_type = SCOPE_OTHER; } @@ -2484,7 +2529,7 @@ VerilatedScope::~VerilatedScope() { void VerilatedScope::configure(VerilatedSyms* symsp, const char* prefixp, const char* suffixp, const char* identifier, vlsint8_t timeunit, - const Type type) VL_MT_UNSAFE { + const Type& type) VL_MT_UNSAFE { // Slowpath - called once/scope at construction // We don't want the space and reference-count access overhead of strings. m_symsp = symsp; @@ -2538,7 +2583,7 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap, if (i == 0) { var.m_packed.m_left = msb; var.m_packed.m_right = lsb; - } else if (i >= 1 && i <= 3) { + } else if (i >= 1 && i <= var.udims()) { var.m_unpacked[i - 1].m_left = msb; var.m_unpacked[i - 1].m_right = lsb; } else { diff --git a/include/verilated.h b/include/verilated.h index 06a70c978..5e25d2f35 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -337,7 +337,7 @@ public: // But internals only - called from VerilatedModule's VerilatedScope(); ~VerilatedScope(); void configure(VerilatedSyms* symsp, const char* prefixp, const char* suffixp, - const char* identifier, vlsint8_t timeunit, const Type type) VL_MT_UNSAFE; + const char* identifier, vlsint8_t timeunit, const Type& type) VL_MT_UNSAFE; void exportInsert(int finalize, const char* namep, void* cb) VL_MT_UNSAFE; void varInsert(int finalize, const char* namep, void* datap, VerilatedVarType vltype, int vlflags, int dims, ...) VL_MT_UNSAFE; @@ -365,7 +365,7 @@ public: // But internals only - called from VerilatedModule's class VerilatedHierarchy { public: - void add(VerilatedScope* fromp, VerilatedScope* top); + static void add(VerilatedScope* fromp, VerilatedScope* top); }; //=========================================================================== @@ -386,8 +386,8 @@ class Verilated { bool s_assertOn; ///< Assertions are enabled bool s_fatalOnVpiError; ///< Stop on vpi error/unsupported // Slow path - unsigned s_timeunit : 4; ///< Time unit as 0..15 - unsigned s_timeprecision : 4; ///< Time precision as 0..15 + vlsint8_t s_timeunit; ///< Time unit as 0..15 + vlsint8_t s_timeprecision; ///< Time precision as 0..15 int s_errorCount; ///< Number of errors int s_errorLimit; ///< Stop on error number int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random @@ -673,13 +673,9 @@ extern WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP r /// File I/O extern IData VL_FGETS_IXI(int obits, void* destp, IData fpi); -extern IData VL_FOPEN_S(const char* filenamep, const char* modep); -extern IData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode); -extern IData VL_FOPEN_QI(QData filename, IData mode); -inline IData VL_FOPEN_II(IData filename, IData mode) VL_MT_SAFE { - return VL_FOPEN_QI(filename, mode); -} - +extern void VL_FFLUSH_I(IData fdi); +extern IData VL_FSEEK_I(IData fdi, IData offset, IData origin); +extern IData VL_FTELL_I(IData fdi); extern void VL_FCLOSE_I(IData fdi); extern IData VL_FREAD_I(int width, int array_lsb, int array_size, void* memp, IData fpi, @@ -711,7 +707,7 @@ extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish /// Return true if data[bit] set; not 0/1 return, but 0/non-zero return. #define VL_BITISSET_I(data, bit) ((data) & (VL_UL(1) << VL_BITBIT_I(bit))) -#define VL_BITISSET_Q(data, bit) ((data) & (VL_ULL(1) << VL_BITBIT_Q(bit))) +#define VL_BITISSET_Q(data, bit) ((data) & (1ULL << VL_BITBIT_Q(bit))) #define VL_BITISSET_E(data, bit) ((data) & (VL_EUL(1) << VL_BITBIT_E(bit))) #define VL_BITISSET_W(data, bit) ((data)[VL_BITWORD_E(bit)] & (VL_EUL(1) << VL_BITBIT_E(bit))) #define VL_BITISSETLIMIT_W(data, width, bit) (((bit) < (width)) && VL_BITISSET_W(data, bit)) @@ -722,22 +718,22 @@ extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish /// Create two 32-bit words from quadword /// WData is always at least 2 words; does not clean upper bits #define VL_SET_WQ(owp, data) \ - { \ + do { \ (owp)[0] = static_cast(data); \ (owp)[1] = static_cast((data) >> VL_EDATASIZE); \ - } + } while (false) #define VL_SET_WI(owp, data) \ - { \ + do { \ (owp)[0] = static_cast(data); \ (owp)[1] = 0; \ - } + } while (false) #define VL_SET_QW(lwp) \ ((static_cast((lwp)[0])) \ | (static_cast((lwp)[1]) << (static_cast(VL_EDATASIZE)))) -#define _VL_SET_QII(ld, rd) ((static_cast(ld) << VL_ULL(32)) | static_cast(rd)) +#define _VL_SET_QII(ld, rd) ((static_cast(ld) << 32ULL) | static_cast(rd)) /// Return FILE* from IData -extern FILE* VL_CVT_I_FP(IData lhs); +extern FILE* VL_CVT_I_FP(IData lhs) VL_MT_SAFE; // clang-format off // Use a union to avoid cast-to-different-size warnings @@ -780,7 +776,7 @@ static inline IData VL_RTOI_I_D(double lhs) VL_PURE { // Sign extend such that if MSB set, we get ffff_ffff, else 0s // (Requires clean input) #define VL_SIGN_I(nbits, lhs) ((lhs) >> VL_BITBIT_I((nbits)-VL_UL(1))) -#define VL_SIGN_Q(nbits, lhs) ((lhs) >> VL_BITBIT_Q((nbits)-VL_ULL(1))) +#define VL_SIGN_Q(nbits, lhs) ((lhs) >> VL_BITBIT_Q((nbits)-1ULL)) #define VL_SIGN_E(nbits, lhs) ((lhs) >> VL_BITBIT_E((nbits)-VL_EUL(1))) #define VL_SIGN_W(nbits, rwp) \ ((rwp)[VL_BITWORD_E((nbits)-VL_EUL(1))] >> VL_BITBIT_E((nbits)-VL_EUL(1))) @@ -792,7 +788,7 @@ static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) VL_PURE { return (-((lhs) & (VL_UL(1) << (lbits - 1)))); } static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) VL_PURE { - return (-((lhs) & (VL_ULL(1) << (lbits - 1)))); + return (-((lhs) & (1ULL << (lbits - 1)))); } // Debugging prints @@ -930,8 +926,7 @@ static inline void VL_ASSIGNBIT_II(int, int bit, IData& lhsr, IData rhs) VL_PURE lhsr = ((lhsr & ~(VL_UL(1) << VL_BITBIT_I(bit))) | (rhs << VL_BITBIT_I(bit))); } static inline void VL_ASSIGNBIT_QI(int, int bit, QData& lhsr, QData rhs) VL_PURE { - lhsr = ((lhsr & ~(VL_ULL(1) << VL_BITBIT_Q(bit))) - | (static_cast(rhs) << VL_BITBIT_Q(bit))); + lhsr = ((lhsr & ~(1ULL << VL_BITBIT_Q(bit))) | (static_cast(rhs) << VL_BITBIT_Q(bit))); } static inline void VL_ASSIGNBIT_WI(int, int bit, WDataOutP owp, IData rhs) VL_MT_SAFE { EData orig = owp[VL_BITWORD_E(bit)]; @@ -949,7 +944,7 @@ static inline void VL_ASSIGNBIT_IO(int, int bit, IData& lhsr, IData) VL_PURE { lhsr = (lhsr | (VL_UL(1) << VL_BITBIT_I(bit))); } static inline void VL_ASSIGNBIT_QO(int, int bit, QData& lhsr, IData) VL_PURE { - lhsr = (lhsr | (VL_ULL(1) << VL_BITBIT_Q(bit))); + lhsr = (lhsr | (1ULL << VL_BITBIT_Q(bit))); } static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) VL_MT_SAFE { EData orig = owp[VL_BITWORD_E(bit)]; @@ -1217,6 +1212,36 @@ static inline IData VL_COUNTONES_W(int words, WDataInP lwp) VL_MT_SAFE { return r; } +// EMIT_RULE: VL_COUNTBITS_II: oclean = false; lhs clean +static inline IData VL_COUNTBITS_I(int lbits, IData lhs, IData ctrl0, IData ctrl1, + IData ctrl2) VL_PURE { + int ctrlSum = (ctrl0 & 0x1) + (ctrl1 & 0x1) + (ctrl2 & 0x1); + if (ctrlSum == 3) { + return VL_COUNTONES_I(lhs); + } else if (ctrlSum == 0) { + IData mask = (lbits == 32) ? -1 : ((1 << lbits) - 1); + return VL_COUNTONES_I(~lhs & mask); + } else { + return (lbits == 32) ? 32 : lbits; + } +} +static inline IData VL_COUNTBITS_Q(int lbits, QData lhs, IData ctrl0, IData ctrl1, + IData ctrl2) VL_PURE { + return VL_COUNTBITS_I(32, static_cast(lhs), ctrl0, ctrl1, ctrl2) + + VL_COUNTBITS_I(lbits - 32, static_cast(lhs >> 32), ctrl0, ctrl1, ctrl2); +} +#define VL_COUNTBITS_E VL_COUNTBITS_I +static inline IData VL_COUNTBITS_W(int lbits, int words, WDataInP lwp, IData ctrl0, IData ctrl1, + IData ctrl2) VL_MT_SAFE { + EData r = 0; + IData wordLbits = 32; + for (int i = 0; i < words; ++i) { + if (i == words - 1) { wordLbits = lbits % 32; } + r += VL_COUNTBITS_E(wordLbits, lwp[i], ctrl0, ctrl1, ctrl2); + } + return r; +} + static inline IData VL_ONEHOT_I(IData lhs) VL_PURE { return (((lhs & (lhs - 1)) == 0) & (lhs != 0)); } @@ -1261,7 +1286,7 @@ static inline IData VL_CLOG2_Q(QData lhs) VL_PURE { if (VL_UNLIKELY(!lhs)) return 0; lhs--; int shifts = 0; - for (; lhs != 0; ++shifts) lhs = lhs >> VL_ULL(1); + for (; lhs != 0; ++shifts) lhs = lhs >> 1ULL; return shifts; } static inline IData VL_CLOG2_W(int words, WDataInP lwp) VL_MT_SAFE { @@ -1459,8 +1484,8 @@ static inline WDataOutP VL_ADD_W(int words, WDataOutP owp, WDataInP lwp, WDataIn QData carry = 0; for (int i = 0; i < words; ++i) { carry = carry + static_cast(lwp[i]) + static_cast(rwp[i]); - owp[i] = (carry & VL_ULL(0xffffffff)); - carry = (carry >> VL_ULL(32)) & VL_ULL(0xffffffff); + owp[i] = (carry & 0xffffffffULL); + carry = (carry >> 32ULL) & 0xffffffffULL; } // Last output word is dirty return owp; @@ -1472,8 +1497,8 @@ static inline WDataOutP VL_SUB_W(int words, WDataOutP owp, WDataInP lwp, WDataIn carry = (carry + static_cast(lwp[i]) + static_cast(static_cast(~rwp[i]))); if (i == 0) ++carry; // Negation of rwp - owp[i] = (carry & VL_ULL(0xffffffff)); - carry = (carry >> VL_ULL(32)) & VL_ULL(0xffffffff); + owp[i] = (carry & 0xffffffffULL); + carry = (carry >> 32ULL) & 0xffffffffULL; } // Last output word is dirty return owp; @@ -1486,8 +1511,8 @@ static inline WDataOutP VL_MUL_W(int words, WDataOutP owp, WDataInP lwp, WDataIn QData mul = static_cast(lwp[lword]) * static_cast(rwp[rword]); for (int qword = lword + rword; qword < words; ++qword) { mul += static_cast(owp[qword]); - owp[qword] = (mul & VL_ULL(0xffffffff)); - mul = (mul >> VL_ULL(32)) & VL_ULL(0xffffffff); + owp[qword] = (mul & 0xffffffffULL); + mul = (mul >> 32ULL) & 0xffffffffULL; } } } @@ -1535,8 +1560,8 @@ static inline WDataOutP VL_MULS_WWW(int, int lbits, int, WDataOutP owp, WDataInP for (int i = 0; i < words; ++i) { carry = carry + static_cast(static_cast(~owp[i])); if (i == 0) ++carry; // Negation of temp2 - owp[i] = (carry & VL_ULL(0xffffffff)); - carry = (carry >> VL_ULL(32)) & VL_ULL(0xffffffff); + owp[i] = (carry & 0xffffffffULL); + carry = (carry >> 32ULL) & 0xffffffffULL; } // Not needed: owp[words-1] |= 1< 0) power = power * power; - if (rhs & (VL_ULL(1) << i)) out *= power; + if (rhs & (1ULL << i)) out *= power; } return out; } @@ -1635,10 +1660,10 @@ static inline QData VL_POW_QQQ(int, int, int rbits, QData lhs, QData rhs) VL_PUR if (VL_UNLIKELY(rhs == 0)) return 1; if (VL_UNLIKELY(lhs == 0)) return 0; QData power = lhs; - QData out = VL_ULL(1); + QData out = 1ULL; for (int i = 0; i < rbits; ++i) { if (i > 0) power = power * power; - if (rhs & (VL_ULL(1) << i)) out *= power; + if (rhs & (1ULL << i)) out *= power; } return out; } @@ -1884,7 +1909,8 @@ static inline IData VL_STREAML_FAST_III(int, int lbits, int, IData ld, IData rd_ case 1: ret = ((ret >> 2) & VL_UL(0x33333333)) | ((ret & VL_UL(0x33333333)) << 2); // FALLTHRU case 2: ret = ((ret >> 4) & VL_UL(0x0f0f0f0f)) | ((ret & VL_UL(0x0f0f0f0f)) << 4); // FALLTHRU case 3: ret = ((ret >> 8) & VL_UL(0x00ff00ff)) | ((ret & VL_UL(0x00ff00ff)) << 8); // FALLTHRU - case 4: ret = ((ret >> 16) | (ret << 16)); + case 4: ret = ((ret >> 16) | (ret << 16)); // FALLTHRU + default:; } return ret >> (VL_IDATASIZE - lbits); } @@ -1896,25 +1922,26 @@ static inline QData VL_STREAML_FAST_QQI(int, int lbits, int, QData ld, IData rd_ vluint32_t lbitsFloor = lbits & ~VL_MASK_I(rd_log2); vluint32_t lbitsRem = lbits - lbitsFloor; QData msbMask = VL_MASK_Q(lbitsRem) << lbitsFloor; - ret = (ret & ~msbMask) | ((ret & msbMask) << ((VL_ULL(1) << rd_log2) - lbitsRem)); + ret = (ret & ~msbMask) | ((ret & msbMask) << ((1ULL << rd_log2) - lbitsRem)); } switch (rd_log2) { case 0: - ret = (((ret >> 1) & VL_ULL(0x5555555555555555)) - | ((ret & VL_ULL(0x5555555555555555)) << 1)); // FALLTHRU + ret = (((ret >> 1) & 0x5555555555555555ULL) + | ((ret & 0x5555555555555555ULL) << 1)); // FALLTHRU case 1: - ret = (((ret >> 2) & VL_ULL(0x3333333333333333)) - | ((ret & VL_ULL(0x3333333333333333)) << 2)); // FALLTHRU + ret = (((ret >> 2) & 0x3333333333333333ULL) + | ((ret & 0x3333333333333333ULL) << 2)); // FALLTHRU case 2: - ret = (((ret >> 4) & VL_ULL(0x0f0f0f0f0f0f0f0f)) - | ((ret & VL_ULL(0x0f0f0f0f0f0f0f0f)) << 4)); // FALLTHRU + ret = (((ret >> 4) & 0x0f0f0f0f0f0f0f0fULL) + | ((ret & 0x0f0f0f0f0f0f0f0fULL) << 4)); // FALLTHRU case 3: - ret = (((ret >> 8) & VL_ULL(0x00ff00ff00ff00ff)) - | ((ret & VL_ULL(0x00ff00ff00ff00ff)) << 8)); // FALLTHRU + ret = (((ret >> 8) & 0x00ff00ff00ff00ffULL) + | ((ret & 0x00ff00ff00ff00ffULL) << 8)); // FALLTHRU case 4: - ret = (((ret >> 16) & VL_ULL(0x0000ffff0000ffff)) - | ((ret & VL_ULL(0x0000ffff0000ffff)) << 16)); // FALLTHRU - case 5: ret = ((ret >> 32) | (ret << 32)); + ret = (((ret >> 16) & 0x0000ffff0000ffffULL) + | ((ret & 0x0000ffff0000ffffULL) << 16)); // FALLTHRU + case 5: ret = ((ret >> 32) | (ret << 32)); // FALLTHRU + default:; } return ret >> (VL_QUADSIZE - lbits); } @@ -2358,14 +2385,14 @@ static inline WDataOutP VL_SEL_WWII(int obits, int lbits, int, int, WDataOutP ow /// Return QData from double (numeric) // EMIT_RULE: VL_RTOIROUND_Q_D: oclean=dirty; lclean==clean/real -static inline QData VL_RTOIROUND_Q_D(int bits, double lhs) VL_PURE { +static inline QData VL_RTOIROUND_Q_D(int, double lhs) VL_PURE { // IEEE format: [63]=sign [62:52]=exp+1023 [51:0]=mantissa // This does not need to support subnormals as they are sub-integral lhs = VL_ROUND(lhs); if (lhs == 0.0) return 0; QData q = VL_CVT_Q_D(lhs); - int lsb = static_cast((q >> VL_ULL(52)) & VL_MASK_Q(11)) - 1023 - 52; - vluint64_t mantissa = (q & VL_MASK_Q(52)) | (VL_ULL(1) << 52); + int lsb = static_cast((q >> 52ULL) & VL_MASK_Q(11)) - 1023 - 52; + vluint64_t mantissa = (q & VL_MASK_Q(52)) | (1ULL << 52); vluint64_t out = 0; if (lsb < 0) { out = mantissa >> -lsb; @@ -2385,8 +2412,8 @@ static inline WDataOutP VL_RTOIROUND_W_D(int obits, WDataOutP owp, double lhs) V VL_ZERO_W(obits, owp); if (lhs == 0.0) return owp; QData q = VL_CVT_Q_D(lhs); - int lsb = static_cast((q >> VL_ULL(52)) & VL_MASK_Q(11)) - 1023 - 52; - vluint64_t mantissa = (q & VL_MASK_Q(52)) | (VL_ULL(1) << 52); + int lsb = static_cast((q >> 52ULL) & VL_MASK_Q(11)) - 1023 - 52; + vluint64_t mantissa = (q & VL_MASK_Q(52)) | (1ULL << 52); if (lsb < 0) { VL_SET_WQ(owp, mantissa >> -lsb); } else if (lsb < obits) { diff --git a/include/verilated.mk.in b/include/verilated.mk.in index bd26a59c8..3a8487c2d 100644 --- a/include/verilated.mk.in +++ b/include/verilated.mk.in @@ -84,27 +84,29 @@ CPPFLAGS += $(VM_USER_CFLAGS) LDFLAGS += $(VM_USER_LDFLAGS) LDLIBS += $(VM_USER_LDLIBS) -# See the benchmarking section of bin/verilator. -# Support class optimizations. This includes the tracing and symbol table. -# SystemC takes minutes to optimize, thus it is off by default. -#OPT_SLOW = -# Fast path optimizations. Most time is spent in these classes. -#OPT_FAST = -Os -fstrict-aliasing -#OPT_FAST = -O -#OPT_FAST = +###################################################################### +# Optimization control. -####################################################################### -##### Aggregates +# See also the BENCHMARKING & OPTIMIZATION section of the manual. -VM_CLASSES += $(VM_CLASSES_FAST) $(VM_CLASSES_SLOW) -VM_SUPPORT += $(VM_SUPPORT_FAST) $(VM_SUPPORT_SLOW) +# Optimization flags for non performance-critical/rarely executed code. +# No optimization by default, which improves compilation speed. +OPT_SLOW = +# Optimization for performance critical/hot code. Most time is spent in these +# routines. Optimizing by default for improved execution speed. +OPT_FAST = -Os +# Optimization applied to the common run-time library used by verilated models. +# For compatibility this is called OPT_GLOBAL even though it only applies to +# files in the run-time library. Normally there should be no need for the user +# to change this as the library is small, but can have significant speed impact. +OPT_GLOBAL = -Os ####################################################################### ##### SystemC builds ifeq ($(VM_SC),1) - CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC_INCLUDE) - LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC_LIBDIR) + CPPFLAGS += $(SYSTEMC_CXX_FLAGS) $(addprefix -I, $(SYSTEMC_INCLUDE)) + LDFLAGS += $(SYSTEMC_CXX_FLAGS) $(addprefix -L, $(SYSTEMC_LIBDIR)) SC_LIBS = -lsystemc ifneq ($(wildcard $(SYSTEMC_LIBDIR)/*numeric_bit*),) # Systemc 1.2.1beta @@ -163,35 +165,39 @@ ifneq ($(VK_LIBS_THREADED),0) endif ####################################################################### -##### Stub +### Aggregates -preproc: +VM_FAST += $(VM_CLASSES_FAST) $(VM_SUPPORT_FAST) +VM_SLOW += $(VM_CLASSES_SLOW) $(VM_SUPPORT_SLOW) ####################################################################### -# Overall Objects Linking +### Overall Objects Linking -VK_CLASSES_FAST_CPP = $(addsuffix .cpp, $(VM_CLASSES_FAST)) -VK_CLASSES_SLOW_CPP = $(addsuffix .cpp, $(VM_CLASSES_SLOW)) - -VK_SUPPORT_FAST_CPP = $(addsuffix .cpp, $(VM_SUPPORT_FAST)) -VK_SUPPORT_SLOW_CPP = $(addsuffix .cpp, $(VM_SUPPORT_SLOW)) +VK_FAST_OBJS = $(addsuffix .o, $(VM_FAST)) +VK_SLOW_OBJS = $(addsuffix .o, $(VM_SLOW)) VK_USER_OBJS = $(addsuffix .o, $(VM_USER_CLASSES)) +# Note VM_GLOBAL_FAST and VM_GLOBAL_SLOW holds the files required from the +# run-time library. In practice everything is actually in VM_GLOBAL_FAST, +# but keeping the distinction for compatibility for now. VK_GLOBAL_OBJS = $(addsuffix .o, $(VM_GLOBAL_FAST) $(VM_GLOBAL_SLOW)) ifneq ($(VM_PARALLEL_BUILDS),1) - # Fast building, all .cpp's in one fell swoop - # This saves about 5 sec per module, but can be slower if only a little changes - VK_OBJS += $(VM_PREFIX)__ALLfast.o $(VM_PREFIX)__ALLslow.o - all_cpp: $(VM_PREFIX)__ALLfast.cpp $(VM_PREFIX)__ALLslow.cpp - $(VM_PREFIX)__ALLfast.cpp: $(VK_CLASSES_FAST_CPP) $(VK_SUPPORT_FAST_CPP) - $(VERILATOR_INCLUDER) -DVL_INCLUDE_OPT=include $^ > $@ - $(VM_PREFIX)__ALLslow.cpp: $(VK_CLASSES_SLOW_CPP) $(VK_SUPPORT_SLOW_CPP) + # Fast build for small designs: All .cpp files in one fell swoop. This + # saves total compute, but can be slower if only a little changes. It is + # also a lot slower for medium to large designs when the speed of the C + # compiler dominates, which in this mode is not parallelizable. + + VK_OBJS += $(VM_PREFIX)__ALL.o + $(VM_PREFIX)__ALL.cpp: $(addsuffix .cpp, $(VM_FAST) $(VM_SLOW)) $(VERILATOR_INCLUDER) -DVL_INCLUDE_OPT=include $^ > $@ + all_cpp: $(VM_PREFIX)__ALL.cpp else - #Slow way of building... Each .cpp file by itself - VK_OBJS += $(addsuffix .o, $(VM_CLASSES) $(VM_SUPPORT)) + # Parallel build: Each .cpp file by itself. This can be somewhat slower for + # very small designs and examples, but is a lot faster for large designs. + + VK_OBJS += $(VK_FAST_OBJS) $(VK_SLOW_OBJS) endif $(VM_PREFIX)__ALL.a: $(VK_OBJS) @@ -202,19 +208,16 @@ $(VM_PREFIX)__ALL.a: $(VK_OBJS) ### Compile rules ifneq ($(VM_DEFAULT_RULES),0) -$(VM_PREFIX)__ALLfast.o: $(VM_PREFIX)__ALLfast.cpp - $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $< - -$(VM_PREFIX)__ALLslow.o: $(VM_PREFIX)__ALLslow.cpp - $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $< - -# VM_GLOBAL_FAST files including verilated.o use this rule +# Anything not in $(VK_SLOW_OBJS) or $(VK_GLOBAL_OBJS), including verilated.o +# and user files passed on the Verilator command line use this rule. %.o: %.cpp $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $< -%__Slow.o: %__Slow.cpp +$(VK_SLOW_OBJS): %.o: %.cpp $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $< +$(VK_GLOBAL_OBJS): %.o: %.cpp + $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_GLOBAL) -c -o $@ $< endif #Default rule embedded in make: diff --git a/include/verilated_cov.cpp b/include/verilated_cov.cpp index 6ca5c8e25..d09aed228 100644 --- a/include/verilated_cov.cpp +++ b/include/verilated_cov.cpp @@ -94,7 +94,6 @@ private: typedef std::map IndexValueMap; typedef std::deque ItemList; -private: // MEMBERS VerilatedMutex m_mutex; ///< Protects all members ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); ///< Unique arbitrary value for values @@ -250,12 +249,12 @@ public: // PUBLIC METHODS void clear() VL_EXCLUDES(m_mutex) { Verilated::quiesce(); - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); clearGuts(); } void clearNonMatch(const char* matchp) VL_EXCLUDES(m_mutex) { Verilated::quiesce(); - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); if (matchp && matchp[0]) { ItemList newlist; for (ItemList::iterator it = m_items.begin(); it != m_items.end(); ++it) { @@ -271,7 +270,7 @@ public: } void zero() VL_EXCLUDES(m_mutex) { Verilated::quiesce(); - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); for (ItemList::const_iterator it = m_items.begin(); it != m_items.end(); ++it) { (*it)->zero(); } @@ -279,17 +278,17 @@ public: // We assume there's always call to i/f/p in that order void inserti(VerilatedCovImpItem* itemp) VL_EXCLUDES(m_mutex) { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); assert(!m_insertp); m_insertp = itemp; } void insertf(const char* filenamep, int lineno) VL_EXCLUDES(m_mutex) { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); m_insertFilenamep = filenamep; m_insertLineno = lineno; } void insertp(const char* ckeyps[MAX_KEYS], const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); assert(m_insertp); // First two key/vals are filename ckeyps[0] = "filename"; @@ -332,10 +331,10 @@ public: m_insertp->m_keys[addKeynum] = valueIndex(key); m_insertp->m_vals[addKeynum] = valueIndex(val); addKeynum++; - if (!legalKey(key)) { + if (VL_UNCOVERABLE(!legalKey(key))) { std::string msg = ("%Error: Coverage keys of one character, or letter+digit are illegal: " - + key); + + key); // LCOV_EXCL_LINE VL_FATAL_MT("", 0, "", msg.c_str()); } } @@ -347,7 +346,7 @@ public: void write(const char* filename) VL_EXCLUDES(m_mutex) { Verilated::quiesce(); - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); #ifndef VM_COVERAGE VL_FATAL_MT("", 0, "", "%Error: Called VerilatedCov::write when VM_COVERAGE disabled\n"); #endif @@ -475,11 +474,11 @@ void VerilatedCov::_insertp(A(0), A(1), A(2), A(3), A(4), A(5), A(6), A(7), A(8) } // Backward compatibility for Verilator void VerilatedCov::_insertp(A(0), A(1), K(2), int val2, K(3), int val3, K(4), - const std::string& val4, A(5), A(6)) VL_MT_SAFE { + const std::string& val4, A(5), A(6), A(7)) VL_MT_SAFE { std::string val2str = vlCovCvtToStr(val2); std::string val3str = vlCovCvtToStr(val3); _insertp(C(0), C(1), key2, val2str.c_str(), key3, val3str.c_str(), key4, val4.c_str(), C(5), - C(6), N(7), N(8), N(9), N(10), N(11), N(12), N(13), N(14), N(15), N(16), N(17), N(18), + C(6), C(7), N(8), N(9), N(10), N(11), N(12), N(13), N(14), N(15), N(16), N(17), N(18), N(19), N(20), N(21), N(22), N(23), N(24), N(25), N(26), N(27), N(28), N(29)); } #undef A diff --git a/include/verilated_cov.h b/include/verilated_cov.h index a7efa51cd..f9d036758 100644 --- a/include/verilated_cov.h +++ b/include/verilated_cov.h @@ -121,7 +121,7 @@ public: D(22), D(23), D(24), D(25), D(26), D(27), D(28), D(29)); // Backward compatibility for Verilator static void _insertp(A(0), A(1), K(2), int val2, K(3), int val3, K(4), const std::string& val4, - A(5), A(6)); + A(5), A(6), A(7)); #undef K #undef A diff --git a/include/verilated_cov_key.h b/include/verilated_cov_key.h index a2807eb5d..d4788d435 100644 --- a/include/verilated_cov_key.h +++ b/include/verilated_cov_key.h @@ -38,6 +38,7 @@ VLCOVGEN_ITEM("name=>'filename', short=>'f', group=>1, default=>undef, descr VLCOVGEN_ITEM("name=>'groupdesc', short=>'d', group=>1, default=>'', descr=>'Description of the covergroup this item belongs to'") VLCOVGEN_ITEM("name=>'groupname', short=>'g', group=>1, default=>'', descr=>'Group name of the covergroup this item belongs to'") VLCOVGEN_ITEM("name=>'groupcmt', short=>'O', group=>1, default=>'', ") +VLCOVGEN_ITEM("name=>'linescov', short=>'S', group=>1, default=>'', descr=>'List of comma-separated lines covered'") VLCOVGEN_ITEM("name=>'per_instance',short=>'P', group=>1, default=>0, descr=>'True if every hierarchy is independently counted; otherwise all hierarchies will be combined into a single count'") VLCOVGEN_ITEM("name=>'row0_name', short=>'R0', group=>1, default=>undef, descr=>'The row title for the header line of this row'") VLCOVGEN_ITEM("name=>'row1_name', short=>'R1', group=>1, default=>undef, ") @@ -80,6 +81,7 @@ VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr #define VL_CIK_HIER "h" #define VL_CIK_LIMIT "L" #define VL_CIK_LINENO "l" +#define VL_CIK_LINESCOV "S" #define VL_CIK_PER_INSTANCE "P" #define VL_CIK_ROW0 "r0" #define VL_CIK_ROW0_NAME "R0" @@ -121,6 +123,7 @@ public: if (key == "hier") return VL_CIK_HIER; if (key == "limit") return VL_CIK_LIMIT; if (key == "lineno") return VL_CIK_LINENO; + if (key == "linescov") return VL_CIK_LINESCOV; if (key == "per_instance") return VL_CIK_PER_INSTANCE; if (key == "row0") return VL_CIK_ROW0; if (key == "row0_name") return VL_CIK_ROW0_NAME; diff --git a/include/verilated_dpi.cpp b/include/verilated_dpi.cpp index 6c6d99a63..909a9cc2a 100644 --- a/include/verilated_dpi.cpp +++ b/include/verilated_dpi.cpp @@ -47,7 +47,7 @@ // Function requires a "context" in the import declaration #define _VL_SVDPI_CONTEXT_WARN() \ _VL_SVDPI_WARN("%%Warning: DPI C Function called by Verilog DPI import with missing " \ - "'context' keyword.\n"); + "'context' keyword.\n") //====================================================================== //====================================================================== @@ -416,7 +416,7 @@ static svBit _vl_svGetBitArrElem(const svOpenArrayHandle s, int nargs, int indx1 case VLVT_UINT16: return (*(reinterpret_cast(datap)) >> lsb) & 1; case VLVT_UINT32: return (*(reinterpret_cast(datap)) >> lsb) & 1; case VLVT_UINT64: - return (*(reinterpret_cast(datap)) >> static_cast(lsb)) & VL_ULL(1); + return (*(reinterpret_cast(datap)) >> static_cast(lsb)) & 1ULL; case VLVT_WDATA: { WDataOutP wdatap = (reinterpret_cast(datap)); return VL_BITRSHIFT_W(wdatap, lsb) & 1; diff --git a/include/verilated_fst_c.cpp b/include/verilated_fst_c.cpp index c54d818d8..6cc3e20de 100644 --- a/include/verilated_fst_c.cpp +++ b/include/verilated_fst_c.cpp @@ -36,17 +36,12 @@ #include "gtkwave/lz4.c" #include -#include -#include -#include #include #include -#include #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) # include #else -# include # include #endif @@ -132,15 +127,17 @@ void VerilatedFst::declDTypeEnum(int dtypenum, const char* name, vluint32_t elem m_local2fstdtype[dtypenum] = enumNum; } -void VerilatedFst::declSymbol(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, - fstVarType vartype, bool array, int arraynum, vluint32_t len, - vluint32_t bits) { +void VerilatedFst::declare(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, + fstVarType vartype, bool array, int arraynum, int msb, int lsb) { + const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1; + VerilatedTrace::declCode(code, bits, false); std::pair p = m_code2symbol.insert(std::make_pair(code, static_cast(NULL))); std::istringstream nameiss(name); - std::istream_iterator beg(nameiss), end; + std::istream_iterator beg(nameiss); + std::istream_iterator end; std::list tokens(beg, end); // Split name std::string symbol_name(tokens.back()); tokens.pop_back(); // Remove symbol name from hierarchy @@ -178,39 +175,32 @@ void VerilatedFst::declSymbol(vluint32_t code, const char* name, int dtypenum, f fstWriterEmitEnumTableRef(m_fst, enumNum); } if (p.second) { // New - p.first->second = fstWriterCreateVar(m_fst, vartype, vardir, len, name_str.c_str(), 0); + p.first->second = fstWriterCreateVar(m_fst, vartype, vardir, bits, name_str.c_str(), 0); assert(p.first->second); } else { // Alias - fstWriterCreateVar(m_fst, vartype, vardir, len, name_str.c_str(), p.first->second); + fstWriterCreateVar(m_fst, vartype, vardir, bits, name_str.c_str(), p.first->second); } } void VerilatedFst::declBit(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, fstVarType vartype, bool array, int arraynum) { - declSymbol(code, name, dtypenum, vardir, vartype, array, arraynum, 1, 1); + declare(code, name, dtypenum, vardir, vartype, array, arraynum, 0, 0); } void VerilatedFst::declBus(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, fstVarType vartype, bool array, int arraynum, int msb, int lsb) { - declSymbol(code, name, dtypenum, vardir, vartype, array, arraynum, msb - lsb + 1, - msb - lsb + 1); + declare(code, name, dtypenum, vardir, vartype, array, arraynum, msb, lsb); } void VerilatedFst::declQuad(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, fstVarType vartype, bool array, int arraynum, int msb, int lsb) { - declSymbol(code, name, dtypenum, vardir, vartype, array, arraynum, msb - lsb + 1, - msb - lsb + 1); + declare(code, name, dtypenum, vardir, vartype, array, arraynum, msb, lsb); } void VerilatedFst::declArray(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, fstVarType vartype, bool array, int arraynum, int msb, int lsb) { - declSymbol(code, name, dtypenum, vardir, vartype, array, arraynum, msb - lsb + 1, - msb - lsb + 1); -} -void VerilatedFst::declFloat(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, - fstVarType vartype, bool array, int arraynum) { - declSymbol(code, name, dtypenum, vardir, vartype, array, arraynum, 1, 32); + declare(code, name, dtypenum, vardir, vartype, array, arraynum, msb, lsb); } void VerilatedFst::declDouble(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, fstVarType vartype, bool array, int arraynum) { - declSymbol(code, name, dtypenum, vardir, vartype, array, arraynum, 2, 64); + declare(code, name, dtypenum, vardir, vartype, array, arraynum, 63, 0); } // Note: emit* are only ever called from one place (full* in @@ -266,11 +256,6 @@ void VerilatedFst::emitWData(vluint32_t code, const WData* newvalp, int bits) { fstWriterEmitValueChange(m_fst, m_symbolp[code], m_strbuf); } -VL_ATTR_ALWINLINE -void VerilatedFst::emitFloat(vluint32_t code, float newval) { - fstWriterEmitValueChange(m_fst, m_symbolp[code], &newval); -} - VL_ATTR_ALWINLINE void VerilatedFst::emitDouble(vluint32_t code, double newval) { fstWriterEmitValueChange(m_fst, m_symbolp[code], &newval); diff --git a/include/verilated_fst_c.h b/include/verilated_fst_c.h index c2b0605c7..9b935f763 100644 --- a/include/verilated_fst_c.h +++ b/include/verilated_fst_c.h @@ -55,8 +55,8 @@ private: // CONSTRUCTORS VL_UNCOPYABLE(VerilatedFst); - void declSymbol(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, - fstVarType vartype, bool array, int arraynum, vluint32_t len, vluint32_t bits); + void declare(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, + fstVarType vartype, bool array, int arraynum, int msb, int lsb); protected: //========================================================================= @@ -77,7 +77,6 @@ protected: inline void emitIData(vluint32_t code, IData newval, int bits); inline void emitQData(vluint32_t code, QData newval, int bits); inline void emitWData(vluint32_t code, const WData* newvalp, int bits); - inline void emitFloat(vluint32_t code, float newval); inline void emitDouble(vluint32_t code, double newval); public: @@ -112,8 +111,6 @@ public: fstVarType vartype, bool array, int arraynum, int msb, int lsb); void declArray(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, fstVarType vartype, bool array, int arraynum, int msb, int lsb); - void declFloat(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, - fstVarType vartype, bool array, int arraynum); void declDouble(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, fstVarType vartype, bool array, int arraynum); }; diff --git a/include/verilated_heavy.h b/include/verilated_heavy.h index ee71d867d..03df61629 100644 --- a/include/verilated_heavy.h +++ b/include/verilated_heavy.h @@ -427,7 +427,8 @@ extern std::string VL_TOLOWER_NN(const std::string& ld); extern std::string VL_TOUPPER_NN(const std::string& ld); extern IData VL_FERROR_IN(IData fpi, std::string& outputr) VL_MT_SAFE; -extern IData VL_FOPEN_NI(const std::string& filename, IData mode) VL_MT_SAFE; +extern IData VL_FOPEN_NN(const std::string& filename, const std::string& mode) VL_MT_SAFE; +extern IData VL_FOPEN_MCD_N(const std::string& filename) VL_MT_SAFE; extern void VL_READMEM_N(bool hex, int bits, QData depth, int array_lsb, const std::string& filename, void* memp, QData start, QData end) VL_MT_SAFE; diff --git a/include/verilated_imp.h b/include/verilated_imp.h index d8cb73785..0260a4154 100644 --- a/include/verilated_imp.h +++ b/include/verilated_imp.h @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef VL_THREADED # include # include @@ -95,7 +96,7 @@ public: // METHODS //// Add message to queue (called by producer) void post(const VerilatedMsg& msg) VL_EXCLUDES(m_mutex) { - VerilatedLockGuard lock(m_mutex); + const VerilatedLockGuard lock(m_mutex); m_queue.insert(msg); // Pass by value to copy the message into queue ++m_depth; } @@ -168,6 +169,24 @@ public: }; #endif // VL_THREADED +// FILE* list constructed from a file-descriptor +class VerilatedFpList { + FILE* m_fp[31]; + std::size_t m_sz; + +public: + typedef FILE* const* const_iterator; + explicit VerilatedFpList() + : m_sz(0) {} + const_iterator begin() const { return m_fp; } + const_iterator end() const { return m_fp + m_sz; } + std::size_t size() const { return m_sz; } + std::size_t capacity() const { return 31; } + void push_back(FILE* fd) { + if (VL_LIKELY(size() < capacity())) m_fp[m_sz++] = fd; + } +}; + //====================================================================== // VerilatedImp @@ -229,17 +248,21 @@ protected: VerilatedMutex m_fdMutex; ///< Protect m_fdps, m_fdFree std::vector m_fdps VL_GUARDED_BY(m_fdMutex); ///< File descriptors /// List of free descriptors (SLOW - FOPEN/CLOSE only) - std::deque m_fdFree VL_GUARDED_BY(m_fdMutex); + std::vector m_fdFree VL_GUARDED_BY(m_fdMutex); + // List of free descriptors in the MCT region [4, 32) + std::vector m_fdFreeMct VL_GUARDED_BY(m_fdMutex); public: // But only for verilated*.cpp // CONSTRUCTORS VerilatedImp() : m_argVecLoaded(false) , m_exportNext(0) { - m_fdps.resize(3); - m_fdps[0] = stdin; - m_fdps[1] = stdout; - m_fdps[2] = stderr; + s_s.m_fdps.resize(31); + std::fill(s_s.m_fdps.begin(), s_s.m_fdps.end(), (FILE*)0); + s_s.m_fdFreeMct.resize(30); + for (std::size_t i = 0, id = 1; i < s_s.m_fdFreeMct.size(); ++i, ++id) { + s_s.m_fdFreeMct[i] = id; + } } ~VerilatedImp() {} @@ -256,7 +279,7 @@ public: static void commandArgs(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex); static void commandArgsAdd(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex); static std::string argPlusMatch(const char* prefixp) VL_EXCLUDES(s_s.m_argMutex) { - VerilatedLockGuard lock(s_s.m_argMutex); + const VerilatedLockGuard lock(s_s.m_argMutex); // Note prefixp does not include the leading "+" size_t len = strlen(prefixp); if (VL_UNLIKELY(!s_s.m_argVecLoaded)) { @@ -285,7 +308,7 @@ public: // There's often many more scopes than userdata's and thus having a ~48byte // per map overhead * N scopes would take much more space and cache thrashing. static inline void userInsert(const void* scopep, void* userKey, void* userData) VL_MT_SAFE { - VerilatedLockGuard lock(s_s.m_userMapMutex); + const VerilatedLockGuard lock(s_s.m_userMapMutex); UserMap::iterator it = s_s.m_userMap.find(std::make_pair(scopep, userKey)); if (it != s_s.m_userMap.end()) { it->second = userData; @@ -294,7 +317,7 @@ public: } } static inline void* userFind(const void* scopep, void* userKey) VL_MT_SAFE { - VerilatedLockGuard lock(s_s.m_userMapMutex); + const VerilatedLockGuard lock(s_s.m_userMapMutex); UserMap::const_iterator it = s_s.m_userMap.find(std::make_pair(scopep, userKey)); if (VL_UNLIKELY(it == s_s.m_userMap.end())) return NULL; return it->second; @@ -304,7 +327,7 @@ private: /// Symbol table destruction cleans up the entries for each scope. static void userEraseScope(const VerilatedScope* scopep) VL_MT_SAFE { // Slow ok - called once/scope on destruction, so we simply iterate. - VerilatedLockGuard lock(s_s.m_userMapMutex); + const VerilatedLockGuard lock(s_s.m_userMapMutex); for (UserMap::iterator it = s_s.m_userMap.begin(); it != s_s.m_userMap.end();) { if (it->first.first == scopep) { s_s.m_userMap.erase(it++); @@ -314,7 +337,7 @@ private: } } static void userDump() VL_MT_SAFE { - VerilatedLockGuard lock(s_s.m_userMapMutex); // Avoid it changing in middle of dump + const VerilatedLockGuard lock(s_s.m_userMapMutex); // Avoid it changing in middle of dump bool first = true; for (UserMap::const_iterator it = s_s.m_userMap.begin(); it != s_s.m_userMap.end(); ++it) { if (first) { @@ -330,14 +353,14 @@ public: // But only for verilated*.cpp // METHODS - scope name static void scopeInsert(const VerilatedScope* scopep) VL_MT_SAFE { // Slow ok - called once/scope at construction - VerilatedLockGuard lock(s_s.m_nameMutex); + const VerilatedLockGuard lock(s_s.m_nameMutex); VerilatedScopeNameMap::iterator it = s_s.m_nameMap.find(scopep->name()); if (it == s_s.m_nameMap.end()) { s_s.m_nameMap.insert(it, std::make_pair(scopep->name(), scopep)); } } static inline const VerilatedScope* scopeFind(const char* namep) VL_MT_SAFE { - VerilatedLockGuard lock(s_s.m_nameMutex); + const VerilatedLockGuard lock(s_s.m_nameMutex); // If too slow, can assume this is only VL_MT_SAFE_POSINIT VerilatedScopeNameMap::const_iterator it = s_s.m_nameMap.find(namep); if (VL_UNLIKELY(it == s_s.m_nameMap.end())) return NULL; @@ -345,13 +368,13 @@ public: // But only for verilated*.cpp } static void scopeErase(const VerilatedScope* scopep) VL_MT_SAFE { // Slow ok - called once/scope at destruction - VerilatedLockGuard lock(s_s.m_nameMutex); + const VerilatedLockGuard lock(s_s.m_nameMutex); userEraseScope(scopep); VerilatedScopeNameMap::iterator it = s_s.m_nameMap.find(scopep->name()); if (it != s_s.m_nameMap.end()) s_s.m_nameMap.erase(it); } static void scopesDump() VL_MT_SAFE { - VerilatedLockGuard lock(s_s.m_nameMutex); + const VerilatedLockGuard lock(s_s.m_nameMutex); VL_PRINTF_MT(" scopesDump:\n"); for (VerilatedScopeNameMap::const_iterator it = s_s.m_nameMap.begin(); it != s_s.m_nameMap.end(); ++it) { @@ -369,7 +392,7 @@ public: // But only for verilated*.cpp // METHODS - hierarchy static void hierarchyAdd(const VerilatedScope* fromp, const VerilatedScope* top) VL_MT_SAFE { // Slow ok - called at construction for VPI accessible elements - VerilatedLockGuard lock(s_s.m_hierMapMutex); + const VerilatedLockGuard lock(s_s.m_hierMapMutex); s_s.m_hierMap[fromp].push_back(top); } static const VerilatedHierarchyMap* hierarchyMap() VL_MT_SAFE_POSTINIT { @@ -388,7 +411,7 @@ public: // But only for verilated*.cpp // miss at the cost of a multiply, and all lookups move to slowpath. static int exportInsert(const char* namep) VL_MT_SAFE { // Slow ok - called once/function at creation - VerilatedLockGuard lock(s_s.m_exportMutex); + const VerilatedLockGuard lock(s_s.m_exportMutex); ExportNameMap::iterator it = s_s.m_exportMap.find(namep); if (it == s_s.m_exportMap.end()) { s_s.m_exportMap.insert(it, std::make_pair(namep, s_s.m_exportNext++)); @@ -398,7 +421,7 @@ public: // But only for verilated*.cpp } } static int exportFind(const char* namep) VL_MT_SAFE { - VerilatedLockGuard lock(s_s.m_exportMutex); + const VerilatedLockGuard lock(s_s.m_exportMutex); ExportNameMap::const_iterator it = s_s.m_exportMap.find(namep); if (VL_LIKELY(it != s_s.m_exportMap.end())) return it->second; std::string msg = (std::string("%Error: Testbench C called ") + namep @@ -408,7 +431,7 @@ public: // But only for verilated*.cpp } static const char* exportName(int funcnum) VL_MT_SAFE { // Slowpath; find name for given export; errors only so no map to reverse-map it - VerilatedLockGuard lock(s_s.m_exportMutex); + const VerilatedLockGuard lock(s_s.m_exportMutex); for (ExportNameMap::const_iterator it = s_s.m_exportMap.begin(); it != s_s.m_exportMap.end(); ++it) { if (it->second == funcnum) return it->first; @@ -416,7 +439,7 @@ public: // But only for verilated*.cpp return "*UNKNOWN*"; } static void exportsDump() VL_MT_SAFE { - VerilatedLockGuard lock(s_s.m_exportMutex); + const VerilatedLockGuard lock(s_s.m_exportMutex); bool first = true; for (ExportNameMap::const_iterator it = s_s.m_exportMap.begin(); it != s_s.m_exportMap.end(); ++it) { @@ -448,16 +471,29 @@ public: // But only for verilated*.cpp public: // But only for verilated*.cpp // METHODS - file IO - static IData fdNew(FILE* fp) VL_MT_SAFE { + static IData fdNewMcd(const char* filenamep) VL_MT_SAFE { + const VerilatedLockGuard lock(s_s.m_fdMutex); + if (s_s.m_fdFreeMct.empty()) return 0; + IData idx = s_s.m_fdFreeMct.back(); + s_s.m_fdFreeMct.pop_back(); + s_s.m_fdps[idx] = fopen(filenamep, "w"); + if (VL_UNLIKELY(!s_s.m_fdps[idx])) return 0; + return (1 << idx); + } + static IData fdNew(const char* filenamep, const char* modep) VL_MT_SAFE { + FILE* fp = fopen(filenamep, modep); if (VL_UNLIKELY(!fp)) return 0; // Bit 31 indicates it's a descriptor not a MCD - VerilatedLockGuard lock(s_s.m_fdMutex); + const VerilatedLockGuard lock(s_s.m_fdMutex); if (s_s.m_fdFree.empty()) { // Need to create more space in m_fdps and m_fdFree - size_t start = s_s.m_fdps.size(); - s_s.m_fdps.resize(start * 2); - for (size_t i = start; i < start * 2; ++i) { - s_s.m_fdFree.push_back(static_cast(i)); + const size_t start = std::max(31ul + 1ul + 3ul, s_s.m_fdps.size()); + const size_t excess = 10; + s_s.m_fdps.resize(start + excess); + std::fill(s_s.m_fdps.begin() + start, s_s.m_fdps.end(), (FILE*)0); + s_s.m_fdFree.resize(excess); + for (std::size_t i = 0, id = start; i < s_s.m_fdFree.size(); ++i, ++id) { + s_s.m_fdFree[i] = id; } } IData idx = s_s.m_fdFree.back(); @@ -465,19 +501,83 @@ public: // But only for verilated*.cpp s_s.m_fdps[idx] = fp; return (idx | (1UL << 31)); // bit 31 indicates not MCD } - static void fdDelete(IData fdi) VL_MT_SAFE { - IData idx = VL_MASK_I(31) & fdi; - VerilatedLockGuard lock(s_s.m_fdMutex); - if (VL_UNLIKELY(!(fdi & (VL_ULL(1) << 31)) || idx >= s_s.m_fdps.size())) return; - if (VL_UNLIKELY(!s_s.m_fdps[idx])) return; // Already free - s_s.m_fdps[idx] = NULL; - s_s.m_fdFree.push_back(idx); + static void fdFlush(IData fdi) VL_MT_SAFE { + const VerilatedLockGuard lock(s_s.m_fdMutex); + const VerilatedFpList fdlist = fdToFpList(fdi); + for (VerilatedFpList::const_iterator it = fdlist.begin(); it != fdlist.end(); ++it) { + fflush(*it); + } + } + static IData fdSeek(IData fdi, IData offset, IData origin) VL_MT_SAFE { + const VerilatedLockGuard lock(s_s.m_fdMutex); + const VerilatedFpList fdlist = fdToFpList(fdi); + if (VL_UNLIKELY(fdlist.size() != 1)) return 0; + return static_cast( + fseek(*fdlist.begin(), static_cast(offset), static_cast(origin))); + } + static IData fdTell(IData fdi) VL_MT_SAFE { + const VerilatedLockGuard lock(s_s.m_fdMutex); + const VerilatedFpList fdlist = fdToFpList(fdi); + if (VL_UNLIKELY(fdlist.size() != 1)) return 0; + return static_cast(ftell(*fdlist.begin())); + } + static void fdWrite(IData fdi, const std::string& output) VL_MT_SAFE { + const VerilatedLockGuard lock(s_s.m_fdMutex); + const VerilatedFpList fdlist = fdToFpList(fdi); + for (VerilatedFpList::const_iterator it = fdlist.begin(); it != fdlist.end(); ++it) { + if (VL_UNLIKELY(!*it)) continue; + fwrite(output.c_str(), 1, output.size(), *it); + } + } + static void fdClose(IData fdi) VL_MT_SAFE { + const VerilatedLockGuard lock(s_s.m_fdMutex); + if ((fdi & (1 << 31)) != 0) { + // Non-MCD case + IData idx = VL_MASK_I(31) & fdi; + if (VL_UNLIKELY(idx >= s_s.m_fdps.size())) return; + if (VL_UNLIKELY(!s_s.m_fdps[idx])) return; // Already free + fclose(s_s.m_fdps[idx]); + s_s.m_fdps[idx] = (FILE*)0; + s_s.m_fdFree.push_back(idx); + } else { + // MCD case + for (int i = 0; (fdi != 0) && (i < 31); i++, fdi >>= 1) { + if (fdi & VL_MASK_I(1)) { + fclose(s_s.m_fdps[i]); + s_s.m_fdps[i] = NULL; + s_s.m_fdFreeMct.push_back(i); + } + } + } } static inline FILE* fdToFp(IData fdi) VL_MT_SAFE { - IData idx = VL_MASK_I(31) & fdi; - VerilatedLockGuard lock(s_s.m_fdMutex); // This might get slow, if it does we can cache it - if (VL_UNLIKELY(!(fdi & (VL_ULL(1) << 31)) || idx >= s_s.m_fdps.size())) return NULL; - return s_s.m_fdps[idx]; + const VerilatedLockGuard lock(s_s.m_fdMutex); + const VerilatedFpList fdlist = fdToFpList(fdi); + if (VL_UNLIKELY(fdlist.size() != 1)) return NULL; + return *fdlist.begin(); + } + +private: + static inline VerilatedFpList fdToFpList(IData fdi) VL_REQUIRES(s_s.m_fdMutex) { + VerilatedFpList fp; + if ((fdi & (1 << 31)) != 0) { + // Non-MCD case + const IData idx = fdi & VL_MASK_I(31); + switch (idx) { + case 0: fp.push_back(stdin); break; + case 1: fp.push_back(stdout); break; + case 2: fp.push_back(stderr); break; + default: + if (VL_LIKELY(idx < s_s.m_fdps.size())) fp.push_back(s_s.m_fdps[idx]); + break; + } + } else { + // MCD Case + for (int i = 0; (fdi != 0) && (i < fp.capacity()); ++i, fdi >>= 1) { + if (fdi & VL_MASK_I(1)) fp.push_back(s_s.m_fdps[i]); + } + } + return fp; } }; diff --git a/include/verilated_save.cpp b/include/verilated_save.cpp index 3b6e3732b..0972f513f 100644 --- a/include/verilated_save.cpp +++ b/include/verilated_save.cpp @@ -123,8 +123,8 @@ void VerilatedSave::open(const char* filenamep) VL_MT_UNSAFE_ONE { if (isOpen()) return; VL_DEBUG_IF(VL_DBG_MSGF("- save: opening save file %s\n", filenamep);); - if (filenamep[0] == '|') { - assert(0); // Not supported yet. + if (VL_UNCOVERABLE(filenamep[0] == '|')) { + assert(0); // LCOV_EXCL_LINE // Not supported yet. } else { // cppcheck-suppress duplicateExpression m_fd = ::open(filenamep, @@ -146,8 +146,8 @@ void VerilatedRestore::open(const char* filenamep) VL_MT_UNSAFE_ONE { if (isOpen()) return; VL_DEBUG_IF(VL_DBG_MSGF("- restore: opening restore file %s\n", filenamep);); - if (filenamep[0] == '|') { - assert(0); // Not supported yet. + if (VL_UNCOVERABLE(filenamep[0] == '|')) { + assert(0); // LCOV_EXCL_LINE // Not supported yet. } else { // cppcheck-suppress duplicateExpression m_fd = ::open(filenamep, O_CREAT | O_RDONLY | O_LARGEFILE | O_CLOEXEC, 0666); @@ -194,13 +194,15 @@ void VerilatedSave::flush() VL_MT_UNSAFE_ONE { ssize_t got = ::write(m_fd, wp, remaining); if (got > 0) { wp += got; - } else if (got < 0) { - if (errno != EAGAIN && errno != EINTR) { + } else if (VL_UNCOVERABLE(got < 0)) { + if (VL_UNCOVERABLE(errno != EAGAIN && errno != EINTR)) { + // LCOV_EXCL_START // write failed, presume error (perhaps out of disk space) std::string msg = std::string(__FUNCTION__) + ": " + strerror(errno); VL_FATAL_MT("", 0, "", msg.c_str()); close(); break; + // LCOV_EXCL_STOP } } } @@ -223,13 +225,15 @@ void VerilatedRestore::fill() VL_MT_UNSAFE_ONE { ssize_t got = ::read(m_fd, m_endp, remaining); if (got > 0) { m_endp += got; - } else if (got < 0) { - if (errno != EAGAIN && errno != EINTR) { + } else if (VL_UNCOVERABLE(got < 0)) { + if (VL_UNCOVERABLE(errno != EAGAIN && errno != EINTR)) { + // LCOV_EXCL_START // write failed, presume error (perhaps out of disk space) std::string msg = std::string(__FUNCTION__) + ": " + strerror(errno); VL_FATAL_MT("", 0, "", msg.c_str()); close(); break; + // LCOV_EXCL_STOP } } else { // got==0, EOF // Fill buffer from here to end with NULLs so reader's don't diff --git a/include/verilated_sym_props.h b/include/verilated_sym_props.h index bc1dfdd94..e95b67ad6 100644 --- a/include/verilated_sym_props.h +++ b/include/verilated_sym_props.h @@ -29,6 +29,8 @@ #include "verilatedos.h" +#include + //=========================================================================== /// Verilator range /// Thread safety: Assume is constructed only with model, then any number of readers @@ -78,7 +80,14 @@ class VerilatedVarProps { const int m_pdims; // Packed dimensions const int m_udims; // Unpacked dimensions VerilatedRange m_packed; // Packed array range - VerilatedRange m_unpacked[3]; // Unpacked array range + std::vector m_unpacked; // Unpacked array ranges + void initUnpacked(const int* ulims) { + for (int i = 0; i < m_udims; ++i) { + const int left = ulims ? ulims[2 * i + 0] : 0; + const int right = ulims ? ulims[2 * i + 1] : 0; + m_unpacked.push_back(VerilatedRange(left, right)); + } + } // CONSTRUCTORS protected: friend class VerilatedScope; @@ -87,7 +96,9 @@ protected: , m_vltype(vltype) , m_vlflags(vlflags) , m_pdims(pdims) - , m_udims(udims) {} + , m_udims(udims) { + initUnpacked(NULL); + } public: class Unpacked {}; @@ -98,34 +109,13 @@ public: , m_vlflags(VerilatedVarFlags(vlflags)) , m_pdims(0) , m_udims(0) {} - VerilatedVarProps(VerilatedVarType vltype, int vlflags, Unpacked, int u0l, int u0r) + VerilatedVarProps(VerilatedVarType vltype, int vlflags, Unpacked, int udims, const int* ulims) : m_magic(MAGIC) , m_vltype(vltype) , m_vlflags(VerilatedVarFlags(vlflags)) , m_pdims(0) - , m_udims(1) { - m_unpacked[0].init(u0l, u0r); - } - VerilatedVarProps(VerilatedVarType vltype, int vlflags, Unpacked, int u0l, int u0r, int u1l, - int u1r) - : m_magic(MAGIC) - , m_vltype(vltype) - , m_vlflags(VerilatedVarFlags(vlflags)) - , m_pdims(0) - , m_udims(2) { - m_unpacked[0].init(u0l, u0r); - m_unpacked[1].init(u1l, u1r); - } - VerilatedVarProps(VerilatedVarType vltype, int vlflags, Unpacked, int u0l, int u0r, int u1l, - int u1r, int u2l, int u2r) - : m_magic(MAGIC) - , m_vltype(vltype) - , m_vlflags(VerilatedVarFlags(vlflags)) - , m_pdims(0) - , m_udims(3) { - m_unpacked[0].init(u0l, u0r); - m_unpacked[1].init(u1l, u1r); - m_unpacked[2].init(u2l, u2r); + , m_udims(udims) { + initUnpacked(ulims); } // With packed class Packed {}; @@ -137,37 +127,14 @@ public: , m_udims(0) , m_packed(pl, pr) {} VerilatedVarProps(VerilatedVarType vltype, int vlflags, Packed, int pl, int pr, Unpacked, - int u0l, int u0r) + int udims, const int* ulims) : m_magic(MAGIC) , m_vltype(vltype) , m_vlflags(VerilatedVarFlags(vlflags)) , m_pdims(1) - , m_udims(1) + , m_udims(udims) , m_packed(pl, pr) { - m_unpacked[0].init(u0l, u0r); - } - VerilatedVarProps(VerilatedVarType vltype, int vlflags, Packed, int pl, int pr, Unpacked, - int u0l, int u0r, int u1l, int u1r) - : m_magic(MAGIC) - , m_vltype(vltype) - , m_vlflags(VerilatedVarFlags(vlflags)) - , m_pdims(1) - , m_udims(2) - , m_packed(pl, pr) { - m_unpacked[0].init(u0l, u0r); - m_unpacked[1].init(u1l, u1r); - } - VerilatedVarProps(VerilatedVarType vltype, int vlflags, Packed, int pl, int pr, Unpacked, - int u0l, int u0r, int u1l, int u1r, int u2l, int u2r) - : m_magic(MAGIC) - , m_vltype(vltype) - , m_vlflags(VerilatedVarFlags(vlflags)) - , m_pdims(1) - , m_udims(3) - , m_packed(pl, pr) { - m_unpacked[0].init(u0l, u0r); - m_unpacked[1].init(u1l, u1r); - m_unpacked[2].init(u2l, u2r); + initUnpacked(ulims); } public: @@ -189,27 +156,29 @@ public: // DPI accessors int left(int dim) const { return dim == 0 ? m_packed.left() - : VL_LIKELY(dim >= 1 && dim <= 3) ? m_unpacked[dim - 1].left() : 0; + : VL_LIKELY(dim >= 1 && dim <= udims()) ? m_unpacked[dim - 1].left() : 0; } int right(int dim) const { return dim == 0 ? m_packed.right() - : VL_LIKELY(dim >= 1 && dim <= 3) ? m_unpacked[dim - 1].right() : 0; + : VL_LIKELY(dim >= 1 && dim <= udims()) ? m_unpacked[dim - 1].right() : 0; } int low(int dim) const { return dim == 0 ? m_packed.low() - : VL_LIKELY(dim >= 1 && dim <= 3) ? m_unpacked[dim - 1].low() : 0; + : VL_LIKELY(dim >= 1 && dim <= udims()) ? m_unpacked[dim - 1].low() : 0; } int high(int dim) const { return dim == 0 ? m_packed.high() - : VL_LIKELY(dim >= 1 && dim <= 3) ? m_unpacked[dim - 1].high() : 0; + : VL_LIKELY(dim >= 1 && dim <= udims()) ? m_unpacked[dim - 1].high() : 0; } int increment(int dim) const { - return dim == 0 ? m_packed.increment() - : VL_LIKELY(dim >= 1 && dim <= 3) ? m_unpacked[dim - 1].increment() : 0; + return dim == 0 + ? m_packed.increment() + : VL_LIKELY(dim >= 1 && dim <= udims()) ? m_unpacked[dim - 1].increment() : 0; } int elements(int dim) const { - return dim == 0 ? m_packed.elements() - : VL_LIKELY(dim >= 1 && dim <= 3) ? m_unpacked[dim - 1].elements() : 0; + return dim == 0 + ? m_packed.elements() + : VL_LIKELY(dim >= 1 && dim <= udims()) ? m_unpacked[dim - 1].elements() : 0; } /// Total size in bytes (note DPI limited to 4GB) size_t totalSize() const; diff --git a/include/verilated_threads.cpp b/include/verilated_threads.cpp index 0ac6cee74..8bc7347d2 100644 --- a/include/verilated_threads.cpp +++ b/include/verilated_threads.cpp @@ -120,13 +120,13 @@ void VlThreadPool::setupProfilingClientThread() { // try not to malloc while collecting profiling. t_profilep->reserve(4096); { - VerilatedLockGuard lk(m_mutex); + const VerilatedLockGuard lk(m_mutex); m_allProfiles.insert(t_profilep); } } void VlThreadPool::profileAppendAll(const VlProfileRec& rec) { - VerilatedLockGuard lk(m_mutex); + const VerilatedLockGuard lk(m_mutex); for (ProfileSet::iterator it = m_allProfiles.begin(); it != m_allProfiles.end(); ++it) { // Every thread's profile trace gets a copy of rec. (*it)->emplace_back(rec); @@ -134,7 +134,7 @@ void VlThreadPool::profileAppendAll(const VlProfileRec& rec) { } void VlThreadPool::profileDump(const char* filenamep, vluint64_t ticksElapsed) { - VerilatedLockGuard lk(m_mutex); + const VerilatedLockGuard lk(m_mutex); VL_DEBUG_IF(VL_DBG_MSGF("+prof+threads writing to '%s'\n", filenamep);); FILE* fp = fopen(filenamep, "w"); diff --git a/include/verilated_threads.h b/include/verilated_threads.h index b1e5a4fd9..aee15f021 100644 --- a/include/verilated_threads.h +++ b/include/verilated_threads.h @@ -234,7 +234,7 @@ public: inline void addTask(VlExecFnp fnp, bool evenCycle, VlThrSymTab sym) { bool notify; { - VerilatedLockGuard lk(m_mutex); + const VerilatedLockGuard lk(m_mutex); m_ready.emplace_back(fnp, evenCycle, sym); m_ready_size.fetch_add(1, std::memory_order_relaxed); notify = m_waiting; diff --git a/include/verilated_trace.h b/include/verilated_trace.h index 471db6b99..8a99bf07d 100644 --- a/include/verilated_trace.h +++ b/include/verilated_trace.h @@ -40,7 +40,7 @@ // Threaded tracing // A simple synchronized first in first out queue -template class VerilatedThreadQueue { +template class VerilatedThreadQueue { // LCOV_EXCL_LINE // lcov bug private: VerilatedMutex m_mutex; // Protects m_queue std::condition_variable_any m_cv; @@ -73,7 +73,7 @@ public: // Non blocking get bool tryGet(T& result) { - VerilatedLockGuard lockGuard(m_mutex); + const VerilatedLockGuard lockGuard(m_mutex); if (m_queue.empty()) { return false; } result = m_queue.front(); m_queue.pop_front(); @@ -95,7 +95,6 @@ public: CHG_IDATA = 0x4, CHG_QDATA = 0x5, CHG_WDATA = 0x6, - CHG_FLOAT = 0x7, CHG_DOUBLE = 0x8, // TODO: full.. TIME_CHANGE = 0xd, @@ -105,8 +104,6 @@ public: }; #endif -class VerilatedTraceCallInfo; - //============================================================================= // VerilatedTrace @@ -114,13 +111,38 @@ class VerilatedTraceCallInfo; // implementations in the format specific derived class, which must be passed // as the type parameter T_Derived template class VerilatedTrace { -private: +public: //========================================================================= // Generic tracing internals + typedef void (*initCb_t)(void*, T_Derived*, uint32_t); // Type of init callbacks + typedef void (*dumpCb_t)(void*, T_Derived*); // Type of all but init callbacks + +private: + struct CallbackRecord { + // Note: would make these fields const, but some old STL implementations + // (the one in Ubuntu 14.04 with GCC 4.8.4 in particular) use the + // assignment operator on inserting into collections, so they don't work + // with const fields... + union { + initCb_t m_initCb; // The callback function + dumpCb_t m_dumpCb; // The callback function + }; + void* m_userp; // The user pointer to pass to the callback (the symbol table) + CallbackRecord(initCb_t cb, void* userp) + : m_initCb(cb) + , m_userp(userp) {} + CallbackRecord(dumpCb_t cb, void* userp) + : m_dumpCb(cb) + , m_userp(userp) {} + }; + vluint32_t* m_sigs_oldvalp; ///< Old value store vluint64_t m_timeLastDump; ///< Last time we did a dump - std::vector m_callbacks; ///< Routines to perform dumping + std::vector m_initCbs; ///< Routines to initialize traciong + std::vector m_fullCbs; ///< Routines to perform full dump + std::vector m_chgCbs; ///< Routines to perform incremental dump + std::vector m_cleanupCbs; ///< Routines to call at the end of dump bool m_fullDump; ///< Whether a full dump is required on the next call to 'dump' vluint32_t m_nextCode; ///< Next code number to assign vluint32_t m_numSignals; ///< Number of distinct signals @@ -130,6 +152,8 @@ private: double m_timeRes; ///< Time resolution (ns/ms etc) double m_timeUnit; ///< Time units (ns/ms etc) + void addCallbackRecord(std::vector& cbVec, CallbackRecord& cbRec); + // Equivalent to 'this' but is of the sub-type 'T_Derived*'. Use 'self()->' // to access duck-typed functions to avoid a virtual function call. T_Derived* self() { return static_cast(this); } @@ -209,8 +233,8 @@ protected: // These hooks are called before a full or change based dump is produced. // The return value indicates whether to proceed with the dump. - virtual bool preFullDump() { return true; } - virtual bool preChangeDump() { return true; } + virtual bool preFullDump() = 0; + virtual bool preChangeDump() = 0; public: //========================================================================= @@ -232,13 +256,13 @@ public: //========================================================================= // Non-hot path internal interface to Verilator generated code - typedef void (*callback_t)(T_Derived* tracep, void* userthis, vluint32_t code); + void addInitCb(initCb_t cb, void* userp) VL_MT_UNSAFE_ONE; + void addFullCb(dumpCb_t cb, void* userp) VL_MT_UNSAFE_ONE; + void addChgCb(dumpCb_t cb, void* userp) VL_MT_UNSAFE_ONE; + void addCleanupCb(dumpCb_t cb, void* userp) VL_MT_UNSAFE_ONE; void changeThread() { m_assertOne.changeThread(); } - void addCallback(callback_t initcb, callback_t fullcb, callback_t changecb, - void* userthis) VL_MT_UNSAFE_ONE; - void module(const std::string& name) VL_MT_UNSAFE_ONE { m_assertOne.check(); m_moduleName = name; @@ -261,7 +285,6 @@ public: // duck-typed void emitIData(vluint32_t code, IData newval, int bits) = 0; // duck-typed void emitQData(vluint32_t code, QData newval, int bits) = 0; // duck-typed void emitWData(vluint32_t code, const WData* newvalp, int bits) = 0; - // duck-typed void emitFloat(vluint32_t code, float newval) = 0; // duck-typed void emitDouble(vluint32_t code, double newval) = 0; vluint32_t* oldp(vluint32_t code) { return m_sigs_oldvalp + code; } @@ -273,7 +296,6 @@ public: void fullIData(vluint32_t* oldp, IData newval, int bits); void fullQData(vluint32_t* oldp, QData newval, int bits); void fullWData(vluint32_t* oldp, const WData* newvalp, int bits); - void fullFloat(vluint32_t* oldp, float newval); void fullDouble(vluint32_t* oldp, double newval); #ifdef VL_TRACE_THREADED @@ -319,14 +341,6 @@ public: for (int i = 0; i < (bits + 31) / 32; ++i) { *m_traceBufferWritep++ = newvalp[i]; } VL_DEBUG_IF(assert(m_traceBufferWritep <= m_traceBufferEndp);); } - inline void chgFloat(vluint32_t code, float newval) { - m_traceBufferWritep[0] = VerilatedTraceCommand::CHG_FLOAT; - m_traceBufferWritep[1] = code; - // cppcheck-suppress invalidPointerCast - *reinterpret_cast(m_traceBufferWritep + 2) = newval; - m_traceBufferWritep += 3; - VL_DEBUG_IF(assert(m_traceBufferWritep <= m_traceBufferEndp);); - } inline void chgDouble(vluint32_t code, double newval) { m_traceBufferWritep[0] = VerilatedTraceCommand::CHG_DOUBLE; m_traceBufferWritep[1] = code; @@ -374,10 +388,6 @@ public: } } } - inline void CHG(Float)(vluint32_t* oldp, float newval) { - // cppcheck-suppress invalidPointerCast - if (VL_UNLIKELY(*reinterpret_cast(oldp) != newval)) fullFloat(oldp, newval); - } inline void CHG(Double)(vluint32_t* oldp, double newval) { // cppcheck-suppress invalidPointerCast if (VL_UNLIKELY(*reinterpret_cast(oldp) != newval)) fullDouble(oldp, newval); diff --git a/include/verilated_trace_imp.cpp b/include/verilated_trace_imp.cpp index 78dc19a11..507b3b3ab 100644 --- a/include/verilated_trace_imp.cpp +++ b/include/verilated_trace_imp.cpp @@ -39,7 +39,7 @@ // Static utility functions static double timescaleToDouble(const char* unitp) { - char* endp; + char* endp = NULL; double value = strtod(unitp, &endp); // On error so we allow just "ns" to return 1e-9. if (value == 0.0 && endp == unitp) value = 1; @@ -73,31 +73,6 @@ static std::string doubleToTimescale(double value) { return valuestr; // Gets converted to string, so no ref to stack } -//============================================================================= -// Internal callback routines for each module being traced. - -// Each module that wishes to be traced registers a set of callbacks stored in -// this class. When the trace file is being constructed, this class provides -// the callback routines to be executed. -class VerilatedTraceCallInfo { -public: // This is in .cpp file so is not widely visible - typedef VerilatedTrace::callback_t callback_t; - - callback_t m_initcb; ///< Initialization Callback function - callback_t m_fullcb; ///< Full Dumping Callback function - callback_t m_changecb; ///< Incremental Dumping Callback function - void* m_userthis; ///< User data pointer for callback - vluint32_t m_code; ///< Starting code number (set later by traceInit) - // CONSTRUCTORS - VerilatedTraceCallInfo(callback_t icb, callback_t fcb, callback_t changecb, void* ut) - : m_initcb(icb) - , m_fullcb(fcb) - , m_changecb(changecb) - , m_userthis(ut) - , m_code(1) {} - ~VerilatedTraceCallInfo() {} -}; - #ifdef VL_TRACE_THREADED //========================================================================= // Buffer management @@ -196,11 +171,6 @@ template <> void VerilatedTrace::workerThreadMain() { chgWDataImpl(oldp, readp, top); readp += VL_WORDS_I(top); continue; - case VerilatedTraceCommand::CHG_FLOAT: - VL_TRACE_THREAD_DEBUG("Command CHG_FLOAT " << top); - chgFloatImpl(oldp, *reinterpret_cast(readp)); - readp += 1; - continue; case VerilatedTraceCommand::CHG_DOUBLE: VL_TRACE_THREAD_DEBUG("Command CHG_DOUBLE " << top); chgDoubleImpl(oldp, *reinterpret_cast(readp)); @@ -224,13 +194,14 @@ template <> void VerilatedTrace::workerThreadMain() { shutdown = true; break; - //=== - // Unknown command - default: + //=== + // Unknown command + default: { // LCOV_EXCL_START VL_TRACE_THREAD_DEBUG("Command UNKNOWN"); VL_PRINTF_MT("Trace command: 0x%08x\n", cmd); VL_FATAL_MT(__FILE__, __LINE__, "", "Unknown trace command"); break; + } // LCOV_EXCL_STOP } // The above switch will execute 'continue' when necessary, @@ -311,10 +282,6 @@ VerilatedTrace::VerilatedTrace() template <> VerilatedTrace::~VerilatedTrace() { if (m_sigs_oldvalp) VL_DO_CLEAR(delete[] m_sigs_oldvalp, m_sigs_oldvalp = NULL); - while (!m_callbacks.empty()) { - delete m_callbacks.back(); - m_callbacks.pop_back(); - } #ifdef VL_TRACE_THREADED close(); #endif @@ -334,11 +301,12 @@ template <> void VerilatedTrace::traceInit() VL_MT_UNSAFE { m_numSignals = 0; m_maxBits = 0; - // Call all initialize callbacks, which will call decl* for each signal. - for (vluint32_t ent = 0; ent < m_callbacks.size(); ++ent) { - VerilatedTraceCallInfo* cip = m_callbacks[ent]; - cip->m_code = nextCode(); - (cip->m_initcb)(self(), cip->m_userthis, cip->m_code); + // Call all initialize callbacks, which will: + // - Call decl* for each signal + // - Store the base code + for (vluint32_t i = 0; i < m_initCbs.size(); ++i) { + const CallbackRecord& cbr = m_initCbs[i]; + cbr.m_initCb(cbr.m_userp, self(), nextCode()); } if (expectedCodes && nextCode() != expectedCodes) { @@ -409,12 +377,12 @@ template <> void VerilatedTrace::set_time_resolution(const std::st template <> void VerilatedTrace::dump(vluint64_t timeui) { m_assertOne.check(); - if (VL_UNLIKELY(m_timeLastDump && timeui <= m_timeLastDump)) { + if (VL_UNCOVERABLE(m_timeLastDump && timeui <= m_timeLastDump)) { // LCOV_EXCL_START VL_PRINTF_MT("%%Warning: previous dump at t=%" VL_PRI64 "u, requesting t=%" VL_PRI64 "u, dump call ignored\n", m_timeLastDump, timeui); return; - } + } // LCOV_EXCL_STOP m_timeLastDump = timeui; Verilated::quiesce(); @@ -452,17 +420,22 @@ template <> void VerilatedTrace::dump(vluint64_t timeui) { // Run the callbacks if (VL_UNLIKELY(m_fullDump)) { m_fullDump = false; // No more need for next dump to be full - for (vluint32_t ent = 0; ent < m_callbacks.size(); ++ent) { - VerilatedTraceCallInfo* cip = m_callbacks[ent]; - (cip->m_fullcb)(self(), cip->m_userthis, cip->m_code); + for (vluint32_t i = 0; i < m_fullCbs.size(); ++i) { + const CallbackRecord& cbr = m_fullCbs[i]; + cbr.m_dumpCb(cbr.m_userp, self()); } } else { - for (vluint32_t ent = 0; ent < m_callbacks.size(); ++ent) { - VerilatedTraceCallInfo* cip = m_callbacks[ent]; - (cip->m_changecb)(self(), cip->m_userthis, cip->m_code); + for (vluint32_t i = 0; i < m_chgCbs.size(); ++i) { + const CallbackRecord& cbr = m_chgCbs[i]; + cbr.m_dumpCb(cbr.m_userp, self()); } } + for (vluint32_t i = 0; i < m_cleanupCbs.size(); ++i) { + const CallbackRecord& cbr = m_cleanupCbs[i]; + cbr.m_dumpCb(cbr.m_userp, self()); + } + #ifdef VL_TRACE_THREADED if (VL_LIKELY(bufferp)) { // Mark end of the trace buffer we just filled @@ -481,17 +454,32 @@ template <> void VerilatedTrace::dump(vluint64_t timeui) { // Non-hot path internal interface to Verilator generated code template <> -void VerilatedTrace::addCallback(callback_t initcb, callback_t fullcb, - callback_t changecb, - void* userthis) VL_MT_UNSAFE_ONE { +void VerilatedTrace::addCallbackRecord(std::vector& cbVec, + CallbackRecord& cbRec) { m_assertOne.check(); - if (VL_UNLIKELY(timeLastDump() != 0)) { + if (VL_UNCOVERABLE(timeLastDump() != 0)) { // LCOV_EXCL_START std::string msg = (std::string("Internal: ") + __FILE__ + "::" + __FUNCTION__ + " called with already open file"); VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str()); - } - VerilatedTraceCallInfo* cip = new VerilatedTraceCallInfo(initcb, fullcb, changecb, userthis); - m_callbacks.push_back(cip); + } // LCOV_EXCL_STOP + cbVec.push_back(cbRec); +} + +template <> void VerilatedTrace::addInitCb(initCb_t cb, void* userp) { + CallbackRecord cbr(cb, userp); + addCallbackRecord(m_initCbs, cbr); +} +template <> void VerilatedTrace::addFullCb(dumpCb_t cb, void* userp) { + CallbackRecord cbr(cb, userp); + addCallbackRecord(m_fullCbs, cbr); +} +template <> void VerilatedTrace::addChgCb(dumpCb_t cb, void* userp) { + CallbackRecord cbr(cb, userp); + addCallbackRecord(m_chgCbs, cbr); +} +template <> void VerilatedTrace::addCleanupCb(dumpCb_t cb, void* userp) { + CallbackRecord cbr(cb, userp); + addCallbackRecord(m_cleanupCbs, cbr); } //========================================================================= @@ -537,12 +525,6 @@ void VerilatedTrace::fullWData(vluint32_t* oldp, const WData* newv self()->emitWData(oldp - m_sigs_oldvalp, newvalp, bits); } -template <> void VerilatedTrace::fullFloat(vluint32_t* oldp, float newval) { - // cppcheck-suppress invalidPointerCast - *reinterpret_cast(oldp) = newval; - self()->emitFloat(oldp - m_sigs_oldvalp, newval); -} - template <> void VerilatedTrace::fullDouble(vluint32_t* oldp, double newval) { // cppcheck-suppress invalidPointerCast *reinterpret_cast(oldp) = newval; diff --git a/include/verilated_unordered_set_map.h b/include/verilated_unordered_set_map.h index 7384e6aab..f66a2bec6 100644 --- a/include/verilated_unordered_set_map.h +++ b/include/verilated_unordered_set_map.h @@ -31,8 +31,8 @@ // //************************************************************************* -#ifndef _V3_UNORDERED_SET_MAP_H_ -#define _V3_UNORDERED_SET_MAP_H_ +#ifndef _VERILATED_UNORDERED_SET_MAP_H_ +#define _VERILATED_UNORDERED_SET_MAP_H_ #include "verilatedos.h" @@ -55,6 +55,12 @@ inline size_t vl_hash_bytes(const void* vbufp, size_t nbytes) { return hash; } +template <> inline size_t vl_hash::operator()(const int& k) const { return k; } + +template <> inline bool vl_equal_to::operator()(const int& a, const int& b) const { + return a == b; +} + template <> inline size_t vl_hash::operator()(const unsigned int& k) const { return k; } @@ -225,8 +231,7 @@ public: return end(); } const_iterator end() const { - return iterator(VL_ULL(0xFFFFFFFFFFFFFFFF), const_cast(m_emptyBucket).begin(), - this); + return iterator(0xFFFFFFFFFFFFFFFFULL, const_cast(m_emptyBucket).begin(), this); } bool empty() const { return m_numElements == 0; } @@ -249,8 +254,7 @@ public: // function further. This permits the use of very fast client // hash funcs (like just returning the int or pointer value as // is!) and tolerates crappy client hash functions pretty well. - size_t mult - = hashVal * ((sizeof(size_t) == 8) ? VL_ULL(11400714819323198485) : 2654435769lu); + size_t mult = hashVal * ((sizeof(size_t) == 8) ? 11400714819323198485ULL : 2654435769lu); size_t result = (mult >> (((sizeof(size_t) == 8) ? 64 : 32) - log2Buckets)); return result; } @@ -339,7 +343,7 @@ public: } private: - size_t numBuckets() const { return (VL_ULL(1) << m_log2Buckets); } + size_t numBuckets() const { return (1ULL << m_log2Buckets); } Bucket* getBucket(size_t idx) { initBuckets(); @@ -372,7 +376,7 @@ private: new_log2Buckets = m_log2Buckets - 2; } - size_t new_num_buckets = VL_ULL(1) << new_log2Buckets; + size_t new_num_buckets = 1ULL << new_log2Buckets; Bucket* new_bucketsp = new Bucket[new_num_buckets]; for (size_t i = 0; i < numBuckets(); i++) { diff --git a/include/verilated_vcd_c.cpp b/include/verilated_vcd_c.cpp index e940ee789..2387275a5 100644 --- a/include/verilated_vcd_c.cpp +++ b/include/verilated_vcd_c.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) # include @@ -35,8 +34,6 @@ # include #endif -#include "verilated_intrinsics.h" - // SPDIFF_ON #ifndef O_LARGEFILE // For example on WIN32 @@ -88,11 +85,11 @@ private: public: static void pushVcd(VerilatedVcd* vcdp) VL_EXCLUDES(singleton().s_vcdMutex) { - VerilatedLockGuard lock(singleton().s_vcdMutex); + const VerilatedLockGuard lock(singleton().s_vcdMutex); singleton().s_vcdVecp.push_back(vcdp); } static void removeVcd(const VerilatedVcd* vcdp) VL_EXCLUDES(singleton().s_vcdMutex) { - VerilatedLockGuard lock(singleton().s_vcdMutex); + const VerilatedLockGuard lock(singleton().s_vcdMutex); VcdVec::iterator pos = find(singleton().s_vcdVecp.begin(), singleton().s_vcdVecp.end(), vcdp); if (pos != singleton().s_vcdVecp.end()) { singleton().s_vcdVecp.erase(pos); } @@ -101,7 +98,7 @@ public: // Thread safety: Although this function is protected by a mutex so // perhaps in the future we can allow tracing in separate threads, // vcdp->flush() assumes call from single thread - VerilatedLockGuard lock(singleton().s_vcdMutex); + const VerilatedLockGuard lock(singleton().s_vcdMutex); for (VcdVec::const_iterator it = singleton().s_vcdVecp.begin(); it != singleton().s_vcdVecp.end(); ++it) { VerilatedVcd* vcdp = *it; @@ -203,8 +200,8 @@ void VerilatedVcd::openNext(bool incFilename) { } m_filename = name; } - if (m_filename[0] == '|') { - assert(0); // Not supported yet. + if (VL_UNCOVERABLE(m_filename[0] == '|')) { + assert(0); // LCOV_EXCL_LINE // Not supported yet. } else { // cppcheck-suppress duplicateExpression if (!m_filep->open(m_filename)) { @@ -358,13 +355,15 @@ void VerilatedVcd::bufferFlush() VL_MT_UNSAFE_ONE { if (got > 0) { wp += got; m_wroteBytes += got; - } else if (got < 0) { - if (errno != EAGAIN && errno != EINTR) { + } else if (VL_UNCOVERABLE(got < 0)) { + if (VL_UNCOVERABLE(errno != EAGAIN && errno != EINTR)) { + // LCOV_EXCL_START // write failed, presume error (perhaps out of disk space) std::string msg = std::string("VerilatedVcd::bufferFlush: ") + strerror(errno); VL_FATAL_MT("", 0, "", msg.c_str()); closeErr(); break; + // LCOV_EXCL_STOP } } } @@ -583,9 +582,6 @@ void VerilatedVcd::declArray(vluint32_t code, const char* name, bool array, int int lsb) { declare(code, name, "wire", array, arraynum, false, true, msb, lsb); } -void VerilatedVcd::declFloat(vluint32_t code, const char* name, bool array, int arraynum) { - declare(code, name, "real", array, arraynum, false, false, 31, 0); -} void VerilatedVcd::declDouble(vluint32_t code, const char* name, bool array, int arraynum) { declare(code, name, "real", array, arraynum, false, false, 63, 0); } @@ -699,15 +695,6 @@ void VerilatedVcd::emitWData(vluint32_t code, const WData* newvalp, int bits) { finishLine(code, wp); } -VL_ATTR_ALWINLINE -void VerilatedVcd::emitFloat(vluint32_t code, float newval) { - char* wp = m_writep; - // Buffer can't overflow before sprintf; we sized during declaration - sprintf(wp, "r%.16g", static_cast(newval)); - wp += strlen(wp); - finishLine(code, wp); -} - VL_ATTR_ALWINLINE void VerilatedVcd::emitDouble(vluint32_t code, double newval) { char* wp = m_writep; @@ -742,7 +729,7 @@ void VerilatedVcd::fullQuad(vluint32_t code, const vluint64_t newval, int bits) (*(reinterpret_cast(oldp(code)))) = newval; *m_writep++ = 'b'; for (int bit = bits - 1; bit >= 0; --bit) { - *m_writep++ = ((newval & (VL_ULL(1) << bit)) ? '1' : '0'); + *m_writep++ = ((newval & (1ULL << bit)) ? '1' : '0'); } *m_writep++ = ' '; m_writep = writeCode(m_writep, code); @@ -764,7 +751,7 @@ void VerilatedVcd::fullArray(vluint32_t code, const vluint64_t* newval, int bits for (int word = 0; word < (((bits - 1) / 64) + 1); ++word) { oldp(code)[word] = newval[word]; } *m_writep++ = 'b'; for (int bit = bits - 1; bit >= 0; --bit) { - *m_writep++ = ((newval[(bit / 64)] & (VL_ULL(1) << (bit & 0x3f))) ? '1' : '0'); + *m_writep++ = ((newval[(bit / 64)] & (1ULL << (bit & 0x3f))) ? '1' : '0'); } *m_writep++ = ' '; m_writep = writeCode(m_writep, code); @@ -792,14 +779,13 @@ void VerilatedVcd::fullTriBus(vluint32_t code, const vluint32_t newval, const vl *m_writep++ = '\n'; bufferCheck(); } -void VerilatedVcd::fullTriQuad(vluint32_t code, const vluint64_t newval, const vluint32_t newtri, +void VerilatedVcd::fullTriQuad(vluint32_t code, const vluint64_t newval, const vluint64_t newtri, int bits) { (*(reinterpret_cast(oldp(code)))) = newval; (*(reinterpret_cast(oldp(code + 1)))) = newtri; *m_writep++ = 'b'; for (int bit = bits - 1; bit >= 0; --bit) { - *m_writep++ - = "01zz"[((newval >> bit) & VL_ULL(1)) | (((newtri >> bit) & VL_ULL(1)) << VL_ULL(1))]; + *m_writep++ = "01zz"[((newval >> bit) & 1ULL) | (((newtri >> bit) & 1ULL) << 1ULL)]; } *m_writep++ = ' '; m_writep = writeCode(m_writep, code); @@ -834,33 +820,6 @@ void VerilatedVcd::fullDouble(vluint32_t code, const double newval) { *m_writep++ = '\n'; bufferCheck(); } -void VerilatedVcd::fullFloat(vluint32_t code, const float newval) { - // cppcheck-suppress invalidPointerCast - (*(reinterpret_cast(oldp(code)))) = newval; - // Buffer can't overflow before sprintf; we sized during declaration - sprintf(m_writep, "r%.16g", static_cast(newval)); - m_writep += strlen(m_writep); - *m_writep++ = ' '; - m_writep = writeCode(m_writep, code); - *m_writep++ = '\n'; - bufferCheck(); -} -void VerilatedVcd::fullBitX(vluint32_t code) { - *m_writep++ = 'x'; - m_writep = writeCode(m_writep, code); - *m_writep++ = '\n'; - bufferCheck(); -} -void VerilatedVcd::fullBusX(vluint32_t code, int bits) { - *m_writep++ = 'b'; - for (int bit = bits - 1; bit >= 0; --bit) *m_writep++ = 'x'; - *m_writep++ = ' '; - m_writep = writeCode(m_writep, code); - *m_writep++ = '\n'; - bufferCheck(); -} -void VerilatedVcd::fullQuadX(vluint32_t code, int bits) { fullBusX(code, bits); } -void VerilatedVcd::fullArrayX(vluint32_t code, int bits) { fullBusX(code, bits); } #endif // VL_TRACE_VCD_OLD_API @@ -873,8 +832,6 @@ void VerilatedVcd::flush_all() VL_MT_UNSAFE_ONE { VerilatedVcdSingleton::flush_a //====================================================================== //====================================================================== -// clang-format off - #ifdef VERILATED_VCD_TEST #include @@ -882,34 +839,39 @@ vluint32_t v1, v2, s1, s2[3]; vluint32_t tri96[3]; vluint32_t tri96__tri[3]; vluint64_t quad96[2]; +vluint64_t tquad; +vluint64_t tquad__tri; vluint8_t ch; vluint64_t timestamp = 1; -double doub = 0; +double doub = 0.0; +float flo = 0.0f; -void vcdInit(VerilatedVcd* vcdp, void* userthis, vluint32_t code) { +void vcdInit(void*, VerilatedVcd* vcdp, vluint32_t) { vcdp->scopeEscape('.'); vcdp->module("top"); - vcdp->declBus(0x2, "v1",-1,5,1); - vcdp->declBus(0x3, "v2",-1,6,0); - vcdp->module("top.sub1"); - vcdp->declBit(0x4, "s1",-1); - vcdp->declBit(0x5, "ch",-1); - vcdp->module("top.sub2"); - vcdp->declArray(0x6, "s2",-1, 40,3); + /**/ vcdp->declBus(0x2, "v1", -1, 0, 5, 1); + /**/ vcdp->declBus(0x3, "v2", -1, 0, 6, 1); + /**/ vcdp->module("top.sub1"); + /***/ vcdp->declBit(0x4, "s1", -1, 0); + /***/ vcdp->declBit(0x5, "ch", -1, 0); + /**/ vcdp->module("top.sub2"); + /***/ vcdp->declArray(0x6, "s2", -1, 0, 40, 3); // Note need to add 3 for next code. vcdp->module("top2"); - vcdp->declBus(0x2, "t2v1",-1,4,1); - vcdp->declTriBit(0x10, "io1",-1); - vcdp->declTriBus(0x12, "io5",-1,4,0); - vcdp->declTriArray(0x16, "io96",-1,95,0); - // Note need to add 6 for next code. - vcdp->declDouble(0x1c, "doub",-1); - // Note need to add 2 for next code. - vcdp->declArray(0x1e, "q2",-1,95,0); - // Note need to add 4 for next code. + /**/ vcdp->declBus(0x2, "t2v1", -1, 0, 4, 1); + /**/ vcdp->declTriBit(0x10, "io1", -1, 0); + /**/ vcdp->declTriBus(0x12, "io5", -1, 0, 4, 0); + /**/ vcdp->declTriArray(0x16, "io96", -1, 0, 95, 0); + /**/ // Note need to add 6 for next code. + /**/ vcdp->declDouble(0x1c, "doub", -1, 0); + /**/ // Note need to add 2 for next code. + /**/ vcdp->declArray(0x20, "q2", -1, 0, 95, 0); + /**/ // Note need to add 4 for next code. + /**/ vcdp->declTriQuad(0x24, "tq", -1, 0, 63, 0); + /**/ // Note need to add 4 for next code. } -void vcdFull(VerilatedVcd* vcdp, void* userthis, vluint32_t code) { +void vcdFull(void*, VerilatedVcd* vcdp) { vcdp->fullBus(0x2, v1, 5); vcdp->fullBus(0x3, v2, 7); vcdp->fullBit(0x4, s1); @@ -919,10 +881,11 @@ void vcdFull(VerilatedVcd* vcdp, void* userthis, vluint32_t code) { vcdp->fullTriBus(0x12, tri96[0] & 0x1f, tri96__tri[0] & 0x1f, 5); vcdp->fullTriArray(0x16, tri96, tri96__tri, 96); vcdp->fullDouble(0x1c, doub); - vcdp->fullArray(0x1e, &quad96[0], 96); + vcdp->fullArray(0x20, &quad96[0], 96); + vcdp->fullTriQuad(0x24, tquad, tquad__tri, 64); } -void vcdChange(VerilatedVcd* vcdp, void* userthis, vluint32_t code) { +void vcdChange(void*, VerilatedVcd* vcdp) { vcdp->chgBus(0x2, v1, 5); vcdp->chgBus(0x3, v2, 7); vcdp->chgBit(0x4, s1); @@ -932,12 +895,12 @@ void vcdChange(VerilatedVcd* vcdp, void* userthis, vluint32_t code) { vcdp->chgTriBus(0x12, tri96[0] & 0x1f, tri96__tri[0] & 0x1f, 5); vcdp->chgTriArray(0x16, tri96, tri96__tri, 96); vcdp->chgDouble(0x1c, doub); - vcdp->chgArray(0x1e, &quad96[0], 96); + vcdp->chgArray(0x20, &quad96[0], 96); + vcdp->chgTriQuad(0x24, tquad, tquad__tri, 64); } -main() { - std::cout << "test: O_LARGEFILE=" << O_LARGEFILE << std::endl; - +// clang-format off +void vcdTestMain(const char* filenamep) { v1 = v2 = s1 = 0; s2[0] = s2[1] = s2[2] = 0; tri96[2] = tri96[1] = tri96[0] = 0; @@ -945,43 +908,52 @@ main() { quad96[1] = quad96[0] = 0; ch = 0; doub = 0; + tquad = tquad__tri = 0; { VerilatedVcdC* vcdp = new VerilatedVcdC; - vcdp->spTrace()->addCallback(&vcdInit, &vcdFull, &vcdChange, 0); - vcdp->open("test.vcd"); + vcdp->evcd(true); + vcdp->spTrace()->addInitCb(&vcdInit, 0); + vcdp->spTrace()->addFullCb(&vcdFull, 0); + vcdp->spTrace()->addChgCb(&vcdChange, 0); + vcdp->open(filenamep); // Dumping - vcdp->dump(timestamp++); + vcdp->dump(++timestamp); v1 = 0xfff; tri96[2] = 4; tri96[1] = 2; tri96[0] = 1; tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = ~0; // Still tri quad96[1] = 0xffffffff; quad96[0] = 0; doub = 1.5; - vcdp->dump(timestamp++); + flo = 1.4f; + vcdp->dump(++timestamp); v2 = 0x1; s2[1] = 2; tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = 0; // enable w/o data change quad96[1] = 0; quad96[0] = ~0; doub = -1.66e13; - vcdp->dump(timestamp++); + flo = 0.123f; + tquad = 0x00ff00ff00ff00ffULL; + tquad__tri = 0x0000fffff0000ffffULL; + vcdp->dump(++timestamp); ch = 2; tri96[2] = ~4; tri96[1] = ~2; tri96[0] = ~1; doub = -3.33e-13; - vcdp->dump(timestamp++); - vcdp->dump(timestamp++); + vcdp->dump(++timestamp); + vcdp->dump(++timestamp); # ifdef VERILATED_VCD_TEST_64BIT - vluint64_t bytesPerDump = VL_ULL(15); - for (vluint64_t i = 0; i < ((VL_ULL(1) << 32) / bytesPerDump); i++) { + vluint64_t bytesPerDump = 15ULL; + for (vluint64_t i = 0; i < ((1ULL << 32) / bytesPerDump); i++) { v1 = i; - vcdp->dump(timestamp++); + vcdp->dump(++timestamp); } # endif vcdp->close(); } } #endif +// clang-format on //******************************************************************** -// ;compile-command: "mkdir -p ../test_dir && cd ../test_dir && c++ -DVERILATED_VCD_TEST ../include/verilated_vcd_c.cpp -o verilated_vcd_c && ./verilated_vcd_c && cat test.vcd" +// ;compile-command: "v4make test_regress/t/t_trace_c_api.pl" // // Local Variables: // End: diff --git a/include/verilated_vcd_c.h b/include/verilated_vcd_c.h index 972c8c0e7..781183c23 100644 --- a/include/verilated_vcd_c.h +++ b/include/verilated_vcd_c.h @@ -130,7 +130,6 @@ protected: inline void emitIData(vluint32_t code, IData newval, int bits); inline void emitQData(vluint32_t code, QData newval, int bits); inline void emitWData(vluint32_t code, const WData* newvalp, int bits); - inline void emitFloat(vluint32_t code, float newval); inline void emitDouble(vluint32_t code, double newval); public: @@ -163,7 +162,6 @@ public: void declBus(vluint32_t code, const char* name, bool array, int arraynum, int msb, int lsb); void declQuad(vluint32_t code, const char* name, bool array, int arraynum, int msb, int lsb); void declArray(vluint32_t code, const char* name, bool array, int arraynum, int msb, int lsb); - void declFloat(vluint32_t code, const char* name, bool array, int arraynum); void declDouble(vluint32_t code, const char* name, bool array, int arraynum); #ifdef VL_TRACE_VCD_OLD_API @@ -195,7 +193,6 @@ public: void fullWData(vluint32_t* oldp, const WData* newvalp, int bits) { fullArray(oldp - this->oldp(0), newvalp, bits); } - void fullFloat(vluint32_t* oldp, float newval) { fullFloat(oldp - this->oldp(0), newval); } void fullDouble(vluint32_t* oldp, double newval) { fullDouble(oldp - this->oldp(0), newval); } inline void chgBit(vluint32_t* oldp, CData newval) { chgBit(oldp - this->oldp(0), newval); } @@ -214,9 +211,6 @@ public: inline void chgWData(vluint32_t* oldp, const WData* newvalp, int bits) { chgArray(oldp - this->oldp(0), newvalp, bits); } - inline void chgFloat(vluint32_t* oldp, float newval) { - chgFloat(oldp - this->oldp(0), newval); - } inline void chgDouble(vluint32_t* oldp, double newval) { chgDouble(oldp - this->oldp(0), newval); } @@ -230,20 +224,10 @@ public: void fullArray(vluint32_t code, const vluint64_t* newvalp, int bits); void fullTriBit(vluint32_t code, const vluint32_t newval, const vluint32_t newtri); void fullTriBus(vluint32_t code, const vluint32_t newval, const vluint32_t newtri, int bits); - void fullTriQuad(vluint32_t code, const vluint64_t newval, const vluint32_t newtri, int bits); + void fullTriQuad(vluint32_t code, const vluint64_t newval, const vluint64_t newtri, int bits); void fullTriArray(vluint32_t code, const vluint32_t* newvalp, const vluint32_t* newtrip, int bits); void fullDouble(vluint32_t code, const double newval); - void fullFloat(vluint32_t code, const float newval); - - /// Inside dumping routines, dump one signal as unknowns - /// Presently this code doesn't change the oldval vector. - /// Thus this is for special standalone applications that after calling - /// fullBitX, must when then value goes non-X call fullBit. - void fullBitX(vluint32_t code); - void fullBusX(vluint32_t code, int bits); - void fullQuadX(vluint32_t code, int bits); - void fullArrayX(vluint32_t code, int bits); /// Inside dumping routines, dump one signal if it has changed. /// We do want to inline these to avoid calls when the value did not change. @@ -262,7 +246,7 @@ public: inline void chgQuad(vluint32_t code, const vluint64_t newval, int bits) { vluint64_t diff = (*(reinterpret_cast(oldp(code)))) ^ newval; if (VL_UNLIKELY(diff)) { - if (VL_UNLIKELY(bits == 64 || (diff & ((VL_ULL(1) << bits) - 1)))) { + if (VL_UNLIKELY(bits == 64 || (diff & ((1ULL << bits) - 1)))) { fullQuad(code, newval, bits); } } @@ -303,12 +287,12 @@ public: } } } - inline void chgTriQuad(vluint32_t code, const vluint64_t newval, const vluint32_t newtri, + inline void chgTriQuad(vluint32_t code, const vluint64_t newval, const vluint64_t newtri, int bits) { vluint64_t diff = (((*(reinterpret_cast(oldp(code)))) ^ newval) | ((*(reinterpret_cast(oldp(code + 1)))) ^ newtri)); if (VL_UNLIKELY(diff)) { - if (VL_UNLIKELY(bits == 64 || (diff & ((VL_ULL(1) << bits) - 1)))) { + if (VL_UNLIKELY(bits == 64 || (diff & ((1ULL << bits) - 1)))) { fullTriQuad(code, newval, newtri, bits); } } @@ -329,15 +313,9 @@ public: fullDouble(code, newval); } } - inline void chgFloat(vluint32_t code, const float newval) { - // cppcheck-suppress invalidPointerCast - if (VL_UNLIKELY((*(reinterpret_cast(oldp(code)))) != newval)) { - fullFloat(code, newval); - } - } -protected: // METHODS + // Old/standalone API only void evcd(bool flag) { m_evcd = flag; } #endif // VL_TRACE_VCD_OLD_API }; @@ -405,6 +383,15 @@ public: /// Internal class access inline VerilatedVcd* spTrace() { return &m_sptrace; } + +#ifdef VL_TRACE_VCD_OLD_API + //========================================================================= + // Note: These are only for testing for backward compatibility with foreign + // code and is not used by Verilator. Do not use these as there is no + // guarantee of functionality. + /// Use evcd format + void evcd(bool flag) VL_MT_UNSAFE_ONE { m_sptrace.evcd(flag); } +#endif }; #endif // guard diff --git a/include/verilated_vcd_sc.h b/include/verilated_vcd_sc.h index 7b8ffa33e..dcadc8bc2 100644 --- a/include/verilated_vcd_sc.h +++ b/include/verilated_vcd_sc.h @@ -77,7 +77,7 @@ private: virtual void set_time_unit(int exponent10_seconds) {} // deprecated #endif #if defined(NC_SYSTEMC) || (SYSTEMC_VERSION >= 20111100) - virtual void set_time_unit(double v, sc_time_unit tu) {} + virtual void set_time_unit(double v, sc_time_unit tu) {} // LCOV_EXCL_LINE #endif //-------------------------------------------------- diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index 6d8b099a8..e4c5a2c20 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -30,7 +30,6 @@ #include #include #include -#include //====================================================================== // Internal constants @@ -50,7 +49,7 @@ // Not supported yet #define _VL_VPI_UNIMP() \ - _VL_VPI_ERROR(__FILE__, __LINE__, Verilated::catName("Unsupported VPI function: ", VL_FUNC)); + (_VL_VPI_ERROR(__FILE__, __LINE__, Verilated::catName("Unsupported VPI function: ", VL_FUNC))) //====================================================================== // Implementation @@ -136,7 +135,7 @@ public: static inline VerilatedVpioConst* castp(vpiHandle h) { return dynamic_cast(reinterpret_cast(h)); } - virtual vluint32_t type() const { return vpiUndefined; } + virtual vluint32_t type() const { return vpiConstant; } vlsint32_t num() const { return m_num; } }; @@ -377,8 +376,8 @@ struct VerilatedVpiTimedCbsCmp { /// Ordering sets keyed by time, then callback descriptor bool operator()(const std::pair& a, const std::pair& b) const { - if (a.first < b.first) return 1; - if (a.first > b.first) return 0; + if (a.first < b.first) return true; + if (a.first > b.first) return false; return a.second < b.second; } }; @@ -450,7 +449,7 @@ public: static QData cbNextDeadline() { VpioTimedCbs::const_iterator it = s_s.m_timedCbs.begin(); if (VL_LIKELY(it != s_s.m_timedCbs.end())) return it->first; - return ~VL_ULL(0); // maxquad + return ~0ULL; // maxquad } static bool callCbs(vluint32_t reason) VL_MT_UNSAFE_ONE { VpioCbList& cbObjList = s_s.m_cbObjLists[reason]; @@ -624,7 +623,7 @@ const char* VerilatedVpiError::strFromVpiVal(PLI_INT32 vpiVal) VL_MT_SAFE { "vpiRawFourStateVal", }; // clang-format on - if (vpiVal < 0) return names[0]; + if (VL_UNCOVERABLE(vpiVal < 0)) return names[0]; return names[(vpiVal <= vpiRawFourStateVal) ? vpiVal : 0]; } const char* VerilatedVpiError::strFromVpiObjType(PLI_INT32 vpiVal) VL_MT_SAFE { @@ -768,7 +767,7 @@ const char* VerilatedVpiError::strFromVpiObjType(PLI_INT32 vpiVal) VL_MT_SAFE { "vpiGenVar" }; // clang-format on - if (vpiVal < 0) return names[0]; + if (VL_UNCOVERABLE(vpiVal < 0)) return names[0]; return names[(vpiVal <= vpiGenVar) ? vpiVal : 0]; } const char* VerilatedVpiError::strFromVpiMethod(PLI_INT32 vpiVal) VL_MT_SAFE { @@ -851,7 +850,7 @@ const char* VerilatedVpiError::strFromVpiCallbackReason(PLI_INT32 vpiVal) VL_MT_ "cbAtEndOfSimTime" }; // clang-format on - if (vpiVal < 0) return names[0]; + if (VL_UNCOVERABLE(vpiVal < 0)) return names[0]; return names[(vpiVal <= cbAtEndOfSimTime) ? vpiVal : 0]; } @@ -940,7 +939,7 @@ const char* VerilatedVpiError::strFromVpiProp(PLI_INT32 vpiVal) VL_MT_SAFE { } #define CHECK_RESULT_CSTR(got, exp) \ - if (strcmp((got), (exp))) { \ + if (0 != strcmp((got), (exp))) { \ std::string msg \ = std::string("%Error: ") + "GOT = '" + got + "'" + " EXP = '" + exp + "'"; \ VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str()); \ @@ -1026,7 +1025,7 @@ vpiHandle vpi_register_cb(p_cb_data cb_data_p) { _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported callback type %s", VL_FUNC, VerilatedVpiError::strFromVpiCallbackReason(cb_data_p->reason)); return NULL; - }; + } } PLI_INT32 vpi_remove_cb(vpiHandle object) { @@ -1135,16 +1134,30 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) { _VL_VPI_ERROR_RESET(); switch (type) { case vpiLeftRange: { - VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); - if (VL_UNLIKELY(!vop)) return 0; - if (VL_UNLIKELY(!vop->rangep())) return 0; - return (new VerilatedVpioConst(vop->rangep()->left()))->castVpiHandle(); + if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) { + if (VL_UNLIKELY(!vop->rangep())) return 0; + return (new VerilatedVpioConst(vop->rangep()->left()))->castVpiHandle(); + } else if (VerilatedVpioRange* vop = VerilatedVpioRange::castp(object)) { + if (VL_UNLIKELY(!vop->rangep())) return 0; + return (new VerilatedVpioConst(vop->rangep()->left()))->castVpiHandle(); + } + _VL_VPI_WARNING(__FILE__, __LINE__, + "%s: Unsupported vpiHandle (%p) for type %s, nothing will be returned", + VL_FUNC, object, VerilatedVpiError::strFromVpiMethod(type)); + return 0; } case vpiRightRange: { - VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); - if (VL_UNLIKELY(!vop)) return 0; - if (VL_UNLIKELY(!vop->rangep())) return 0; - return (new VerilatedVpioConst(vop->rangep()->right()))->castVpiHandle(); + if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) { + if (VL_UNLIKELY(!vop->rangep())) return 0; + return (new VerilatedVpioConst(vop->rangep()->right()))->castVpiHandle(); + } else if (VerilatedVpioRange* vop = VerilatedVpioRange::castp(object)) { + if (VL_UNLIKELY(!vop->rangep())) return 0; + return (new VerilatedVpioConst(vop->rangep()->right()))->castVpiHandle(); + } + _VL_VPI_WARNING(__FILE__, __LINE__, + "%s: Unsupported vpiHandle (%p) for type %s, nothing will be returned", + VL_FUNC, object, VerilatedVpiError::strFromVpiMethod(type)); + return 0; } case vpiIndex: { VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); @@ -1361,7 +1374,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) { } case VLVT_UINT64: { QData data = *(reinterpret_cast(vop->varDatap())); - out[1].aval = static_cast(data >> VL_ULL(32)); + out[1].aval = static_cast(data >> 32ULL); out[1].bval = 0; out[0].aval = static_cast(data); out[0].bval = 0; @@ -1600,8 +1613,8 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) { VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname()); return; } - _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format %s", VL_FUNC, - VerilatedVpiError::strFromVpiVal(value_p->format)); + + _VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported vpiHandle (%p)", VL_FUNC, object); } vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p, p_vpi_time /*time_p*/, @@ -1907,6 +1920,7 @@ void vpi_put_value_array(vpiHandle /*object*/, p_vpi_arrayvalue /*arrayvalue_p*/ void vpi_get_time(vpiHandle object, p_vpi_time time_p) { VerilatedVpiImp::assertOneCheck(); + _VL_VPI_ERROR_RESET(); // cppcheck-suppress nullPointer if (VL_UNLIKELY(!time_p)) { _VL_VPI_WARNING(__FILE__, __LINE__, "Ignoring vpi_get_time with NULL value pointer"); @@ -1937,7 +1951,7 @@ void vpi_get_time(vpiHandle object, p_vpi_time time_p) { PLI_UINT32 vpi_mcd_open(PLI_BYTE8* filenamep) { VerilatedVpiImp::assertOneCheck(); _VL_VPI_ERROR_RESET(); - return VL_FOPEN_S(filenamep, "wb"); + return VL_FOPEN_NN(filenamep, "wb"); } PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd) { @@ -2072,17 +2086,19 @@ PLI_INT32 vpi_control(PLI_INT32 operation, ...) { _VL_VPI_ERROR_RESET(); switch (operation) { case vpiFinish: { - VL_FINISH_MT(__FILE__, __LINE__, "*VPI*"); + VL_FINISH_MT("", 0, "*VPI*"); return 1; } case vpiStop: { - VL_STOP_MT(__FILE__, __LINE__, "*VPI*"); - return 1; + VL_STOP_MT("", 0, "*VPI*"); + return 1; // LCOV_EXCL_LINE + } + default: { + _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported type %s, ignoring", VL_FUNC, + VerilatedVpiError::strFromVpiProp(operation)); + return 0; } } - _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported type %s, ignoring", VL_FUNC, - VerilatedVpiError::strFromVpiProp(operation)); - return 0; } vpiHandle vpi_handle_by_multi_index(vpiHandle /*obj*/, PLI_INT32 /*num_index*/, diff --git a/include/verilatedos.h b/include/verilatedos.h index 66904c460..357ee8654 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -144,30 +144,23 @@ #define VL_MT_UNSAFE_ONE ///< Comment tag that function is not threadsafe when VL_THREADED, ///< protected to make sure single-caller -#ifdef _MSC_VER -# define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant -// Was "(c##ui64)". C++11 has standardized on ULL, and MSVC now supports this. -// We propose to no longer require using this macro no sooner than June 2020. -// File an issue ASAP if this breaks anything. -#else -# define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant -#endif +#define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant (deprecated) // This is not necessarily the same as #UL, depending on what the IData typedef is. #define VL_UL(c) (static_cast(c##UL)) ///< Add appropriate suffix to 32-bit constant -#if defined(VL_CPPCHECK) || defined(__clang_analyzer__) +#if defined(VL_CPPCHECK) || defined(__clang_analyzer__) || __cplusplus < 201103L # define VL_DANGLING(var) #else -///< After e.g. delete, set variable to NULL to indicate must not use later +/// After e.g. delete, set variable to NULL to indicate must not use later # define VL_DANGLING(var) \ do { \ - (var) = NULL; \ + *const_cast(reinterpret_cast(&var)) = NULL; \ } while (false) #endif -///< Perform an e.g. delete, then set variable to NULL to indicate must not use later. -///< Unlike VL_DO_CLEAR the setting of the variable is only for debug reasons. +/// Perform an e.g. delete, then set variable to NULL to indicate must not use later. +/// Unlike VL_DO_CLEAR the setting of the variable is only for debug reasons. #define VL_DO_DANGLING(stmt, var) \ do { \ do { \ @@ -176,7 +169,7 @@ VL_DANGLING(var); \ } while (false) -///< Perform an e.g. delete, then set variable to NULL as a requirement +/// Perform an e.g. delete, then set variable to NULL as a requirement #define VL_DO_CLEAR(stmt, stmt2) \ do { \ do { \ @@ -224,6 +217,20 @@ # define VL_INLINE_OPT ///< "inline" if compiling all objects in single compiler run #endif +//========================================================================= +// Internal coverage + +#ifdef VL_GCOV +extern "C" { +void __gcov_flush(); // gcc sources gcc/gcov-io.h has the prototype +} +/// Flush internal code coverage data before e.g. abort() +# define VL_GCOV_FLUSH() \ + __gcov_flush() +#else +# define VL_GCOV_FLUSH() +#endif + //========================================================================= // Warning disabled @@ -401,7 +408,7 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type #define VL_MASK_I(nbits) (((nbits) & VL_SIZEBITS_I) ? ((1U << ((nbits) & VL_SIZEBITS_I)) - 1) : ~0) /// Mask for quads with 1's where relevant bits are (0=all bits) #define VL_MASK_Q(nbits) \ - (((nbits) & VL_SIZEBITS_Q) ? ((VL_ULL(1) << ((nbits) & VL_SIZEBITS_Q)) - VL_ULL(1)) : VL_ULL(~0)) + (((nbits) & VL_SIZEBITS_Q) ? ((1ULL << ((nbits) & VL_SIZEBITS_Q)) - 1ULL) : ~0ULL) /// Mask for EData with 1's where relevant bits are (0=all bits) #define VL_MASK_E(nbits) VL_MASK_I(nbits) #define VL_EUL(n) VL_UL(n) ///< Make constant number EData sized diff --git a/nodist/bisonreader b/nodist/bisonreader deleted file mode 100755 index 561dd77be..000000000 --- a/nodist/bisonreader +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env perl -###################################################################### -# -# Copyright 2007-2020 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 -# -###################################################################### - -# DESCRIPTION: Debugging of bison output - -use warnings; -use strict; - -my $Debug; - -my %declared; -my %used; - -my $body = 0; -my $rule = ""; -my $lineno = 0; -foreach my $line () { - $lineno++; - chomp $line; - $line =~ s!//.*$!!g; - $line =~ s!\s+! !g; - next if $line eq ''; - if ($line =~ m!^\%\%!) { - $body++; - } elsif ($body == 1) { - $rule .= $line; - if ($line =~ m!^\s*;\s*$!) { - #print "Rule: $rule\n"; - ($rule =~ /^([a-zA-Z0-9_]+)(<\S+>)?:(.*)$/) or die "%Error: No rule name: $1\n"; - my $rulename = $1; my $preaction = $3; - $declared{$rulename} = $lineno; - $preaction =~ s/\{[^\}]*\}/ /g; - #print "RULEN $rulename PA $preaction\n" if $Debug; - $rule = ''; - foreach my $ref (split /\s+/, $preaction) { - next if $ref !~ /^[a-zA-Z]/; - next if $ref eq $rulename; - if (!$used{$ref} && $declared{$ref}) { - print " %Warning: $lineno: $ref used by $rulename after declaration\n"; - } - $used{$ref} = $lineno; - print " ref $ref\n" if $Debug; - } - } - } -} - -# Local Variables: -# compile-command: "./bisonreader < ../src/verilog.y" -# End: diff --git a/nodist/code_coverage b/nodist/code_coverage index 9659bedbd..869027ecf 100755 --- a/nodist/code_coverage +++ b/nodist/code_coverage @@ -6,30 +6,71 @@ use warnings; use Cwd; use File::Copy qw(cp); use File::Path qw(mkpath); +use File::Spec; +use FindBin qw($RealBin); use Getopt::Long; +use Parallel::Forker; +use Unix::Processors; use IO::File; use Pod::Usage; use strict; use vars qw($Debug); +our $Opt_Stop = 1; +our $Opt_Fastcov = 1; +our $Exclude_Branch_Regexp; our $Exclude_Line_Regexp; +our $Remove_Gcda_Regexp; + our @Remove_Sources; our @Source_Globs; +our $Fork = new Parallel::Forker(use_sig_child => 1, poll_interval => 10*1000); +$Fork->max_proc(Unix::Processors->new->max_online * 1.5); +$SIG{CHLD} = sub { Parallel::Forker::sig_child($Fork); }; +$SIG{TERM} = sub { $Fork->kill_tree_all('TERM') if $Fork && $Fork->in_parent; die "Quitting...\n"; }; + #====================================================================== # main -our $Opt_Stage = 0; +our $Opt_Hashset; +our $opt_stages = ''; +our $Opt_Scenarios; +our %Opt_Stages; +our @Opt_Tests; autoflush STDOUT 1; autoflush STDERR 1; Getopt::Long::config("no_auto_abbrev"); if (! GetOptions( "debug" => sub { $Debug = 1; }, + "hashset=s" => \$Opt_Hashset, # driver.pl hashset "<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; }, - "stage=i" => \$Opt_Stage, + "fastcov!" => \$Opt_Fastcov, # use fastcov, not documented, for debug + "scenarios=s" => \$Opt_Scenarios, # driver.pl scenarios + "stage=s" => \$opt_stages, # starting stage number + "stages=s" => \$opt_stages, # starting stage number + "stop!" => \$Opt_Stop, # stop/do not stop on error in tests + "test=s@" => \@Opt_Tests, # test name )) { - die "%Error: Bad usage, try 'install_test --help'\n"; + die "%Error: Bad usage, try 'code_coverage --help'\n"; +} + +{ + my $start = 0; + my $end = 99; + if ($opt_stages && $opt_stages =~ /^(\d+)$/) { + $start = $end = $1; + } elsif ($opt_stages && $opt_stages =~ /^(\d+)-(\d+$)$/) { + $start = $1; $end = $2; + } elsif ($opt_stages && $opt_stages =~ /^-(\d+$)$/) { + $end = $1; + } elsif ($opt_stages && $opt_stages =~ /^(\d+)-$/) { + $start = $1; + } elsif ($opt_stages) { + die "%Error: --stages not understood: $opt_stages,"; + } + for (my $n = $start; $n <= $end; ++$n) { $Opt_Stages{$n} = 1; } } test(); @@ -41,97 +82,238 @@ sub test { -r "nodist/code_coverage.dat" or die "%Error: Run from the top of the verilator kit,"; require "./nodist/code_coverage.dat"; - if ($Opt_Stage <= 0) { - print "Stage 0: configure (coverage on)\n"; - run("make distclean"); - run("./configure --enable-longtests CXX='g++ --coverage'"); - run("make -k"); + if ($Opt_Stages{1}) { + travis_fold_start("configure"); + print "Stage 1: configure (coverage on)\n"; + run("make distclean || true"); + run("autoconf"); + # Exceptions can pollute the branch coverage data + run("./configure --enable-longtests CXX='g++ --coverage -fno-exceptions -DVL_GCOV'"); + travis_fold_end(); + } + + if ($Opt_Stages{2}) { + travis_fold_start("build"); + print "Stage 2: build\n"; + my $nproc = Unix::Processors->new->max_online; + run("make -k -j $nproc VERILATOR_NO_OPT_BUILD=1"); # The optimized versions will not collect good coverage, overwrite them run("cp bin/verilator_bin_dbg bin/verilator_bin"); run("cp bin/verilator_coverage_bin_dbg bin/verilator_coverage_bin"); + travis_fold_end(); } - if ($Opt_Stage <= 1) { - print "Stage 1: make examples (with coverage on)\n"; - run("make examples"); - run("make test_regress"); + if ($Opt_Stages{3}) { + travis_fold_start("test"); + print "Stage 3: make tests (with coverage on)\n"; + if ($#Opt_Tests < 0) { + run("make examples VERILATOR_NO_OPT_BUILD=1") + if !$Opt_Scenarios || $Opt_Scenarios =~ /dist/i; + run("make test_regress VERILATOR_NO_OPT_BUILD=1" + . ($Opt_Scenarios ? " SCENARIOS='".$Opt_Scenarios."'" : "") + . ($Opt_Hashset ? " DRIVER_HASHSET='--hashset=".$Opt_Hashset."'" : "") + . ($Opt_Stop ? '' : ' || true')); + } else { + foreach my $test (@Opt_Tests) { + if (! -f $test && -f "test_regress/t/${test}") { + $test = "test_regress/t/${test}"; + } + run($test); + } + } + travis_fold_end(); } my $cc_dir = "nodist/obj_dir/coverage"; - if ($Opt_Stage <= 2) { - print "Stage 2: Create info files under $cc_dir\n"; + if ($Opt_Stages{4}) { + travis_fold_start("gcno"); + print "Stage 4: Create gcno files under $cc_dir\n"; mkpath($cc_dir); mkpath("$cc_dir/info"); my $dats = `find . -print | grep .gcda`; + my %dats; + foreach my $dat (split '\n', $dats) { + $dats{$dat} = 1; + } + foreach my $dat (sort keys %dats) { + (my $gcno = $dat) =~ s!\.gcda$!.gcno!; + if ($dat =~ /$Remove_Gcda_Regexp/) { + # Remove .gcda/.gcno for files we don't care about before we slowly + # read them + unlink $dat; + unlink $gcno; + delete $dats{$dat}; + next; + } + } + $dats = `find . -print | grep .gcno`; + my %gcnos; + foreach my $gcno (split '\n', $dats) { + (my $gbase = $gcno) =~ s!.*/!!; + $gcnos{$gbase} = File::Spec->rel2abs($gcno); + } + # We need a matching .gcno for every .gcda, try to find a matching file elsewhere + foreach my $dat (sort keys %dats) { + (my $gcno = $dat) =~ s!\.gcda$!.gcno!; + (my $gbase = $gcno) =~ s!.*/!!; + if (!-r $gcno) { + if ($gcnos{$gbase}) { + symlink($gcnos{$gbase}, $gcno) + or die "%Error: can't ln -s $gcnos{$gbase} $gcno,"; + } else { + warn "MISSING .gcno for a .gcda: $gcno\n"; + } + } + } + travis_fold_end(); + } + + if ($Opt_Stages{5} && $Opt_Fastcov) { + travis_fold_start("fastcov"); + # Must run in root directory to find all files + mkpath($cc_dir); + #run("${RealBin}/fastcov.py -b -c src/obj_dbg -X". + # " --exclude /usr --exclude test_regress" + # ." -o ${cc_dir}/app_total.json"); + run("${RealBin}/fastcov.py -b -c src/obj_dbg -X --lcov". + " --exclude /usr --exclude test_regress" + ." -o ${cc_dir}/app_total.info"); + travis_fold_end(); + } + + if ($Opt_Stages{5} && !$Opt_Fastcov) { + travis_fold_start("infos"); + print "Stage 5: make infos\n"; + my $dats = `find . -print | grep .gcda`; my %dirs; foreach my $dat (split '\n', $dats) { - $dat =~ s!/[^/]+$!!; - $dirs{$dat} = 1; + (my $dir = $dat) =~ s!/[^/]+$!!; + $dirs{$dir} = 1; } + foreach my $dir (sort keys %dirs) { (my $outname = $dir) =~ s![^a-zA-Z0-9]+!_!g; - run("cd $cc_dir/info ; lcov -c -d ../../../../$dir -o app_test_${outname}.info"); + $Fork->schedule(run_on_start => sub { + # .info may be empty, so ignore errors (unfortunately) + run("cd $cc_dir/info ; lcov -c -d ../../../../$dir --exclude /usr -o app_test_${outname}.info || true"); + })->run; } + $Fork->wait_all; + travis_fold_end(); } - if ($Opt_Stage <= 3) { - # lcov doesn't have a control file to override single lines, so replicate the sources - print "Stage 3: Clone sources under $cc_dir\n"; + if ($Opt_Stages{6}) { + travis_fold_start("clone"); + # No control file to override single lines, so replicate the sources + # Also lets us see the insertion markers in the HTML source res + print "Stage 6: Clone sources under $cc_dir\n"; clone_sources($cc_dir); + travis_fold_end(); } - if ($Opt_Stage <= 4) { - print "Stage 4: Copy .gcno files\n"; + if ($Opt_Stages{8} && !$Opt_Fastcov) { + travis_fold_start("copy"); + print "Stage 8: Copy .gcno files\n"; my $dats = `find . -print | grep .gcno`; - foreach my $dat (split '\n', $dats) { + foreach my $dat (sort (split '\n', $dats)) { next if $dat =~ /$cc_dir/; my $outdat = $cc_dir."/".$dat; #print "cp $dat, $outdat);\n"; cp($dat, $outdat); } + travis_fold_end(); } - if ($Opt_Stage <= 5) { - print "Stage 5: Combine data files\n"; - run("cd $cc_dir ; lcov -c -i -d src/obj_dbg -o app_base.info"); - run("cd $cc_dir ; lcov -a app_base.info -o app_total.info"); - my $infos = `cd $cc_dir ; find info -print | grep .info`; - my $comb = ""; - my @infos = (split /\n/, $infos); - foreach my $info (@infos) { - $comb .= " -a $info"; - # Need to batch them to avoid overrunning shell command length limit - if (length($comb) > 10000 || $info eq $infos[$#infos]) { - run("cd $cc_dir ; lcov -a app_total.info $comb -o app_total.info"); - $comb = ""; + if ($Opt_Stages{10} && !$Opt_Fastcov) { + travis_fold_start("combine"); + print "Stage 10: Combine data files\n"; + { + run("cd $cc_dir ; lcov -c -i -d src/obj_dbg -o app_base.info"); + run("cd $cc_dir ; lcov -a app_base.info -o app_total.info"); + my $infos = `cd $cc_dir ; find info -print | grep .info`; + my $comb = ""; + my @infos = (sort (split /\n/, $infos)); + foreach my $info (@infos) { + $comb .= " -a $info"; + # Need to batch them to avoid overrunning shell command length limit + if (length($comb) > 10000 || $info eq $infos[$#infos]) { + # .info may be empty, so ignore errors (unfortunately) + run("cd $cc_dir ; lcov -a app_total.info $comb -o app_total.info || true"); + $comb = ""; + } } } + travis_fold_end(); } - if ($Opt_Stage <= 6) { - print "Stage 6: Filter processed source files\n"; - my $cmd = ''; - foreach my $glob (@Remove_Sources) { - $cmd .= " '$glob'"; + if ($Opt_Stages{11}) { + travis_fold_start("dirs"); + print "Stage 11: Cleanup paths\n"; + if ($Opt_Fastcov) { + cleanup_abs_paths_info($cc_dir, "$cc_dir/app_total.info", "$cc_dir/app_total.info"); + #cleanup_abs_paths_json($cc_dir, "$cc_dir/app_total.json", "$cc_dir/app_total.json"); + } else { + cleanup_abs_paths_info($cc_dir, "$cc_dir/app_total.info", "$cc_dir/app_total.info"); } - run("cd $cc_dir ; lcov --remove app_total.info $cmd -o app_total.info"); + travis_fold_end(); } - if ($Opt_Stage <= 7) { - print "Stage 7: Create HTML\n"; - cleanup_abs_paths($cc_dir, "$cc_dir/app_total.info", "$cc_dir/app_total.info"); - run("cd $cc_dir ; genhtml app_total.info --demangle-cpp" + if ($Opt_Stages{12}) { + travis_fold_start("filter"); + print "Stage 12: Filter processed source files\n"; + my $inc = ''; + foreach my $glob (@Source_Globs) { + foreach my $infile (glob $glob) { + $inc .= " '$infile'"; + } + } + my $exc = ''; + foreach my $glob (@Remove_Sources) { + # Fastcov does exact match not globbing at present + # Lcov requires whole path match so needs the glob + $glob =~ s!^\*!! if $Opt_Fastcov; + $glob =~ s!\*$!! if $Opt_Fastcov; + $exc .= " '$glob'"; + } + if ($Opt_Fastcov) { + $inc = "--include ".$inc if $inc ne ''; + $exc = "--exclude ".$exc if $exc ne ''; + run("cd $cc_dir ; ${RealBin}/fastcov.py -C app_total.info ${inc} ${exc} -x --lcov -o app_total_f.info"); + } else { + run("cd $cc_dir ; lcov --remove app_total.info $exc -o app_total_f.info"); + } + travis_fold_end(); + } + + if ($Opt_Stages{17}) { + travis_fold_start("report"); + print "Stage 17: Create HTML\n"; + run("cd $cc_dir ; genhtml app_total_f.info --demangle-cpp" ." --rc lcov_branch_coverage=1 --rc genhtml_hi_limit=100 --output-directory html"); + travis_fold_end(); } - if ($Opt_Stage <= 9) { + if ($Opt_Stages{18}) { + travis_fold_start("upload"); + print "Stage 18: Upload\n"; + my $cmd = "bash <(curl -s https://codecov.io/bash) -f $cc_dir/app_total.info"; + print "print: Not running: export CODECOV_TOKEN=\n"; + print "print: Not running: $cmd\n"; + travis_fold_end(); + } + + if ($Opt_Stages{19}) { print "*-* All Finished *-*\n"; + print "\n"; + print "* See report in ${cc_dir}/html/index.html\n"; + print "* Remember to make distclean && ./configure before working on non-coverage\n"; } } sub clone_sources { my $cc_dir = shift; my $excluded_lines = 0; + my $excluded_br_lines = 0; foreach my $glob (@Source_Globs) { foreach my $infile (glob $glob) { $infile !~ m!^/! @@ -145,21 +327,35 @@ sub clone_sources { while (defined(my $line = $fh->getline)) { $lineno++; chomp $line; - if ($line !~ m!// LCOV_EXCL_LINE! - && $line =~ /$Exclude_Line_Regexp/) { - $line .= " //code_coverage: // LCOV_EXCL_LINE"; + if ($line =~ /LCOV_EXCL_LINE/) { + $line .= " LCOV_EXCL_BR_LINE"; + } + elsif ($line =~ /LCOV_EXCL_START/) { + $line .= " LCOV_EXCL_BR_START"; + } + elsif ($line =~ /LCOV_EXCL_STOP/) { + $line .= " LCOV_EXCL_BR_STOP"; + } + elsif ($line =~ /$Exclude_Line_Regexp/) { + $line .= " //code_coverage: // LCOV_EXCL_LINE LCOV_EXCL_BR_LINE"; $excluded_lines++; + $excluded_br_lines++; + #print "$infile:$lineno: $line"; + } + elsif ($line =~ /$Exclude_Branch_Regexp/) { + $line .= " //code_coverage: // LCOV_EXCL_BR_LINE"; + $excluded_br_lines++; #print "$infile:$lineno: $line"; - } else { } $ofh->print("$line\n"); } } } - print "Source code lines automatically LCOV_EXCL_LINE'ed: $excluded_lines\n"; + print "Number of source lines automatically LCOV_EXCL_LINE'ed: $excluded_lines\n"; + print "Number of source lines automatically LCOV_EXCL_BR_LINE'ed: $excluded_br_lines\n"; } -sub cleanup_abs_paths { +sub cleanup_abs_paths_info { my $cc_dir = shift; my $infile = shift; my $outfile = shift; @@ -178,18 +374,41 @@ sub cleanup_abs_paths { $ofh->print(@lines); } +sub cleanup_abs_paths_json { + my $cc_dir = shift; + my $infile = shift; + my $outfile = shift; + # Handcrafted cleanup, alternative would be to deserialize/serialize JSON + # But JSON::Parse not installed by default + # JSON::PP more likely to be installed, but slower + my $fh = IO::File->new("<$infile") or die "%Error: $! $infile,"; + my @lines; + while (defined(my $line = $fh->getline)) { + $line =~ s!"$ENV{VERILATOR_ROOT}/!"!g; + $line =~ s!"$cc_dir/!"!g; + $line =~ s!obj_dbg/verilog.y$!verilog.y!g; + push @lines, $line; + } + my $ofh = IO::File->new(">$outfile") or die "%Error: $! $outfile,"; + $ofh->print(@lines); +} + ####################################################################### # .dat file callbacks +sub exclude_branch_regexp { + $Exclude_Branch_Regexp = shift; +} sub exclude_line_regexp { $Exclude_Line_Regexp = shift; } - +sub remove_gcda_regexp { + $Remove_Gcda_Regexp = shift; +} sub remove_source { my @srcs = @_; push @Remove_Sources, @srcs; } - sub source_globs { my @dirs = @_; push @Source_Globs, @dirs; @@ -206,6 +425,15 @@ sub run { ($status == 0) or die "%Error: Command Failed $command, $status, stopped"; } +our $_Travis_Action; +sub travis_fold_start { + $_Travis_Action = shift; + print "travis_fold:start:$_Travis_Action\n"; +} +sub travis_fold_end { + print "travis_fold:end:$_Travis_Action\n"; +} + ####################################################################### __END__ @@ -231,13 +459,30 @@ This will rebuild the current object files. =over 4 +=item --hashset I + +Pass test hashset onto driver.pl test harness. + =item --help Displays this message and program version and exits. -=item -stage I +=item --scenarios I -Runs a specific stage (see the script). +Pass test scenarios onto driver.pl test harness. + +=item --stages I + +Runs a specific stage or range of stages (see the script). + +=item --no-stop + +Do not stop collecting data if tests fail. + +=item --test I + +Instead of normal regressions, run the specified test. May be specified +multiple times for multiple tests. =back diff --git a/nodist/code_coverage.dat b/nodist/code_coverage.dat index 898b65cf7..df768a0ab 100644 --- a/nodist/code_coverage.dat +++ b/nodist/code_coverage.dat @@ -21,7 +21,8 @@ source_globs("src/*.cpp", "include/*/*.c", ); -remove_source("/usr/include/*"); +# Note *'s are removed when using fastcov +remove_source("/usr/*"); remove_source("*/include/sysc/*"); remove_source("*/V3ClkGater.cpp"); remove_source("*/V3ClkGater.h"); @@ -37,7 +38,21 @@ remove_source("*include/gtkwave/*"); remove_source("*test_regress/*"); remove_source("*examples/*"); +# Remove collected coverage on each little test main file +# Would just be removed with remove_source in later step +remove_gcda_regexp(qr!test_regress/.*/(Vt_|Vtop_).*\.gcda!); -exclude_line_regexp(qr/(\bv3fatalSrc\b|\bVL_UNCOVERABLE\b)/); +# Exclude line entirely, also excludes from function and branch coverage +exclude_line_regexp(qr/(\bv3fatalSrc\b + |\bfatalSrc\b + |\bVL_UNCOVERABLE\b + |\bVL_FATAL + |\bUASSERT + |\bERROR_RSVD_WORD + |\bV3ERROR_NA + |\bUINFO\b)/x); + +# Exclude for branch coverage only +exclude_branch_regexp(qr/(\bdebug\(\))/x); 1; diff --git a/nodist/fastcov.py b/nodist/fastcov.py new file mode 100755 index 000000000..5be4ca7bf --- /dev/null +++ b/nodist/fastcov.py @@ -0,0 +1,744 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: MIT +# Copyright 2018-present, Bryan Gillespie +""" + Author: Bryan Gillespie + https://github.com/RPGillespie6/fastcov + + A massively parallel gcov wrapper for generating intermediate coverage formats fast + + The goal of fastcov is to generate code coverage intermediate formats as fast as possible, + even for large projects with hundreds of gcda objects. The intermediate formats may then be + consumed by a report generator such as lcov's genhtml, or a dedicated frontend such as coveralls. + + Sample Usage: + $ cd build_dir + $ ./fastcov.py --zerocounters + $ + $ ./fastcov.py --exclude /usr/include test/ --lcov -o report.info + $ genhtml -o code_coverage report.info +""" + +import re +import os +import sys +import glob +import json +import time +import logging +import argparse +import threading +import subprocess +import multiprocessing + +FASTCOV_VERSION = (1,7) +MINIMUM_PYTHON = (3,5) +MINIMUM_GCOV = (9,0,0) + +# Interesting metrics +START_TIME = time.monotonic() +GCOVS_TOTAL = 0 +GCOVS_SKIPPED = 0 + +# For when things go wrong... +# Start error codes at 3 because 1-2 are special +# See https://stackoverflow.com/a/1535733/2516916 +EXIT_CODE = 0 +EXIT_CODES = { + "gcov_version": 3, + "python_version": 4, + "unsupported_coverage_format": 5, + "excl_not_found": 6, +} + +# Disable all logging in case developers are using this as a module +logging.disable(level=logging.CRITICAL) + +class FastcovFormatter(logging.Formatter): + def format(self, record): + record.levelname = record.levelname.lower() + log_message = super(FastcovFormatter, self).format(record) + return "[{:.3f}s] {}".format(stopwatch(), log_message) + +def chunks(l, n): + """Yield successive n-sized chunks from l.""" + for i in range(0, len(l), n): + yield l[i:i + n] + +def setExitCode(key): + global EXIT_CODE + EXIT_CODE = EXIT_CODES[key] + +def incrementCounters(total, skipped): + global GCOVS_TOTAL + global GCOVS_SKIPPED + GCOVS_TOTAL += total + GCOVS_SKIPPED += skipped + +def stopwatch(): + """Return number of seconds since last time this was called.""" + global START_TIME + end_time = time.monotonic() + delta = end_time - START_TIME + START_TIME = end_time + return delta + +def parseVersionFromLine(version_str): + """Given a string containing a dotted integer version, parse out integers and return as tuple.""" + version = re.search(r'(\d+\.\d+\.\d+)', version_str) + + if not version: + return (0,0,0) + + return tuple(map(int, version.group(1).split("."))) + +def getGcovVersion(gcov): + p = subprocess.Popen([gcov, "-v"], stdout=subprocess.PIPE) + output = p.communicate()[0].decode('UTF-8') + p.wait() + return parseVersionFromLine(output.split("\n")[0]) + +def removeFiles(files): + for file in files: + os.remove(file) + +def getFilteredCoverageFiles(coverage_files, exclude): + def excludeGcda(gcda): + for ex in exclude: + if ex in gcda: + logging.debug("Omitting %s due to '--exclude-gcda %s'", gcda, ex) + return False + return True + return list(filter(excludeGcda, coverage_files)) + +def findCoverageFiles(cwd, coverage_files, use_gcno): + coverage_type = "user provided" + if not coverage_files: + coverage_type = "gcno" if use_gcno else "gcda" + coverage_files = glob.glob(os.path.join(os.path.abspath(cwd), "**/*." + coverage_type), recursive=True) + + logging.info("Found {} coverage files ({})".format(len(coverage_files), coverage_type)) + logging.debug("Coverage files found:\n %s", "\n ".join(coverage_files)) + return coverage_files + +def gcovWorker(data_q, metrics_q, args, chunk, gcov_filter_options): + base_report = {"sources": {}} + gcovs_total = 0 + gcovs_skipped = 0 + + gcov_args = "-it" + if args.branchcoverage or args.xbranchcoverage: + gcov_args += "b" + + p = subprocess.Popen([args.gcov, gcov_args] + chunk, cwd=args.cdirectory, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) + for line in iter(p.stdout.readline, b''): + intermediate_json = json.loads(line.decode(sys.stdout.encoding)) + intermediate_json_files = processGcovs(args.cdirectory, intermediate_json["files"], gcov_filter_options) + for f in intermediate_json_files: + distillSource(f, base_report["sources"], args.test_name, args.xbranchcoverage) + gcovs_total += len(intermediate_json["files"]) + gcovs_skipped += len(intermediate_json["files"]) - len(intermediate_json_files) + + p.wait() + data_q.put(base_report) + metrics_q.put((gcovs_total, gcovs_skipped)) + +def processGcdas(args, coverage_files, gcov_filter_options): + chunk_size = max(args.minimum_chunk, int(len(coverage_files) / args.jobs) + 1) + + processes = [] + data_q = multiprocessing.Queue() + metrics_q = multiprocessing.Queue() + for chunk in chunks(coverage_files, chunk_size): + p = multiprocessing.Process(target=gcovWorker, args=(data_q, metrics_q, args, chunk, gcov_filter_options)) + processes.append(p) + p.start() + + logging.info("Spawned {} gcov processes, each processing at most {} coverage files".format(len(processes), chunk_size)) + + fastcov_jsons = [] + for p in processes: + fastcov_jsons.append(data_q.get()) + incrementCounters(*metrics_q.get()) + + for p in processes: + p.join() + + base_fastcov = fastcov_jsons.pop() + for fj in fastcov_jsons: + combineReports(base_fastcov, fj) + + return base_fastcov + +def shouldFilterSource(source, gcov_filter_options): + """Returns true if the provided source file should be filtered due to CLI options, otherwise returns false.""" + # If explicit sources were passed, check for match + if gcov_filter_options["sources"]: + if source not in gcov_filter_options["sources"]: + logging.debug("Filtering coverage for '%s' due to option '--source-files'", source) + return True + + # Check exclude filter + for ex in gcov_filter_options["exclude"]: + if ex in source: + logging.debug("Filtering coverage for '%s' due to option '--exclude %s'", source, ex) + return True + + # Check include filter + if gcov_filter_options["include"]: + included = False + for inc in gcov_filter_options["include"]: + if inc in source: + included = True + break + + if not included: + logging.debug("Filtering coverage for '%s' due to option '--include %s'", source, " ".join(gcov_filter_options["include"])) + return True + + return False + +def filterFastcov(fastcov_json, args): + logging.info("Performing filtering operations (if applicable)") + gcov_filter_options = getGcovFilterOptions(args) + for source in list(fastcov_json["sources"].keys()): + if shouldFilterSource(source, gcov_filter_options): + del fastcov_json["sources"][source] + +def processGcov(cwd, gcov, files, gcov_filter_options): + # Add absolute path + gcov["file_abs"] = os.path.abspath(os.path.join(cwd, gcov["file"])) + + if shouldFilterSource(gcov["file_abs"], gcov_filter_options): + return + + files.append(gcov) + logging.debug("Accepted coverage for '%s'", gcov["file_abs"]) + +def processGcovs(cwd, gcov_files, gcov_filter_options): + files = [] + for gcov in gcov_files: + processGcov(cwd, gcov, files, gcov_filter_options) + return files + +def dumpBranchCoverageToLcovInfo(f, branches): + branch_miss = 0 + branch_found = 0 + brda = [] + for line_num, branch_counts in branches.items(): + for i, count in enumerate(branch_counts): + # Branch (, , , ) + brda.append((line_num, int(i/2), i, count)) + branch_miss += int(count == 0) + branch_found += 1 + for v in sorted(brda): + f.write("BRDA:{},{},{},{}\n".format(*v)) + f.write("BRF:{}\n".format(branch_found)) # Branches Found + f.write("BRH:{}\n".format(branch_found - branch_miss)) # Branches Hit + +def dumpToLcovInfo(fastcov_json, output): + with open(output, "w") as f: + sources = fastcov_json["sources"] + for sf in sorted(sources.keys()): + for tn in sorted(sources[sf].keys()): + data = sources[sf][tn] + f.write("TN:{}\n".format(tn)) #Test Name - used mainly in conjuction with genhtml --show-details + f.write("SF:{}\n".format(sf)) #Source File + + fn_miss = 0 + fn = [] + fnda = [] + for function, fdata in data["functions"].items(): + fn.append((fdata["start_line"], function)) # Function Start Line + fnda.append((fdata["execution_count"], function)) # Function Hits + fn_miss += int(fdata["execution_count"] == 0) + # NOTE: lcov sorts FN, but not FNDA. + for v in sorted(fn): + f.write("FN:{},{}\n".format(*v)) + for v in sorted(fnda): + f.write("FNDA:{},{}\n".format(*v)) + f.write("FNF:{}\n".format(len(data["functions"]))) #Functions Found + f.write("FNH:{}\n".format((len(data["functions"]) - fn_miss))) #Functions Hit + + if data["branches"]: + dumpBranchCoverageToLcovInfo(f, data["branches"]) + + line_miss = 0 + da = [] + for line_num, count in data["lines"].items(): + da.append((line_num, count)) + line_miss += int(count == 0) + for v in sorted(da): + f.write("DA:{},{}\n".format(*v)) # Line + f.write("LF:{}\n".format(len(data["lines"]))) #Lines Found + f.write("LH:{}\n".format((len(data["lines"]) - line_miss))) #Lines Hit + f.write("end_of_record\n") + +def getSourceLines(source, fallback_encodings=[]): + """Return a list of lines from the provided source, trying to decode with fallback encodings if the default fails.""" + default_encoding = sys.getdefaultencoding() + for encoding in [default_encoding] + fallback_encodings: + try: + with open(source, encoding=encoding) as f: + return f.readlines() + except UnicodeDecodeError: + pass + + logging.warning("Could not decode '{}' with {} or fallback encodings ({}); ignoring errors".format(source, default_encoding, ",".join(fallback_encodings))) + with open(source, errors="ignore") as f: + return f.readlines() + +def exclProcessSource(fastcov_sources, source, exclude_branches_sw, include_branches_sw, fallback_encodings): + start_line = 0 + end_line = 0 + # Start enumeration at line 1 because the first line of the file is line 1 not 0 + for i, line in enumerate(getSourceLines(source, fallback_encodings), 1): + # Cycle through test names (likely only 1) + for test_name in fastcov_sources[source]: + fastcov_data = fastcov_sources[source][test_name] + + # Build line to function dict so can quickly delete by line number + line_to_func = {} + for f in fastcov_data["functions"].keys(): + l = fastcov_data["functions"][f]["start_line"] + if l not in line_to_func: + line_to_func[l] = set() + line_to_func[l].add(f) + + if i in fastcov_data["branches"]: + del_exclude_br = exclude_branches_sw and any(line.lstrip().startswith(e) for e in exclude_branches_sw) + del_include_br = include_branches_sw and all(not line.lstrip().startswith(e) for e in include_branches_sw) + if del_exclude_br or del_include_br: + del fastcov_data["branches"][i] + + if "LCOV_EXCL" not in line: + continue + + if "LCOV_EXCL_LINE" in line: + for key in ["lines", "branches"]: + if i in fastcov_data[key]: + del fastcov_data[key][i] + if i in line_to_func: + for key in line_to_func[i]: + if key in fastcov_data["functions"]: + del fastcov_data["functions"][key] + elif "LCOV_EXCL_START" in line: + start_line = i + elif "LCOV_EXCL_STOP" in line: + end_line = i + + if not start_line: + end_line = 0 + continue + + for key in ["lines", "branches"]: + for line_num in list(fastcov_data[key].keys()): + if start_line <= line_num <= end_line: + del fastcov_data[key][line_num] + + for line_num in range(start_line, end_line): + if line_num in line_to_func: + for key in line_to_func[line_num]: + if key in fastcov_data["functions"]: + del fastcov_data["functions"][key] + + start_line = end_line = 0 + elif "LCOV_EXCL_BR_LINE" in line: + if i in fastcov_data["branches"]: + del fastcov_data["branches"][i] + +def exclMarkerWorker(fastcov_sources, chunk, exclude_branches_sw, include_branches_sw, fallback_encodings): + for source in chunk: + try: + exclProcessSource(fastcov_sources, source, exclude_branches_sw, include_branches_sw, fallback_encodings) + except FileNotFoundError: + logging.error("Could not find '%s' to scan for exclusion markers...", source) + setExitCode("excl_not_found") # Set exit code because of error + +def scanExclusionMarkers(fastcov_json, jobs, exclude_branches_sw, include_branches_sw, min_chunk_size, fallback_encodings): + chunk_size = max(min_chunk_size, int(len(fastcov_json["sources"]) / jobs) + 1) + + threads = [] + for chunk in chunks(list(fastcov_json["sources"].keys()), chunk_size): + t = threading.Thread(target=exclMarkerWorker, args=(fastcov_json["sources"], chunk, exclude_branches_sw, include_branches_sw, fallback_encodings)) + threads.append(t) + t.start() + + logging.info("Spawned {} threads each scanning at most {} source files".format(len(threads), chunk_size)) + for t in threads: + t.join() + +def distillFunction(function_raw, functions): + function_name = function_raw["name"] + # NOTE: need to explicitly cast all counts coming from gcov to int - this is because gcov's json library + # will pass as scientific notation (i.e. 12+e45) + start_line = int(function_raw["start_line"]) + execution_count = int(function_raw["execution_count"]) + if function_name not in functions: + functions[function_name] = { + "start_line": start_line, + "execution_count": execution_count + } + else: + functions[function_name]["execution_count"] += execution_count + +def emptyBranchSet(branch1, branch2): + return (branch1["count"] == 0 and branch2["count"] == 0) + +def matchingBranchSet(branch1, branch2): + return (branch1["count"] == branch2["count"]) + +def filterExceptionalBranches(branches): + filtered_branches = [] + exception_branch = False + for i in range(0, len(branches), 2): + if i+1 >= len(branches): + filtered_branches.append(branches[i]) + break + + # Filter exceptional branch noise + if branches[i+1]["throw"]: + exception_branch = True + continue + + # Filter initializer list noise + if exception_branch and emptyBranchSet(branches[i], branches[i+1]) and len(filtered_branches) >= 2 and matchingBranchSet(filtered_branches[-1], filtered_branches[-2]): + return [] + + filtered_branches.append(branches[i]) + filtered_branches.append(branches[i+1]) + + return filtered_branches + +def distillLine(line_raw, lines, branches, include_exceptional_branches): + line_number = int(line_raw["line_number"]) + count = int(line_raw["count"]) + if line_number not in lines: + lines[line_number] = count + else: + lines[line_number] += count + + # Filter out exceptional branches by default unless requested otherwise + if not include_exceptional_branches: + line_raw["branches"] = filterExceptionalBranches(line_raw["branches"]) + + # Increment all branch counts + for i, branch in enumerate(line_raw["branches"]): + if line_number not in branches: + branches[line_number] = [] + blen = len(branches[line_number]) + glen = len(line_raw["branches"]) + if blen < glen: + branches[line_number] += [0] * (glen - blen) + branches[line_number][i] += int(branch["count"]) + +def distillSource(source_raw, sources, test_name, include_exceptional_branches): + source_name = source_raw["file_abs"] + if source_name not in sources: + sources[source_name] = { + test_name: { + "functions": {}, + "branches": {}, + "lines": {} + } + } + + for function in source_raw["functions"]: + distillFunction(function, sources[source_name][test_name]["functions"]) + + for line in source_raw["lines"]: + distillLine(line, sources[source_name][test_name]["lines"], sources[source_name][test_name]["branches"], include_exceptional_branches) + +def dumpToJson(intermediate, output): + with open(output, "w") as f: + json.dump(intermediate, f) + +def getGcovFilterOptions(args): + return { + "sources": set([os.path.abspath(s) for s in args.sources]), #Make paths absolute, use set for fast lookups + "include": args.includepost, + "exclude": args.excludepost, + } + +def addDicts(dict1, dict2): + """Add dicts together by value. i.e. addDicts({"a":1,"b":0}, {"a":2}) == {"a":3,"b":0}.""" + result = {k:v for k,v in dict1.items()} + for k,v in dict2.items(): + if k in result: + result[k] += v + else: + result[k] = v + + return result + +def addLists(list1, list2): + """Add lists together by value. i.e. addLists([1,1], [2,2]) == [3,3].""" + # Find big list and small list + blist, slist = list(list2), list(list1) + if len(list1) > len(list2): + blist, slist = slist, blist + + # Overlay small list onto big list + for i, b in enumerate(slist): + blist[i] += b + + return blist + +def combineReports(base, overlay): + for source, scov in overlay["sources"].items(): + # Combine Source Coverage + if source not in base["sources"]: + base["sources"][source] = scov + continue + + for test_name, tcov in scov.items(): + # Combine Source Test Name Coverage + if test_name not in base["sources"][source]: + base["sources"][source][test_name] = tcov + continue + + # Drill down and create convenience variable + base_data = base["sources"][source][test_name] + + # Combine Line Coverage + base_data["lines"] = addDicts(base_data["lines"], tcov["lines"]) + + # Combine Branch Coverage + for branch, cov in tcov["branches"].items(): + if branch not in base_data["branches"]: + base_data["branches"][branch] = cov + else: + base_data["branches"][branch] = addLists(base_data["branches"][branch], cov) + + # Combine Function Coverage + for function, cov in tcov["functions"].items(): + if function not in base_data["functions"]: + base_data["functions"][function] = cov + else: + base_data["functions"][function]["execution_count"] += cov["execution_count"] + +def parseInfo(path): + """Parse an lcov .info file into fastcov json.""" + fastcov_json = { + "sources": {} + } + + with open(path) as f: + for line in f: + if line.startswith("TN:"): + current_test_name = line[3:].strip() + elif line.startswith("SF:"): + current_sf = line[3:].strip() + fastcov_json["sources"][current_sf] = { + current_test_name: { + "functions": {}, + "branches": {}, + "lines": {}, + } + } + current_data = fastcov_json["sources"][current_sf][current_test_name] + elif line.startswith("FN:"): + line_num, function_name = line[3:].strip().split(",") + current_data["functions"][function_name] = {} + current_data["functions"][function_name]["start_line"] = int(line_num) + elif line.startswith("FNDA:"): + count, function_name = line[5:].strip().split(",") + current_data["functions"][function_name]["execution_count"] = int(count) + elif line.startswith("DA:"): + line_num, count = line[3:].strip().split(",") + current_data["lines"][line_num] = int(count) + elif line.startswith("BRDA:"): + branch_tokens = line[5:].strip().split(",") + line_num, count = branch_tokens[0], branch_tokens[-1] + if line_num not in current_data["branches"]: + current_data["branches"][line_num] = [] + current_data["branches"][line_num].append(int(count)) + + return fastcov_json + +def convertKeysToInt(report): + for source in report["sources"].keys(): + for test_name in report["sources"][source].keys(): + report_data = report["sources"][source][test_name] + report_data["lines"] = {int(k):v for k,v in report_data["lines"].items()} + report_data["branches"] = {int(k):v for k,v in report_data["branches"].items()} + +def parseAndCombine(paths): + base_report = {} + + for path in paths: + if path.endswith(".json"): + with open(path) as f: + report = json.load(f) + elif path.endswith(".info"): + report = parseInfo(path) + else: + logging.error("Currently only fastcov .json and lcov .info supported for combine operations, aborting due to %s...\n", path) + sys.exit(EXIT_CODES["unsupported_coverage_format"]) + + # In order for sorting to work later when we serialize, + # make sure integer keys are int + convertKeysToInt(report) + + if not base_report: + base_report = report + logging.info("Setting {} as base report".format(path)) + else: + combineReports(base_report, report) + logging.info("Adding {} to base report".format(path)) + + return base_report + +def getCombineCoverage(args): + logging.info("Performing combine operation") + fastcov_json = parseAndCombine(args.combine) + filterFastcov(fastcov_json, args) + return fastcov_json + +def getGcovCoverage(args): + # Need at least python 3.5 because of use of recursive glob + checkPythonVersion(sys.version_info[0:2]) + + # Need at least gcov 9.0.0 because that's when gcov JSON and stdout streaming was introduced + checkGcovVersion(getGcovVersion(args.gcov)) + + # Get list of gcda files to process + coverage_files = findCoverageFiles(args.directory, args.coverage_files, args.use_gcno) + + # If gcda/gcno filtering is enabled, filter them out now + if args.excludepre: + coverage_files = getFilteredCoverageFiles(coverage_files, args.excludepre) + logging.info("Found {} coverage files after filtering".format(len(coverage_files))) + + # We "zero" the "counters" by simply deleting all gcda files + if args.zerocounters: + removeFiles(coverage_files) + logging.info("Removed {} .gcda files".format(len(coverage_files))) + sys.exit() + + # Fire up one gcov per cpu and start processing gcdas + gcov_filter_options = getGcovFilterOptions(args) + fastcov_json = processGcdas(args, coverage_files, gcov_filter_options) + + # Summarize processing results + logging.info("Processed {} .gcov files ({} total, {} skipped)".format(GCOVS_TOTAL - GCOVS_SKIPPED, GCOVS_TOTAL, GCOVS_SKIPPED)) + logging.debug("Final report will contain coverage for the following %d source files:\n %s", len(fastcov_json["sources"]), "\n ".join(fastcov_json["sources"])) + + return fastcov_json + +def dumpFile(fastcov_json, args): + if args.lcov: + dumpToLcovInfo(fastcov_json, args.output) + logging.info("Created lcov info file '{}'".format(args.output)) + else: + dumpToJson(fastcov_json, args.output) + logging.info("Created fastcov json file '{}'".format(args.output)) + +def tupleToDotted(tup): + return ".".join(map(str, tup)) + +def parseArgs(): + parser = argparse.ArgumentParser(description='A parallel gcov wrapper for fast coverage report generation') + parser.add_argument('-z', '--zerocounters', dest='zerocounters', action="store_true", help='Recursively delete all gcda files') + + # Enable Branch Coverage + parser.add_argument('-b', '--branch-coverage', dest='branchcoverage', action="store_true", help='Include only the most useful branches in the coverage report.') + parser.add_argument('-B', '--exceptional-branch-coverage', dest='xbranchcoverage', action="store_true", help='Include ALL branches in the coverage report (including potentially noisy exceptional branches).') + parser.add_argument('-A', '--exclude-br-lines-starting-with', dest='exclude_branches_sw', nargs="+", metavar='', default=[], help='Exclude branches from lines starting with one of the provided strings (i.e. assert, return, etc.)') + parser.add_argument('-a', '--include-br-lines-starting-with', dest='include_branches_sw', nargs="+", metavar='', default=[], help='Include only branches from lines starting with one of the provided strings (i.e. if, else, while, etc.)') + parser.add_argument('-X', '--skip-exclusion-markers', dest='skip_exclusion_markers', action="store_true", help='Skip reading source files to search for lcov exclusion markers (such as "LCOV_EXCL_LINE")') + parser.add_argument('-x', '--scan-exclusion-markers', dest='scan_exclusion_markers', action="store_true", help='(Combine operations) Force reading source files to search for lcov exclusion markers (such as "LCOV_EXCL_LINE")') + + # Capture untested file coverage as well via gcno + parser.add_argument('-n', '--process-gcno', dest='use_gcno', action="store_true", help='Process both gcno and gcda coverage files. This option is useful for capturing untested files in the coverage report.') + + # Filtering Options + parser.add_argument('-s', '--source-files', dest='sources', nargs="+", metavar='', default=[], help='Filter: Specify exactly which source files should be included in the final report. Paths must be either absolute or relative to current directory.') + parser.add_argument('-e', '--exclude', dest='excludepost', nargs="+", metavar='', default=[], help='Filter: Exclude source files from final report if they contain one of the provided substrings (i.e. /usr/include test/, etc.)') + parser.add_argument('-i', '--include', dest='includepost', nargs="+", metavar='', default=[], help='Filter: Only include source files in final report that contain one of the provided substrings (i.e. src/ etc.)') + parser.add_argument('-f', '--gcda-files', dest='coverage_files', nargs="+", metavar='', default=[], help='Filter: Specify exactly which gcda or gcno files should be processed. Note that specifying gcno causes both gcno and gcda to be processed.') + parser.add_argument('-E', '--exclude-gcda', dest='excludepre', nargs="+", metavar='', default=[], help='Filter: Exclude gcda or gcno files from being processed via simple find matching (not regex)') + + parser.add_argument('-g', '--gcov', dest='gcov', default='gcov', help='Which gcov binary to use') + + parser.add_argument('-d', '--search-directory', dest='directory', default=".", help='Base directory to recursively search for gcda files (default: .)') + parser.add_argument('-c', '--compiler-directory', dest='cdirectory', default=".", help='Base directory compiler was invoked from (default: .) \ + This needs to be set if invoking fastcov from somewhere other than the base compiler directory.') + + parser.add_argument('-j', '--jobs', dest='jobs', type=int, default=multiprocessing.cpu_count(), help='Number of parallel gcov to spawn (default: {}).'.format(multiprocessing.cpu_count())) + parser.add_argument('-m', '--minimum-chunk-size', dest='minimum_chunk', type=int, default=5, help='Minimum number of files a thread should process (default: 5). \ + If you have only 4 gcda files but they are monstrously huge, you could change this value to a 1 so that each thread will only process 1 gcda. Otherwise fastcov will spawn only 1 thread to process all of them.') + + parser.add_argument('-F', '--fallback-encodings', dest='fallback_encodings', nargs="+", metavar='', default=[], help='List of encodings to try if opening a source file with the default fails (i.e. latin1, etc.). This option is not usually needed.') + + parser.add_argument('-l', '--lcov', dest='lcov', action="store_true", help='Output in lcov info format instead of fastcov json') + parser.add_argument('-o', '--output', dest='output', default="coverage.json", help='Name of output file (default: coverage.json)') + parser.add_argument('-q', '--quiet', dest='quiet', action="store_true", help='Suppress output to stdout') + + parser.add_argument('-t', '--test-name', dest='test_name', default="", help='Specify a test name for the coverage. Equivalent to lcov\'s `-t`.') + parser.add_argument('-C', '--add-tracefile', dest='combine', nargs="+", help='Combine multiple coverage files into one. If this flag is specified, fastcov will do a combine operation instead invoking gcov. Equivalent to lcov\'s `-a`.') + + parser.add_argument('-V', '--verbose', dest="verbose", action="store_true", help="Print more detailed information about what fastcov is doing") + parser.add_argument('-v', '--version', action="version", version='%(prog)s {version}'.format(version=__version__), help="Show program's version number and exit") + + args = parser.parse_args() + + return args + +def checkPythonVersion(version): + """Exit if the provided python version is less than the supported version.""" + if version < MINIMUM_PYTHON: + sys.stderr.write("Minimum python version {} required, found {}\n".format(tupleToDotted(MINIMUM_PYTHON), tupleToDotted(version))) + sys.exit(EXIT_CODES["python_version"]) + +def checkGcovVersion(version): + """Exit if the provided gcov version is less than the supported version.""" + if version < MINIMUM_GCOV: + sys.stderr.write("Minimum gcov version {} required, found {}\n".format(tupleToDotted(MINIMUM_GCOV), tupleToDotted(version))) + sys.exit(EXIT_CODES["gcov_version"]) + +def setupLogging(quiet, verbose): + handler = logging.StreamHandler() + handler.setFormatter(FastcovFormatter("[%(levelname)s]: %(message)s")) + + root = logging.getLogger() + root.setLevel(logging.INFO) + root.addHandler(handler) + + if not quiet: + logging.disable(level=logging.NOTSET) # Re-enable logging + + if verbose: + root.setLevel(logging.DEBUG) + +def main(): + args = parseArgs() + + # Setup logging + setupLogging(args.quiet, args.verbose) + + # Get report from appropriate source + if args.combine: + fastcov_json = getCombineCoverage(args) + skip_exclusion_markers = not args.scan_exclusion_markers + else: + fastcov_json = getGcovCoverage(args) + skip_exclusion_markers = args.skip_exclusion_markers + + # Scan for exclusion markers + if not skip_exclusion_markers: + scanExclusionMarkers(fastcov_json, args.jobs, args.exclude_branches_sw, args.include_branches_sw, args.minimum_chunk, args.fallback_encodings) + logging.info("Scanned {} source files for exclusion markers".format(len(fastcov_json["sources"]))) + + # Dump to desired file format + dumpFile(fastcov_json, args) + + # If there was an error along the way, but we still completed the pipeline... + if EXIT_CODE: + sys.exit(EXIT_CODE) + +# Set package version... it's way down here so that we can call tupleToDotted +__version__ = tupleToDotted(FASTCOV_VERSION) + +if __name__ == '__main__': + main() diff --git a/nodist/git_untabify b/nodist/git_untabify deleted file mode 100755 index 68bbbac04..000000000 --- a/nodist/git_untabify +++ /dev/null @@ -1,257 +0,0 @@ -#!/usr/bin/env perl -# See copyright, etc in below POD section. -###################################################################### - -use warnings; -use Getopt::Long; -#use Data::Dumper; $Data::Dumper::Indent=1; $Data::Dumper::Sortkeys=1; #Debug -use IO::File; -use IO::Dir; -use Pod::Usage; -use strict; -use vars qw($Debug); - -our $VERSION = '0.001'; -our $Opt_Widen = 1; - -#====================================================================== -# main - -autoflush STDOUT 1; -autoflush STDERR 1; -Getopt::Long::config("no_auto_abbrev"); -if (! GetOptions ( - "debug" => sub { $Debug = 1; }, - "help" => sub { print "Version $VERSION\n"; - pod2usage(-verbose=>2, -exitval => 0, - output=>\*STDOUT, -noperldoc=>1); }, - "narrow!" => sub { $Opt_Widen = 0; }, - "version" => sub { print "Version $VERSION\n"; exit(0); }, - "widen!" => sub { $Opt_Widen = 1; }, # Default, undocumented - "<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; }, - )) { - die "%Error: Bad usage, try 'git_untabify --help'\n"; -} - -read_patch(); - -####################################################################### - -sub read_patch { - my $filename = undef; - my $lineno = 0; - my $hunk = 0; - my $editlines = {}; - while (defined(my $line = )) { - chomp $line; - if ($line =~ m!^\+\+\+ b/(.*)!) { - find_edits($editlines); - edit_file($filename, $editlines); - $filename = $1; - $lineno = 0; - $editlines = {}; - print "FILE $filename\n" if $Debug; - } - elsif ($line =~ m!^@@ -?[0-9]+,?[0-9]* \+?([0-9]+)!) { - $lineno = $1 - 1; - ++$hunk; - print " LINE $1 $line" if $Debug; - } - elsif ($line =~ m!^ !) { - ++$lineno; - $editlines->{$lineno} = {line => $line, - hunk => $hunk, - user_edit => 0, }; - } - elsif ($line =~ m!^\+!) { - ++$lineno; - print " $lineno: $line" if $Debug; - $editlines->{$lineno} = {line => $line, - hunk => $hunk, - user_edit => 1, }; - } - } - find_edits($editlines); - edit_file($filename, $editlines); -} - -sub find_edits { - my $editlines = shift; - # Expand edit regions so if have edited line, non-edited line, edited - # line, we will tab expand the middle ones. - my %hunk_firstlines; - foreach my $lineno (sort {$a <=> $b} keys %$editlines) { - my $hunk = $editlines->{$lineno}{hunk}; - $hunk_firstlines{$hunk} ||= $lineno if $editlines->{$lineno}{user_edit}; - } - my %hunk_lastlines; - foreach my $lineno (sort {$b <=> $a} keys %$editlines) { - my $hunk = $editlines->{$lineno}{hunk}; - $hunk_lastlines{$hunk} ||= $lineno if $editlines->{$lineno}{user_edit}; - } - - if ($Opt_Widen) { - # Expand to include }'s that finish basic block - foreach my $hunk (keys %hunk_lastlines) { - while (my $lineno = $hunk_lastlines{$hunk}) { - ++$lineno; - if (($editlines->{$lineno}{line} || "") - =~ /^[+ ]\s+}[ \t};]*$/) { - $hunk_lastlines{$hunk} = $lineno; - } else { - last; - } - } - } - # Expand to always untabify at least 3 lines (so that future diff will - # have non-tabs within a edit hunk distance - foreach my $hunk (keys %hunk_firstlines) { - if ($hunk_firstlines{$hunk} == $hunk_lastlines{$hunk}) { - --$hunk_firstlines{$hunk}; - ++$hunk_lastlines{$hunk}; - } - elsif ($hunk_firstlines{$hunk}+1 == $hunk_lastlines{$hunk}) { - ++$hunk_lastlines{$hunk}; - } - } - } - - foreach my $lineno (sort {$a <=> $b} keys %$editlines) { - if (($editlines->{$lineno}{line}||"") =~ /\t/) { - my $hunk = $editlines->{$lineno}{hunk}; - if ($hunk_firstlines{$hunk} <= $lineno && $hunk_lastlines{$hunk} >= $lineno) { - $editlines->{$lineno}{editit} = 1; - } - } - } -} - -sub edit_file { - my $filename = shift; - my $editlines = shift; - - my @editits; - foreach my $lineno (sort {$a <=> $b} keys %$editlines) { - push @editits, $lineno if $editlines->{$lineno}{editit}; - } - - return if $#editits < 0; - if (ignore($filename)) { - print "%Warning: Ignoring $filename\n"; - return; - } - print "Edit $filename ",join(",",@editits),"\n"; - - my $lineno = 0; - my @out; - { - my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n"; - while (defined(my $line = $fh->getline)) { - ++$lineno; - if ($editlines->{$lineno}{editit}) { - print $line; - push @out, untabify($line); - } else { - push @out, $line; - } - } - $fh->close; - } - { - my $fh = IO::File->new(">${filename}.untab") or die "%Error: $! ${filename}.untab,"; - $fh->print(join('',@out)); - $fh->close; - - my ($dev,$ino,$mode) = stat($filename); - chmod $mode, "${filename}.untab"; - } - - rename("${filename}.untab", $filename) or die "%Error: $! ${filename}.untab,"; -} - -sub ignore { - my $filename = shift; - return 1 if ($filename =~ /(Makefile|\.mk)/); - return 1 if ($filename =~ /\.(y|l|out|vcd)$/); - return 1 if ($filename =~ /gtkwave/); - # - return 0 if ($filename =~ /\.(sv|v|vh|svh|h|vc|cpp|pl)$/); - return 0; -} - -sub untabify { - my $line = shift; - my $out = ""; - my $col = 0; - foreach my $c (split //, $line) { - if ($c eq "\t") { - my $destcol = int(($col+8)/8)*8; - while ($col < $destcol) { ++$col; $out .= " "; } - } else { - $out .= $c; - $col++; - } - } - return $out; -} - -####################################################################### -__END__ - -=pod - -=head1 NAME - -git_untabify - Pipe a git diff report and untabify differences - -=head1 SYNOPSIS - - git diff a..b | git_untabify - -=head1 DESCRIPTION - -Take a patch file, and edit the files in the destination patch list to -untabify the related patch lines. - -=head1 ARGUMENTS - -=over 4 - -=item --help - -Displays this message and program version and exits. - -=item --narrow - -Only edit lines which the user edited. - -If not provided, also edit other lines within at least a 3 line area around -the edit, and between any edits within the same hunk. - -=item --version - -Displays program version and exits. - -=back - -=head1 DISTRIBUTION - -Copyright 2005-2020 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 - -=head1 AUTHORS - -Wilson Snyder - -=head1 SEE ALSO - -=cut - -###################################################################### -### Local Variables: -### compile-command: "./git_untabify " -### End: diff --git a/src/Makefile.in b/src/Makefile.in index 4bf742008..e8bb467c3 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -84,7 +84,7 @@ maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_* *.log *.dmp *.vpd core -rm -f *.o *.d perlxsi.c *_gen_* - -rm -f *__gen* + -rm -f *__gen* obj_* -rm -f .objcache* distclean maintainer-clean:: diff --git a/src/Makefile_obj.in b/src/Makefile_obj.in index 911f97e1f..0cd331087 100644 --- a/src/Makefile_obj.in +++ b/src/Makefile_obj.in @@ -211,11 +211,13 @@ RAW_OBJS = \ V3LinkCells.o \ V3LinkDot.o \ V3LinkJump.o \ + V3LinkInc.o \ V3LinkLValue.o \ V3LinkLevel.o \ V3LinkParse.o \ V3LinkResolve.o \ V3Localize.o \ + V3MergeCond.o \ V3Name.o \ V3Number.o \ V3Options.o \ @@ -246,6 +248,7 @@ RAW_OBJS = \ V3Undriven.o \ V3Unknown.o \ V3Unroll.o \ + V3Waiver.o \ V3Width.o \ V3WidthSel.o \ @@ -287,21 +290,21 @@ V3Number_test: V3Number_test.o $(PERL) $(ASTGEN) -I$(srcdir) $*.cpp %.o: %.cpp - $(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSWALL} -c $< + $(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSWALL} -c $< -o $@ %.o: %.c - $(OBJCACHE) ${CC} ${CFLAGS} ${CPPFLAGSWALL} -c $< + $(OBJCACHE) ${CC} ${CFLAGS} ${CPPFLAGSWALL} -c $< -o $@ V3ParseLex.o: V3ParseLex.cpp V3Lexer.yy.cpp V3ParseBison.c - $(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSPARSER} -c $< + $(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSPARSER} -c $< -o $@ V3ParseGrammar.o: V3ParseGrammar.cpp V3ParseBison.c - $(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSPARSER} -c $< + $(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSPARSER} -c $< -o $@ V3ParseImp.o: V3ParseImp.cpp V3ParseBison.c - $(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSPARSER} -c $< + $(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSPARSER} -c $< -o $@ V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp - $(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSPARSER} -c $< + $(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSPARSER} -c $< -o $@ #### Generated files diff --git a/src/V3Active.cpp b/src/V3Active.cpp index 13689cb9f..eb24b00d7 100644 --- a/src/V3Active.cpp +++ b/src/V3Active.cpp @@ -50,7 +50,6 @@ protected: class ActiveNamer : public ActiveBaseVisitor { private: - typedef std::map ActiveNameMap; // STATE AstScope* m_scopep; // Current scope to add statement to AstActive* m_iActivep; // For current scope, the IActive we're building diff --git a/src/V3ActiveTop.cpp b/src/V3ActiveTop.cpp index e7548a7c5..933ba26fa 100644 --- a/src/V3ActiveTop.cpp +++ b/src/V3ActiveTop.cpp @@ -89,7 +89,7 @@ private: } // Move the SENTREE for each active up to the global level. // This way we'll easily see what clock domains are identical - AstSenTree* wantp = m_finder.getSenTree(nodep->fileline(), sensesp); + AstSenTree* wantp = m_finder.getSenTree(sensesp); UINFO(4, " lookdone\n"); if (wantp != sensesp) { // Move the active's contents to the other active @@ -108,7 +108,7 @@ private: // No need to do statements under it, they're already moved. // iterateChildren(nodep); } - virtual void visit(AstInitial* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE + virtual void visit(AstNodeProcedure* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE nodep->v3fatalSrc("Node should have been under ACTIVE"); } virtual void visit(AstAssignAlias* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE @@ -117,15 +117,9 @@ private: virtual void visit(AstAssignW* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE nodep->v3fatalSrc("Node should have been under ACTIVE"); } - virtual void visit(AstAlways* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE - nodep->v3fatalSrc("Node should have been under ACTIVE"); - } virtual void visit(AstAlwaysPublic* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE nodep->v3fatalSrc("Node should have been under ACTIVE"); } - virtual void visit(AstFinal* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE - nodep->v3fatalSrc("Node should have been deleted"); - } //-------------------- virtual void visit(AstNodeMath*) VL_OVERRIDE {} // Accelerate virtual void visit(AstVarScope*) VL_OVERRIDE {} // Accelerate diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 254301efa..501c9039f 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -23,9 +23,6 @@ #include "V3GraphDfa.h" #include "V3Stats.h" -#include -#include - //###################################################################### // Assert class functions diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp index 0cd815b40..c23e1bd75 100644 --- a/src/V3AssertPre.cpp +++ b/src/V3AssertPre.cpp @@ -23,9 +23,6 @@ #include "V3Global.h" #include "V3AssertPre.h" -#include -#include - //###################################################################### // Assert class functions diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index dbd8e8779..31d0b892d 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -23,7 +23,6 @@ #include "V3Broken.h" #include "V3String.h" -#include #include #include @@ -727,7 +726,7 @@ void AstNode::deleteNode() { this->m_op4p = reinterpret_cast(0x1); if ( #if !defined(VL_DEBUG) || defined(VL_LEAK_CHECKS) - 1 + true #else !v3Global.opt.debugLeak() #endif @@ -1129,6 +1128,7 @@ void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) { *logsp << "No changes since last dump!\n"; } else { dumpTree(*logsp); + editCountSetLast(); // Next dump can indicate start from here } } } @@ -1139,13 +1139,11 @@ void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) { // set by other steps if it is called in the middle of other operations if (AstNetlist* netp = VN_CAST(this, Netlist)) V3Broken::brokenAll(netp); } - // Next dump can indicate start from here - editCountSetLast(); } void AstNode::v3errorEndFatal(std::ostringstream& str) const { v3errorEnd(str); - assert(0); + assert(0); // LCOV_EXCL_LINE VL_UNREACHABLE } @@ -1154,10 +1152,10 @@ string AstNode::locationStr() const { const AstNode* backp = this; int itmax = 10000; // Max iterations before giving up on location search while (backp) { - if (--itmax < 0) { + if (VL_UNCOVERABLE(--itmax < 0)) { // Likely some circular back link, and V3Ast is trying to report a low-level error UINFO(1, "Ran out of iterations finding locationStr on " << backp << endl); - return ""; + return ""; // LCOV_EXCL_LINE } const AstScope* scopep; if ((scopep = VN_CAST_CONST(backp, Scope))) { diff --git a/src/V3Ast.h b/src/V3Ast.h index ae501831e..c2ab16559 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -193,12 +193,14 @@ class AstCFuncType { public: enum en { FT_NORMAL, + TRACE_REGISTER, TRACE_INIT, TRACE_INIT_SUB, TRACE_FULL, TRACE_FULL_SUB, TRACE_CHANGE, - TRACE_CHANGE_SUB + TRACE_CHANGE_SUB, + TRACE_CLEANUP }; enum en m_e; inline AstCFuncType() @@ -210,10 +212,7 @@ public: : m_e(static_cast(_e)) {} operator en() const { return m_e; } // METHODS - bool isTrace() const { - return (m_e == TRACE_INIT || m_e == TRACE_INIT_SUB || m_e == TRACE_FULL - || m_e == TRACE_FULL_SUB || m_e == TRACE_CHANGE || m_e == TRACE_CHANGE_SUB); - } + bool isTrace() const { return m_e != FT_NORMAL; } }; inline bool operator==(const AstCFuncType& lhs, const AstCFuncType& rhs) { return lhs.m_e == rhs.m_e; @@ -258,7 +257,7 @@ public: case ET_HIGHEDGE: return ET_LOWEDGE; case ET_LOWEDGE: return ET_HIGHEDGE; default: UASSERT_STATIC(0, "Inverting bad edgeType()"); - }; + } return VEdgeType::ET_ILLEGAL; } const char* ascii() const { @@ -1081,9 +1080,6 @@ public: // - Also used to allow parameter passing up/down iterate calls class WidthVP; -class LinkVP; -class OrderBlockNU; -class OrderVarNU; class V3GraphVertex; class VSymEnt; @@ -1104,15 +1100,11 @@ public: explicit VNUser(void* p) { m_u.up = p; } ~VNUser() {} // Casters - WidthVP* c() { return ((WidthVP*)m_u.up); } - LinkVP* toLinkVP() { return ((LinkVP*)m_u.up); } - VSymEnt* toSymEnt() { return ((VSymEnt*)m_u.up); } - AstNode* toNodep() { return ((AstNode*)m_u.up); } - OrderBlockNU* toOrderBlock() { return ((OrderBlockNU*)m_u.up); } - OrderVarNU* toOrderVar() { return ((OrderVarNU*)m_u.up); } - V3GraphVertex* toGraphVertex() { return ((V3GraphVertex*)m_u.up); } - inline int toInt() { return m_u.ui; } - static inline VNUser fromZero() { return VNUser(0); } + WidthVP* c() const { return reinterpret_cast(m_u.up); } + VSymEnt* toSymEnt() const { return reinterpret_cast(m_u.up); } + AstNode* toNodep() const { return reinterpret_cast(m_u.up); } + V3GraphVertex* toGraphVertex() const { return reinterpret_cast(m_u.up); } + int toInt() const { return m_u.ui; } static inline VNUser fromInt(int i) { return VNUser(i); } }; @@ -1318,7 +1310,7 @@ public: class FullValue {}; // for creator type-overload selection explicit V3Hash(Illegal) { m_both = 0; } // Saving and restoring inside a userp - explicit V3Hash(VNUser u) { m_both = u.toInt(); } + explicit V3Hash(const VNUser& u) { m_both = u.toInt(); } V3Hash operator+=(const V3Hash& rh) { setBoth(depth() + rh.depth(), (hshval() * 31 + rh.hshval())); return *this; @@ -1355,12 +1347,12 @@ public: // Prefetch a node. // The if() makes it faster, even though prefetch won't fault on null pointers #define ASTNODE_PREFETCH(nodep) \ - { \ + do { \ if (nodep) { \ VL_PREFETCH_RD(&((nodep)->m_nextp)); \ VL_PREFETCH_RD(&((nodep)->m_iterpp)); \ } \ - } + } while (false) class AstNode { // v ASTNODE_PREFETCH depends on below ordering of members @@ -1508,6 +1500,7 @@ public: } bool brokeExists() const; bool brokeExistsAbove() const; + bool brokeExistsBelow() const; // CONSTRUCTORS virtual ~AstNode() {} @@ -1788,20 +1781,22 @@ public: static void dumpTreeFileGdb(const char* filenamep = NULL); // METHODS - queries - // Else a $display, etc, that must be ordered with other displays - virtual bool isPure() const { return true; } // Changes control flow, disable some optimizations virtual bool isBrancher() const { return false; } // Else a AstTime etc that can't be pushed out virtual bool isGateOptimizable() const { return true; } // GateDedupable is a slightly larger superset of GateOptimzable (eg, AstNodeIf) virtual bool isGateDedupable() const { return isGateOptimizable(); } - // Else a AstTime etc that can't be substituted out - virtual bool isSubstOptimizable() const { return true; } - // Else a AstTime etc which output can't be predicted from input - virtual bool isPredictOptimizable() const { return true; } + // Needs verilated_heavy.h (uses std::string or some others) + virtual bool isHeavy() const { return false; } // Else creates output or exits, etc, not unconsumed virtual bool isOutputter() const { return false; } + // Else a AstTime etc which output can't be predicted from input + virtual bool isPredictOptimizable() const { return true; } + // Else a $display, etc, that must be ordered with other displays + virtual bool isPure() const { return true; } + // Else a AstTime etc that can't be substituted out + virtual bool isSubstOptimizable() const { return true; } // isUnlikely handles $stop or similar statement which means an above IF // statement is unlikely to be taken virtual bool isUnlikely() const { return false; } @@ -1998,6 +1993,43 @@ public: virtual bool same(const AstNode*) const { return true; } }; +class AstNodeQuadop : public AstNodeMath { + // Quaternary math +public: + AstNodeQuadop(AstType t, FileLine* fl, AstNode* lhs, AstNode* rhs, AstNode* ths, AstNode* fhs) + : AstNodeMath(t, fl) { + setOp1p(lhs); + setOp2p(rhs); + setOp3p(ths); + setOp4p(fhs); + } + ASTNODE_BASE_FUNCS(NodeQuadop) + AstNode* lhsp() const { return op1p(); } + AstNode* rhsp() const { return op2p(); } + AstNode* thsp() const { return op3p(); } + AstNode* fhsp() const { return op4p(); } + void lhsp(AstNode* nodep) { return setOp1p(nodep); } + void rhsp(AstNode* nodep) { return setOp2p(nodep); } + void thsp(AstNode* nodep) { return setOp3p(nodep); } + void fhsp(AstNode* nodep) { return setOp4p(nodep); } + // METHODS + // Set out to evaluation of a AstConst'ed + virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, + const V3Number& ths, const V3Number& fhs) + = 0; + virtual bool cleanLhs() const = 0; // True if LHS must have extra upper bits zero + virtual bool cleanRhs() const = 0; // True if RHS must have extra upper bits zero + virtual bool cleanThs() const = 0; // True if THS must have extra upper bits zero + virtual bool cleanFhs() const = 0; // True if THS must have extra upper bits zero + virtual bool sizeMattersLhs() const = 0; // True if output result depends on lhs size + virtual bool sizeMattersRhs() const = 0; // True if output result depends on rhs size + virtual bool sizeMattersThs() const = 0; // True if output result depends on ths size + virtual bool sizeMattersFhs() const = 0; // True if output result depends on ths size + virtual int instrCount() const { return widthInstrs(); } + virtual V3Hash sameHash() const { return V3Hash(); } + virtual bool same(const AstNode*) const { return true; } +}; + class AstNodeBiCom : public AstNodeBiop { // Binary math with commutative properties public: @@ -2090,6 +2122,20 @@ public: virtual bool same(const AstNode*) const { return true; } }; +class AstNodeProcedure : public AstNode { + // IEEE procedure: initial, final, always +public: + AstNodeProcedure(AstType t, FileLine* fl, AstNode* bodysp) + : AstNode(t, fl) { + addNOp2p(bodysp); + } + ASTNODE_BASE_FUNCS(NodeProcedure) + // METHODS + AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate + void addStmtp(AstNode* nodep) { addOp2p(nodep); } + bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); } +}; + class AstNodeStmt : public AstNode { // Statement -- anything that's directly under a function bool m_statement; // Really a statement (e.g. not a function with return) @@ -2323,9 +2369,8 @@ public: virtual AstNodeDType* skipRefToEnump() const = 0; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthAlignBytes() const = 0; - virtual int // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... - widthTotalBytes() const = 0; + virtual int widthTotalBytes() const = 0; virtual bool maybePointedTo() const { return true; } // Iff has a non-null refDTypep(), as generic node function virtual AstNodeDType* virtRefDTypep() const { return NULL; } @@ -2429,9 +2474,8 @@ public: } // op1 = AstMember list void addMembersp(AstNode* nodep) { addNOp1p(nodep); } bool packed() const { return m_packed; } - bool packedUnsup() const { - return true; - } // packed() but as don't support unpacked, presently all structs + // packed() but as don't support unpacked, presently all structs + static bool packedUnsup() { return true; } void isFourstate(bool flag) { m_isFourstate = flag; } virtual bool isFourstate() const { return m_isFourstate; } void clearCache() { m_members.clear(); } @@ -2440,7 +2484,7 @@ public: MemberNameMap::const_iterator it = m_members.find(name); return (it == m_members.end()) ? NULL : it->second; } - int lsb() const { return 0; } + static int lsb() { return 0; } int msb() const { return dtypep()->width() - 1; } // Packed classes look like arrays VNumRange declRange() const { return VNumRange(msb(), lsb(), false); } }; @@ -2482,10 +2526,8 @@ public: virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep), V3Hash(msb()), V3Hash(lsb())); } - AstNodeDType* getChildDTypep() const { return childDTypep(); } - AstNodeDType* childDTypep() const { - return VN_CAST(op1p(), NodeDType); - } // op1 = Range of variable + virtual AstNodeDType* getChildDTypep() const { return childDTypep(); } + AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } @@ -2680,11 +2722,13 @@ private: string m_dotted; // Dotted part of scope the name()ed task/func is under or "" string m_inlinedDots; // Dotted hierarchy flattened out AstNodeModule* m_packagep; // Package hierarchy + bool m_pli; // Pli system call ($name) public: AstNodeFTaskRef(AstType t, FileLine* fl, bool statement, AstNode* namep, AstNode* pinsp) : AstNodeStmt(t, fl, statement) , m_taskp(NULL) - , m_packagep(NULL) { + , m_packagep(NULL) + , m_pli(false) { setOp1p(namep); addNOp3p(pinsp); } @@ -2692,7 +2736,8 @@ public: : AstNodeStmt(t, fl, statement) , m_taskp(NULL) , m_name(name) - , m_packagep(NULL) { + , m_packagep(NULL) + , m_pli(false) { addNOp3p(pinsp); } ASTNODE_BASE_FUNCS(NodeFTaskRef) @@ -2716,6 +2761,8 @@ public: void dotted(const string& name) { m_dotted = name; } AstNodeModule* packagep() const { return m_packagep; } void packagep(AstNodeModule* nodep) { m_packagep = nodep; } + bool pli() const { return m_pli; } + void pli(bool flag) { m_pli = flag; } // op1 = namep AstNode* namep() const { return op1p(); } // op2 = reserved for AstMethodCall diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index c7fb643c2..78f710b73 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -24,7 +24,6 @@ #include "V3PartitionGraph.h" // Just for mtask dumping #include "V3EmitCBase.h" -#include #include #include @@ -282,16 +281,16 @@ string AstVar::verilogKwd() const { class AstVar::VlArgTypeRecursed { public: - string m_oref; // To output, reference part before name, "&" - string m_osuffix; // To output, suffixed after name, "[3]" - string m_oprefix; // To output, prefixed before name, "Foo_t" - void clear() { - m_oref.clear(); - m_osuffix.clear(); - m_oprefix.clear(); - } - string refParen(const string& name) { - return m_oref.empty() ? name : "(" + m_oref + " " + name + ")"; + bool m_isRef; // Is it a reference? + string m_type; // The base type, e.g.: "Foo_t"s + string m_dims; // Array dimensions, e.g.: "[3][2][1]" + string render(const string& name) { + string out; + out += m_type; + out += " "; + out += m_isRef ? "(&" + name + ")" : name; + out += m_dims; + return out; } }; @@ -301,126 +300,86 @@ string AstVar::vlArgType(bool named, bool forReturn, bool forFunc, const string& string ostatic; if (isStatic() && namespc.empty()) ostatic = "static "; - VlArgTypeRecursed info = vlArgTypeRecurse(forFunc, dtypep(), false); + VlArgTypeRecursed info = vlArgTypeRecurse(forFunc, dtypep()); string oname; if (named) { - oname += " "; if (!namespc.empty()) oname += namespc + "::"; oname += VIdProtect::protectIf(name(), protect()); } - return ostatic + info.m_oprefix + info.refParen(oname) + info.m_osuffix; + return ostatic + info.render(oname); } AstVar::VlArgTypeRecursed AstVar::vlArgTypeRecurse(bool forFunc, const AstNodeDType* dtypep, - bool arrayed) const { + bool compound) const { + VlArgTypeRecursed info; + info.m_isRef + = isDpiOpenArray() || (forFunc && (isWritable() || direction().isRefOrConstRef())); + dtypep = dtypep->skipRefp(); if (const AstAssocArrayDType* adtypep = VN_CAST_CONST(dtypep, AssocArrayDType)) { - VlArgTypeRecursed key = vlArgTypeRecurse(forFunc, adtypep->keyDTypep(), true); - VlArgTypeRecursed sub = vlArgTypeRecurse(forFunc, adtypep->subDTypep(), true); - string out = "VlAssocArray<"; - out += key.m_oprefix; - if (!key.m_osuffix.empty() || !key.m_oref.empty()) { - out += " " + key.m_osuffix + key.m_oref; - } - out += ", "; - out += sub.m_oprefix; - if (!sub.m_osuffix.empty() || !sub.m_oref.empty()) { - out += " " + sub.m_osuffix + sub.m_oref; - } - out += "> "; - VlArgTypeRecursed info; - info.m_oprefix = out; - return info; + const VlArgTypeRecursed key = vlArgTypeRecurse(false, adtypep->keyDTypep(), true); + const VlArgTypeRecursed val = vlArgTypeRecurse(false, adtypep->subDTypep(), true); + info.m_type = "VlAssocArray<" + key.m_type + ", " + val.m_type + ">"; } else if (const AstDynArrayDType* adtypep = VN_CAST_CONST(dtypep, DynArrayDType)) { - VlArgTypeRecursed sub = vlArgTypeRecurse(forFunc, adtypep->subDTypep(), true); - string out = "VlQueue<"; - out += sub.m_oprefix; - if (!sub.m_osuffix.empty() || !sub.m_oref.empty()) { - out += " " + sub.m_osuffix + sub.m_oref; - } - out += "> "; - VlArgTypeRecursed info; - info.m_oprefix = out; - return info; + const VlArgTypeRecursed sub = vlArgTypeRecurse(false, adtypep->subDTypep(), true); + info.m_type = "VlQueue<" + sub.m_type + ">"; } else if (const AstQueueDType* adtypep = VN_CAST_CONST(dtypep, QueueDType)) { - VlArgTypeRecursed sub = vlArgTypeRecurse(forFunc, adtypep->subDTypep(), true); - VlArgTypeRecursed info; - string out = "VlQueue<" + sub.m_oprefix; - if (!sub.m_osuffix.empty() || !sub.m_oref.empty()) { - out += " " + sub.m_osuffix + sub.m_oref; - } + const VlArgTypeRecursed sub = vlArgTypeRecurse(false, adtypep->subDTypep(), true); + info.m_type = "VlQueue<" + sub.m_type; // + 1 below as VlQueue uses 0 to mean unlimited, 1 to mean size() max is 1 - if (adtypep->boundp()) out += ", " + cvtToStr(adtypep->boundConst() + 1); - out += "> "; - info.m_oprefix = out; - return info; + if (adtypep->boundp()) info.m_type += ", " + cvtToStr(adtypep->boundConst() + 1); + info.m_type += ">"; } else if (const AstClassRefDType* adtypep = VN_CAST_CONST(dtypep, ClassRefDType)) { - VlArgTypeRecursed info; - info.m_oprefix = "VlClassRef<" + EmitCBaseVisitor::prefixNameProtect(adtypep) + ">"; - return info; + info.m_type = "VlClassRef<" + EmitCBaseVisitor::prefixNameProtect(adtypep) + ">"; } else if (const AstUnpackArrayDType* adtypep = VN_CAST_CONST(dtypep, UnpackArrayDType)) { - VlArgTypeRecursed info = vlArgTypeRecurse(forFunc, adtypep->subDTypep(), arrayed); - info.m_osuffix = "[" + cvtToStr(adtypep->declRange().elements()) + "]" + info.m_osuffix; - return info; - } else if (const AstBasicDType* bdtypep = dtypep->basicp()) { - string otype; - string oarray; - bool strtype = bdtypep->keyword() == AstBasicDTypeKwd::STRING; - string bitvec; - if (!bdtypep->isOpaque() && !v3Global.opt.protectIds()) { - // We don't print msb()/lsb() as multidim packed would require recursion, - // and may confuse users as C++ data is stored always with bit 0 used - bitvec += "/*" + cvtToStr(dtypep->width() - 1) + ":0*/"; + if (compound) { + v3fatalSrc("Dynamic arrays or queues with unpacked elements are not yet supported"); } - if ((forFunc && isReadOnly()) || bdtypep->keyword() == AstBasicDTypeKwd::CHARPTR - || bdtypep->keyword() == AstBasicDTypeKwd::SCOPEPTR) - otype += "const "; + const VlArgTypeRecursed sub = vlArgTypeRecurse(false, adtypep->subDTypep(), compound); + info.m_type = sub.m_type; + info.m_dims = "[" + cvtToStr(adtypep->declRange().elements()) + "]" + sub.m_dims; + } else if (const AstBasicDType* bdtypep = dtypep->basicp()) { + // We don't print msb()/lsb() as multidim packed would require recursion, + // and may confuse users as C++ data is stored always with bit 0 used + const string bitvec = (!bdtypep->isOpaque() && !v3Global.opt.protectIds()) + ? "/*" + cvtToStr(dtypep->width() - 1) + ":0*/" + : ""; if (bdtypep->keyword() == AstBasicDTypeKwd::CHARPTR) { - otype += "char*"; + info.m_type = "const char*"; } else if (bdtypep->keyword() == AstBasicDTypeKwd::SCOPEPTR) { - otype += "VerilatedScope*"; + info.m_type = "const VerilatedScope*"; } else if (bdtypep->keyword() == AstBasicDTypeKwd::DOUBLE) { - otype += "double"; + info.m_type = "double"; } else if (bdtypep->keyword() == AstBasicDTypeKwd::FLOAT) { - otype += "float"; - } else if (strtype) { - otype += "std::string"; + info.m_type = "float"; + } else if (bdtypep->keyword() == AstBasicDTypeKwd::STRING) { + info.m_type = "std::string"; } else if (dtypep->widthMin() <= 8) { // Handle unpacked arrays; not bdtypep->width - otype += "CData" + bitvec; + info.m_type = "CData" + bitvec; } else if (dtypep->widthMin() <= 16) { - otype += "SData" + bitvec; + info.m_type = "SData" + bitvec; } else if (dtypep->widthMin() <= VL_IDATASIZE) { - otype += "IData" + bitvec; + info.m_type = "IData" + bitvec; } else if (dtypep->isQuad()) { - otype += "QData" + bitvec; + info.m_type = "QData" + bitvec; } else if (dtypep->isWide()) { - if (arrayed) { - otype += "VlWide<" + cvtToStr(dtypep->widthWords()) + "> "; + if (compound) { + info.m_type = "VlWide<" + cvtToStr(dtypep->widthWords()) + "> "; } else { - otype += "WData" + bitvec; // []'s added later - oarray += "[" + cvtToStr(dtypep->widthWords()) + "]"; + info.m_type += "WData" + bitvec; // []'s added later + info.m_dims = "[" + cvtToStr(dtypep->widthWords()) + "]"; } } - - string oref; - if (isDpiOpenArray() - || (forFunc - && (isWritable() || direction() == VDirection::REF - || direction() == VDirection::CONSTREF || (strtype && isNonOutput())))) { - oref = "&"; - } - - VlArgTypeRecursed info; - info.m_oprefix = otype; - info.m_osuffix = oarray; - info.m_oref = oref; - // UINFO(9, "vlArgRec "<<"oprefix="<prettyName()); } + + UASSERT_OBJ(!compound || info.m_dims.empty(), this, "Declaring C array inside compound type"); + + if (forFunc && isReadOnly() && info.m_isRef) { info.m_type = "const " + info.m_type; } + + return info; } string AstVar::vlEnumType() const { @@ -472,29 +431,52 @@ string AstVar::vlEnumDir() const { return out; } -string AstVar::vlPropInit() const { +string AstVar::vlPropDecl(string propName) const { string out; - out = vlEnumType(); // VLVT_UINT32 etc - out += ", " + vlEnumDir(); // VLVD_IN etc - if (AstBasicDType* bdtypep = basicp()) { - out += ", VerilatedVarProps::Packed()"; - out += ", " + cvtToStr(bdtypep->left()) + ", " + cvtToStr(bdtypep->right()); - } - bool first = true; - for (AstNodeDType* dtp = dtypep(); dtp;) { + + std::vector ulims; // Unpacked dimension limits + for (const AstNodeDType* dtp = dtypep(); dtp;) { dtp = dtp->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node - if (AstNodeArrayDType* adtypep = VN_CAST(dtp, NodeArrayDType)) { - if (first) { - out += ", VerilatedVarProps::Unpacked()"; - first = false; - } - out += ", " + cvtToStr(adtypep->declRange().left()) + ", " - + cvtToStr(adtypep->declRange().right()); + if (const AstNodeArrayDType* const adtypep = VN_CAST_CONST(dtp, NodeArrayDType)) { + ulims.push_back(adtypep->declRange().left()); + ulims.push_back(adtypep->declRange().right()); dtp = adtypep->subDTypep(); } else { break; // AstBasicDType - nothing below } } + + if (!ulims.empty()) { + out += "static const int " + propName + "__ulims["; + out += cvtToStr(ulims.size()); + out += "] = {"; + std::vector::const_iterator it = ulims.begin(); + out += cvtToStr(*it); + while (++it != ulims.end()) { + out += ", "; + out += cvtToStr(*it); + } + out += "};\n"; + } + + out += "static const VerilatedVarProps "; + out += propName; + out += "("; + out += vlEnumType(); // VLVT_UINT32 etc + out += ", " + vlEnumDir(); // VLVD_IN etc + if (const AstBasicDType* const bdtypep = basicp()) { + out += ", VerilatedVarProps::Packed()"; + out += ", " + cvtToStr(bdtypep->left()); + out += ", " + cvtToStr(bdtypep->right()); + } + + if (!ulims.empty()) { + out += ", VerilatedVarProps::Unpacked()"; + out += ", " + cvtToStr(ulims.size() / 2); + out += ", " + propName + "__ulims"; + } + + out += ");\n"; return out; } @@ -746,6 +728,14 @@ AstNode* AstArraySel::baseFromp(AstNode* nodep) { return nodep; } +const char* AstJumpBlock::broken() const { + BROKEN_RTN(!labelp()->brokeExistsBelow()); + return NULL; +} +void AstJumpBlock::cloneRelink() { + if (m_labelp->clonep()) m_labelp = m_labelp->clonep(); +} + const char* AstScope::broken() const { BROKEN_RTN(m_aboveScopep && !m_aboveScopep->brokeExists()); BROKEN_RTN(m_aboveCellp && !m_aboveCellp->brokeExists()); @@ -753,7 +743,6 @@ const char* AstScope::broken() const { BROKEN_RTN(m_modp && !m_modp->brokeExists()); return NULL; } - void AstScope::cloneRelink() { if (m_aboveScopep && m_aboveScopep->clonep()) m_aboveScopep->clonep(); if (m_aboveCellp && m_aboveCellp->clonep()) m_aboveCellp->clonep(); @@ -761,7 +750,6 @@ void AstScope::cloneRelink() { static_cast(m_modp)->clonep(); } } - string AstScope::nameDotless() const { string out = shortName(); string::size_type pos; @@ -780,7 +768,6 @@ string AstScopeName::scopePrettyNameFormatter(AstText* scopeTextp) const { if (out.substr(0, 1) == ".") out.replace(0, 1, ""); return AstNode::prettyName(out); } - string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const { string out; for (AstText* textp = scopeTextp; textp; textp = VN_CAST(textp->nextp(), Text)) { @@ -977,27 +964,37 @@ void AstWhile::addNextStmt(AstNode* newp, AstNode* belowp) { //====================================================================== // Per-type Debugging +// Render node address for dumps. By default this is just the address +// printed as hex, but with --dump-tree-addrids we map addresses to short +// strings with a bijection to aid human readability. Observe that this might +// not actually be a unique identifier as the address can get reused after a +// node has been freed. +static std::string nodeAddr(const AstNode* nodep) { + return v3Global.opt.dumpTreeAddrids() ? v3Global.ptrToId(nodep) : cvtToHex(nodep); +} + void AstNode::dump(std::ostream& str) const { str << typeName() << " " - << cvtToHex(this) - //<<" "<m_backp + << nodeAddr(this) + //<< " " << nodeAddr(m_backp) << " = editCountLast()) ? "#>" : ">") - << " {" << fileline()->filenameLetters() << std::dec << fileline()->lastLineno() << "}"; - if (user1p()) str << " u1=" << cvtToHex(user1p()); - if (user2p()) str << " u2=" << cvtToHex(user2p()); - if (user3p()) str << " u3=" << cvtToHex(user3p()); - if (user4p()) str << " u4=" << cvtToHex(user4p()); - if (user5p()) str << " u5=" << cvtToHex(user5p()); + << " {" << fileline()->filenameLetters() << std::dec << fileline()->lastLineno() + << fileline()->firstColumnLetters() << "}"; + if (user1p()) str << " u1=" << nodeAddr(user1p()); + if (user2p()) str << " u2=" << nodeAddr(user2p()); + if (user3p()) str << " u3=" << nodeAddr(user3p()); + if (user4p()) str << " u4=" << nodeAddr(user4p()); + if (user5p()) str << " u5=" << nodeAddr(user5p()); if (hasDType()) { // Final @ so less likely to by accident read it as a nodep if (dtypep() == this) { str << " @dt=this@"; } else { - str << " @dt=" << cvtToHex(dtypep()) << "@"; + str << " @dt=" << nodeAddr(dtypep()) << "@"; } if (AstNodeDType* dtp = dtypep()) { dtp->dumpSmall(str); } } else { // V3Broken will throw an error - if (dtypep()) str << " %Error-dtype-exp=null,got=" << cvtToHex(dtypep()); + if (dtypep()) str << " %Error-dtype-exp=null,got=" << nodeAddr(dtypep()); } if (name() != "") { if (VN_IS(this, Const)) { @@ -1142,6 +1139,15 @@ void AstJumpGo::dump(std::ostream& str) const { str << "%Error:UNLINKED"; } } +void AstJumpLabel::dump(std::ostream& str) const { + this->AstNode::dump(str); + str << " -> "; + if (blockp()) { + blockp()->dump(str); + } else { + str << "%Error:UNLINKED"; + } +} void AstMemberSel::dump(std::ostream& str) const { this->AstNode::dump(str); str << " -> "; @@ -1218,12 +1224,16 @@ void AstRange::dump(std::ostream& str) const { } void AstRefDType::dump(std::ostream& str) const { this->AstNodeDType::dump(str); - if (defp()) { + if (typedefp() || subDTypep()) { static bool s_recursing = false; if (!s_recursing) { // Prevent infinite dump if circular typedefs s_recursing = true; str << " -> "; - defp()->dump(str); + if (typedefp()) { + typedefp()->dump(str); + } else if (subDTypep()) { + subDTypep()->dump(str); + } s_recursing = false; } } else { @@ -1239,7 +1249,7 @@ void AstNodeDType::dump(std::ostream& str) const { this->AstNode::dump(str); if (generic()) str << " [GENERIC]"; if (AstNodeDType* dtp = virtRefDTypep()) { - str << " refdt=" << cvtToHex(dtp); + str << " refdt=" << nodeAddr(dtp); dtp->dumpSmall(str); } } @@ -1384,7 +1394,7 @@ void AstVarScope::dump(std::ostream& str) const { } void AstVarXRef::dump(std::ostream& str) const { this->AstNode::dump(str); - if (packagep()) { str << " pkg=" << cvtToHex(packagep()); } + if (packagep()) { str << " pkg=" << nodeAddr(packagep()); } if (lvalue()) { str << " [LV] => "; } else { @@ -1402,7 +1412,7 @@ void AstVarXRef::dump(std::ostream& str) const { } void AstVarRef::dump(std::ostream& str) const { this->AstNode::dump(str); - if (packagep()) { str << " pkg=" << cvtToHex(packagep()); } + if (packagep()) { str << " pkg=" << nodeAddr(packagep()); } if (lvalue()) { str << " [LV] => "; } else { @@ -1454,7 +1464,7 @@ void AstParseRef::dump(std::ostream& str) const { } void AstPackageRef::dump(std::ostream& str) const { this->AstNode::dump(str); - if (packagep()) { str << " pkg=" << cvtToHex(packagep()); } + if (packagep()) { str << " pkg=" << nodeAddr(packagep()); } str << " -> "; if (packagep()) { packagep()->dump(str); @@ -1462,7 +1472,10 @@ void AstPackageRef::dump(std::ostream& str) const { str << "UNLINKED"; } } -void AstDot::dump(std::ostream& str) const { this->AstNode::dump(str); } +void AstDot::dump(std::ostream& str) const { + this->AstNode::dump(str); + if (colon()) str << "[::]"; +} void AstActive::dump(std::ostream& str) const { this->AstNode::dump(str); str << " => "; @@ -1474,7 +1487,7 @@ void AstActive::dump(std::ostream& str) const { } void AstNodeFTaskRef::dump(std::ostream& str) const { this->AstNode::dump(str); - if (packagep()) { str << " pkg=" << cvtToHex(packagep()); } + if (packagep()) { str << " pkg=" << nodeAddr(packagep()); } str << " -> "; if (dotted() != "") { str << ".=" << dotted() << " "; } if (taskp()) { @@ -1506,6 +1519,8 @@ void AstBegin::dump(std::ostream& str) const { } void AstCoverDecl::dump(std::ostream& str) const { this->AstNode::dump(str); + if (!page().empty()) str << " page=" << page(); + if (!linescov().empty()) str << " lc=" << linescov(); if (this->dataDeclNullp()) { str << " -> "; this->dataDeclNullp()->dump(str); diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index f113607b7..4f9c1d99a 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -319,6 +319,7 @@ public: , m_packagep(NULL) {} ASTNODE_NODE_FUNCS(Class) virtual string verilogKwd() const { return "class"; } + virtual bool isHeavy() const { return true; } virtual bool maybePointedTo() const { return true; } virtual void dump(std::ostream& str) const; virtual const char* broken() const { @@ -345,19 +346,18 @@ public: }; class AstClassExtends : public AstNode { - // Children: AstClassRefDType during early parse, then moves to dtype + // Children: List of AstParseRef for packages/classes + // during early parse, then moves to dtype public: - AstClassExtends(FileLine* fl, AstNodeDType* dtp) + AstClassExtends(FileLine* fl, AstNode* classOrPkgsp) : ASTGEN_SUPER(fl) { - childDTypep(dtp); // Only for parser + setNOp1p(classOrPkgsp); // Only for parser } ASTNODE_NODE_FUNCS(ClassExtends) virtual string verilogKwd() const { return "extends"; } virtual bool hasDType() const { return true; } - AstNodeDType* getChildDTypep() const { return childDTypep(); } - // op1 = Type assigning to - AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } + AstNodeDType* classOrPkgsp() const { return VN_CAST(op1p(), NodeDType); } + void classOrPkgsp(AstNodeDType* nodep) { setOp1p(nodep); } AstClass* classp() const; // Class being extended (after link) }; @@ -541,6 +541,7 @@ public: virtual string prettyDTypeName() const; virtual void dumpSmall(std::ostream& str) const; virtual V3Hash sameHash() const { return V3Hash(m_refDTypep); } + virtual bool isHeavy() const { return true; } AstNodeDType* getChildDTypep() const { return childDTypep(); } // op1 = Range of variable AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } @@ -603,6 +604,7 @@ public: virtual string prettyDTypeName() const; virtual void dumpSmall(std::ostream& str) const; virtual V3Hash sameHash() const { return V3Hash(m_refDTypep); } + virtual bool isHeavy() const { return true; } AstNodeDType* getChildDTypep() const { return childDTypep(); } // op1 = Range of variable AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } @@ -815,6 +817,7 @@ public: BROKEN_RTN(dtypep() != this); return NULL; } + virtual bool isHeavy() const { return keyword() == AstBasicDTypeKwd::STRING; } AstRange* rangep() const { return VN_CAST(op1p(), Range); } // op1 = Range of variable void rangep(AstRange* nodep) { setNOp1p(nodep); } void setSignedState(const VSigning& signst) { @@ -832,8 +835,8 @@ public: virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthAlignBytes() const; - virtual int - widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... + // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... + virtual int widthTotalBytes() const; virtual bool isFourstate() const { return keyword().isFourstate(); } AstBasicDTypeKwd keyword() const { // Avoid using - use isSomething accessors instead return m.m_keyword; @@ -855,9 +858,8 @@ public: bool isDpiPrimitive() const { // DPI uses a primitive type return !isDpiBitVec() && !isDpiLogicVec(); } - const VNumRange& nrange() const { - return m.m_nrange; - } // Generally the msb/lsb/etc funcs should be used instead + // Generally the msb/lsb/etc funcs should be used instead + const VNumRange& nrange() const { return m.m_nrange; } int msb() const { return (rangep() ? rangep()->msbConst() : m.m_nrange.hi()); } int lsb() const { return (rangep() ? rangep()->lsbConst() : m.m_nrange.lo()); } int left() const { return littleEndian() ? lsb() : msb(); } // How to show a declaration @@ -1067,6 +1069,7 @@ public: virtual void dumpSmall(std::ostream& str) const; virtual V3Hash sameHash() const { return V3Hash(m_refDTypep); } virtual string prettyDTypeName() const; + virtual bool isHeavy() const { return true; } AstNodeDType* getChildDTypep() const { return childDTypep(); } // op1 = Range of variable AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } @@ -1095,25 +1098,24 @@ public: class AstRefDType : public AstNodeDType { private: + // Pre-Width must reference the Typeref, not what it points to, as some child + // types like AstBracketArrayType will disappear and can't lose the handle + AstTypedef* m_typedefp; // referenced type + // Post-width typedefs are removed and point to type directly AstNodeDType* m_refDTypep; // data type pointed to, BELOW the AstTypedef string m_name; // Name of an AstTypedef AstNodeModule* m_packagep; // Package hierarchy public: AstRefDType(FileLine* fl, const string& name) : ASTGEN_SUPER(fl) + , m_typedefp(NULL) , m_refDTypep(NULL) , m_name(name) , m_packagep(NULL) {} - AstRefDType(FileLine* fl, AstNodeDType* defp) - : ASTGEN_SUPER(fl) - , m_refDTypep(defp) - , m_packagep(NULL) { - dtypeFrom(defp->dtypep()); - widthFromSub(subDTypep()); - } class FlagTypeOfExpr {}; // type(expr) for parser only AstRefDType(FileLine* fl, FlagTypeOfExpr, AstNode* typeofp) : ASTGEN_SUPER(fl) + , m_typedefp(NULL) , m_refDTypep(NULL) , m_packagep(NULL) { setOp2p(typeofp); @@ -1121,47 +1123,53 @@ public: ASTNODE_NODE_FUNCS(RefDType) // METHODS virtual const char* broken() const { + BROKEN_RTN(m_typedefp && !m_typedefp->brokeExists()); BROKEN_RTN(m_refDTypep && !m_refDTypep->brokeExists()); return NULL; } virtual void cloneRelink() { + if (m_typedefp && m_typedefp->clonep()) { m_typedefp = m_typedefp->clonep(); } if (m_refDTypep && m_refDTypep->clonep()) { m_refDTypep = m_refDTypep->clonep(); } } virtual bool same(const AstNode* samep) const { const AstRefDType* asamep = static_cast(samep); - return (m_refDTypep == asamep->m_refDTypep && m_name == asamep->m_name - && m_packagep == asamep->m_packagep); + return (m_typedefp == asamep->m_typedefp && m_refDTypep == asamep->m_refDTypep + && m_name == asamep->m_name && m_packagep == asamep->m_packagep); } virtual bool similarDType(AstNodeDType* samep) const { return skipRefp()->similarDType(samep->skipRefp()); } - virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep), V3Hash(m_packagep)); } + virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_typedefp), V3Hash(m_packagep)); } virtual void dump(std::ostream& str = std::cout) const; virtual string name() const { return m_name; } virtual string prettyDTypeName() const { return subDTypep() ? subDTypep()->name() : prettyName(); } virtual AstBasicDType* basicp() const { return subDTypep() ? subDTypep()->basicp() : NULL; } + AstNodeDType* subDTypep() const { + if (typedefp()) return typedefp()->subDTypep(); + return refDTypep(); // Maybe NULL + } virtual AstNodeDType* skipRefp() const { // Skip past both the Ref and the Typedef - if (defp()) { - return defp()->skipRefp(); + if (subDTypep()) { + return subDTypep()->skipRefp(); } else { v3fatalSrc("Typedef not linked"); return NULL; } } virtual AstNodeDType* skipRefToConstp() const { - if (defp()) { - return defp()->skipRefToConstp(); + if (subDTypep()) { + return subDTypep()->skipRefToConstp(); } else { v3fatalSrc("Typedef not linked"); return NULL; } } virtual AstNodeDType* skipRefToEnump() const { - if (defp()) { - return defp()->skipRefToEnump(); + if (subDTypep()) { + return subDTypep()->skipRefToEnump(); } else { v3fatalSrc("Typedef not linked"); return NULL; @@ -1171,15 +1179,13 @@ public: virtual int widthTotalBytes() const { return dtypeSkipRefp()->widthTotalBytes(); } void name(const string& flag) { m_name = flag; } // op1 = Range of variable - AstNodeDType* dtypeSkipRefp() const { return defp()->skipRefp(); } - AstNodeDType* defp() const { - return m_refDTypep; - } // Code backward compatibility name for refDTypep + AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } + AstTypedef* typedefp() const { return m_typedefp; } + void typedefp(AstTypedef* nodep) { m_typedefp = nodep; } AstNodeDType* refDTypep() const { return m_refDTypep; } void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } virtual AstNodeDType* virtRefDTypep() const { return refDTypep(); } virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } - virtual AstNodeDType* subDTypep() const { return m_refDTypep; } AstNodeModule* packagep() const { return m_packagep; } void packagep(AstNodeModule* nodep) { m_packagep = nodep; } AstNode* typeofp() const { return op2p(); } @@ -1902,11 +1908,11 @@ public: VDirection declDirection() const { return m_declDirection; } void varType(AstVarType type) { m_varType = type; } void varType2Out() { - m_tristate = 0; + m_tristate = false; m_direction = VDirection::OUTPUT; } void varType2In() { - m_tristate = 0; + m_tristate = false; m_direction = VDirection::INPUT; } AstBasicDTypeKwd declKwd() const { return m_declKwd; } @@ -1918,7 +1924,7 @@ public: string vlArgType(bool named, bool forReturn, bool forFunc, const string& namespc = "") const; string vlEnumType() const; // Return VerilatorVarType: VLVT_UINT32, etc string vlEnumDir() const; // Return VerilatorVarDir: VLVD_INOUT, etc - string vlPropInit() const; // Return VerilatorVarProps initializer + string vlPropDecl(string propName) const; // Return VerilatorVarProps declaration void combineType(AstVarType type); AstNodeDType* getChildDTypep() const { return childDTypep(); } // op1 = Range of variable @@ -2078,7 +2084,7 @@ public: private: class VlArgTypeRecursed; VlArgTypeRecursed vlArgTypeRecurse(bool forFunc, const AstNodeDType* dtypep, - bool arrayed) const; + bool compound = false) const; }; class AstDefParam : public AstNode { @@ -2867,9 +2873,11 @@ public: class AstDot : public AstNode { // A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef // These are eliminated in the link stage + bool m_colon; // Is a "::" instead of a "." (lhs must be package/class) public: - AstDot(FileLine* fl, AstNode* lhsp, AstNode* rhsp) - : ASTGEN_SUPER(fl) { + AstDot(FileLine* fl, bool colon, AstNode* lhsp, AstNode* rhsp) + : ASTGEN_SUPER(fl) + , m_colon(colon) { setOp1p(lhsp); setOp2p(rhsp); } @@ -2877,23 +2885,28 @@ public: // For parser, make only if non-null package static AstNode* newIfPkg(FileLine* fl, AstPackage* packagep, AstNode* rhsp) { if (!packagep) return rhsp; - return new AstDot(fl, new AstPackageRef(fl, packagep), rhsp); + return new AstDot(fl, true, new AstPackageRef(fl, packagep), rhsp); } virtual void dump(std::ostream& str) const; virtual string emitVerilog() { V3ERROR_NA_RETURN(""); } virtual string emitC() { V3ERROR_NA_RETURN(""); } AstNode* lhsp() const { return op1p(); } AstNode* rhsp() const { return op2p(); } + bool colon() const { return m_colon; } }; -class AstUnbounded : public AstNode { +class AstUnbounded : public AstNodeMath { // A $ in the parser, used for unbounded and queues + // Due to where is used, treated as Signed32 public: explicit AstUnbounded(FileLine* fl) - : ASTGEN_SUPER(fl) {} + : ASTGEN_SUPER(fl) { + dtypeSetSigned32(); + } ASTNODE_NODE_FUNCS(Unbounded) virtual string emitVerilog() { return "$"; } virtual string emitC() { V3ERROR_NA_RETURN(""); } + virtual bool cleanOut() const { return true; } }; //###################################################################### @@ -3076,25 +3089,34 @@ public: bool hasCombo() const; // Includes a COMBO SenItem }; -class AstAlways : public AstNode { +class AstFinal : public AstNodeProcedure { +public: + AstFinal(FileLine* fl, AstNode* bodysp) + : ASTGEN_SUPER(fl, bodysp) {} + ASTNODE_NODE_FUNCS(Final) +}; + +class AstInitial : public AstNodeProcedure { +public: + AstInitial(FileLine* fl, AstNode* bodysp) + : ASTGEN_SUPER(fl, bodysp) {} + ASTNODE_NODE_FUNCS(Initial) +}; + +class AstAlways : public AstNodeProcedure { VAlwaysKwd m_keyword; public: AstAlways(FileLine* fl, VAlwaysKwd keyword, AstSenTree* sensesp, AstNode* bodysp) - : ASTGEN_SUPER(fl) + : ASTGEN_SUPER(fl, bodysp) , m_keyword(keyword) { addNOp1p(sensesp); - addNOp2p(bodysp); } ASTNODE_NODE_FUNCS(Always) // virtual void dump(std::ostream& str) const; AstSenTree* sensesp() const { return VN_CAST(op1p(), SenTree); } // op1 = Sensitivity list - AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate - void addStmtp(AstNode* nodep) { addOp2p(nodep); } VAlwaysKwd keyword() const { return m_keyword; } - // Special accessors - bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); } }; class AstAlwaysPublic : public AstNodeStmt { @@ -3300,14 +3322,17 @@ private: string m_page; string m_text; string m_hier; - int m_column; + string m_linescov; + int m_offset; // Offset column numbers to uniq-ify IFs int m_binNum; // Set by V3EmitCSyms to tell final V3Emit what to increment public: - AstCoverDecl(FileLine* fl, int column, const string& page, const string& comment) + AstCoverDecl(FileLine* fl, const string& page, const string& comment, const string& linescov, + int offset) : ASTGEN_SUPER(fl) { - m_text = comment; m_page = page; - m_column = column; + m_text = comment; + m_linescov = linescov; + m_offset = offset; m_binNum = 0; m_dataDeclp = NULL; } @@ -3325,10 +3350,11 @@ public: virtual void dump(std::ostream& str) const; virtual int instrCount() const { return 1 + 2 * instrCountLd(); } virtual bool maybePointedTo() const { return true; } - int column() const { return m_column; } void binNum(int flag) { m_binNum = flag; } int binNum() const { return m_binNum; } + int offset() const { return m_offset; } const string& comment() const { return m_text; } // text to insert in code + const string& linescov() const { return m_linescov; } const string& page() const { return m_page; } const string& hier() const { return m_hier; } void hier(const string& flag) { m_hier = flag; } @@ -3336,8 +3362,8 @@ public: virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { const AstCoverDecl* asamep = static_cast(samep); - return (fileline() == asamep->fileline() && hier() == asamep->hier() - && comment() == asamep->comment() && column() == asamep->column()); + return (fileline() == asamep->fileline() && linescov() == asamep->linescov() + && hier() == asamep->hier() && comment() == asamep->comment()); } virtual bool isPredictOptimizable() const { return false; } void dataDeclp(AstCoverDecl* nodep) { m_dataDeclp = nodep; } @@ -3626,6 +3652,7 @@ public: virtual string emitVerilog() { return "%f" + verilogKwd() + "(%l)"; } virtual string emitC() { V3ERROR_NA_RETURN(""); } virtual bool isGateOptimizable() const { return false; } + virtual bool isHeavy() const { return true; } virtual bool isPredictOptimizable() const { return false; } virtual bool isOutputter() const { return true; } virtual bool cleanOut() const { return true; } @@ -3777,6 +3804,7 @@ public: ASTNODE_NODE_FUNCS(FOpen) virtual string verilogKwd() const { return "$fopen"; } virtual bool isGateOptimizable() const { return false; } + virtual bool isHeavy() const { return true; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } virtual bool isOutputter() const { return true; } @@ -3788,6 +3816,28 @@ public: AstNode* modep() const { return op3p(); } }; +class AstFOpenMcd : public AstNodeStmt { + // Although a system function in IEEE, here a statement which sets the file pointer (MCD) +public: + AstFOpenMcd(FileLine* fl, AstNode* filep, AstNode* filenamep) + : ASTGEN_SUPER(fl) { + setOp1p(filep); + setOp2p(filenamep); + } + ASTNODE_NODE_FUNCS(FOpenMcd) + virtual string verilogKwd() const { return "$fopen"; } + virtual bool isGateOptimizable() const { return false; } + virtual bool isHeavy() const { return true; } + virtual bool isPredictOptimizable() const { return false; } + virtual bool isPure() const { return false; } + virtual bool isOutputter() const { return true; } + virtual bool isUnlikely() const { return true; } + virtual V3Hash sameHash() const { return V3Hash(); } + virtual bool same(const AstNode* samep) const { return true; } + AstNode* filep() const { return op1p(); } + AstNode* filenamep() const { return op2p(); } +}; + class AstFFlush : public AstNodeStmt { // Parents: stmtlist // Children: file which must be a varref @@ -4009,6 +4059,7 @@ public: setNOp4p(msbp); } virtual bool isGateOptimizable() const { return false; } + virtual bool isHeavy() const { return true; } virtual bool isPredictOptimizable() const { return false; } virtual bool isPure() const { return false; } virtual bool isOutputter() const { return true; } @@ -4099,6 +4150,7 @@ public: virtual string emitVerilog() { return "%f$value$plusargs(%l, %k%r)"; } virtual string emitC() { V3ERROR_NA_RETURN(""); } virtual bool isGateOptimizable() const { return false; } + virtual bool isHeavy() const { return true; } virtual bool isPredictOptimizable() const { return false; } virtual bool cleanOut() const { return true; } virtual V3Hash sameHash() const { return V3Hash(); } @@ -4283,44 +4335,81 @@ public: void priorityPragma(bool flag) { m_priorityPragma = flag; } }; -class AstJumpLabel : public AstNodeStmt { - // Jump point declaration - // Separate from AstJumpGo; as a declaration can't be deleted +class AstJumpBlock : public AstNodeStmt { + // Block of code including a JumpGo and JumpLabel // Parents: {statement list} - // Children: {statement list, with JumpGo below} + // Children: {statement list, with JumpGo and JumpLabel below} private: + AstJumpLabel* m_labelp; // [After V3Jump] Pointer to declaration int m_labelNum; // Set by V3EmitCSyms to tell final V3Emit what to increment public: - AstJumpLabel(FileLine* fl, AstNode* stmtsp) + // After construction must call ->labelp to associate with appropriate label + AstJumpBlock(FileLine* fl, AstNode* stmtsp) : ASTGEN_SUPER(fl) , m_labelNum(0) { addNOp1p(stmtsp); } + virtual const char* broken() const; + virtual void cloneRelink(); + ASTNODE_NODE_FUNCS(JumpBlock) virtual int instrCount() const { return 0; } - ASTNODE_NODE_FUNCS(JumpLabel) virtual bool maybePointedTo() const { return true; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(const AstNode* samep) const { return true; } // op1 = Statements AstNode* stmtsp() const { return op1p(); } // op1 = List of statements void addStmtsp(AstNode* nodep) { addNOp1p(nodep); } + AstNode* endStmtsp() const { return op2p(); } // op1 = List of end-of-block + void addEndStmtsp(AstNode* nodep) { addNOp2p(nodep); } int labelNum() const { return m_labelNum; } void labelNum(int flag) { m_labelNum = flag; } + AstJumpLabel* labelp() const { return m_labelp; } + void labelp(AstJumpLabel* labelp) { m_labelp = labelp; } +}; + +class AstJumpLabel : public AstNodeStmt { + // Jump point declaration + // Parents: {statement list with JumpBlock above} + // Children: none +private: + AstJumpBlock* m_blockp; // [After V3Jump] Pointer to declaration +public: + AstJumpLabel(FileLine* fl, AstJumpBlock* blockp) + : ASTGEN_SUPER(fl) + , m_blockp(blockp) {} + ASTNODE_NODE_FUNCS(JumpLabel) + virtual bool maybePointedTo() const { return true; } + virtual const char* broken() const { + BROKEN_RTN(!blockp()->brokeExistsAbove()); + BROKEN_RTN(blockp()->labelp() != this); + return NULL; + } + virtual void cloneRelink() { + if (m_blockp->clonep()) m_blockp = m_blockp->clonep(); + } + virtual void dump(std::ostream& str) const; + virtual int instrCount() const { return 0; } + virtual V3Hash sameHash() const { return V3Hash(); } + virtual bool same(const AstNode* samep) const { + return blockp() == static_cast(samep)->blockp(); + } + AstJumpBlock* blockp() const { return m_blockp; } }; class AstJumpGo : public AstNodeStmt { - // Jump point; branch up to the JumpLabel - // Parents: {statement list} + // Jump point; branch down to a JumpLabel + // No support for backward jumps at present + // Parents: {statement list with JumpBlock above} + // Children: none private: AstJumpLabel* m_labelp; // [After V3Jump] Pointer to declaration public: AstJumpGo(FileLine* fl, AstJumpLabel* labelp) - : ASTGEN_SUPER(fl) { - m_labelp = labelp; - } - ASTNODE_NODE_FUNCS(JumpGo) + : ASTGEN_SUPER(fl) + , m_labelp(labelp) {} + ASTNODE_NODE_FUNCS(JumpGo); virtual const char* broken() const { - BROKEN_RTN(!labelp()->brokeExistsAbove()); + BROKEN_RTN(!labelp()->brokeExistsBelow()); return NULL; } virtual void cloneRelink() { @@ -4330,7 +4419,6 @@ public: virtual int instrCount() const { return instrCountBranch(); } virtual V3Hash sameHash() const { return V3Hash(labelp()); } virtual bool same(const AstNode* samep) const { - // Also same if identical tree structure all the way down, but hard to detect return labelp() == static_cast(samep)->labelp(); } virtual bool isGateOptimizable() const { return false; } @@ -4433,28 +4521,6 @@ public: void joinType(const VJoinType& flag) { m_joinType = flag; } }; -class AstInitial : public AstNode { -public: - AstInitial(FileLine* fl, AstNode* bodysp) - : ASTGEN_SUPER(fl) { - addNOp1p(bodysp); - } - ASTNODE_NODE_FUNCS(Initial) - AstNode* bodysp() const { return op1p(); } // op1 = Expressions to evaluate - // Special accessors - bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); } -}; - -class AstFinal : public AstNode { -public: - AstFinal(FileLine* fl, AstNode* bodysp) - : ASTGEN_SUPER(fl) { - addNOp1p(bodysp); - } - ASTNODE_NODE_FUNCS(Final) - AstNode* bodysp() const { return op1p(); } // op1 = Expressions to evaluate -}; - class AstInside : public AstNodeMath { public: AstInside(FileLine* fl, AstNode* exprp, AstNode* itemsp) @@ -4761,35 +4827,36 @@ class AstTraceDecl : public AstNodeStmt { // Trace point declaration // Separate from AstTraceInc; as a declaration can't be deleted // Parents: {statement list} - // Children: none + // Children: expression being traced private: - string m_showname; // Name of variable uint32_t m_code; // Trace identifier code; converted to ASCII by trace routines - VNumRange m_bitRange; // Property of var the trace details - VNumRange m_arrayRange; // Property of var the trace details - uint32_t m_codeInc; // Code increment - AstVarType m_varType; // Type of variable (for localparam vs. param) - AstBasicDTypeKwd m_declKwd; // Keyword at declaration time - VDirection m_declDirection; // Declared direction input/output etc - bool m_isScoped; // Uses run-time scope (for interfaces) + const string m_showname; // Name of variable + const VNumRange m_bitRange; // Property of var the trace details + const VNumRange m_arrayRange; // Property of var the trace details + const uint32_t m_codeInc; // Code increment + const AstVarType m_varType; // Type of variable (for localparam vs. param) + const AstBasicDTypeKwd m_declKwd; // Keyword at declaration time + const VDirection m_declDirection; // Declared direction input/output etc + const bool m_isScoped; // Uses run-time scope (for interfaces) public: AstTraceDecl(FileLine* fl, const string& showname, AstVar* varp, // For input/output state etc AstNode* valuep, const VNumRange& bitRange, const VNumRange& arrayRange, bool isScoped) : ASTGEN_SUPER(fl) + , m_code(0) , m_showname(showname) , m_bitRange(bitRange) , m_arrayRange(arrayRange) + , m_codeInc( + ((arrayRange.ranged() ? arrayRange.elements() : 1) * valuep->dtypep()->widthWords() + * (VL_EDATASIZE / 32))) // A code is always 32-bits + , m_varType(varp->varType()) + , m_declKwd(varp->declKwd()) + , m_declDirection(varp->declDirection()) , m_isScoped(isScoped) { dtypeFrom(valuep); - m_code = 0; - m_codeInc - = ((arrayRange.ranged() ? arrayRange.elements() : 1) * valuep->dtypep()->widthWords() - * (VL_EDATASIZE / (8 * sizeof(uint32_t)))); // A code is always 32-bits - m_varType = varp->varType(); - m_declKwd = varp->declKwd(); - m_declDirection = varp->declDirection(); + addNOp1p(valuep); } virtual int instrCount() const { return 100; } // Large... ASTNODE_NODE_FUNCS(TraceDecl) @@ -4808,20 +4875,25 @@ public: AstBasicDTypeKwd declKwd() const { return m_declKwd; } VDirection declDirection() const { return m_declDirection; } bool isScoped() const { return m_isScoped; } + AstNode* valuep() const { return op1p(); } }; class AstTraceInc : public AstNodeStmt { - // Trace point; incremental change detect and dump + // Trace point dump // Parents: {statement list} - // Children: incremental value + // Children: op1: things to emit before this node, + // op2: expression being traced (from decl) + private: - AstTraceDecl* m_declp; // [After V3Trace] Pointer to declaration + AstTraceDecl* m_declp; // Pointer to declaration + const bool m_full; // Is this a full vs incremental dump public: - AstTraceInc(FileLine* fl, AstTraceDecl* declp, AstNode* valuep) - : ASTGEN_SUPER(fl) { + AstTraceInc(FileLine* fl, AstTraceDecl* declp, bool full) + : ASTGEN_SUPER(fl) + , m_declp(declp) + , m_full(full) { dtypeFrom(declp); - m_declp = declp; - addNOp2p(valuep); + addOp2p(declp->valuep()->cloneTree(true)); } ASTNODE_NODE_FUNCS(TraceInc) virtual const char* broken() const { @@ -4843,13 +4915,11 @@ public: virtual bool isOutputter() const { return true; } // but isPure() true // op1 = Statements before the value - AstNode* precondsp() const { - return op1p(); - } // op1 = prepare statements for condition (exec every loop) + AstNode* precondsp() const { return op1p(); } void addPrecondsp(AstNode* newp) { addOp1p(newp); } - // op2 = Value to trace - AstTraceDecl* declp() const { return m_declp; } // Where defined AstNode* valuep() const { return op2p(); } + AstTraceDecl* declp() const { return m_declp; } + bool full() const { return m_full; } }; class AstActive : public AstNode { @@ -5397,6 +5467,33 @@ public: virtual bool sizeMattersLhs() const { return false; } virtual int instrCount() const { return widthInstrs() * 16; } }; +class AstCountBits : public AstNodeQuadop { + // Number of bits set in vector +public: + AstCountBits(FileLine* fl, AstNode* exprp, AstNode* ctrl1p) + : ASTGEN_SUPER(fl, exprp, ctrl1p, ctrl1p->cloneTree(false), ctrl1p->cloneTree(false)) {} + AstCountBits(FileLine* fl, AstNode* exprp, AstNode* ctrl1p, AstNode* ctrl2p) + : ASTGEN_SUPER(fl, exprp, ctrl1p, ctrl2p, ctrl2p->cloneTree(false)) {} + AstCountBits(FileLine* fl, AstNode* exprp, AstNode* ctrl1p, AstNode* ctrl2p, AstNode* ctrl3p) + : ASTGEN_SUPER(fl, exprp, ctrl1p, ctrl2p, ctrl3p) {} + ASTNODE_NODE_FUNCS(CountBits) + virtual void numberOperate(V3Number& out, const V3Number& expr, const V3Number& ctrl1, + const V3Number& ctrl2, const V3Number& ctrl3) { + out.opCountBits(expr, ctrl1, ctrl2, ctrl3); + } + virtual string emitVerilog() { return "%f$countbits(%l, %r, %f, %o)"; } + virtual string emitC() { return ""; } + virtual bool cleanOut() const { return false; } + virtual bool cleanLhs() const { return true; } + virtual bool cleanRhs() const { return true; } + virtual bool cleanThs() const { return true; } + virtual bool cleanFhs() const { return true; } + virtual bool sizeMattersLhs() const { return false; } + virtual bool sizeMattersRhs() const { return false; } + virtual bool sizeMattersThs() const { return false; } + virtual bool sizeMattersFhs() const { return false; } + virtual int instrCount() const { return widthInstrs() * 16; } +}; class AstCountOnes : public AstNodeUniop { // Number of bits set in vector public: @@ -5426,6 +5523,24 @@ public: virtual bool cleanLhs() const { return false; } virtual bool sizeMattersLhs() const { return false; } }; +class AstIsUnbounded : public AstNodeUniop { + // True if is unmbounded ($) +public: + AstIsUnbounded(FileLine* fl, AstNode* lhsp) + : ASTGEN_SUPER(fl, lhsp) { + dtypeSetLogicBool(); + } + ASTNODE_NODE_FUNCS(IsUnbounded) + virtual void numberOperate(V3Number& out, const V3Number&) { + // Any constant isn't unbounded + out.setZero(); + } + virtual string emitVerilog() { return "%f$isunbounded(%l)"; } + virtual string emitC() { V3ERROR_NA_RETURN(""); } + virtual bool cleanOut() const { return false; } + virtual bool cleanLhs() const { return false; } + virtual bool sizeMattersLhs() const { return false; } +}; class AstOneHot : public AstNodeUniop { // True if only single bit set in vector public: @@ -5967,6 +6082,7 @@ public: virtual bool cleanOut() const { return true; } virtual bool cleanLhs() const { return true; } virtual bool sizeMattersLhs() const { return false; } + virtual bool isHeavy() const { return true; } FmtType format() const { return m_fmt; } }; @@ -7133,6 +7249,106 @@ public: virtual int instrCount() const { return widthInstrs() * instrCountMul() * 10; } virtual bool signedFlavor() const { return true; } }; +class AstPreAdd : public AstNodeTriop { + // Pre-increment/add + // Parents: MATH + // Children: lhsp: AstConst (1) as currently support only ++ not += + // Children: rhsp: tree with AstVarRef that is value to read before operation + // Children: thsp: tree with AstVarRef LValue that is stored after operation +public: + AstPreAdd(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp) + : ASTGEN_SUPER(fl, lhsp, rhsp, thsp) {} + ASTNODE_NODE_FUNCS(PreAdd) + virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, + const V3Number& ths) { + V3ERROR_NA; // Need to modify lhs + } + virtual string emitVerilog() { return "%k(++%r)"; } + virtual string emitC() { V3ERROR_NA_RETURN(""); } + virtual string emitSimpleOperator() { V3ERROR_NA_RETURN(""); } + virtual bool cleanOut() const { return false; } + virtual bool cleanLhs() const { return false; } + virtual bool cleanRhs() const { return false; } + virtual bool cleanThs() const { return false; } + virtual bool sizeMattersLhs() const { return true; } + virtual bool sizeMattersRhs() const { return true; } + virtual bool sizeMattersThs() const { return true; } +}; +class AstPreSub : public AstNodeTriop { + // Pre-decrement/subtract + // Parents: MATH + // Children: lhsp: AstConst (1) as currently support only -- not -= + // Children: rhsp: tree with AstVarRef that is value to read before operation + // Children: thsp: tree with AstVarRef LValue that is stored after operation +public: + AstPreSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp) + : ASTGEN_SUPER(fl, lhsp, rhsp, thsp) {} + ASTNODE_NODE_FUNCS(PreSub) + virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, + const V3Number& ths) { + V3ERROR_NA; // Need to modify lhs + } + virtual string emitVerilog() { return "%k(--%r)"; } + virtual string emitC() { V3ERROR_NA_RETURN(""); } + virtual string emitSimpleOperator() { V3ERROR_NA_RETURN(""); } + virtual bool cleanOut() const { return false; } + virtual bool cleanLhs() const { return false; } + virtual bool cleanRhs() const { return false; } + virtual bool cleanThs() const { return false; } + virtual bool sizeMattersLhs() const { return true; } + virtual bool sizeMattersRhs() const { return true; } + virtual bool sizeMattersThs() const { return true; } +}; +class AstPostAdd : public AstNodeTriop { + // Post-increment/add + // Parents: MATH + // Children: lhsp: AstConst (1) as currently support only ++ not += + // Children: rhsp: tree with AstVarRef that is value to read before operation + // Children: thsp: tree with AstVarRef LValue that is stored after operation +public: + AstPostAdd(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp) + : ASTGEN_SUPER(fl, lhsp, rhsp, thsp) {} + ASTNODE_NODE_FUNCS(PostAdd) + virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, + const V3Number& ths) { + V3ERROR_NA; // Need to modify lhs + } + virtual string emitVerilog() { return "%k(%r++)"; } + virtual string emitC() { V3ERROR_NA_RETURN(""); } + virtual string emitSimpleOperator() { V3ERROR_NA_RETURN(""); } + virtual bool cleanOut() const { return false; } + virtual bool cleanLhs() const { return false; } + virtual bool cleanRhs() const { return false; } + virtual bool cleanThs() const { return false; } + virtual bool sizeMattersLhs() const { return true; } + virtual bool sizeMattersRhs() const { return true; } + virtual bool sizeMattersThs() const { return true; } +}; +class AstPostSub : public AstNodeTriop { + // Post-decrement/subtract + // Parents: MATH + // Children: lhsp: AstConst (1) as currently support only -- not -= + // Children: rhsp: tree with AstVarRef that is value to read before operation + // Children: thsp: tree with AstVarRef LValue that is stored after operation +public: + AstPostSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp) + : ASTGEN_SUPER(fl, lhsp, rhsp, thsp) {} + ASTNODE_NODE_FUNCS(PostSub) + virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, + const V3Number& ths) { + V3ERROR_NA; // Need to modify lhs + } + virtual string emitVerilog() { return "%k(%r--)"; } + virtual string emitC() { V3ERROR_NA_RETURN(""); } + virtual string emitSimpleOperator() { V3ERROR_NA_RETURN(""); } + virtual bool cleanOut() const { return false; } + virtual bool cleanLhs() const { return false; } + virtual bool cleanRhs() const { return false; } + virtual bool cleanThs() const { return false; } + virtual bool sizeMattersLhs() const { return true; } + virtual bool sizeMattersRhs() const { return true; } + virtual bool sizeMattersThs() const { return true; } +}; class AstEqCase : public AstNodeBiCom { public: AstEqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp) @@ -7500,6 +7716,7 @@ public: virtual bool sizeMattersLhs() const { return false; } virtual bool sizeMattersRhs() const { return false; } virtual bool sizeMattersThs() const { return false; } + virtual bool isHeavy() const { return true; } }; class AstGetcN : public AstNodeBiop { @@ -7525,6 +7742,7 @@ public: virtual bool cleanRhs() const { return true; } virtual bool sizeMattersLhs() const { return false; } virtual bool sizeMattersRhs() const { return false; } + virtual bool isHeavy() const { return true; } }; class AstGetcRefN : public AstNodeBiop { @@ -7543,13 +7761,14 @@ public: V3ERROR_NA; } virtual string emitVerilog() { return "%k%l[%r]"; } - virtual string emitC() { V3ERROR_NA; } + virtual string emitC() { V3ERROR_NA_RETURN(""); } virtual string emitSimpleOperator() { return ""; } virtual bool cleanOut() const { return true; } virtual bool cleanLhs() const { return true; } virtual bool cleanRhs() const { return true; } virtual bool sizeMattersLhs() const { return false; } virtual bool sizeMattersRhs() const { return false; } + virtual bool isHeavy() const { return true; } }; class AstSubstrN : public AstNodeTriop { @@ -7575,6 +7794,7 @@ public: virtual bool sizeMattersLhs() const { return false; } virtual bool sizeMattersRhs() const { return false; } virtual bool sizeMattersThs() const { return false; } + virtual bool isHeavy() const { return true; } }; class AstCompareNN : public AstNodeBiop { @@ -7607,6 +7827,7 @@ public: virtual bool cleanRhs() const { return true; } virtual bool sizeMattersLhs() const { return false; } virtual bool sizeMattersRhs() const { return false; } + virtual bool isHeavy() const { return true; } }; class AstPast : public AstNodeMath { @@ -7675,11 +7896,10 @@ public: virtual bool cleanOut() const { V3ERROR_NA_RETURN(""); } virtual int instrCount() const { return widthInstrs(); } AstNodeDType* getChildDTypep() const { return childDTypep(); } - AstNodeDType* childDTypep() const { - return VN_CAST(op1p(), NodeDType); - } // op1 = Type assigning to - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } + // op1 = Type assigning to + AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } + void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } AstNode* itemsp() const { return op2p(); } // op2 = AstPatReplicate, AstPatMember, etc }; class AstPatMember : public AstNodeMath { diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index 900f1f6f6..30ae3cbc5 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -30,12 +30,9 @@ #include "V3Global.h" #include "V3Begin.h" -#include "V3Inst.h" #include "V3Ast.h" #include -#include -#include //###################################################################### diff --git a/src/V3Branch.cpp b/src/V3Branch.cpp index b89dc427d..94123dd6a 100644 --- a/src/V3Branch.cpp +++ b/src/V3Branch.cpp @@ -30,7 +30,6 @@ #include "V3Branch.h" #include "V3Ast.h" -#include #include //###################################################################### diff --git a/src/V3Broken.cpp b/src/V3Broken.cpp index 21db1485f..e9371d2be 100644 --- a/src/V3Broken.cpp +++ b/src/V3Broken.cpp @@ -32,7 +32,6 @@ #include "V3AstConstOnly.h" #include -#include #include VL_INCLUDE_UNORDERED_MAP //###################################################################### @@ -131,6 +130,14 @@ public: if (!(iter->second & FLAG_LINKABLE)) return false; return true; } + static bool okIfAbove(const AstNode* nodep) { + // Must be linked to and below current node + if (!okIfLinkedTo(nodep)) return false; + NodeMap::iterator iter = s_nodes.find(nodep); + if (iter == s_nodes.end()) return false; + if ((iter->second & FLAG_UNDER_NOW)) return false; + return true; + } static bool okIfBelow(const AstNode* nodep) { // Must be linked to and below current node if (!okIfLinkedTo(nodep)) return false; @@ -142,19 +149,22 @@ public: static void prepForTree() { #ifndef VL_LEAK_CHECKS s_nodes.clear(); -#endif +#else for (NodeMap::iterator it = s_nodes.begin(); it != s_nodes.end(); ++it) { it->second &= ~FLAG_IN_TREE; it->second &= ~FLAG_LINKABLE; } +#endif } static void doneWithTree() { for (int backs = 0; backs < 2; backs++) { // Those with backp() are probably under one leaking without for (NodeMap::iterator it = s_nodes.begin(); it != s_nodes.end(); ++it) { - if ((it->second & FLAG_ALLOCATED) && !(it->second & FLAG_IN_TREE) - && !(it->second & FLAG_LEAKED) - && (it->first->backp() ? backs == 1 : backs == 0)) { + // LCOV_EXCL_START + if (VL_UNCOVERABLE((it->second & FLAG_ALLOCATED) && !(it->second & FLAG_IN_TREE) + && !(it->second & FLAG_LEAKED) + && (it->first->backp() ? backs == 1 : backs == 0))) { + // Use only AstNode::dump instead of the virtual one, as there // may be varp() and other cross links that are bad. if (v3Global.opt.debugCheck()) { @@ -173,6 +183,7 @@ public: } it->second |= FLAG_LEAKED; } + // LCOV_EXCL_STOP } } } @@ -193,6 +204,10 @@ bool AstNode::brokeExistsAbove() const { // Called by node->broken() routines to do table lookup return BrokenTable::okIfBelow(this); } +bool AstNode::brokeExistsBelow() const { + // Called by node->broken() routines to do table lookup + return BrokenTable::okIfAbove(this); +} //###################################################################### diff --git a/src/V3CCtors.cpp b/src/V3CCtors.cpp index 962b382f9..a08f0dd5b 100644 --- a/src/V3CCtors.cpp +++ b/src/V3CCtors.cpp @@ -32,10 +32,7 @@ #include "V3CCtors.h" #include -#include -#include #include -#include class V3CCtorsVisitor { private: @@ -49,7 +46,6 @@ private: int m_funcNum; // Function number being built public: - AstCFunc* builtFuncp() const { return m_tlFuncp; } void add(AstNode* nodep) { if (v3Global.opt.outputSplitCFuncs() && v3Global.opt.outputSplitCFuncs() < m_numStmts) { m_funcp = NULL; @@ -146,13 +142,11 @@ void V3CCtors::cctorsAll() { modp = VN_CAST(modp->nextp(), NodeModule)) { // Process each module in turn { - AstCFunc* varResetFuncp; V3CCtorsVisitor var_reset( modp, "_ctor_var_reset", (VN_IS(modp, Class) ? EmitCBaseVisitor::symClassVar() : ""), (VN_IS(modp, Class) ? "vlSymsp" : ""), (VN_IS(modp, Class) ? "if (false && vlSymsp) {} // Prevent unused\n" : "")); - varResetFuncp = var_reset.builtFuncp(); for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) { if (AstVar* varp = VN_CAST(np, Var)) { diff --git a/src/V3CUse.cpp b/src/V3CUse.cpp index fe1f6f073..82a20e7a5 100644 --- a/src/V3CUse.cpp +++ b/src/V3CUse.cpp @@ -218,7 +218,7 @@ public: //###################################################################### // Class class functions -void V3CUse::cUseAll(AstNetlist* nodep) { +void V3CUse::cUseAll() { UINFO(2, __FUNCTION__ << ": " << endl); // Call visitor separately for each module, so visitor state is cleared for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; diff --git a/src/V3CUse.h b/src/V3CUse.h index f0d87aeae..ffae09a46 100644 --- a/src/V3CUse.h +++ b/src/V3CUse.h @@ -27,7 +27,7 @@ class V3CUse { public: - static void cUseAll(AstNetlist* nodep); + static void cUseAll(); }; #endif // Guard diff --git a/src/V3Case.cpp b/src/V3Case.cpp index e125afcd7..01ba0b96d 100644 --- a/src/V3Case.cpp +++ b/src/V3Case.cpp @@ -43,7 +43,6 @@ #include "V3Stats.h" #include -#include #define CASE_OVERLAP_WIDTH 16 // Maximum width we can check for overlaps in #define CASE_BARF 999999 // Magic width when non-constant @@ -96,7 +95,7 @@ private: } else if (VN_IS(m_caseExprp, Case) && (VN_CAST(m_caseExprp, Case)->casez() || VN_CAST(m_caseExprp, Case)->caseInside())) { - if (nodep->num().isUnknown()) { + if (nodep->num().isAnyX()) { nodep->v3warn(CASEWITHX, "Use of x constant in casez statement, " "(perhaps intended ?/z in constant)"); } @@ -281,13 +280,13 @@ private: // IF(msb-1, 01, 00)) AstNode* cexprp = nodep->exprp()->unlinkFrBack(); - if (debug() >= 9) { + if (debug() >= 9) { // LCOV_EXCL_START for (uint32_t i = 0; i < (1UL << m_caseWidth); ++i) { if (AstNode* itemp = m_valueItem[i]) { UINFO(9, "Value " << std::hex << i << " " << itemp << endl); } } - } + } // LCOV_EXCL_STOP // Handle any assertions replaceCaseParallel(nodep, m_caseNoOverlapsAllCovered); @@ -460,7 +459,7 @@ private: // Xs in case or casez are impossible due to two state simulations if (casep->casex()) { } else if (casep->casez() || casep->caseInside()) { - if (itemp->num().isUnknown()) return true; + if (itemp->num().isAnyX()) return true; } else { if (itemp->num().isFourState()) return true; } diff --git a/src/V3Cast.cpp b/src/V3Cast.cpp index 9c716e75b..d8f24070f 100644 --- a/src/V3Cast.cpp +++ b/src/V3Cast.cpp @@ -45,7 +45,6 @@ #include "V3Ast.h" #include -#include //###################################################################### // Cast state, as a visitor of each AstNode @@ -128,6 +127,15 @@ private: if (nodep->sizeMattersRhs()) ensureCast(nodep->rhsp()); if (nodep->sizeMattersThs()) ensureCast(nodep->thsp()); } + virtual void visit(AstNodeQuadop* nodep) VL_OVERRIDE { + iterateChildren(nodep); + nodep->user1(nodep->lhsp()->user1() | nodep->rhsp()->user1() | nodep->thsp()->user1() + | nodep->fhsp()->user1()); + if (nodep->sizeMattersLhs()) ensureCast(nodep->lhsp()); + if (nodep->sizeMattersRhs()) ensureCast(nodep->rhsp()); + if (nodep->sizeMattersThs()) ensureCast(nodep->thsp()); + if (nodep->sizeMattersFhs()) ensureCast(nodep->fhsp()); + } virtual void visit(AstCCast* nodep) VL_OVERRIDE { iterateChildren(nodep); ensureLower32Cast(nodep); diff --git a/src/V3Cdc.cpp b/src/V3Cdc.cpp index 358160c49..e47600fc0 100644 --- a/src/V3Cdc.cpp +++ b/src/V3Cdc.cpp @@ -33,12 +33,9 @@ #include "V3File.h" #include -#include #include #include -#include #include -#include #define CDC_WEIGHT_ASYNC 0x1000 // Weight for edges that feed async logic @@ -258,7 +255,7 @@ private: iterateChildren(nodep); m_logicVertexp = NULL; - if (0 && debug() >= 9) { + if (false && debug() >= 9) { UINFO(9, "Trace Logic:\n"); nodep->dumpTree(cout, "-log1: "); } @@ -298,7 +295,7 @@ private: static bool told_file = false; nodep->v3warnCode(code, msg); if (!told_file) { - told_file = 1; + told_file = true; std::cerr << V3Error::msgPrefix() << " See details in " << m_ofFilename << endl; } *m_ofp << "%Warning-" << code.ascii() << ": " << nodep->fileline() << " " << msg << endl; @@ -732,7 +729,7 @@ private: // Ignores virtual void visit(AstInitial*) VL_OVERRIDE {} - virtual void visit(AstTraceInc*) VL_OVERRIDE {} + virtual void visit(AstTraceDecl*) VL_OVERRIDE {} virtual void visit(AstCoverToggle*) VL_OVERRIDE {} virtual void visit(AstNodeDType*) VL_OVERRIDE {} diff --git a/src/V3Changed.cpp b/src/V3Changed.cpp index 164e3b314..47be72d4c 100644 --- a/src/V3Changed.cpp +++ b/src/V3Changed.cpp @@ -35,8 +35,6 @@ #include "V3EmitCBase.h" #include -#include -#include //###################################################################### diff --git a/src/V3Clean.cpp b/src/V3Clean.cpp index 164463364..274c628c5 100644 --- a/src/V3Clean.cpp +++ b/src/V3Clean.cpp @@ -31,7 +31,6 @@ #include "V3Ast.h" #include -#include //###################################################################### // Clean state, as a visitor of each AstNode @@ -160,6 +159,15 @@ private: if (nodep->cleanThs()) ensureClean(nodep->thsp()); // no setClean.. must do it in each user routine. } + void operandQuadop(AstNodeQuadop* nodep) { + iterateChildren(nodep); + computeCppWidth(nodep); + if (nodep->cleanLhs()) { ensureClean(nodep->lhsp()); } + if (nodep->cleanRhs()) { ensureClean(nodep->rhsp()); } + if (nodep->cleanThs()) { ensureClean(nodep->thsp()); } + if (nodep->cleanFhs()) { ensureClean(nodep->fhsp()); } + // no setClean.. must do it in each user routine. + } // VISITORS virtual void visit(AstNodeModule* nodep) VL_OVERRIDE { @@ -192,6 +200,10 @@ private: operandBiop(nodep); setClean(nodep, isClean(nodep->lhsp()) && isClean(nodep->rhsp())); } + virtual void visit(AstNodeQuadop* nodep) VL_OVERRIDE { + operandQuadop(nodep); + setClean(nodep, nodep->cleanOut()); + } virtual void visit(AstNodeMath* nodep) VL_OVERRIDE { iterateChildren(nodep); computeCppWidth(nodep); diff --git a/src/V3Clock.cpp b/src/V3Clock.cpp index 5e89b0e72..331701260 100644 --- a/src/V3Clock.cpp +++ b/src/V3Clock.cpp @@ -36,7 +36,6 @@ #include "V3EmitCBase.h" #include -#include //###################################################################### // Clock state, as a visitor of each AstNode @@ -48,9 +47,6 @@ private: // AstVarScope::user1p() -> AstVarScope*. Temporary signal that was created. AstUser1InUse m_inuser1; - // TYPES - enum { DOUBLE_OR_RATE = 10 }; // How many | per ||, Determined experimentally as best - // STATE AstNodeModule* m_modp; // Current module AstTopScope* m_topScopep; // Current top scope diff --git a/src/V3Combine.cpp b/src/V3Combine.cpp index 9224e0576..c38cc96f7 100644 --- a/src/V3Combine.cpp +++ b/src/V3Combine.cpp @@ -40,7 +40,6 @@ #include "V3Ast.h" #include -#include #include #include @@ -57,15 +56,6 @@ protected: // METHODS virtual ~CombBaseVisitor() {} VL_DEBUG_FUNC; // Declare debug() - - //***** optimization levels - static bool emptyFunctionDeletion() { return true; } - static bool duplicateFunctionCombine() { return true; } - // Note this is disabled, it still needed work - // Also repair it for DPI functions; when make __common need to ensure proper - // flags get inherited from the old to new AstCFunc, and that AstText doesn't - // get split between functions causing the text to have a dangling reference. - bool statementCombine() { return false; } // duplicateFunctionCombine(); }; //###################################################################### @@ -86,11 +76,10 @@ public: } else { UINFO(4, " Remove " << oldfuncp << endl); } - std::pair eqrange - = m_callMmap.equal_range(oldfuncp); - for (CallMmap::iterator nextit = eqrange.first; nextit != eqrange.second;) { - CallMmap::iterator eqit = nextit++; - AstCCall* callp = eqit->second; + // Note: m_callMmap modified in loop, so not using equal_range. + for (CallMmap::iterator it = m_callMmap.find(oldfuncp); it != m_callMmap.end(); + it = m_callMmap.find(oldfuncp)) { + AstCCall* callp = it->second; if (!callp->user3()) { // !already done UINFO(4, " Called " << callp << endl); UASSERT_OBJ(callp->funcp() == oldfuncp, callp, @@ -105,8 +94,13 @@ public: } callp->user3(true); // Dead now VL_DO_DANGLING(pushDeletep(callp), callp); - m_callMmap.erase(eqit); // Fix the table } + // It is safe to unconditionally remove this entry here as the above + // 'if' would never be entered again for this entry (we set user3). + // The only other place where m_callMmap is looked up is deleteCall + // below, but that is only ever called straight after an addCall + // of the node being deleted, so it won't miss this entry. + m_callMmap.erase(it); // Fix the table } } // METHODS @@ -182,7 +176,6 @@ private: CombineState m_state; // Major state AstNodeModule* m_modp; // Current module AstCFunc* m_funcp; // Current function - V3Hash m_lowerHash; // Hash of the statement we're building CombCallVisitor m_call; // Tracking of function call users int m_modNFuncs; // Number of functions made AstNode* m_walkLast1p; // Final node that is the same in duplicate list @@ -195,6 +188,7 @@ private: m_hashed.hashAndInsert(nodep); // UINFO(9, " stmthash " << hex << nodep->user4() << " " << nodep << endl); } +#ifdef VL_COMBINE_STATEMENTS void hashFunctions(AstCFunc* nodep) { // Compute hash of all statement trees in the function CombineState oldState = m_state; @@ -204,6 +198,7 @@ private: } m_state = oldState; } +#endif void walkEmptyFuncs() { for (V3Hashed::iterator it = m_hashed.begin(); it != m_hashed.end(); ++it) { AstNode* node1p = it->second; @@ -251,6 +246,8 @@ private: oldfuncp->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(oldfuncp), oldfuncp); } + +#ifdef VL_COMBINE_STATEMENTS void replaceOnlyCallFunc(AstCCall* nodep) { if (AstCFunc* oldfuncp = VN_CAST(nodep->backp(), CFunc)) { // oldfuncp->dumpTree(cout, "MAYDEL: "); @@ -343,7 +340,7 @@ private: // Grab statement bodies AstNRelinker relink1Handle; AstNRelinker relink2Handle; - for (AstNode *nextp, *walkp = node1p; 1; walkp = nextp) { + for (AstNode *nextp, *walkp = node1p; true; walkp = nextp) { nextp = walkp->nextp(); if (walkp == node1p) { walkp->unlinkFrBack(&relink1Handle); @@ -353,7 +350,7 @@ private: } if (walkp == last1p) break; } - for (AstNode *nextp, *walkp = node2p; 1; walkp = nextp) { + for (AstNode *nextp, *walkp = node2p; true; walkp = nextp) { nextp = walkp->nextp(); if (walkp == node2p) { walkp->unlinkFrBack(&relink2Handle); @@ -381,6 +378,7 @@ private: VL_DO_DANGLING(replaceOnlyCallFunc(call1p), call1p); VL_DO_DANGLING(replaceOnlyCallFunc(call2p), call2p); } +#endif // VISITORS virtual void visit(AstNetlist* nodep) VL_OVERRIDE { @@ -404,15 +402,21 @@ private: m_state = STATE_IDLE; if (debug() >= 9) m_hashed.dumpFilePrefixed("combine"); // Walk the hashes removing empty functions - if (emptyFunctionDeletion()) walkEmptyFuncs(); + walkEmptyFuncs(); // Walk the hashes looking for duplicate functions - if (duplicateFunctionCombine()) walkDupFuncs(); + walkDupFuncs(); // Walk the statements looking for large replicated code sections - if (statementCombine()) { + // Note this is disabled, it still needed work + // Also repair it for DPI functions; when make __common need to ensure proper + // flags get inherited from the old to new AstCFunc, and that AstText doesn't + // get split between functions causing the text to have a dangling reference. +#ifdef VL_COMBINE_STATEMENTS + { m_state = STATE_DUP; iterateChildren(nodep); m_state = STATE_IDLE; } +#endif m_modp = NULL; } virtual void visit(AstCFunc* nodep) VL_OVERRIDE { @@ -420,9 +424,12 @@ private: if (!nodep->dontCombine()) { if (m_state == STATE_HASH) { hashStatement(nodep); // Hash the entire function - it might be identical - } else if (m_state == STATE_DUP) { + } +#ifdef VL_COMBINE_STATEMENTS + else if (m_state == STATE_DUP) { iterateChildren(nodep); } +#endif } m_funcp = NULL; } @@ -433,9 +440,12 @@ private: } if (m_state == STATE_HASH && m_funcp) { hashStatement(nodep); - } else if (m_state == STATE_DUP && m_funcp) { + } +#ifdef VL_COMBINE_STATEMENTS + else if (m_state == STATE_DUP && m_funcp) { walkDupCodeStart(nodep); } +#endif } //-------------------- diff --git a/src/V3Config.cpp b/src/V3Config.cpp index eca233a8d..4cf88e78b 100644 --- a/src/V3Config.cpp +++ b/src/V3Config.cpp @@ -335,7 +335,7 @@ public: // UINFO(9, " Hit " << *m_lastIt << endl); filelinep->warnOn(m_lastIgnore.it->m_code, m_lastIgnore.it->m_on); } - if (0 && debug() >= 9) { + if (false && debug() >= 9) { for (IgnLines::const_iterator it = m_lastIgnore.it; it != m_ignLines.end(); ++it) { UINFO(9, " NXT " << *it << endl); } diff --git a/src/V3Config.h b/src/V3Config.h index 96346c4f1..dd542192c 100644 --- a/src/V3Config.h +++ b/src/V3Config.h @@ -43,7 +43,7 @@ public: static void applyModule(AstNodeModule* modulep); static void applyFTask(AstNodeModule* modulep, AstNodeFTask* ftaskp); static void applyVarAttr(AstNodeModule* modulep, AstNodeFTask* ftaskp, AstVar* varp); - static bool waive(FileLine* filelinep, V3ErrorCode code, const string& match); + static bool waive(FileLine* filelinep, V3ErrorCode code, const string& message); }; #endif // Guard diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 7418df2fa..fb3456d78 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -31,7 +31,6 @@ #include "V3Simulate.h" #include -#include #include //###################################################################### @@ -102,7 +101,7 @@ private: bool m_doShort; // Remove expressions that short circuit bool m_doV; // Verilog, not C++ conversion bool m_doGenerate; // Postpone width checking inside generate - bool m_hasJumpGo; // JumpGo under this while + bool m_hasJumpDelay; // JumpGo or Delay under this while AstNodeModule* m_modp; // Current module AstArraySel* m_selp; // Current select AstNode* m_scopep; // Current scope @@ -664,6 +663,14 @@ private: UINFO(4, "TRICONST -> " << num << endl); VL_DO_DANGLING(replaceNum(nodep, num), nodep); } + void replaceConst(AstNodeQuadop* nodep) { + V3Number num(nodep, nodep->width()); + nodep->numberOperate( + num, VN_CAST(nodep->lhsp(), Const)->num(), VN_CAST(nodep->rhsp(), Const)->num(), + VN_CAST(nodep->thsp(), Const)->num(), VN_CAST(nodep->fhsp(), Const)->num()); + UINFO(4, "QUADCONST -> " << num << endl); + VL_DO_DANGLING(replaceNum(nodep, num), nodep); + } void replaceConstString(AstNode* oldp, const string& num) { // Replace oldp node with a constant set to specified value @@ -1629,6 +1636,11 @@ private: nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); did = true; + } else if (nodep->varp()->isParam() && VN_IS(valuep, Unbounded)) { + AstNode* newp = valuep->cloneTree(false); + nodep->replaceWith(newp); + VL_DO_DANGLING(nodep->deleteTree(), nodep); + did = true; } } } @@ -2114,11 +2126,11 @@ private: iterateChildren(nodep); } virtual void visit(AstWhile* nodep) VL_OVERRIDE { - bool oldHasJumpGo = m_hasJumpGo; - m_hasJumpGo = false; + bool oldHasJumpDelay = m_hasJumpDelay; + m_hasJumpDelay = false; { iterateChildren(nodep); } - bool thisWhileHasJumpGo = m_hasJumpGo; - m_hasJumpGo = thisWhileHasJumpGo || oldHasJumpGo; + bool thisWhileHasJumpDelay = m_hasJumpDelay; + m_hasJumpDelay = thisWhileHasJumpDelay || oldHasJumpDelay; if (m_doNConst) { if (nodep->condp()->isZero()) { UINFO(4, "WHILE(0) => nop " << nodep << endl); @@ -2129,7 +2141,7 @@ private: } VL_DO_DANGLING(nodep->deleteTree(), nodep); } else if (nodep->condp()->isNeqZero()) { - if (!thisWhileHasJumpGo) { + if (!thisWhileHasJumpDelay) { nodep->v3warn(INFINITELOOP, "Infinite loop (condition always true)"); nodep->fileline()->modifyWarnOff(V3ErrorCode::INFINITELOOP, true); // Complain just once @@ -2141,6 +2153,7 @@ private: } virtual void visit(AstInitArray* nodep) VL_OVERRIDE { iterateChildren(nodep); } virtual void visit(AstInitItem* nodep) VL_OVERRIDE { iterateChildren(nodep); } + virtual void visit(AstUnbounded* nodep) VL_OVERRIDE { iterateChildren(nodep); } // These are converted by V3Param. Don't constify as we don't want the // from() VARREF to disappear, if any. // If output of a presel didn't get consted, chances are V3Param didn't visit properly @@ -2161,26 +2174,42 @@ private: //----- // Jump elimination + virtual void visit(AstDelay* nodep) VL_OVERRIDE { + iterateChildren(nodep); + m_hasJumpDelay = true; + } virtual void visit(AstJumpGo* nodep) VL_OVERRIDE { iterateChildren(nodep); - m_hasJumpGo = true; + // Jump to label where label immediately follows label is not useful + if (nodep->labelp() == VN_CAST(nodep->nextp(), JumpLabel)) { + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); + // Keep the label, might be other jumps pointing to it, gets cleaned later + return; + } if (m_doExpensive) { + // Any non-label statements (at this statement level) can never execute + while (nodep->nextp() && !VN_IS(nodep->nextp(), JumpLabel)) { + nodep->nextp()->unlinkFrBack()->deleteTree(); + } // If last statement in a jump label we have JumpLabel(...., JumpGo) // Often caused by "return" in a Verilog function. The Go is pointless, remove. if (!nodep->nextp()) { - if (AstJumpLabel* aboveLabelp = VN_CAST(nodep->abovep(), JumpLabel)) { - if (aboveLabelp == nodep->labelp()) { - UINFO(4, "JUMPGO => last remove " << nodep << endl); - VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); - return; + if (AstJumpBlock* aboveBlockp = VN_CAST(nodep->abovep(), JumpBlock)) { + if (aboveBlockp == nodep->labelp()->blockp()) { + if (aboveBlockp->endStmtsp() == nodep->labelp()) { + UINFO(4, "JUMPGO => last remove " << nodep << endl); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); + return; + } } } } - nodep->labelp()->user4(true); + nodep->labelp()->blockp()->user4(true); } + m_hasJumpDelay = true; } - virtual void visit(AstJumpLabel* nodep) VL_OVERRIDE { + virtual void visit(AstJumpBlock* nodep) VL_OVERRIDE { // Because JumpLabels disable many optimizations, // remove JumpLabels that are not pointed to by any AstJumpGos // Note this assumes all AstJumpGos are underneath the given label; V3Broken asserts this @@ -2195,6 +2224,7 @@ private: } else { nodep->unlinkFrBack(); } + nodep->labelp()->unlinkFrBack()->deleteTree(); VL_DO_DANGLING(nodep->deleteTree(), nodep); } } @@ -2235,6 +2265,7 @@ private: // Generic constants on both side. Do this first to avoid other replacements TREEOPC("AstNodeBiop {$lhsp.castConst, $rhsp.castConst}", "replaceConst(nodep)"); TREEOPC("AstNodeUniop{$lhsp.castConst, !nodep->isOpaque()}", "replaceConst(nodep)"); + TREEOPC("AstNodeQuadop{$lhsp.castConst, $rhsp.castConst, $thsp.castConst, $fhsp.castConst}", "replaceConst(nodep)"); // Zero on one side or the other TREEOP ("AstAdd {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)"); TREEOP ("AstAnd {$lhsp.isZero, $rhsp, isTPure($rhsp)}", "replaceZero(nodep)"); // Can't use replaceZeroChkPure as we make this pattern in ChkPure @@ -2518,6 +2549,9 @@ private: TREEOPC("AstPutcN{$lhsp.castConst, $rhsp.castConst, $thsp.castConst}", "replaceConst(nodep)"); TREEOPC("AstSubstrN{$lhsp.castConst, $rhsp.castConst, $thsp.castConst}", "replaceConst(nodep)"); TREEOPC("AstCvtPackString{$lhsp.castConst}", "replaceConstString(nodep, VN_CAST(nodep->lhsp(), Const)->num().toString())"); + // Custom + // Implied by AstIsUnbounded::numberOperate: V("AstIsUnbounded{$lhsp.castConst}", "replaceNum(nodep, 0)"); + TREEOPV("AstIsUnbounded{$lhsp.castUnbounded}", "replaceNum(nodep, 1)"); // clang-format on // Possible futures: @@ -2566,7 +2600,7 @@ public: m_doShort = true; // Presently always done m_doV = false; m_doGenerate = false; // Inside generate conditionals - m_hasJumpGo = false; + m_hasJumpDelay = false; m_warn = false; m_wremove = true; // Overridden in visitors m_modp = NULL; diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 953e9dc7c..ccbd365cb 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -31,8 +31,8 @@ #include "V3Coverage.h" #include "V3Ast.h" -#include #include +#include VL_INCLUDE_UNORDERED_MAP //###################################################################### // Coverage state, as a visitor of each AstNode @@ -40,7 +40,9 @@ class CoverageVisitor : public AstNVisitor { private: // TYPES - typedef std::map FileMap; + typedef vl_unordered_map VarNameMap; + typedef std::set LinenoSet; + typedef vl_unordered_map HandleLines; struct ToggleEnt { string m_comment; // Comment for coverage dump @@ -57,18 +59,35 @@ private: } }; + struct CheckState { // State save-restored on each new coverage scope/block + bool m_on; // Should this block get covered? + bool m_inModOff; // In module with no coverage + int m_handle; // Opaque handle for index into line tracking + const AstNode* m_nodep; // Node establishing this state + CheckState() + : m_on(false) + , m_inModOff(false) + , m_handle(0) + , m_nodep(NULL) {} + bool lineCoverageOn(const AstNode* nodep) { + return m_on && !m_inModOff && nodep->fileline()->coverageOn() + && v3Global.opt.coverageLine(); + } + }; + int m_nextHandle; + // NODE STATE // Entire netlist: // AstIf::user1() -> bool. True indicates ifelse processed AstUser1InUse m_inuser1; // STATE - bool m_checkBlock; // Should this block get covered? + CheckState m_state; // State save-restored on each new coverage scope/block AstNodeModule* m_modp; // Current module to add statement to bool m_inToggleOff; // In function/task etc - bool m_inModOff; // In module with no coverage - FileMap m_fileps; // Column counts for each fileline + VarNameMap m_varnames; // Uniquification of inserted variable names string m_beginHier; // AstBegin hier name for user coverage points + HandleLines m_handleLines; // All line numbers for a given m_stateHandle // METHODS VL_DEBUG_FUNC; // Declare debug() @@ -91,21 +110,8 @@ private: } AstCoverInc* newCoverInc(FileLine* fl, const string& hier, const string& page_prefix, - const string& comment, const string& trace_var_name) { - // For line coverage, we may have multiple if's on one line, so disambiguate if - // everything is otherwise identical - // (Don't set column otherwise as it may result in making bins not match up with - // different types of coverage enabled.) - string key = fl->filename() + "\001" + cvtToStr(fl->lineno()) + "\001" + hier + "\001" - + page_prefix + "\001" + comment; - int column = 0; - FileMap::iterator it = m_fileps.find(key); - if (it == m_fileps.end()) { - m_fileps.insert(make_pair(key, column + 1)); - } else { - column = (it->second)++; - } - + const string& comment, const string& linescov, int offset, + const string& trace_var_name) { // We could use the basename of the filename to the page, but seems // better for code from an include file to be listed under the // module using it rather than the include file. @@ -114,9 +120,10 @@ private: // Someday the user might be allowed to specify a different page suffix string page = page_prefix + "/" + m_modp->prettyName(); - AstCoverDecl* declp = new AstCoverDecl(fl, column, page, comment); + AstCoverDecl* declp = new AstCoverDecl(fl, page, comment, linescov, offset); declp->hier(hier); m_modp->addStmtp(declp); + UINFO(9, "new " << declp << endl); AstCoverInc* incp = new AstCoverInc(fl, declp); if (!trace_var_name.empty() && v3Global.opt.traceCoverage()) { @@ -135,35 +142,131 @@ private: return incp; } string traceNameForLine(AstNode* nodep, const string& type) { - return "vlCoverageLineTrace_" + nodep->fileline()->filebasenameNoExt() + "__" - + cvtToStr(nodep->fileline()->lineno()) + "_" + type; + string name = "vlCoverageLineTrace_" + nodep->fileline()->filebasenameNoExt() + "__" + + cvtToStr(nodep->fileline()->lineno()) + "_" + type; + VarNameMap::iterator it = m_varnames.find(name); + if (it == m_varnames.end()) { + m_varnames.insert(make_pair(name, 1)); + } else { + int suffix = (it->second)++; + name += "_" + cvtToStr(suffix); + } + return name; } + + // Line tracking + void createHandle(const AstNode* nodep) { + // Start tracking lines for the given handling node + // If and if's else have separate handles for same nodep, + // so nodep cannot have a pointer to a unique handle + m_state.m_on = true; + m_state.m_handle = ++m_nextHandle; + // Ensure line numbers we track are in the same file as this block + // so track via nodep + m_state.m_nodep = nodep; + UINFO(9, "line create h" << m_state.m_handle << " " << nodep << endl); + } + void lineTrack(const AstNode* nodep) { + if (m_state.lineCoverageOn(nodep) + && m_state.m_nodep->fileline()->filenameno() == nodep->fileline()->filenameno()) { + for (int lineno = nodep->fileline()->firstLineno(); + lineno <= nodep->fileline()->lastLineno(); ++lineno) { + UINFO(9, "line track " << lineno << " for h" << m_state.m_handle << " " + << m_state.m_nodep << endl); + m_handleLines[m_state.m_handle].insert(lineno); + } + } + } + static string linesFirstLast(const int first, const int last) { + if (first && first == last) { + return cvtToStr(first); + } else if (first && last) { + return cvtToStr(first) + "-" + cvtToStr(last); + } else { + return ""; + } + } + string linesCov(const CheckState& state, const AstNode* nodep) { + // Return comma separated list of ranged numbers + string out; + const LinenoSet& lines = m_handleLines[state.m_handle]; + int first = 0; + int last = 0; + for (LinenoSet::iterator it = lines.begin(); it != lines.end(); ++it) { + if (!first) { + first = last = *it; + } else if (*it == last + 1) { + ++last; + } else { + if (!out.empty()) out += ","; + out += linesFirstLast(first, last); + first = last = *it; + } + } + if (first) { + if (!out.empty()) out += ","; + out += linesFirstLast(first, last); + } + UINFO(9, "lines out " << out << " for h" << state.m_handle << " " << nodep << endl); + return out; + } + // VISITORS - BOTH virtual void visit(AstNodeModule* nodep) VL_OVERRIDE { AstNodeModule* origModp = m_modp; - bool origInModOff = m_inModOff; + CheckState lastState = m_state; { + createHandle(nodep); m_modp = nodep; - m_inModOff = nodep->isTop(); // Ignore coverage on top module; it's a shell we created - m_fileps.clear(); + m_state.m_inModOff + = nodep->isTop(); // Ignore coverage on top module; it's a shell we created + if (!origModp) { + // No blocks cross (non-nested) modules, so save some memory + m_varnames.clear(); + m_handleLines.clear(); + } iterateChildren(nodep); } m_modp = origModp; - m_inModOff = origInModOff; + m_state = lastState; } - // VISITORS - TOGGLE COVERAGE + virtual void visit(AstNodeProcedure* nodep) VL_OVERRIDE { iterateProcedure(nodep); } + virtual void visit(AstWhile* nodep) VL_OVERRIDE { iterateProcedure(nodep); } virtual void visit(AstNodeFTask* nodep) VL_OVERRIDE { + if (!nodep->dpiImport()) iterateProcedure(nodep); + } + void iterateProcedure(AstNode* nodep) { + CheckState lastState = m_state; bool oldtog = m_inToggleOff; { m_inToggleOff = true; + createHandle(nodep); iterateChildren(nodep); + if (m_state.lineCoverageOn(nodep)) { + lineTrack(nodep); + AstNode* newp + = newCoverInc(nodep->fileline(), "", "v_line", "block", + linesCov(m_state, nodep), 0, traceNameForLine(nodep, "block")); + if (AstNodeProcedure* itemp = VN_CAST(nodep, NodeProcedure)) { + itemp->addStmtp(newp); + } else if (AstNodeFTask* itemp = VN_CAST(nodep, NodeFTask)) { + itemp->addStmtsp(newp); + } else if (AstWhile* itemp = VN_CAST(nodep, While)) { + itemp->addBodysp(newp); + } else { + nodep->v3fatalSrc("Bad node type"); + } + } } + m_state = lastState; m_inToggleOff = oldtog; } + + // VISITORS - TOGGLE COVERAGE virtual void visit(AstVar* nodep) VL_OVERRIDE { iterateChildren(nodep); - if (m_modp && !m_inModOff && !m_inToggleOff && nodep->fileline()->coverageOn() + if (m_modp && !m_inToggleOff && !m_state.m_inModOff && nodep->fileline()->coverageOn() && v3Global.opt.coverageToggle()) { const char* disablep = varIgnoreToggle(nodep); if (disablep) { @@ -203,7 +306,8 @@ private: void toggleVarBottom(const ToggleEnt& above, const AstVar* varp) { AstCoverToggle* newp = new AstCoverToggle( varp->fileline(), - newCoverInc(varp->fileline(), "", "v_toggle", varp->name() + above.m_comment, ""), + newCoverInc(varp->fileline(), "", "v_toggle", varp->name() + above.m_comment, "", 0, + ""), above.m_varRefp->cloneTree(true), above.m_chgRefp->cloneTree(true)); m_modp->addStmtp(newp); } @@ -282,78 +386,133 @@ private: } // VISITORS - LINE COVERAGE - virtual void - visit(AstIf* nodep) VL_OVERRIDE { // Note not AstNodeIf; other types don't get covered + // Note not AstNodeIf; other types don't get covered + virtual void visit(AstIf* nodep) VL_OVERRIDE { UINFO(4, " IF: " << nodep << endl); - if (m_checkBlock) { + if (m_state.m_on) { // An else-if. When we iterate the if, use "elsif" marking - bool elsif = (VN_IS(nodep->elsesp(), If) && !VN_CAST(nodep->elsesp(), If)->nextp()); + bool elsif = nodep->ifsp() && VN_IS(nodep->elsesp(), If) && !nodep->elsesp()->nextp(); if (elsif) VN_CAST(nodep->elsesp(), If)->user1(true); + bool first_elsif = !nodep->user1() && elsif; + bool cont_elsif = nodep->user1() && elsif; + bool final_elsif = nodep->user1() && !elsif && nodep->elsesp(); // - iterateAndNextNull(nodep->ifsp()); - if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn() - && v3Global.opt.coverageLine()) { // if a "if" branch didn't disable it - UINFO(4, " COVER: " << nodep << endl); - if (nodep->user1()) { + // Considered: If conditional is on a different line from if/else then we + // can show it as part of line coverage of the statement + // above. Otherwise show it based on what is inside. + // But: Seemed too complicated, and fragile. + CheckState lastState = m_state; + CheckState ifState; + CheckState elseState; + { + createHandle(nodep); + iterateAndNextNull(nodep->ifsp()); + lineTrack(nodep); + ifState = m_state; + } + m_state = lastState; + { + createHandle(nodep); + iterateAndNextNull(nodep->elsesp()); + elseState = m_state; + } + m_state = lastState; + // + // If both if and else are "on", and we're not in an if/else, then + // we do branch coverage + if (!(first_elsif || cont_elsif || final_elsif) && ifState.lineCoverageOn(nodep) + && elseState.lineCoverageOn(nodep)) { + // Normal if. Linecov shows what's inside the if (not condition that is + // always executed) + UINFO(4, " COVER-branch: " << nodep << endl); + nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_branch", "if", + linesCov(ifState, nodep), 0, + traceNameForLine(nodep, "if"))); + // The else has a column offset of 1 to uniquify it relative to the if + // As "if" and "else" are more than one character wide, this won't overlap + // another token + nodep->addElsesp(newCoverInc(nodep->fileline(), "", "v_branch", "else", + linesCov(elseState, nodep), 1, + traceNameForLine(nodep, "else"))); + } + // If/else attributes to each block as non-branch coverage + else if (first_elsif || cont_elsif) { + UINFO(4, " COVER-elsif: " << nodep << endl); + if (ifState.lineCoverageOn(nodep)) { nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "elsif", + linesCov(ifState, nodep), 0, traceNameForLine(nodep, "elsif"))); - } else { + } + // and we don't insert the else as the child if-else will do so + } else { + // Cover as separate blocks (not a branch as is not two-legged) + if (ifState.lineCoverageOn(nodep)) { + UINFO(4, " COVER-half-if: " << nodep << endl); nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "if", + linesCov(ifState, nodep), 0, traceNameForLine(nodep, "if"))); } - } - // Don't do empty else's, only empty if/case's - if (nodep->elsesp()) { - m_checkBlock = true; - iterateAndNextNull(nodep->elsesp()); - if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn() - && v3Global.opt.coverageLine()) { // if a "else" branch didn't disable it - UINFO(4, " COVER: " << nodep << endl); - if (!elsif) { // elsif done inside if() - nodep->addElsesp(newCoverInc(nodep->elsesp()->fileline(), "", "v_line", - "else", traceNameForLine(nodep, "else"))); - } + if (elseState.lineCoverageOn(nodep)) { + UINFO(4, " COVER-half-el: " << nodep << endl); + nodep->addElsesp(newCoverInc(nodep->fileline(), "", "v_line", "else", + linesCov(elseState, nodep), 1, + traceNameForLine(nodep, "else"))); } } - m_checkBlock = true; // Reset as a child may have cleared it + m_state = lastState; } + UINFO(9, " done HANDLE " << m_state.m_handle << " for " << nodep << endl); } virtual void visit(AstCaseItem* nodep) VL_OVERRIDE { + // We don't add an explicit "default" coverage if not provided, + // as we already have a warning when there is no default. UINFO(4, " CASEI: " << nodep << endl); - if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn() - && v3Global.opt.coverageLine()) { - iterateAndNextNull(nodep->bodysp()); - if (m_checkBlock) { // if the case body didn't disable it - UINFO(4, " COVER: " << nodep << endl); - nodep->addBodysp(newCoverInc(nodep->fileline(), "", "v_line", "case", - traceNameForLine(nodep, "case"))); + if (m_state.lineCoverageOn(nodep)) { + CheckState lastState = m_state; + { + createHandle(nodep); + iterateAndNextNull(nodep->bodysp()); + if (m_state.lineCoverageOn(nodep)) { // if the case body didn't disable it + lineTrack(nodep); + UINFO(4, " COVER: " << nodep << endl); + nodep->addBodysp(newCoverInc(nodep->fileline(), "", "v_line", "case", + linesCov(m_state, nodep), 0, + traceNameForLine(nodep, "case"))); + } } - m_checkBlock = true; // Reset as a child may have cleared it + m_state = lastState; } } virtual void visit(AstCover* nodep) VL_OVERRIDE { UINFO(4, " COVER: " << nodep << endl); - m_checkBlock = true; // Always do cover blocks, even if there's a $stop - iterateChildren(nodep); - if (!nodep->coverincp()) { - // Note the name may be overridden by V3Assert processing - nodep->coverincp(newCoverInc(nodep->fileline(), m_beginHier, "v_user", "cover", - m_beginHier + "_vlCoverageUserTrace")); + CheckState lastState = m_state; + { + m_state.m_on = true; // Always do cover blocks, even if there's a $stop + createHandle(nodep); + iterateChildren(nodep); + if (!nodep->coverincp() && v3Global.opt.coverageUser()) { + // Note the name may be overridden by V3Assert processing + lineTrack(nodep); + nodep->coverincp(newCoverInc(nodep->fileline(), m_beginHier, "v_user", "cover", + linesCov(m_state, nodep), 0, + m_beginHier + "_vlCoverageUserTrace")); + } } - m_checkBlock = true; // Reset as a child may have cleared it + m_state = lastState; } virtual void visit(AstStop* nodep) VL_OVERRIDE { UINFO(4, " STOP: " << nodep << endl); - m_checkBlock = false; + m_state.m_on = false; } virtual void visit(AstPragma* nodep) VL_OVERRIDE { if (nodep->pragType() == AstPragmaType::COVERAGE_BLOCK_OFF) { // Skip all NEXT nodes under this block, and skip this if/case branch - UINFO(4, " OFF: " << nodep << endl); - m_checkBlock = false; + UINFO(4, " OFF: h" << m_state.m_handle << " " << nodep << endl); + m_state.m_on = false; VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else { - if (m_checkBlock) iterateChildren(nodep); + if (m_state.m_on) iterateChildren(nodep); + lineTrack(nodep); } } virtual void visit(AstBegin* nodep) VL_OVERRIDE { @@ -370,6 +529,7 @@ private: m_beginHier = m_beginHier + (m_beginHier != "" ? "." : "") + nodep->name(); } iterateChildren(nodep); + lineTrack(nodep); } m_beginHier = oldHier; m_inToggleOff = oldtog; @@ -377,21 +537,18 @@ private: // VISITORS - BOTH virtual void visit(AstNode* nodep) VL_OVERRIDE { - if (m_checkBlock) { - iterateChildren(nodep); - m_checkBlock = true; // Reset as a child may have cleared it - } + iterateChildren(nodep); + lineTrack(nodep); } public: // CONSTRUCTORS explicit CoverageVisitor(AstNetlist* rootp) { // Operate on all modules - m_checkBlock = true; + m_nextHandle = 0; m_modp = NULL; m_beginHier = ""; m_inToggleOff = false; - m_inModOff = true; iterateChildren(rootp); } virtual ~CoverageVisitor() {} diff --git a/src/V3CoverageJoin.cpp b/src/V3CoverageJoin.cpp index d25bd8c8f..b0b1025ac 100644 --- a/src/V3CoverageJoin.cpp +++ b/src/V3CoverageJoin.cpp @@ -25,7 +25,6 @@ #include "V3Hashed.h" #include "V3Stats.h" -#include #include //###################################################################### diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index 0cf64c20a..d43e011ee 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -41,7 +41,6 @@ #include "V3Dead.h" #include "V3Ast.h" -#include #include #include @@ -96,7 +95,6 @@ private: AssignMap m_assignMap; // List of all simple assignments for each variable bool m_elimUserVars; // Allow removal of user's vars bool m_elimDTypes; // Allow removal of DTypes - bool m_elimScopes; // Allow removal of Scopes bool m_elimCells; // Allow removal of Cells bool m_sideEffect; // Side effects discovered in assign RHS @@ -197,6 +195,8 @@ private: iterateChildren(nodep); checkDType(nodep); checkAll(nodep); + UASSERT_OBJ(!(m_elimCells && nodep->typedefp()), nodep, + "RefDType should point to data type before typedefs removed"); if (nodep->packagep()) { if (m_elimCells) { nodep->packagep(NULL); @@ -442,7 +442,6 @@ public: m_elimCells = elimCells; m_elimUserVars = elimUserVars; m_elimDTypes = elimDTypes; - m_elimScopes = elimScopes; m_sideEffect = false; // Prepare to remove some datatypes nodep->typeTablep()->clearCache(); diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 44b8bc858..e0f67f03e 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -57,7 +57,6 @@ #include "V3Stats.h" #include -#include #include #include @@ -457,7 +456,7 @@ private: } } - virtual void visit(AstNodeFor* nodep) VL_OVERRIDE { + virtual void visit(AstNodeFor* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE nodep->v3fatalSrc( "For statements should have been converted to while statements in V3Begin"); } diff --git a/src/V3Depth.cpp b/src/V3Depth.cpp index ae23d3cd2..9ca85d2ef 100644 --- a/src/V3Depth.cpp +++ b/src/V3Depth.cpp @@ -31,7 +31,6 @@ #include "V3Ast.h" #include -#include //###################################################################### diff --git a/src/V3DepthBlock.cpp b/src/V3DepthBlock.cpp index 04fab51f6..55000a20a 100644 --- a/src/V3DepthBlock.cpp +++ b/src/V3DepthBlock.cpp @@ -29,7 +29,6 @@ #include "V3EmitCBase.h" #include -#include //###################################################################### diff --git a/src/V3Descope.cpp b/src/V3Descope.cpp index 4f4966a60..d969ec144 100644 --- a/src/V3Descope.cpp +++ b/src/V3Descope.cpp @@ -30,7 +30,6 @@ #include "V3Ast.h" #include "V3EmitCBase.h" -#include #include //###################################################################### diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index d31156ccf..19f8939a3 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -26,8 +26,6 @@ #include "V3TSP.h" #include -#include -#include #include #include #include VL_INCLUDE_UNORDERED_SET @@ -73,7 +71,7 @@ public: void displayNode(AstNode* nodep, AstScopeName* scopenamep, const string& vformat, AstNode* exprsp, bool isScan); void displayEmit(AstNode* nodep, bool isScan); - void displayArg(AstNode* dispp, AstNode** elistp, bool isScan, const string& vfmt, + void displayArg(AstNode* dispp, AstNode** elistp, bool isScan, const string& vfmt, bool ignore, char fmtLetter); void emitVarDecl(const AstVar* nodep, const string& prefixIfImp); @@ -304,13 +302,7 @@ public: AstAssocArrayDType* adtypep = VN_CAST(nodep->fromp()->dtypep(), AssocArrayDType); UASSERT_OBJ(adtypep, nodep, "Associative select on non-associative type"); if (adtypep->keyDTypep()->isWide()) { - // Container class must take non-C-array (pointer) argument, so convert - putbs("VL_CVT_W_A("); - iterateAndNextNull(nodep->bitp()); - puts(", "); - iterateAndNextNull(nodep->fromp()); - putbs(".atDefault()"); // Not accessed; only to get the proper type of values - puts(")"); + emitCvtWideArray(nodep->bitp(), nodep->fromp()); } else { iterateAndNextNull(nodep->bitp()); } @@ -351,10 +343,21 @@ public: bool comma = false; for (AstNode* subnodep = nodep->pinsp(); subnodep; subnodep = subnodep->nextp()) { if (comma) puts(", "); - iterate(subnodep); + // handle wide arguments to the queues + if (VN_IS(nodep->fromp()->dtypep(), QueueDType) && subnodep->dtypep()->isWide()) { + emitCvtWideArray(subnodep, nodep->fromp()); + } else { + iterate(subnodep); + } comma = true; } puts(")"); + // if there is a return value that is wide convert to array + if (nodep->dtypep()->isWide() + && (VN_IS(nodep->fromp()->dtypep(), QueueDType) + || VN_IS(nodep->fromp()->dtypep(), DynArrayDType))) { + puts(".data()"); // Access returned std::array as C array + } // Some are statements some are math. if (nodep->isStatement()) puts(";\n"); UASSERT_OBJ(!nodep->isStatement() || VN_IS(nodep->dtypep(), VoidDType), nodep, @@ -363,7 +366,7 @@ public: virtual void visit(AstIntfRef* nodep) VL_OVERRIDE { putsQuoted(VIdProtect::protectWordsIf(AstNode::vcdName(nodep->name()), nodep->protect())); } - virtual void visit(AstNodeCase* nodep) VL_OVERRIDE { + virtual void visit(AstNodeCase* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE // In V3Case... nodep->v3fatalSrc("Case statements should have been reduced out"); } @@ -395,7 +398,7 @@ public: puts(", "); puts(cvtToStr(nodep->fileline()->lineno())); puts(", "); - puts(cvtToStr(nodep->column())); + puts(cvtToStr(nodep->offset() + nodep->fileline()->firstColumn())); puts(", "); putsQuoted((!nodep->hier().empty() ? "." : "") + protectWordsIf(nodep->hier(), nodep->protect())); @@ -403,6 +406,8 @@ public: putsQuoted(protectWordsIf(nodep->page(), nodep->protect())); puts(", "); putsQuoted(protectWordsIf(nodep->comment(), nodep->protect())); + puts(", "); + putsQuoted(nodep->linescov()); puts(");\n"); } virtual void visit(AstCoverInc* nodep) VL_OVERRIDE { @@ -526,20 +531,18 @@ public: } virtual void visit(AstFOpen* nodep) VL_OVERRIDE { iterateAndNextNull(nodep->filep()); - puts(" = VL_FOPEN_"); - emitIQW(nodep->filenamep()); - emitIQW(nodep->modep()); + puts(" = VL_FOPEN_NN("); + emitCvtPackStr(nodep->filenamep()); + putbs(", "); if (nodep->modep()->width() > 4 * 8) nodep->modep()->v3error("$fopen mode should be <= 4 characters"); - puts("("); - if (nodep->filenamep()->isWide()) { - puts(cvtToStr(nodep->filenamep()->widthWords())); - putbs(", "); - } - checkMaxWords(nodep->filenamep()); - iterateAndNextNull(nodep->filenamep()); - putbs(", "); - iterateAndNextNull(nodep->modep()); + emitCvtPackStr(nodep->modep()); + puts(");\n"); + } + virtual void visit(AstFOpenMcd* nodep) VL_OVERRIDE { + iterateAndNextNull(nodep->filep()); + puts(" = VL_FOPEN_MCD_N("); + emitCvtPackStr(nodep->filenamep()); puts(");\n"); } virtual void visit(AstNodeReadWriteMem* nodep) VL_OVERRIDE { @@ -582,7 +585,7 @@ public: if (nodep->msbp()) { iterateAndNextNull(nodep->msbp()); } else { - puts("~VL_ULL(0)"); + puts("~0ULL"); } puts(");\n"); } @@ -599,29 +602,29 @@ public: } else { puts("if ("); iterateAndNextNull(nodep->filep()); - puts(") { fflush(VL_CVT_I_FP("); + puts(") { VL_FFLUSH_I("); iterateAndNextNull(nodep->filep()); - puts(")); }\n"); + puts("); }\n"); } } virtual void visit(AstFSeek* nodep) VL_OVERRIDE { - puts("(fseek(VL_CVT_I_FP("); + puts("(VL_FSEEK_I("); iterateAndNextNull(nodep->filep()); - puts("),"); + puts(","); iterateAndNextNull(nodep->offset()); puts(","); iterateAndNextNull(nodep->operation()); puts(")==-1?-1:0)"); } virtual void visit(AstFTell* nodep) VL_OVERRIDE { - puts("ftell(VL_CVT_I_FP("); + puts("VL_FTELL_I("); iterateAndNextNull(nodep->filep()); - puts("))"); + puts(")"); } virtual void visit(AstFRewind* nodep) VL_OVERRIDE { - puts("(fseek(VL_CVT_I_FP("); + puts("(VL_FSEEK_I("); iterateAndNextNull(nodep->filep()); - puts("), 0, 0)==-1?-1:0)"); + puts(", 0, 0)==-1?-1:0)"); } virtual void visit(AstFRead* nodep) VL_OVERRIDE { puts("VL_FREAD_I("); @@ -697,15 +700,18 @@ public: iterateAndNextNull(nodep->lhsp()); puts(")"); } - virtual void visit(AstJumpGo* nodep) VL_OVERRIDE { - puts("goto __Vlabel" + cvtToStr(nodep->labelp()->labelNum()) + ";\n"); - } - virtual void visit(AstJumpLabel* nodep) VL_OVERRIDE { + virtual void visit(AstJumpBlock* nodep) VL_OVERRIDE { nodep->labelNum(++m_labelNum); puts("{\n"); // Make it visually obvious label jumps outside these iterateAndNextNull(nodep->stmtsp()); + iterateAndNextNull(nodep->endStmtsp()); puts("}\n"); - puts("__Vlabel" + cvtToStr(nodep->labelNum()) + ": ;\n"); + } + virtual void visit(AstJumpGo* nodep) VL_OVERRIDE { + puts("goto __Vlabel" + cvtToStr(nodep->labelp()->blockp()->labelNum()) + ";\n"); + } + virtual void visit(AstJumpLabel* nodep) VL_OVERRIDE { + puts("__Vlabel" + cvtToStr(nodep->blockp()->labelNum()) + ": ;\n"); } virtual void visit(AstWhile* nodep) VL_OVERRIDE { iterateAndNextNull(nodep->precondsp()); @@ -997,6 +1003,26 @@ public: emitOpName(nodep, "VL_STREAML_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)", nodep->lhsp(), nodep->rhsp(), NULL); } + virtual void visit(AstCountBits* nodep) VL_OVERRIDE { + putbs("VL_COUNTBITS_"); + emitIQW(nodep->lhsp()); + puts("("); + puts(cvtToStr(nodep->lhsp()->widthMin())); + puts(", "); + if (nodep->lhsp()->isWide()) { + puts(cvtToStr(nodep->lhsp()->widthWords())); // Note argument width, not node width + // (which is always 32) + puts(", "); + } + iterateAndNextNull(nodep->lhsp()); + puts(", "); + iterateAndNextNull(nodep->rhsp()); + puts(", "); + iterateAndNextNull(nodep->thsp()); + puts(", "); + iterateAndNextNull(nodep->fhsp()); + puts(")"); + } // Terminals virtual void visit(AstVarRef* nodep) VL_OVERRIDE { puts(nodep->hiernameProtect()); @@ -1020,6 +1046,14 @@ public: puts(")"); } } + void emitCvtWideArray(AstNode* nodep, AstNode* fromp) { + putbs("VL_CVT_W_A("); + iterate(nodep); + puts(", "); + iterate(fromp); + putbs(".atDefault()"); // Not accessed; only to get the proper type of values + puts(")"); + } void emitConstant(AstConst* nodep, AstVarRef* assigntop, const string& assignString) { // Put out constant set to the specified variable, or given variable in a string if (nodep->num().isFourState()) { @@ -1103,9 +1137,9 @@ public: } else if (nodep->isQuad()) { vluint64_t num = nodep->toUQuad(); if (num < 10) { - ofp()->printf("VL_ULL(%" VL_PRI64 "u)", num); + ofp()->printf("%" VL_PRI64 "uULL", num); } else { - ofp()->printf("VL_ULL(0x%" VL_PRI64 "x)", num); + ofp()->printf("0x%" VL_PRI64 "xULL", num); } } else { uint32_t num = nodep->toUInt(); @@ -1617,17 +1651,22 @@ class EmitCImp : EmitCStmts { AstBasicDType* basicp = dtypep->basicp(); // Returns string to do resetting, empty to do nothing (which caller should handle) if (AstAssocArrayDType* adtypep = VN_CAST(dtypep, AssocArrayDType)) { - string cvtarray - = (adtypep->subDTypep()->isWide() ? ".data()" - : ""); // Access std::array as C array + // Access std::array as C array + string cvtarray = (adtypep->subDTypep()->isWide() ? ".data()" : ""); return emitVarResetRecurse(varp, adtypep->subDTypep(), depth + 1, ".atDefault()" + cvtarray); - } else if (AstClassRefDType* adtypep = VN_CAST(dtypep, ClassRefDType)) { + } else if (VN_IS(dtypep, ClassRefDType)) { return ""; // Constructor does it } else if (AstDynArrayDType* adtypep = VN_CAST(dtypep, DynArrayDType)) { - return emitVarResetRecurse(varp, adtypep->subDTypep(), depth + 1, ".atDefault()"); + // Access std::array as C array + string cvtarray = (adtypep->subDTypep()->isWide() ? ".data()" : ""); + return emitVarResetRecurse(varp, adtypep->subDTypep(), depth + 1, + ".atDefault()" + cvtarray); } else if (AstQueueDType* adtypep = VN_CAST(dtypep, QueueDType)) { - return emitVarResetRecurse(varp, adtypep->subDTypep(), depth + 1, ".atDefault()"); + // Access std::array as C array + string cvtarray = (adtypep->subDTypep()->isWide() ? ".data()" : ""); + return emitVarResetRecurse(varp, adtypep->subDTypep(), depth + 1, + ".atDefault()" + cvtarray); } else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) { UASSERT_OBJ(adtypep->msb() >= adtypep->lsb(), varp, "Should have swapped msb & lsb earlier."); @@ -1710,7 +1749,7 @@ public: m_fast = false; } virtual ~EmitCImp() {} - void mainImp(AstNodeModule* modp, bool slow, bool fast); + void mainImp(AstNodeModule* modp, bool slow); void mainInt(AstNodeModule* modp); void mainDoFunc(AstCFunc* nodep) { iterate(nodep); } }; @@ -1845,12 +1884,12 @@ void EmitCStmts::emitOpName(AstNode* nodep, const string& format, AstNode* lhsp, string nextComma; bool needComma = false; #define COMMA \ - { \ + do { \ if (!nextComma.empty()) { \ puts(nextComma); \ nextComma = ""; \ } \ - } + } while (false) putbs(""); for (string::const_iterator pos = format.begin(); pos != format.end(); ++pos) { @@ -2019,27 +2058,30 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) { ofp()->putsQuoted(emitDispState.m_format); // Arguments for (unsigned i = 0; i < emitDispState.m_argsp.size(); i++) { - puts(","); char fmt = emitDispState.m_argsChar[i]; AstNode* argp = emitDispState.m_argsp[i]; string func = emitDispState.m_argsFunc[i]; - ofp()->indentInc(); - ofp()->putbs(""); - if (func != "") puts(func); - if (argp) { - if (isScan) { - puts("&("); - } else if (fmt == '@') { - puts("&("); - } - iterate(argp); - if (isScan) { - puts(")"); - } else if (fmt == '@') { - puts(")"); + if (func != "" || argp) { + puts(","); + ofp()->indentInc(); + ofp()->putbs(""); + if (func != "") { + puts(func); + } else if (argp) { + if (isScan) { + puts("&("); + } else if (fmt == '@') { + puts("&("); + } + iterate(argp); + if (isScan) { + puts(")"); + } else if (fmt == '@') { + puts(")"); + } } + ofp()->indentDec(); } - ofp()->indentDec(); } // End puts(")"); @@ -2053,28 +2095,33 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) { } void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan, const string& vfmt, - char fmtLetter) { + bool ignore, char fmtLetter) { // Print display argument, edits elistp - AstNode* argp = *elistp; - if (VL_UNCOVERABLE(!argp)) { - // expectDisplay() checks this first, so internal error if found here - dispp->v3error("Internal: Missing arguments for $display-like format"); // LCOV_EXCL_LINE - return; // LCOV_EXCL_LINE + AstNode* argp = NULL; + if (!ignore) { + argp = *elistp; + // Prep for next parameter + *elistp = (*elistp)->nextp(); + if (VL_UNCOVERABLE(!argp)) { + // expectDisplay() checks this first, so internal error if found here + dispp->v3error( + "Internal: Missing arguments for $display-like format"); // LCOV_EXCL_LINE + return; // LCOV_EXCL_LINE + } + if (argp->widthMin() > VL_VALUE_STRING_MAX_WIDTH) { + dispp->v3error("Exceeded limit of " + cvtToStr(VL_VALUE_STRING_MAX_WIDTH) + + " bits for any $display-like arguments"); + } + if (argp->widthMin() > 8 && fmtLetter == 'c') { + // Technically legal, but surely not what the user intended. + argp->v3warn(WIDTH, dispp->verilogKwd() << "of %c format of > 8 bit value"); + } } - if (argp->widthMin() > VL_VALUE_STRING_MAX_WIDTH) { - dispp->v3error("Exceeded limit of " + cvtToStr(VL_VALUE_STRING_MAX_WIDTH) - + " bits for any $display-like arguments"); - } - if (argp->widthMin() > 8 && fmtLetter == 'c') { - // Technically legal, but surely not what the user intended. - argp->v3warn(WIDTH, dispp->verilogKwd() << "of %c format of > 8 bit value"); - } - // string pfmt = "%"+displayFormat(argp, vfmt, fmtLetter)+fmtLetter; string pfmt; if ((fmtLetter == '#' || fmtLetter == 'd') && !isScan && vfmt == "") { // Size decimal output. Spec says leading spaces, not zeros - const double mantissabits = argp->widthMin() - ((fmtLetter == 'd') ? 1 : 0); + const double mantissabits = ignore ? 0 : (argp->widthMin() - ((fmtLetter == 'd') ? 1 : 0)); // This is log10(2**mantissabits) as log2(2**mantissabits)/log2(10), // + 1.0 rounding bias. double dchars = mantissabits / 3.321928094887362 + 1.0; @@ -2085,11 +2132,12 @@ void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan, const pfmt = string("%") + vfmt + fmtLetter; } emitDispState.pushFormat(pfmt); - emitDispState.pushArg(' ', NULL, cvtToStr(argp->widthMin())); - emitDispState.pushArg(fmtLetter, argp, ""); - - // Next parameter - *elistp = (*elistp)->nextp(); + if (!ignore) { + emitDispState.pushArg(' ', NULL, cvtToStr(argp->widthMin())); + emitDispState.pushArg(fmtLetter, argp, ""); + } else { + emitDispState.pushArg(fmtLetter, NULL, ""); + } } void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep, const string& vformat, @@ -2102,17 +2150,28 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep, const str string vfmt; string::const_iterator pos = vformat.begin(); bool inPct = false; + bool ignore = false; for (; pos != vformat.end(); ++pos) { // UINFO(1, "Parse '" << *pos << "' IP" << inPct << " List " << cvtToHex(elistp) << endl); if (!inPct && pos[0] == '%') { inPct = true; + ignore = false; vfmt = ""; } else if (!inPct) { // Normal text emitDispState.pushFormat(*pos); } else { // Format character inPct = false; switch (tolower(pos[0])) { - case '0' ... '9': + case '0': // FALLTHRU + case '1': // FALLTHRU + case '2': // FALLTHRU + case '3': // FALLTHRU + case '4': // FALLTHRU + case '5': // FALLTHRU + case '6': // FALLTHRU + case '7': // FALLTHRU + case '8': // FALLTHRU + case '9': // FALLTHRU case '.': // FALLTHRU case '-': // Digits, like %5d, etc. @@ -2122,25 +2181,36 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep, const str case '%': emitDispState.pushFormat("%%"); // We're printf'ing it, so need to quote the % break; + case '*': + vfmt += pos[0]; + inPct = true; // Get more digits + ignore = true; + break; // Special codes - case '~': displayArg(nodep, &elistp, isScan, vfmt, 'd'); break; // Signed decimal + case '~': + displayArg(nodep, &elistp, isScan, vfmt, ignore, 'd'); + break; // Signed decimal case '@': - displayArg(nodep, &elistp, isScan, vfmt, '@'); + displayArg(nodep, &elistp, isScan, vfmt, ignore, '@'); break; // Packed string // Spec: h d o b c l - case 'b': displayArg(nodep, &elistp, isScan, vfmt, 'b'); break; - case 'c': displayArg(nodep, &elistp, isScan, vfmt, 'c'); break; - case 't': displayArg(nodep, &elistp, isScan, vfmt, 't'); break; - case 'd': displayArg(nodep, &elistp, isScan, vfmt, '#'); break; // Unsigned decimal - case 'o': displayArg(nodep, &elistp, isScan, vfmt, 'o'); break; + case 'b': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'b'); break; + case 'c': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'c'); break; + case 't': displayArg(nodep, &elistp, isScan, vfmt, ignore, 't'); break; + case 'd': + displayArg(nodep, &elistp, isScan, vfmt, ignore, '#'); + break; // Unsigned decimal + case 'o': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'o'); break; case 'h': // FALLTHRU - case 'x': displayArg(nodep, &elistp, isScan, vfmt, 'x'); break; - case 's': displayArg(nodep, &elistp, isScan, vfmt, 's'); break; - case 'e': displayArg(nodep, &elistp, isScan, vfmt, 'e'); break; - case 'f': displayArg(nodep, &elistp, isScan, vfmt, 'f'); break; - case 'g': displayArg(nodep, &elistp, isScan, vfmt, 'g'); break; - case '^': displayArg(nodep, &elistp, isScan, vfmt, '^'); break; // Realtime - case 'v': displayArg(nodep, &elistp, isScan, vfmt, 'v'); break; + case 'x': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'x'); break; + case 's': displayArg(nodep, &elistp, isScan, vfmt, ignore, 's'); break; + case 'e': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'e'); break; + case 'f': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'f'); break; + case 'g': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'g'); break; + case '^': displayArg(nodep, &elistp, isScan, vfmt, ignore, '^'); break; // Realtime + case 'v': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'v'); break; + case 'u': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'u'); break; + case 'z': displayArg(nodep, &elistp, isScan, vfmt, ignore, 'z'); break; case 'm': { UASSERT_OBJ(scopenamep, nodep, "Display with %m but no AstScopeName"); string suffix = scopenamep->scopePrettySymName(); @@ -2181,7 +2251,8 @@ void EmitCImp::emitCoverageDecl(AstNodeModule* modp) { puts("void __vlCoverInsert("); puts(v3Global.opt.threads() ? "std::atomic" : "uint32_t"); puts("* countp, bool enable, const char* filenamep, int lineno, int column,\n"); - puts("const char* hierp, const char* pagep, const char* commentp);\n"); + puts("const char* hierp, const char* pagep, const char* commentp, const char* " + "linescovp);\n"); } } @@ -2285,12 +2356,12 @@ void EmitCImp::emitConfigureImp(AstNodeModule* modp) { puts("if (false && this->__VlSymsp) {} // Prevent unused\n"); if (v3Global.opt.coverage()) { puts(protect("_configure_coverage") + "(vlSymsp, first);\n"); } if (modp->isTop() && !v3Global.rootp()->timeunit().isNone()) { - puts("Verilated::timeunit(" + cvtToStr(v3Global.rootp()->timeunit().negativeInt()) + puts("Verilated::timeunit(" + cvtToStr(v3Global.rootp()->timeunit().powerOfTen()) + ");\n"); } if (modp->isTop() && !v3Global.rootp()->timeprecision().isNone()) { - puts("Verilated::timeprecision(" - + cvtToStr(v3Global.rootp()->timeprecision().negativeInt()) + ");\n"); + puts("Verilated::timeprecision(" + cvtToStr(v3Global.rootp()->timeprecision().powerOfTen()) + + ");\n"); } puts("}\n"); splitSizeInc(10); @@ -2304,7 +2375,8 @@ void EmitCImp::emitCoverageImp(AstNodeModule* modp) { puts("void " + prefixNameProtect(m_modp) + "::__vlCoverInsert("); puts(v3Global.opt.threads() ? "std::atomic" : "uint32_t"); puts("* countp, bool enable, const char* filenamep, int lineno, int column,\n"); - puts("const char* hierp, const char* pagep, const char* commentp) {\n"); + puts("const char* hierp, const char* pagep, const char* commentp, const char* linescovp) " + "{\n"); if (v3Global.opt.threads()) { puts("assert(sizeof(uint32_t) == sizeof(std::atomic));\n"); puts("uint32_t* count32p = reinterpret_cast(countp);\n"); @@ -2324,7 +2396,8 @@ void EmitCImp::emitCoverageImp(AstNodeModule* modp) { // puts( "\"hier\",std::string(__VlSymsp->name())+hierp,"); puts("\"hier\",std::string(name())+hierp,"); puts(" \"page\",pagep,"); - puts(" \"comment\",commentp);\n"); + puts(" \"comment\",commentp,"); + puts(" (linescovp[0] ? \"linescov\" : \"\"), linescovp);\n"); puts("}\n"); splitSizeInc(10); } @@ -2370,7 +2443,7 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) { hash.insert(varp->dtypep()->width()); } } - ofp()->printf("vluint64_t __Vcheckval = VL_ULL(0x%" VL_PRI64 "x);\n", + ofp()->printf("vluint64_t __Vcheckval = 0x%" VL_PRI64 "xULL;\n", static_cast(hash.digestUInt64())); if (de) { puts("os.readAssert(__Vcheckval);\n"); @@ -2872,9 +2945,6 @@ void EmitCImp::emitIntTop(AstNodeModule* modp) { puts("#include \"verilated_cov.h\"\n"); if (v3Global.opt.savable()) v3error("--coverage and --savable not supported together"); } - if (v3Global.needHInlines()) { // Set by V3EmitCInlines; should have been called before us - puts("#include \"" + topClassName() + "__Inlines.h\"\n"); - } if (v3Global.dpi()) { // do this before including our main .h file so that any references to // types defined in svdpi.h are available @@ -3099,13 +3169,9 @@ void EmitCImp::emitInt(AstNodeModule* modp) { emitIntFuncDecls(modp, true); if (v3Global.opt.trace() && !VN_IS(modp, Class)) { - ofp()->putsPrivate(false); // public: - puts("static void " + protect("traceInit") + "(" + v3Global.opt.traceClassBase() - + "* vcdp, void* userthis, uint32_t code);\n"); - puts("static void " + protect("traceFull") + "(" + v3Global.opt.traceClassBase() - + "* vcdp, void* userthis, uint32_t code);\n"); - puts("static void " + protect("traceChg") + "(" + v3Global.opt.traceClassBase() - + "* vcdp, void* userthis, uint32_t code);\n"); + ofp()->putsPrivate(true); // private: + puts("static void " + protect("traceInit") + "(void* userp, " + + v3Global.opt.traceClassBase() + "* tracep, uint32_t code) VL_ATTR_COLD;\n"); } if (v3Global.opt.savable()) { ofp()->putsPrivate(false); // public: @@ -3180,6 +3246,8 @@ void EmitCImp::emitImp(AstNodeModule* modp) { void EmitCImp::maybeSplit(AstNodeModule* fileModp) { if (splitNeeded()) { + // Splitting file, so using parallel build. + v3Global.useParallelBuild(true); // Close old file VL_DO_CLEAR(delete m_ofp, m_ofp = NULL); // Open a new file @@ -3210,12 +3278,12 @@ void EmitCImp::mainInt(AstNodeModule* modp) { VL_DO_CLEAR(delete m_ofp, m_ofp = NULL); } -void EmitCImp::mainImp(AstNodeModule* modp, bool slow, bool fast) { +void EmitCImp::mainImp(AstNodeModule* modp, bool slow) { // Output a module AstNodeModule* fileModp = modp; // Filename constructed using this module m_modp = modp; m_slow = slow; - m_fast = fast; + m_fast = !slow; UINFO(5, " Emitting " << prefixNameProtect(modp) << endl); @@ -3232,7 +3300,7 @@ void EmitCImp::mainImp(AstNodeModule* modp, bool slow, bool fast) { m_modp = modp; } - if (fast && modp->isTop() && v3Global.opt.mtasks()) { + if (m_fast && modp->isTop() && v3Global.opt.mtasks()) { // Make a final pass and emit function definitions for the mtasks // in the ExecGraph AstExecGraph* execGraphp = v3Global.rootp()->execGraphp(); @@ -3305,7 +3373,7 @@ class EmitCTrace : EmitCStmts { if (v3Global.needTraceDumper() && !optSystemC()) { puts("void " + topClassName() + "::_traceDump() {\n"); // Caller checked for __Vm_dumperp non-NULL - puts("VerilatedLockGuard lock(__VlSymsp->__Vm_dumperMutex);\n"); + puts("const VerilatedLockGuard lock(__VlSymsp->__Vm_dumperMutex);\n"); puts("__VlSymsp->__Vm_dumperp->dump(VL_TIME_Q());\n"); puts("}\n"); splitSizeInc(10); @@ -3313,7 +3381,7 @@ class EmitCTrace : EmitCStmts { if (v3Global.needTraceDumper()) { puts("void " + topClassName() + "::_traceDumpOpen() {\n"); - puts("VerilatedLockGuard lock(__VlSymsp->__Vm_dumperMutex);\n"); + puts("const VerilatedLockGuard lock(__VlSymsp->__Vm_dumperMutex);\n"); puts("if (VL_UNLIKELY(!__VlSymsp->__Vm_dumperp)) {\n"); puts("__VlSymsp->__Vm_dumperp = new " + v3Global.opt.traceClassLang() + "();\n"); puts("const char* cp = vl_dumpctl_filenamep();\n"); @@ -3326,7 +3394,7 @@ class EmitCTrace : EmitCStmts { splitSizeInc(10); puts("void " + topClassName() + "::_traceDumpClose() {\n"); - puts("VerilatedLockGuard lock(__VlSymsp->__Vm_dumperMutex);\n"); + puts("const VerilatedLockGuard lock(__VlSymsp->__Vm_dumperMutex);\n"); puts("__VlSymsp->__Vm_dumping = false;\n"); puts("VL_DO_CLEAR(delete __VlSymsp->__Vm_dumperp, __VlSymsp->__Vm_dumperp = NULL);\n"); puts("}\n"); @@ -3335,53 +3403,26 @@ class EmitCTrace : EmitCStmts { puts("void " + topClassName() + "::trace("); puts(v3Global.opt.traceClassBase() + "C* tfp, int, int) {\n"); - puts("tfp->spTrace()->addCallback(" - "&" - + topClassName() + "::" + protect("traceInit") + ", &" + topClassName() - + "::" + protect("traceFull") + ", &" + topClassName() + "::" + protect("traceChg") - + ", this);\n"); + puts("tfp->spTrace()->addInitCb(&" + protect("traceInit") + ", __VlSymsp);\n"); + puts(protect("traceRegister") + "(tfp->spTrace());\n"); puts("}\n"); + puts("\n"); splitSizeInc(10); - puts("void " + topClassName() + "::" + protect("traceInit") + "(" - + v3Global.opt.traceClassBase() + "* vcdp, void* userthis, uint32_t code) {\n"); - putsDecoration("// Callback from vcd->open()\n"); - puts(topClassName() + "* t = (" + topClassName() + "*)userthis;\n"); - puts(EmitCBaseVisitor::symClassVar() + " = t->__VlSymsp; // Setup global symbol table\n"); + puts("void " + topClassName() + "::" + protect("traceInit") + "(void* userp, " + + v3Global.opt.traceClassBase() + "* tracep, uint32_t code) {\n"); + putsDecoration("// Callback from tracep->open()\n"); + puts(symClassVar() + " = static_cast<" + symClassName() + "*>(userp);\n"); puts("if (!Verilated::calcUnusedSigs()) {\n"); puts("VL_FATAL_MT(__FILE__, __LINE__, __FILE__,\n"); puts(" \"Turning on wave traces requires Verilated::traceEverOn(true) call " "before time 0.\");\n"); puts("}\n"); - puts("vcdp->scopeEscape(' ');\n"); - puts("t->" + protect("traceInitThis") + "(vlSymsp, vcdp, code);\n"); - puts("vcdp->scopeEscape('.');\n"); // Restore so later traced files won't break - puts("}\n"); - splitSizeInc(10); - - puts("void " + topClassName() + "::" + protect("traceFull") + "(" - + v3Global.opt.traceClassBase() + "* vcdp, void* userthis, uint32_t code) {\n"); - putsDecoration("// Callback from vcd->dump()\n"); - puts(topClassName() + "* t = (" + topClassName() + "*)userthis;\n"); - puts(EmitCBaseVisitor::symClassVar() + " = t->__VlSymsp; // Setup global symbol table\n"); - puts("t->" + protect("traceFullThis") + "(vlSymsp, vcdp, code);\n"); - puts("}\n"); - splitSizeInc(10); - - puts("\n//======================\n\n"); - } - - void emitTraceFast() { - puts("\n//======================\n\n"); - - puts("void " + topClassName() + "::" + protect("traceChg") + "(" - + v3Global.opt.traceClassBase() + "* vcdp, void* userthis, uint32_t code) {\n"); - putsDecoration("// Callback from vcd->dump()\n"); - puts(topClassName() + "* t = (" + topClassName() + "*)userthis;\n"); - puts(EmitCBaseVisitor::symClassVar() + " = t->__VlSymsp; // Setup global symbol table\n"); - puts("if (vlSymsp->getClearActivity()) {\n"); - puts("t->" + protect("traceChgThis") + "(vlSymsp, vcdp, code);\n"); - puts("}\n"); + puts("vlSymsp->__Vm_baseCode = code;\n"); + puts("tracep->module(vlSymsp->name());\n"); + puts("tracep->scopeEscape(' ');\n"); + puts(topClassName() + "::" + protect("traceInitTop") + "(vlSymsp, tracep);\n"); + puts("tracep->scopeEscape('.');\n"); // Restore so later traced files won't break puts("}\n"); splitSizeInc(10); @@ -3389,21 +3430,21 @@ class EmitCTrace : EmitCStmts { } bool emitTraceIsScBv(AstTraceInc* nodep) { - const AstVarRef* varrefp = VN_CAST(nodep->valuep(), VarRef); + const AstVarRef* varrefp = VN_CAST(nodep->declp()->valuep(), VarRef); if (!varrefp) return false; AstVar* varp = varrefp->varp(); return varp->isSc() && varp->isScBv(); } bool emitTraceIsScBigUint(AstTraceInc* nodep) { - const AstVarRef* varrefp = VN_CAST(nodep->valuep(), VarRef); + const AstVarRef* varrefp = VN_CAST(nodep->declp()->valuep(), VarRef); if (!varrefp) return false; AstVar* varp = varrefp->varp(); return varp->isSc() && varp->isScBigUint(); } bool emitTraceIsScUint(AstTraceInc* nodep) { - const AstVarRef* varrefp = VN_CAST(nodep->valuep(), VarRef); + const AstVarRef* varrefp = VN_CAST(nodep->declp()->valuep(), VarRef); if (!varrefp) return false; AstVar* varp = varrefp->varp(); return varp->isSc() && varp->isScUint(); @@ -3411,15 +3452,15 @@ class EmitCTrace : EmitCStmts { void emitTraceInitOne(AstTraceDecl* nodep, int enumNum) { if (nodep->dtypep()->basicp()->isDouble()) { - puts("vcdp->declDouble"); + puts("tracep->declDouble"); } else if (nodep->isWide()) { - puts("vcdp->declArray"); + puts("tracep->declArray"); } else if (nodep->isQuad()) { - puts("vcdp->declQuad"); + puts("tracep->declQuad"); } else if (nodep->bitRange().ranged()) { - puts("vcdp->declBus"); + puts("tracep->declBus"); } else { - puts("vcdp->declBit"); + puts("tracep->declBit"); } puts("(c+" + cvtToStr(nodep->code())); @@ -3533,10 +3574,10 @@ class EmitCTrace : EmitCStmts { putbs("\"" + constp->num().displayed(nodep, "%0b") + "\""); } puts("};\n"); - puts("vcdp->declDTypeEnum(" + cvtToStr(enumNum) + ", \"" + enump->prettyName() - + "\", " + cvtToStr(nvals) + ", " + cvtToStr(enump->widthMin()) + ", " - + protect("__VenumItemNames") + ", " + protect("__VenumItemValues") - + ");\n"); + puts("tracep->declDTypeEnum(" + cvtToStr(enumNum) + ", \"" + + enump->prettyName() + "\", " + cvtToStr(nvals) + ", " + + cvtToStr(enump->widthMin()) + ", " + protect("__VenumItemNames") + ", " + + protect("__VenumItemValues") + ");\n"); puts("}\n"); } return enumNum; @@ -3547,31 +3588,29 @@ class EmitCTrace : EmitCStmts { void emitTraceChangeOne(AstTraceInc* nodep, int arrayindex) { iterateAndNextNull(nodep->precondsp()); - const bool full = (m_funcp->funcType() == AstCFuncType::TRACE_FULL - || m_funcp->funcType() == AstCFuncType::TRACE_FULL_SUB); - const string func = full ? "full" : "chg"; + const string func = nodep->full() ? "full" : "chg"; bool emitWidth = true; if (nodep->dtypep()->basicp()->isDouble()) { - puts("vcdp->" + func + "Double"); + puts("tracep->" + func + "Double"); emitWidth = false; } else if (nodep->isWide() || emitTraceIsScBv(nodep) || emitTraceIsScBigUint(nodep)) { - puts("vcdp->" + func + "WData"); + puts("tracep->" + func + "WData"); } else if (nodep->isQuad()) { - puts("vcdp->" + func + "QData"); + puts("tracep->" + func + "QData"); } else if (nodep->declp()->widthMin() > 16) { - puts("vcdp->" + func + "IData"); + puts("tracep->" + func + "IData"); } else if (nodep->declp()->widthMin() > 8) { - puts("vcdp->" + func + "SData"); + puts("tracep->" + func + "SData"); } else if (nodep->declp()->widthMin() > 1) { - puts("vcdp->" + func + "CData"); + puts("tracep->" + func + "CData"); } else { - puts("vcdp->" + func + "Bit"); + puts("tracep->" + func + "Bit"); emitWidth = false; } const uint32_t offset = (arrayindex < 0) ? 0 : (arrayindex * nodep->declp()->widthWords()); const uint32_t code = nodep->declp()->code() + offset; - puts(v3Global.opt.trueTraceThreads() && !full ? "(base+" : "(oldp+"); + puts(v3Global.opt.trueTraceThreads() && !nodep->full() ? "(base+" : "(oldp+"); puts(cvtToStr(code - m_baseCode)); puts(","); emitTraceValue(nodep, arrayindex); @@ -3579,8 +3618,7 @@ class EmitCTrace : EmitCStmts { puts(");\n"); } void emitTraceValue(AstTraceInc* nodep, int arrayindex) { - if (VN_IS(nodep->valuep(), VarRef)) { - AstVarRef* varrefp = VN_CAST(nodep->valuep(), VarRef); + if (AstVarRef* const varrefp = VN_CAST(nodep->valuep(), VarRef)) { AstVar* varp = varrefp->varp(); puts("("); if (emitTraceIsScBigUint(nodep)) { @@ -3628,6 +3666,8 @@ class EmitCTrace : EmitCStmts { m_funcp = nodep; if (splitNeeded()) { + // Splitting file, so using parallel build. + v3Global.useParallelBuild(true); // Close old file VL_DO_CLEAR(delete m_ofp, m_ofp = NULL); // Open a new file @@ -3641,41 +3681,37 @@ class EmitCTrace : EmitCStmts { puts(" "); puts(topClassName() + "::" + nodep->nameProtect() + "(" + cFuncArgs(nodep) + ") {\n"); - if (nodep->symProlog()) puts(EmitCBaseVisitor::symTopAssign() + "\n"); + if (nodep->funcType() != AstCFuncType::TRACE_REGISTER) { + puts(symClassVar() + " = static_cast<" + symClassName() + "*>(userp);\n"); + } + + if (nodep->symProlog()) puts(symTopAssign() + "\n"); m_baseCode = -1; - if (nodep->funcType() == AstCFuncType::TRACE_FULL_SUB - || nodep->funcType() == AstCFuncType::TRACE_CHANGE_SUB) { - const AstTraceInc* const stmtp = VN_CAST_CONST(nodep->stmtsp(), TraceInc); - if (!stmtp) { - nodep->stmtsp()->v3fatalSrc("Trace sub function should contain AstTraceInc"); - } - m_baseCode = stmtp->declp()->code(); - if (v3Global.opt.trueTraceThreads() - && nodep->funcType() == AstCFuncType::TRACE_CHANGE_SUB) { - puts("vluint32_t base = code+" + cvtToStr(m_baseCode) + ";\n"); - puts("if (false && vcdp && base) {} // Prevent unused\n"); + if (nodep->funcType() == AstCFuncType::TRACE_CHANGE_SUB) { + const AstNode* const stmtp = nodep->stmtsp(); + const AstIf* const ifp = VN_CAST_CONST(stmtp, If); + const AstTraceInc* const tracep + = VN_CAST_CONST(ifp ? ifp->ifsp() : stmtp, TraceInc); + // On rare occasions we can end up with an empty sub function + m_baseCode = tracep ? tracep->declp()->code() : 0; + if (v3Global.opt.trueTraceThreads()) { + puts("const vluint32_t base = vlSymsp->__Vm_baseCode + " + cvtToStr(m_baseCode) + + ";\n"); + puts("if (false && tracep && base) {} // Prevent unused\n"); } else { - puts("vluint32_t* oldp = vcdp->oldp(code+" + cvtToStr(m_baseCode) + ");\n"); - puts("if (false && vcdp && oldp) {} // Prevent unused\n"); + puts("vluint32_t* const oldp = tracep->oldp(vlSymsp->__Vm_baseCode + " + + cvtToStr(m_baseCode) + ");\n"); + puts("if (false && oldp) {} // Prevent unused\n"); } - } else if (nodep->funcType() == AstCFuncType::TRACE_INIT_SUB) { - puts("int c = code;\n"); - puts("if (false && vcdp && c) {} // Prevent unused\n"); - } else { - puts("if (false && vcdp) {} // Prevent unused\n"); - } - - if (nodep->funcType() == AstCFuncType::TRACE_INIT) { - puts("vcdp->module(vlSymsp->name()); // Setup signal names\n"); - } else if (nodep->funcType() == AstCFuncType::TRACE_INIT_SUB) { - } else if (nodep->funcType() == AstCFuncType::TRACE_FULL) { } else if (nodep->funcType() == AstCFuncType::TRACE_FULL_SUB) { - } else if (nodep->funcType() == AstCFuncType::TRACE_CHANGE) { - } else if (nodep->funcType() == AstCFuncType::TRACE_CHANGE_SUB) { - } else { - nodep->v3fatalSrc("Bad Case"); + m_baseCode = 0; + puts("vluint32_t* const oldp = tracep->oldp(vlSymsp->__Vm_baseCode);\n"); + puts("if (false && oldp) {} // Prevent unused\n"); + } else if (nodep->funcType() == AstCFuncType::TRACE_INIT_SUB) { + puts("const int c = vlSymsp->__Vm_baseCode;\n"); + puts("if (false && tracep && c) {} // Prevent unused\n"); } if (nodep->initsp()) { @@ -3734,11 +3770,7 @@ public: // Put out the file newOutCFile(0); - if (m_slow) { - emitTraceSlow(); - } else { - emitTraceFast(); - } + if (m_slow) { emitTraceSlow(); } iterate(v3Global.rootp()); @@ -3757,12 +3789,8 @@ void V3EmitC::emitc() { if (VN_IS(nodep, Class)) continue; // Imped with ClassPackage // clang-format off { EmitCImp cint; cint.mainInt(nodep); } - if (v3Global.opt.outputSplit()) { - { EmitCImp fast; fast.mainImp(nodep, false, true); } - { EmitCImp slow; slow.mainImp(nodep, true, false); } - } else { - { EmitCImp both; both.mainImp(nodep, true, true); } - } + { EmitCImp slow; slow.mainImp(nodep, true); } + { EmitCImp fast; fast.mainImp(nodep, false); } // clang-format on } } diff --git a/src/V3EmitCBase.h b/src/V3EmitCBase.h index 8e98efafe..94a5e2d8e 100644 --- a/src/V3EmitCBase.h +++ b/src/V3EmitCBase.h @@ -55,7 +55,7 @@ public: static string symClassName() { return v3Global.opt.prefix() + "_" + protect("_Syms"); } static string symClassVar() { return symClassName() + "* __restrict vlSymsp"; } static string symTopAssign() { - return v3Global.opt.prefix() + "* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;"; + return v3Global.opt.prefix() + "* const __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;"; } static string funcNameProtect(const AstCFunc* nodep, const AstNodeModule* modp) { if (nodep->isConstructor()) { diff --git a/src/V3EmitCInlines.cpp b/src/V3EmitCInlines.cpp index 23a4aecf8..39a2f4fd6 100644 --- a/src/V3EmitCInlines.cpp +++ b/src/V3EmitCInlines.cpp @@ -22,10 +22,7 @@ #include "V3EmitCBase.h" #include "V3Stats.h" -#include -#include #include -#include //###################################################################### @@ -33,104 +30,37 @@ class EmitCInlines : EmitCBaseVisitor { // STATE // METHODS - void emitInt(); + void checkHeavy(AstNode* nodep) { + if (nodep->isHeavy()) v3Global.needHeavy(true); + } // VISITORS - virtual void visit(AstBasicDType* nodep) VL_OVERRIDE { - if (nodep->keyword() == AstBasicDTypeKwd::STRING) { - // Request #include via verilated_heavy.h when we create symbol file - v3Global.needHeavy(true); - } - } - virtual void visit(AstAssocArrayDType* nodep) VL_OVERRIDE { - v3Global.needHeavy(true); - iterateChildren(nodep); - } virtual void visit(AstClass* nodep) VL_OVERRIDE { + checkHeavy(nodep); v3Global.needC11(true); - v3Global.needHeavy(true); - iterateChildren(nodep); - } - virtual void visit(AstDynArrayDType* nodep) VL_OVERRIDE { - v3Global.needHeavy(true); - iterateChildren(nodep); - } - virtual void visit(AstQueueDType* nodep) VL_OVERRIDE { - v3Global.needHeavy(true); - iterateChildren(nodep); - } - virtual void visit(AstNodeReadWriteMem* nodep) VL_OVERRIDE { - v3Global.needHeavy(true); - iterateChildren(nodep); - } - virtual void visit(AstValuePlusArgs* nodep) VL_OVERRIDE { - v3Global.needHeavy(true); iterateChildren(nodep); } virtual void visit(AstCNew* nodep) VL_OVERRIDE { + checkHeavy(nodep); if (v3Global.opt.savable()) v3error("Unsupported: --savable with dynamic new"); iterateChildren(nodep); } - virtual void visit(AstAtoN* nodep) VL_OVERRIDE { - v3Global.needHeavy(true); - iterateChildren(nodep); - } virtual void visit(AstDumpCtl* nodep) VL_OVERRIDE { + checkHeavy(nodep); if (v3Global.opt.trace()) v3Global.needTraceDumper(true); - v3Global.needHeavy(true); - iterateChildren(nodep); - } - virtual void visit(AstPutcN* nodep) VL_OVERRIDE { - v3Global.needHeavy(true); - iterateChildren(nodep); - } - virtual void visit(AstGetcN* nodep) VL_OVERRIDE { - v3Global.needHeavy(true); - iterateChildren(nodep); - } - virtual void visit(AstGetcRefN* nodep) VL_OVERRIDE { - v3Global.needHeavy(true); - iterateChildren(nodep); - } - virtual void visit(AstSubstrN* nodep) VL_OVERRIDE { - v3Global.needHeavy(true); - iterateChildren(nodep); - } - virtual void visit(AstCompareNN* nodep) VL_OVERRIDE { - v3Global.needHeavy(true); iterateChildren(nodep); } //--------------------------------------- - virtual void visit(AstNode* nodep) VL_OVERRIDE { iterateChildren(nodep); } + virtual void visit(AstNode* nodep) VL_OVERRIDE { + checkHeavy(nodep); + iterateChildren(nodep); + } public: - explicit EmitCInlines(AstNetlist* nodep) { - iterate(nodep); - if (v3Global.needHInlines()) emitInt(); - } + explicit EmitCInlines(AstNetlist* nodep) { iterate(nodep); } }; -void EmitCInlines::emitInt() { - string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Inlines.h"; - newCFile(filename, false /*slow*/, false /*source*/); - V3OutCFile hf(filename); - m_ofp = &hf; - - ofp()->putsHeader(); - ofp()->putsGuard(); - puts("\n"); - - puts("#include \"verilated.h\"\n"); - - puts("\n//======================\n\n"); - - // Placeholder - v3Global.needHInlines(true) currently not used - - puts("//======================\n\n"); - ofp()->putsEndGuard(); -} - //###################################################################### // EmitC class functions diff --git a/src/V3EmitCMain.cpp b/src/V3EmitCMain.cpp index f74bae3b0..6eba5ec84 100644 --- a/src/V3EmitCMain.cpp +++ b/src/V3EmitCMain.cpp @@ -22,10 +22,7 @@ #include "V3EmitCBase.h" #include "V3EmitCMain.h" -#include -#include #include -#include //###################################################################### @@ -33,7 +30,8 @@ class EmitCMain : EmitCBaseVisitor { // METHODS // VISITORS - virtual void visit(AstNode* nodep) { iterateChildren(nodep); } + // This visitor doesn't really iterate, but exist to appease base class + virtual void visit(AstNode* nodep) { iterateChildren(nodep); } // LCOV_EXCL_LINE public: // CONSTRUCTORS diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 807886536..bc5ce4587 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -23,10 +23,7 @@ #include "V3LanguageWords.h" #include -#include -#include #include -#include #include //###################################################################### @@ -107,7 +104,6 @@ class EmitCSyms : EmitCBaseVisitor { ScopeVars m_scopeVars; // Each {scope,public-var} ScopeNames m_vpiScopeCandidates; // All scopes for VPI ScopeNameHierarchy m_vpiScopeHierarchy; // The actual hierarchy of scopes - V3LanguageWords m_words; // Reserved word detector int m_coverBins; // Coverage bin number bool m_dpiHdrOnly; // Only emit the DPI header int m_numStmts; // Number of statements output @@ -130,7 +126,7 @@ class EmitCSyms : EmitCBaseVisitor { && !(VN_IS(nodep, CFunc) && (VN_CAST(nodep, CFunc)->isConstructor() || VN_CAST(nodep, CFunc)->isDestructor()))) { - string rsvd = m_words.isKeyword(nodep->name()); + string rsvd = V3LanguageWords::isKeyword(nodep->name()); if (rsvd != "") { // Generally V3Name should find all of these and throw SYMRSVDWORD. // We'll still check here because the compiler errors @@ -292,7 +288,7 @@ class EmitCSyms : EmitCBaseVisitor { string type = (nodep->origModName() == "__BEGIN__") ? "SCOPE_OTHER" : "SCOPE_MODULE"; string name = nodep->scopep()->name() + "__DOT__" + nodep->name(); string name_dedot = AstNode::dedotName(name); - int timeunit = m_modp->timeunit().negativeInt(); + int timeunit = m_modp->timeunit().powerOfTen(); m_vpiScopeCandidates.insert( make_pair(name, ScopeData(scopeSymString(name), name_dedot, timeunit, type))); } @@ -305,7 +301,7 @@ class EmitCSyms : EmitCBaseVisitor { if (v3Global.opt.vpi() && !nodep->isTop()) { string name_dedot = AstNode::dedotName(nodep->shortName()); - int timeunit = m_modp->timeunit().negativeInt(); + int timeunit = m_modp->timeunit().powerOfTen(); m_vpiScopeCandidates.insert( make_pair(nodep->name(), ScopeData(scopeSymString(nodep->name()), name_dedot, timeunit, "SCOPE_MODULE"))); @@ -315,7 +311,7 @@ class EmitCSyms : EmitCBaseVisitor { string name = nodep->scopeSymName(); // UINFO(9,"scnameins sp "<name()<<" sp "<scopePrettySymName() // <<" ss"<timeunit().negativeInt() : 0; + int timeunit = m_modp ? m_modp->timeunit().powerOfTen() : 0; if (m_scopeNames.find(name) == m_scopeNames.end()) { m_scopeNames.insert(make_pair( name, ScopeData(name, nodep->scopePrettySymName(), timeunit, "SCOPE_OTHER"))); @@ -442,6 +438,8 @@ void EmitCSyms::emitSymHdr() { } if (v3Global.opt.trace()) { puts("bool __Vm_activity; ///< Used by trace routines to determine change occurred\n"); + puts("uint32_t __Vm_baseCode; " + "///< Used by trace routines when tracing multiple models\n"); } puts("bool __Vm_didInit;\n"); @@ -495,10 +493,6 @@ void EmitCSyms::emitSymHdr() { puts("\n// METHODS\n"); puts("inline const char* name() { return __Vm_namep; }\n"); - if (v3Global.opt.trace()) { - puts("inline bool getClearActivity() { bool r=__Vm_activity; " - "__Vm_activity=false; return r; }\n"); - } if (v3Global.opt.savable()) { puts("void " + protect("__Vserialize") + "(VerilatedSerialize& os);\n"); puts("void " + protect("__Vdeserialize") + "(VerilatedDeserialize& os);\n"); @@ -523,6 +517,9 @@ void EmitCSyms::checkSplit(bool usesVfinal) { return; } + // Splitting file, so using parallel build. + v3Global.useParallelBuild(true); + m_numStmts = 0; string filename = v3Global.opt.makeDir() + "/" + symClassName() + "__" + cvtToStr(++m_funcNum) + ".cpp"; @@ -627,7 +624,10 @@ void EmitCSyms::emitSymImp() { puts(" , __Vm_dumping(false)\n"); puts(" , __Vm_dumperp(NULL)\n"); } - if (v3Global.opt.trace()) puts(" , __Vm_activity(false)\n"); + if (v3Global.opt.trace()) { + puts(" , __Vm_activity(false)\n"); + puts(" , __Vm_baseCode(0)\n"); + } puts(" , __Vm_didInit(false)\n"); puts(" // Setup submodule names\n"); char comma = ','; diff --git a/src/V3EmitMk.cpp b/src/V3EmitMk.cpp index 19816a465..e148bb1a0 100644 --- a/src/V3EmitMk.cpp +++ b/src/V3EmitMk.cpp @@ -57,7 +57,7 @@ public: of.puts("\n"); of.puts("# Parallel builds? 0/1 (from --output-split)\n"); of.puts("VM_PARALLEL_BUILDS = "); - of.puts(v3Global.opt.outputSplit() ? "1" : "0"); + of.puts(v3Global.useParallelBuild() ? "1" : "0"); of.puts("\n"); of.puts("# Threaded output mode? 0/1/N threads (from --threads)\n"); of.puts("VM_THREADS = "); @@ -160,6 +160,13 @@ public: of.puts("# SystemC library directory with libsystemc.a (from $SYSTEMC_LIBDIR)\n"); of.puts(string("SYSTEMC_LIBDIR ?= ") + V3Options::getenvSYSTEMC_LIBDIR() + "\n"); + // Only check it if we really need the value + if (v3Global.opt.usingSystemCLibs() && !V3Options::systemCFound()) { + v3fatal("Need $SYSTEMC_INCLUDE in environment or when Verilator configured,\n" + "and need $SYSTEMC_LIBDIR in environment or when Verilator configured\n" + "Probably System-C isn't installed, see http://www.systemc.org\n"); + } + of.puts("\n### Switches...\n"); of.puts("# SystemC output mode? 0/1 (from --sc)\n"); of.puts(string("VM_SC = ") + ((v3Global.opt.systemC()) ? "1" : "0") + "\n"); @@ -234,7 +241,7 @@ public: of.puts("\n### Link rules... (from --exe)\n"); of.puts(v3Global.opt.exeName() + ": $(VK_USER_OBJS) $(VK_GLOBAL_OBJS) $(VM_PREFIX)__ALL.a\n"); - of.puts("\t$(LINK) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) $(SC_LIBS)\n"); + of.puts("\t$(LINK) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) $(LIBS) $(SC_LIBS) -o $@\n"); of.puts("\n"); } diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index 5b28dec41..19b6c7ec8 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -22,8 +22,6 @@ #include "V3EmitCBase.h" #include -#include -#include #include #include @@ -252,12 +250,16 @@ class EmitVBaseVisitor : public EmitCBaseVisitor { } virtual void visit(AstFOpen* nodep) VL_OVERRIDE { putfs(nodep, nodep->verilogKwd()); - putbs(" ("); - if (nodep->filep()) iterateAndNextNull(nodep->filep()); + putbs("("); + iterateAndNextNull(nodep->filenamep()); putbs(","); - if (nodep->filenamep()) iterateAndNextNull(nodep->filenamep()); - putbs(","); - if (nodep->modep()) iterateAndNextNull(nodep->modep()); + iterateAndNextNull(nodep->modep()); + puts(");\n"); + } + virtual void visit(AstFOpenMcd* nodep) VL_OVERRIDE { + putfs(nodep, nodep->verilogKwd()); + putbs("("); + iterateAndNextNull(nodep->filenamep()); puts(");\n"); } virtual void visit(AstFClose* nodep) VL_OVERRIDE { @@ -272,14 +274,17 @@ class EmitVBaseVisitor : public EmitCBaseVisitor { if (nodep->filep()) iterateAndNextNull(nodep->filep()); puts(");\n"); } - virtual void visit(AstJumpGo* nodep) VL_OVERRIDE { - putbs("disable " + cvtToHex(nodep->labelp()) + ";\n"); - } - virtual void visit(AstJumpLabel* nodep) VL_OVERRIDE { - putbs("begin : " + cvtToHex(nodep) + "\n"); + virtual void visit(AstJumpBlock* nodep) VL_OVERRIDE { + putbs("begin : label" + cvtToStr(nodep->labelNum()) + "\n"); if (nodep->stmtsp()) iterateAndNextNull(nodep->stmtsp()); puts("end\n"); } + virtual void visit(AstJumpGo* nodep) VL_OVERRIDE { + putbs("disable label" + cvtToStr(nodep->labelp()->blockp()->labelNum()) + ";\n"); + } + virtual void visit(AstJumpLabel* nodep) VL_OVERRIDE { + putbs("// " + cvtToStr(nodep->blockp()) + ":\n"); + } virtual void visit(AstNodeReadWriteMem* nodep) VL_OVERRIDE { putfs(nodep, nodep->verilogKwd()); putbs(" ("); @@ -408,13 +413,15 @@ class EmitVBaseVisitor : public EmitCBaseVisitor { // Operators virtual void emitVerilogFormat(AstNode* nodep, const string& format, AstNode* lhsp = NULL, - AstNode* rhsp = NULL, AstNode* thsp = NULL) { + AstNode* rhsp = NULL, AstNode* thsp = NULL, + AstNode* fhsp = NULL) { // Look at emitVerilog() format for term/uni/dual/triops, // and write out appropriate text. // %f Potential fileline-if-change and line break // %l lhsp - if appropriate // %r rhsp - if appropriate // %t thsp - if appropriate + // %o fhsp - if appropriate // %d dtypep - if appropriate // %k Potential line break bool inPct = false; @@ -447,6 +454,11 @@ class EmitVBaseVisitor : public EmitCBaseVisitor { iterateAndNextNull(thsp); break; } + case 'o': { + UASSERT_OBJ(thsp, nodep, "emitVerilog() references undef node"); + iterateAndNextNull(fhsp); + break; + } case 'd': { UASSERT_OBJ(nodep->dtypep(), nodep, "emitVerilog() references undef node"); iterateAndNextNull(nodep->dtypep()); @@ -789,27 +801,6 @@ public: //###################################################################### // EmitV class functions -void V3EmitV::emitv() { - UINFO(2, __FUNCTION__ << ": " << endl); - if (true) { - // All-in-one file - V3OutVFile of(v3Global.opt.makeDir() + "/" + v3Global.opt.prefix() + "__Vout.v"); - of.putsHeader(); - of.puts("# DESCR" - "IPTION: Verilator output: Verilog representation of internal tree for debug\n"); - EmitVFileVisitor visitor(v3Global.rootp(), &of); - } else { - // Process each module in turn - for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; - modp = VN_CAST(modp->nextp(), NodeModule)) { - V3OutVFile of(v3Global.opt.makeDir() + "/" + EmitCBaseVisitor::prefixNameProtect(modp) - + "__Vout.v"); - of.putsHeader(); - EmitVFileVisitor visitor(modp, &of); - } - } -} - void V3EmitV::verilogForTree(AstNode* nodep, std::ostream& os) { EmitVStreamVisitor(nodep, os); } void V3EmitV::verilogPrefixedTree(AstNode* nodep, std::ostream& os, const string& prefix, diff --git a/src/V3EmitV.h b/src/V3EmitV.h index 12dc38509..5ccf5c9b8 100644 --- a/src/V3EmitV.h +++ b/src/V3EmitV.h @@ -27,7 +27,6 @@ class V3EmitV { public: - static void emitv(); static void verilogForTree(AstNode* nodep, std::ostream& os = std::cout); static void verilogPrefixedTree(AstNode* nodep, std::ostream& os, const string& prefix, int flWidth, AstSenTree* domainp, bool user3mark); diff --git a/src/V3EmitXml.cpp b/src/V3EmitXml.cpp index a748aecdc..671410316 100644 --- a/src/V3EmitXml.cpp +++ b/src/V3EmitXml.cpp @@ -22,9 +22,6 @@ #include "V3EmitXml.h" #include "V3EmitCBase.h" -#include -#include -#include #include #include @@ -46,9 +43,6 @@ class EmitXmlFileVisitor : public AstNVisitor { // Outfile methods V3OutFile* ofp() const { return m_ofp; } virtual void puts(const string& str) { ofp()->puts(str); } - virtual void putbs(const string& str) { ofp()->putbs(str); } - virtual void putfs(AstNode*, const string& str) { putbs(str); } - virtual void putqs(AstNode*, const string& str) { putbs(str); } virtual void putsNoTracking(const string& str) { ofp()->putsNoTracking(str); } virtual void putsQuoted(const string& str) { // Quote \ and " for use inside C programs @@ -64,7 +58,8 @@ class EmitXmlFileVisitor : public AstNVisitor { if (!nodep->user1()) { nodep->user1(++m_id); } puts("\"" + cvtToStr(nodep->user1()) + "\""); } - void outputTag(AstNode* nodep, string tag) { + void outputTag(AstNode* nodep, const string& tagin) { + string tag = tagin; if (tag == "") tag = VString::downcase(nodep->typeName()); puts("<" + tag + " " + nodep->fileline()->xml()); puts(" " + nodep->fileline()->xmlDetailedLocation()); @@ -92,7 +87,8 @@ class EmitXmlFileVisitor : public AstNVisitor { } } } - void outputChildrenEnd(AstNode* nodep, string tag) { + void outputChildrenEnd(AstNode* nodep, const string& tagin) { + string tag = tagin; if (tag == "") tag = VString::downcase(nodep->typeName()); if (nodep->op1p() || nodep->op2p() || nodep->op3p() || nodep->op4p()) { puts(">\n"); diff --git a/src/V3Error.cpp b/src/V3Error.cpp index e483c0699..8c617d294 100644 --- a/src/V3Error.cpp +++ b/src/V3Error.cpp @@ -23,8 +23,6 @@ #endif // clang-format on -#include - //====================================================================== // Statics @@ -158,15 +156,20 @@ string V3Error::msgPrefix() { //====================================================================== // Abort/exit -void V3Error::vlAbort() { +void V3Error::vlAbortOrExit() { if (V3Error::debugDefault()) { std::cerr << msgPrefix() << "Aborting since under --debug" << endl; - abort(); + V3Error::vlAbort(); } else { exit(1); } } +void V3Error::vlAbort() { + VL_GCOV_FLUSH(); + abort(); +} + //====================================================================== // Global Functions @@ -274,7 +277,7 @@ void V3Error::v3errorEnd(std::ostringstream& sstr, const string& locationStr) { #endif } - vlAbort(); + vlAbortOrExit(); } else if (isError(s_errorCode, s_errorSuppressed)) { // We don't dump tree on any error because a Visitor may be in middle of // a tree cleanup and cause a false broken problem. diff --git a/src/V3Error.h b/src/V3Error.h index db32d6e04..f86d5888f 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -136,7 +136,7 @@ public: operator en() const { return m_e; } const char* ascii() const { // clang-format off - const char* names[] = { + static const char* const names[] = { // Leading spaces indicate it can't be disabled. " MIN", " INFO", " FATAL", " FATALEXIT", " FATALSRC", " ERROR", // Boolean @@ -238,7 +238,7 @@ private: V3Error() { std::cerr << ("Static class"); - abort(); + V3Error::vlAbort(); } public: @@ -253,7 +253,6 @@ public: static string msgPrefix(); // returns %Error/%Warn static int errorCount() { return s_errCount; } static int warnCount() { return s_warnCount; } - static int errorOrWarnCount() { return errorCount() + warnCount(); } static bool errorContexted() { return s_errorContexted; } static void errorContexted(bool flag) { s_errorContexted = flag; } // METHODS @@ -288,6 +287,7 @@ public: s_errorSuppressed = false; } static std::ostringstream& v3errorStr() { return s_errorStr; } + static void vlAbortOrExit(); static void vlAbort(); // static, but often overridden in classes. static void v3errorEnd(std::ostringstream& sstr, const string& locationStr = ""); @@ -298,7 +298,7 @@ inline int debug() { return V3Error::debugDefault(); } inline void v3errorEnd(std::ostringstream& sstr) { V3Error::v3errorEnd(sstr); } inline void v3errorEndFatal(std::ostringstream& sstr) { V3Error::v3errorEnd(sstr); - assert(0); + assert(0); // LCOV_EXCL_LINE VL_UNREACHABLE } @@ -307,11 +307,10 @@ inline void v3errorEndFatal(std::ostringstream& sstr) { // Note the commas are the comma operator, not separating arguments. These are needed to ensure // evaluation order as otherwise we couldn't ensure v3errorPrep is called first. #define v3warnCode(code, msg) \ - v3errorEnd( \ - (V3Error::v3errorPrep(code), (V3Error::v3errorStr() << msg), V3Error::v3errorStr())); + v3errorEnd((V3Error::v3errorPrep(code), (V3Error::v3errorStr() << msg), V3Error::v3errorStr())) #define v3warnCodeFatal(code, msg) \ v3errorEndFatal( \ - (V3Error::v3errorPrep(code), (V3Error::v3errorStr() << msg), V3Error::v3errorStr())); + (V3Error::v3errorPrep(code), (V3Error::v3errorStr() << msg), V3Error::v3errorStr())) #define v3warn(code, msg) v3warnCode(V3ErrorCode::code, msg) #define v3info(msg) v3warnCode(V3ErrorCode::EC_INFO, msg) #define v3error(msg) v3warnCode(V3ErrorCode::EC_ERROR, msg) @@ -324,28 +323,28 @@ inline void v3errorEndFatal(std::ostringstream& sstr) { __FILE__ << ":" << std::dec << __LINE__ << ": " << msg) // Use this when normal v3fatal is called in static method that overrides fileline. #define v3fatalStatic(msg) \ - ::v3errorEndFatal((V3Error::v3errorPrep(V3ErrorCode::EC_FATAL), \ - (V3Error::v3errorStr() << msg), V3Error::v3errorStr())); + (::v3errorEndFatal((V3Error::v3errorPrep(V3ErrorCode::EC_FATAL), \ + (V3Error::v3errorStr() << msg), V3Error::v3errorStr()))) #define UINFO(level, stmsg) \ - { \ + do { \ if (VL_UNCOVERABLE(debug() >= (level))) { \ cout << "- " << V3Error::lineStr(__FILE__, __LINE__) << stmsg; \ } \ - } + } while (false) #define UINFONL(level, stmsg) \ - { \ + do { \ if (VL_UNCOVERABLE(debug() >= (level))) { cout << stmsg; } \ - } + } while (false) #ifdef VL_DEBUG #define UDEBUGONLY(stmts) \ - { stmts } + do { stmts } while (false) #else #define UDEBUGONLY(stmts) \ - { \ + do { \ if (false) { stmts } \ - } + } while (false) #endif // Assertion without object, generally UOBJASSERT preferred @@ -364,7 +363,7 @@ inline void v3errorEndFatal(std::ostringstream& sstr) { if (VL_UNCOVERABLE(!(condition))) { \ std::cerr << "Internal Error: " << __FILE__ << ":" << std::dec << __LINE__ << ":" \ << (stmsg) << std::endl; \ - abort(); \ + V3Error::vlAbort(); \ } \ } while (false) // Check self test values for expected value. Safe from side-effects. diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index 6b33f497f..f3e47f857 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -33,7 +33,6 @@ #include "V3Ast.h" #include -#include //###################################################################### // Expand state, as a visitor of each AstNode @@ -152,21 +151,31 @@ private: return newp; } - AstNode* newSelBitWord(AstNode* lsbp, int wordAdder) { + AstNode* newWordSel(FileLine* fl, AstNode* fromp, AstNode* lsbp, int wordAdder) { // Return equation to get the VL_BITWORD of a constant or non-constant - if (VN_IS(lsbp, Const)) { - return new AstConst(lsbp->fileline(), - wordAdder + VL_BITWORD_E(VN_CAST(lsbp, Const)->toUInt())); + UASSERT_OBJ(fromp->isWide(), fromp, "Only need AstWordSel on wide from's"); + if (wordAdder >= fromp->widthWords()) { + // e.g. "logic [95:0] var[0]; logic [0] sel; out = var[sel];" + // Squash before C++ to avoid getting a C++ compiler warning + // (even though code would be unreachable as presumably a + // AstCondBound is protecting above this node. + return new AstConst(fl, AstConst::SizedEData(), 0); } else { - AstNode* shiftp - = new AstShiftR(lsbp->fileline(), lsbp->cloneTree(true), - new AstConst(lsbp->fileline(), VL_EDATASIZE_LOG2), VL_EDATASIZE); - if (wordAdder != 0) { - shiftp = new AstAdd(lsbp->fileline(), - // This is indexing a arraysel, so a 32 bit constant is fine - new AstConst(lsbp->fileline(), wordAdder), shiftp); + AstNode* wordp; + if (VN_IS(lsbp, Const)) { + wordp = new AstConst(lsbp->fileline(), + wordAdder + VL_BITWORD_E(VN_CAST(lsbp, Const)->toUInt())); + } else { + wordp = new AstShiftR(lsbp->fileline(), lsbp->cloneTree(true), + new AstConst(lsbp->fileline(), VL_EDATASIZE_LOG2), + VL_EDATASIZE); + if (wordAdder != 0) { + wordp = new AstAdd(lsbp->fileline(), + // This is indexing a arraysel, so a 32 bit constant is fine + new AstConst(lsbp->fileline(), wordAdder), wordp); + } } - return shiftp; + return new AstWordSel(fl, fromp, wordp); } } @@ -197,7 +206,8 @@ private: UINFO(8, " Wordize ASSIGN(CONST) " << nodep << endl); // -> {for each_word{ ASSIGN(WORDSEL(wide,#),WORDSEL(CONST,#))}} if (rhsp->num().isFourState()) { - rhsp->v3error("Unsupported: 4-state numbers in this context"); + rhsp->v3error( // LCOV_EXCL_LINE // impossible? + "Unsupported: 4-state numbers in this context"); } for (int w = 0; w < nodep->widthWords(); w++) { addWordAssign( @@ -307,17 +317,6 @@ private: VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } } - bool expandWide(AstNodeAssign* nodep, AstExtend* rhsp) { - UINFO(8, " Wordize ASSIGN(EXTEND) " << nodep << endl); - int w = 0; - for (w = 0; w < rhsp->lhsp()->widthWords(); w++) { - addWordAssign(nodep, w, newAstWordSelClone(rhsp->lhsp(), w)); - } - for (; w < nodep->widthWords(); w++) { - addWordAssign(nodep, w, new AstConst(rhsp->fileline(), AstConst::SizedEData(), 0)); - } - return true; - } virtual void visit(AstSel* nodep) VL_OVERRIDE { if (nodep->user1SetOnce()) return; // Process once @@ -334,9 +333,8 @@ private: // Selection amounts // Check for constant shifts & save some constification work later. // Grab lowest bit(s) - AstNode* lowwordp - = new AstWordSel(nodep->fromp()->fileline(), nodep->fromp()->cloneTree(true), - newSelBitWord(nodep->lsbp(), 0)); + AstNode* lowwordp = newWordSel(nodep->fromp()->fileline(), + nodep->fromp()->cloneTree(true), nodep->lsbp(), 0); if (nodep->isQuad() && !lowwordp->isQuad()) { lowwordp = new AstCCast(nodep->fileline(), lowwordp, nodep); } @@ -347,8 +345,8 @@ private: V3Number zero(nodep, longOrQuadWidth(nodep)); if (nodep->widthConst() > 1) { AstNode* midwordp = // SEL(from,[1+wordnum]) - new AstWordSel(nodep->fromp()->fileline(), nodep->fromp()->cloneTree(true), - newSelBitWord(nodep->lsbp(), 1)); + newWordSel(nodep->fromp()->fileline(), nodep->fromp()->cloneTree(true), + nodep->lsbp(), 1); if (nodep->isQuad() && !midwordp->isQuad()) { midwordp = new AstCCast(nodep->fileline(), midwordp, nodep); } @@ -383,8 +381,8 @@ private: AstNode* hip = NULL; if (nodep->widthConst() > VL_EDATASIZE) { AstNode* hiwordp = // SEL(from,[2+wordnum]) - new AstWordSel(nodep->fromp()->fileline(), nodep->fromp()->cloneTree(true), - newSelBitWord(nodep->lsbp(), 2)); + newWordSel(nodep->fromp()->fileline(), nodep->fromp()->cloneTree(true), + nodep->lsbp(), 2); if (nodep->isQuad() && !hiwordp->isQuad()) { hiwordp = new AstCCast(nodep->fileline(), hiwordp, nodep); } @@ -439,16 +437,15 @@ private: UINFO(8, " Wordize ASSIGN(EXTRACT,misalign) " << nodep << endl); for (int w = 0; w < nodep->widthWords(); w++) { // Grab lowest bits - AstNode* lowwordp - = new AstWordSel(rhsp->fileline(), rhsp->fromp()->cloneTree(true), - newSelBitWord(rhsp->lsbp(), w)); + AstNode* lowwordp = newWordSel(rhsp->fileline(), rhsp->fromp()->cloneTree(true), + rhsp->lsbp(), w); AstNode* lowp = new AstShiftR(rhsp->fileline(), lowwordp, newSelBitBit(rhsp->lsbp()), VL_EDATASIZE); // Upper bits V3Number zero(nodep, VL_EDATASIZE, 0); AstNode* midwordp = // SEL(from,[1+wordnum]) - new AstWordSel(rhsp->fromp()->fileline(), rhsp->fromp()->cloneTree(true), - newSelBitWord(rhsp->lsbp(), w + 1)); + newWordSel(rhsp->fromp()->fileline(), rhsp->fromp()->cloneTree(true), + rhsp->lsbp(), w + 1); AstNode* midshiftp = new AstSub( rhsp->lsbp()->fileline(), new AstConst(rhsp->lsbp()->fileline(), VL_EDATASIZE), newSelBitBit(rhsp->lsbp())); @@ -531,8 +528,8 @@ private: UINFO(8, " ASSIGNSEL(varlsb,wide,1bit) " << nodep << endl); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNode* destp = lhsp->fromp()->unlinkFrBack(); - AstNode* oldvalp = new AstWordSel(lhsp->fileline(), destp->cloneTree(true), - newSelBitWord(lhsp->lsbp(), 0)); + AstNode* oldvalp + = newWordSel(lhsp->fileline(), destp->cloneTree(true), lhsp->lsbp(), 0); fixCloneLvalue(oldvalp); if (!ones) { oldvalp = new AstAnd( @@ -552,10 +549,8 @@ private: AstNode* newp = new AstOr(lhsp->fileline(), oldvalp, new AstShiftL(lhsp->fileline(), rhsp, shiftp, VL_EDATASIZE)); - newp = new AstAssign( - nodep->fileline(), - new AstWordSel(nodep->fileline(), destp, newSelBitWord(lhsp->lsbp(), 0)), - newp); + newp = new AstAssign(nodep->fileline(), + newWordSel(nodep->fileline(), destp, lhsp->lsbp(), 0), newp); insertBefore(nodep, newp); return true; } else if (destwide) { diff --git a/src/V3File.cpp b/src/V3File.cpp index a01457afd..e2437ccb9 100644 --- a/src/V3File.cpp +++ b/src/V3File.cpp @@ -20,7 +20,6 @@ #include "V3Global.h" #include "V3File.h" #include "V3Os.h" -#include "V3PreShell.h" #include "V3String.h" #include "V3Ast.h" @@ -645,7 +644,7 @@ V3OutFormatter::V3OutFormatter(const string& filename, V3OutFormatter::Language //---------------------------------------------------------------------- -const string V3OutFormatter::indentSpaces(int num) { +string V3OutFormatter::indentSpaces(int num) { // Indent the specified number of spaces. Use spaces. static char str[MAXSPACE + 20]; char* cp = str; diff --git a/src/V3File.h b/src/V3File.h index dcbb7672e..e98496bc9 100644 --- a/src/V3File.h +++ b/src/V3File.h @@ -165,7 +165,7 @@ public: if (!m_parenVec.empty()) m_parenVec.pop(); } // STATIC METHODS - static const string indentSpaces(int num); + static string indentSpaces(int num); // Add escaped characters to strings static string quoteNameControls(const string& namein, Language lang = LA_C); diff --git a/src/V3FileLine.cpp b/src/V3FileLine.cpp index 2fce3e34b..23b07c4cd 100644 --- a/src/V3FileLine.cpp +++ b/src/V3FileLine.cpp @@ -22,23 +22,21 @@ #include "V3FileLine.h" #include "V3String.h" #ifndef _V3ERROR_NO_GLOBAL_ -# include "V3Ast.h" # include "V3Global.h" -# include "V3Stats.h" # include "V3Config.h" # include "V3File.h" #endif +#include "V3Waiver.h" // clang-format on #include -#include #include #include VL_INCLUDE_UNORDERED_SET //###################################################################### // FileLineSingleton class functions -const string FileLineSingleton::filenameLetters(int fileno) { +string FileLineSingleton::filenameLetters(int fileno) { const int size = 1 + (64 / 4); // Each letter retires more than 4 bits of a > 64 bit number char out[size]; char* op = out + size - 1; @@ -167,7 +165,7 @@ void FileLine::newContent() { m_contentLineno = 1; } -const string FileLine::xmlDetailedLocation() const { +string FileLine::xmlDetailedLocation() const { return "loc=\"" + cvtToStr(filenameLetters()) + "," + cvtToStr(firstLineno()) + "," + cvtToStr(firstColumn()) + "," + cvtToStr(lastLineno()) + "," + cvtToStr(lastColumn()) + "\""; @@ -261,21 +259,27 @@ FileLine* FileLine::copyOrSameFileLine() { return newp; } -const string FileLine::filebasename() const { +string FileLine::filebasename() const { string name = filename(); string::size_type pos; if ((pos = name.rfind('/')) != string::npos) name.erase(0, pos + 1); return name; } -const string FileLine::filebasenameNoExt() const { +string FileLine::filebasenameNoExt() const { string name = filebasename(); string::size_type pos; if ((pos = name.find('.')) != string::npos) name = name.substr(0, pos); return name; } -const string FileLine::profileFuncname() const { +string FileLine::firstColumnLetters() const { + char a = ((firstColumn() / 26) % 26) + 'a'; + char b = (firstColumn() % 26) + 'a'; + return string(1, a) + string(1, b); +} + +string FileLine::profileFuncname() const { // Return string that is OK as a function name - for profiling string name = filebasenameNoExt(); string::size_type pos; @@ -360,12 +364,13 @@ void FileLine::v3errorEnd(std::ostringstream& sstr, const string& locationStr) { lstr << std::setw(ascii().length()) << " " << ": " << locationStr; } - if (warnIsOff(V3Error::errorCode()) - || V3Config::waive(this, V3Error::errorCode(), sstr.str())) { + m_waive = V3Config::waive(this, V3Error::errorCode(), sstr.str()); + if (warnIsOff(V3Error::errorCode()) || m_waive) { V3Error::suppressThisWarning(); } else if (!V3Error::errorContexted()) { nsstr << warnContextPrimary(); } + if (!m_waive) { V3Waiver::addEntry(V3Error::errorCode(), filename(), sstr.str()); } V3Error::v3errorEnd(nsstr, lstr.str()); } @@ -385,14 +390,14 @@ string FileLine::warnOther() const { } string FileLine::source() const { - if (VL_UNCOVERABLE(!m_contentp)) { + if (VL_UNCOVERABLE(!m_contentp)) { // LCOV_EXCL_START if (debug() || v3Global.opt.debugCheck()) { // The newline here is to work around the " | " return "\n%Error: internal tracking of file contents failed"; } else { return ""; } - } + } // LCOV_EXCL_STOP return m_contentp->getLine(m_contentLineno); } string FileLine::prettySource() const { diff --git a/src/V3FileLine.h b/src/V3FileLine.h index d5d1833cd..579e3cb75 100644 --- a/src/V3FileLine.h +++ b/src/V3FileLine.h @@ -14,8 +14,8 @@ // //************************************************************************* -#ifndef _V3FileLine_H_ -#define _V3FileLine_H_ 1 +#ifndef _V3FILELINE_H_ +#define _V3FILELINE_H_ 1 #include "config_build.h" #include "verilatedos.h" @@ -40,7 +40,6 @@ class FileLine; class FileLineSingleton { // TYPES typedef std::map FileNameNumMap; - typedef std::map FileLangNumMap; // MEMBERS FileNameNumMap m_namemap; // filenameno for each filename std::deque m_names; // filename text for each filenameno @@ -52,8 +51,8 @@ class FileLineSingleton { protected: friend class FileLine; int nameToNumber(const string& filename); - const string numberToName(int filenameno) const { return m_names[filenameno]; } - const V3LangCode numberToLang(int filenameno) const { return m_languages[filenameno]; } + string numberToName(int filenameno) const { return m_names[filenameno]; } + V3LangCode numberToLang(int filenameno) const { return m_languages[filenameno]; } void numberToLang(int filenameno, const V3LangCode& l) { m_languages[filenameno] = l; } void clear() { m_namemap.clear(); @@ -61,7 +60,7 @@ protected: m_languages.clear(); } void fileNameNumMapDumpXml(std::ostream& os); - static const string filenameLetters(int fileno); + static string filenameLetters(int fileno); }; //! All source lines from a file/stream, to enable errors to show sources @@ -103,6 +102,7 @@ class FileLine { VFileContent* m_contentp; // Source text contents line is within FileLine* m_parent; // Parent line that included this line std::bitset m_warnOn; + bool m_waive; // Waive warning protected: // User routines should never need to change line numbers @@ -134,7 +134,8 @@ public: , m_contentLineno(0) , m_contentp(NULL) , m_parent(NULL) - , m_warnOn(defaultFileLine().m_warnOn) {} + , m_warnOn(defaultFileLine().m_warnOn) + , m_waive(false) {} explicit FileLine(FileLine* fromp) : m_firstLineno(fromp->m_firstLineno) , m_firstColumn(fromp->m_firstColumn) @@ -144,7 +145,8 @@ public: , m_contentLineno(fromp->m_contentLineno) , m_contentp(fromp->m_contentp) , m_parent(fromp->m_parent) - , m_warnOn(fromp->m_warnOn) {} + , m_warnOn(fromp->m_warnOn) + , m_waive(fromp->m_waive) {} struct EmptySecret {}; // Constructor selection explicit FileLine(EmptySecret); FileLine* copyOrSameFileLine(); @@ -161,7 +163,7 @@ public: m_lastLineno = num; m_firstColumn = m_lastColumn = 1; } - void language(V3LangCode lang) { singleton().numberToLang(m_filenameno, lang); } + void language(V3LangCode lang) { singleton().numberToLang(filenameno(), lang); } void filename(const string& name) { m_filenameno = singleton().nameToNumber(name); } void parent(FileLine* fileline) { m_parent = fileline; } void lineDirective(const char* textp, int& enterExitRef); @@ -187,21 +189,21 @@ public: string source() const; string prettySource() const; // Source, w/stripped unprintables and newlines FileLine* parent() const { return m_parent; } - V3LangCode language() const { return singleton().numberToLang(m_filenameno); } + V3LangCode language() const { return singleton().numberToLang(filenameno()); } string ascii() const; string asciiLineCol() const; - const string filename() const { return singleton().numberToName(m_filenameno); } + int filenameno() const { return m_filenameno; } + string filename() const { return singleton().numberToName(filenameno()); } bool filenameIsGlobal() const { return (filename() == commandLineFilename() || filename() == builtInFilename()); } - const string filenameLetters() const { return singleton().filenameLetters(m_filenameno); } - const string filebasename() const; - const string filebasenameNoExt() const; - const string profileFuncname() const; - const string xml() const { - return "fl=\"" + filenameLetters() + cvtToStr(lastLineno()) + "\""; - } - const string xmlDetailedLocation() const; + string filenameLetters() const { return FileLineSingleton::filenameLetters(filenameno()); } + string filebasename() const; + string filebasenameNoExt() const; + string firstColumnLetters() const; + string profileFuncname() const; + string xml() const { return "fl=\"" + filenameLetters() + cvtToStr(lastLineno()) + "\""; } + string xmlDetailedLocation() const; string lineDirectiveStrg(int enterExit) const; // Turn on/off warning messages on this line. @@ -213,6 +215,7 @@ public: void warnStyleOff(bool flag); void warnStateFrom(const FileLine& from) { m_warnOn = from.m_warnOn; } void warnResetDefault() { warnStateFrom(defaultFileLine()); } + bool lastWarnWaived() { return m_waive; } // Specific flag ACCESSORS/METHODS bool coverageOn() const { return m_warnOn.test(V3ErrorCode::I_COVERAGE); } @@ -264,14 +267,13 @@ public: } private: - void v3errorEndFatalGuts(std::ostringstream& str); string warnContext(bool secondary) const; }; std::ostream& operator<<(std::ostream& os, FileLine* fileline); inline void FileLine::v3errorEndFatal(std::ostringstream& str) { v3errorEnd(str); - assert(0); + assert(0); // LCOV_EXCL_LINE VL_UNREACHABLE } diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index 2c843c0c9..cf3676f2b 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -33,11 +33,8 @@ #include "V3Hashed.h" #include -#include -#include #include #include -#include #include VL_INCLUDE_UNORDERED_SET typedef std::list GateVarRefList; @@ -516,8 +513,8 @@ private: virtual void visit(AstCoverToggle* nodep) VL_OVERRIDE { iterateNewStmt(nodep, "CoverToggle", "CoverToggle"); } - virtual void visit(AstTraceInc* nodep) VL_OVERRIDE { - bool lastslow = m_inSlow; + virtual void visit(AstTraceDecl* nodep) VL_OVERRIDE { + const bool lastslow = m_inSlow; m_inSlow = true; iterateNewStmt(nodep, "Tracing", "Tracing"); m_inSlow = lastslow; @@ -1181,7 +1178,7 @@ private: GateLogicVertex* consumeVertexp = dynamic_cast(outedgep->top()); AstNode* consumerp = consumeVertexp->nodep(); - m_graphp->dumpDotFilePrefixed("gate_preelim"); + // if (debug() >= 9) m_graphp->dumpDotFilePrefixed("gate_preelim"); UINFO(9, "elim src vtx" << lvertexp << " node " << lvertexp->nodep() << endl); UINFO(9, @@ -1549,7 +1546,7 @@ private: UINFO(9, " to - " << m_clk_vsp << endl); AstNode* rhsp = assignp->rhsp(); rhsp->replaceWith(new AstVarRef(rhsp->fileline(), m_clk_vsp, false)); - for (V3GraphEdge* edgep = lvertexp->inBeginp(); edgep;) { + while (V3GraphEdge* edgep = lvertexp->inBeginp()) { VL_DO_DANGLING(edgep->unlinkDelete(), edgep); } new V3GraphEdge(m_graphp, m_clk_vvertexp, lvertexp, 1); diff --git a/src/V3GenClk.cpp b/src/V3GenClk.cpp index 5cef03170..135d1394a 100644 --- a/src/V3GenClk.cpp +++ b/src/V3GenClk.cpp @@ -26,8 +26,6 @@ #include "V3GenClk.h" #include "V3Ast.h" -#include - //###################################################################### // GenClk state, as a visitor of each AstNode diff --git a/src/V3Global.cpp b/src/V3Global.cpp index 54d20cb5d..1e1f0a784 100644 --- a/src/V3Global.cpp +++ b/src/V3Global.cpp @@ -36,10 +36,6 @@ AstNetlist* V3Global::makeNetlist() { void V3Global::checkTree() { rootp()->checkTree(); } -void V3Global::clear() { - if (m_rootp) VL_DO_CLEAR(m_rootp->deleteTree(), m_rootp = NULL); -} - void V3Global::readFiles() { // NODE STATE // AstNode::user4p() // VSymEnt* Package and typedef symbol names @@ -80,3 +76,20 @@ void V3Global::dumpCheckGlobalTree(const string& stagename, int newNumber, bool doDump); if (v3Global.opt.stats()) V3Stats::statsStage(stagename); } + +const std::string& V3Global::ptrToId(const void* p) { + PtrToIdMap::iterator it = m_ptrToId.find(p); + if (it == m_ptrToId.end()) { + std::ostringstream os; + if (p) { + os << "("; + unsigned id = m_ptrToId.size(); + do { os << static_cast('A' + id % 26); } while (id /= 26); + os << ")"; + } else { + os << "0"; + } + it = m_ptrToId.insert(std::make_pair(p, os.str())).first; + } + return it->second; +} diff --git a/src/V3Global.h b/src/V3Global.h index 07bc52e7b..659b47737 100644 --- a/src/V3Global.h +++ b/src/V3Global.h @@ -31,6 +31,7 @@ #include "V3Options.h" #include +#include VL_INCLUDE_UNORDERED_MAP class AstNetlist; @@ -74,16 +75,19 @@ class V3Global { bool m_assertDTypesResolved; // Tree should have dtypep()'s bool m_constRemoveXs; // Const needs to strip any Xs bool m_needC11; // Need C++11 - bool m_needHInlines; // Need __Inlines file bool m_needHeavy; // Need verilated_heavy.h include bool m_needTraceDumper; // Need __Vm_dumperp in symbols bool m_dpi; // Need __Dpi include files + bool m_useParallelBuild; // Use parallel build for model + + // Memory address to short string mapping (for debug) + typedef vl_unordered_map PtrToIdMap; // The map type + PtrToIdMap m_ptrToId; // The actual 'address' <=> 'short string' bijection public: // Options V3Options opt; // All options; let user see them directly -public: // CONSTRUCTORS V3Global() : m_rootp(NULL) // created by makeInitNetlist() so static constructors run first @@ -92,16 +96,15 @@ public: , m_assertDTypesResolved(false) , m_constRemoveXs(false) , m_needC11(false) - , m_needHInlines(false) , m_needHeavy(false) , m_needTraceDumper(false) - , m_dpi(false) {} + , m_dpi(false) + , m_useParallelBuild(false) {} AstNetlist* makeNetlist(); void boot() { UASSERT(!m_rootp, "call once"); m_rootp = makeNetlist(); } - void clear(); // ACCESSORS (general) AstNetlist* rootp() const { return m_rootp; } VWidthMinUsage widthMinUsage() const { return m_widthMinUsage; } @@ -125,14 +128,15 @@ public: } bool needC11() const { return m_needC11; } void needC11(bool flag) { m_needC11 = flag; } - bool needHInlines() const { return m_needHInlines; } - void needHInlines(bool flag) { m_needHInlines = flag; } bool needHeavy() const { return m_needHeavy; } void needHeavy(bool flag) { m_needHeavy = flag; } bool needTraceDumper() const { return m_needTraceDumper; } void needTraceDumper(bool flag) { m_needTraceDumper = flag; } bool dpi() const { return m_dpi; } void dpi(bool flag) { m_dpi = flag; } + void useParallelBuild(bool flag) { m_useParallelBuild = flag; } + bool useParallelBuild() const { return m_useParallelBuild; } + const std::string& ptrToId(const void* p); }; extern V3Global v3Global; diff --git a/src/V3Graph.cpp b/src/V3Graph.cpp index fc2cc08f5..0b91d6ac4 100644 --- a/src/V3Graph.cpp +++ b/src/V3Graph.cpp @@ -21,7 +21,6 @@ #include "V3File.h" #include "V3Graph.h" -#include #include #include #include @@ -142,7 +141,7 @@ void V3GraphVertex::v3errorEnd(std::ostringstream& str) const { } void V3GraphVertex::v3errorEndFatal(std::ostringstream& str) const { v3errorEnd(str); - assert(0); + assert(0); // LCOV_EXCL_LINE VL_UNREACHABLE } diff --git a/src/V3GraphAcyc.cpp b/src/V3GraphAcyc.cpp index 7e57b078e..da07309ca 100644 --- a/src/V3GraphAcyc.cpp +++ b/src/V3GraphAcyc.cpp @@ -21,7 +21,6 @@ #include "V3Graph.h" #include -#include #include #include @@ -80,9 +79,9 @@ public: struct GraphAcycEdgeCmp { inline bool operator()(const V3GraphEdge* lhsp, const V3GraphEdge* rhsp) const { - if (lhsp->weight() > rhsp->weight()) return 1; // LHS goes first - if (lhsp->weight() < rhsp->weight()) return 0; // RHS goes first - return 0; + if (lhsp->weight() > rhsp->weight()) return true; // LHS goes first + if (lhsp->weight() < rhsp->weight()) return false; // RHS goes first + return false; } }; diff --git a/src/V3GraphAlg.cpp b/src/V3GraphAlg.cpp index 95db5be4f..d82babee4 100644 --- a/src/V3GraphAlg.cpp +++ b/src/V3GraphAlg.cpp @@ -21,7 +21,6 @@ #include "V3GraphAlg.h" #include "V3GraphPathChecker.h" -#include #include #include #include diff --git a/src/V3GraphDfa.cpp b/src/V3GraphDfa.cpp index 69160fbfd..084f628e9 100644 --- a/src/V3GraphDfa.cpp +++ b/src/V3GraphDfa.cpp @@ -21,7 +21,6 @@ #include "V3GraphDfa.h" #include "V3GraphAlg.h" -#include #include #include #include @@ -194,7 +193,7 @@ private: return NULL; // No match } - void findNfasWithInput(DfaVertex* dfaStatep, DfaInput input, DfaStates& nfasWithInput) { + void findNfasWithInput(DfaVertex* dfaStatep, const DfaInput& input, DfaStates& nfasWithInput) { // Return all NFA states, with the given input transition from // the nfa states a given dfa state was constructed from. nextStep(); diff --git a/src/V3GraphTest.cpp b/src/V3GraphTest.cpp index 232cb01b0..19f489f0c 100644 --- a/src/V3GraphTest.cpp +++ b/src/V3GraphTest.cpp @@ -21,8 +21,6 @@ #include "V3Graph.h" #include "V3GraphDfa.h" -#include - //###################################################################### //###################################################################### // Test class diff --git a/src/V3Hashed.cpp b/src/V3Hashed.cpp index ee7208147..8a3589234 100644 --- a/src/V3Hashed.cpp +++ b/src/V3Hashed.cpp @@ -30,7 +30,6 @@ #include "V3File.h" #include -#include #include #include #include @@ -159,7 +158,7 @@ void V3Hashed::dumpFile(const string& filename, bool tree) { V3Hash lasthash; int num_in_bucket = 0; - for (HashMmap::iterator it = begin(); 1; ++it) { + for (HashMmap::iterator it = begin(); true; ++it) { if (it == end() || lasthash != it->first) { if (it != end()) lasthash = it->first; if (num_in_bucket) { diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index 49c795669..301590f3b 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -35,7 +35,6 @@ #include "V3String.h" #include -#include #include #include VL_INCLUDE_UNORDERED_SET diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index fab5f9eac..17343944d 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -27,11 +27,9 @@ #include "V3Global.h" #include "V3Inst.h" #include "V3Ast.h" -#include "V3Changed.h" #include "V3Const.h" #include -#include //###################################################################### // Inst state, as a visitor of each AstNode @@ -205,8 +203,6 @@ private: int m_instSelNum; // Current instantiation count 0..N-1 InstDeModVarVisitor m_deModVars; // State of variables for current cell module - typedef std::map VarNameMap; - VL_DEBUG_FUNC; // Declare debug() // VISITORS @@ -423,7 +419,7 @@ private: } } if (!varNewp) { - if (debug() >= 9) m_deModVars.dump(); + if (debug() >= 9) m_deModVars.dump(); // LCOV_EXCL_LINE nodep->v3fatalSrc("Module dearray failed for " << AstNode::prettyNameQ(varNewName)); } diff --git a/src/V3InstrCount.cpp b/src/V3InstrCount.cpp index e0a24b201..972c791fd 100644 --- a/src/V3InstrCount.cpp +++ b/src/V3InstrCount.cpp @@ -139,10 +139,10 @@ private: iterateAndNextNull(nodep->lsbp()); iterateAndNextNull(nodep->widthp()); } - virtual void visit(AstSliceSel* nodep) VL_OVERRIDE { + virtual void visit(AstSliceSel* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE nodep->v3fatalSrc("AstSliceSel unhandled"); } - virtual void visit(AstMemberSel* nodep) VL_OVERRIDE { + virtual void visit(AstMemberSel* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE nodep->v3fatalSrc("AstMemberSel unhandled"); } virtual void visit(AstConcat* nodep) VL_OVERRIDE { diff --git a/src/V3Life.cpp b/src/V3Life.cpp index f8788bafe..1462ee4c4 100644 --- a/src/V3Life.cpp +++ b/src/V3Life.cpp @@ -32,7 +32,6 @@ #include "V3Ast.h" #include "V3Const.h" -#include #include #include @@ -390,7 +389,7 @@ private: VL_DO_DANGLING(delete condLifep, condLifep); VL_DO_DANGLING(delete bodyLifep, bodyLifep); } - virtual void visit(AstJumpLabel* nodep) VL_OVERRIDE { + virtual void visit(AstJumpBlock* nodep) VL_OVERRIDE { // As with While's we can't predict if a JumpGo will kill us or not // It's worse though as an IF(..., JUMPGO) may change the control flow. // Just don't optimize blocks with labels; they're rare - so far. @@ -476,15 +475,7 @@ private: LifeVisitor visitor(nodep, m_statep); } } - virtual void visit(AstAlways* nodep) VL_OVERRIDE { - // Usage model 2: Cleanup basic blocks - LifeVisitor visitor(nodep, m_statep); - } - virtual void visit(AstInitial* nodep) VL_OVERRIDE { - // Usage model 2: Cleanup basic blocks - LifeVisitor visitor(nodep, m_statep); - } - virtual void visit(AstFinal* nodep) VL_OVERRIDE { + virtual void visit(AstNodeProcedure* nodep) VL_OVERRIDE { // Usage model 2: Cleanup basic blocks LifeVisitor visitor(nodep, m_statep); } diff --git a/src/V3LifePost.cpp b/src/V3LifePost.cpp index da75454bb..80c72f749 100644 --- a/src/V3LifePost.cpp +++ b/src/V3LifePost.cpp @@ -34,7 +34,6 @@ #include "V3Stats.h" #include "V3Ast.h" -#include #include // for vl_unique_ptr -> auto_ptr or unique_ptr #include VL_INCLUDE_UNORDERED_MAP diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 17fe78662..e55660d70 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -34,7 +34,6 @@ #include "V3Graph.h" #include -#include #include #include #include VL_INCLUDE_UNORDERED_SET diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 9b080c9c4..df2da2803 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -71,7 +71,6 @@ #include "V3String.h" #include -#include #include #include @@ -712,13 +711,13 @@ class LinkDotFindVisitor : public AstNVisitor { // METHODS int debug() { return LinkDotState::debug(); } - virtual AstConst* parseParamLiteral(FileLine* fl, const string& literal) { + AstConst* parseParamLiteral(FileLine* fl, const string& literal) const { bool success = false; if (literal[0] == '"') { // This is a string string v = literal.substr(1, literal.find('"', 1) - 1); return new AstConst(fl, AstConst::VerilogStringLiteral(), v); - } else if ((literal.find('.') != string::npos) || (literal.find('e') != string::npos)) { + } else if (literal.find_first_of(".eEpP") != string::npos) { // This may be a real double v = V3ParseImp::parseDouble(literal.c_str(), literal.length(), &success); if (success) return new AstConst(fl, AstConst::RealDouble(), v); @@ -2369,6 +2368,13 @@ private: } } } + virtual void visit(AstEnumDType* nodep) VL_OVERRIDE { + iterateChildren(nodep); + AstRefDType* refdtypep = VN_CAST(nodep->subDTypep(), RefDType); + if (refdtypep && (nodep == refdtypep->subDTypep())) { + refdtypep->v3error("Self-referential enumerated type definition"); + } + } virtual void visit(AstEnumItemRef* nodep) VL_OVERRIDE { // EnumItemRef may be under a dot. Should already be resolved. iterateChildren(nodep); @@ -2485,11 +2491,39 @@ private: } else if (VN_IS(nodep, New) && m_statep->forPrearray()) { // Resolved in V3Width } else if (nodep->dotted() == "") { - string suggest = m_statep->suggestSymFallback(dotSymp, nodep->name(), - LinkNodeMatcherFTask()); - nodep->v3error("Can't find definition of task/function: " - << nodep->prettyNameQ() << endl - << (suggest.empty() ? "" : nodep->warnMore() + suggest)); + if (nodep->pli()) { + if (v3Global.opt.bboxSys()) { + AstNode* newp; + if (VN_IS(nodep, FuncRef)) { + newp = new AstConst(nodep->fileline(), AstConst::StringToParse(), + "'0"); + } else { + AstNode* outp = NULL; + while (nodep->pinsp()) { + AstNode* pinp = nodep->pinsp()->unlinkFrBack(); + AstNode* addp = pinp; + if (AstArg* argp = VN_CAST(pinp, Arg)) { + addp = argp->exprp()->unlinkFrBack(); + VL_DO_DANGLING(pinp->deleteTree(), pinp); + } + outp = AstNode::addNext(outp, addp); + } + newp = new AstSysIgnore(nodep->fileline(), outp); + } + nodep->replaceWith(newp); + VL_DO_DANGLING(nodep->deleteTree(), nodep); + return; + } else { + nodep->v3error("Unsupported or unknown PLI call: " + << nodep->prettyNameQ() << endl); + } + } else { + string suggest = m_statep->suggestSymFallback(dotSymp, nodep->name(), + LinkNodeMatcherFTask()); + nodep->v3error("Can't find definition of task/function: " + << nodep->prettyNameQ() << endl + << (suggest.empty() ? "" : nodep->warnMore() + suggest)); + } } else { string suggest = m_statep->suggestSymFallback(dotSymp, nodep->name(), LinkNodeMatcherFTask()); @@ -2639,7 +2673,7 @@ private: checkNoDot(nodep); } if (nodep->typeofp()) { // Really is a typeof not a reference - } else if (!nodep->defp()) { + } else if (!nodep->typedefp() && !nodep->subDTypep()) { VSymEnt* foundp; if (nodep->packagep()) { foundp = m_statep->getNodeSym(nodep->packagep())->findIdFlat(nodep->name()); @@ -2647,7 +2681,7 @@ private: foundp = m_curSymp->findIdFallback(nodep->name()); } if (AstTypedef* defp = foundp ? VN_CAST(foundp->nodep(), Typedef) : NULL) { - nodep->refDTypep(defp->subDTypep()); + nodep->typedefp(defp); nodep->packagep(foundp->packagep()); } else if (AstParamTypeDType* defp = foundp ? VN_CAST(foundp->nodep(), ParamTypeDType) : NULL) { diff --git a/src/V3LinkInc.cpp b/src/V3LinkInc.cpp new file mode 100644 index 000000000..73fbe604c --- /dev/null +++ b/src/V3LinkInc.cpp @@ -0,0 +1,254 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: Replace increments/decrements with new variables +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// Copyright 2003-2020 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 +// +//************************************************************************* +// V3LinkInc's Transformations: +// +// prepost_stmt_visit +// PREADD/PRESUB +// Create a temporary __VIncrementX variable, assign the value of +// the current variable value to it, substitute the current +// variable with the temporary one in the statement. +// Increment/decrement the original variable with by the given +// value. +// POSTADD/POSTSUB +// Increment/decrement the current variable by the given value. +// Create a temporary __VIncrementX variable, assign the value of +// of the current variable (after the operation) to it. Substitute +// The original variable with the temporary one in the statement. +// prepost_non_stmt_visit +// PREADD/PRESUB/POSTADD/POSTSUB +// Increment/decrement the current variable by the given value. +// The order (pre/post) doesn't matter outside statements thus +// the pre/post operations are treated equally and there is no +// need for a temporary variable. +// +//************************************************************************* + +#include "config_build.h" +#include "verilatedos.h" + +#include "V3Global.h" +#include "V3LinkInc.h" +#include "V3Ast.h" + +#include + +//###################################################################### + +class LinkIncVisitor : public AstNVisitor { +private: + // TYPES + enum InsertMode { + IM_BEFORE, // Pointing at statement ref is in, insert before this + IM_AFTER, // Pointing at last inserted stmt, insert after + IM_WHILE_PRECOND // Pointing to for loop, add to body end + }; + + // STATE + int m_modIncrementsNum; // Var name counter + InsertMode m_insMode; // How to insert + AstNode* m_insStmtp; // Where to insert statement + bool m_unsupportedHere; // Used to detect where it's not supported yet + +private: + void insertBeforeStmt(AstNode* nodep, AstNode* newp) { + // Return node that must be visited, if any + // See also AstNode::addBeforeStmt; this predates that function + if (debug() >= 9) newp->dumpTree(cout, "-newstmt:"); + UASSERT_OBJ(m_insStmtp, nodep, "Function not underneath a statement"); + if (m_insMode == IM_BEFORE) { + // Add the whole thing before insertAt + if (debug() >= 9) newp->dumpTree(cout, "-newfunc:"); + m_insStmtp->addHereThisAsNext(newp); + } else if (m_insMode == IM_AFTER) { + m_insStmtp->addNextHere(newp); + } else if (m_insMode == IM_WHILE_PRECOND) { + AstWhile* whilep = VN_CAST(m_insStmtp, While); + UASSERT_OBJ(whilep, nodep, "Insert should be under WHILE"); + whilep->addPrecondsp(newp); + } else { + nodep->v3fatalSrc("Unknown InsertMode"); + } + m_insMode = IM_AFTER; + m_insStmtp = newp; + } + + // VISITORS + virtual void visit(AstNodeModule* nodep) VL_OVERRIDE { + // Reset increments count + m_modIncrementsNum = 0; + iterateChildren(nodep); + } + virtual void visit(AstWhile* nodep) VL_OVERRIDE { + // Special, as statements need to be put in different places + // Preconditions insert first just before themselves (the normal + // rule for other statement types) + m_insStmtp = NULL; // First thing should be new statement + iterateAndNextNull(nodep->precondsp()); + // Conditions insert first at end of precondsp. + m_insMode = IM_WHILE_PRECOND; + m_insStmtp = nodep; + iterateAndNextNull(nodep->condp()); + // Body insert just before themselves + m_insStmtp = NULL; // First thing should be new statement + iterateAndNextNull(nodep->bodysp()); + iterateAndNextNull(nodep->incsp()); + // Done the loop + m_insStmtp = NULL; // Next thing should be new statement + } + virtual void visit(AstNodeIf* nodep) VL_OVERRIDE { + m_insStmtp = nodep; + iterateAndNextNull(nodep->condp()); + m_insStmtp = NULL; + iterateAndNextNull(nodep->ifsp()); + iterateAndNextNull(nodep->elsesp()); + m_insStmtp = NULL; + } + virtual void visit(AstNodeFor* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE + nodep->v3fatalSrc( + "For statements should have been converted to while statements in V3Begin.cpp"); + } + virtual void visit(AstNodeStmt* nodep) VL_OVERRIDE { + if (!nodep->isStatement()) { + iterateChildren(nodep); + return; + } + m_insMode = IM_BEFORE; + m_insStmtp = nodep; + iterateChildren(nodep); + m_insStmtp = NULL; // Next thing should be new statement + } + void unsupported_visit(AstNode* nodep) { + m_unsupportedHere = true; + UINFO(9, "Marking unsupported " << nodep << endl); + iterateChildren(nodep); + m_unsupportedHere = false; + } + virtual void visit(AstLogAnd* nodep) VL_OVERRIDE { unsupported_visit(nodep); } + virtual void visit(AstLogOr* nodep) VL_OVERRIDE { unsupported_visit(nodep); } + virtual void visit(AstLogEq* nodep) VL_OVERRIDE { unsupported_visit(nodep); } + virtual void visit(AstLogIf* nodep) VL_OVERRIDE { unsupported_visit(nodep); } + virtual void visit(AstNodeCond* nodep) VL_OVERRIDE { unsupported_visit(nodep); } + void prepost_visit(AstNodeTriop* nodep) { + // Check if we are underneath a statement + if (!m_insStmtp) { + prepost_non_stmt_visit(nodep); + } else { + prepost_stmt_visit(nodep); + } + } + void prepost_non_stmt_visit(AstNodeTriop* nodep) { + iterateChildren(nodep); + + AstConst* constp = VN_CAST(nodep->lhsp(), Const); + UASSERT_OBJ(nodep, constp, "Expecting CONST"); + AstConst* newconstp = constp->cloneTree(true); + + AstNode* storetop = nodep->thsp(); + AstNode* valuep = nodep->rhsp(); + + storetop->unlinkFrBack(); + valuep->unlinkFrBack(); + + AstAssign* assignp; + if (VN_IS(nodep, PreSub) || VN_IS(nodep, PostSub)) { + assignp = new AstAssign(nodep->fileline(), storetop, + new AstSub(nodep->fileline(), valuep, newconstp)); + } else { + assignp = new AstAssign(nodep->fileline(), storetop, + new AstAdd(nodep->fileline(), valuep, newconstp)); + } + nodep->replaceWith(assignp); + VL_DO_DANGLING(nodep->deleteTree(), nodep); + } + void prepost_stmt_visit(AstNodeTriop* nodep) { + iterateChildren(nodep); + + AstNodeVarRef* varrefp; + if (m_unsupportedHere || !(varrefp = VN_CAST(nodep->rhsp(), VarRef))) { + nodep->v3error("Unsupported: Incrementation in this context."); + return; + } + + AstConst* constp = VN_CAST(nodep->lhsp(), Const); + UASSERT_OBJ(nodep, constp, "Expecting CONST"); + AstNode* backp = nodep->backp(); + AstConst* newconstp = constp->cloneTree(true); + + // Prepare a temporary variable + FileLine* fl = backp->fileline(); + string name = string("__Vincrement") + cvtToStr(++m_modIncrementsNum); + AstVar* varp = new AstVar(fl, AstVarType::BLOCKTEMP, name, VFlagChildDType(), + varrefp->varp()->subDTypep()->cloneTree(true)); + + // Declare the variable + insertBeforeStmt(nodep, varp); + + // Define what operation will we be doing + AstNode* operp; + if (VN_IS(nodep, PostSub) || VN_IS(nodep, PreSub)) { + operp = new AstSub(fl, new AstVarRef(fl, varrefp->varp(), false), newconstp); + } else { + operp = new AstAdd(fl, new AstVarRef(fl, varrefp->varp(), false), newconstp); + } + + if (VN_IS(nodep, PreAdd) || VN_IS(nodep, PreSub)) { + // PreAdd/PreSub operations + // Immediately after declaration - increment it by one + m_insStmtp->addHereThisAsNext(new AstAssign(fl, new AstVarRef(fl, varp, true), operp)); + // Immediately after incrementing - assign it to the original variable + m_insStmtp->addHereThisAsNext(new AstAssign( + fl, new AstVarRef(fl, varrefp->varp(), true), new AstVarRef(fl, varp, false))); + } else { + // PostAdd/PostSub operations + // assign the original variable to the temporary one + m_insStmtp->addHereThisAsNext(new AstAssign( + fl, new AstVarRef(fl, varp, true), new AstVarRef(fl, varrefp->varp(), false))); + // Increment the original variable by one + m_insStmtp->addHereThisAsNext( + new AstAssign(fl, new AstVarRef(fl, varrefp->varp(), true), operp)); + } + + // Replace the node with the temporary + nodep->replaceWith(new AstVarRef(varrefp->fileline(), varp, true)); + VL_DO_DANGLING(nodep->deleteTree(), nodep); + } + virtual void visit(AstPreAdd* nodep) VL_OVERRIDE { prepost_visit(nodep); } + virtual void visit(AstPostAdd* nodep) VL_OVERRIDE { prepost_visit(nodep); } + virtual void visit(AstPreSub* nodep) VL_OVERRIDE { prepost_visit(nodep); } + virtual void visit(AstPostSub* nodep) VL_OVERRIDE { prepost_visit(nodep); } + virtual void visit(AstGenFor* nodep) VL_OVERRIDE { iterateChildren(nodep); } + virtual void visit(AstNode* nodep) VL_OVERRIDE { iterateChildren(nodep); } + +public: + // CONSTRUCTORS + explicit LinkIncVisitor(AstNetlist* nodep) { + m_modIncrementsNum = 0; + m_insMode = IM_BEFORE; + m_insStmtp = NULL; + m_unsupportedHere = false; + iterate(nodep); + } + virtual ~LinkIncVisitor() {} +}; + +//###################################################################### +// Task class functions + +void V3LinkInc::linkIncrements(AstNetlist* nodep) { + UINFO(2, __FUNCTION__ << ": " << endl); + { LinkIncVisitor bvisitor(nodep); } // Destruct before checking + V3Global::dumpCheckGlobalTree("linkInc", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); +} diff --git a/src/V3LinkInc.h b/src/V3LinkInc.h new file mode 100644 index 000000000..a1679e6d3 --- /dev/null +++ b/src/V3LinkInc.h @@ -0,0 +1,36 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: Replace increments/decrements with new variables +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// Copyright 2003-2020 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 _V3LINKINC_H_ +#define _V3LINKINC_H_ 1 + +#include "config_build.h" +#include "verilatedos.h" + +#include "V3Error.h" +#include "V3Ast.h" + +//============================================================================ + +class V3LinkInc { +public: + static void linkIncrements(AstNetlist* nodep); + +private: + void prepost_visit(AstNode* nodep); +}; + +#endif // Guard diff --git a/src/V3LinkJump.cpp b/src/V3LinkJump.cpp index 097cdbc9a..3c9185b33 100644 --- a/src/V3LinkJump.cpp +++ b/src/V3LinkJump.cpp @@ -16,9 +16,16 @@ // V3LinkJump's Transformations: // // Each module: -// Look for BEGINs -// BEGIN(VAR...) -> VAR ... {renamed} -// FOR -> WHILEs +// Look for BEGINs +// BEGIN(VAR...) -> VAR ... {renamed} +// FOR -> WHILEs +// +// Add JumpLabel which branches to after statements within JumpLabel +// RETURN -> JUMPBLOCK(statements with RETURN changed to JUMPGO, ..., JUMPLABEL) +// WHILE(... BREAK) -> JUMPBLOCK(WHILE(... statements with BREAK changed to JUMPGO), +// ... JUMPLABEL) +// WHILE(... CONTINUE) -> WHILE(JUMPBLOCK(... statements with CONTINUE changed to JUMPGO, +// ... JUMPPABEL)) // //************************************************************************* @@ -30,7 +37,6 @@ #include "V3Ast.h" #include -#include #include //###################################################################### @@ -45,6 +51,7 @@ private: AstNodeFTask* m_ftaskp; // Current function/task AstWhile* m_loopp; // Current loop bool m_loopInc; // In loop increment + bool m_inFork; // Under fork int m_modRepeatNum; // Repeat counter BlockStack m_blockStack; // All begin blocks above current node @@ -85,7 +92,9 @@ private: if (VN_IS(underp, JumpLabel)) { return VN_CAST(underp, JumpLabel); } else { // Move underp stuff to be under a new label - AstJumpLabel* labelp = new AstJumpLabel(nodep->fileline(), NULL); + AstJumpBlock* blockp = new AstJumpBlock(nodep->fileline(), NULL); + AstJumpLabel* labelp = new AstJumpLabel(nodep->fileline(), blockp); + blockp->labelp(labelp); AstNRelinker repHandle; if (under_and_next) { @@ -93,14 +102,16 @@ private: } else { underp->unlinkFrBack(&repHandle); } - repHandle.relink(labelp); + repHandle.relink(blockp); - labelp->addStmtsp(underp); + blockp->addStmtsp(underp); // Keep any AstVars under the function not under the new JumpLabel for (AstNode *nextp, *varp = underp; varp; varp = nextp) { nextp = varp->nextp(); - if (VN_IS(varp, Var)) labelp->addPrev(varp->unlinkFrBack()); + if (VN_IS(varp, Var)) blockp->addPrev(varp->unlinkFrBack()); } + // Label goes last + blockp->addEndStmtsp(labelp); return labelp; } } @@ -125,9 +136,14 @@ private: } virtual void visit(AstNodeBlock* nodep) VL_OVERRIDE { UINFO(8, " " << nodep << endl); + bool oldFork = m_inFork; m_blockStack.push_back(nodep); - iterateChildren(nodep); + { + m_inFork = m_inFork || VN_IS(nodep, Fork); + iterateChildren(nodep); + } m_blockStack.pop_back(); + m_inFork = oldFork; } virtual void visit(AstRepeat* nodep) VL_OVERRIDE { // So later optimizations don't need to deal with them, @@ -174,7 +190,11 @@ private: virtual void visit(AstReturn* nodep) VL_OVERRIDE { iterateChildren(nodep); AstFunc* funcp = VN_CAST(m_ftaskp, Func); - if (!m_ftaskp) { + if (m_inFork) { + nodep->v3error("Return isn't legal under fork (IEEE 1800-2017 9.2.3)"); + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); + return; + } else if (!m_ftaskp) { nodep->v3error("Return isn't underneath a task or function"); } else if (funcp && !nodep->lhsp()) { nodep->v3error("Return underneath a function should have return value"); @@ -257,6 +277,7 @@ public: explicit LinkJumpVisitor(AstNetlist* nodep) { m_modp = NULL; m_ftaskp = NULL; + m_inFork = false; m_loopp = NULL; m_loopInc = false; m_modRepeatNum = 0; diff --git a/src/V3LinkLValue.cpp b/src/V3LinkLValue.cpp index 251146a94..915501d51 100644 --- a/src/V3LinkLValue.cpp +++ b/src/V3LinkLValue.cpp @@ -25,10 +25,7 @@ #include "V3LinkLValue.h" #include "V3Ast.h" -#include -#include #include -#include //###################################################################### // Link state, as a visitor of each AstNode @@ -91,6 +88,16 @@ private: } m_setRefLvalue = last_setRefLvalue; } + virtual void visit(AstFOpenMcd* nodep) VL_OVERRIDE { + bool last_setRefLvalue = m_setRefLvalue; + { + m_setRefLvalue = true; + iterateAndNextNull(nodep->filep()); + m_setRefLvalue = false; + iterateAndNextNull(nodep->filenamep()); + } + m_setRefLvalue = last_setRefLvalue; + } virtual void visit(AstFClose* nodep) VL_OVERRIDE { bool last_setRefLvalue = m_setRefLvalue; { @@ -205,6 +212,21 @@ private: } m_setRefLvalue = last_setRefLvalue; } + void prepost_visit(AstNodeTriop* nodep) { + bool last_setRefLvalue = m_setRefLvalue; + { + m_setRefLvalue = false; + iterateAndNextNull(nodep->lhsp()); + iterateAndNextNull(nodep->rhsp()); + m_setRefLvalue = true; + iterateAndNextNull(nodep->thsp()); + } + m_setRefLvalue = last_setRefLvalue; + } + virtual void visit(AstPreAdd* nodep) VL_OVERRIDE { prepost_visit(nodep); } + virtual void visit(AstPostAdd* nodep) VL_OVERRIDE { prepost_visit(nodep); } + virtual void visit(AstPreSub* nodep) VL_OVERRIDE { prepost_visit(nodep); } + virtual void visit(AstPostSub* nodep) VL_OVERRIDE { prepost_visit(nodep); } // Nodes that change LValue state virtual void visit(AstSel* nodep) VL_OVERRIDE { diff --git a/src/V3LinkLevel.cpp b/src/V3LinkLevel.cpp index 7231c96eb..8c0fe88ec 100644 --- a/src/V3LinkLevel.cpp +++ b/src/V3LinkLevel.cpp @@ -27,7 +27,6 @@ #include "V3Ast.h" #include -#include #include #include @@ -47,8 +46,6 @@ void V3LinkLevel::modSortByLevel() { // level() was computed for us in V3LinkCells - typedef std::vector ModVec; - ModVec mods; // Modules ModVec tops; // Top level modules for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index ad875a432..8fb47dc64 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -27,7 +27,6 @@ #include "V3Config.h" #include -#include #include #include #include @@ -53,8 +52,6 @@ private: ImplTypedefMap m_implTypedef; // Created typedefs for each FileLineSet m_filelines; // Filelines that have been seen bool m_inAlways; // Inside an always - bool m_inGenerate; // Inside a generate - bool m_needStart; // Need start marker on lower AstParse AstNodeModule* m_valueModp; // If set, move AstVar->valuep() initial values to this module AstNodeModule* m_modp; // Current module AstNodeFTask* m_ftaskp; // Current task @@ -173,6 +170,10 @@ private: virtual void visit(AstVar* nodep) VL_OVERRIDE { cleanFileline(nodep); + if (nodep->isParam() && !nodep->valuep() + && nodep->fileline()->language() < V3LangCode::L1800_2009) { + nodep->v3error("Parameter requires default value, or use IEEE 1800-2009 or later."); + } if (VN_IS(nodep->subDTypep(), ParseTypeDType)) { // It's a parameter type. Use a different node type for this. AstNodeDType* dtypep = VN_CAST(nodep->valuep(), NodeDType); @@ -463,8 +464,7 @@ private: iterateChildren(nodep); m_valueModp = upperValueModp; } - virtual void visit(AstInitial* nodep) VL_OVERRIDE { visitIterateNoValueMod(nodep); } - virtual void visit(AstFinal* nodep) VL_OVERRIDE { visitIterateNoValueMod(nodep); } + virtual void visit(AstNodeProcedure* nodep) VL_OVERRIDE { visitIterateNoValueMod(nodep); } virtual void visit(AstAlways* nodep) VL_OVERRIDE { m_inAlways = true; visitIterateNoValueMod(nodep); @@ -491,17 +491,6 @@ private: } iterateChildren(nodep); } - virtual void visit(AstFork* nodep) VL_OVERRIDE { - if (v3Global.opt.bboxUnsup()) { - AstBegin* newp - = new AstBegin(nodep->fileline(), nodep->name(), nodep->stmtsp()->unlinkFrBack()); - nodep->replaceWith(newp); - VL_DO_DANGLING(nodep->deleteTree(), nodep); - } else { - nodep->v3error("Unsupported: fork statements"); - // TBD might support only normal join, if so complain about other join flavors - } - } virtual void visit(AstCase* nodep) VL_OVERRIDE { V3Config::applyCase(nodep); cleanFileline(nodep); @@ -544,8 +533,6 @@ public: m_ftaskp = NULL; m_dtypep = NULL; m_inAlways = false; - m_inGenerate = false; - m_needStart = false; m_valueModp = NULL; iterate(rootp); } diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 90752c815..a6074a554 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -33,9 +33,7 @@ #include "V3Ast.h" #include -#include #include -#include //###################################################################### // Link state, as a visitor of each AstNode @@ -212,7 +210,7 @@ private: nodep->v3error("Unsupported: Complex statement in sensitivity list"); } } - virtual void visit(AstSenGate* nodep) VL_OVERRIDE { + virtual void visit(AstSenGate* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE nodep->v3fatalSrc("SenGates shouldn't be in tree yet"); } @@ -289,11 +287,13 @@ private: // Check display arguments, return new format string string newFormat; bool inPct = false; + bool inIgnore = false; string fmt; for (string::const_iterator it = format.begin(); it != format.end(); ++it) { char ch = *it; if (!inPct && ch == '%') { inPct = true; + inIgnore = false; fmt = ch; } else if (inPct && (isdigit(ch) || ch == '.' || ch == '-')) { fmt += ch; @@ -303,6 +303,10 @@ private: switch (tolower(ch)) { case '%': // %% - just output a % break; + case '*': + inPct = true; + inIgnore = true; + break; case 'm': // %m - auto insert "name" if (isScan) { nodep->v3error("Unsupported: %m in $fscanf"); @@ -317,9 +321,9 @@ private: if (m_modp) fmt = VString::quotePercent(m_modp->prettyName()); break; default: // Most operators, just move to next argument - if (!V3Number::displayedFmtLegal(ch)) { + if (!V3Number::displayedFmtLegal(ch, isScan)) { nodep->v3error("Unknown $display-like format code: '%" << ch << "'"); - } else { + } else if (!inIgnore) { if (!argp) { nodep->v3error("Missing arguments for $display-like format"); } else { @@ -358,11 +362,20 @@ private: } else if (inpercent) { inpercent = 0; switch (c) { - case '0' ... '9': + case '0': // FALLTHRU + case '1': // FALLTHRU + case '2': // FALLTHRU + case '3': // FALLTHRU + case '4': // FALLTHRU + case '5': // FALLTHRU + case '6': // FALLTHRU + case '7': // FALLTHRU + case '8': // FALLTHRU + case '9': // FALLTHRU case '.': inpercent = true; break; case '%': break; default: - if (V3Number::displayedFmtLegal(c)) { skipCount++; } + if (V3Number::displayedFmtLegal(c, isScan)) ++skipCount; } } } @@ -391,6 +404,10 @@ private: iterateChildren(nodep); expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef)); } + virtual void visit(AstFOpenMcd* nodep) VL_OVERRIDE { + iterateChildren(nodep); + expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef)); + } virtual void visit(AstFClose* nodep) VL_OVERRIDE { iterateChildren(nodep); expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef)); diff --git a/src/V3Localize.cpp b/src/V3Localize.cpp index 1ca733c6a..3a9b17946 100644 --- a/src/V3Localize.cpp +++ b/src/V3Localize.cpp @@ -30,7 +30,6 @@ #include "V3Stats.h" #include "V3Ast.h" -#include #include //###################################################################### @@ -192,7 +191,8 @@ private: virtual void visit(AstVarRef* nodep) VL_OVERRIDE { if (!VarFlags(nodep->varp()).m_notOpt) { if (!m_cfuncp) { // Not in function, can't optimize - clearOptimizable(nodep->varp(), "BVnofunc"); + // Perhaps impossible, but better safe + clearOptimizable(nodep->varp(), "BVnofunc"); // LCOV_EXCL_LINE } else { // If we're scoping down to it, it isn't really in the same block if (!nodep->hierThis()) clearOptimizable(nodep->varp(), "HierRef"); diff --git a/src/V3MergeCond.cpp b/src/V3MergeCond.cpp new file mode 100644 index 000000000..483d32c15 --- /dev/null +++ b/src/V3MergeCond.cpp @@ -0,0 +1,339 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: Merge branches/ternary ?: +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// Copyright 2003-2020 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 +// +//************************************************************************* +// V3BranchMerge's Transformations: +// +// Look for sequences of assignments with ternary conditional on the right +// hand side with the same condition: +// lhs0 = cond ? then0 : else0; +// lhs1 = cond ? then1 : else1; +// lhs2 = cond ? then2 : else2; +// +// This seems to be a common pattern and can make the C compiler take a +// long time when compiling it with optimization. For us it's easy and fast +// to convert this to 'if' statements because we know the pattern is common: +// if (cond) { +// lhs0 = then0; +// lhs1 = then1; +// lhs2 = then2; +// } else { +// lhs0 = else0; +// lhs1 = else1; +// lhs2 = else2; +// } +// +// For 1-bit signals, we consider strength reduced forms to be conditionals, +// but only if we already encountered a true conditional we can merge with. +// If we did, then act as if: +// 'lhs = cond & value' is actually 'lhs = cond ? value : 1'd0' +// 'lhs = cond' is actually 'lhs = cond ? 1'd1 : 1'd0'. +// +//************************************************************************* + +#include "config_build.h" +#include "verilatedos.h" + +#include "V3Global.h" +#include "V3MergeCond.h" +#include "V3Stats.h" +#include "V3Ast.h" + +//###################################################################### + +class CheckMergeableVisitor : public AstNVisitor { +private: + // STATE + bool m_mergeable; // State tracking whether tree being processed is a mergeable condition + + // METHODS + VL_DEBUG_FUNC; // Declare debug() + + void clearMergeable(const AstNode* nodep, const char* reason) { + UASSERT_OBJ(m_mergeable, nodep, "Should have short-circuited traversal"); + m_mergeable = false; + UINFO(9, "Clearing mergeable on " << nodep << " due to " << reason << endl); + } + + // VISITORS + virtual void visit(AstNode* nodep) VL_OVERRIDE { + if (!m_mergeable) return; + // Clear if node is impure + if (!nodep->isPure()) { + clearMergeable(nodep, "impure"); + return; + } + iterateChildrenConst(nodep); + } + virtual void visit(AstVarRef* nodep) VL_OVERRIDE { + if (!m_mergeable) return; + // Clear if it's an LValue referencing a marked variable + if (nodep->lvalue() && nodep->varp()->user1()) { + clearMergeable(nodep, "might modify condition"); + } + } + +public: + CheckMergeableVisitor() + : m_mergeable(false) {} + + // Return false if this node should not be merged at all because: + // - It contains an impure expression + // - It contains an LValue referencing the condition + bool operator()(const AstNodeAssign* node) { + m_mergeable = true; + iterateChildrenConst(const_cast(node)); + return m_mergeable; + } +}; + +class MarkVarsVisitor : public AstNVisitor { +private: + // METHODS + VL_DEBUG_FUNC; // Declare debug() + + // VISITORS + virtual void visit(AstVarRef* nodep) VL_OVERRIDE { nodep->varp()->user1(1); } + virtual void visit(AstNode* nodep) VL_OVERRIDE { iterateChildrenConst(nodep); } + +public: + // Set user1 on all referenced AstVar + void operator()(AstNode* node) { + AstNode::user1ClearTree(); + iterate(node); + } +}; + +class MergeCondVisitor : public AstNVisitor { +private: + // NODE STATE + // AstVar::user1 -> Flag set for variables referenced by m_mgCondp + AstUser1InUse m_user1InUse; + + // STATE + VDouble0 m_statMerges; // Statistic tracking + VDouble0 m_statMergedItems; // Statistic tracking + VDouble0 m_statLongestList; // Statistic tracking + + AstNode* m_mgFirstp; // First node in merged sequence + AstNode* m_mgCondp; // The condition of the first node + AstNode* m_mgLastp; // Last node in merged sequence + const AstNode* m_mgNextp; // Next node in list being examined + uint32_t m_listLenght; // Length of current list + + CheckMergeableVisitor m_checkMergeable; // Sub visitor for encapsulation & speed + MarkVarsVisitor m_markVars; // Sub visitor for encapsulation & speed + + // METHODS + VL_DEBUG_FUNC; // Declare debug() + + // This function extracts the Cond node from the RHS, if there is one and + // it is in a supported position, which are: + // - RHS is the Cond + // - RHS is And(Const, Cond). This And is inserted often by V3Clean. + AstNodeCond* extractCond(AstNode* rhsp) { + if (AstNodeCond* const condp = VN_CAST(rhsp, NodeCond)) { + return condp; + } else if (AstAnd* const andp = VN_CAST(rhsp, And)) { + if (AstNodeCond* const condp = VN_CAST(andp->rhsp(), NodeCond)) { + if (VN_IS(andp->lhsp(), Const)) { return condp; } + } + } + return NULL; + } + + // Apply (_ & 1'b1). This is necessary because this pass is after V3Clean, + // and sometimes we have an AstAnd with a 1-bit condition on one side, but + // a more than 1-bit value on the other side, so we need to keep only the + // LSB. Ideally we would only do this iff the node is known not to be 1-bit + // wide, but working that out here is a bit difficult. As this masking is + // rarely required (only when trying to merge a "cond & value" with an + // earlier ternary), we will just always mask it for safety. + AstNode* maskLsb(AstNode* nodep) { + AstNode* const maskp = new AstConst(nodep->fileline(), AstConst::LogicTrue()); + return new AstAnd(nodep->fileline(), nodep, maskp); + } + + // Fold the RHS expression assuming the given condition state. Unlink bits + // from the RHS which is only used once, and can be reused. What remains + // of the RHS is expected to be deleted by the caller. + AstNode* foldAndUnlink(AstNode* rhsp, bool condTrue) { + if (rhsp->sameTree(m_mgCondp)) { + return condTrue ? new AstConst(rhsp->fileline(), AstConst::LogicTrue()) + : new AstConst(rhsp->fileline(), AstConst::LogicFalse()); + } else if (AstNodeCond* const condp = extractCond(rhsp)) { + AstNode* const resp + = condTrue ? condp->expr1p()->unlinkFrBack() : condp->expr2p()->unlinkFrBack(); + if (condp == rhsp) { return resp; } + if (AstAnd* const andp = VN_CAST(rhsp, And)) { + UASSERT_OBJ(andp->rhsp() == condp, rhsp, "Should not try to fold this"); + return new AstAnd(andp->fileline(), andp->lhsp()->cloneTree(false), resp); + } + } else if (AstAnd* const andp = VN_CAST(rhsp, And)) { + if (andp->lhsp()->sameTree(m_mgCondp)) { + return condTrue ? maskLsb(andp->rhsp()->unlinkFrBack()) + : new AstConst(rhsp->fileline(), AstConst::LogicFalse()); + } else { + UASSERT_OBJ(andp->rhsp()->sameTree(m_mgCondp), rhsp, + "AstAnd doesn't hold condition expression"); + return condTrue ? maskLsb(andp->lhsp()->unlinkFrBack()) + : new AstConst(rhsp->fileline(), AstConst::LogicFalse()); + } + } + rhsp->v3fatalSrc("Don't know how to fold expression"); + } + + void mergeEnd() { + UASSERT(m_mgFirstp, "mergeEnd without list"); + // Merge if list is longer than one node + if (m_mgFirstp != m_mgLastp) { + UINFO(6, "MergeCond - First: " << m_mgFirstp << " Last: " << m_mgLastp << endl); + ++m_statMerges; + if (m_listLenght > m_statLongestList) m_statLongestList = m_listLenght; + + // Create equivalent 'if' statement and insert it before the first node + AstIf* const ifp + = new AstIf(m_mgCondp->fileline(), m_mgCondp->unlinkFrBack(), NULL, NULL); + m_mgFirstp->replaceWith(ifp); + ifp->addNextHere(m_mgFirstp); + // Unzip the list and insert under branches + AstNode* nextp = m_mgFirstp; + do { + // Grab next pointer and unlink + AstNode* const currp = nextp; + nextp = currp != m_mgLastp ? currp->nextp() : NULL; + currp->unlinkFrBack(); + // Skip over comments + if (VN_IS(currp, Comment)) { + VL_DO_DANGLING(currp->deleteTree(), currp); + continue; + } + // Count + ++m_statMergedItems; + // Unlink RHS and clone to get the 2 assignments (reusing currp) + AstNodeAssign* const thenp = VN_CAST(currp, NodeAssign); + AstNode* const rhsp = thenp->rhsp()->unlinkFrBack(); + AstNodeAssign* const elsep = thenp->cloneTree(false); + // Construct the new RHSs and add to branches + thenp->rhsp(foldAndUnlink(rhsp, true)); + elsep->rhsp(foldAndUnlink(rhsp, false)); + ifp->addIfsp(thenp); + ifp->addElsesp(elsep); + // Cleanup + VL_DO_DANGLING(rhsp->deleteTree(), rhsp); + } while (nextp); + } + // Reset state + m_mgFirstp = NULL; + m_mgCondp = NULL; + m_mgLastp = NULL; + m_mgNextp = NULL; + } + + void addToList(AstNode* nodep, AstNode* condp) { + // Set up head of new list if node is first in list + if (!m_mgFirstp) { + UASSERT_OBJ(condp, nodep, "Cannot start new list without condition"); + m_mgFirstp = nodep; + m_mgCondp = condp; + m_listLenght = 0; + m_markVars(condp); + } + // Add node + ++m_listLenght; + // Track end of list + m_mgLastp = nodep; + // Set up expected next node in list. Skip over any comments, (inserted + // by V3Order before always blocks) + m_mgNextp = nodep->nextp(); + while (m_mgNextp && VN_IS(m_mgNextp, Comment)) { m_mgNextp = m_mgNextp->nextp(); } + // If last under parent, done with current list + if (!m_mgNextp) mergeEnd(); + } + + // VISITORS + virtual void visit(AstNodeAssign* nodep) VL_OVERRIDE { + AstNode* const rhsp = nodep->rhsp(); + if (AstNodeCond* const condp = extractCond(rhsp)) { + if (!m_checkMergeable(nodep)) { + // Node not mergeable. + // Finish current list if any, do not start a new one. + if (m_mgFirstp) mergeEnd(); + return; + } + if (m_mgFirstp && (m_mgNextp != nodep || !condp->condp()->sameTree(m_mgCondp))) { + // Node in different list, or has different condition. + // Finish current list, addToList will start a new one. + mergeEnd(); + } + // Add current node + addToList(nodep, condp->condp()); + } else if (m_mgFirstp) { + // RHS is not a conditional, but we already started a list. + // If it's a 1-bit signal, and a mergeable assignment, try reduced forms + if (rhsp->widthMin() == 1 && m_checkMergeable(nodep)) { + // Is it a 'lhs = cond & value' or 'lhs = value & cond'? + if (AstAnd* const andp = VN_CAST(rhsp, And)) { + if (andp->lhsp()->sameTree(m_mgCondp) || andp->rhsp()->sameTree(m_mgCondp)) { + addToList(nodep, NULL); + return; + } + } + // Is it simply 'lhs = cond'? + if (rhsp->sameTree(m_mgCondp)) { + addToList(nodep, NULL); + return; + } + } + // Not added to list, so we are done with the current list + mergeEnd(); + } + } + virtual void visit(AstComment*) VL_OVERRIDE {} // Skip over comments + // For speed, only iterate what is necessary. + virtual void visit(AstNetlist* nodep) VL_OVERRIDE { iterateAndNextNull(nodep->modulesp()); } + virtual void visit(AstNodeModule* nodep) VL_OVERRIDE { iterateAndNextNull(nodep->stmtsp()); } + virtual void visit(AstCFunc* nodep) VL_OVERRIDE { + iterateChildren(nodep); + // Close list, if there is one at the end of the function + if (m_mgFirstp) mergeEnd(); + } + virtual void visit(AstNodeStmt* nodep) VL_OVERRIDE { iterateChildren(nodep); } + virtual void visit(AstNode* nodep) VL_OVERRIDE {} + +public: + // CONSTRUCTORS + explicit MergeCondVisitor(AstNetlist* nodep) { + m_mgFirstp = NULL; + m_mgCondp = NULL; + m_mgLastp = NULL; + m_mgNextp = NULL; + m_listLenght = 0; + iterate(nodep); + } + virtual ~MergeCondVisitor() { + V3Stats::addStat("Optimizations, MergeCond merges", m_statMerges); + V3Stats::addStat("Optimizations, MergeCond merged items", m_statMergedItems); + V3Stats::addStat("Optimizations, MergeCond longest merge", m_statLongestList); + } +}; + +//###################################################################### +// MergeConditionals class functions + +void V3MergeCond::mergeAll(AstNetlist* nodep) { + UINFO(2, __FUNCTION__ << ": " << endl); + { MergeCondVisitor visitor(nodep); } + V3Global::dumpCheckGlobalTree("merge_cond", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6); +} diff --git a/src/V3MergeCond.h b/src/V3MergeCond.h new file mode 100644 index 000000000..52232bd0b --- /dev/null +++ b/src/V3MergeCond.h @@ -0,0 +1,33 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: Recreate loops to help pack caches +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// Copyright 2003-2020 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 _V3MERGECOND_H_ +#define _V3MERGECOND_H_ 1 + +#include "config_build.h" +#include "verilatedos.h" + +#include "V3Error.h" +#include "V3Ast.h" + +//============================================================================ + +class V3MergeCond { +public: + static void mergeAll(AstNetlist* nodep); +}; + +#endif // Guard diff --git a/src/V3Name.cpp b/src/V3Name.cpp index e1004b0ef..d08e1776a 100644 --- a/src/V3Name.cpp +++ b/src/V3Name.cpp @@ -25,12 +25,8 @@ #include "V3Global.h" #include "V3Name.h" #include "V3Ast.h" -#include "V3File.h" #include "V3LanguageWords.h" -#include -#include - //###################################################################### // Name state, as a visitor of each AstNode @@ -45,7 +41,6 @@ private: // STATE AstNodeModule* m_modp; - V3LanguageWords m_words; // Reserved word detector // METHODS VL_DEBUG_FUNC; // Declare debug() @@ -58,7 +53,7 @@ private: nodep->editCountInc(); } else if (VN_IS(nodep, CFunc) && VN_CAST(nodep, CFunc)->isConstructor()) { } else { - string rsvd = m_words.isKeyword(nodep->name()); + string rsvd = V3LanguageWords::isKeyword(nodep->name()); if (rsvd != "") { nodep->v3warn(SYMRSVDWORD, "Symbol matches " + rsvd + ": " << nodep->prettyNameQ()); diff --git a/src/V3Number.cpp b/src/V3Number.cpp index 1e1360f33..e7b19e4e5 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -24,42 +24,49 @@ #include #include #include -#include -#include -#define MAX_SPRINTF_DOUBLE_SIZE 100 // Maximum characters with a sprintf %e/%f/%g (probably < 30) +#define MAX_SPRINTF_DOUBLE_SIZE 1100 // Maximum characters with a sprintf %e/%f/%g (really 1079) // Number operations build output in-place so can't call e.g. foo.opX(foo) #define NUM_ASSERT_OP_ARGS1(arg1) \ - UASSERT((this != &(arg1)), "Number operation called with same source and dest"); + UASSERT((this != &(arg1)), "Number operation called with same source and dest") #define NUM_ASSERT_OP_ARGS2(arg1, arg2) \ UASSERT((this != &(arg1) && this != &(arg2)), \ - "Number operation called with same source and dest"); + "Number operation called with same source and dest") #define NUM_ASSERT_OP_ARGS3(arg1, arg2, arg3) \ UASSERT((this != &(arg1) && this != &(arg2) && this != &(arg3)), \ - "Number operation called with same source and dest"); + "Number operation called with same source and dest") +#define NUM_ASSERT_OP_ARGS4(arg1, arg2, arg3, arg4) \ + UASSERT((this != &(arg1) && this != &(arg2) && this != &(arg3) && this != &(arg4)), \ + "Number operation called with same source and dest") #define NUM_ASSERT_LOGIC_ARGS1(arg1) \ UASSERT((!(arg1).isDouble() && !(arg1).isString()), \ "Number operation called with non-logic (double or string) argument: '" << (arg1) \ - << '"'); + << '"') #define NUM_ASSERT_LOGIC_ARGS2(arg1, arg2) \ NUM_ASSERT_LOGIC_ARGS1(arg1); \ - NUM_ASSERT_LOGIC_ARGS1(arg2); + NUM_ASSERT_LOGIC_ARGS1(arg2) + +#define NUM_ASSERT_LOGIC_ARGS4(arg1, arg2, arg3, arg4) \ + NUM_ASSERT_LOGIC_ARGS1(arg1); \ + NUM_ASSERT_LOGIC_ARGS1(arg2); \ + NUM_ASSERT_LOGIC_ARGS1(arg3); \ + NUM_ASSERT_LOGIC_ARGS1(arg4) #define NUM_ASSERT_STRING_ARGS1(arg1) \ UASSERT((arg1).isString(), \ - "Number operation called with non-string argument: '" << (arg1) << '"'); + "Number operation called with non-string argument: '" << (arg1) << '"') #define NUM_ASSERT_STRING_ARGS2(arg1, arg2) \ NUM_ASSERT_STRING_ARGS1(arg1); \ - NUM_ASSERT_STRING_ARGS1(arg2); + NUM_ASSERT_STRING_ARGS1(arg2) #define NUM_ASSERT_DOUBLE_ARGS1(arg1) \ UASSERT((arg1).isDouble(), \ - "Number operation called with non-double argument: '" << (arg1) << '"'); + "Number operation called with non-double argument: '" << (arg1) << '"') #define NUM_ASSERT_DOUBLE_ARGS2(arg1, arg2) \ NUM_ASSERT_DOUBLE_ARGS1(arg1); \ - NUM_ASSERT_DOUBLE_ARGS1(arg2); + NUM_ASSERT_DOUBLE_ARGS1(arg2) //====================================================================== // Errors @@ -74,6 +81,12 @@ void V3Number::v3errorEnd(std::ostringstream& str) const { } } +void V3Number::v3errorEndFatal(std::ostringstream& str) const { + v3errorEnd(str); + assert(0); // LCOV_EXCL_LINE + VL_UNREACHABLE +} + //====================================================================== // Read class functions // CREATION @@ -188,7 +201,16 @@ void V3Number::V3NumberCreate(AstNode* nodep, const char* sourcep, FileLine* fl) int got_01 = 0; for (const char* cp = value_startp; *cp; cp++) { switch (tolower(*cp)) { - case '0' ... '9': { + case '0': // FALLTHRU + case '1': // FALLTHRU + case '2': // FALLTHRU + case '3': // FALLTHRU + case '4': // FALLTHRU + case '5': // FALLTHRU + case '6': // FALLTHRU + case '7': // FALLTHRU + case '8': // FALLTHRU + case '9': { if (olen <= 7) { // 10000000 fits in 32 bits, so ok // Constants are common, so for speed avoid wide math until we need it val = val * 10 + (*cp - '0'); @@ -340,7 +362,7 @@ void V3Number::setNames(AstNode* nodep) { int V3Number::log2b(uint32_t num) { // See also opCLog2 for (int bit = 31; bit > 0; bit--) { - if (num & (VL_ULL(1) << bit)) return bit; + if (num & (1ULL << bit)) return bit; } return 0; } @@ -354,8 +376,8 @@ V3Number& V3Number::setZero() { } V3Number& V3Number::setQuad(vluint64_t value) { for (int i = 0; i < words(); i++) m_value[i] = m_valueX[i] = 0; - m_value[0] = value & VL_ULL(0xffffffff); - m_value[1] = (value >> VL_ULL(32)) & VL_ULL(0xffffffff); + m_value[0] = value & 0xffffffffULL; + m_value[1] = (value >> 32ULL) & 0xffffffffULL; opCleanThis(); return *this; } @@ -452,8 +474,8 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const { if (isDouble()) { out.precision(17); - if (width() != 64) { - out << "%E-bad-width-double"; + if (VL_UNCOVERABLE(width() != 64)) { + out << "%E-bad-width-double"; // LCOV_EXCL_LINE } else { out << toDouble(); } @@ -461,8 +483,8 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const { } else if (isString()) { return '"' + toString() + '"'; } else { - if ((m_value[words() - 1] | m_valueX[words() - 1]) & ~hiWordMask()) { - out << "%E-hidden-bits"; + if (VL_UNCOVERABLE((m_value[words() - 1] | m_valueX[words() - 1]) & ~hiWordMask())) { + out << "%E-hidden-bits"; // LCOV_EXCL_LINE } } if (prefixed) { @@ -509,7 +531,7 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const { return out.str(); } -bool V3Number::displayedFmtLegal(char format) { +bool V3Number::displayedFmtLegal(char format, bool isScan) { // Is this a valid format letter? switch (tolower(format)) { case 'b': return true; @@ -529,6 +551,7 @@ bool V3Number::displayedFmtLegal(char format) { case 'z': return true; // Packed 4-state case '@': return true; // Packed string case '~': return true; // Signed decimal + case '*': return isScan; // $scan ignore argument default: return false; } } @@ -769,7 +792,7 @@ string V3Number::toDecimalU() const { if (bcd.bitsValue(lsb, 4)) break; } for (; lsb >= 0; lsb -= 4) { - output += ('0' + bcd.bitsValue(lsb, 4)); // 0..9 + output += static_cast('0' + bcd.bitsValue(lsb, 4)); // 0..9 } return output; } @@ -826,14 +849,14 @@ vluint64_t V3Number::toUQuad() const { } } if (width() <= 32) return (static_cast(toUInt())); - return ((static_cast(m_value[1]) << VL_ULL(32)) + return ((static_cast(m_value[1]) << 32ULL) | (static_cast(m_value[0]))); } vlsint64_t V3Number::toSQuad() const { if (isDouble()) return static_cast(toDouble()); vluint64_t v = toUQuad(); - vluint64_t signExtend = (-(v & (VL_ULL(1) << (width() - 1)))); + vluint64_t signExtend = (-(v & (1ULL << (width() - 1)))); vluint64_t extended = v | signExtend; return static_cast(extended); } @@ -906,31 +929,29 @@ bool V3Number::isFourState() const { } return false; } -bool V3Number::isUnknown() const { +bool V3Number::isAnyX() const { if (isDouble() || isString()) return false; for (int bit = 0; bit < width(); bit++) { if (bitIsX(bit)) return true; } return false; } -bool V3Number::isLt(const V3Number& rhs) const { - for (int bit = 0; bit < std::max(this->width(), rhs.width()); bit++) { - if (this->bitIs1(bit) && rhs.bitIs0(bit)) { return 1; } - if (rhs.bitIs1(bit) && this->bitIs0(bit)) { return 0; } - if (this->bitIsXZ(bit)) { return 0; } - if (rhs.bitIsXZ(bit)) { return 0; } +bool V3Number::isAnyXZ() const { + if (isDouble() || isString()) return false; + for (int bit = 0; bit < width(); bit++) { + if (bitIsX(bit) || bitIsZ(bit)) return true; } - return 0; + return false; } bool V3Number::isLtXZ(const V3Number& rhs) const { // Include X/Z in comparisons for sort ordering for (int bit = 0; bit < std::max(this->width(), rhs.width()); bit++) { - if (this->bitIs1(bit) && rhs.bitIs0(bit)) { return 1; } - if (rhs.bitIs1(bit) && this->bitIs0(bit)) { return 0; } - if (this->bitIsXZ(bit)) { return 1; } - if (rhs.bitIsXZ(bit)) { return 0; } + if (this->bitIs1(bit) && rhs.bitIs0(bit)) { return true; } + if (rhs.bitIs1(bit) && this->bitIs0(bit)) { return false; } + if (this->bitIsXZ(bit)) { return true; } + if (rhs.bitIsXZ(bit)) { return false; } } - return 0; + return false; } int V3Number::widthMin() const { @@ -940,6 +961,37 @@ int V3Number::widthMin() const { return 1; // one bit even if number is == 0 } +uint32_t V3Number::countBits(const V3Number& ctrl) const { + int n = 0; + for (int bit = 0; bit < this->width(); ++bit) { + switch (ctrl.bitIs(0)) { + case '0': + if (bitIs0(bit)) ++n; + break; + case '1': + if (bitIs1(bit)) ++n; + break; + case 'x': + if (bitIsX(bit)) ++n; + break; + case 'z': + if (bitIsZ(bit)) ++n; + break; + } + } + return n; +} + +uint32_t V3Number::countBits(const V3Number& ctrl1, const V3Number& ctrl2, + const V3Number& ctrl3) const { + int n = countBits(ctrl1); + if (ctrl2.bitIs(0) != ctrl1.bitIs(0)) n += countBits(ctrl2); + if ((ctrl3.bitIs(0) != ctrl1.bitIs(0)) && (ctrl3.bitIs(0) != ctrl2.bitIs(0))) { + n += countBits(ctrl3); + } + return n; +} + uint32_t V3Number::countOnes() const { int n = 0; for (int bit = 0; bit < this->width(); bit++) { @@ -1082,6 +1134,15 @@ V3Number& V3Number::opRedXnor(const V3Number& lhs) { return setSingleBits(outc); } +V3Number& V3Number::opCountBits(const V3Number& expr, const V3Number& ctrl1, const V3Number& ctrl2, + const V3Number& ctrl3) { + NUM_ASSERT_OP_ARGS4(expr, ctrl1, ctrl2, ctrl3); + NUM_ASSERT_LOGIC_ARGS4(expr, ctrl1, ctrl2, ctrl3); + setZero(); + m_value[0] = expr.countBits(ctrl1, ctrl2, ctrl3); + opCleanThis(); + return *this; +} V3Number& V3Number::opCountOnes(const V3Number& lhs) { NUM_ASSERT_OP_ARGS1(lhs); NUM_ASSERT_LOGIC_ARGS1(lhs); @@ -1093,7 +1154,7 @@ V3Number& V3Number::opCountOnes(const V3Number& lhs) { } V3Number& V3Number::opIsUnknown(const V3Number& lhs) { NUM_ASSERT_OP_ARGS1(lhs); - return setSingleBits(lhs.isUnknown()); + return setSingleBits(lhs.isAnyXZ()); } V3Number& V3Number::opOneHot(const V3Number& lhs) { NUM_ASSERT_OP_ARGS1(lhs); @@ -1179,7 +1240,7 @@ V3Number& V3Number::opOr(const V3Number& lhs, const V3Number& rhs) { if (lhs.bitIs1(bit) || rhs.bitIs1(bit)) { setBit(bit, 1); } else if (lhs.bitIs0(bit) && rhs.bitIs0(bit)) { - ; // 0 + // 0 } else { setBit(bit, 'x'); } @@ -1774,8 +1835,8 @@ V3Number& V3Number::opMul(const V3Number& lhs, const V3Number& rhs) { * static_cast(rhs.m_value[rword]); for (int qword = lword + rword; qword < this->words(); qword++) { mul += static_cast(m_value[qword]); - m_value[qword] = (mul & VL_ULL(0xffffffff)); - mul = (mul >> VL_ULL(32)) & VL_ULL(0xffffffff); + m_value[qword] = (mul & 0xffffffffULL); + mul = (mul >> 32ULL) & 0xffffffffULL; } } } @@ -1890,7 +1951,7 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool if (vw == 1) { // Single divisor word breaks rest of algorithm vluint64_t k = 0; for (int j = uw - 1; j >= 0; j--) { - vluint64_t unw64 = ((k << VL_ULL(32)) + static_cast(lhs.m_value[j])); + vluint64_t unw64 = ((k << 32ULL) + static_cast(lhs.m_value[j])); m_value[j] = unw64 / static_cast(rhs.m_value[0]); k = unw64 - (static_cast(m_value[j]) * static_cast(rhs.m_value[0])); @@ -1940,26 +2001,25 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool // Main loop for (int j = uw - vw; j >= 0; j--) { // Estimate - vluint64_t unw64 = (static_cast(un[j + vw]) << VL_ULL(32) + vluint64_t unw64 = (static_cast(un[j + vw]) << 32ULL | static_cast(un[j + vw - 1])); vluint64_t qhat = unw64 / static_cast(vn[vw - 1]); vluint64_t rhat = unw64 - qhat * static_cast(vn[vw - 1]); again: - if (qhat >= VL_ULL(0x100000000) - || ((qhat * vn[vw - 2]) > ((rhat << VL_ULL(32)) + un[j + vw - 2]))) { + if (qhat >= 0x100000000ULL || ((qhat * vn[vw - 2]) > ((rhat << 32ULL) + un[j + vw - 2]))) { qhat = qhat - 1; rhat = rhat + vn[vw - 1]; - if (rhat < VL_ULL(0x100000000)) goto again; + if (rhat < 0x100000000ULL) goto again; } vlsint64_t t = 0; // Must be signed vluint64_t k = 0; for (int i = 0; i < vw; i++) { vluint64_t p = qhat * vn[i]; // Multiply by estimate - t = un[i + j] - k - (p & VL_ULL(0xFFFFFFFF)); // Subtract + t = un[i + j] - k - (p & 0xFFFFFFFFULL); // Subtract un[i + j] = t; - k = (p >> VL_ULL(32)) - (t >> VL_ULL(32)); + k = (p >> 32ULL) - (t >> 32ULL); } t = un[j + vw] - k; un[j + vw] = t; @@ -1972,7 +2032,7 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool for (int i = 0; i < vw; i++) { t = static_cast(un[i + j]) + static_cast(vn[i]) + k; un[i + j] = t; - k = t >> VL_ULL(32); + k = t >> 32ULL; } un[j + vw] = un[j + vw] + k; } @@ -2169,31 +2229,6 @@ V3Number& V3Number::opSelInto(const V3Number& lhs, int lsbval, int width) { return *this; } -V3Number& V3Number::opCond(const V3Number& lhs, const V3Number& if1s, const V3Number& if0s) { - NUM_ASSERT_OP_ARGS3(lhs, if1s, if0s); - NUM_ASSERT_LOGIC_ARGS1(lhs); - V3Number lhstrue(&lhs); - lhstrue.opRedOr(lhs); - if (lhstrue.bitIs0(0)) { - this->opAssign(if0s); - } else if (lhstrue.bitIs1(0)) { - this->opAssign(if1s); - } else { // select is "X/Z" - setZero(); - NUM_ASSERT_LOGIC_ARGS2(if1s, if0s); - for (int bit = 0; bit < this->width(); bit++) { - if (if0s.bitIs1(bit) && if1s.bitIs1(bit)) { - setBit(bit, 1); - } else if (if0s.bitIs0(bit) && if1s.bitIs0(bit)) { - setBit(bit, 0); - } else { - setBit(bit, 'x'); - } - } - } - return *this; -} - //====================================================================== // Ops - Floating point @@ -2224,14 +2259,14 @@ V3Number& V3Number::opRToIRoundS(const V3Number& lhs) { u.d = v; if (u.d == 0.0) {} - int exp = static_cast((u.q >> VL_ULL(52)) & VL_MASK_Q(11)) - 1023; + int exp = static_cast((u.q >> 52ULL) & VL_MASK_Q(11)) - 1023; int lsb = exp - 52; - vluint64_t mantissa = (u.q & VL_MASK_Q(52)) | (VL_ULL(1) << 52); + vluint64_t mantissa = (u.q & VL_MASK_Q(52)) | (1ULL << 52); if (v != 0) { // IEEE format: [63]=sign [62:52]=exp+1023 [51:0]=mantissa // This does not need to support subnormals as they are sub-integral for (int bit = 0; bit <= 52; ++bit) { - if (mantissa & (VL_ULL(1) << bit)) { + if (mantissa & (1ULL << bit)) { int outbit = bit + lsb; if (outbit >= 0) setBit(outbit, 1); } diff --git a/src/V3Number.h b/src/V3Number.h index 363868a9a..9245b2dfd 100644 --- a/src/V3Number.h +++ b/src/V3Number.h @@ -204,6 +204,7 @@ private: public: void v3errorEnd(std::ostringstream& sstr) const; + void v3errorEndFatal(std::ostringstream& sstr) const VL_ATTR_NORETURN; void width(int width, bool sized = true) { // Set width. Only set m_width here, as we need to tweak vector size if (width) { @@ -230,7 +231,7 @@ public: // ACCESSORS string ascii(bool prefixed = true, bool cleanVerilog = false) const; string displayed(AstNode* nodep, const string& vformat) const; - static bool displayedFmtLegal(char format); // Is this a valid format letter? + static bool displayedFmtLegal(char format, bool isScan); // Is this a valid format letter? int width() const { return m_width; } int widthMin() const; // Minimum width that can represent this number (~== log2(num)+1) bool sized() const { return m_sized; } @@ -266,10 +267,10 @@ public: bool isEqOne() const; bool isEqAllOnes(int optwidth = 0) const; bool isCaseEq(const V3Number& rhs) const; // operator== - bool isLt(const V3Number& rhs) const; // operator< bool isLtXZ(const V3Number& rhs) const; // operator< with XZ compared void isSigned(bool ssigned) { m_signed = ssigned; } - bool isUnknown() const; + bool isAnyX() const; + bool isAnyXZ() const; bool isMsbXZ() const { return bitIsXZ(m_width); } uint32_t toUInt() const; vlsint32_t toSInt() const; @@ -282,6 +283,8 @@ public: uint32_t toHash() const; uint32_t edataWord(int eword) const; uint8_t dataByte(int byte) const; + uint32_t countBits(const V3Number& ctrl) const; + uint32_t countBits(const V3Number& ctrl1, const V3Number& ctrl2, const V3Number& ctrl3) const; uint32_t countOnes() const; uint32_t mostSetBitP1() const; // Highest bit set plus one, IE for 16 return 5, for 0 return 0. @@ -312,6 +315,8 @@ public: V3Number& opRedAnd(const V3Number& lhs); V3Number& opRedXor(const V3Number& lhs); V3Number& opRedXnor(const V3Number& lhs); + V3Number& opCountBits(const V3Number& expr, const V3Number& ctrl1, const V3Number& ctrl2, + const V3Number& ctrl3); V3Number& opCountOnes(const V3Number& lhs); V3Number& opIsUnknown(const V3Number& lhs); V3Number& opOneHot(const V3Number& lhs); @@ -329,7 +334,6 @@ public: V3Number& opSelInto(const V3Number& lhs, int lsbval, int width); V3Number& opToLowerN(const V3Number& lhs); V3Number& opToUpperN(const V3Number& lhs); - V3Number& opCond(const V3Number& lhs, const V3Number& if1s, const V3Number& if0s); V3Number& opCaseEq(const V3Number& lhs, const V3Number& rhs); V3Number& opCaseNeq(const V3Number& lhs, const V3Number& rhs); V3Number& opWildEq(const V3Number& lhs, const V3Number& rhs); diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 733cea183..ba8827c96 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -125,7 +125,7 @@ VTimescale::VTimescale(const string& value, bool& badr) : m_e(VTimescale::NONE) { badr = true; string spaceless = VString::removeWhitespace(value); - for (int i = TS_1S; i < _ENUM_END; ++i) { + for (int i = TS_100S; i < _ENUM_END; ++i) { VTimescale ts(i); if (spaceless == ts.ascii()) { badr = false; @@ -329,9 +329,9 @@ void V3Options::fileNfsFlush(const string& filename) { // NFS caches stat() calls so to get up-to-date information must // do a open or opendir on the filename. // Faster to just try both rather than check if a file is a dir. - if (DIR* dirp = opendir(filename.c_str())) { - closedir(dirp); - } else if (int fd = ::open(filename.c_str(), O_RDONLY)) { + if (DIR* dirp = opendir(filename.c_str())) { // LCOV_EXCL_BR_LINE + closedir(dirp); // LCOV_EXCL_LINE + } else if (int fd = ::open(filename.c_str(), O_RDONLY)) { // LCOV_EXCL_BR_LINE if (fd > 0) ::close(fd); } } @@ -540,13 +540,6 @@ string V3Options::getenvSYSTEMC_INCLUDE() { string sc = getenvSYSTEMC(); if (sc != "") var = sc + "/include"; } - // Only correct or check it if we really need the value - if (v3Global.opt.usingSystemCLibs()) { - if (var == "") { - v3fatal("Need $SYSTEMC_INCLUDE in environment or when Verilator configured\n" - "Probably System-C isn't installed, see http://www.systemc.org\n"); - } - } return var; } @@ -561,13 +554,6 @@ string V3Options::getenvSYSTEMC_LIBDIR() { string arch = getenvSYSTEMC_ARCH(); if (sc != "" && arch != "") var = sc + "/lib-" + arch; } - // Only correct or check it if we really need the value - if (v3Global.opt.usingSystemCLibs()) { - if (var == "") { - v3fatal("Need $SYSTEMC_LIBDIR in environment or when Verilator configured\n" - "Probably System-C isn't installed, see http://www.systemc.org\n"); - } - } return var; } @@ -581,6 +567,19 @@ string V3Options::getenvVERILATOR_ROOT() { return var; } +bool V3Options::systemCSystemWide() { +#ifdef HAVE_SYSTEMC_H + return true; +#else + return false; +#endif +} + +bool V3Options::systemCFound() { + return (systemCSystemWide() + || (!getenvSYSTEMC_INCLUDE().empty() && !getenvSYSTEMC_LIBDIR().empty())); +} + //###################################################################### // V3 Options notification methods @@ -637,13 +636,13 @@ void V3Options::notify() { && !v3Global.opt.xmlOnly()); } - if (v3Global.opt.main() && v3Global.opt.systemC()) { - cmdfl->v3error("--main not usable with SystemC. Suggest see examples for sc_main()."); - } - // --trace-threads implies --threads 1 unless explicitly specified if (traceThreads() && !threads()) m_threads = 1; + // Default split limits if not specified + if (m_outputSplitCFuncs < 0) m_outputSplitCFuncs = m_outputSplit; + if (m_outputSplitCTrace < 0) m_outputSplitCTrace = m_outputSplit; + if (v3Global.opt.main() && v3Global.opt.systemC()) { cmdfl->v3error("--main not usable with SystemC. Suggest see examples for sc_main()."); } @@ -668,13 +667,13 @@ string V3Options::protectKeyDefaulted() { return m_protectKey; } -void V3Options::throwSigsegv() { +void V3Options::throwSigsegv() { // LCOV_EXCL_START #if !(defined(VL_CPPCHECK) || defined(__clang_analyzer__)) // clang-format off { char* zp = NULL; *zp = 0; } // Intentional core dump, ignore warnings here // clang-format on #endif -} +} // LCOV_EXCL_STOP VTimescale V3Options::timeComputePrec(const VTimescale& flag) const { if (!timeOverridePrec().isNone()) { @@ -779,7 +778,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char addArg(argv[i]); // -f's really should be inserted in the middle, but this is for debug } #define shift \ - { ++i; } + do { ++i; } while (false) for (int i = 0; i < argc;) { UINFO(9, " Option: " << argv[i] << endl); // + options @@ -843,7 +842,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char else if ( onoff (sw, "-coverage-underscore", flag/*ref*/)){ m_coverageUnderscore = flag; } else if ( onoff (sw, "-coverage-user", flag/*ref*/)){ m_coverageUser = flag; } else if ( onoff (sw, "-covsp", flag/*ref*/)) { } // TBD - else if (!strcmp(sw, "-debug-abort")) { abort(); } // Undocumented, see also --debug-sigsegv + else if (!strcmp(sw, "-debug-abort")) { V3Error::vlAbort(); } // Undocumented, see also --debug-sigsegv else if ( onoff (sw, "-debug-check", flag/*ref*/)) { m_debugCheck = flag; } else if ( onoff (sw, "-debug-collision", flag/*ref*/)) { m_debugCollision = flag; } // Undocumented else if ( onoff (sw, "-debug-leak", flag/*ref*/)) { m_debugLeak = flag; } @@ -857,6 +856,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char else if ( onoff (sw, "-dpi-hdr-only", flag/*ref*/)) { m_dpiHdrOnly = flag; } else if ( onoff (sw, "-dump-defines", flag/*ref*/)) { m_dumpDefines = flag; } else if ( onoff (sw, "-dump-tree", flag/*ref*/)) { m_dumpTree = flag ? 3 : 0; } // Also see --dump-treei + else if ( onoff (sw, "-dump-tree-addrids", flag/*ref*/)){ m_dumpTreeAddrids = flag; } else if ( onoff (sw, "-exe", flag/*ref*/)) { m_exe = flag; } else if ( onoff (sw, "-flatten", flag/*ref*/)) { m_flatten = flag; } else if ( onoff (sw, "-ignc", flag/*ref*/)) { m_ignc = flag; } @@ -892,7 +892,6 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char else if ( onoff (sw, "-threads-coarsen", flag/*ref*/)) { m_threadsCoarsen = flag; } // Undocumented, debug else if ( onoff (sw, "-trace", flag/*ref*/)) { m_trace = flag; } else if ( onoff (sw, "-trace-coverage", flag/*ref*/)) { m_traceCoverage = flag; } - else if ( onoff (sw, "-trace-dups", flag/*ref*/)) { m_traceDups = flag; } else if ( onoff (sw, "-trace-params", flag/*ref*/)) { m_traceParams = flag; } else if ( onoff (sw, "-trace-structs", flag/*ref*/)) { m_traceStructs = flag; } else if ( onoff (sw, "-trace-underscore", flag/*ref*/)) { m_traceUnderscore = flag; } @@ -919,12 +918,12 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char case 'b': m_oCombine = flag; break; case 'c': m_oConst = flag; break; case 'd': m_oDedupe = flag; break; - case 'm': m_oAssemble = flag; break; case 'e': m_oCase = flag; break; case 'g': m_oGate = flag; break; case 'i': m_oInline = flag; break; case 'k': m_oSubstConst = flag; break; case 'l': m_oLife = flag; break; + case 'm': m_oAssemble = flag; break; case 'p': m_public = !flag; break; // With -Op so flag=0, we want public on so few optimizations done @@ -933,6 +932,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char case 't': m_oLifePost = flag; break; case 'u': m_oSubst = flag; break; case 'v': m_oReloop = flag; break; + case 'w': m_oMergeCond = flag; break; case 'x': m_oExpand = flag; break; case 'y': m_oAcycSimp = flag; break; case 'z': m_oLocalize = flag; break; @@ -1062,13 +1062,15 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char } else if (!strcmp(sw, "-output-split-cfuncs") && (i + 1) < argc) { shift; m_outputSplitCFuncs = atoi(argv[i]); - if (m_outputSplitCFuncs - && (!m_outputSplitCTrace || m_outputSplitCTrace > m_outputSplitCFuncs)) { - m_outputSplitCTrace = m_outputSplitCFuncs; + if (m_outputSplitCFuncs < 0) { + fl->v3error("--output-split-cfuncs must be >= 0: " << argv[i]); } - } else if (!strcmp(sw, "-output-split-ctrace")) { // Undocumented optimization tweak + } else if (!strcmp(sw, "-output-split-ctrace")) { shift; m_outputSplitCTrace = atoi(argv[i]); + if (m_outputSplitCTrace < 0) { + fl->v3error("--output-split-ctrace must be >= 0: " << argv[i]); + } } else if (!strcmp(sw, "-protect-lib") && (i + 1) < argc) { shift; m_protectLib = argv[i]; @@ -1195,6 +1197,9 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char parseOptsFile(fl, parseFileArg(optdir, argv[i]), false); } else if (!strcmp(sw, "-gdb")) { // Used only in perl shell + } else if (!strcmp(sw, "-waiver-output") && (i + 1) < argc) { + shift; + m_waiverOutput = argv[i]; } else if (!strcmp(sw, "-rr")) { // Used only in perl shell } else if (!strcmp(sw, "-gdbbt")) { @@ -1509,6 +1514,7 @@ void V3Options::showVersion(bool verbose) { cout << " SYSTEMC_INCLUDE = " << DEFENV_SYSTEMC_INCLUDE << endl; cout << " SYSTEMC_LIBDIR = " << DEFENV_SYSTEMC_LIBDIR << endl; cout << " VERILATOR_ROOT = " << DEFENV_VERILATOR_ROOT << endl; + cout << " SystemC system-wide = " << cvtToStr(systemCSystemWide()) << endl; cout << endl; cout << "Environment:\n"; @@ -1521,6 +1527,10 @@ void V3Options::showVersion(bool verbose) { cout << " VERILATOR_ROOT = " << V3Os::getenvStr("VERILATOR_ROOT", "") << endl; // wrapper uses this: cout << " VERILATOR_BIN = " << V3Os::getenvStr("VERILATOR_BIN", "") << endl; + + cout << endl; + cout << "Features (based on environment or compiled-in support):\n"; + cout << " SystemC found = " << cvtToStr(systemCFound()) << endl; } //====================================================================== @@ -1589,7 +1599,6 @@ V3Options::V3Options() { m_threadsMaxMTasks = 0; m_trace = false; m_traceCoverage = false; - m_traceDups = false; m_traceFormat = TraceFormat::VCD; m_traceParams = true; m_traceStructs = false; @@ -1604,14 +1613,15 @@ V3Options::V3Options() { m_buildJobs = 1; m_convergeLimit = 100; m_dumpTree = 0; + m_dumpTreeAddrids = false; m_gateStmts = 100; m_ifDepth = 0; m_inlineMult = 2000; m_maxNumWidth = 65536; m_moduleRecursion = 100; - m_outputSplit = 0; - m_outputSplitCFuncs = 0; - m_outputSplitCTrace = 0; + m_outputSplit = 20000; + m_outputSplitCFuncs = -1; + m_outputSplitCTrace = -1; m_traceDepth = 0; m_traceMaxArray = 32; m_traceMaxWidth = 256; @@ -1625,6 +1635,7 @@ V3Options::V3Options() { m_makeDir = "obj_dir"; m_bin = ""; m_flags = ""; + m_waiverOutput = ""; m_l2Name = ""; m_unusedRegexp = "*unused*"; m_xAssign = "fast"; @@ -1698,23 +1709,24 @@ void V3Options::optimize(int level) { // Set all optimizations to on/off bool flag = level > 0; m_oAcycSimp = flag; + m_oAssemble = flag; m_oCase = flag; m_oCombine = flag; m_oConst = flag; + m_oDedupe = flag; m_oExpand = flag; m_oGate = flag; m_oInline = flag; m_oLife = flag; m_oLifePost = flag; m_oLocalize = flag; + m_oMergeCond = flag; m_oReloop = flag; m_oReorder = flag; m_oSplit = flag; m_oSubst = flag; m_oSubstConst = flag; m_oTable = flag; - m_oDedupe = flag; - m_oAssemble = flag; // And set specific optimization levels if (level >= 3) { m_inlineMult = -1; // Maximum inlining diff --git a/src/V3Options.h b/src/V3Options.h index 28082d8a9..0a4d72f03 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -72,15 +72,15 @@ inline std::ostream& operator<<(std::ostream& os, const VOptionBool& rhs) { class VTimescale { public: enum en { - TS_1S = 0, // clang-format off - TS_100MS = 1, TS_10MS = 2, TS_1MS = 3, - TS_100US = 4, TS_10US = 5, TS_1US = 6, - TS_100NS = 7, TS_10NS = 8, TS_1NS = 9, - TS_100PS = 10, TS_10PS = 11, TS_1PS = 12, - TS_100FS = 13, TS_10FS = 14, TS_1FS = 15, + TS_100S = 0, TS_10S = 1, TS_1S = 2, + TS_100MS = 3, TS_10MS = 4, TS_1MS = 5, + TS_100US = 6, TS_10US = 7, TS_1US = 8, + TS_100NS = 9, TS_10NS = 10, TS_1NS = 11, + TS_100PS = 12, TS_10PS = 13, TS_1PS = 14, + TS_100FS = 15, TS_10FS = 16, TS_1FS = 17, // clang-format on - NONE = 16, + NONE = 18, _ENUM_END }; enum { TS_DEFAULT = TS_1PS }; @@ -93,30 +93,47 @@ public: : m_e(_e) {} explicit inline VTimescale(int _e) : m_e(static_cast(_e)) {} - int negativeInt() { return -static_cast(m_e); } // Construct from string VTimescale(const string& value, bool& badr); VTimescale(double value, bool& badr) { badr = false; - // clang-format off - if (value == 1e0) m_e = TS_1S; - else if (value == 1e-1) m_e = TS_100MS; - else if (value == 1e-2) m_e = TS_10MS; - else if (value == 1e-3) m_e = TS_1MS; - else if (value == 1e-4) m_e = TS_100US; - else if (value == 1e-5) m_e = TS_10US; - else if (value == 1e-6) m_e = TS_1US; - else if (value == 1e-7) m_e = TS_100NS; - else if (value == 1e-8) m_e = TS_10NS; - else if (value == 1e-9) m_e = TS_1NS; - else if (value == 1e-10) m_e = TS_100PS; - else if (value == 1e-11) m_e = TS_10PS; - else if (value == 1e-12) m_e = TS_1PS; - else if (value == 1e-13) m_e = TS_100FS; - else if (value == 1e-14) m_e = TS_10FS; - else if (value == 1e-15) m_e = TS_1FS; - // clang-format on - else { + if (value == 10e2) { + m_e = TS_100S; + } else if (value == 1e1) { + m_e = TS_10S; + } else if (value == 1e0) { + m_e = TS_1S; + } else if (value == 1e-1) { + m_e = TS_100MS; + } else if (value == 1e-2) { + m_e = TS_10MS; + } else if (value == 1e-3) { + m_e = TS_1MS; + } else if (value == 1e-4) { + m_e = TS_100US; + } else if (value == 1e-5) { + m_e = TS_10US; + } else if (value == 1e-6) { + m_e = TS_1US; + } else if (value == 1e-7) { + m_e = TS_100NS; + } else if (value == 1e-8) { + m_e = TS_10NS; + } else if (value == 1e-9) { + m_e = TS_1NS; + } else if (value == 1e-10) { + m_e = TS_100PS; + } else if (value == 1e-11) { + m_e = TS_10PS; + } else if (value == 1e-12) { + m_e = TS_1PS; + } else if (value == 1e-13) { + m_e = TS_100FS; + } else if (value == 1e-14) { + m_e = TS_10FS; + } else if (value == 1e-15) { + m_e = TS_1FS; + } else { m_e = NONE; badr = true; } @@ -127,13 +144,15 @@ public: bool allowEmpty = false); const char* ascii() const { static const char* const names[] - = {"1s", "100ms", "10ms", "1ms", "100us", "10us", "1us", "100ns", "10ns", - "1ns", "100ps", "10ps", "1ps", "100fs", "10fs", "1fs", "NONE"}; + = {"100s", "10s", "1s", "100ms", "10ms", "1ms", "100us", "10us", "1us", "100ns", + "10ns", "1ns", "100ps", "10ps", "1ps", "100fs", "10fs", "1fs", "NONE"}; return names[m_e]; } + int powerOfTen() const { return 2 - static_cast(m_e); } double multiplier() const { - static double values[] = {1, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8, - 1e-9, 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 0}; + static const double values[] + = {100, 10, 1, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, + 1e-8, 1e-9, 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 0}; return values[m_e]; } }; @@ -261,7 +280,6 @@ private: bool m_threadsDpiUnpure; // main switch: --threads-dpi all bool m_trace; // main switch: --trace bool m_traceCoverage; // main switch: --trace-coverage - bool m_traceDups; // main switch: --trace-dups bool m_traceParams; // main switch: --trace-params bool m_traceStructs; // main switch: --trace-structs bool m_traceUnderscore;// main switch: --trace-underscore @@ -274,6 +292,7 @@ private: int m_buildJobs; // main switch: -j int m_convergeLimit;// main switch: --converge-limit int m_dumpTree; // main switch: --dump-tree + bool m_dumpTreeAddrids;// main switch: --dump-tree-addrids int m_gateStmts; // main switch: --gate-stmts int m_ifDepth; // main switch: --if-depth int m_inlineMult; // main switch: --inline-mult @@ -315,6 +334,7 @@ private: string m_protectLib; // main switch: --protect-lib {lib_name} string m_topModule; // main switch: --top-module string m_unusedRegexp; // main switch: --unused-regexp + string m_waiverOutput; // main switch: --waiver-output {filename} string m_xAssign; // main switch: --x-assign string m_xInitial; // main switch: --x-initial string m_xmlOutput; // main switch: --xml-output @@ -326,17 +346,18 @@ private: // MEMBERS (optimizations) // // main switch: -Op: --public bool m_oAcycSimp; // main switch: -Oy: acyclic pre-optimizations + bool m_oAssemble; // main switch: -Om: assign assemble bool m_oCase; // main switch: -Oe: case tree conversion bool m_oCombine; // main switch: -Ob: common icode packing bool m_oConst; // main switch: -Oc: constant folding bool m_oDedupe; // main switch: -Od: logic deduplication - bool m_oAssemble; // main switch: -Om: assign assemble bool m_oExpand; // main switch: -Ox: expansion of C macros bool m_oGate; // main switch: -Og: gate wire elimination + bool m_oInline; // main switch: -Oi: module inlining bool m_oLife; // main switch: -Ol: variable lifetime bool m_oLifePost; // main switch: -Ot: delayed assignment elimination bool m_oLocalize; // main switch: -Oz: convert temps to local variables - bool m_oInline; // main switch: -Oi: module inlining + bool m_oMergeCond; // main switch: -Ob: merge conditionals bool m_oReloop; // main switch: -Ov: reform loops bool m_oReorder; // main switch: -Or: reorder assignments in blocks bool m_oSplit; // main switch: -Os: always assignment splitting @@ -433,7 +454,6 @@ public: bool threadsCoarsen() const { return m_threadsCoarsen; } bool trace() const { return m_trace; } bool traceCoverage() const { return m_traceCoverage; } - bool traceDups() const { return m_traceDups; } bool traceParams() const { return m_traceParams; } bool traceStructs() const { return m_traceStructs; } bool traceUnderscore() const { return m_traceUnderscore; } @@ -465,6 +485,7 @@ public: int buildJobs() const { return m_buildJobs; } int convergeLimit() const { return m_convergeLimit; } int dumpTree() const { return m_dumpTree; } + bool dumpTreeAddrids() const { return m_dumpTreeAddrids; } int gateStmts() const { return m_gateStmts; } int ifDepth() const { return m_ifDepth; } int inlineMult() const { return m_inlineMult; } @@ -520,6 +541,8 @@ public: } string topModule() const { return m_topModule; } string unusedRegexp() const { return m_unusedRegexp; } + string waiverOutput() const { return m_waiverOutput; } + bool isWaiverOutput() const { return !m_waiverOutput.empty(); } string xAssign() const { return m_xAssign; } string xInitial() const { return m_xInitial; } string xmlOutput() const { return m_xmlOutput; } @@ -544,18 +567,18 @@ public: // ACCESSORS (optimization options) bool oAcycSimp() const { return m_oAcycSimp; } + bool oAssemble() const { return m_oAssemble; } bool oCase() const { return m_oCase; } bool oCombine() const { return m_oCombine; } bool oConst() const { return m_oConst; } bool oDedupe() const { return m_oDedupe; } - bool oAssemble() const { return m_oAssemble; } bool oExpand() const { return m_oExpand; } bool oGate() const { return m_oGate; } - bool oDup() const { return oLife(); } + bool oInline() const { return m_oInline; } bool oLife() const { return m_oLife; } bool oLifePost() const { return m_oLifePost; } bool oLocalize() const { return m_oLocalize; } - bool oInline() const { return m_oInline; } + bool oMergeCond() const { return m_oMergeCond; } bool oReloop() const { return m_oReloop; } bool oReorder() const { return m_oReorder; } bool oSplit() const { return m_oSplit; } @@ -591,6 +614,8 @@ public: static string getenvSYSTEMC_INCLUDE(); static string getenvSYSTEMC_LIBDIR(); static string getenvVERILATOR_ROOT(); + static bool systemCSystemWide(); + static bool systemCFound(); // SystemC installed, or environment points to it // METHODS (file utilities using these options) string fileExists(const string& filename); diff --git a/src/V3Order.cpp b/src/V3Order.cpp index b57678bee..eb8b9a593 100644 --- a/src/V3Order.cpp +++ b/src/V3Order.cpp @@ -94,7 +94,6 @@ #include "V3OrderGraph.h" #include -#include #include #include #include @@ -104,8 +103,6 @@ #include VL_INCLUDE_UNORDERED_MAP #include VL_INCLUDE_UNORDERED_SET -class OrderMoveDomScope; - static bool domainsExclusive(const AstSenTree* fromp, const AstSenTree* top); //###################################################################### @@ -666,9 +663,7 @@ private: SenTreeFinder m_finder; // Find global sentree's and add them AstSenTree* m_comboDomainp; // Combo activation tree AstSenTree* m_deleteDomainp; // Delete this from tree - AstSenTree* m_settleDomainp; // Initial activation tree OrderInputsVertex* m_inputsVxp; // Top level vertex all inputs point from - OrderSettleVertex* m_settleVxp; // Top level vertex all settlement vertexes point from OrderLogicVertex* m_logicVxp; // Current statement being tracked, NULL=ignored AstTopScope* m_topScopep; // Current top scope being processed AstScope* m_scopetopp; // Scope under TOPSCOPE @@ -816,7 +811,8 @@ private: nodep->v3warn(UNOPT, "Signal unoptimizable: Feedback to public clock or circular logic: " << nodep->prettyNameQ()); - if (!nodep->fileline()->warnIsOff(V3ErrorCode::UNOPT)) { + if (!nodep->fileline()->warnIsOff(V3ErrorCode::UNOPT) + && !nodep->fileline()->lastWarnWaived()) { nodep->fileline()->modifyWarnOff(V3ErrorCode::UNOPT, true); // Complain just once // Give the user an example. @@ -834,7 +830,8 @@ private: nodep->v3warn(UNOPTFLAT, "Signal unoptimizable: Feedback to clock or circular logic: " << nodep->prettyNameQ()); - if (!nodep->fileline()->warnIsOff(V3ErrorCode::UNOPTFLAT)) { + if (!nodep->fileline()->warnIsOff(V3ErrorCode::UNOPTFLAT) + && !nodep->fileline()->lastWarnWaived()) { nodep->fileline()->modifyWarnOff(V3ErrorCode::UNOPTFLAT, true); // Complain just once // Give the user an example. @@ -975,13 +972,8 @@ private: AstSenTree* combp = new AstSenTree(nodep->fileline(), // Gets cloned() so ok if goes out of scope new AstSenItem(nodep->fileline(), AstSenItem::Combo())); - m_comboDomainp = m_finder.getSenTree(nodep->fileline(), combp); + m_comboDomainp = m_finder.getSenTree(combp); pushDeletep(combp); // Cleanup when done - AstSenTree* settlep - = new AstSenTree(nodep->fileline(), // Gets cloned() so ok if goes out of scope - new AstSenItem(nodep->fileline(), AstSenItem::Settle())); - m_settleDomainp = m_finder.getSenTree(nodep->fileline(), settlep); - pushDeletep(settlep); // Cleanup when done // Fake AstSenTree we set domainp to indicate needs deletion m_deleteDomainp = new AstSenTree(nodep->fileline(), new AstSenItem(nodep->fileline(), AstSenItem::Settle())); @@ -1241,8 +1233,6 @@ public: m_inPre = m_inPost = false; m_comboDomainp = NULL; m_deleteDomainp = NULL; - m_settleDomainp = NULL; - m_settleVxp = NULL; m_inputsVxp = NULL; m_activeSenVxp = NULL; m_logicVxp = NULL; @@ -1352,7 +1342,7 @@ void OrderVisitor::processInputs() { void OrderVisitor::processInputsInIterate(OrderEitherVertex* vertexp, VertexVec& todoVec) { // Propagate PrimaryIn through simple assignments if (vertexp->user()) return; // Already processed - if (0 && debug() >= 9) { + if (false && debug() >= 9) { UINFO(9, " InIIter " << vertexp << endl); if (OrderLogicVertex* vvertexp = dynamic_cast(vertexp)) { vvertexp->nodep()->dumpTree(cout, "- TT: "); @@ -1530,14 +1520,16 @@ void OrderVisitor::processDomainsIterate(OrderEitherVertex* vertexp) { } else if (domainp != fromVertexp->domainp()) { // Make a domain that merges the two domains bool ddebug = debug() >= 9; - if (ddebug) { + + if (ddebug) { // LCOV_EXCL_START + cout << endl; UINFO(0, " conflicting domain " << fromVertexp << endl); UINFO(0, " dorig=" << domainp << endl); domainp->dumpTree(cout); UINFO(0, " d2 =" << fromVertexp->domainp() << endl); fromVertexp->domainp()->dumpTree(cout); - } + } // LCOV_EXCL_STOP AstSenTree* newtreep = domainp->cloneTree(false); AstNodeSenItem* newtree2p = fromVertexp->domainp()->sensesp()->cloneTree(true); UASSERT_OBJ(newtree2p, fromVertexp->domainp(), @@ -1546,14 +1538,14 @@ void OrderVisitor::processDomainsIterate(OrderEitherVertex* vertexp) { newtree2p = NULL; // Below edit may replace it V3Const::constifyExpensiveEdit(newtreep); // Remove duplicates newtreep->multi(true); // Comment that it was made from 2 clock domains - domainp = m_finder.getSenTree(domainp->fileline(), newtreep); - if (ddebug) { + domainp = m_finder.getSenTree(newtreep); + if (ddebug) { // LCOV_EXCL_START UINFO(0, " dnew =" << newtreep << endl); newtreep->dumpTree(cout); UINFO(0, " find =" << domainp << endl); domainp->dumpTree(cout); cout << endl; - } + } // LCOV_EXCL_STOP VL_DO_DANGLING(newtreep->deleteTree(), newtreep); } } @@ -2019,7 +2011,7 @@ void OrderVisitor::process() { // Dump data m_graph.dumpDotFilePrefixed("orderg_done"); - if (0 && debug()) { + if (false && debug()) { string dfilename = v3Global.opt.makeDir() + "/" + v3Global.opt.prefix() + "_INT_order"; const vl_unique_ptr logp(V3File::new_ofstream(dfilename)); if (logp->fail()) v3fatal("Can't write " << dfilename); diff --git a/src/V3OrderGraph.h b/src/V3OrderGraph.h index 8816d4898..fc81aaf44 100644 --- a/src/V3OrderGraph.h +++ b/src/V3OrderGraph.h @@ -20,7 +20,6 @@ // MTaskMoveVertex // OrderEitherVertex // OrderInputsVertex -// OrderSettleVertex // OrderLogicVertex // OrderVarVertex // OrderVarStdVertex @@ -57,7 +56,6 @@ class OrderMoveDomScope; enum OrderWeights { WEIGHT_INPUT = 1, // Low weight just so dot graph looks nice WEIGHT_COMBO = 1, // Breakable combo logic - WEIGHT_LOOPBE = 1, // Connection to loop begin/end WEIGHT_POST = 2, // Post-delayed used var WEIGHT_PRE = 3, // Breakable pre-delayed used var WEIGHT_MEDIUM = 8, // Medium weight just so dot graph looks nice @@ -68,7 +66,6 @@ struct OrderVEdgeType { enum en { VERTEX_UNKNOWN = 0, VERTEX_INPUTS, - VERTEX_SETTLE, VERTEX_LOGIC, VERTEX_VARSTD, VERTEX_VARPRE, @@ -77,7 +74,6 @@ struct OrderVEdgeType { VERTEX_VARSETTLE, VERTEX_MOVE, EDGE_STD, - EDGE_CHANGEDET, EDGE_COMBOCUT, EDGE_PRECUT, EDGE_POSTCUT, @@ -85,10 +81,10 @@ struct OrderVEdgeType { }; const char* ascii() const { static const char* const names[] - = {"%E-vedge", "VERTEX_INPUTS", "VERTEX_SETTLE", "VERTEX_LOGIC", - "VERTEX_VARSTD", "VERTEX_VARPRE", "VERTEX_VARPOST", "VERTEX_VARPORD", - "VERTEX_VARSETTLE", "VERTEX_MOVE", "EDGE_STD", "EDGE_CHANGEDET", - "EDGE_COMBOCUT", "EDGE_PRECUT", "EDGE_POSTCUT", "_ENUM_END"}; + = {"%E-vedge", "VERTEX_INPUTS", "VERTEX_LOGIC", "VERTEX_VARSTD", + "VERTEX_VARPRE", "VERTEX_VARPOST", "VERTEX_VARPORD", "VERTEX_VARSETTLE", + "VERTEX_MOVE", "EDGE_STD", "EDGE_COMBOCUT", "EDGE_PRECUT", + "EDGE_POSTCUT", "_ENUM_END"}; return names[m_e]; } enum en m_e; @@ -122,15 +118,6 @@ public: virtual void loopsVertexCb(V3GraphVertex* vertexp); }; -//! Graph for UNOPTFLAT loops -class UnoptflatGraph : public OrderGraph { -public: - UnoptflatGraph() {} - virtual ~UnoptflatGraph() {} - // Methods - virtual void loopsVertexCb(V3GraphVertex* vertexp); -}; - //###################################################################### // Vertex types @@ -185,24 +172,6 @@ public: virtual bool domainMatters() { return false; } }; -class OrderSettleVertex : public OrderEitherVertex { - OrderSettleVertex(V3Graph* graphp, const OrderSettleVertex& old) - : OrderEitherVertex(graphp, old) {} - -public: - OrderSettleVertex(V3Graph* graphp, AstSenTree* domainp) - : OrderEitherVertex(graphp, NULL, domainp) {} - virtual ~OrderSettleVertex() {} - virtual OrderSettleVertex* clone(V3Graph* graphp) const { - return new OrderSettleVertex(graphp, *this); - } - virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_SETTLE; } - virtual string name() const { return "*SETTLE*"; } - virtual string dotColor() const { return "green"; } - virtual string dotName() const { return ""; } - virtual bool domainMatters() { return true; } -}; - class OrderLogicVertex : public OrderEitherVertex { AstNode* m_nodep; @@ -386,12 +355,12 @@ public: } virtual string name() const { string nm; - if (logicp()) { + if (VL_UNCOVERABLE(!logicp())) { // Avoid crash when debugging + nm = "nul"; // LCOV_EXCL_LINE + } else { nm = logicp()->name(); nm += (string("\\nMV:") + " d=" + cvtToHex(logicp()->domainp()) + " s=" + cvtToHex(logicp()->scopep())); - } else { - nm = "nul"; } return nm; } @@ -422,7 +391,6 @@ class MTaskMoveVertex : public V3GraphVertex { protected: friend class OrderVisitor; - friend class MTaskMoveVertexMaker; public: MTaskMoveVertex(V3Graph* graphp, OrderLogicVertex* logicp, const OrderEitherVertex* varp, @@ -487,17 +455,11 @@ public: // When ordering combo blocks with stronglyConnected, follow edges not // involving pre/pos variables virtual bool followComboConnected() const { return true; } - virtual bool followSequentConnected() const { return true; } static bool followComboConnected(const V3GraphEdge* edgep) { const OrderEdge* oedgep = dynamic_cast(edgep); if (!oedgep) v3fatalSrc("Following edge of non-OrderEdge type"); return (oedgep->followComboConnected()); } - static bool followSequentConnected(const V3GraphEdge* edgep) { - const OrderEdge* oedgep = dynamic_cast(edgep); - if (!oedgep) v3fatalSrc("Following edge of non-OrderEdge type"); - return (oedgep->followSequentConnected()); - } }; class OrderComboCutEdge : public OrderEdge { @@ -519,7 +481,6 @@ public: } virtual string dotColor() const { return "yellowGreen"; } virtual bool followComboConnected() const { return true; } - virtual bool followSequentConnected() const { return true; } }; class OrderPostCutEdge : public OrderEdge { @@ -541,7 +502,6 @@ public: } virtual string dotColor() const { return "PaleGreen"; } virtual bool followComboConnected() const { return false; } - virtual bool followSequentConnected() const { return true; } }; class OrderPreCutEdge : public OrderEdge { @@ -563,7 +523,6 @@ public: virtual ~OrderPreCutEdge() {} virtual string dotColor() const { return "khaki"; } virtual bool followComboConnected() const { return false; } - virtual bool followSequentConnected() const { return false; } }; #endif // Guard diff --git a/src/V3Os.cpp b/src/V3Os.cpp index 6fb2b9088..8d0d07546 100644 --- a/src/V3Os.cpp +++ b/src/V3Os.cpp @@ -29,17 +29,13 @@ #include "verilatedos.h" // Limited V3 headers here - this is a base class for Vlc etc -#include "V3Global.h" #include "V3String.h" #include "V3Os.h" #include -#include #include #include -#include #include -#include #include #include #include @@ -54,6 +50,7 @@ # include #else # include +# include // Needed on FreeBSD for WIFEXITED # include // usleep #endif // clang-format on @@ -64,8 +61,9 @@ string V3Os::getenvStr(const string& envvar, const string& defaultValue) { #if defined(_MSC_VER) // Note: MinGW does not offer _dupenv_s - char* envvalue; - if (_dupenv_s(&envvalue, nullptr, envvar.c_str()) == 0) { + char* envvalue = nullptr; + _dupenv_s(&envvalue, nullptr, envvar.c_str()); + if (envvalue != nullptr) { const std::string result{envvalue}; free(envvalue); return result; @@ -242,8 +240,6 @@ void V3Os::unlinkRegexp(const string& dir, const string& regexp) { } } -std::string V3Os::getcwd() { return filenameRealPath("."); } - //###################################################################### // METHODS (random) @@ -269,8 +265,8 @@ string V3Os::trueRandom(size_t size) { std::ifstream is("/dev/urandom", std::ios::in | std::ios::binary); // This read uses the size of the buffer. // Flawfinder: ignore - if (!is.read(data, size)) { - v3fatal("Could not open /dev/urandom, no source of randomness. " + if (VL_UNCOVERABLE(!is.read(data, size))) { + v3fatal("Could not open /dev/urandom, no source of randomness. " // LCOV_EXCL_LINE "Try specifying a key instead."); } #endif @@ -313,15 +309,12 @@ uint64_t V3Os::memUsageBytes() { FILE* fp = fopen(statmFilename, "r"); if (!fp) return 0; vluint64_t size, resident, share, text, lib, data, dt; // All in pages - if (7 - != fscanf(fp, - "%" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 - "u %" VL_PRI64 "u %" VL_PRI64 "u", - &size, &resident, &share, &text, &lib, &data, &dt)) { - fclose(fp); - return 0; - } + int items = fscanf(fp, + "%" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 "u %" VL_PRI64 + "u %" VL_PRI64 "u %" VL_PRI64 "u", + &size, &resident, &share, &text, &lib, &data, &dt); fclose(fp); + if (VL_UNCOVERABLE(7 != items)) return 0; return (text + data) * getpagesize(); #endif } @@ -342,9 +335,10 @@ void V3Os::u_sleep(int64_t usec) { int V3Os::system(const string& command) { UINFO(1, "Running system: " << command << endl); const int ret = ::system(command.c_str()); - if (ret == -1) { - v3fatal("Failed to execute command:" << command << " " << strerror(errno)); - return -1; + if (VL_UNCOVERABLE(ret == -1)) { + v3fatal("Failed to execute command:" // LCOV_EXCL_LINE + << command << " " << strerror(errno)); + return -1; // LCOV_EXCL_LINE } else { UASSERT(WIFEXITED(ret), "system(" << command << ") returned unexpected value of " << ret); const int exit_code = WEXITSTATUS(ret); diff --git a/src/V3Os.h b/src/V3Os.h index 8e511257d..a107f36dc 100644 --- a/src/V3Os.h +++ b/src/V3Os.h @@ -53,7 +53,6 @@ public: // METHODS (directory utilities) static void createDir(const string& dirname); static void unlinkRegexp(const string& dir, const string& regexp); - static std::string getcwd(); // Return the current working directory // METHODS (random) static vluint64_t rand64(vluint64_t* statep); diff --git a/src/V3Param.cpp b/src/V3Param.cpp index d50433cdd..64e14916a 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -56,7 +56,6 @@ #include "V3Unroll.h" #include "V3Hashed.h" -#include #include #include #include @@ -301,7 +300,8 @@ private: << " (IEEE 1800-2017 6.20.1): " << nodep->prettyNameQ()); } else { V3Const::constifyParamsEdit(nodep); // The variable, not just the var->init() - if (!VN_IS(nodep->valuep(), Const)) { // Complex init, like an array + if (!VN_IS(nodep->valuep(), Const) + && !VN_IS(nodep->valuep(), Unbounded)) { // Complex init, like an array // Make a new INITIAL to set the value. // This allows the normal array/struct handling code to properly // initialize the parameter. @@ -409,11 +409,9 @@ private: string index = AstNode::encodeNumber(constp->toSInt()); string replacestr = nodep->name() + "__BRA__??__KET__"; size_t pos = m_unlinkedTxt.find(replacestr); - if (pos == string::npos) { - nodep->v3error("Could not find array index in unlinked text: '" - << m_unlinkedTxt << "' for node: " << nodep); - return; - } + UASSERT_OBJ(pos != string::npos, nodep, + "Could not find array index in unlinked text: '" + << m_unlinkedTxt << "' for node: " << nodep); m_unlinkedTxt.replace(pos, replacestr.length(), nodep->name() + "__BRA__" + index + "__KET__"); } else { @@ -485,7 +483,7 @@ private: m_generateHierName = rootHierName; } } - virtual void visit(AstGenFor* nodep) VL_OVERRIDE { + virtual void visit(AstGenFor* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE nodep->v3fatalSrc("GENFOR should have been wrapped in BEGIN"); } virtual void visit(AstGenCase* nodep) VL_OVERRIDE { diff --git a/src/V3ParseGrammar.cpp b/src/V3ParseGrammar.cpp index 9385ef4b1..bfe861e5a 100644 --- a/src/V3ParseGrammar.cpp +++ b/src/V3ParseGrammar.cpp @@ -65,15 +65,20 @@ void V3ParseImp::parserClear() { //====================================================================== // V3ParseGrammar functions requiring bison state -void V3ParseGrammar::argWrapList(AstNodeFTaskRef* nodep) { +AstNode* V3ParseGrammar::argWrapList(AstNode* nodep) { // Convert list of expressions to list of arguments + if (!nodep) return NULL; AstNode* outp = NULL; - while (nodep->pinsp()) { - AstNode* exprp = nodep->pinsp()->unlinkFrBack(); + AstBegin* tempp = new AstBegin(nodep->fileline(), "[EditWrapper]", nodep); + while (nodep) { + AstNode* nextp = nodep->nextp(); + AstNode* exprp = nodep->unlinkFrBack(); + nodep = nextp; // addNext can handle nulls: outp = AstNode::addNext(outp, new AstArg(exprp->fileline(), "", exprp)); } - if (outp) nodep->addPinsp(outp); + VL_DO_DANGLING(tempp->deleteTree(), tempp); + return outp; } AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, const string& name, int value) { diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index be019ff31..d095e5234 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -34,8 +34,6 @@ #include "V3PreShell.h" #include "V3LanguageWords.h" -#include -#include #include //====================================================================== @@ -166,8 +164,8 @@ void V3ParseImp::errorPreprocDirective(const char* textp) { // Find all `preprocessor spelling candidates // Can't make this static as might get more defines later when read cells VSpellCheck speller; - V3LanguageWords words; - for (V3LanguageWords::const_iterator it = words.begin(); it != words.end(); ++it) { + for (V3LanguageWords::const_iterator it = V3LanguageWords::begin(); + it != V3LanguageWords::end(); ++it) { string ppDirective = it->first; if (ppDirective[0] == '`') speller.pushCandidate(ppDirective); } diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 975ddaebe..3441cc1c4 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -227,12 +227,11 @@ public: // Interactions with lexer void lexNew(); void lexDestroy(); - void statePop(); // Parser -> lexer communication static int stateVerilogRecent(); // Parser -> lexer communication - int prevLexToken() { return m_prevLexToken; } // Parser -> lexer communication + int prevLexToken() const { return m_prevLexToken; } // Parser -> lexer communication size_t flexPpInputToLex(char* buf, size_t max_size) { return ppInputToLex(buf, max_size); } - const V3ParseBisonYYSType curBisonVal() const { return m_curBisonVal; } - const V3ParseBisonYYSType prevBisonVal() const { return m_prevBisonVal; } + V3ParseBisonYYSType curBisonVal() const { return m_curBisonVal; } + V3ParseBisonYYSType prevBisonVal() const { return m_prevBisonVal; } //==== Symbol tables V3ParseSym* symp() { return m_symp; } diff --git a/src/V3ParseLex.cpp b/src/V3ParseLex.cpp index 7f5895d93..14100969a 100644 --- a/src/V3ParseLex.cpp +++ b/src/V3ParseLex.cpp @@ -17,12 +17,8 @@ #include "config_build.h" #include "verilatedos.h" -#include "V3Error.h" -#include "V3Global.h" -#include "V3File.h" #include "V3ParseImp.h" -#include #include //====================================================================== @@ -43,7 +39,6 @@ public: : V3LexerBase(NULL) {} ~V3Lexer() {} // METHODS - void statePop() { yy_pop_state(); } void unputString(const char* textp, size_t length) { // Add characters to input stream in back-to-front order const char* cp = textp; @@ -51,8 +46,6 @@ public: } }; -void V3ParseImp::statePop() { parsep()->m_lexerp->statePop(); } - void V3ParseImp::unputString(const char* textp, size_t length) { parsep()->m_lexerp->unputString(textp, length); } diff --git a/src/V3ParseSym.h b/src/V3ParseSym.h index d8c39b7d7..dbe9bebc5 100644 --- a/src/V3ParseSym.h +++ b/src/V3ParseSym.h @@ -129,7 +129,7 @@ public: UINFO(1, "ParseSym Current: " << symCurrentp()->nodep() << endl); } void dump(std::ostream& os, const string& indent = "") { m_syms.dump(os, indent); } - AstNode* findEntUpward(const string& name) { + AstNode* findEntUpward(const string& name) const { // Lookup the given string as an identifier, return type of the id, scanning upward VSymEnt* foundp = symCurrentp()->findIdFallback(name); if (foundp) { diff --git a/src/V3Partition.cpp b/src/V3Partition.cpp index 11edc49dd..aca9696c1 100644 --- a/src/V3Partition.cpp +++ b/src/V3Partition.cpp @@ -20,7 +20,6 @@ #include "V3Os.h" #include "V3File.h" #include "V3GraphAlg.h" -#include "V3GraphPathChecker.h" #include "V3GraphStream.h" #include "V3InstrCount.h" #include "V3Partition.h" @@ -330,7 +329,7 @@ private: } void go() { // Generate a pseudo-random graph - vluint64_t rngState[2] = {VL_ULL(0x12345678), VL_ULL(0x9abcdef0)}; + vluint64_t rngState[2] = {0x12345678ULL, 0x9abcdef0ULL}; // Create 50 vertices for (unsigned i = 0; i < 50; ++i) m_vx[i] = new V3GraphVertex(&m_graph); // Create 250 edges at random. Edges must go from diff --git a/src/V3PreLex.h b/src/V3PreLex.h index 95cc114b1..71e684412 100644 --- a/src/V3PreLex.h +++ b/src/V3PreLex.h @@ -18,8 +18,8 @@ // It is not intended for user applications. //************************************************************************* -#ifndef _VPREPROCLEX_H_ // Guard -#define _VPREPROCLEX_H_ 1 +#ifndef _VPRELEX_H_ // Guard +#define _VPRELEX_H_ 1 #include "V3Error.h" #include "V3FileLine.h" diff --git a/src/V3PreLex.l b/src/V3PreLex.l index 443a199f7..4647f81e4 100644 --- a/src/V3PreLex.l +++ b/src/V3PreLex.l @@ -32,7 +32,7 @@ V3PreLex* V3PreLex::s_currentLexp = NULL; // Current lexing point #define LEXP V3PreLex::s_currentLexp #define YY_INPUT(buf,result,max_size) \ - result = LEXP->inputToLex(buf, max_size); + do { result = LEXP->inputToLex(buf, max_size); } while (false) // Accessors, because flex keeps changing the type of yyleng char* yyourtext() { return yytext; } @@ -41,9 +41,9 @@ void yyourtext(const char* textp, size_t size) { yytext=(char*)textp; yyleng=siz // FL_FWD only tracks columns; preproc uses linenoInc() to track lines, so // insertion of a \n does not mess up line count -#define FL_FWDC { LEXP->curFilelinep()->forwardToken(yytext, yyleng, false); } +#define FL_FWDC (LEXP->curFilelinep()->forwardToken(yytext, yyleng, false)) // Use this to break between tokens whereever not return'ing a token (e.g. skipping inside lexer) -#define FL_BRK { LEXP->curFilelinep()->startToken(); } +#define FL_BRK (LEXP->curFilelinep()->startToken()) // Prevent conflicts from perl version static void linenoInc() {LEXP->linenoInc();} diff --git a/src/V3PreProc.cpp b/src/V3PreProc.cpp index 466d3b209..de42e8c02 100644 --- a/src/V3PreProc.cpp +++ b/src/V3PreProc.cpp @@ -26,7 +26,6 @@ #include "V3PreShell.h" #include "V3String.h" -#include #include #include #include @@ -141,7 +140,7 @@ public: ps_STRIFY }; static const char* procStateName(ProcState s) { - static const char* states[] + static const char* const states[] = {"ps_TOP", "ps_DEFNAME_UNDEF", "ps_DEFNAME_DEFINE", "ps_DEFNAME_IFDEF", "ps_DEFNAME_IFNDEF", "ps_DEFNAME_ELSIF", "ps_DEFFORM", "ps_DEFVALUE", "ps_DEFPAREN", @@ -287,9 +286,9 @@ public: m_finFilelinep->lineno(1); // Create lexer m_lexp = new V3PreLex(this, filelinep); - m_lexp->m_keepComments = m_preprocp->keepComments(); - m_lexp->m_keepWhitespace = m_preprocp->keepWhitespace(); - m_lexp->m_pedantic = m_preprocp->pedantic(); + m_lexp->m_keepComments = keepComments(); + m_lexp->m_keepWhitespace = keepWhitespace(); + m_lexp->m_pedantic = pedantic(); m_lexp->debug(debug() >= 5 ? debug() : 0); // See also V3PreProc::debug() method } ~V3PreProcImp() { @@ -549,7 +548,7 @@ void V3PreProcImp::unputString(const string& strg) { // However this can lead to "flex scanner push-back overflow" // so instead we scan from a temporary buffer, then on EOF return. // This is also faster than the old scheme, amazingly. - if (m_lexp->m_bufferState != m_lexp->currentBuffer()) { + if (VL_UNCOVERABLE(m_lexp->m_bufferState != m_lexp->currentBuffer())) { fatalSrc("bufferStack missing current buffer; will return incorrectly"); // Hard to debug lost text as won't know till much later } @@ -1087,7 +1086,7 @@ int V3PreProcImp::getStateToken() { stateChange(ps_DEFFORM); m_lexp->pushStateDefForm(); goto next_tok; - } else { + } else { // LCOV_EXCL_LINE fatalSrc("Bad case\n"); } goto next_tok; @@ -1174,7 +1173,9 @@ int V3PreProcImp::getStateToken() { stateChange(ps_DEFARG); goto next_tok; } else { - if (m_defRefs.empty()) fatalSrc("Shouldn't be in DEFPAREN w/o active defref"); + if (VL_UNCOVERABLE(m_defRefs.empty())) { + fatalSrc("Shouldn't be in DEFPAREN w/o active defref"); + } VDefineRef* refp = &(m_defRefs.top()); error(string("Expecting ( to begin argument list for define reference `") + refp->name() + "\n"); @@ -1183,7 +1184,9 @@ int V3PreProcImp::getStateToken() { } } case ps_DEFARG: { - if (m_defRefs.empty()) fatalSrc("Shouldn't be in DEFARG w/o active defref"); + if (VL_UNCOVERABLE(m_defRefs.empty())) { + fatalSrc("Shouldn't be in DEFARG w/o active defref"); + } VDefineRef* refp = &(m_defRefs.top()); refp->nextarg(refp->nextarg() + m_lexp->m_defValue); m_lexp->m_defValue = ""; @@ -1208,7 +1211,9 @@ int V3PreProcImp::getStateToken() { statePop(); if (state() == ps_JOIN) { // Handle {left}```FOO(ARG) where `FOO(ARG) might be empty - if (m_joinStack.empty()) fatalSrc("`` join stack empty, but in a ``"); + if (VL_UNCOVERABLE(m_joinStack.empty())) { + fatalSrc("`` join stack empty, but in a ``"); + } string lhs = m_joinStack.top(); m_joinStack.pop(); out.insert(0, lhs); @@ -1295,7 +1300,9 @@ int V3PreProcImp::getStateToken() { } case ps_JOIN: { if (tok == VP_SYMBOL || tok == VP_TEXT) { - if (m_joinStack.empty()) fatalSrc("`` join stack empty, but in a ``"); + if (VL_UNCOVERABLE(m_joinStack.empty())) { + fatalSrc("`` join stack empty, but in a ``"); + } string lhs = m_joinStack.top(); m_joinStack.pop(); UINFO(5, "`` LHS:" << lhs << endl); @@ -1429,7 +1436,9 @@ int V3PreProcImp::getStateToken() { if (m_defRefs.empty()) { // Just output the substitution if (state() == ps_JOIN) { // Handle {left}```FOO where `FOO might be empty - if (m_joinStack.empty()) fatalSrc("`` join stack empty, but in a ``"); + if (VL_UNCOVERABLE(m_joinStack.empty())) { + fatalSrc("`` join stack empty, but in a ``"); + } string lhs = m_joinStack.top(); m_joinStack.pop(); out.insert(0, lhs); @@ -1500,9 +1509,9 @@ int V3PreProcImp::getStateToken() { case VP_COMMENT: // Handled at top of loop case VP_DEFFORM: // Handled by state=ps_DEFFORM; case VP_DEFVALUE: // Handled by state=ps_DEFVALUE; - default: + default: // LCOV_EXCL_LINE fatalSrc(string("Internal error: Unexpected token ") + tokenName(tok) + "\n"); - break; + break; // LCOV_EXCL_LINE } return tok; } @@ -1518,7 +1527,7 @@ int V3PreProcImp::getFinalToken(string& buf) { } int tok = m_finToken; buf = m_finBuf; - if (0 && debug() >= 5) { + if (false && debug() >= 5) { string bufcln = V3PreLex::cleanDbgStrg(buf); string flcol = m_lexp->m_tokFilelinep->asciiLineCol(); fprintf(stderr, "%s: FIN: %-10s: %s\n", flcol.c_str(), tokenName(tok), diff --git a/src/V3PreProc.h b/src/V3PreProc.h index 4bed3ae54..de2d02215 100644 --- a/src/V3PreProc.h +++ b/src/V3PreProc.h @@ -103,7 +103,7 @@ protected: public: static V3PreProc* createPreProc(FileLine* fl); - virtual ~V3PreProc() {} + virtual ~V3PreProc() {} // LCOV_EXCL_LINE // Persistent }; #endif // Guard diff --git a/src/V3PreShell.cpp b/src/V3PreShell.cpp index 714f2ac22..2695051a4 100644 --- a/src/V3PreShell.cpp +++ b/src/V3PreShell.cpp @@ -25,10 +25,7 @@ #include "V3Os.h" #include -#include #include -#include -#include //###################################################################### diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index e4271defa..2b75eafa6 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -32,8 +32,6 @@ #include "V3Ast.h" #include -#include -#include //###################################################################### // Structure for global state diff --git a/src/V3ProtectLib.cpp b/src/V3ProtectLib.cpp index 6a2aac6e9..c04726c8b 100644 --- a/src/V3ProtectLib.cpp +++ b/src/V3ProtectLib.cpp @@ -20,7 +20,6 @@ #include "V3Global.h" #include "V3String.h" #include "V3ProtectLib.h" -#include "V3File.h" #include "V3Hashed.h" #include "V3Task.h" @@ -261,7 +260,7 @@ private: void castPtr(FileLine* fl, AstTextBlock* txtp) { txtp->addText(fl, m_topName - + "_container* handlep__V = " + + "_container* handlep__V = " // LCOV_EXCL_LINE // lcov bug "static_cast<" + m_topName + "_container*>(vhandlep__V);\n"); } diff --git a/src/V3Reloop.cpp b/src/V3Reloop.cpp index 350aa2dd2..05b090a72 100644 --- a/src/V3Reloop.cpp +++ b/src/V3Reloop.cpp @@ -38,7 +38,6 @@ #include "V3Ast.h" #include -#include #define RELOOP_MIN_ITERS 40 // Need at least this many loops to do this optimization diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index 4ce1a1485..755ed82e2 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -29,8 +29,6 @@ #include "V3Ast.h" #include -#include -#include #include #include VL_INCLUDE_UNORDERED_MAP #include VL_INCLUDE_UNORDERED_SET @@ -189,21 +187,13 @@ private: virtual void visit(AstCellInline* nodep) VL_OVERRIDE { // nodep->scopep(m_scopep); } - virtual void visit(AstActive* nodep) VL_OVERRIDE { + virtual void visit(AstActive* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE nodep->v3fatalSrc("Actives now made after scoping"); } - virtual void visit(AstInitial* nodep) VL_OVERRIDE { + virtual void visit(AstNodeProcedure* nodep) VL_OVERRIDE { // Add to list of blocks under this scope UINFO(4, " Move " << nodep << endl); - AstInitial* clonep = nodep->cloneTree(false); - nodep->user2p(clonep); - m_scopep->addActivep(clonep); - iterateChildren(clonep); // We iterate under the *clone* - } - virtual void visit(AstFinal* nodep) VL_OVERRIDE { - // Add to list of blocks under this scope - UINFO(4, " Move " << nodep << endl); - AstFinal* clonep = nodep->cloneTree(false); + AstNode* clonep = nodep->cloneTree(false); nodep->user2p(clonep); m_scopep->addActivep(clonep); iterateChildren(clonep); // We iterate under the *clone* @@ -232,14 +222,6 @@ private: m_scopep->addActivep(clonep); iterateChildren(clonep); // We iterate under the *clone* } - virtual void visit(AstAlways* nodep) VL_OVERRIDE { - // Add to list of blocks under this scope - UINFO(4, " Move " << nodep << endl); - AstNode* clonep = nodep->cloneTree(false); - nodep->user2p(clonep); - m_scopep->addActivep(clonep); - iterateChildren(clonep); // We iterate under the *clone* - } virtual void visit(AstAlwaysPublic* nodep) VL_OVERRIDE { // Add to list of blocks under this scope UINFO(4, " Move " << nodep << endl); @@ -380,12 +362,10 @@ private: } } - virtual void visit(AstInitial* nodep) VL_OVERRIDE { movedDeleteOrIterate(nodep); } - virtual void visit(AstFinal* nodep) VL_OVERRIDE { movedDeleteOrIterate(nodep); } + virtual void visit(AstNodeProcedure* nodep) VL_OVERRIDE { movedDeleteOrIterate(nodep); } virtual void visit(AstAssignAlias* nodep) VL_OVERRIDE { movedDeleteOrIterate(nodep); } virtual void visit(AstAssignVarScope* nodep) VL_OVERRIDE { movedDeleteOrIterate(nodep); } virtual void visit(AstAssignW* nodep) VL_OVERRIDE { movedDeleteOrIterate(nodep); } - virtual void visit(AstAlways* nodep) VL_OVERRIDE { movedDeleteOrIterate(nodep); } virtual void visit(AstAlwaysPublic* nodep) VL_OVERRIDE { movedDeleteOrIterate(nodep); } virtual void visit(AstCoverToggle* nodep) VL_OVERRIDE { movedDeleteOrIterate(nodep); } virtual void visit(AstNodeFTask* nodep) VL_OVERRIDE { movedDeleteOrIterate(nodep); } diff --git a/src/V3Scoreboard.h b/src/V3Scoreboard.h index 84621b775..3936d831b 100644 --- a/src/V3Scoreboard.h +++ b/src/V3Scoreboard.h @@ -125,7 +125,7 @@ public: // No more values but it's not defined to decrement an // iterator past the beginning. v3fatalSrc("Decremented iterator past beginning"); - return; + return; // LCOV_EXCL_LINE } --m_valIt; // Should find a value here, as Every value bucket is supposed @@ -292,7 +292,7 @@ public: typename Key2Val::iterator kvit = m_keys.find(k); if (kvit != m_keys.end()) { if (kvit->second == v) { - return; // Same value already present; stop. + return; // LCOV_EXCL_LINE // Same value already present; stop. } // Must remove element from m_vals[oldValue] removeKeyFromOldVal(k, kvit->second); diff --git a/src/V3SenTree.h b/src/V3SenTree.h index 50002f7d4..deca31018 100644 --- a/src/V3SenTree.h +++ b/src/V3SenTree.h @@ -128,7 +128,7 @@ public: m_topscopep = NULL; m_trees.clear(); } - AstSenTree* getSenTree(FileLine* fl, AstSenTree* sensesp) { + AstSenTree* getSenTree(AstSenTree* sensesp) { // Return a global sentree that matches given sense list. AstSenTree* treep = m_trees.find(sensesp); // Not found, form a new one diff --git a/src/V3Simulate.h b/src/V3Simulate.h index ac14e601f..d7cedc099 100644 --- a/src/V3Simulate.h +++ b/src/V3Simulate.h @@ -350,7 +350,7 @@ private: } } - AstNode* varOrScope(AstVarRef* nodep) { + AstNode* varOrScope(AstVarRef* nodep) const { AstNode* vscp; if (m_scoped) { vscp = nodep->varScopep(); @@ -508,7 +508,7 @@ private: iterateAndNextNull(valuep); if (optimizable()) newValue(nodep, fetchValue(valuep)); } else { - clearOptimizable(nodep, "No value found for enum item"); + clearOptimizable(nodep, "No value found for enum item"); // LCOV_EXCL_LINE } } } @@ -539,6 +539,17 @@ private: fetchConst(nodep->thsp())->num()); } } + virtual void visit(AstNodeQuadop* nodep) VL_OVERRIDE { + if (!optimizable()) return; // Accelerate + checkNodeInfo(nodep); + iterateChildren(nodep); + if (!m_checkOnly && optimizable()) { + nodep->numberOperate(newConst(nodep)->num(), fetchConst(nodep->lhsp())->num(), + fetchConst(nodep->rhsp())->num(), + fetchConst(nodep->thsp())->num(), + fetchConst(nodep->fhsp())->num()); + } + } virtual void visit(AstLogAnd* nodep) VL_OVERRIDE { // Need to short circuit if (!optimizable()) return; // Accelerate @@ -818,6 +829,10 @@ private: virtual void visit(AstComment*) VL_OVERRIDE {} + virtual void visit(AstJumpBlock* nodep) VL_OVERRIDE { + if (jumpingOver(nodep)) return; + iterateChildren(nodep); + } virtual void visit(AstJumpGo* nodep) VL_OVERRIDE { if (jumpingOver(nodep)) return; checkNodeInfo(nodep); @@ -827,6 +842,8 @@ private: } } virtual void visit(AstJumpLabel* nodep) VL_OVERRIDE { + // This only supports forward jumps. That's all we make at present, + // AstJumpGo::broken uses brokeExistsBelow() to check this. if (jumpingOver(nodep)) return; checkNodeInfo(nodep); iterateChildren(nodep); @@ -1002,7 +1019,7 @@ private: } else { // Format character inPct = false; - if (V3Number::displayedFmtLegal(tolower(pos[0]))) { + if (V3Number::displayedFmtLegal(tolower(pos[0]), false)) { AstNode* argp = nextArgp; nextArgp = nextArgp->nextp(); AstConst* constp = fetchConstNull(argp); diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index c77a28bef..2c41c1db6 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -42,8 +42,6 @@ #include "V3Slice.h" #include "V3Ast.h" -#include - //************************************************************************* class SliceVisitor : public AstNVisitor { @@ -130,10 +128,7 @@ class SliceVisitor : public AstNVisitor { if (!nodep->user1() && !VN_IS(nodep, AssignAlias)) { nodep->user1(true); m_assignError = false; - if (debug() >= 9) { - cout << endl; - nodep->dumpTree(cout, " Deslice-In: "); - } + if (debug() >= 9) nodep->dumpTree(cout, " Deslice-In: "); AstNodeDType* dtp = nodep->lhsp()->dtypep()->skipRefp(); if (AstUnpackArrayDType* arrayp = VN_CAST(dtp, UnpackArrayDType)) { // Left and right could have different msb/lsbs/endianness, but #elements is common @@ -148,10 +143,7 @@ class SliceVisitor : public AstNVisitor { if (debug() >= 9) { newp->dumpTree(cout, "-new "); } newlistp = AstNode::addNextNull(newlistp, newp); } - if (debug() >= 9) { - cout << endl; - nodep->dumpTree(cout, " Deslice-Dn: "); - } + if (debug() >= 9) nodep->dumpTree(cout, " Deslice-Dn: "); nodep->replaceWith(newlistp); VL_DO_DANGLING(nodep->deleteTree(), nodep); // Normal edit iterator will now iterate on all of the expansion assignments diff --git a/src/V3Split.cpp b/src/V3Split.cpp index 6e69257d3..bca88e300 100644 --- a/src/V3Split.cpp +++ b/src/V3Split.cpp @@ -87,7 +87,6 @@ #include "V3Graph.h" #include -#include #include #include #include VL_INCLUDE_UNORDERED_MAP diff --git a/src/V3SplitAs.cpp b/src/V3SplitAs.cpp index d600cc819..3aa5a4c2a 100644 --- a/src/V3SplitAs.cpp +++ b/src/V3SplitAs.cpp @@ -29,10 +29,7 @@ #include "V3Stats.h" #include "V3Ast.h" -#include -#include #include -#include //###################################################################### diff --git a/src/V3SplitVar.cpp b/src/V3SplitVar.cpp index f051ed1c8..5cc78823a 100644 --- a/src/V3SplitVar.cpp +++ b/src/V3SplitVar.cpp @@ -114,7 +114,6 @@ #include "verilatedos.h" #include "V3Ast.h" -#include "V3Const.h" #include "V3Global.h" #include "V3SplitVar.h" #include "V3Stats.h" @@ -475,7 +474,7 @@ class SplitUnpackedVarVisitor : public AstNVisitor, public SplitVarImpl { UINFO(4, "Skip " << nodep->prettyNameQ() << "\n"); return; } - UASSERT_OBJ(!m_modp, m_modp, "Nested module declration"); + UASSERT_OBJ(!m_modp, m_modp, "Nested module declaration"); UASSERT_OBJ(m_refs.empty(), nodep, "The last module didn't finish split()"); m_modp = nodep; iterateChildren(nodep); @@ -990,7 +989,7 @@ class SplitPackedVarVisitor : public AstNVisitor, public SplitVarImpl { // key:variable to be split. value:location where the variable is referenced. vl_unordered_map m_refs; virtual void visit(AstNodeModule* nodep) VL_OVERRIDE { - UASSERT_OBJ(m_modp == NULL, m_modp, "Nested module declration"); + UASSERT_OBJ(m_modp == NULL, m_modp, "Nested module declaration"); if (!VN_IS(nodep, Module)) { UINFO(5, "Skip " << nodep->prettyNameQ() << "\n"); return; @@ -1275,7 +1274,7 @@ public: reason = "it is not an aggregate type of bit nor logic"; if (!reason) reason = cannotSplitVarCommonReason(nodep); } else { - reason = "its type is unknown"; + reason = "its type is unknown"; // LCOV_EXCL_LINE } if (reason) UINFO(5, diff --git a/src/V3Stats.cpp b/src/V3Stats.cpp index c63488f13..c5d8e1d8c 100644 --- a/src/V3Stats.cpp +++ b/src/V3Stats.cpp @@ -20,12 +20,10 @@ #include "V3Global.h" #include "V3Stats.h" #include "V3Ast.h" -#include "V3File.h" // This visitor does not edit nodes, and is called at error-exit, so should use constant iterators #include "V3AstConstOnly.h" -#include #include #include @@ -45,7 +43,6 @@ private: bool m_fast; AstCFunc* m_cfuncp; // Current CFUNC - VDouble0 m_statInstrLong; // Instruction count bool m_counting; // Currently counting double m_instrs; // Current instr count (for determining branch direction) bool m_tracingCall; // Iterating into a CCall to a CFunc diff --git a/src/V3Stats.h b/src/V3Stats.h index b383f21da..e43ee539a 100644 --- a/src/V3Stats.h +++ b/src/V3Stats.h @@ -36,29 +36,29 @@ public: ~VDouble0() {} // Implicit conversion operators: - inline explicit VDouble0(const vluint64_t v) + explicit VDouble0(const vluint64_t v) : m_d(v) {} - inline operator double() const { return m_d; } + operator double() const { return m_d; } // Explicit operators: - inline VDouble0& operator++() { // prefix + VDouble0& operator++() { // prefix ++m_d; return *this; } - inline VDouble0 operator++(int) { // postfix + VDouble0 operator++(int) { // postfix VDouble0 old = *this; m_d++; return old; } - inline VDouble0& operator=(const double v) { + VDouble0& operator=(const double v) { m_d = v; return *this; } - inline VDouble0& operator+=(const double v) { + VDouble0& operator+=(const double v) { m_d += v; return *this; } - inline VDouble0& operator-=(const double v) { + VDouble0& operator-=(const double v) { m_d -= v; return *this; } diff --git a/src/V3StatsReport.cpp b/src/V3StatsReport.cpp index 6ce36bf70..107d1d08d 100644 --- a/src/V3StatsReport.cpp +++ b/src/V3StatsReport.cpp @@ -23,7 +23,6 @@ #include "V3File.h" #include "V3Os.h" -#include #include #include #include VL_INCLUDE_UNORDERED_MAP diff --git a/src/V3String.cpp b/src/V3String.cpp index 70c0f8a80..3433306a6 100644 --- a/src/V3String.cpp +++ b/src/V3String.cpp @@ -66,10 +66,6 @@ bool VString::wildmatch(const string& s, const string& p) { return wildmatch(s.c_str(), p.c_str()); } -bool VString::isWildcard(const string& p) { - return ((p.find('*') != string::npos) || (p.find('?') != string::npos)); -} - string VString::dot(const string& a, const string& dot, const string& b) { if (b == "") return a; if (a == "") return b; diff --git a/src/V3String.h b/src/V3String.h index 1d22a7f08..50a725dbd 100644 --- a/src/V3String.h +++ b/src/V3String.h @@ -74,8 +74,6 @@ public: static bool wildmatch(const char* s, const char* p); // Return true if p with ? or *'s matches s static bool wildmatch(const string& s, const string& p); - // Return true if this is a wildcard string (contains * or ?) - static bool isWildcard(const string& p); // Return {a}{dot}{b}, omitting dot if a or b are empty static string dot(const string& a, const string& dot, const string& b); // Convert string to lowercase (tolower) diff --git a/src/V3Subst.cpp b/src/V3Subst.cpp index f79964434..d86f50864 100644 --- a/src/V3Subst.cpp +++ b/src/V3Subst.cpp @@ -27,12 +27,10 @@ #include "V3Global.h" #include "V3Subst.h" -#include "V3Const.h" #include "V3Stats.h" #include "V3Ast.h" #include -#include #include //###################################################################### diff --git a/src/V3SymTable.h b/src/V3SymTable.h index 7a2b54331..10dd2f439 100644 --- a/src/V3SymTable.h +++ b/src/V3SymTable.h @@ -14,8 +14,8 @@ // //************************************************************************* -#ifndef _V3LINKSYMTABLE_H_ -#define _V3LINKSYMTABLE_H_ 1 +#ifndef _V3SYMTABLE_H_ +#define _V3SYMTABLE_H_ 1 #include "config_build.h" #include "verilatedos.h" @@ -36,7 +36,6 @@ class VSymEnt; //###################################################################### // Symbol table -typedef std::set VSymMap; typedef std::set VSymConstMap; class VSymEnt { @@ -74,8 +73,8 @@ public: if (m_symPrefix != "") os << " symPrefix=" << m_symPrefix; os << " n=" << nodep(); os << endl; - if (doneSymsr.find(this) != doneSymsr.end()) { - os << indent << "| ^ duplicate, so no children printed\n"; + if (VL_UNCOVERABLE(doneSymsr.find(this) != doneSymsr.end())) { + os << indent << "| ^ duplicate, so no children printed\n"; // LCOV_EXCL_LINE } else { doneSymsr.insert(this); for (IdNameMap::const_iterator it = m_idNameMap.begin(); it != m_idNameMap.end(); @@ -190,7 +189,7 @@ private: reinsert(name, symp); } } - void exportOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) { + void exportOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) const { if (srcp->exported()) { if (VSymEnt* symp = findIdFlat(name)) { // Should already exist in current table if (!symp->exported()) symp->exported(true); @@ -284,7 +283,6 @@ public: for (SymStack::iterator it = m_symsp.begin(); it != m_symsp.end(); ++it) delete (*it); } -public: // METHODS VSymEnt* rootp() const { return m_symRootp; } // Debug diff --git a/src/V3TSP.cpp b/src/V3TSP.cpp index 57f22c16e..617653c0e 100644 --- a/src/V3TSP.cpp +++ b/src/V3TSP.cpp @@ -28,17 +28,12 @@ #include "V3Graph.h" #include "V3TSP.h" -#include #include -#include -#include #include -#include #include #include #include #include -#include #include #include VL_INCLUDE_UNORDERED_SET #include VL_INCLUDE_UNORDERED_MAP diff --git a/src/V3Table.cpp b/src/V3Table.cpp index 9c1754e57..43eeef696 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -31,7 +31,6 @@ #include "V3Ast.h" #include -#include #include //###################################################################### diff --git a/src/V3Task.cpp b/src/V3Task.cpp index bdb75e68d..30ef04ec9 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -29,13 +29,11 @@ #include "V3Global.h" #include "V3Const.h" #include "V3Task.h" -#include "V3Inst.h" #include "V3Ast.h" #include "V3EmitCBase.h" #include "V3Graph.h" #include "V3LinkLValue.h" -#include #include //###################################################################### @@ -875,12 +873,17 @@ private: if (args != "") args += ", "; if (portp->isDpiOpenArray()) { + AstNodeDType* dtypep = portp->dtypep()->skipRefp(); + if (VN_IS(dtypep, DynArrayDType) || VN_IS(dtypep, QueueDType)) { + v3fatalSrc("Passing dynamic array or queue as actual argument to DPI " + "open array is not yet supported"); + } + // Ideally we'd make a table of variable // characteristics, and reuse it wherever we can // At least put them into the module's CTOR as static? string propName = portp->name() + "__Vopenprops"; - string propCode = ("static const VerilatedVarProps " + propName + "(" - + portp->vlPropInit() + ");\n"); + string propCode = portp->vlPropDecl(propName); cfuncp->addStmtsp(new AstCStmt(portp->fileline(), propCode)); // // At runtime we need the svOpenArrayHandle to @@ -1330,7 +1333,7 @@ private: // Done the loop m_insStmtp = NULL; // Next thing should be new statement } - virtual void visit(AstNodeFor* nodep) VL_OVERRIDE { + virtual void visit(AstNodeFor* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE nodep->v3fatalSrc( "For statements should have been converted to while statements in V3Begin.cpp"); } @@ -1501,12 +1504,12 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp) } } - if (debug() >= 9) { + if (debug() >= 9) { // LCOV_EXCL_START nodep->dumpTree(cout, "-ftref-out: "); for (int i = 0; i < tpinnum; ++i) { UINFO(0, " pin " << i << " conn=" << cvtToHex(tconnects[i].second) << endl); } - } + } // LCOV_EXCL_STOP return tconnects; } diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index 76e125592..de8e2e50d 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -14,31 +14,24 @@ // //************************************************************************* // V3Trace's Transformations: +// +// Examine whole design and build a graph describing which function call +// may result in a write to a traced variable. This is done in 2 passes: +// // Pass 1: -// For each TRACE -// Add to list of traces, Mark where traces came from, unlink it -// Look for duplicate values; if so, cross reference -// Make vertex for each var it references +// Add vertices for TraceDecl, CFunc, CCall and VarRef nodes, add +// edges from CCall -> CFunc, VarRef -> TraceDecl, also add edges +// for public entry points to CFuncs (these are like a spontaneous +// call) +// // Pass 2: -// Go through _eval; if there's a call on the same flat statement list -// then all functions for that call can get the same activity code. -// Likewise, all _slow functions can get the same code. -// CFUNCs that are public need unique codes, as does _eval +// Add edges from CFunc -> VarRef being written // -// For each CFUNC with unique callReason -// Make vertex -// For each var it sets, make vertex and edge from cfunc vertex -// -// For each CFUNC in graph -// Add ASSIGN(SEL(__Vm_traceActivity,activityNumber++),1) -// Create __Vm_traceActivity vector -// Sort TRACEs by activityNumber(s) they come from (may be more than one) -// Each set of activityNumbers -// Add IF (SEL(__Vm_traceActivity,activityNumber),1) -// Add traces under that activity number. -// Assign trace codes: -// If from a VARSCOPE, record the trace->varscope map -// Else, assign trace codes to each variable +// Finally: +// Process graph to determine when traced variables can change, allocate +// activity flags, insert nodes to set activity flags, allocate signal +// numbers (codes), and construct the full and incremental trace +// functions, together with all other trace support functions. // //************************************************************************* @@ -52,7 +45,6 @@ #include "V3Hashed.h" #include "V3Stats.h" -#include #include #include @@ -60,9 +52,8 @@ // Graph vertexes class TraceActivityVertex : public V3GraphVertex { - AstNode* m_insertp; // Insert before this statement + AstNode* const m_insertp; vlsint32_t m_activityCode; - bool m_activityCodeValid; bool m_slow; // If always slow, we can use the same code public: enum { ACTIVITY_NEVER = ((1UL << 31) - 1) }; @@ -72,14 +63,12 @@ public: : V3GraphVertex(graphp) , m_insertp(nodep) { m_activityCode = 0; - m_activityCodeValid = false; m_slow = slow; } TraceActivityVertex(V3Graph* graphp, vlsint32_t code) : V3GraphVertex(graphp) , m_insertp(NULL) { m_activityCode = code; - m_activityCodeValid = true; m_slow = false; } virtual ~TraceActivityVertex() {} @@ -96,13 +85,10 @@ public: } } virtual string dotColor() const { return slow() ? "yellowGreen" : "green"; } - bool activityCodeValid() const { return m_activityCodeValid; } vlsint32_t activityCode() const { return m_activityCode; } bool activityAlways() const { return activityCode() == ACTIVITY_ALWAYS; } - void activityCode(vlsint32_t code) { - m_activityCode = code; - m_activityCodeValid = true; - } + bool activitySlow() const { return activityCode() == ACTIVITY_SLOW; } + void activityCode(vlsint32_t code) { m_activityCode = code; } bool slow() const { return m_slow; } void slow(bool flag) { if (!flag) m_slow = false; @@ -125,19 +111,19 @@ public: }; class TraceTraceVertex : public V3GraphVertex { - AstTraceInc* m_nodep; // TRACEINC this represents + AstTraceDecl* const m_nodep; // TRACEINC this represents // NULL, or other vertex with the real code() that duplicates this one TraceTraceVertex* m_duplicatep; public: - TraceTraceVertex(V3Graph* graphp, AstTraceInc* nodep) + TraceTraceVertex(V3Graph* graphp, AstTraceDecl* nodep) : V3GraphVertex(graphp) , m_nodep(nodep) , m_duplicatep(NULL) {} virtual ~TraceTraceVertex() {} // ACCESSORS - AstTraceInc* nodep() const { return m_nodep; } - virtual string name() const { return nodep()->declp()->name(); } + AstTraceDecl* nodep() const { return m_nodep; } + virtual string name() const { return nodep()->name(); } virtual string dotColor() const { return "red"; } virtual FileLine* fileline() const { return nodep()->fileline(); } TraceTraceVertex* duplicatep() const { return m_duplicatep; } @@ -172,7 +158,7 @@ private: // Ast*::user4() // V3Hashed calculation // Cleared entire netlist // AstCFunc::user1() // V3GraphVertex* for this node - // AstTraceInc::user1() // V3GraphVertex* for this node + // AstTraceDecl::user1() // V3GraphVertex* for this node // AstVarScope::user1() // V3GraphVertex* for this node // AstCCall::user2() // bool; walked next list for other ccalls // Ast*::user3() // TraceActivityVertex* for this node @@ -183,29 +169,25 @@ private: // STATE AstNodeModule* m_topModp; // Module to add variables to - AstScope* m_highScopep; // Scope to add variables to + AstScope* m_topScopep; // Scope to add variables to AstCFunc* m_funcp; // C function adding to graph - AstTraceInc* m_tracep; // Trace function adding to graph - AstCFunc* m_initFuncp; // Trace function we add statements to - AstCFunc* m_fullFuncp; // Trace function we add statements to - AstCFunc* m_fullSubFuncp; // Trace function we add statements to (under full) - int m_fullSubStmts; // Statements under function being built - AstCFunc* m_chgFuncp; // Trace function we add statements to - AstCFunc* m_chgSubFuncp; // Trace function we add statements to (under full) - AstNode* m_chgSubParentp; // Which node has call to m_chgSubFuncp - int m_chgSubStmts; // Statements under function being built + AstTraceDecl* m_tracep; // Trace function adding to graph AstVarScope* m_activityVscp; // Activity variable uint32_t m_activityNumber; // Count of fields in activity variable uint32_t m_code; // Trace ident code# being assigned V3Graph m_graph; // Var/CFunc tracking - TraceActivityVertex* m_alwaysVtxp; // "Always trace" vertex + TraceActivityVertex* const m_alwaysVtxp; // "Always trace" vertex bool m_finding; // Pass one of algorithm? - int m_funcNum; // Function number being built VDouble0 m_statChgSigs; // Statistic tracking VDouble0 m_statUniqSigs; // Statistic tracking VDouble0 m_statUniqCodes; // Statistic tracking + // All activity numbers applying to a given trace + typedef std::set ActCodeSet; + // For activity set, what traces apply + typedef std::multimap TraceVec; + // METHODS VL_DEBUG_FUNC; // Declare debug() @@ -214,9 +196,11 @@ private: // Note uses user4 V3Hashed hashed; // Duplicate code detection // Hash all of the values the traceIncs need - for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { - if (TraceTraceVertex* vvertexp = dynamic_cast(itp)) { - AstTraceInc* nodep = vvertexp->nodep(); + for (const V3GraphVertex* itp = m_graph.verticesBeginp(); itp; + itp = itp->verticesNextp()) { + if (const TraceTraceVertex* const vvertexp + = dynamic_cast(itp)) { + const AstTraceDecl* const nodep = vvertexp->nodep(); if (nodep->valuep()) { UASSERT_OBJ(nodep->valuep()->backp() == nodep, nodep, "Trace duplicate back needs consistency," @@ -234,18 +218,18 @@ private: } // Find if there are any duplicates for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { - if (TraceTraceVertex* vvertexp = dynamic_cast(itp)) { - AstTraceInc* nodep = vvertexp->nodep(); + if (TraceTraceVertex* const vvertexp = dynamic_cast(itp)) { + AstTraceDecl* const nodep = vvertexp->nodep(); if (nodep->valuep() && !vvertexp->duplicatep()) { V3Hashed::iterator dupit = hashed.findDuplicate(nodep->valuep()); if (dupit != hashed.end()) { - AstTraceInc* dupincp - = VN_CAST(hashed.iteratorNodep(dupit)->backp(), TraceInc); - UASSERT_OBJ(dupincp, nodep, "Trace duplicate of wrong type"); - TraceTraceVertex* dupvertexp - = dynamic_cast(dupincp->user1u().toGraphVertex()); + const AstTraceDecl* const dupDeclp + = VN_CAST_CONST(hashed.iteratorNodep(dupit)->backp(), TraceDecl); + UASSERT_OBJ(dupDeclp, nodep, "Trace duplicate of wrong type"); + TraceTraceVertex* const dupvertexp + = dynamic_cast(dupDeclp->user1u().toGraphVertex()); UINFO(8, " Orig " << nodep << endl); - UINFO(8, " dup " << dupincp << endl); + UINFO(8, " dup " << dupDeclp << endl); // Mark the hashed node as the original and our // iterating node as duplicated vvertexp->duplicatep(dupvertexp); @@ -256,24 +240,27 @@ private: hashed.clear(); } - void graphSimplify() { - // Remove all variable nodes - for (V3GraphVertex *nextp, *itp = m_graph.verticesBeginp(); itp; itp = nextp) { - nextp = itp->verticesNextp(); - if (TraceVarVertex* vvertexp = dynamic_cast(itp)) { - vvertexp->rerouteEdges(&m_graph); - vvertexp->unlinkDelete(&m_graph); + void graphSimplify(bool initial) { + if (initial) { + // Remove all variable nodes + for (V3GraphVertex *nextp, *itp = m_graph.verticesBeginp(); itp; itp = nextp) { + nextp = itp->verticesNextp(); + if (TraceVarVertex* const vvertexp = dynamic_cast(itp)) { + vvertexp->rerouteEdges(&m_graph); + vvertexp->unlinkDelete(&m_graph); + } } - } - // Remove multiple variables connecting funcs to traces - // We do this twice, as then we have fewer edges to multiply out in the below expansion. - m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); - // Remove all Cfunc nodes - for (V3GraphVertex *nextp, *itp = m_graph.verticesBeginp(); itp; itp = nextp) { - nextp = itp->verticesNextp(); - if (TraceCFuncVertex* vvertexp = dynamic_cast(itp)) { - vvertexp->rerouteEdges(&m_graph); - vvertexp->unlinkDelete(&m_graph); + // Remove multiple variables connecting funcs to traces + // We do this twice, as then we have fewer edges to multiply out in the below + // expansion. + m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); + // Remove all Cfunc nodes + for (V3GraphVertex *nextp, *itp = m_graph.verticesBeginp(); itp; itp = nextp) { + nextp = itp->verticesNextp(); + if (TraceCFuncVertex* const vvertexp = dynamic_cast(itp)) { + vvertexp->rerouteEdges(&m_graph); + vvertexp->unlinkDelete(&m_graph); + } } } @@ -281,12 +268,16 @@ private: m_graph.removeRedundantEdges(&V3GraphEdge::followAlwaysTrue); // If there are any edges from a always, keep only the always - for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { - if (TraceTraceVertex* vvertexp = dynamic_cast(itp)) { - V3GraphEdge* alwaysEdgep = NULL; - for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { - TraceActivityVertex* actVtxp - = dynamic_cast(edgep->fromp()); + for (const V3GraphVertex* itp = m_graph.verticesBeginp(); itp; + itp = itp->verticesNextp()) { + if (const TraceTraceVertex* const vvertexp + = dynamic_cast(itp)) { + // Search for the incoming always edge + const V3GraphEdge* alwaysEdgep = NULL; + for (const V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; + edgep = edgep->inNextp()) { + const TraceActivityVertex* const actVtxp + = dynamic_cast(edgep->fromp()); UASSERT_OBJ(actVtxp, vvertexp->nodep(), "Tracing a node with FROM non activity"); if (actVtxp->activityAlways()) { @@ -294,6 +285,7 @@ private: break; } } + // If always edge exists, remove all other edges if (alwaysEdgep) { for (V3GraphEdge *nextp, *edgep = vvertexp->inBeginp(); edgep; edgep = nextp) { nextp = edgep->inNextp(); @@ -306,296 +298,458 @@ private: // Activity points with no outputs can be removed for (V3GraphVertex *nextp, *itp = m_graph.verticesBeginp(); itp; itp = nextp) { nextp = itp->verticesNextp(); - if (TraceActivityVertex* vvertexp = dynamic_cast(itp)) { - if (!vvertexp->outBeginp()) { vvertexp->unlinkDelete(&m_graph); } + if (TraceActivityVertex* const vtxp = dynamic_cast(itp)) { + // Leave in the always vertex for later use. + if (vtxp != m_alwaysVtxp && !vtxp->outBeginp()) { vtxp->unlinkDelete(&m_graph); } } } } - void assignActivity() { - // Select activity numbers and put into each CFunc vertex - m_activityNumber = 1; // Note 0 indicates "slow" + uint32_t assignactivityNumbers() { + uint32_t activityNumber = 1; // Note 0 indicates "slow" only for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { - if (TraceActivityVertex* vvertexp = dynamic_cast(itp)) { - if (!vvertexp->activityCodeValid()) { + if (TraceActivityVertex* const vvertexp = dynamic_cast(itp)) { + if (vvertexp != m_alwaysVtxp) { if (vvertexp->slow()) { - // If all functions in the calls are slow, we'll share the same code. - // This makes us need less activityNumbers and so speeds up the fast path. vvertexp->activityCode(TraceActivityVertex::ACTIVITY_SLOW); } else { - vvertexp->activityCode(m_activityNumber++); + vvertexp->activityCode(activityNumber++); } } } } + return activityNumber; + } - AstVar* newvarp; - if (v3Global.opt.mtasks()) { - // Create a vector of bytes, not bits, for the tracing vector, - // so that we can set them atomically without locking. - // - // TODO: It would be slightly faster to have a bit vector per - // chain of packed MTasks, but we haven't packed the MTasks yet. - // If we support fully threaded tracing in the future, it would - // make sense to improve this at that time. - AstNodeDType* newScalarDtp - = new AstBasicDType(m_chgFuncp->fileline(), VFlagLogicPacked(), 1); - v3Global.rootp()->typeTablep()->addTypesp(newScalarDtp); - AstNodeDType* newArrDtp = new AstUnpackArrayDType( - m_chgFuncp->fileline(), newScalarDtp, - new AstRange(m_chgFuncp->fileline(), VNumRange(m_activityNumber - 1, 0, false))); - v3Global.rootp()->typeTablep()->addTypesp(newArrDtp); - newvarp = new AstVar(m_chgFuncp->fileline(), AstVarType::MODULETEMP, - "__Vm_traceActivity", newArrDtp); - } else { - // For tighter code; round to next word point. - int activityBits = VL_WORDS_I(m_activityNumber) * VL_EDATASIZE; - newvarp = new AstVar(m_chgFuncp->fileline(), AstVarType::MODULETEMP, - "__Vm_traceActivity", VFlagBitPacked(), activityBits); - } - m_topModp->addStmtp(newvarp); - AstVarScope* newvscp = new AstVarScope(newvarp->fileline(), m_highScopep, newvarp); - m_highScopep->addVarp(newvscp); - m_activityVscp = newvscp; - - // Insert activity setter + void sortTraces(TraceVec& traces, uint32_t& nFullCodes, uint32_t& nChgCodes) { + // Populate sort structure + traces.clear(); + nFullCodes = 0; + nChgCodes = 0; for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { - if (TraceActivityVertex* vvertexp = dynamic_cast(itp)) { - if (!vvertexp->activityAlways()) { - FileLine* fl = vvertexp->insertp()->fileline(); - uint32_t acode = vvertexp->activityCode(); - vvertexp->insertp()->addNextHere( - new AstAssign(fl, selectActivity(fl, acode, true), - new AstConst(fl, AstConst::LogicTrue()))); - } - } - } - } - - AstNode* selectActivity(FileLine* flp, uint32_t acode, bool lvalue) { - if (v3Global.opt.mtasks()) { - return new AstArraySel(flp, new AstVarRef(flp, m_activityVscp, lvalue), acode); - } else { - return new AstSel(flp, new AstVarRef(flp, m_activityVscp, lvalue), acode, 1); - } - } - - AstCFunc* newCFunc(AstCFuncType type, const string& name, AstCFunc* basep) { - AstCFunc* funcp = new AstCFunc(basep->fileline(), name, basep->scopep()); - funcp->slow(basep->slow()); - funcp->argTypes(EmitCBaseVisitor::symClassVar() + ", " + v3Global.opt.traceClassBase() - + "* vcdp, uint32_t code"); - funcp->funcType(type); - funcp->symProlog(true); - basep->addNext(funcp); - UINFO(5, " Newfunc " << funcp << endl); - return funcp; - } - AstCFunc* newCFuncSub(AstCFunc* basep, AstNode* callfromp) { - string name = basep->name() + "__" + cvtToStr(++m_funcNum); - AstCFunc* funcp = NULL; - if (basep->funcType() == AstCFuncType::TRACE_FULL) { - funcp = newCFunc(AstCFuncType::TRACE_FULL_SUB, name, basep); - } else if (basep->funcType() == AstCFuncType::TRACE_CHANGE) { - funcp = newCFunc(AstCFuncType::TRACE_CHANGE_SUB, name, basep); - } else { - basep->v3fatalSrc("Strange base function type"); - } - AstCCall* callp = new AstCCall(funcp->fileline(), funcp); - callp->argTypes("vlSymsp, vcdp, code"); - if (VN_IS(callfromp, CFunc)) { - VN_CAST(callfromp, CFunc)->addStmtsp(callp); - } else if (VN_IS(callfromp, If)) { - VN_CAST(callfromp, If)->addIfsp(callp); - } else { - callfromp->v3fatalSrc("Unknown caller node type"); // Where to add it?? - } - return funcp; - } - void addToChgSub(AstNode* underp, AstNode* stmtsp) { - if (!m_chgSubFuncp || (m_chgSubParentp != underp) - || (m_chgSubStmts && v3Global.opt.outputSplitCTrace() - && m_chgSubStmts > v3Global.opt.outputSplitCTrace())) { - m_chgSubFuncp = newCFuncSub(m_chgFuncp, underp); - m_chgSubParentp = underp; - m_chgSubStmts = 0; - } - m_chgSubFuncp->addStmtsp(stmtsp); - m_chgSubStmts += EmitCBaseCounterVisitor(stmtsp).count(); - } - - void putTracesIntoTree() { - // Form a sorted list of the traces we are interested in - UINFO(9, "Making trees\n"); - - typedef std::set ActCodeSet; // All activity numbers applying to a given trace - typedef std::multimap - TraceVec; // For activity set, what traces apply - TraceVec traces; - - // Form sort structure - // If a trace doesn't have activity, it's constant, and we don't - // need to track changes on it. - for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { - if (TraceTraceVertex* vvertexp = dynamic_cast(itp)) { - ActCodeSet actset; - UINFO(9, " Add to sort: " << vvertexp << endl); - if (debug() >= 9) vvertexp->nodep()->dumpTree(cout, "- trnode: "); - for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { - TraceActivityVertex* cfvertexp - = dynamic_cast(edgep->fromp()); - UASSERT_OBJ(cfvertexp, vvertexp->nodep(), + if (TraceTraceVertex* const vtxp = dynamic_cast(itp)) { + ActCodeSet actSet; + UINFO(9, " Add to sort: " << vtxp << endl); + if (debug() >= 9) vtxp->nodep()->dumpTree(cout, "- trnode: "); + for (const V3GraphEdge* edgep = vtxp->inBeginp(); edgep; + edgep = edgep->inNextp()) { + const TraceActivityVertex* const cfvertexp + = dynamic_cast(edgep->fromp()); + UASSERT_OBJ(cfvertexp, vtxp->nodep(), "Should have been function pointing to this trace"); UINFO(9, " Activity: " << cfvertexp << endl); if (cfvertexp->activityAlways()) { // If code 0, we always trace; ignore other codes - actset.clear(); - actset.insert(TraceActivityVertex::ACTIVITY_ALWAYS); - break; + actSet.insert(TraceActivityVertex::ACTIVITY_ALWAYS); } else { - uint32_t acode = cfvertexp->activityCode(); - actset.insert(acode); + actSet.insert(cfvertexp->activityCode()); } } - // If a trace doesn't have activity, it's constant, and we - // don't need to track changes on it. - // We put constants and non-changers last, as then the - // prevvalue vector is more compacted - if (actset.empty()) actset.insert(TraceActivityVertex::ACTIVITY_NEVER); - traces.insert(make_pair(actset, vvertexp)); + UASSERT_OBJ(actSet.count(TraceActivityVertex::ACTIVITY_ALWAYS) == 0 + || actSet.size() == 1, + vtxp->nodep(), "Always active trace has further triggers"); + // Count nodes + if (!vtxp->duplicatep()) { + const uint32_t inc = vtxp->nodep()->codeInc(); + nFullCodes += inc; + if (!actSet.empty()) nChgCodes += inc; + } + if (actSet.empty()) { + // If a trace doesn't have activity, it's constant, and we + // don't need to track changes on it. + actSet.insert(TraceActivityVertex::ACTIVITY_NEVER); + } else if (actSet.count(TraceActivityVertex::ACTIVITY_SLOW) && actSet.size() > 1) { + // If a trace depends on the slow flag as well as other + // flags, remove the dependency on the slow flag. We will + // make slow routines set all activity flags. + actSet.erase(TraceActivityVertex::ACTIVITY_SLOW); + } + traces.insert(make_pair(actSet, vtxp)); + } + } + } + + void graphOptimize() { + // Assign initial activity numbers to activity vertices + assignactivityNumbers(); + + // Sort the traces by activity sets + TraceVec traces; + uint32_t unused1; + uint32_t unused2; + sortTraces(traces, unused1, unused2); + + // For each activity set with only a small number of signals, make those + // signals always traced, as it's cheaper to check a few value changes + // than to test a lot of activity flags + TraceVec::iterator it = traces.begin(); + const TraceVec::iterator end = traces.end(); + while (it != end) { + TraceVec::iterator head = it; + // Approximate the complexity of the value change check + uint32_t complexity = 0; + const ActCodeSet& actSet = it->first; + for (; it != end && it->first == actSet; ++it) { + if (!it->second->duplicatep()) { + uint32_t cost = 0; + AstTraceDecl* const declp = it->second->nodep(); + // The number of comparisons required by tracep->chg* + cost += declp->isWide() ? declp->codeInc() : 1; + // Arrays are traced by element + cost *= declp->arrayRange().ranged() ? declp->arrayRange().elements() : 1; + // Note: Experiments factoring in the size of declp->valuep() + // showed no benefit in tracing speed, even for large trees, + // so we will leve those out for now. + complexity += cost; + } + } + // Leave alone always changing, never changing and signals only set in slow code + if (actSet.count(TraceActivityVertex::ACTIVITY_ALWAYS)) continue; + if (actSet.count(TraceActivityVertex::ACTIVITY_NEVER)) continue; + if (actSet.count(TraceActivityVertex::ACTIVITY_SLOW)) continue; + // If the value comparisons are cheaper to perform than checking the + // activity flags make the signals always traced. Note this cost + // equation is heuristic. + if (complexity <= actSet.size() * 2) { + for (; head != it; ++head) { + new V3GraphEdge(&m_graph, m_alwaysVtxp, head->second, 1); + } } } - // Our keys are now sorted to have same activity number adjacent, - // then by trace order. (Better would be execution order for cache efficiency....) - // Last are constants and non-changers, as then the last value vector is more compact + graphSimplify(false); + } - // Put TRACEs back into the tree - const ActCodeSet* lastactp = NULL; - AstNode* ifnodep = NULL; - for (TraceVec::iterator it = traces.begin(); it != traces.end(); ++it) { - const ActCodeSet& actset = it->first; - TraceTraceVertex* vvertexp = it->second; - UINFO(9, " Done sort: " << vvertexp << endl); - bool needChg = true; - if (actset.find(TraceActivityVertex::ACTIVITY_NEVER) != actset.end()) { - // No activity needed; it's a constant value or only set in initial block - needChg = false; + AstNode* selectActivity(FileLine* flp, uint32_t acode, bool lvalue) { + return new AstArraySel(flp, new AstVarRef(flp, m_activityVscp, lvalue), acode); + } + + void addActivitySetter(AstNode* insertp, uint32_t code) { + FileLine* const fl = insertp->fileline(); + AstAssign* const setterp = new AstAssign(fl, selectActivity(fl, code, true), + new AstConst(fl, AstConst::LogicTrue())); + if (AstCCall* const callp = VN_CAST(insertp, CCall)) { + callp->addNextHere(setterp); + } else if (AstCFunc* const funcp = VN_CAST(insertp, CFunc)) { + funcp->addStmtsp(setterp); + } else { + insertp->v3fatalSrc("Bad trace activity vertex"); + } + } + + void createActivityFlags() { + // Assign final activity numbers + m_activityNumber = assignactivityNumbers(); + + // Create an array of bytes, not a bit vector, as they can be set + // atomically by mtasks, and are cheaper to set (no need for + // read-modify-write on the C type), and the speed of the tracing code + // is the same on largish designs. + FileLine* const flp = m_topScopep->fileline(); + AstNodeDType* const newScalarDtp = new AstBasicDType(flp, VFlagLogicPacked(), 1); + v3Global.rootp()->typeTablep()->addTypesp(newScalarDtp); + AstRange* const newArange = new AstRange(flp, VNumRange(m_activityNumber - 1, 0, false)); + AstNodeDType* const newArrDtp = new AstUnpackArrayDType(flp, newScalarDtp, newArange); + v3Global.rootp()->typeTablep()->addTypesp(newArrDtp); + AstVar* const newvarp + = new AstVar(flp, AstVarType::MODULETEMP, "__Vm_traceActivity", newArrDtp); + m_topModp->addStmtp(newvarp); + AstVarScope* const newvscp = new AstVarScope(flp, m_topScopep, newvarp); + m_topScopep->addVarp(newvscp); + m_activityVscp = newvscp; + + // Insert activity setters + for (const V3GraphVertex* itp = m_graph.verticesBeginp(); itp; + itp = itp->verticesNextp()) { + if (const TraceActivityVertex* const vtxp + = dynamic_cast(itp)) { + if (vtxp->activitySlow()) { + // Just set all flags in slow code as it should be rare. + // This will be rolled up into a loop by V3Reloop. + for (uint32_t code = 0; code < m_activityNumber; ++code) { + addActivitySetter(vtxp->insertp(), code); + } + } else if (!vtxp->activityAlways()) { + addActivitySetter(vtxp->insertp(), vtxp->activityCode()); + } } - AstNode* addp = assignTraceCode(vvertexp, vvertexp->nodep(), needChg); - if (addp) { // Else no activity or duplicate - if (actset.find(TraceActivityVertex::ACTIVITY_NEVER) != actset.end()) { - vvertexp->nodep()->v3fatalSrc( - "If never, needChg=0 and shouldn't need to add."); - } else if (actset.find(TraceActivityVertex::ACTIVITY_ALWAYS) != actset.end()) { - // Must always set it; add to base of function - addToChgSub(m_chgFuncp, addp); - } else if (lastactp && actset == *lastactp && ifnodep) { - // Add to last statement we built - addToChgSub(ifnodep, addp); + } + } + + AstCFunc* newCFunc(AstCFuncType type, AstCFunc* callfromp, AstCFunc* regp, int& funcNump) { + // Create new function + string name; + switch (type) { + case AstCFuncType::TRACE_FULL: name = "traceFullTop"; break; + case AstCFuncType::TRACE_FULL_SUB: name = "traceFullSub"; break; + case AstCFuncType::TRACE_CHANGE: name = "traceChgTop"; break; + case AstCFuncType::TRACE_CHANGE_SUB: name = "traceChgSub"; break; + default: m_topScopep->v3fatalSrc("Bad trace function type"); + } + name += cvtToStr(funcNump++); + FileLine* const flp = m_topScopep->fileline(); + AstCFunc* const funcp = new AstCFunc(flp, name, m_topScopep); + const string argTypes("void* userp, " + v3Global.opt.traceClassBase() + "* tracep"); + funcp->argTypes(argTypes); + funcp->funcType(type); + funcp->slow(type == AstCFuncType::TRACE_FULL || type == AstCFuncType::TRACE_FULL_SUB); + funcp->symProlog(true); + funcp->declPrivate(true); + // Add it to top scope + m_topScopep->addActivep(funcp); + // Add call to new function + if (callfromp) { + AstCCall* callp = new AstCCall(funcp->fileline(), funcp); + callp->argTypes("userp, tracep"); + callfromp->addStmtsp(callp); + } + // Register function + if (regp) { + string registration = "tracep->add"; + if (type == AstCFuncType::TRACE_FULL) { + registration += "Full"; + } else if (type == AstCFuncType::TRACE_CHANGE) { + registration += "Chg"; + } else { + funcp->v3fatalSrc("Don't know how to register this type of function"); + } + registration += "Cb(&" + protect(name) + ", __VlSymsp);\n"; + AstCStmt* const stmtp = new AstCStmt(flp, registration); + regp->addStmtsp(stmtp); + } + // Add global activity check to TRACE_CHANGE functions + if (type == AstCFuncType::TRACE_CHANGE) { + funcp->addInitsp( + new AstCStmt(flp, string("if (VL_UNLIKELY(!vlSymsp->__Vm_activity)) return;\n"))); + } + // Done + UINFO(5, " newCFunc " << funcp << endl); + return funcp; + } + + void createFullTraceFunction(const TraceVec& traces, uint32_t nAllCodes, uint32_t parallelism, + AstCFunc* regFuncp) { + const int splitLimit = v3Global.opt.outputSplitCTrace() ? v3Global.opt.outputSplitCTrace() + : std::numeric_limits::max(); + + int topFuncNum = 0; + int subFuncNum = 0; + TraceVec::const_iterator it = traces.begin(); + while (it != traces.end()) { + AstCFunc* topFuncp = NULL; + AstCFunc* subFuncp = NULL; + int subStmts = 0; + const uint32_t maxCodes = (nAllCodes + parallelism - 1) / parallelism; + uint32_t nCodes = 0; + for (; nCodes < maxCodes && it != traces.end(); ++it) { + const TraceTraceVertex* const vtxp = it->second; + AstTraceDecl* const declp = vtxp->nodep(); + if (const TraceTraceVertex* const canonVtxp = vtxp->duplicatep()) { + // This is a duplicate trace node. We will assign the signal + // number to the canonical node, and emit this as an alias, so + // no need to create a TraceInc node. + AstTraceDecl* const canonDeclp = canonVtxp->nodep(); + UASSERT_OBJ(!canonVtxp->duplicatep(), canonDeclp, + "Canonical node is a duplicate"); + UASSERT_OBJ(canonDeclp->code() != 0, canonDeclp, + "Canonical node should have code assigned already"); + declp->code(canonDeclp->code()); } else { - // Build a new IF statement - FileLine* fl = addp->fileline(); - AstNode* condp = NULL; - for (ActCodeSet::const_iterator csit = actset.begin(); csit != actset.end(); - ++csit) { - uint32_t acode = *csit; - AstNode* selp = selectActivity(fl, acode, false); - if (condp) - condp = new AstOr(fl, condp, selp); - else - condp = selp; - } - AstIf* ifp = new AstIf(fl, condp, NULL, NULL); - ifp->branchPred(VBranchPred::BP_UNLIKELY); - m_chgFuncp->addStmtsp(ifp); - lastactp = &actset; - ifnodep = ifp; + // This is a canonical trace node. Assign signal number and + // add a TraceInc node to the full dump function. + UASSERT_OBJ(declp->code() == 0, declp, + "Canonical node should not have code assigned yet"); + declp->code(m_code); + m_code += declp->codeInc(); + m_statUniqCodes += declp->codeInc(); + ++m_statUniqSigs; - addToChgSub(ifnodep, addp); + // Create top function if not yet created + if (!topFuncp) { + topFuncp = newCFunc(AstCFuncType::TRACE_FULL, NULL, regFuncp, topFuncNum); + } + + // Crate new sub function if required + if (!subFuncp || subStmts > splitLimit) { + subStmts = 0; + subFuncp + = newCFunc(AstCFuncType::TRACE_FULL_SUB, topFuncp, NULL, subFuncNum); + } + + // Add TraceInc node + AstTraceInc* const incp = new AstTraceInc(declp->fileline(), declp, true); + subFuncp->addStmtsp(incp); + subStmts += EmitCBaseCounterVisitor(incp).count(); + + // Track partitioning + nCodes += declp->codeInc(); } } - } - - // Set in initializer - - // Clear activity after tracing completes - FileLine* fl = m_chgFuncp->fileline(); - if (v3Global.opt.mtasks()) { - for (uint32_t i = 0; i < m_activityNumber; ++i) { - AstNode* clrp = new AstAssign(fl, selectActivity(fl, i, true), - new AstConst(fl, AstConst::LogicFalse())); - m_fullFuncp->addFinalsp(clrp->cloneTree(true)); - m_chgFuncp->addFinalsp(clrp); + if (topFuncp) { // might be NULL if all trailing entries were duplicates + UINFO(5, "traceFullTop" << topFuncNum - 1 << " codes: " << nCodes << "/" + << maxCodes << endl); } - } else { - AstNode* clrp = new AstAssign( - fl, new AstVarRef(fl, m_activityVscp, true), - new AstConst(fl, AstConst::WidthedValue(), m_activityVscp->width(), 0)); - m_fullFuncp->addFinalsp(clrp->cloneTree(true)); - m_chgFuncp->addFinalsp(clrp); } } - uint32_t assignDeclCode(AstTraceDecl* nodep) { - if (!nodep->code()) { - nodep->code(m_code); - m_code += nodep->codeInc(); - m_statUniqCodes += nodep->codeInc(); - ++m_statUniqSigs; + void createChgTraceFunctions(const TraceVec& traces, uint32_t nAllCodes, uint32_t parallelism, + AstCFunc* regFuncp) { + const int splitLimit = v3Global.opt.outputSplitCTrace() ? v3Global.opt.outputSplitCTrace() + : std::numeric_limits::max(); + int topFuncNum = 0; + int subFuncNum = 0; + TraceVec::const_iterator it = traces.begin(); + while (it != traces.end()) { + AstCFunc* topFuncp = NULL; + AstCFunc* subFuncp = NULL; + int subStmts = 0; + const uint32_t maxCodes = (nAllCodes + parallelism - 1) / parallelism; + uint32_t nCodes = 0; + const ActCodeSet* prevActSet = NULL; + AstIf* ifp = NULL; + for (; nCodes < maxCodes && it != traces.end(); ++it) { + const TraceTraceVertex* const vtxp = it->second; + // This is a duplicate decl, no need to add it to incremental dump + if (vtxp->duplicatep()) continue; + const ActCodeSet& actSet = it->first; + // Traced value never changes, no need to add it to incremental dump + if (actSet.count(TraceActivityVertex::ACTIVITY_NEVER)) continue; + + // Create top function if not yet created + if (!topFuncp) { + topFuncp = newCFunc(AstCFuncType::TRACE_CHANGE, NULL, regFuncp, topFuncNum); + } + + // Crate new sub function if required + if (!subFuncp || subStmts > splitLimit) { + subStmts = 0; + subFuncp + = newCFunc(AstCFuncType::TRACE_CHANGE_SUB, topFuncp, NULL, subFuncNum); + prevActSet = NULL; + ifp = NULL; + } + + // If required, create the conditional node checking the activity flags + if (!prevActSet || actSet != *prevActSet) { + FileLine* const flp = m_topScopep->fileline(); + bool always = actSet.count(TraceActivityVertex::ACTIVITY_ALWAYS) != 0; + AstNode* condp = NULL; + if (always) { + condp = new AstConst(flp, 1); // Always true, will be folded later + } else { + for (ActCodeSet::iterator it = actSet.begin(); it != actSet.end(); ++it) { + const uint32_t actCode = *it; + AstNode* const selp = selectActivity(flp, actCode, false); + condp = condp ? new AstOr(flp, condp, selp) : selp; + } + } + ifp = new AstIf(flp, condp, NULL, NULL); + if (!always) { ifp->branchPred(VBranchPred::BP_UNLIKELY); } + subFuncp->addStmtsp(ifp); + subStmts += EmitCBaseCounterVisitor(ifp).count(); + prevActSet = &actSet; + } + + // Add TraceInc node + AstTraceDecl* const declp = vtxp->nodep(); + AstTraceInc* const incp = new AstTraceInc(declp->fileline(), declp, false); + ifp->addIfsp(incp); + subStmts += EmitCBaseCounterVisitor(incp).count(); + + // Track partitioning + nCodes += declp->codeInc(); + } + if (topFuncp) { // might be NULL if all trailing entries were duplicates/constants + UINFO(5, "traceChgTop" << topFuncNum - 1 << " codes: " << nCodes << "/" << maxCodes + << endl); + } } - return nodep->code(); } - AstNode* assignTraceCode(TraceTraceVertex* vvertexp, AstTraceInc* nodep, bool needChg) { - // Assign trace code, add to tree, return node for change tree or null - // Look for identical copies - uint32_t codePreassigned = 0; - // if (debug() >= 9) nodep->dumpTree(cout, "- assnnode: "); - // Find non-duplicated node; note some nodep's maybe null, as they were deleted below - TraceTraceVertex* dupvertexp = vvertexp; - if (dupvertexp->duplicatep()) { - dupvertexp = dupvertexp->duplicatep(); - UINFO(9, " dupOf " << cvtToHex(dupvertexp) << " " << cvtToHex(dupvertexp->nodep()) - << " " << dupvertexp << endl); - UASSERT_OBJ(!dupvertexp->duplicatep(), dupvertexp->nodep(), - "Original node was marked as a duplicate"); + void createCleanupFunction(AstCFunc* regFuncp) { + FileLine* const fl = m_topScopep->fileline(); + AstCFunc* const cleanupFuncp = new AstCFunc(fl, "traceCleanup", m_topScopep); + const string argTypes("void* userp, " + v3Global.opt.traceClassBase() + "* /*unused*/"); + cleanupFuncp->argTypes(argTypes); + cleanupFuncp->funcType(AstCFuncType::TRACE_CLEANUP); + cleanupFuncp->slow(false); + cleanupFuncp->symProlog(true); + cleanupFuncp->declPrivate(true); + m_topScopep->addActivep(cleanupFuncp); + + // Register it + regFuncp->addStmtsp(new AstCStmt( + fl, string("tracep->addCleanupCb(&" + protect("traceCleanup") + ", __VlSymsp);\n"))); + + // Clear global activity flag + cleanupFuncp->addStmtsp( + new AstCStmt(m_topScopep->fileline(), string("vlSymsp->__Vm_activity = false;\n"))); + + // Clear fine grained activity flags + for (uint32_t i = 0; i < m_activityNumber; ++i) { + AstNode* const clrp = new AstAssign(fl, selectActivity(fl, i, true), + new AstConst(fl, AstConst::LogicFalse())); + cleanupFuncp->addStmtsp(clrp); + } + } + + void createTraceFunctions() { + // Detect and remove duplicate values + detectDuplicates(); + + // Simplify & optimize the graph + if (debug() >= 6) m_graph.dumpDotFilePrefixed("trace_pre"); + graphSimplify(true); + if (debug() >= 6) m_graph.dumpDotFilePrefixed("trace_simplified"); + graphOptimize(); + if (debug() >= 6) m_graph.dumpDotFilePrefixed("trace_optimized"); + + // Create the fine grained activity flags + createActivityFlags(); + + // Form a sorted list of the traces we are interested in + TraceVec traces; // The sorted traces + // We will split functions such that each have to dump roughly the same amount of data + // for this we need to keep tack of the number of codes used by the trace functions. + uint32_t nFullCodes = 0; // Number of non-duplicate codes (need to go into full* dump) + uint32_t nChgCodes = 0; // Number of non-consant codes (need to go in to chg* dump) + sortTraces(traces, nFullCodes, nChgCodes); + + UINFO(5, "nFullCodes: " << nFullCodes << " nChgCodes: " << nChgCodes << endl); + + // Our keys are now sorted to have same activity number adjacent, then + // by trace order. (Better would be execution order for cache + // efficiency....) Last are constants and non-changers, as then the + // last value vector is more compact + + // Create the trace registration function + AstCFunc* const regFuncp + = new AstCFunc(m_topScopep->fileline(), "traceRegister", m_topScopep); + regFuncp->argTypes(v3Global.opt.traceClassBase() + "* tracep"); + regFuncp->funcType(AstCFuncType::TRACE_REGISTER); + regFuncp->slow(true); + regFuncp->isStatic(false); + regFuncp->declPrivate(true); + m_topScopep->addActivep(regFuncp); + + const int parallelism = 1; // Note: will bump this later, code below works for any value + + // Create the full dump functions, also allocates signal numbers + createFullTraceFunction(traces, nFullCodes, parallelism, regFuncp); + + // Create the incremental dump functions + createChgTraceFunctions(traces, nChgCodes, parallelism, regFuncp); + + // Remove refs to traced values from TraceDecl nodes, these have now moved under + // TraceInc + for (TraceVec::iterator it = traces.begin(); it != traces.end(); ++it) { + AstNode* const valuep = it->second->nodep()->valuep(); + valuep->unlinkFrBack(); + valuep->deleteTree(); } - if (dupvertexp != vvertexp) { - // It's an exact copy. We'll assign the code to the master on - // the first one we hit; the later ones will share the code. - codePreassigned = assignDeclCode(dupvertexp->nodep()->declp()); - nodep->declp()->code(codePreassigned); - } else { - assignDeclCode(nodep->declp()); - } - UINFO(8, " Created code=" << nodep->declp()->code() << " " - << (codePreassigned ? "[PREASS]" : "") << " " - << (needChg ? "[CHG]" : "") << " " << nodep << endl); - - AstNode* incAddp = NULL; - if (!codePreassigned) { - // Add to trace cfuncs - if (needChg) { - ++m_statChgSigs; - incAddp = nodep->cloneTree(true); - } - - if (!m_fullSubFuncp - || (m_fullSubStmts && v3Global.opt.outputSplitCTrace() - && m_fullSubStmts > v3Global.opt.outputSplitCTrace())) { - m_fullSubFuncp = newCFuncSub(m_fullFuncp, m_fullFuncp); - m_fullSubStmts = 0; - } - - m_fullSubFuncp->addStmtsp(nodep); - m_fullSubStmts += EmitCBaseCounterVisitor(nodep).count(); - } else { - // Duplicates don't need a TraceInc - VL_DO_DANGLING(pushDeletep(nodep), nodep); - } - return incAddp; + // Create the trace cleanup function clearing the activity flags + createCleanupFunction(regFuncp); } TraceCFuncVertex* getCFuncVertexp(AstCFunc* nodep) { @@ -623,38 +777,25 @@ private: m_code = 1; // Multiple TopScopes will require fixing how code#s // are assigned as duplicate varscopes must result in the same tracing code#. - // Make a always vertex - m_alwaysVtxp = new TraceActivityVertex(&m_graph, TraceActivityVertex::ACTIVITY_ALWAYS); - - // Add vertexes for all TRACES, and edges from VARs each trace looks at + // Add vertexes for all TraceDecl, and edges from VARs each trace looks at m_finding = false; iterateChildren(nodep); // Add vertexes for all CFUNCs, and edges to VARs the func sets m_finding = true; iterateChildren(nodep); - m_finding = false; - // Detect and remove duplicate values - detectDuplicates(); - - // Simplify it - if (debug() >= 6) m_graph.dumpDotFilePrefixed("trace_pre"); - graphSimplify(); - if (debug() >= 6) m_graph.dumpDotFilePrefixed("trace_opt"); - - // Create new TRACEINCs - assignActivity(); - putTracesIntoTree(); + // Create the trace functions and insert them into the tree + createTraceFunctions(); } virtual void visit(AstNodeModule* nodep) VL_OVERRIDE { if (nodep->isTop()) m_topModp = nodep; iterateChildren(nodep); } virtual void visit(AstTopScope* nodep) VL_OVERRIDE { - AstScope* scopep = nodep->scopep(); + AstScope* const scopep = nodep->scopep(); UASSERT_OBJ(scopep, nodep, "No scope found on top level"); - m_highScopep = scopep; + m_topScopep = scopep; iterateChildren(nodep); } virtual void visit(AstCCall* nodep) VL_OVERRIDE { @@ -662,12 +803,13 @@ private: if (!m_finding && !nodep->user2()) { // See if there are other calls in same statement list; // If so, all funcs might share the same activity code - TraceActivityVertex* activityVtxp = getActivityVertexp(nodep, nodep->funcp()->slow()); + TraceActivityVertex* const activityVtxp + = getActivityVertexp(nodep, nodep->funcp()->slow()); for (AstNode* nextp = nodep; nextp; nextp = nextp->nextp()) { - if (AstCCall* ccallp = VN_CAST(nextp, CCall)) { + if (AstCCall* const ccallp = VN_CAST(nextp, CCall)) { ccallp->user2(true); // Processed UINFO(8, " SubCCALL " << ccallp << endl); - V3GraphVertex* ccallFuncVtxp = getCFuncVertexp(ccallp->funcp()); + V3GraphVertex* const ccallFuncVtxp = getCFuncVertexp(ccallp->funcp()); activityVtxp->slow(ccallp->funcp()->slow()); new V3GraphEdge(&m_graph, activityVtxp, ccallFuncVtxp, 1); } @@ -677,22 +819,11 @@ private: } virtual void visit(AstCFunc* nodep) VL_OVERRIDE { UINFO(8, " CFUNC " << nodep << endl); - if (nodep->funcType() == AstCFuncType::TRACE_INIT) { - m_initFuncp = nodep; - } else if (nodep->funcType() == AstCFuncType::TRACE_FULL) { - m_fullFuncp = nodep; - } else if (nodep->funcType() == AstCFuncType::TRACE_CHANGE) { - m_chgFuncp = nodep; - } - V3GraphVertex* funcVtxp = getCFuncVertexp(nodep); - if (!m_finding) { // If public, we need a unique activity code to allow for sets directly - // in this func + V3GraphVertex* const funcVtxp = getCFuncVertexp(nodep); + if (!m_finding) { // If public, we need a unique activity code to allow for sets + // directly in this func if (nodep->funcPublic() || nodep->dpiExport() || nodep == v3Global.rootp()->evalp()) { - // Need a non-null place to remember to later add a statement; make one - if (!nodep->stmtsp()) - nodep->addStmtsp( - new AstComment(nodep->fileline(), "Tracing activity check", true)); - V3GraphVertex* activityVtxp = getActivityVertexp(nodep->stmtsp(), nodep->slow()); + V3GraphVertex* const activityVtxp = getActivityVertexp(nodep, nodep->slow()); new V3GraphEdge(&m_graph, activityVtxp, funcVtxp, 1); } } @@ -700,18 +831,17 @@ private: iterateChildren(nodep); m_funcp = NULL; } - virtual void visit(AstTraceInc* nodep) VL_OVERRIDE { + virtual void visit(AstTraceDecl* nodep) VL_OVERRIDE { UINFO(8, " TRACE " << nodep << endl); - UASSERT_OBJ(!m_finding, nodep, "Traces should have been removed in prev step."); - nodep->unlinkFrBack(); + if (!m_finding) { + V3GraphVertex* const vertexp = new TraceTraceVertex(&m_graph, nodep); + nodep->user1p(vertexp); - V3GraphVertex* vertexp = new TraceTraceVertex(&m_graph, nodep); - nodep->user1p(vertexp); - - UASSERT_OBJ(m_funcp && m_chgFuncp && m_fullFuncp, nodep, "Trace not under func"); - m_tracep = nodep; - iterateChildren(nodep); - m_tracep = NULL; + UASSERT_OBJ(m_funcp, nodep, "Trace not under func"); + m_tracep = nodep; + iterateChildren(nodep); + m_tracep = NULL; + } } virtual void visit(AstVarRef* nodep) VL_OVERRIDE { if (m_tracep) { @@ -722,7 +852,7 @@ private: varVtxp = new TraceVarVertex(&m_graph, nodep->varScopep()); nodep->varScopep()->user1p(varVtxp); } - V3GraphVertex* traceVtxp = m_tracep->user1u().toGraphVertex(); + V3GraphVertex* const traceVtxp = m_tracep->user1u().toGraphVertex(); new V3GraphEdge(&m_graph, varVtxp, traceVtxp, 1); if (nodep->varp()->isPrimaryInish() // Always need to trace primary inputs || nodep->varp()->isSigPublic()) { // Or ones user can change @@ -730,8 +860,8 @@ private: } } else if (m_funcp && m_finding && nodep->lvalue()) { UASSERT_OBJ(nodep->varScopep(), nodep, "No var scope?"); - V3GraphVertex* funcVtxp = getCFuncVertexp(m_funcp); - V3GraphVertex* varVtxp = nodep->varScopep()->user1u().toGraphVertex(); + V3GraphVertex* const funcVtxp = getCFuncVertexp(m_funcp); + V3GraphVertex* const varVtxp = nodep->varScopep()->user1u().toGraphVertex(); if (varVtxp) { // else we're not tracing this signal new V3GraphEdge(&m_graph, funcVtxp, varVtxp, 1); } @@ -742,25 +872,16 @@ private: public: // CONSTRUCTORS - explicit TraceVisitor(AstNetlist* nodep) { + explicit TraceVisitor(AstNetlist* nodep) + : m_alwaysVtxp(new TraceActivityVertex(&m_graph, TraceActivityVertex::ACTIVITY_ALWAYS)) { m_funcp = NULL; m_tracep = NULL; m_topModp = NULL; - m_highScopep = NULL; + m_topScopep = NULL; m_finding = false; m_activityVscp = NULL; - m_alwaysVtxp = NULL; - m_initFuncp = NULL; - m_fullFuncp = NULL; - m_fullSubFuncp = NULL; - m_fullSubStmts = 0; - m_chgFuncp = NULL; - m_chgSubFuncp = NULL; - m_chgSubParentp = NULL; - m_chgSubStmts = 0; m_activityNumber = 0; m_code = 0; - m_funcNum = 0; iterate(nodep); } virtual ~TraceVisitor() { diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index 029587e88..e404efda3 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -14,9 +14,9 @@ // //************************************************************************* // V3TraceDecl's Transformations: -// Create trace CFUNCs -// For each VARSCOPE -// If appropriate type of signal, create a TRACE +// Create trace init CFunc +// For each VarScope +// If appropriate type of signal, create a TraceDecl // //************************************************************************* @@ -28,8 +28,6 @@ #include "V3EmitCBase.h" #include "V3Stats.h" -#include - //###################################################################### // TraceDecl state, as a visitor of each AstNode @@ -38,12 +36,10 @@ private: // NODE STATE // STATE - AstScope* m_scopetopp; // Current top scope + AstScope* m_topScopep; // Current top scope AstCFunc* m_initFuncp; // Trace function being built AstCFunc* m_initSubFuncp; // Trace function being built (under m_init) int m_initSubStmts; // Number of statements in function - AstCFunc* m_fullFuncp; // Trace function being built - AstCFunc* m_chgFuncp; // Trace function being built int m_funcNum; // Function number being built AstVarScope* m_traVscp; // Signal being trace constructed AstNode* m_traValuep; // Signal being traced's value to trace in it @@ -56,50 +52,45 @@ private: // METHODS VL_DEBUG_FUNC; // Declare debug() - const char* vscIgnoreTrace(AstVarScope* nodep) { + const char* vscIgnoreTrace(const AstVarScope* nodep) { // Return true if this shouldn't be traced // See also similar rule in V3Coverage::varIgnoreToggle - AstVar* varp = nodep->varp(); + const AstVar* const varp = nodep->varp(); if (!varp->isTrace()) { return "Verilator trace_off"; } else if (!nodep->isTrace()) { return "Verilator cell trace_off"; } else if (!v3Global.opt.traceUnderscore()) { - string prettyName = varp->prettyName(); + const string prettyName = varp->prettyName(); if (!prettyName.empty() && prettyName[0] == '_') return "Leading underscore"; if (prettyName.find("._") != string::npos) return "Inlined leading underscore"; } return NULL; } - AstCFunc* newCFunc(AstCFuncType type, const string& name, bool slow) { - AstCFunc* funcp = new AstCFunc(m_scopetopp->fileline(), name, m_scopetopp); - funcp->slow(slow); - string argTypes(EmitCBaseVisitor::symClassVar() + ", " + v3Global.opt.traceClassBase() - + "* vcdp, uint32_t code"); + AstCFunc* newCFunc(AstCFuncType type, const string& name) { + FileLine* const flp = m_topScopep->fileline(); + AstCFunc* const funcp = new AstCFunc(flp, name, m_topScopep); + string argTypes("void* userp, " + v3Global.opt.traceClassBase() + "* tracep"); if (m_interface) argTypes += ", const char* scopep"; funcp->argTypes(argTypes); funcp->funcType(type); funcp->symProlog(true); - m_scopetopp->addActivep(funcp); + funcp->slow(true); + funcp->declPrivate(true); + m_topScopep->addActivep(funcp); UINFO(5, " Newfunc " << funcp << endl); return funcp; } void callCFuncSub(AstCFunc* basep, AstCFunc* funcp, AstIntfRef* irp) { AstCCall* callp = new AstCCall(funcp->fileline(), funcp); - callp->argTypes("vlSymsp, vcdp, code"); + callp->argTypes("userp, tracep"); if (irp) callp->addArgsp(irp->unlinkFrBack()); basep->addStmtsp(callp); } AstCFunc* newCFuncSub(AstCFunc* basep) { - string name = basep->name() + "__" + cvtToStr(++m_funcNum); - AstCFunc* funcp = NULL; - if (basep->funcType() == AstCFuncType::TRACE_INIT - || basep->funcType() == AstCFuncType::TRACE_INIT_SUB) { - funcp = newCFunc(AstCFuncType::TRACE_INIT_SUB, name, basep->slow()); - } else { - basep->v3fatalSrc("Strange base function type"); - } + const string name = "traceInitSub" + cvtToStr(m_funcNum++); + AstCFunc* const funcp = newCFunc(AstCFuncType::TRACE_INIT_SUB, name); if (!m_interface) callCFuncSub(basep, funcp, NULL); return funcp; } @@ -107,15 +98,14 @@ private: int widthOverride) { // If !=0, is packed struct/array where basicp size // misreflects one element VNumRange bitRange; - AstBasicDType* bdtypep = m_traValuep->dtypep()->basicp(); if (widthOverride) { bitRange = VNumRange(widthOverride - 1, 0, false); - } else if (bdtypep) { + } else if (const AstBasicDType* const bdtypep = m_traValuep->dtypep()->basicp()) { bitRange = bdtypep->nrange(); } - AstTraceDecl* declp + AstTraceDecl* const declp = new AstTraceDecl(m_traVscp->fileline(), m_traShowname, m_traVscp->varp(), - m_traValuep, bitRange, arrayRange, m_interface); + m_traValuep->cloneTree(true), bitRange, arrayRange, m_interface); UINFO(9, "Decl " << declp << endl); if (!m_interface && v3Global.opt.outputSplitCTrace() @@ -126,10 +116,6 @@ private: m_initSubFuncp->addStmtsp(declp); m_initSubStmts += EmitCBaseCounterVisitor(declp).count(); - - m_chgFuncp->addStmtsp( - new AstTraceInc(m_traVscp->fileline(), declp, m_traValuep->cloneTree(true))); - // The full version will get constructed in V3Trace } void addIgnore(const char* why) { ++m_statIgnSigs; @@ -139,39 +125,37 @@ private: // VISITORS virtual void visit(AstTopScope* nodep) VL_OVERRIDE { - m_scopetopp = nodep->scopep(); - // Make containers for TRACEDECLs first - m_initFuncp = newCFunc(AstCFuncType::TRACE_INIT, "traceInitThis", true); - m_fullFuncp = newCFunc(AstCFuncType::TRACE_FULL, "traceFullThis", true); - m_chgFuncp = newCFunc(AstCFuncType::TRACE_CHANGE, "traceChgThis", false); - // + m_topScopep = nodep->scopep(); + // Create the trace init function + m_initFuncp = newCFunc(AstCFuncType::TRACE_INIT, "traceInitTop"); + // Create initial sub function m_initSubFuncp = newCFuncSub(m_initFuncp); // And find variables iterateChildren(nodep); } virtual void visit(AstScope* nodep) VL_OVERRIDE { - AstCell* cellp = VN_CAST(nodep->aboveCellp(), Cell); + AstCell* const cellp = VN_CAST(nodep->aboveCellp(), Cell); if (cellp && VN_IS(cellp->modp(), Iface)) { - AstCFunc* origSubFunc = m_initSubFuncp; + AstCFunc* const origSubFunc = m_initSubFuncp; int origSubStmts = m_initSubStmts; { m_interface = true; m_initSubFuncp = newCFuncSub(origSubFunc); string scopeName = nodep->prettyName(); - size_t lastDot = scopeName.find_last_of('.'); + const size_t lastDot = scopeName.find_last_of('.'); UASSERT_OBJ(lastDot != string::npos, nodep, "Expected an interface scope name to have at least one dot"); scopeName = scopeName.substr(0, lastDot + 1); - size_t scopeLen = scopeName.length(); + const size_t scopeLen = scopeName.length(); AstIntfRef* nextIrp = cellp->intfRefp(); // While instead of for loop because interface references will // be unlinked as we go while (nextIrp) { - AstIntfRef* irp = nextIrp; + AstIntfRef* const irp = nextIrp; nextIrp = VN_CAST(irp->nextp(), IntfRef); - string irpName = irp->prettyName(); + const string irpName = irp->prettyName(); if (scopeLen > irpName.length()) continue; string intfScopeName = irpName.substr(0, scopeLen); if (scopeName != intfScopeName) continue; @@ -196,8 +180,8 @@ private: if ((!nodep->varp()->isTemp() || nodep->varp()->isTrace()) && !nodep->varp()->isClassMember() && !nodep->varp()->isFuncLocal()) { UINFO(5, " vsc " << nodep << endl); - AstVar* varp = nodep->varp(); - AstScope* scopep = nodep->scopep(); + const AstVar* const varp = nodep->varp(); + const AstScope* const scopep = nodep->scopep(); // Compute show name // This code assumes SPTRACEVCDC_VERSION >= 1330; // it uses spaces to separate hierarchy components. @@ -205,14 +189,13 @@ private: m_traShowname = AstNode::vcdName(varp->name()); } else { m_traShowname = AstNode::vcdName(scopep->name() + " " + varp->name()); - if (m_traShowname.substr(0, 4) == "TOP ") m_traShowname.replace(0, 4, ""); + if (m_traShowname.substr(0, 4) == "TOP ") m_traShowname.erase(0, 4); } UASSERT_OBJ(m_initSubFuncp, nodep, "NULL"); m_traVscp = nodep; - m_traValuep = NULL; - if (vscIgnoreTrace(nodep)) { - addIgnore(vscIgnoreTrace(nodep)); + if (const char* const ignoreReasonp = vscIgnoreTrace(nodep)) { + addIgnore(ignoreReasonp); } else { ++m_statSigs; if (nodep->valuep()) { @@ -220,15 +203,12 @@ private: } else { m_traValuep = new AstVarRef(nodep->fileline(), nodep, false); } - { - // Recurse into data type of the signal; the visitors will call addTraceDecl() - iterate(varp->dtypep()->skipRefToEnump()); - } + // Recurse into data type of the signal; the visitors will call addTraceDecl() + iterate(varp->dtypep()->skipRefToEnump()); // Cleanup if (m_traValuep) VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = NULL); } m_traVscp = NULL; - m_traValuep = NULL; m_traShowname = ""; } } @@ -257,10 +237,10 @@ private: } } else { // Unroll now, as have no other method to get right signal names - AstNodeDType* subtypep = nodep->subDTypep()->skipRefToEnump(); + AstNodeDType* const subtypep = nodep->subDTypep()->skipRefToEnump(); for (int i = nodep->lsb(); i <= nodep->msb(); ++i) { - string oldShowname = m_traShowname; - AstNode* oldValuep = m_traValuep; + const string oldShowname = m_traShowname; + AstNode* const oldValuep = m_traValuep; { m_traShowname += string("(") + cvtToStr(i) + string(")"); m_traValuep = new AstArraySel( @@ -284,10 +264,10 @@ private: // a much faster way to trace addTraceDecl(VNumRange(), nodep->width()); } else { - AstNodeDType* subtypep = nodep->subDTypep()->skipRefToEnump(); + AstNodeDType* const subtypep = nodep->subDTypep()->skipRefToEnump(); for (int i = nodep->lsb(); i <= nodep->msb(); ++i) { - string oldShowname = m_traShowname; - AstNode* oldValuep = m_traValuep; + const string oldShowname = m_traShowname; + AstNode* const oldValuep = m_traValuep; { m_traShowname += string("(") + cvtToStr(i) + string(")"); m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true), @@ -310,31 +290,29 @@ private: // This may not be the nicest for user presentation, but is // a much faster way to trace addTraceDecl(VNumRange(), nodep->width()); + } else if (!nodep->packed()) { + addIgnore("Unsupported: Unpacked struct/union"); } else { - if (!nodep->packed()) { - addIgnore("Unsupported: Unpacked struct/union"); - } else { - for (AstMemberDType* itemp = nodep->membersp(); itemp; - itemp = VN_CAST(itemp->nextp(), MemberDType)) { - AstNodeDType* subtypep = itemp->subDTypep()->skipRefToEnump(); - string oldShowname = m_traShowname; - AstNode* oldValuep = m_traValuep; - { - m_traShowname += string(" ") + itemp->prettyName(); - if (VN_IS(nodep, StructDType)) { - m_traValuep - = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true), - itemp->lsb(), subtypep->width()); - m_traValuep->dtypep(subtypep); - iterate(subtypep); - VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = NULL); - } else { // Else union, replicate fields - iterate(subtypep); - } + for (const AstMemberDType* itemp = nodep->membersp(); itemp; + itemp = VN_CAST_CONST(itemp->nextp(), MemberDType)) { + AstNodeDType* const subtypep = itemp->subDTypep()->skipRefToEnump(); + const string oldShowname = m_traShowname; + AstNode* const oldValuep = m_traValuep; + { + m_traShowname += string(" ") + itemp->prettyName(); + if (VN_IS(nodep, StructDType)) { + m_traValuep + = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true), + itemp->lsb(), subtypep->width()); + m_traValuep->dtypep(subtypep); + iterate(subtypep); + VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = NULL); + } else { // Else union, replicate fields + iterate(subtypep); } - m_traShowname = oldShowname; - m_traValuep = oldValuep; } + m_traShowname = oldShowname; + m_traValuep = oldValuep; } } } @@ -361,12 +339,10 @@ private: public: // CONSTRUCTORS explicit TraceDeclVisitor(AstNetlist* nodep) { - m_scopetopp = NULL; + m_topScopep = NULL; m_initFuncp = NULL; m_initSubFuncp = NULL; m_initSubStmts = 0; - m_fullFuncp = NULL; - m_chgFuncp = NULL; m_funcNum = 0; m_traVscp = NULL; m_traValuep = NULL; diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index c2c0e8436..184f92571 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -60,14 +60,11 @@ #include "V3Global.h" #include "V3Tristate.h" #include "V3Ast.h" -#include "V3Const.h" #include "V3Stats.h" #include "V3Inst.h" -#include "V3Stats.h" #include "V3Graph.h" #include -#include #include //###################################################################### diff --git a/src/V3Undriven.cpp b/src/V3Undriven.cpp index 0bc57da59..d0b48debc 100644 --- a/src/V3Undriven.cpp +++ b/src/V3Undriven.cpp @@ -32,7 +32,6 @@ #include "V3Ast.h" #include -#include #include //###################################################################### diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 5abbd20c0..d0769702d 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -38,7 +38,6 @@ #include "V3Stats.h" #include -#include //###################################################################### diff --git a/src/V3Unroll.cpp b/src/V3Unroll.cpp index 3a0191190..6d1eb0cb7 100644 --- a/src/V3Unroll.cpp +++ b/src/V3Unroll.cpp @@ -35,7 +35,6 @@ #include "V3Simulate.h" #include -#include //###################################################################### // Unroll state, as a visitor of each AstNode @@ -389,6 +388,7 @@ private: if (nodep->backp()->nextp() == nodep) initp = nodep->backp(); // Grab assignment AstNode* incp = NULL; // Should be last statement + AstNode* bodysp = nodep->bodysp(); if (nodep->incsp()) V3Const::constifyEdit(nodep->incsp()); // cppcheck-suppress duplicateCondition if (nodep->incsp()) { @@ -397,11 +397,12 @@ private: for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {} if (incp) VL_DO_DANGLING(V3Const::constifyEdit(incp), incp); // Again, as may have changed + bodysp = nodep->bodysp(); for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {} + if (incp == bodysp) bodysp = NULL; } // And check it - if (forUnrollCheck(nodep, initp, nodep->precondsp(), nodep->condp(), incp, - nodep->bodysp())) { + if (forUnrollCheck(nodep, initp, nodep->precondsp(), nodep->condp(), incp, bodysp)) { VL_DO_DANGLING(pushDeletep(nodep), nodep); // Did replacement } } diff --git a/src/V3Waiver.cpp b/src/V3Waiver.cpp new file mode 100644 index 000000000..cc62c823b --- /dev/null +++ b/src/V3Waiver.cpp @@ -0,0 +1,56 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: Emit waivers into a config file +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// Copyright 2020 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 +// +//************************************************************************* + +#include "verilatedos.h" + +#include "V3File.h" +#include "V3Waiver.h" + +#include +#include + +void V3Waiver::addEntry(V3ErrorCode errorCode, const std::string& filename, + const std::string& str) { + std::stringstream entry; + entry << "lint_off -rule " << errorCode.ascii() << " -file \"*" << filename << "\" -match \"" + << str << "\""; + s_waiverList.push_back(entry.str()); +} + +void V3Waiver::write(const std::string& filename) { + const vl_unique_ptr ofp(V3File::new_ofstream(filename)); + if (ofp->fail()) v3fatal("Can't write " << filename); + + *ofp << "// DESCR" + "IPTION: Verilator output: Waivers generated with --waiver-output" + << std::endl + << endl; + + *ofp << "`verilator_config" << endl << endl; + + *ofp << "// Below you find suggested waivers. You have three options:" << endl; + *ofp << "// 1. Fix the reason for the linter warning" << endl; + *ofp << "// 2. Keep the waiver permanently if you are sure this is okay" << endl; + *ofp << "// 3. Keep the waiver temporarily to suppress the output" << endl << endl; + + if (s_waiverList.size() == 0) { *ofp << "// No waivers needed - great!" << endl; } + + for (V3Waiver::WaiverList::const_iterator it = s_waiverList.begin(); it != s_waiverList.end(); + ++it) { + *ofp << "// " << *it << std::endl << endl; + } +} + +V3Waiver::WaiverList V3Waiver::s_waiverList; diff --git a/src/V3Waiver.h b/src/V3Waiver.h new file mode 100644 index 000000000..67d4d65a0 --- /dev/null +++ b/src/V3Waiver.h @@ -0,0 +1,35 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: Emit Waivers +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// Copyright 2003-2020 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 _V3WAIVER_H_ +#define _V3WAIVER_H_ 1 + +#include "V3Error.h" + +#include +#include + +class V3Waiver { + // TYPES + typedef std::vector WaiverList; + static WaiverList s_waiverList; + +public: + static void addEntry(V3ErrorCode errorCode, const string& filename, const std::string& str); + static void write(const std::string& filename); +}; + +#endif // Guard diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 2d5a4d94a..940d50ea8 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -74,7 +74,6 @@ #include "V3Task.h" #include -#include // More code; this file was getting too large; see actions there #define _V3WIDTH_CPP_ @@ -189,8 +188,8 @@ private: bool m_paramsOnly; // Computing parameter value; limit operation AstRange* m_cellRangep; // Range for arrayed instantiations, NULL for normal instantiations AstNodeFTask* m_ftaskp; // Current function/task + AstNodeProcedure* m_procedurep; // Current final/always AstFunc* m_funcp; // Current function - AstInitial* m_initialp; // Current initial block AstAttrOf* m_attrp; // Current attribute bool m_doGenerate; // Do errors later inside generate statement int m_dtTables; // Number of created data type tables @@ -426,13 +425,12 @@ private: nodep->dtypeSetUInt64(); // A pointer, but not that it matters } - // Special cases. So many.... virtual void visit(AstNodeCond* nodep) VL_OVERRIDE { - // op=cond?expr1:expr2 - // Signed: Output signed iff RHS & THS signed (presumed, not in IEEE) + // op = cond ? expr1 : expr2 // See IEEE-2012 11.4.11 and Table 11-21. // LHS is self-determined - // Width: max(RHS,THS) + // Width: max(RHS, THS) + // Signed: Output signed iff RHS & THS signed (presumed, not in IEEE) // Real: Output real if either expression is real, non-real argument gets converted if (m_vup->prelim()) { // First stage evaluation // Just once, do the conditional, expect one bit out. @@ -539,9 +537,37 @@ private: } } virtual void visit(AstDelay* nodep) VL_OVERRIDE { + if (VN_IS(m_procedurep, Final)) { + nodep->v3error("Delays are not legal in final blocks (IEEE 1800-2017 9.2.3)"); + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); + return; + } + if (VN_IS(m_ftaskp, Func)) { + nodep->v3error("Delays are not legal in functions. Suggest use a task " + "(IEEE 1800-2017 13.4.4)"); + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); + return; + } nodep->v3warn(STMTDLY, "Unsupported: Ignoring delay on this delayed statement."); VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); } + virtual void visit(AstFork* nodep) VL_OVERRIDE { + if (VN_IS(m_ftaskp, Func) && !nodep->joinType().joinNone()) { + nodep->v3error("Only fork .. join_none is legal in functions. " + "(IEEE 1800-2017 13.4.4)"); + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); + return; + } + if (v3Global.opt.bboxUnsup()) { + AstBegin* newp + = new AstBegin(nodep->fileline(), nodep->name(), nodep->stmtsp()->unlinkFrBack()); + nodep->replaceWith(newp); + VL_DO_DANGLING(nodep->deleteTree(), nodep); + } else { + nodep->v3error("Unsupported: fork statements"); + // TBD might support only normal join, if so complain about other join flavors + } + } virtual void visit(AstToLowerN* nodep) VL_OVERRIDE { if (m_vup->prelim()) { iterateCheckString(nodep, "LHS", nodep->lhsp(), BOTH); @@ -1034,7 +1060,17 @@ private: } } virtual void visit(AstUnbounded* nodep) VL_OVERRIDE { - nodep->v3error("Unsupported/illegal unbounded ('$') in this context."); + nodep->dtypeSetSigned32(); // Used in int context + if (!VN_IS(nodep->backp(), IsUnbounded) + && !(VN_IS(nodep->backp(), Var) && VN_CAST(nodep->backp(), Var)->isParam())) { + nodep->v3error("Unsupported/illegal unbounded ('$') in this context."); + } + } + virtual void visit(AstIsUnbounded* nodep) VL_OVERRIDE { + if (m_vup->prelim()) { + userIterateAndNext(nodep->lhsp(), WidthVP(SELF, BOTH).p()); + nodep->dtypeSetLogicBool(); + } } virtual void visit(AstUCFunc* nodep) VL_OVERRIDE { // Give it the size the user wants. @@ -1119,6 +1155,18 @@ private: userIterateAndNext(nodep->lhsp(), WidthVP(SELF, BOTH).p()); userIterateAndNext(nodep->rhsp(), WidthVP(SELF, BOTH).p()); } + virtual void visit(AstCountBits* nodep) VL_OVERRIDE { + if (m_vup->prelim()) { + iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH); + iterateCheckSizedSelf(nodep, "RHS", nodep->rhsp(), SELF, BOTH); + iterateCheckSizedSelf(nodep, "THS", nodep->thsp(), SELF, BOTH); + iterateCheckSizedSelf(nodep, "FHS", nodep->fhsp(), SELF, BOTH); + // If it's a 32 bit number, we need a 6 bit number as we need to return '32'. + int selwidth = V3Number::log2b(nodep->lhsp()->width()) + 1; + nodep->dtypeSetLogicSized(selwidth, + VSigning::UNSIGNED); // Spec doesn't indicate if an integer + } + } virtual void visit(AstCountOnes* nodep) VL_OVERRIDE { if (m_vup->prelim()) { iterateCheckSizedSelf(nodep, "LHS", nodep->lhsp(), SELF, BOTH); @@ -1388,18 +1436,21 @@ private: // Type comes from expression's type userIterateAndNext(nodep->typeofp(), WidthVP(SELF, BOTH).p()); AstNode* typeofp = nodep->typeofp(); + nodep->typedefp(NULL); nodep->refDTypep(typeofp->dtypep()); VL_DO_DANGLING(typeofp->unlinkFrBack()->deleteTree(), typeofp); // We had to use AstRefDType for this construct as pointers to this type // in type table are still correct (which they wouldn't be if we replaced the node) } userIterateChildren(nodep, NULL); - if (nodep->subDTypep()) nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep())); + if (nodep->subDTypep()) { + nodep->refDTypep(iterateEditDTypep(nodep, nodep->subDTypep())); + nodep->typedefp(NULL); // Note until line above subDTypep() may have followed this + } // Effectively nodep->dtypeFrom(nodep->dtypeSkipRefp()); // But might be recursive, so instead manually recurse into the referenced type - UASSERT_OBJ(nodep->defp(), nodep, "Unlinked"); - nodep->dtypeFrom(nodep->defp()); - userIterate(nodep->defp(), NULL); + UASSERT_OBJ(nodep->subDTypep(), nodep, "Unlinked"); + nodep->dtypeFrom(nodep->subDTypep()); nodep->widthFromSub(nodep->subDTypep()); UINFO(4, "dtWidthed " << nodep << endl); nodep->doingWidth(false); @@ -1661,7 +1712,8 @@ private: // if (debug() >= 9) nodep->dumpTree(cout, " VRout "); if (nodep->lvalue() && nodep->varp()->direction() == VDirection::CONSTREF) { nodep->v3error("Assigning to const ref variable: " << nodep->prettyNameQ()); - } else if (nodep->lvalue() && nodep->varp()->isConst() && !m_paramsOnly && !m_initialp) { + } else if (nodep->lvalue() && nodep->varp()->isConst() && !m_paramsOnly + && !VN_IS(m_procedurep, Initial)) { // Too loose, but need to allow our generated first assignment // Move this to a property of the AstInitial block nodep->v3error("Assigning to const variable: " << nodep->prettyNameQ()); @@ -1878,11 +1930,12 @@ private: } virtual void visit(AstClassExtends* nodep) VL_OVERRIDE { if (nodep->didWidthAndSet()) return; - if (nodep->childDTypep()) { - nodep->dtypep(moveChildDTypeEdit(nodep)); // data_type '{ pattern } - } nodep->v3error("Unsupported: class extends"); // Member/meth access breaks - userIterateChildren(nodep, NULL); + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); + // if (nodep->childDTypep()) { + // nodep->dtypep(moveChildDTypeEdit(nodep)); // data_type '{ pattern } + // } + // userIterateChildren(nodep, NULL); } virtual void visit(AstMemberDType* nodep) VL_OVERRIDE { if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed @@ -1922,6 +1975,7 @@ private: } } else if (VN_IS(fromDtp, EnumDType) // || VN_IS(fromDtp, AssocArrayDType) // + || VN_IS(fromDtp, UnpackArrayDType) // || VN_IS(fromDtp, DynArrayDType) // || VN_IS(fromDtp, QueueDType) // || VN_IS(fromDtp, BasicDType)) { @@ -2151,7 +2205,7 @@ private: } } int selwidth = V3Number::log2b(msbdim) + 1; // Width to address a bit - AstVar* varp = enumVarp(adtypep, attrType, (VL_ULL(1) << selwidth) - 1); + AstVar* varp = enumVarp(adtypep, attrType, (1ULL << selwidth) - 1); AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false); varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp()); AstNode* newp = new AstArraySel( @@ -2398,7 +2452,7 @@ private: nodep->dtypeSetSigned32(); // Guess on error } void methodCallUnpack(AstMethodCall* nodep, AstUnpackArrayDType* adtypep) { - enum { UNKNOWN = 0, ARRAY_OR, ARRAY_AND, ARRAY_XOR } methodId; + enum { UNKNOWN = 0, ARRAY_OR, ARRAY_AND, ARRAY_XOR, ARRAY_SUM, ARRAY_PRODUCT } methodId; methodId = UNKNOWN; if (nodep->name() == "or") { @@ -2407,6 +2461,10 @@ private: methodId = ARRAY_AND; } else if (nodep->name() == "xor") { methodId = ARRAY_XOR; + } else if (nodep->name() == "sum") { + methodId = ARRAY_SUM; + } else if (nodep->name() == "product") { + methodId = ARRAY_PRODUCT; } if (methodId) { @@ -2423,6 +2481,8 @@ private: case ARRAY_OR: newp = new AstOr(fl, newp, selector); break; case ARRAY_AND: newp = new AstAnd(fl, newp, selector); break; case ARRAY_XOR: newp = new AstXor(fl, newp, selector); break; + case ARRAY_SUM: newp = new AstAdd(fl, newp, selector); break; + case ARRAY_PRODUCT: newp = new AstMul(fl, newp, selector); break; default: nodep->v3fatalSrc("bad case"); } } @@ -3260,6 +3320,11 @@ private: userIterateAndNext(nodep->filenamep(), WidthVP(SELF, BOTH).p()); userIterateAndNext(nodep->modep(), WidthVP(SELF, BOTH).p()); } + virtual void visit(AstFOpenMcd* nodep) VL_OVERRIDE { + assertAtStatement(nodep); + iterateCheckFileDesc(nodep, nodep->filep(), BOTH); + userIterateAndNext(nodep->filenamep(), WidthVP(SELF, BOTH).p()); + } virtual void visit(AstFClose* nodep) VL_OVERRIDE { assertAtStatement(nodep); iterateCheckFileDesc(nodep, nodep->filep(), BOTH); @@ -3763,11 +3828,11 @@ private: processFTaskRefArgs(nodep); nodep->didWidth(true); } - virtual void visit(AstInitial* nodep) VL_OVERRIDE { + virtual void visit(AstNodeProcedure* nodep) VL_OVERRIDE { assertAtStatement(nodep); - m_initialp = nodep; + m_procedurep = nodep; userIterateChildren(nodep, NULL); - m_initialp = NULL; + m_procedurep = NULL; } virtual void visit(AstNetlist* nodep) VL_OVERRIDE { // Iterate modules backwards, in bottom-up order. That's faster @@ -4527,14 +4592,17 @@ private: } else if (expDTypep->isDouble() && underp->isDouble()) { // Also good underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, FINAL).p()); } else if (expDTypep->isDouble() && !underp->isDouble()) { + AstNode* oldp = underp; // Need FINAL on children; otherwise splice would block it underp = spliceCvtD(underp); - underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, FINAL).p()); + underp = userIterateSubtreeReturnEdits(oldp, WidthVP(SELF, FINAL).p()); } else if (!expDTypep->isDouble() && underp->isDouble()) { + AstNode* oldp = underp; // Need FINAL on children; otherwise splice would block it underp = spliceCvtS(underp, true, expDTypep->width()); // Round RHS - underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, FINAL).p()); + underp = userIterateSubtreeReturnEdits(oldp, WidthVP(SELF, FINAL).p()); } else if (expDTypep->isString() && !underp->dtypep()->isString()) { + AstNode* oldp = underp; // Need FINAL on children; otherwise splice would block it underp = spliceCvtString(underp); - underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF, FINAL).p()); + underp = userIterateSubtreeReturnEdits(oldp, WidthVP(SELF, FINAL).p()); } else { AstBasicDType* expBasicp = expDTypep->basicp(); AstBasicDType* underBasicp = underp->dtypep()->basicp(); @@ -5227,8 +5295,8 @@ public: m_paramsOnly = paramsOnly; m_cellRangep = NULL; m_ftaskp = NULL; + m_procedurep = NULL; m_funcp = NULL; - m_initialp = NULL; m_attrp = NULL; m_doGenerate = doGenerate; m_dtTables = 0; diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index 78622792c..65eff9830 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -33,8 +33,6 @@ #include "V3Width.h" #include "V3Const.h" -#include - //###################################################################### // Width state, as a visitor of each AstNode @@ -191,6 +189,13 @@ private: } } + void warnTri(AstNode* nodep) { + if (VN_IS(nodep, Const) && VN_CAST(nodep, Const)->num().isFourState()) { + nodep->v3error( + "Selection index is constantly unknown or tristated: " << nodep->name()); + } + } + // VISITORS // If adding new visitors, ensure V3Width's visit(TYPE) calls into here @@ -451,6 +456,8 @@ private: UINFO(6, "SELPLUS/MINUS " << nodep << endl); // Below 2 lines may change nodep->widthp() if (debug() >= 9) nodep->dumpTree(cout, "--SELPM0: "); + V3Width::widthParamsEdit(nodep->rhsp()); // constifyEdit doesn't ensure widths finished + V3Const::constifyEdit(nodep->rhsp()); // May relink pointed to node, ok if not const V3Const::constifyParamsEdit(nodep->thsp()); // May relink pointed to node checkConstantOrReplace(nodep->thsp(), "Width of :+ or :- bit extract isn't a constant"); if (debug() >= 9) nodep->dumpTree(cout, "--SELPM3: "); @@ -458,6 +465,7 @@ private: AstNode* fromp = nodep->lhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNode* widthp = nodep->thsp()->unlinkFrBack(); + warnTri(rhsp); int width = VN_CAST(widthp, Const)->toSInt(); if (width > (1 << 28)) { nodep->v3error("Width of :+ or :- is huge; vector of over 1billion bits: " @@ -467,9 +475,35 @@ private: FromData fromdata = fromDataForArray(nodep, fromp); AstNodeDType* ddtypep = fromdata.m_dtypep; VNumRange fromRange = fromdata.m_fromRange; - if (VN_IS(ddtypep, BasicDType) || VN_IS(ddtypep, PackArrayDType) - || (VN_IS(ddtypep, NodeUOrStructDType) - && VN_CAST(ddtypep, NodeUOrStructDType)->packedUnsup())) { + if (VN_IS(ddtypep, UnpackArrayDType)) { + // Slice +: and -: extraction + if (fromRange.elements() == width && VN_IS(rhsp, Const) + && VN_CAST(rhsp, Const)->toSInt() + == fromRange.lo()) { // Extracting whole of original array + nodep->replaceWith(fromp); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + } else if (fromRange.elements() == 1) { // Extracting single element + AstArraySel* newp = new AstArraySel(nodep->fileline(), fromp, rhsp); + nodep->replaceWith(newp); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + } else if (VN_IS(rhsp, Const)) { // Slice + vlsint32_t rhs = VN_CAST(rhsp, Const)->toSInt(); + // down array: lsb/lo +: width + // down array: msb/hi -: width + // up array: msb/lo +: width + // up array: lsb/hi -: width + vlsint32_t msb = VN_IS(nodep, SelPlus) ? rhs + width - 1 : rhs; + vlsint32_t lsb = VN_IS(nodep, SelPlus) ? rhs : rhs - width + 1; + AstSliceSel* newp = new AstSliceSel(nodep->fileline(), fromp, + VNumRange(msb, lsb, fromRange.littleEndian())); + nodep->replaceWith(newp); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + } else { + nodep->v3error("Unsupported: Slice of non-constant bounds"); + } + } else if (VN_IS(ddtypep, BasicDType) || VN_IS(ddtypep, PackArrayDType) + || (VN_IS(ddtypep, NodeUOrStructDType) + && VN_CAST(ddtypep, NodeUOrStructDType)->packedUnsup())) { int elwidth = 1; AstNode* newwidthp = widthp; if (const AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) { diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 33f3c9388..1ef486096 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -23,8 +23,11 @@ #include "V3AssertPre.h" #include "V3Begin.h" #include "V3Branch.h" +#include "V3CCtors.h" +#include "V3CUse.h" #include "V3Case.h" #include "V3Cast.h" +#include "V3Cdc.h" #include "V3Changed.h" #include "V3Class.h" #include "V3Clean.h" @@ -33,22 +36,19 @@ #include "V3Const.h" #include "V3Coverage.h" #include "V3CoverageJoin.h" -#include "V3CCtors.h" -#include "V3CUse.h" #include "V3Dead.h" #include "V3Delayed.h" #include "V3Depth.h" #include "V3DepthBlock.h" #include "V3Descope.h" #include "V3EmitC.h" -#include "V3EmitCMake.h" #include "V3EmitCMain.h" +#include "V3EmitCMake.h" #include "V3EmitMk.h" #include "V3EmitV.h" #include "V3EmitXml.h" #include "V3Expand.h" #include "V3File.h" -#include "V3Cdc.h" #include "V3Gate.h" #include "V3GenClk.h" #include "V3Graph.h" @@ -56,19 +56,19 @@ #include "V3Inst.h" #include "V3Life.h" #include "V3LifePost.h" -#include "V3LinkCells.h" #include "V3LinkDot.h" #include "V3LinkJump.h" +#include "V3LinkInc.h" #include "V3LinkLValue.h" #include "V3LinkLevel.h" #include "V3LinkParse.h" #include "V3LinkResolve.h" #include "V3Localize.h" +#include "V3MergeCond.h" #include "V3Name.h" #include "V3Order.h" #include "V3Os.h" #include "V3Param.h" -#include "V3Parse.h" #include "V3ParseSym.h" #include "V3Partition.h" #include "V3PreShell.h" @@ -84,19 +84,19 @@ #include "V3Stats.h" #include "V3String.h" #include "V3Subst.h" +#include "V3TSP.h" #include "V3Table.h" #include "V3Task.h" #include "V3Trace.h" #include "V3TraceDecl.h" #include "V3Tristate.h" -#include "V3TSP.h" #include "V3Undriven.h" #include "V3Unknown.h" #include "V3Unroll.h" +#include "V3Waiver.h" #include "V3Width.h" #include -#include V3Global v3Global; @@ -119,6 +119,8 @@ static void process() { V3LinkLValue::linkLValue(v3Global.rootp()); // Convert return/continue/disable to jumps V3LinkJump::linkJump(v3Global.rootp()); + // Convert --/++ to normal operations. Must be after LinkJump. + V3LinkInc::linkIncrements(v3Global.rootp()); V3Error::abortIfErrors(); if (v3Global.opt.stats()) V3Stats::statsStageAll(v3Global.rootp(), "Link"); @@ -419,13 +421,18 @@ static void process() { V3Dead::deadifyAll(v3Global.rootp()); } - if (!v3Global.opt.lintOnly() && !v3Global.opt.xmlOnly() && v3Global.opt.oReloop()) { - // Reform loops to reduce code size - // Must be after all Sel/array index based optimizations - V3Reloop::reloopAll(v3Global.rootp()); - } - if (!v3Global.opt.lintOnly() && !v3Global.opt.xmlOnly()) { + if (v3Global.opt.oMergeCond()) { + // Merge conditionals + V3MergeCond::mergeAll(v3Global.rootp()); + } + + if (v3Global.opt.oReloop()) { + // Reform loops to reduce code size + // Must be after all Sel/array index based optimizations + V3Reloop::reloopAll(v3Global.rootp()); + } + // Fix very deep expressions // Mark evaluation functions as member functions, if needed. V3Depth::depthAll(v3Global.rootp()); @@ -447,7 +454,7 @@ static void process() { if (!v3Global.opt.lintOnly() && !v3Global.opt.xmlOnly() && !v3Global.opt.dpiHdrOnly()) { // Create AstCUse to determine what class forward declarations/#includes needed in C // Must be before V3EmitC - V3CUse::cUseAll(v3Global.rootp()); + V3CUse::cUseAll(); // emitcInlines is first, as it may set needHInlines which other emitters read V3EmitC::emitcInlines(); @@ -542,6 +549,14 @@ static void verilate(const string& argString) { // Final steps V3Global::dumpCheckGlobalTree("final", 990, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); + + V3Error::abortIfErrors(); + + if (v3Global.opt.isWaiverOutput()) { + // Create waiver output, must be just before we exit on warnings + V3Waiver::write(v3Global.opt.waiverOutput()); + } + V3Error::abortIfWarnings(); if (v3Global.opt.makeDepend().isTrue()) { diff --git a/src/VlcBucket.h b/src/VlcBucket.h index 994c2e3d2..b422c9e95 100644 --- a/src/VlcBucket.h +++ b/src/VlcBucket.h @@ -32,7 +32,6 @@ private: vluint64_t m_dataSize; ///< Current entries in m_datap vluint64_t m_bucketsCovered; ///< Num buckets with sufficient coverage -private: static inline vluint64_t covBit(vluint64_t point) { return 1ULL << (point & 63); } inline vluint64_t allocSize() const { return sizeof(vluint64_t) * m_dataSize / 64; } void allocate(vluint64_t point) { @@ -41,10 +40,10 @@ private: m_dataSize *= 2; // UINFO(9, "Realloc "<(realloc(m_datap, allocSize())); - if (!newp) { + if (VL_UNCOVERABLE(!newp)) { // cppcheck-suppress doubleFree // cppcheck 1.90 bug - realloc doesn't free on fail - free(m_datap); - v3fatal("Out of memory increasing buckets"); + free(m_datap); // LCOV_EXCL_LINE + v3fatal("Out of memory increasing buckets"); // LCOV_EXCL_LINE } m_datap = newp; for (vluint64_t i = oldsize; i < m_dataSize; i += 64) m_datap[i / 64] = 0; diff --git a/src/VlcMain.cpp b/src/VlcMain.cpp index 5cdbdb36d..c004e8efc 100644 --- a/src/VlcMain.cpp +++ b/src/VlcMain.cpp @@ -71,7 +71,7 @@ void VlcOptions::parseOptsList(int argc, char** argv) { // Note argc and argv DO NOT INCLUDE the filename in [0]!!! // May be called recursively when there are -f files. #define shift \ - { ++i; } + do { ++i; } while (false) for (int i = 0; i < argc;) { UINFO(9, " Option: " << argv[i] << endl); if (argv[i][0] == '-') { @@ -108,6 +108,9 @@ void VlcOptions::parseOptsList(int argc, char** argv) { } else if (!strcmp(sw, "-write") && (i + 1) < argc) { shift; m_writeFile = argv[i]; + } else if (!strcmp(sw, "-write-info") && (i + 1) < argc) { + shift; + m_writeInfoFile = argv[i]; } else { v3fatal("Invalid option: " << argv[i]); } @@ -170,8 +173,9 @@ int main(int argc, char** argv, char** /*env*/) { top.tests().dump(false); } - if (!top.opt.writeFile().empty()) { - top.writeCoverage(top.opt.writeFile()); + if (!top.opt.writeFile().empty() || !top.opt.writeInfoFile().empty()) { + if (!top.opt.writeFile().empty()) top.writeCoverage(top.opt.writeFile()); + if (!top.opt.writeInfoFile().empty()) top.writeInfo(top.opt.writeInfoFile()); V3Error::abortIfWarnings(); if (top.opt.unlink()) { const VlStringSet& readFiles = top.opt.readFiles(); diff --git a/src/VlcOptions.h b/src/VlcOptions.h index 6d76dd99d..74e8c6380 100644 --- a/src/VlcOptions.h +++ b/src/VlcOptions.h @@ -29,7 +29,6 @@ //###################################################################### // V3Options - Command line options -typedef std::vector VlStringList; typedef std::set VlStringSet; class VlcOptions { @@ -42,6 +41,7 @@ class VlcOptions { bool m_rank; // main switch: --rank bool m_unlink; // main switch: --unlink string m_writeFile; // main switch: --write + string m_writeInfoFile; // main switch: --write-info // clang-format on private: @@ -58,7 +58,6 @@ public: m_unlink = false; } ~VlcOptions() {} - void setDebugMode(int level); // METHODS void parseOptsList(int argc, char** argv); @@ -72,6 +71,7 @@ public: bool rank() const { return m_rank; } bool unlink() const { return m_unlink; } string writeFile() const { return m_writeFile; } + string writeInfoFile() const { return m_writeInfoFile; } // METHODS (from main) static string version(); diff --git a/src/VlcPoint.h b/src/VlcPoint.h index 90c42e7fc..09e059ab7 100644 --- a/src/VlcPoint.h +++ b/src/VlcPoint.h @@ -58,6 +58,7 @@ public: string comment() const { return keyExtract(VL_CIK_COMMENT); } string type() const { return keyExtract(VL_CIK_TYPE); } string thresh() const { return keyExtract(VL_CIK_THRESH); } // string as maybe "" + string linescov() const { return keyExtract(VL_CIK_LINESCOV); } int lineno() const { return atoi(keyExtract(VL_CIK_LINENO).c_str()); } int column() const { return atoi(keyExtract(VL_CIK_COLUMN).c_str()); } // METHODS @@ -107,7 +108,6 @@ public: ByName::iterator begin() { return m_nameMap.begin(); } ByName::iterator end() { return m_nameMap.end(); } -public: // CONSTRUCTORS VlcPoints() : m_numPoints(0) {} diff --git a/src/VlcSource.h b/src/VlcSource.h index f01a575a7..9e438d9b2 100644 --- a/src/VlcSource.h +++ b/src/VlcSource.h @@ -118,7 +118,6 @@ public: NameMap::iterator begin() { return m_sources.begin(); } NameMap::iterator end() { return m_sources.end(); } -public: // CONSTRUCTORS VlcSources() {} ~VlcSources() {} diff --git a/src/VlcTest.h b/src/VlcTest.h index 42c17993e..dd0a6ccea 100644 --- a/src/VlcTest.h +++ b/src/VlcTest.h @@ -74,7 +74,7 @@ public: void dump(bool bucketsToo) { if (testrun() || computrons() != 0.0) { // currently unused // LCOV_EXCL_LINE cout << " " << std::setw(8) << std::setfill('0') << testrun() // LCOV_EXCL_LINE - << ", " << std::setw(7) << std::setfill(' ') << computrons() + << ", " << std::setw(7) << std::setfill(' ') << computrons() // LCOV_EXCL_LINE << ","; // LCOV_EXCL_LINE } cout << " " << std::setw(7) << std::setfill(' ') << bucketsCovered(); @@ -103,7 +103,6 @@ public: ByName::iterator begin() { return m_tests.begin(); } ByName::iterator end() { return m_tests.end(); } -public: // CONSTRUCTORS VlcTests() {} ~VlcTests() { diff --git a/src/VlcTop.cpp b/src/VlcTop.cpp index 864479146..67f74570c 100644 --- a/src/VlcTop.cpp +++ b/src/VlcTop.cpp @@ -21,7 +21,6 @@ #include #include -#include //###################################################################### @@ -77,6 +76,61 @@ void VlcTop::writeCoverage(const string& filename) { } } +void VlcTop::writeInfo(const string& filename) { + UINFO(2, "writeInfo " << filename << endl); + + std::ofstream os(filename.c_str()); + if (!os) { + v3fatal("Can't write " << filename); + return; + } + + annotateCalc(); + + // See 'man lcov' for format details + // TN: + // Source file: + // SF: + // FN:, + // FNDA:, + // FNF: + // FNH: + // Branches: + // BRDA:,,, + // BRF: + // BRH: + // Line counts: + // DA:, + // LF: + // LH: + // Section ending: + // end_of_record + + os << "TN:verilator_coverage\n"; + for (VlcSources::NameMap::iterator sit = m_sources.begin(); sit != m_sources.end(); ++sit) { + VlcSource& source = sit->second; + os << "SF:" << source.name() << endl; + VlcSource::LinenoMap& lines = source.lines(); + for (VlcSource::LinenoMap::iterator lit = lines.begin(); lit != lines.end(); ++lit) { + int lineno = lit->first; + VlcSource::ColumnMap& cmap = lit->second; + bool first = true; + vluint64_t min_count = 0; // Minimum across all columns on line + for (VlcSource::ColumnMap::iterator cit = cmap.begin(); cit != cmap.end(); ++cit) { + VlcSourceCount& col = cit->second; + if (first) { + min_count = col.count(); + first = false; + } else { + min_count = std::min(min_count, col.count()); + } + } + os << "DA:" << lineno << "," << min_count << "\n"; + } + os << "end_of_record\n"; + } +} + //******************************************************************** struct CmpComputrons { @@ -115,8 +169,8 @@ void VlcTop::rank() { // solution and move up to larger subset of tests. (Aka quick sort.) while (true) { if (debug()) { - UINFO(9, "Left on iter" << nextrank << ": "); - remaining.dump(); + UINFO(9, "Left on iter" << nextrank << ": "); // LCOV_EXCL_LINE + remaining.dump(); // LCOV_EXCL_LINE } VlcTest* bestTestp = NULL; vluint64_t bestRemain = 0; @@ -149,14 +203,38 @@ void VlcTop::annotateCalc() { string filename = point.filename(); int lineno = point.lineno(); if (!filename.empty() && lineno != 0) { - int column = point.column(); VlcSource& source = sources().findNewSource(filename); string threshStr = point.thresh(); unsigned thresh = (!threshStr.empty()) ? atoi(threshStr.c_str()) : opt.annotateMin(); bool ok = (point.count() >= thresh); - UINFO(9, - "AnnoCalc count " << filename << " " << lineno << " " << point.count() << endl); - source.incCount(lineno, column, point.count(), ok); + UINFO(9, "AnnoCalc count " << filename << ":" << lineno << ":" << point.column() << " " + << point.count() << " " << point.linescov() << endl); + // Base coverage + source.incCount(lineno, point.column(), point.count(), ok); + // Additional lines covered by this statement + bool range = false; + int start = 0; + int end = 0; + string linescov = point.linescov(); + for (const char* covp = linescov.c_str(); true; ++covp) { + if (!*covp || *covp == ',') { // Ending + for (int lni = start; start && lni <= end; ++lni) { + source.incCount(lni, point.column(), point.count(), ok); + } + if (!*covp) { break; } + start = 0; // Prep for next + end = 0; + range = false; + } else if (*covp == '-') { + range = true; + } else if (isdigit(*covp)) { + const char* digitsp = covp; + while (isdigit(*covp)) ++covp; + --covp; // Will inc in for loop + if (!range) start = atoi(digitsp); + end = atoi(digitsp); + } + } } } } diff --git a/src/VlcTop.h b/src/VlcTop.h index c314b81b2..f54725fcf 100644 --- a/src/VlcTop.h +++ b/src/VlcTop.h @@ -39,7 +39,6 @@ private: VlcSources m_sources; //< List of all source files to annotate // METHODS - void createDir(const string& dirname); void annotateCalc(); void annotateCalcNeeded(); void annotateOutputFiles(const string& dirname); @@ -58,6 +57,7 @@ public: void annotate(const string& dirname); void readCoverage(const string& filename, bool nonfatal = false); void writeCoverage(const string& filename); + void writeInfo(const string& filename); void rank(); }; diff --git a/src/astgen b/src/astgen index 69cba4d08..8a7e02469 100644 --- a/src/astgen +++ b/src/astgen @@ -140,7 +140,11 @@ sub read_refs { sub open_file { my $filename = shift; my $fh = IO::File->new($filename,"w") or die "%Error: $! $filename,"; - print $fh '// Generated by astgen // -*- mode: C++; c-file-style: "cc-mode" -*-'."\n"; + if ($filename =~ /\.txt$/) { + print $fh '// Generated by astgen'."\n"; + } else { + print $fh '// Generated by astgen // -*- mode: C++; c-file-style: "cc-mode" -*-'."\n"; + } return $fh; } @@ -182,32 +186,32 @@ sub write_report { $fh->print("Processing stages (approximate, based on order in Verilator.cpp):\n"); foreach my $class (sort {$Stages{$a} <=> $Stages{$b}} keys %Stages) { - $fh->print("\t$class\n"); + $fh->print(" $class\n"); } - $fh->print("\nProcessing stages (approximate, based on order in Verilator.cpp):\n"); + $fh->print("\nClasses:\n"); foreach my $type (sort (keys %Classes)) { printf $fh " class %-20s\n", "Ast${type}"; - $fh->print("\tparent:\t"); + $fh->print(" parent: "); foreach my $subclass (subclasses_of($type)) { next if $subclass eq 'Node'; printf $fh "Ast%-12s ",$subclass; } printf $fh "\n"; - $fh->print("\tchilds:\t"); + $fh->print(" childs: "); foreach my $subclass (children_of($type)) { next if $subclass eq 'Node'; printf $fh "Ast%-12s ",$subclass; } printf $fh "\n"; if (my $refs = $ClassRefs{"Ast${type}"}) { - $fh->print("\tnewed:\t"); + $fh->print(" newed: "); foreach my $stage (sort {($Stages{$a}||-1) <=> ($Stages{$b}||-1)} keys %{$refs->{newed}}) { $fh->print($stage." "); } $fh->print("\n"); - $fh->print("\tused:\t"); + $fh->print(" used: "); foreach my $stage (sort {($Stages{$a}||-1) <=> ($Stages{$b}||-1)} keys %{$refs->{used}}) { $fh->print($stage." "); diff --git a/src/bisonpre b/src/bisonpre index 395979575..48cf26eb3 100755 --- a/src/bisonpre +++ b/src/bisonpre @@ -212,6 +212,8 @@ sub clean_output { $line =~ s!\(YY_\("!(YY_((char*)"!g; # Fix bison 2.3 glr-parser warning about yyerrorloc.YYTYPE::yydummy uninit $line =~ s!(YYLTYPE yyerrloc;)!$1 yyerrloc.yydummy=0;/*bisonpre*/!g; + # Fix bison 3.6.1 unexpected nested-comment + $line =~ s!/\* "/\*.*\*/" \*/!!g; $fh->write($line); } $fh->close; diff --git a/src/config_build.h.in b/src/config_build.h.in index 02c915300..250ac1f96 100644 --- a/src/config_build.h.in +++ b/src/config_build.h.in @@ -77,6 +77,10 @@ using std::make_pair; // Define if struct stat has st_mtim.tv_nsec (from configure) #undef HAVE_STAT_NSEC +// Define if SystemC found +// - If defined, the default search path has it, so support is always enabled. +// - If undef, not system-wide, user can set SYSTEMC_INCLUDE. +#undef HAVE_SYSTEMC_H //********************************************************************** //**** OS and compiler specifics diff --git a/src/verilog.l b/src/verilog.l index 77b30e29d..6635286ac 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -22,48 +22,39 @@ #include "V3ParseImp.h" // Defines YYTYPE; before including bison header #include "V3ParseBison.h" // Generated by bison -#include - extern void yyerror(const char*); extern void yyerrorf(const char* format, ...); -#define STATE_VERILOG_RECENT S17 // State name for most recent Verilog Version +#define STATE_VERILOG_RECENT S17 // State name for most recent Verilog Version #define PARSEP V3ParseImp::parsep() #define SYMP PARSEP->symp() -#define YY_INPUT(buf,result,max_size) \ - result = PARSEP->flexPpInputToLex(buf, max_size); +#define YY_INPUT(buf, result, max_size) \ + do { result = PARSEP->flexPpInputToLex(buf, max_size); } while (false) //====================================================================== -#define FL_FWD { PARSEP->fileline()->forwardToken(yytext, yyleng, true); } +#define FL_FWD (PARSEP->fileline()->forwardToken(yytext, yyleng, true)) // Use this to break between tokens whereever not return'ing a token (e.g. skipping inside lexer) -#define FL_BRK { PARSEP->fileline()->startToken(); } +#define FL_BRK (PARSEP->fileline()->startToken()) #define CRELINE() (PARSEP->copyOrSameFileLine()) -#define FL { FL_FWD; yylval.fl = CRELINE(); } - -#define RETURN_BBOX_SYS_OR_MSG(msg,yytext) { \ - if (!v3Global.opt.bboxSys()) { yyerrorf(msg, yytext); FL_BRK; } \ - return yaD_IGNORE; } +#define FL do { FL_FWD; yylval.fl = CRELINE(); } while (false) #define ERROR_RSVD_WORD(language) \ do { FL_FWD; \ yyerrorf("Unsupported: " language " reserved word not implemented: '%s'", yytext); \ FL_BRK; } while(0) -// See V3Read.cpp -//void V3ParseImp::statePop() { yy_pop_state(); } - //====================================================================== void yyerror(const char* errmsg) { PARSEP->fileline()->v3error(errmsg); static const char* const colonmsg = "syntax error, unexpected ::, "; - //tokens; - if (0==strncmp(errmsg, colonmsg, strlen(colonmsg)) + // tokens; + if (0 == strncmp(errmsg, colonmsg, strlen(colonmsg)) && PARSEP->prevBisonVal().token == yaID__ETC && PARSEP->curBisonVal().token == yP_COLONCOLON) { static int warned = false; @@ -83,7 +74,7 @@ void yyerrorf(const char* format, ...) { va_list ap; va_start(ap, format); VL_VSNPRINTF(msg, maxlen, format, ap); - msg[maxlen-1] = '\0'; + msg[maxlen - 1] = '\0'; va_end(ap); yyerror(msg); @@ -434,6 +425,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} { /* System Tasks */ "$bits" { FL; return yD_BITS; } + "$countbits" { FL; return yD_COUNTBITS; } "$countones" { FL; return yD_COUNTONES; } "$dimensions" { FL; return yD_DIMENSIONS; } "$error" { FL; return yD_ERROR; } @@ -441,6 +433,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "$high" { FL; return yD_HIGH; } "$increment" { FL; return yD_INCREMENT; } "$info" { FL; return yD_INFO; } + "$isunbounded" { FL; return yD_ISUNBOUNDED; } "$isunknown" { FL; return yD_ISUNKNOWN; } "$left" { FL; return yD_LEFT; } "$low" { FL; return yD_LOW; } @@ -600,10 +593,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} { "$"[a-zA-Z_$][a-zA-Z0-9_$]* { string str (yytext, yyleng); yylval.strp = PARSEP->newString(AstNode::encodeName(str)); - // Lookup unencoded name including the $, to avoid hitting normal signals - if (SYMP->symCurrentp()->findIdFallback(str)) { - FL; return yaD_DPI; - } else { FL; RETURN_BBOX_SYS_OR_MSG("Unsupported or unknown PLI call: %s", yytext); } + FL; return yaD_PLI; } } @@ -1049,6 +1039,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} /* Catch all - absolutely last */ <*>.|\n { FL_FWD; yyerrorf("Missing verilog.l rule: Default rule invoked in state %d: %s", YY_START, yytext); FL_BRK; } %% + int V3ParseImp::stateVerilogRecent() { return STATE_VERILOG_RECENT; } void V3ParseImp::lexToken() { @@ -1063,18 +1054,20 @@ void V3ParseImp::lexToken() { } else { // Parse new token token = yylexReadTok(); - //yylval // Set by yylexReadTok() + // yylval // Set by yylexReadTok() } // If a paren, read another - if (token == '(' - || token == yCONST__LEX - || token == yGLOBAL__LEX - || token == yLOCAL__LEX - || token == yNEW__LEX + if (token == '(' // + || token == yCONST__LEX // + || token == yGLOBAL__LEX // + || token == yLOCAL__LEX // + || token == yNEW__LEX // || token == yVIRTUAL__LEX // Never put yID_* here; below symbol table resolution would break - ) { - if (debugFlex()>=6) { cout<<" lexToken: reading ahead to find possible strength"<= 6) { + cout << " lexToken: reading ahead to find possible strength" << endl; + } V3ParseBisonYYSType curValue = yylval; // Remember value, as about to read ahead int nexttok = yylexReadTok(); m_ahead = true; @@ -1082,36 +1075,50 @@ void V3ParseImp::lexToken() { m_aheadVal.token = nexttok; yylval = curValue; // Now potentially munge the current token - if (token == '(' && (nexttok == ygenSTRENGTH - || nexttok == ySUPPLY0 - || nexttok == ySUPPLY1)) { + if (token == '(' + && (nexttok == ygenSTRENGTH || nexttok == ySUPPLY0 || nexttok == ySUPPLY1)) { token = yP_PAR__STRENGTH; - } - else if (token == yCONST__LEX) { - if (nexttok == yREF) token = yCONST__REF; - else token = yCONST__ETC; - } - else if (token == yGLOBAL__LEX) { - if (nexttok == yCLOCKING) token = yGLOBAL__CLOCKING; - else if (v3Global.opt.pedantic()) token = yGLOBAL__ETC; + } else if (token == yCONST__LEX) { + if (nexttok == yREF) { + token = yCONST__REF; + } else { + token = yCONST__ETC; + } + } else if (token == yGLOBAL__LEX) { + if (nexttok == yCLOCKING) { + token = yGLOBAL__CLOCKING; + } else if (v3Global.opt.pedantic()) { + token = yGLOBAL__ETC; + } // Avoid 2009 "global" conflicting with old code when we can - else { token = yaID__LEX; yylval.strp = PARSEP->newString("global"); } - } - else if (token == yLOCAL__LEX) { - if (nexttok == yP_COLONCOLON) token = yLOCAL__COLONCOLON; - else token = yLOCAL__ETC; - } - else if (token == yNEW__LEX) { - if (nexttok == '(') token = yNEW__PAREN; - else token = yNEW__ETC; - } - else if (token == yVIRTUAL__LEX) { - if (nexttok == yCLASS) token = yVIRTUAL__CLASS; - else if (nexttok == yINTERFACE) token = yVIRTUAL__INTERFACE; - else if (nexttok == yaID__ETC || nexttok == yaID__LEX) - // || nexttok == yaID__aINTERFACE // but we may not know interfaces yet. + else { + token = yaID__LEX; + yylval.strp = PARSEP->newString("global"); + } + } else if (token == yLOCAL__LEX) { + if (nexttok == yP_COLONCOLON) { + token = yLOCAL__COLONCOLON; + } else { + token = yLOCAL__ETC; + } + } else if (token == yNEW__LEX) { + if (nexttok == '(') { + token = yNEW__PAREN; + } else { + token = yNEW__ETC; + } + } else if (token == yVIRTUAL__LEX) { + if (nexttok == yCLASS) { + token = yVIRTUAL__CLASS; + } else if (nexttok == yINTERFACE) { + token = yVIRTUAL__INTERFACE; + } else if (nexttok == yaID__ETC // + || nexttok == yaID__LEX) { + // || nexttok == yaID__aINTERFACE // but we may not know interfaces yet. token = yVIRTUAL__anyID; - else token = yVIRTUAL__ETC; + } else { + token = yVIRTUAL__ETC; + } } // If add to above "else if", also add to "if (token" further above } @@ -1120,26 +1127,36 @@ void V3ParseImp::lexToken() { if (token == yaID__LEX) { VSymEnt* foundp; if (VSymEnt* look_underp = SYMP->nextId()) { - UINFO(7," lexToken: next id lookup forced under "<findIdFallback(*(yylval.strp)); // "consume" it. Must set again if want another token under temp scope SYMP->nextId(NULL); } else { - UINFO(7," lexToken: find upward "<symCurrentp() - <<" for '"<<*(yylval.strp)<<"'"<=9) SYMP->symCurrentp()->dump(cout," -findtree: ", true); + UINFO(7, " lexToken: find upward " << SYMP->symCurrentp() << " for '" + << *(yylval.strp) << "'" << endl); + // if (debug()>=9) SYMP->symCurrentp()->dump(cout," -findtree: ", true); foundp = SYMP->symCurrentp()->findIdFallback(*(yylval.strp)); } if (foundp) { AstNode* scp = foundp->nodep(); yylval.scp = scp; - UINFO(7," lexToken: Found "<=6 || debugBison()>=6) { // --debugi-flex and --debugi-bison - cout<<" {"<filenameLetters()<asciiLineCol() - <<"} lexToBison TOKEN="<= 6 || debugBison() >= 6) { // --debugi-flex and --debugi-bison + cout << " {" << yylval.fl->filenameLetters() << yylval.fl->asciiLineCol() + << "} lexToBison TOKEN=" << yylval.token << " " << tokenName(yylval.token); + if (yylval.token == yaID__ETC // + || yylval.token == yaID__LEX // || yylval.token == yaID__aTYPE) { - cout<<" strp='"<<*(yylval.strp)<<"'"; + cout << " strp='" << *(yylval.strp) << "'"; } - cout<tracingOn(); } @@ -311,8 +311,7 @@ class AstSenTree; %token yVLT_D_TASK "--task" %token yVLT_D_VAR "--var" -%token yaD_IGNORE "${ignored-bbox-sys}" -%token yaD_DPI "${dpi-sys}" +%token yaD_PLI "${pli-system}" %token yaT_RESETALL "`resetall" @@ -552,6 +551,7 @@ class AstSenTree; %token yD_CLOG2 "$clog2" %token yD_COS "$cos" %token yD_COSH "$cosh" +%token yD_COUNTBITS "$countbits" %token yD_COUNTONES "$countones" %token yD_DIMENSIONS "$dimensions" %token yD_DISPLAY "$display" @@ -595,6 +595,7 @@ class AstSenTree; %token yD_HYPOT "$hypot" %token yD_INCREMENT "$increment" %token yD_INFO "$info" +%token yD_ISUNBOUNDED "$isunbounded" %token yD_ISUNKNOWN "$isunknown" %token yD_ITOR "$itor" %token yD_LEFT "$left" @@ -893,7 +894,7 @@ package_or_generate_item_declaration: // ==IEEE: package_or_generate_item //UNSUP extern_constraint_declaration { $$ = $1; } | class_declaration { $$ = $1; } // // class_constructor_declaration is part of function_declaration - | local_parameter_declaration ';' { $$ = $1; } + // // local_parameter_declaration under parameter_declaration | parameter_declaration ';' { $$ = $1; } //UNSUP covergroup_declaration { $$ = $1; } //UNSUP assertion_item_declaration { $$ = $1; } @@ -915,13 +916,19 @@ package_import_itemList: ; package_import_item: // ==IEEE: package_import_item - yaID__aPACKAGE yP_COLONCOLON package_import_itemObj - { $$ = new AstPackageImport($2, VN_CAST($1, Package), *$3); - SYMP->importItem($1,*$3); } + idAny/*package_identifier*/ yP_COLONCOLON package_import_itemObj + { + if (!VN_CAST($1, Package)) { + $$ = NULL; + $1->v3error("Importing from missing package '" << *$1 << "'"); + } else { + $$ = new AstPackageImport($2, VN_CAST($1, Package), *$3); + SYMP->importItem($1,*$3); + } } ; package_import_itemObj: // IEEE: part of package_import_item - idAny { $$=$1; $$=$1; } + idAny/*package_identifier*/ { $$=$1; $$=$1; } | '*' { $$=$1; static string star="*"; $$=☆ } ; @@ -936,7 +943,7 @@ package_export_itemList: ; package_export_item: // ==IEEE: package_export_item - yaID__aPACKAGE yP_COLONCOLON package_import_itemObj + idAny yP_COLONCOLON package_import_itemObj { $$ = new AstPackageExport($3, VN_CAST($1, Package), *$3); SYMP->exportItem($1,*$3); } ; @@ -948,7 +955,7 @@ module_declaration: // ==IEEE: module_declaration // // timeunits_declaration instead in module_item // // IEEE: module_nonansi_header + module_ansi_header modFront importsAndParametersE portsStarE ';' - module_itemListE yENDMODULE endLabelE + /*cont*/ module_itemListE yENDMODULE endLabelE { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); @@ -956,7 +963,7 @@ module_declaration: // ==IEEE: module_declaration SYMP->popScope($1); GRAMMARP->endLabel($7,$1,$7); } | udpFront parameter_port_listE portsStarE ';' - module_itemListE yENDPRIMITIVE endLabelE + /*cont*/ module_itemListE yENDPRIMITIVE endLabelE { $1->modTrace(false); // Stash for implicit wires, etc if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); @@ -1003,7 +1010,11 @@ udpFront: parameter_value_assignmentE: // IEEE: [ parameter_value_assignment ] /* empty */ { $$ = NULL; } - | '#' '(' cellparamList ')' { $$ = $3; } + | parameter_value_assignment { $$ = $1; } + ; + +parameter_value_assignment: // IEEE: parameter_value_assignment + '#' '(' cellparamList ')' { $$ = $3; } // // Parentheses are optional around a single parameter | '#' yaINTNUM { $$ = new AstPin($2, 1, "", new AstConst($2, *$2)); } | '#' yaFLOATNUM { $$ = new AstPin($2, 1, "", @@ -1136,7 +1147,7 @@ port: // ==IEEE: port { $$=$4; VARDTYPE($3); if (AstVar* vp=VARDONEP($$,$5,$6)) { $$->addNextNull(vp); vp->valuep($8); } } | portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$2; /*VARDTYPE-same*/ if (AstVar* vp=VARDONEP($$,$3,$4)) { $$->addNextNull(vp); vp->valuep($6); } } - ; + ; portDirNetE: // IEEE: part of port, optional net type and/or direction /* empty */ { } @@ -1145,17 +1156,17 @@ portDirNetE: // IEEE: part of port, optional net type and/or direction | port_direction { VARDECL(PORT); VARDTYPE_NDECL(NULL/*default_nettype*/); } | port_direction { VARDECL(PORT); } net_type { VARDTYPE_NDECL(NULL/*default_nettype*/); } // net_type calls VARDECL | net_type { } // net_type calls VARDECL - ; + ; port_declNetE: // IEEE: part of port_declaration, optional net type /* empty */ { } | net_type { } // net_type calls VARDECL - ; + ; portSig: id/*port*/ { $$ = new AstPort($1,PINNUMINC(),*$1); } | idSVKwd { $$ = new AstPort($1,PINNUMINC(),*$1); } - ; + ; //********************************************************************** // Interface headers @@ -1248,7 +1259,7 @@ anonymous_program_item: // ==IEEE: anonymous_program_item program_declaration: // IEEE: program_declaration + program_nonansi_header + program_ansi_header: // // timeunits_delcarationE is instead in program_item pgmFront parameter_port_listE portsStarE ';' - program_itemListE yENDPROGRAM endLabelE + /*cont*/ program_itemListE yENDPROGRAM endLabelE { $1->modTrace(GRAMMARP->allTracingOn($1->fileline())); // Stash for implicit wires, etc if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); @@ -1321,7 +1332,7 @@ modport_itemList: // IEEE: part of modport_declaration modport_item: // ==IEEE: modport_item id/*new-modport*/ '(' { VARRESET_NONLIST(UNKNOWN); VARIO(INOUT); } - /*cont*/ modportPortsDeclList ')' { $$ = new AstModport($1, *$1, $4); } + /*cont*/ modportPortsDeclList ')' { $$ = new AstModport($1, *$1, $4); } ; modportPortsDeclList: @@ -1374,14 +1385,7 @@ genvar_identifierDecl: // IEEE: genvar_identifier (for declaration) $$ = VARDONEA($1, *$1, NULL, $2); } ; -local_parameter_declaration: // IEEE: local_parameter_declaration - // // See notes in parameter_declaration - // // Front must execute first so VARDTYPE is ready before list of vars - local_parameter_declarationFront list_of_param_assignments { $$ = $2; } - | local_parameter_declarationTypeFront list_of_type_assignments { $$ = $2; } - ; - -parameter_declaration: // IEEE: parameter_declaration +parameter_declaration: // IEEE: local_ or parameter_declaration // // IEEE: yPARAMETER yTYPE list_of_type_assignments ';' // // Instead of list_of_type_assignments // // we use list_of_param_assignments because for port handling @@ -1391,47 +1395,33 @@ parameter_declaration: // IEEE: parameter_declaration | parameter_declarationTypeFront list_of_type_assignments { $$ = $2; } ; -local_parameter_declarationFront: // IEEE: local_parameter_declaration w/o assignment +parameter_declarationFront: // IEEE: local_ or parameter_declaration w/o assignment // // Front must execute first so VARDTYPE is ready before list of vars - varLParamReset implicit_typeE { /*VARRESET-in-varLParam*/ VARDTYPE($2); } - | varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); } + varParamReset implicit_typeE { /*VARRESET-in-varParam*/ VARDTYPE($2); } + | varParamReset data_type { /*VARRESET-in-varParam*/ VARDTYPE($2); } ; -local_parameter_declarationTypeFront: // IEEE: local_parameter_declaration w/o assignment +parameter_declarationTypeFront: // IEEE: local_ or parameter_declaration w/o assignment // // Front must execute first so VARDTYPE is ready before list of vars - varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE(new AstParseTypeDType($2)); } + varParamReset yTYPE { /*VARRESET-in-varParam*/ VARDTYPE(new AstParseTypeDType($2)); } ; -parameter_declarationFront: // IEEE: parameter_declaration w/o assignment - // // Front must execute first so VARDTYPE is ready before list of vars - varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); } - | varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); } - ; - -parameter_declarationTypeFront: // IEEE: parameter_declaration w/o assignment - // // Front must execute first so VARDTYPE is ready before list of vars - varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($2)); } - ; - -parameter_port_declarationFrontE: // IEEE: parameter_port_declaration w/o assignment +parameter_port_declarationFrontE: // IEEE: local_ or parameter_port_declaration w/o assignment // // IEEE: parameter_declaration (minus assignment) // // IEEE: local_parameter_declaration (minus assignment) // // Front must execute first so VARDTYPE is ready before list of vars - varGParamReset implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($2); } - | varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); } - | varLParamReset implicit_typeE { /*VARRESET-in-varLParam*/ VARDTYPE($2); } - | varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); } - | implicit_typeE { /*VARRESET-in-varGParam*/ VARDTYPE($1); } - | data_type { /*VARRESET-in-varGParam*/ VARDTYPE($1); } + varParamReset implicit_typeE { /*VARRESET-in-varParam*/ VARDTYPE($2); } + | varParamReset data_type { /*VARRESET-in-varParam*/ VARDTYPE($2); } + | implicit_typeE { /*VARRESET-in-varParam*/ VARDTYPE($1); } + | data_type { /*VARRESET-in-varParam*/ VARDTYPE($1); } ; parameter_port_declarationTypeFrontE: // IEEE: parameter_port_declaration w/o assignment // // IEEE: parameter_declaration (minus assignment) // // IEEE: local_parameter_declaration (minus assignment) // // Front must execute first so VARDTYPE is ready before list of vars - varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($2)); } - | varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE(new AstParseTypeDType($2)); } - | yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE(new AstParseTypeDType($1)); } + varParamReset yTYPE { /*VARRESET-in-varParam*/ VARDTYPE(new AstParseTypeDType($2)); } + | yTYPE { /*VARRESET-in-varParam*/ VARDTYPE(new AstParseTypeDType($1)); } ; net_declaration: // IEEE: net_declaration - excluding implict @@ -1480,12 +1470,9 @@ net_type: // ==IEEE: net_type | yWREAL { VARDECL(WREAL); } ; -varGParamReset: +varParamReset: yPARAMETER { VARRESET_NONLIST(GPARAM); } - ; - -varLParamReset: - yLOCALPARAM { VARRESET_NONLIST(LPARAM); } + | yLOCALPARAM { VARRESET_NONLIST(LPARAM); } ; port_direction: // ==IEEE: port_direction + tf_port_direction @@ -1516,17 +1503,17 @@ port_declaration: // ==IEEE: port_declaration // // IEEE: output_declaration // // IEEE: ref_declaration port_directionReset port_declNetE data_type { VARDTYPE($3); } - list_of_variable_decl_assignments { $$ = $5; } + /*cont*/ list_of_variable_decl_assignments { $$ = $5; } | port_directionReset port_declNetE yVAR data_type { VARDTYPE($4); } - list_of_variable_decl_assignments { $$ = $6; } + /*cont*/ list_of_variable_decl_assignments { $$ = $6; } | port_directionReset port_declNetE yVAR implicit_typeE { VARDTYPE($4); } - list_of_variable_decl_assignments { $$ = $6; } + /*cont*/ list_of_variable_decl_assignments { $$ = $6; } | port_directionReset port_declNetE signingE rangeList { VARDTYPE_NDECL(GRAMMARP->addRange(new AstBasicDType($4->fileline(), LOGIC_IMPLICIT, $3), $4, true)); } - list_of_variable_decl_assignments { $$ = $6; } + /*cont*/ list_of_variable_decl_assignments { $$ = $6; } | port_directionReset port_declNetE signing { VARDTYPE_NDECL(new AstBasicDType($3, LOGIC_IMPLICIT, $3)); } - list_of_variable_decl_assignments { $$ = $5; } + /*cont*/ list_of_variable_decl_assignments { $$ = $5; } | port_directionReset port_declNetE /*implicit*/ { VARDTYPE_NDECL(NULL);/*default_nettype*/} - list_of_variable_decl_assignments { $$ = $4; } + /*cont*/ list_of_variable_decl_assignments { $$ = $4; } // // IEEE: interface_declaration // // Looks just like variable declaration unless has a period // // See etcInst @@ -1576,19 +1563,6 @@ signing: // ==IEEE: signing //************************************************ // Data Types -casting_type: // IEEE: casting_type - simple_type { $$ = $1; } - // // IEEE: constant_primary - // // In expr:cast this is expanded to just "expr" - // - // // IEEE: signing - //See where casting_type used - //^^ ySIGNED { $$ = new AstSigned($1,$3); } - //^^ yUNSIGNED { $$ = new AstUnsigned($1,$3); } - //UNSUP ySTRING { $$ = $1; } - //UNSUP yCONST__ETC/*then `*/ { $$ = $1; } - ; - simple_type: // ==IEEE: simple_type // // IEEE: integer_type integer_atom_type { $$ = $1; } @@ -1596,7 +1570,12 @@ simple_type: // ==IEEE: simple_type | non_integer_type { $$ = $1; } // // IEEE: ps_type_identifier // // IEEE: ps_parameter_identifier (presumably a PARAMETER TYPE) - | ps_type { $$ = $1; } + // // Even though we looked up the type and have a AstNode* to it, + // // we can't fully resolve it because it may have been just a forward definition. + | package_scopeIdFollowsE idType + { AstRefDType* refp = new AstRefDType($2, *$2); + refp->packagep($1); $$ = refp; } + // // // { generate_block_identifer ... } '.' // // Need to determine if generate_block_identifier can be lex-detected ; @@ -1611,13 +1590,15 @@ data_type: // ==IEEE: data_type // // IEEE: class_type // // IEEE: ps_covergroup_identifier // // Don't distinguish between types and classes so all these combined - | package_scopeIdFollowsE idRefDType packed_dimensionListE - { $2->packagep($1); - $$ = GRAMMARP->createArray($2, $3, true); } - | package_scopeIdFollowsE idRefDType parameter_value_assignmentClass packed_dimensionListE - { $2->packagep($1); + | package_scopeIdFollowsE idType packed_dimensionListE + { AstRefDType* refp = new AstRefDType($2, *$2); + refp->packagep($1); + $$ = GRAMMARP->createArray(refp, $3, true); } + | package_scopeIdFollowsE idType parameter_value_assignmentClass packed_dimensionListE + { AstRefDType* refp = new AstRefDType($2, *$2); + refp->packagep($1); BBUNSUP($3->fileline(), "Unsupported: Parameter classes"); - $$ = GRAMMARP->createArray($2, $4, true); } + $$ = GRAMMARP->createArray(refp, $4, true); } ; data_typeBasic: // IEEE: part of data_type @@ -1666,10 +1647,10 @@ type_reference: // ==IEEE: type_reference struct_unionDecl: // IEEE: part of data_type // // packedSigningE is NOP for unpacked ySTRUCT packedSigningE '{' { $$ = new AstStructDType($1, $2); SYMP->pushNew($$); } - /*cont*/ struct_union_memberList '}' + /*cont*/ struct_union_memberList '}' { $$=$4; $$->addMembersp($5); SYMP->popScope($$); } | yUNION taggedE packedSigningE '{' { $$ = new AstUnionDType($1, $3); SYMP->pushNew($$); } - /*cont*/ struct_union_memberList '}' + /*cont*/ struct_union_memberList '}' { $$=$5; $$->addMembersp($6); SYMP->popScope($$); } ; @@ -1681,7 +1662,7 @@ struct_union_memberList: // IEEE: { struct_union_member } struct_union_member: // ==IEEE: struct_union_member random_qualifierE data_type_or_void { GRAMMARP->m_memDTypep = $2; } // As a list follows, need to attach this dtype to each member. - /*cont*/ list_of_member_decl_assignments ';' { $$ = $4; GRAMMARP->m_memDTypep = NULL; } + /*cont*/ list_of_member_decl_assignments ';' { $$ = $4; GRAMMARP->m_memDTypep = NULL; } ; list_of_member_decl_assignments: // Derived from IEEE: list_of_variable_decl_assignments @@ -1692,7 +1673,7 @@ list_of_member_decl_assignments: // Derived from IEEE: list_of_variable_d member_decl_assignment: // Derived from IEEE: variable_decl_assignment // // At present we allow only packed structures/unions. So this is different from variable_decl_assignment id variable_dimensionListE - { if ($2) $2->v3error("Unsupported: Unpacked array in packed struct/union"); + { if ($2) $2->v3warn(UNPACKED, "Unsupported: Unpacked array in packed struct/union (struct/union converted to unpacked)"); $$ = new AstMemberDType($1, *$1, VFlagChildDType(), AstNodeDType::cloneTreeNull(GRAMMARP->m_memDTypep, true)); PARSEP->tagNodep($$); @@ -1743,11 +1724,9 @@ list_of_tf_variable_identifiers: // ==IEEE: list_of_tf_variable_identifie ; tf_variable_identifier: // IEEE: part of list_of_tf_variable_identifiers - id variable_dimensionListE sigAttrListE - { $$ = VARDONEA($1,*$1, $2, $3); } - | id variable_dimensionListE sigAttrListE '=' expr + id variable_dimensionListE sigAttrListE exprEqE { $$ = VARDONEA($1,*$1, $2, $3); - $$->addNext(new AstAssign($4, new AstVarRef($1, *$1, true), $5)); } + if ($4) $$->addNext(new AstAssign($4->fileline(), new AstVarRef($1, *$1, true), $4)); } ; variable_declExpr: // IEEE: part of variable_decl_assignment - rhs of expr @@ -1828,8 +1807,10 @@ enum_base_typeE: // IEEE: enum_base_type // // however other simulators allow [ class_scope | package_scope ] type_identifier | idAny rangeListE { $$ = GRAMMARP->createArray(new AstRefDType($1, *$1), $2, true); } - | package_scopeIdFollows idRefDType rangeListE - { $2->packagep($1); $$ = GRAMMARP->createArray($2, $3, true); } + | package_scopeIdFollows idType rangeListE + { AstRefDType* refp = new AstRefDType($2, *$2); + refp->packagep($1); + $$ = GRAMMARP->createArray(refp, $3, true); } ; enum_nameList: @@ -1896,12 +1877,12 @@ data_declarationVarFront: // IEEE: part of data_declaration // // // Expanded: "constE yVAR lifetimeE data_type" // // implicit_type expanded into /*empty*/ or "signingE rangeList" - /**/ yVAR lifetimeE data_type + yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARLIFE($2); VARDTYPE($3); } - | /**/ yVAR lifetimeE + | yVAR lifetimeE { VARRESET_NONLIST(VAR); VARLIFE($2); VARDTYPE(new AstBasicDType($1, LOGIC_IMPLICIT)); } - | /**/ yVAR lifetimeE signingE rangeList + | yVAR lifetimeE signingE rangeList { /*VARRESET-in-ddVar*/ VARLIFE($2); VARDTYPE(GRAMMARP->addRange(new AstBasicDType($1, LOGIC_IMPLICIT, $3), $4,true)); } // @@ -1970,6 +1951,8 @@ type_declaration: // ==IEEE: type_declaration | yTYPEDEF id/*interface*/ '.' idAny/*type*/ idAny/*type*/ ';' { $$ = NULL; BBUNSUP($1, "Unsupported: SystemVerilog 2005 typedef in this context"); } // // Combines into above "data_type id" rule // // Verilator: Not important what it is in the AST, just need to make sure the yaID__aTYPE gets returned + //UNSUP // Below should be idAny to allow duplicate forward defs; need to expand + // // data_type to exclude IDs, or add id__SEMI rule | yTYPEDEF id ';' { $$ = NULL; $$ = new AstTypedefFwd($2, *$2); SYMP->reinsert($$); PARSEP->tagNodep($$); } | yTYPEDEF yENUM idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($3, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); } | yTYPEDEF ySTRUCT idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($3, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); } @@ -2305,7 +2288,13 @@ assignOne: delayE: /* empty */ { } - | delay_control { $1->v3warn(ASSIGNDLY,"Unsupported: Ignoring delay on this assignment/primitive."); DEL($1); } /* ignored */ + | delay { } + ; + +delay: + delay_control + { $1->v3warn(ASSIGNDLY, "Unsupported: Ignoring delay on this assignment/primitive."); + DEL($1); } ; delay_control: //== IEEE: delay_control @@ -2329,7 +2318,7 @@ delayExpr: minTypMax: // IEEE: mintypmax_expression and constant_mintypmax_expression delayExpr { $$ = $1; } - | delayExpr ':' delayExpr ':' delayExpr { $$ = $1; DEL($3); DEL($5); } + | delayExpr ':' delayExpr ':' delayExpr { $$ = $3; DEL($1); DEL($5); } ; netSigList: // IEEE: list_of_port_identifiers @@ -2419,12 +2408,8 @@ packed_dimension: // ==IEEE: packed_dimension param_assignment: // ==IEEE: param_assignment // // IEEE: constant_param_expression // // constant_param_expression: '$' is in expr - id/*new-parameter*/ variable_dimensionListE sigAttrListE '=' expr - /**/ { $$ = VARDONEA($1,*$1, $2, $3); $$->valuep($5); } - | id/*new-parameter*/ variable_dimensionListE sigAttrListE - /**/ { $$ = VARDONEA($1,*$1, $2, $3); - if ($1->language() < V3LangCode::L1800_2009) { - $1->v3error("Parameter requires default value, or use IEEE 1800-2009 or later."); } } + id/*new-parameter*/ variable_dimensionListE sigAttrListE exprEqE + { $$ = VARDONEA($1, *$1, $2, $3); if ($4) $$->valuep($4); } ; list_of_param_assignments: // ==IEEE: list_of_param_assignments @@ -2435,7 +2420,7 @@ list_of_param_assignments: // ==IEEE: list_of_param_assignments type_assignment: // ==IEEE: type_assignment // // note exptOrDataType being a data_type is only for yPARAMETER yTYPE idAny/*new-parameter*/ sigAttrListE '=' data_type - /**/ { $$ = VARDONEA($1,*$1, NULL, $2); $$->valuep($4); } + { $$ = VARDONEA($1, *$1, NULL, $2); $$->valuep($4); } ; list_of_type_assignments: // ==IEEE: list_of_type_assignments @@ -2449,8 +2434,10 @@ list_of_defparam_assignments: //== IEEE: list_of_defparam_assignments ; defparam_assignment: // ==IEEE: defparam_assignment - id '.' id '=' expr { $$ = new AstDefParam($4,*$1,*$3,$5); } - //UNSUP More general dotted identifiers + idAny '.' idAny '=' expr { $$ = new AstDefParam($4, *$1, *$3, $5); } + | idAny '.' idAny '.' + { $$ = NULL; + BBUNSUP($4, "Unsupported: defparam with more than one dot"); } ; //************************************************ @@ -2478,7 +2465,7 @@ instDecl: | id/*interface*/ '.' id/*modport*/ { VARRESET_NONLIST(AstVarType::IFACEREF); VARDTYPE(new AstIfaceRefDType($1, $3, "", *$1, *$3)); } - mpInstnameList ';' + /*cont*/ mpInstnameList ';' { $$ = VARDONEP($5,NULL,NULL); } //UNSUP: strengthSpecE for udp_instantiations ; @@ -2549,7 +2536,7 @@ cellpinItList: // IEEE: list_of_port_connections ; cellparamItemE: // IEEE: named_parameter_assignment + empty - // Note empty can match either () or (,); V3LinkCells cleans up () + // // Note empty can match either () or (,); V3LinkCells cleans up () /* empty: ',,' is legal */ { $$ = new AstPin(CRELINE(), PINNUMINC(), "", NULL); } | yP_DOTSTAR { $$ = new AstPin($1,PINNUMINC(),".*",NULL); } | '.' idSVKwd { $$ = new AstPin($2,PINNUMINC(), *$2, @@ -2560,21 +2547,18 @@ cellparamItemE: // IEEE: named_parameter_assignment + empty $$->svImplicit(true);} | '.' idAny '(' ')' { $$ = new AstPin($2,PINNUMINC(),*$2,NULL); } // // mintypmax is expanded here, as it might be a UDP or gate primitive - | '.' idAny '(' expr ')' { $$ = new AstPin($2,PINNUMINC(),*$2,$4); } - //UNSUP '.' idAny '(' expr ':' expr ')' { } - //UNSUP '.' idAny '(' expr ':' expr ':' expr ')' { } - // // For parameters - | '.' idAny '(' data_type ')' { $$ = new AstPin($2, PINNUMINC(), *$2, $4); } - // // For parameters - | data_type { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); } - // - | expr { $$ = new AstPin($1->fileline(),PINNUMINC(),"",$1); } - //UNSUP expr ':' expr { } - //UNSUP expr ':' expr ':' expr { } + // // data_type for 'parameter type' hookups + | '.' idAny '(' exprOrDataType ')' { $$ = new AstPin($2, PINNUMINC(), *$2, $4); } + //UNSUP '.' idAny '(' exprOrDataType/*expr*/ ':' expr ')' { } + //UNSUP '.' idAny '(' exprOrDataType/*expr*/ ':' expr ':' expr ')' { } + // // data_type for 'parameter type' hookups + | exprOrDataType { $$ = new AstPin($1->fileline(), PINNUMINC(), "", $1); } + //UNSUP exprOrDataType/*expr*/ ':' expr { } + //UNSUP exprOrDataType/*expr*/ ':' expr ':' expr { } ; cellpinItemE: // IEEE: named_port_connection + empty - // Note empty can match either () or (,); V3LinkCells cleans up () + // // Note empty can match either () or (,); V3LinkCells cleans up () /* empty: ',,' is legal */ { $$ = new AstPin(CRELINE(), PINNUMINC(), "", NULL); } | yP_DOTSTAR { $$ = new AstPin($1,PINNUMINC(),".*",NULL); } | '.' idSVKwd { $$ = new AstPin($2,PINNUMINC(),*$2,new AstParseRef($2,VParseRefExp::PX_TEXT,*$2,NULL,NULL)); $$->svImplicit(true);} @@ -2736,7 +2720,6 @@ block_item_declarationList: // IEEE: [ block_item_declaration ] block_item_declaration: // ==IEEE: block_item_declaration data_declaration { $$ = $1; } - | local_parameter_declaration ';' { $$ = $1; } | parameter_declaration ';' { $$ = $1; } //UNSUP let_declaration { $$ = $1; } ; @@ -2818,7 +2801,7 @@ statement_item: // IEEE: statement_item newfl->warnOff(V3ErrorCode::IGNOREDRETURN, true); $$->fileline(newfl); } | yVOID yP_TICK '(' expr '.' task_subroutine_callNoMethod ')' ';' - { $$ = new AstDot($5, $4, $6); + { $$ = new AstDot($5, false, $4, $6); FileLine* newfl = new FileLine($6->fileline()); newfl->warnOff(V3ErrorCode::IGNOREDRETURN, true); $6->fileline(newfl); } @@ -2826,7 +2809,7 @@ statement_item: // IEEE: statement_item // // Expr here must result in a subroutine_call | task_subroutine_callNoMethod ';' { $$ = $1; } //UNSUP fexpr '.' array_methodNoRoot ';' { UNSUP } - | fexpr '.' task_subroutine_callNoMethod ';' { $$ = new AstDot($2,$1,$3); } + | fexpr '.' task_subroutine_callNoMethod ';' { $$ = new AstDot($2, false, $1, $3); } //UNSUP fexprScope ';' { UNSUP } // // Not here in IEEE; from class_constructor_declaration // // Because we've joined class_constructor_declaration into generic functions @@ -2932,7 +2915,7 @@ statementVerilatorPragmas: foperator_assignment: // IEEE: operator_assignment (for first part of expression) fexprLvalue '=' delayE expr { $$ = new AstAssign($2,$1,$4); } - | fexprLvalue '=' yD_FOPEN '(' expr ')' { $$ = NULL; BBUNSUP($3, "Unsupported: $fopen with multichannel descriptor. Add ,\"w\" as second argument to open a file descriptor."); } + | fexprLvalue '=' yD_FOPEN '(' expr ')' { $$ = new AstFOpenMcd($3,$1,$5); } | fexprLvalue '=' yD_FOPEN '(' expr ',' expr ')' { $$ = new AstFOpen($3,$1,$5,$7); } // //UNSUP ~f~exprLvalue '=' delay_or_event_controlE expr { UNSUP } @@ -2952,23 +2935,17 @@ foperator_assignment: // IEEE: operator_assignment (for first part of exp //UNSUP BISONPRE_COPY(operator_assignment,{s/~f~/f/g}) // {copied} ; -//UNSUPinc_or_dec_expression: // ==IEEE: inc_or_dec_expression -//UNSUP // // Need fexprScope instead of variable_lvalue to prevent conflict -//UNSUP ~l~exprScope yP_PLUSPLUS { $$=$1; $$ = $1+$2; } -//UNSUP | ~l~exprScope yP_MINUSMINUS { $$=$1; $$ = $1+$2; } -//UNSUP // // Need expr instead of variable_lvalue to prevent conflict -//UNSUP | yP_PLUSPLUS expr { $$=$1; $$ = $1+$2; } -//UNSUP | yP_MINUSMINUS expr { $$=$1; $$ = $1+$2; } -//UNSUP ; +inc_or_dec_expression: // ==IEEE: inc_or_dec_expression + // // Need fexprScope instead of variable_lvalue to prevent conflict + ~l~exprScope yP_PLUSPLUS { $$=$1; $$ = new AstPostAdd($2, new AstConst($2, AstConst::StringToParse(), "'b1"), $1, $1->cloneTree(true)); } + | ~l~exprScope yP_MINUSMINUS { $$=$1; $$ = new AstPostSub($2, new AstConst($2, AstConst::StringToParse(), "'b1"), $1, $1->cloneTree(true)); } + // // Need expr instead of variable_lvalue to prevent conflict + | yP_PLUSPLUS expr { $$=$1; $$ = new AstPreAdd($1, new AstConst($1, AstConst::StringToParse(), "'b1"), $2, $2->cloneTree(true)); } + | yP_MINUSMINUS expr { $$=$1; $$ = new AstPreSub($1, new AstConst($1, AstConst::StringToParse(), "'b1"), $2, $2->cloneTree(true)); } + ; finc_or_dec_expression: // ==IEEE: inc_or_dec_expression - //UNSUP: Generic scopes in incrementes, remove below - fexprLvalue yP_PLUSPLUS { $$ = new AstAssign($2,$1,new AstAdd ($2,$1->cloneTree(true),new AstConst($2, AstConst::StringToParse(), "'b1"))); } - | fexprLvalue yP_MINUSMINUS { $$ = new AstAssign($2,$1,new AstSub ($2,$1->cloneTree(true),new AstConst($2, AstConst::StringToParse(), "'b1"))); } - | yP_PLUSPLUS fexprLvalue { $$ = new AstAssign($1,$2,new AstAdd ($1,$2->cloneTree(true),new AstConst($1, AstConst::StringToParse(), "'b1"))); } - | yP_MINUSMINUS fexprLvalue { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1, AstConst::StringToParse(), "'b1"))); } - //UNSUP: Generic scopes in incrementes, remove above - //UNSUP BISONPRE_COPY(inc_or_dec_expression,{s/~l~/f/g}) // {copied} + BISONPRE_COPY(inc_or_dec_expression,{s/~l~/f/g}) // {copied} ; //UNSUPsinc_or_dec_expression: // IEEE: inc_or_dec_expression (for sequence_expression) @@ -3124,7 +3101,7 @@ patternKey: // IEEE: merge structure_pattern_key, array_pattern_key, ass // // So for now we only allow a true constant number, or a identifier which we treat as a structure member name yaINTNUM { $$ = new AstConst($1,*$1); } | yaFLOATNUM { $$ = new AstConst($1,AstConst::RealDouble(),$1); } - | yaID__ETC { $$ = new AstText($1,*$1); } + | id { $$ = new AstText($1,*$1); } | strAsInt { $$ = $1; } ; @@ -3208,7 +3185,8 @@ loop_variables: // IEEE: loop_variables taskRef: // IEEE: part of tf_call id { $$ = new AstTaskRef($1,*$1,NULL); } | id '(' list_of_argumentsE ')' { $$ = new AstTaskRef($1,*$1,$3); } - | package_scopeIdFollows id '(' list_of_argumentsE ')' { $$ = AstDot::newIfPkg($2, $1, new AstTaskRef($2,*$2,$4)); } + | package_scopeIdFollows id '(' list_of_argumentsE ')' + { $$ = AstDot::newIfPkg($2, $1, new AstTaskRef($2,*$2,$4)); } ; funcRef: // IEEE: part of tf_call @@ -3222,7 +3200,8 @@ funcRef: // IEEE: part of tf_call // // let_expression let_identifier let_actual_arg // id '(' list_of_argumentsE ')' { $$ = new AstFuncRef($1, *$1, $3); } - | package_scopeIdFollows id '(' list_of_argumentsE ')' { $$ = AstDot::newIfPkg($2, $1, new AstFuncRef($2,*$2,$4)); } + | package_scopeIdFollows id '(' list_of_argumentsE ')' + { $$ = AstDot::newIfPkg($2, $1, new AstFuncRef($2,*$2,$4)); } //UNSUP list_of_argumentE should be pev_list_of_argumentE //UNSUP: idDotted is really just id to allow dotted method calls ; @@ -3255,12 +3234,7 @@ function_subroutine_callNoMethod: // IEEE: function_subroutine_call (as f system_t_call: // IEEE: system_tf_call (as task) // - yaD_IGNORE parenE { $$ = new AstSysIgnore($1,NULL); } - | yaD_IGNORE '(' exprList ')' { $$ = new AstSysIgnore($1,$3); } - // - | yaD_DPI parenE { $$ = new AstTaskRef($1,*$1,NULL); } - | yaD_DPI '(' exprList ')' { $$ = new AstTaskRef($1, *$1, $3); - GRAMMARP->argWrapList(VN_CAST($$, TaskRef)); } + yaD_PLI systemDpiArgsE { $$ = new AstTaskRef($1, *$1, $2); VN_CAST($$, TaskRef)->pli(true); } // | yD_DUMPPORTS '(' idDotted ',' expr ')' { $$ = new AstDumpCtl($1, VDumpCtlType::FILE, $5); DEL($3); $$->addNext(new AstDumpCtl($1, VDumpCtlType::VARS, @@ -3302,42 +3276,42 @@ system_t_call: // IEEE: system_tf_call (as task) | yD_SWRITEO '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1, $3, *$5, $6, 'o'); } // | yD_DISPLAY parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, NULL); } - | yD_DISPLAY '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3); } + | yD_DISPLAY '(' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3); } | yD_DISPLAYB parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, NULL, 'b'); } - | yD_DISPLAYB '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3, 'b'); } + | yD_DISPLAYB '(' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3, 'b'); } | yD_DISPLAYH parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, NULL, 'h'); } - | yD_DISPLAYH '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3, 'h'); } + | yD_DISPLAYH '(' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3, 'h'); } | yD_DISPLAYO parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, NULL, 'o'); } - | yD_DISPLAYO '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3, 'o'); } + | yD_DISPLAYO '(' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, NULL, $3, 'o'); } | yD_WRITE parenE { $$ = NULL; } // NOP - | yD_WRITE '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3); } + | yD_WRITE '(' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3); } | yD_WRITEB parenE { $$ = NULL; } // NOP - | yD_WRITEB '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3, 'b'); } + | yD_WRITEB '(' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3, 'b'); } | yD_WRITEH parenE { $$ = NULL; } // NOP - | yD_WRITEH '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3, 'h'); } + | yD_WRITEH '(' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3, 'h'); } | yD_WRITEO parenE { $$ = NULL; } // NOP - | yD_WRITEO '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3, 'o'); } + | yD_WRITEO '(' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, NULL, $3, 'o'); } | yD_FDISPLAY '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL); } - | yD_FDISPLAY '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5); } - | yD_FDISPLAYB '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL, 'b'); } - | yD_FDISPLAYB '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5, 'b'); } - | yD_FDISPLAYH '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL, 'h'); } - | yD_FDISPLAYH '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5, 'h'); } - | yD_FDISPLAYO '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL, 'o'); } - | yD_FDISPLAYO '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5, 'o'); } - | yD_FWRITE '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5); } - | yD_FWRITEB '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5, 'b'); } - | yD_FWRITEO '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5, 'h'); } - | yD_FWRITEH '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5, 'o'); } + | yD_FDISPLAY '(' expr ',' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5); } + | yD_FDISPLAYB '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL, 'b'); } + | yD_FDISPLAYB '(' expr ',' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5, 'b'); } + | yD_FDISPLAYH '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL, 'h'); } + | yD_FDISPLAYH '(' expr ',' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5, 'h'); } + | yD_FDISPLAYO '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, NULL, 'o'); } + | yD_FDISPLAYO '(' expr ',' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY, $3, $5, 'o'); } + | yD_FWRITE '(' expr ',' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5); } + | yD_FWRITEB '(' expr ',' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5, 'b'); } + | yD_FWRITEO '(' expr ',' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5, 'h'); } + | yD_FWRITEH '(' expr ',' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WRITE, $3, $5, 'o'); } | yD_INFO parenE { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, NULL, NULL); } - | yD_INFO '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, NULL, $3); } + | yD_INFO '(' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_INFO, NULL, $3); } | yD_WARNING parenE { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING, NULL, NULL); } - | yD_WARNING '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING, NULL, $3); } + | yD_WARNING '(' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_WARNING, NULL, $3); } | yD_ERROR parenE { $$ = GRAMMARP->createDisplayError($1); } - | yD_ERROR '(' exprList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_ERROR, NULL, $3); $$->addNext(new AstStop($1, true)); } + | yD_ERROR '(' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_ERROR, NULL, $3); $$->addNext(new AstStop($1, true)); } | yD_FATAL parenE { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, NULL, NULL); $$->addNext(new AstStop($1, false)); } | yD_FATAL '(' expr ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, NULL, NULL); $$->addNext(new AstStop($1, false)); DEL($3); } - | yD_FATAL '(' expr ',' exprListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, NULL, $5); $$->addNext(new AstStop($1, false)); DEL($3); } + | yD_FATAL '(' expr ',' exprDispList ')' { $$ = new AstDisplay($1,AstDisplayType::DT_FATAL, NULL, $5); $$->addNext(new AstStop($1, false)); DEL($3); } // | yD_PRINTTIMESCALE { $$ = new AstPrintTimeScale($1); } | yD_PRINTTIMESCALE '(' ')' { $$ = new AstPrintTimeScale($1); } @@ -3360,11 +3334,7 @@ system_t_call: // IEEE: system_tf_call (as task) ; system_f_call: // IEEE: system_tf_call (as func) - yaD_IGNORE parenE { $$ = new AstConst($1, AstConst::StringToParse(), "'b0"); } // Unsized 0 - | yaD_IGNORE '(' exprList ')' { $$ = new AstConst($1, AstConst::StringToParse(), "'b0"); } // Unsized 0 - // - | yaD_DPI parenE { $$ = new AstFuncRef($1,*$1,NULL); } - | yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($1,*$1,$3); GRAMMARP->argWrapList(VN_CAST($$, FuncRef)); } + yaD_PLI systemDpiArgsE { $$ = new AstFuncRef($1, *$1, $2); VN_CAST($$, FuncRef)->pli(true); } // | yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCFunc($1,$3)); } | yD_SYSTEM '(' expr ')' { $$ = new AstSystemF($1,$3); } @@ -3372,6 +3342,11 @@ system_f_call: // IEEE: system_tf_call (as func) | system_f_call_or_t { $$ = $1; } ; +systemDpiArgsE: // IEEE: part of system_if_call for aruments of $dpi call + parenE { $$ = NULL; } + | '(' exprList ')' { $$ = GRAMMARP->argWrapList($2); } + ; + system_f_call_or_t: // IEEE: part of system_tf_call (can be task or func) yD_ACOS '(' expr ')' { $$ = new AstAcosD($1,$3); } | yD_ACOSH '(' expr ')' { $$ = new AstAcoshD($1,$3); } @@ -3388,6 +3363,12 @@ system_f_call_or_t: // IEEE: part of system_tf_call (can be task or func) | yD_CLOG2 '(' expr ')' { $$ = new AstCLog2($1,$3); } | yD_COS '(' expr ')' { $$ = new AstCosD($1,$3); } | yD_COSH '(' expr ')' { $$ = new AstCoshD($1,$3); } + | yD_COUNTBITS '(' expr ',' expr ')' { $$ = new AstCountBits($1,$3,$5); } + | yD_COUNTBITS '(' expr ',' expr ',' expr ')' { $$ = new AstCountBits($1,$3,$5,$7); } + | yD_COUNTBITS '(' expr ',' expr ',' expr ',' expr ')' { $$ = new AstCountBits($1,$3,$5,$7,$9); } + | yD_COUNTBITS '(' expr ',' expr ',' expr ',' expr ',' exprList ')' + { $$ = new AstCountBits($1, $3, $5, $7, $9); + $11->v3error("Unsupported: $countbits with more than 3 control fields"); } | yD_COUNTONES '(' expr ')' { $$ = new AstCountOnes($1,$3); } | yD_DIMENSIONS '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_DIMENSIONS,$3); } | yD_EXP '(' expr ')' { $$ = new AstExpD($1,$3); } @@ -3408,7 +3389,8 @@ system_f_call_or_t: // IEEE: part of system_tf_call (can be task or func) | yD_HYPOT '(' expr ',' expr ')' { $$ = new AstHypotD($1,$3,$5); } | yD_INCREMENT '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_INCREMENT,$3,NULL); } | yD_INCREMENT '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_INCREMENT,$3,$5); } - | yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown($1,$3); } + | yD_ISUNBOUNDED '(' expr ')' { $$ = new AstIsUnbounded($1, $3); } + | yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown($1, $3); } | yD_ITOR '(' expr ')' { $$ = new AstIToRD($1,$3); } | yD_LEFT '(' exprOrDataType ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LEFT,$3,NULL); } | yD_LEFT '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf($1,AstAttrType::DIM_LEFT,$3,$5); } @@ -3423,7 +3405,8 @@ system_f_call_or_t: // IEEE: part of system_tf_call (can be task or func) | yD_PAST '(' expr ',' expr ',' expr ')' { $1->v3error("Unsupported: $past expr2 and clock arguments"); $$ = $3; } | yD_PAST '(' expr ',' expr ',' expr ',' expr')' { $1->v3error("Unsupported: $past expr2 and clock arguments"); $$ = $3; } | yD_POW '(' expr ',' expr ')' { $$ = new AstPowD($1,$3,$5); } - | yD_RANDOM '(' expr ')' { $$ = NULL; $1->v3error("Unsupported: Seeding $random doesn't map to C++, use $c(\"srand\")"); } + // // Seeding is unsupported as would be slow to invalidate all per-thread RNGs + | yD_RANDOM '(' expr ')' { $$ = new AstRand($1); $1->v3error("Unsupported: Seed on $random. Suggest use +verilator+seed+ runtime flag"); } | yD_RANDOM parenE { $$ = new AstRand($1); } | yD_REALTIME parenE { $$ = new AstTimeD($1, VTimescale(VTimescale::NONE)); } | yD_REALTOBITS '(' expr ')' { $$ = new AstRealToBits($1,$3); } @@ -3503,8 +3486,10 @@ exprOrDataType: // expr | data_type: combined to prevent conflicts list_of_argumentsE: // IEEE: [list_of_arguments] argsDottedList { $$ = $1; } - | argsExprListE { if (VN_IS($1, Arg) && VN_CAST($1, Arg)->emptyConnectNoNext()) { $1->deleteTree(); $$ = NULL; } // Mis-created when have 'func()' - /*cont*/ else $$ = $1; } + | argsExprListE + { if (VN_IS($1, Arg) && VN_CAST($1, Arg)->emptyConnectNoNext()) { + $1->deleteTree(); $$ = NULL; // Mis-created when have 'func()' + } else { $$ = $1; } } | argsExprListE ',' argsDottedList { $$ = $1->addNextNull($3); } ; @@ -3521,7 +3506,7 @@ task_prototype: // ==IEEE: task_prototype ; function_declaration: // IEEE: function_declaration + function_body_declaration - yFUNCTION lifetimeE funcId funcIsolateE tfGuts yENDFUNCTION endLabelE + yFUNCTION lifetimeE funcId funcIsolateE tfGuts yENDFUNCTION endLabelE { $$ = $3; $3->attrIsolateAssign($4); $$->addStmtsp($5); $$->lifetime($2); SYMP->popScope($$); @@ -3589,8 +3574,8 @@ funcId: // IEEE: function_data_type_or_implicit + part of function_bod { $$ = new AstFunc($2,*$2,NULL,$1); SYMP->pushNewUnder($$, NULL); } // // To verilator tasks are the same as void functions (we separately detect time passing) - | yVOID tfIdScoped - { $$ = new AstTask($2,*$2,NULL); + | yVOID tfIdScoped + { $$ = new AstTask($2, *$2, NULL); SYMP->pushNewUnder($$, NULL); } ; @@ -3648,8 +3633,9 @@ tf_item_declarationVerilator: // Verilator extensions tf_port_listE: // IEEE: tf_port_list + empty // // Empty covered by tf_port_item - {VARRESET_LIST(UNKNOWN); VARIO(INPUT); } - tf_port_listList { $$ = $2; VARRESET_NONLIST(UNKNOWN); } + /*empty*/ + { VARRESET_LIST(UNKNOWN); VARIO(INPUT); } + /*cont*/ tf_port_listList { $$ = $2; VARRESET_NONLIST(UNKNOWN); } ; tf_port_listList: // IEEE: part of tf_port_list @@ -3684,10 +3670,8 @@ tf_port_itemDir: // IEEE: part of tf_port_item, direction ; tf_port_itemAssignment: // IEEE: part of tf_port_item, which has assignment - id variable_dimensionListE sigAttrListE - { $$ = VARDONEA($1, *$1, $2, $3); } - | id variable_dimensionListE sigAttrListE '=' expr - { $$ = VARDONEA($1, *$1, $2, $3); $$->valuep($5); } + id variable_dimensionListE sigAttrListE exprEqE + { $$ = VARDONEA($1, *$1, $2, $3); if ($4) $$->valuep($4); } ; parenE: @@ -3706,24 +3690,28 @@ array_methodNoRoot: yOR { $$ = new AstFuncRef($1, "or", NULL); } | yAND { $$ = new AstFuncRef($1, "and", NULL); } | yXOR { $$ = new AstFuncRef($1, "xor", NULL); } - //UNSUP yUNIQUE { $$ = new AstFuncRef($1, "unique", NULL); } + | yUNIQUE { $$ = new AstFuncRef($1, "unique", NULL); } ; dpi_import_export: // ==IEEE: dpi_import_export yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE function_prototype ';' - { $$ = $5; if (*$4!="") $5->cname(*$4); $5->dpiContext($3==iprop_CONTEXT); $5->pure($3==iprop_PURE); + { $$ = $5; if (*$4 != "") $5->cname(*$4); + $5->dpiContext($3==iprop_CONTEXT); $5->pure($3==iprop_PURE); $5->dpiImport(true); GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); if ($$->prettyName()[0]=='$') SYMP->reinsert($$,NULL,$$->prettyName()); // For $SysTF overriding SYMP->reinsert($$); } | yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE task_prototype ';' - { $$ = $5; if (*$4!="") $5->cname(*$4); $5->dpiContext($3==iprop_CONTEXT); $5->pure($3==iprop_PURE); + { $$ = $5; if (*$4 != "") $5->cname(*$4); + $5->dpiContext($3==iprop_CONTEXT); $5->pure($3==iprop_PURE); $5->dpiImport(true); $5->dpiTask(true); GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); if ($$->prettyName()[0]=='$') SYMP->reinsert($$,NULL,$$->prettyName()); // For $SysTF overriding SYMP->reinsert($$); } - | yEXPORT yaSTRING dpi_importLabelE yFUNCTION idAny ';' { $$ = new AstDpiExport($5, *$5, *$3); - GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); } - | yEXPORT yaSTRING dpi_importLabelE yTASK idAny ';' { $$ = new AstDpiExport($5, *$5, *$3); - GRAMMARP->checkDpiVer($1,*$2); v3Global.dpi(true); } + | yEXPORT yaSTRING dpi_importLabelE yFUNCTION idAny ';' + { $$ = new AstDpiExport($5, *$5, *$3); + GRAMMARP->checkDpiVer($1, *$2); v3Global.dpi(true); } + | yEXPORT yaSTRING dpi_importLabelE yTASK idAny ';' + { $$ = new AstDpiExport($5, *$5, *$3); + GRAMMARP->checkDpiVer($1, *$2); v3Global.dpi(true); } ; dpi_importLabelE: // IEEE: part of dpi_import_export @@ -3748,6 +3736,12 @@ dpi_tf_import_propertyE: // IEEE: [ dpi_function_import_property + dpi_ta // ~p~ means this is a (p)arenthetized expression // it will get replaced by "", or "s"equence +exprEqE: // IEEE: optional '=' expression (part of param_assignment) + // // constant_param_expression: '$' is in expr + /*empty*/ { $$ = NULL; } + | '=' expr { $$ = $2; } + ; + constExpr: expr { $$ = $1; } ; @@ -3768,7 +3762,7 @@ expr: // IEEE: part of expression/constant_expression/primary | yP_XNOR ~r~expr %prec prREDUCTION { $$ = new AstRedXnor ($1,$2); } // // // IEEE: inc_or_dec_expression - //UNSUP ~l~inc_or_dec_expression { UNSUP } + | ~l~inc_or_dec_expression { $$=$1; $$ = $1; } // // // IEEE: '(' operator_assignment ')' // // Need exprScope of variable_lvalue to prevent conflict @@ -3859,9 +3853,9 @@ expr: // IEEE: part of expression/constant_expression/primary // | function_subroutine_callNoMethod { $$ = $1; } // // method_call - | ~l~expr '.' function_subroutine_callNoMethod { $$ = new AstDot($2,$1,$3); } + | ~l~expr '.' function_subroutine_callNoMethod { $$ = new AstDot($2, false, $1, $3); } // // method_call:array_method requires a '.' - | ~l~expr '.' array_methodNoRoot { $$ = new AstDot($2,$1,$3); } + | ~l~expr '.' array_methodNoRoot { $$ = new AstDot($2, false, $1, $3); } // // // IEEE: let_expression // // see funcRef @@ -3873,13 +3867,15 @@ expr: // IEEE: part of expression/constant_expression/primary | '_' '(' expr ')' { $$ = $3; } // Arbitrary Verilog inside PSL // // // IEEE: cast/constant_cast - | casting_type yP_TICK '(' expr ')' { $$ = new AstCast($1->fileline(), $4, $1); } // // expanded from casting_type - | ySIGNED yP_TICK '(' expr ')' { $$ = new AstSigned($1,$4); } - | yUNSIGNED yP_TICK '(' expr ')' { $$ = new AstUnsigned($1,$4); } + | simple_type yP_TICK '(' expr ')' { $$ = new AstCast($1->fileline(), $4, $1); } + | ySIGNED yP_TICK '(' expr ')' { $$ = new AstSigned($1, $4); } + | yUNSIGNED yP_TICK '(' expr ')' { $$ = new AstUnsigned($1, $4); } + | ySTRING yP_TICK '(' expr ')' { $$ = new AstCvtPackString($1, $4); } + | yCONST__ETC yP_TICK '(' expr ')' { $$ = $4; } // Not linting const presently // // Spec only allows primary with addition of a type reference // // We'll be more general, and later assert LHS was a type. - | ~l~expr yP_TICK '(' expr ')' { $$ = new AstCastParse($2,$4,$1); } + | ~l~expr yP_TICK '(' expr ')' { $$ = new AstCastParse($2,$4,$1); } // // // IEEE: assignment_pattern_expression // // IEEE: streaming_concatenation @@ -4013,7 +4009,7 @@ exprScope: // scope and variable for use to inside an expression | idArrayed { $$ = $1; } | package_scopeIdFollows idArrayed { $$ = AstDot::newIfPkg($2->fileline(), $1, $2); } | class_scopeIdFollows idArrayed { $$ = $2; BBUNSUP($1, "Unsupported: scoped class reference"); } - | ~l~expr '.' idArrayed { $$ = new AstDot($2,$1,$3); } + | ~l~expr '.' idArrayed { $$ = new AstDot($2, false, $1, $3); } // // expr below must be a "yTHIS" | ~l~expr '.' ySUPER { $$ = $1; BBUNSUP($3, "Unsupported: super"); } // // Part of implicit_class_handle @@ -4069,6 +4065,14 @@ exprList: | exprList ',' expr { $$ = $1;$1->addNext($3); } ; +exprDispList: // exprList for within $display + expr { $$ = $1; } + | exprDispList ',' expr { $$ = $1; $1->addNext($3); } + // // ,, creates a space in $display + | exprDispList ',' /*empty*/ + { $$ = $1; $1->addNext(new AstConst($2, AstConst::VerilogStringLiteral(), " ")); } + ; + commaEListE: /* empty */ { $$ = NULL; } | ',' exprList { $$ = $2; } @@ -4137,21 +4141,18 @@ streaming_concatenation: // ==IEEE: streaming_concatenation // // IEEE: "'{' yP_SL/R stream_concatenation '}'" // // IEEE: "'{' yP_SL/R simple_type stream_concatenation '}'" // // IEEE: "'{' yP_SL/R constExpr stream_concatenation '}'" - '{' yP_SLEFT stream_concOrExprOrType '}' { $$ = new AstStreamL($2, $3, new AstConst($2,1)); } - | '{' yP_SRIGHT stream_concOrExprOrType '}' { $$ = new AstStreamR($2, $3, new AstConst($2,1)); } - | '{' yP_SLEFT stream_concOrExprOrType stream_concatenation '}' { $$ = new AstStreamL($2, $4, $3); } - | '{' yP_SRIGHT stream_concOrExprOrType stream_concatenation '}' { $$ = new AstStreamR($2, $4, $3); } - ; - -stream_concOrExprOrType: // IEEE: stream_concatenation | slice_size:simple_type | slice_size:constExpr - cateList { $$ = $1; } - | simple_type { $$ = $1; } - // // stream_concatenation found via cateList:stream_expr:'{-normal-concat' - // // simple_typeRef found via cateList:stream_expr:expr:id - // // constant_expression found via cateList:stream_expr:expr + '{' yP_SLEFT stream_concatenation '}' + { $$ = new AstStreamL($2, $3, new AstConst($2, 1)); } + | '{' yP_SRIGHT stream_concatenation '}' + { $$ = new AstStreamR($2, $3, new AstConst($2, 1)); } + | '{' yP_SLEFT stream_expressionOrDataType stream_concatenation '}' + { $$ = new AstStreamL($2, $4, $3); } + | '{' yP_SRIGHT stream_expressionOrDataType stream_concatenation '}' + { $$ = new AstStreamR($2, $4, $3); } ; stream_concatenation: // ==IEEE: stream_concatenation + // // '{' { stream_expression } '}' '{' cateList '}' { $$ = $2; } ; @@ -4164,6 +4165,14 @@ stream_expression: // ==IEEE: stream_expression //UNSUP expr yWITH__BRA '[' expr yP_MINUSCOLON expr ']' { UNSUP } ; +stream_expressionOrDataType: // IEEE: from streaming_concatenation + exprOrDataType { $$ = $1; } + //UNSUP expr yWITH__BRA '[' expr ']' { UNSUP } + //UNSUP expr yWITH__BRA '[' expr ':' expr ']' { UNSUP } + //UNSUP expr yWITH__BRA '[' expr yP_PLUSCOLON expr ']' { UNSUP } + //UNSUP expr yWITH__BRA '[' expr yP_MINUSCOLON expr ']' { UNSUP } + ; + //************************************************ // Gate declarations @@ -4265,6 +4274,8 @@ gateRangeE: gateBuf: gateFront variable_lvalue ',' gatePinExpr ')' { $$ = new AstAssignW($1, $2, $4); DEL($1); } + // UNSUP // IEEE: Multiple output variable_lvalues + // UNSUP // Causes conflict - need to take in variable_lvalue or a gatePinExpr ; gateBufif0: gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')' @@ -4277,6 +4288,8 @@ gateBufif1: gateNot: gateFront variable_lvalue ',' gatePinExpr ')' { $$ = new AstAssignW($1, $2, new AstNot($1, $4)); DEL($1); } + // UNSUP // IEEE: Multiple output variable_lvalues + // UNSUP // Causes conflict - need to take in variable_lvalue or a gatePinExpr ; gateNotif0: gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')' @@ -4407,7 +4420,7 @@ specparam_declaration: // ==IEEE: specparam_declaration junkToSemiList: junkToSemi { } /* ignored */ | junkToSemiList junkToSemi { } /* ignored */ - ; + ; junkToSemi: BISONPRE_NOT(';',yENDSPECIFY,yENDMODULE) { } @@ -4427,9 +4440,9 @@ idAny: // Any kind of identifier | yaID__ETC { $$ = $1; $$=$1; } ; -idRefDType: // IEEE: class_identifier or other type identifier - // Used where reference is needed - yaID__aTYPE { $$ = new AstRefDType($1, *$1); } +idType: // IEEE: class_identifier or other type identifier + // // Used where reference is needed + yaID__aTYPE { $$ = $1; $$=$1; } ; idSVKwd: // Warn about non-forward compatible Verilog 2001 code @@ -4474,13 +4487,13 @@ idClassSel: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged va idDotted: yD_ROOT '.' idDottedMore - { $$ = new AstDot($2, new AstParseRef($1, VParseRefExp::PX_ROOT, "$root"), $3); } + { $$ = new AstDot($2, false, new AstParseRef($1, VParseRefExp::PX_ROOT, "$root"), $3); } | idDottedMore { $$ = $1; } ; idDottedMore: idArrayed { $$ = $1; } - | idDottedMore '.' idArrayed { $$ = new AstDot($2,$1,$3); } + | idDottedMore '.' idArrayed { $$ = new AstDot($2, false, $1, $3); } ; // Single component of dotted path, maybe [#]. @@ -4505,7 +4518,7 @@ idClassForeach: idForeach: varRefBase { $$ = $1; } - | idForeach '.' varRefBase { $$ = new AstDot($2,$1,$3); } + | idForeach '.' varRefBase { $$ = new AstDot($2, false, $1, $3); } ; @@ -4598,8 +4611,7 @@ clocking_declaration: // IEEE: clocking_declaration (INCOMPLETE) //UNSUP ; //UNSUPclocking_decl_assign: // ==IEEE: clocking_decl_assign -//UNSUP idAny/*new-signal_identifier*/ { $$ = $1; } -//UNSUP | idAny/*new-signal_identifier*/ '=' expr { } +//UNSUP idAny/*new-signal_identifier*/ exprEqE { $$ = $1; } //UNSUP ; //UNSUPclocking_skewE: // IEEE: [clocking_skew] @@ -5501,7 +5513,7 @@ class_declaration: // ==IEEE: part of class_declaration // // The classExtendsE rule relys on classFront having the // // new class scope correct via classFront classFront parameter_port_listE classExtendsE classImplementsE ';' - class_itemListE yENDCLASS endLabelE + /*cont*/ class_itemListE yENDCLASS endLabelE { $$ = $1; $1->addMembersp($2); $1->extendsp($3); $1->addMembersp($4); @@ -5543,10 +5555,10 @@ classExtendsList: // IEEE: part of class_declaration ; classExtendsOne: // IEEE: part of class_declaration - class_typeWithoutId + class_typeExtImpList { $$ = new AstClassExtends($1->fileline(), $1); } // // IEEE: Might not be legal to have more than one set of parameters in an extends - | class_typeWithoutId '(' list_of_argumentsE ')' + | class_typeExtImpList '(' list_of_argumentsE ')' { $$ = new AstClassExtends($1->fileline(), $1); if ($3) BBUNSUP($3, "Unsupported: extends with parameters"); } ; @@ -5559,8 +5571,36 @@ classImplementsE: // IEEE: part of class_declaration classImplementsList: // IEEE: part of class_declaration // // All 1800-2012 - class_typeWithoutId { $$ = NULL; BBUNSUP($1, "Unsupported: implements class"); } - | classImplementsList ',' class_typeWithoutId { $$ = AstNode::addNextNull($1, $3); } + class_typeExtImpList { $$ = NULL; BBUNSUP($1, "Unsupported: implements class"); } + | classImplementsList ',' class_typeExtImpList { $$ = AstNode::addNextNull($1, $3); } + ; + +class_typeExtImpList: // IEEE: class_type: "[package_scope] id [ parameter_value_assignment ]" + // // but allow yaID__aTYPE for extends/implements + // // If you follow the rules down, class_type is really a list via ps_class_identifier + class_typeExtImpOne { $$ = $1; } + | class_typeExtImpList yP_COLONCOLON class_typeExtImpOne + { $$ = $3; + // Cannot just add as next() as that breaks implements lists + //UNSUP $$ = new AstDot($1, true, $1, $3); + BBUNSUP($2, "Unsupported: Hierarchical class references"); } + ; + +class_typeExtImpOne: // part of IEEE: class_type, where we either get a package_scope component or class + // // If you follow the rules down, class_type is really a list via ps_class_identifier + // // Not listed in IEEE, but see bug627 any parameter type maybe a class + // // If idAny below is a class, parameter_value is legal + // // If idAny below is a package, parameter_value is not legal + // // If idAny below is otherwise, not legal + idAny parameter_value_assignmentE + { $$ = new AstParseRef($1, VParseRefExp::PX_TEXT, *$1, NULL, NULL); + if ($2) BBUNSUP($2->fileline(), "Unsupported: Parameterized classes"); } + // // package_sopeIdFollows expanded + | yD_UNIT yP_COLONCOLON + { $$ = new AstParseRef($1, VParseRefExp::PX_TEXT, "$unit", NULL, NULL); } + | yLOCAL__COLONCOLON yP_COLONCOLON + { $$ = new AstParseRef($1, VParseRefExp::PX_TEXT, "local", NULL, NULL); + BBUNSUP($1, "Unsupported: Randomize 'local::'"); } ; //========= @@ -5569,25 +5609,14 @@ classImplementsList: // IEEE: part of class_declaration // Each of these must end with {symsPackageDone | symsClassDone} ps_id_etc: // package_scope + general id - package_scopeIdFollowsE varRefBase { $$ = $2; $2->packagep($1); } - ; - -ps_type: // IEEE: ps_parameter_identifier | ps_type_identifier - // Even though we looked up the type and have a AstNode* to it, - // we can't fully resolve it because it may have been just a forward definition. - package_scopeIdFollowsE idRefDType { $$ = $2; $2->packagep($1); } - // // Simplify typing - from ps_covergroup_identifier + package_scopeIdFollowsE varRefBase { $$ = $2; $2->packagep($1); } ; //=== Below rules assume special scoping per above -class_typeWithoutId: // as with class_typeWithoutId but allow yaID__aTYPE - // // and we thus don't need to resolve it in specified package - package_scopeIdFollowsE class_typeOneList { $$ = $2; $2->packagep($1); } - ; - class_scopeWithoutId: // class_type standalone without following id // // and we thus don't need to resolve it in specified package + // // Used only where declare "function ::new" class_scopeIdFollows { $$ = $1; } ; @@ -5613,8 +5642,9 @@ class_typeOneList: // IEEE: class_type: "id [ parameter_value_assignm class_typeOne: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE // // If you follow the rules down, class_type is really a list via ps_class_identifier // // Not listed in IEEE, but see bug627 any parameter type maybe a class - idRefDType parameter_value_assignmentE - { $$ = $1; if ($2) BBUNSUP($2->fileline(), "Unsupported: Parameterized classes"); } + idType parameter_value_assignmentE + { $$ = new AstRefDType($1, *$1); + if ($2) BBUNSUP($2->fileline(), "Unsupported: Parameterized classes"); } ; package_scopeIdFollowsE: // IEEE: [package_scope] @@ -5626,13 +5656,16 @@ package_scopeIdFollowsE: // IEEE: [package_scope] package_scopeIdFollows: // IEEE: package_scope // // IMPORTANT: The lexer will parse the following ID to be in the found package + // // Also see class_typeExtImpOne which has these rules too // //vv mid rule action needed otherwise we might not have NextId in time to parse the id token - yD_UNIT { SYMP->nextId(PARSEP->rootp()); } - /*cont*/ yP_COLONCOLON { $$ = GRAMMARP->unitPackage($1); } - | yaID__aPACKAGE { SYMP->nextId($1); } - /*cont*/ yP_COLONCOLON { $$ = VN_CAST($1, Package); } - //UNSUP yLOCAL__COLONCOLON { PARSEP->symTableNextId($1); } - //UNSUP /*cont*/ yP_COLONCOLON { UNSUP } + yaID__aPACKAGE { SYMP->nextId($1); } + /*cont*/ yP_COLONCOLON + { $$ = VN_CAST($1, Package); } + | yD_UNIT yP_COLONCOLON + { SYMP->nextId(PARSEP->rootp()); $$ = GRAMMARP->unitPackage($1); } + | yLOCAL__COLONCOLON yP_COLONCOLON + { BBUNSUP($1, "Unsupported: Randomize 'local::'"); + SYMP->nextId(PARSEP->rootp()); $$ = GRAMMARP->unitPackage($1); } ; //^^^========= @@ -5655,7 +5688,7 @@ class_item: // ==IEEE: class_item | class_declaration { $$ = NULL; BBUNSUP($1, "Unsupported: class within class"); } | timeunits_declaration { $$ = $1; } //UNSUP covergroup_declaration { $$ = $1; } - | local_parameter_declaration ';' { $$ = $1; BBUNSUP($2, "Unsupported: class parameters"); } // 1800-2009 + // // local_parameter_declaration under parameter_declaration | parameter_declaration ';' { $$ = $1; BBUNSUP($2, "Unsupported: class parameters"); } // 1800-2009 | ';' { $$ = NULL; } // @@ -5851,11 +5884,11 @@ vltOffFront: yVLT_COVERAGE_OFF { $$ = V3ErrorCode::I_COVERAGE; } | yVLT_TRACING_OFF { $$ = V3ErrorCode::I_TRACING; } | yVLT_LINT_OFF { $$ = V3ErrorCode::I_LINT; } - | yVLT_LINT_OFF yVLT_D_MSG yaID__ETC + | yVLT_LINT_OFF yVLT_D_MSG idAny { $$ = V3ErrorCode((*$3).c_str()); if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<v3warn(DEPRECATED, "Deprecated -msg in configuration files, use -rule instead."<v3error("Unknown Error Code: "<<*$3<: yVLT_COVERAGE_ON { $$ = V3ErrorCode::I_COVERAGE; } | yVLT_TRACING_ON { $$ = V3ErrorCode::I_TRACING; } | yVLT_LINT_ON { $$ = V3ErrorCode::I_LINT; } - | yVLT_LINT_ON yVLT_D_MSG yaID__ETC + | yVLT_LINT_ON yVLT_D_MSG idAny { $$ = V3ErrorCode((*$3).c_str()); if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown Error Code: "<<*$3<v3warn(DEPRECATED, "Deprecated -msg in configuration files, use -rule instead."<v3error("Unknown Error Code: "<<*$3<: - /* empty */ { static string unit = "__024unit"; $$ = &unit; } + /* empty */ { static string unit = "__024unit"; $$ = &unit; } | yVLT_D_MODULE str { $$ = $2; } ; vltDFTaskE: - /* empty */ { static string empty = ""; $$ = ∅ } + /* empty */ { static string empty = ""; $$ = ∅ } | yVLT_D_FUNCTION str { $$ = $2; } | yVLT_D_TASK str { $$ = $2; } ; vltInlineFront: - yVLT_INLINE { $$ = true; } + yVLT_INLINE { $$ = true; } | yVLT_NO_INLINE { $$ = false; } ; vltVarAttrVarE: - /* empty */ { static string empty = ""; $$ = ∅ } + /* empty */ { static string empty = ""; $$ = ∅ } | yVLT_D_VAR str { $$ = $2; } ; diff --git a/src/vlcovgen b/src/vlcovgen index c99d9aa88..c5a3e2a7f 100755 --- a/src/vlcovgen +++ b/src/vlcovgen @@ -65,7 +65,7 @@ sub lint { my $ok = 1; foreach my $itemref (@Items) { if ($shorts{$itemref->{short}}) { - warn "%Error: Duplicate short code: $itemref->{short},"; + die "%Error: Duplicate short code: $itemref->{short},"; $ok = 0; } $shorts{$itemref->{short}} = 1; diff --git a/test_regress/CMakeLists.txt b/test_regress/CMakeLists.txt index e07568e89..0cb22c4b7 100644 --- a/test_regress/CMakeLists.txt +++ b/test_regress/CMakeLists.txt @@ -13,7 +13,8 @@ ###################################################################### cmake_minimum_required(VERSION 3.8) -set(TEST_REQUIRED_VARS NAME CSOURCES OPT_FAST VERILATOR_ROOT VERILATOR_ARGS +set(TEST_REQUIRED_VARS NAME CSOURCES OPT_FAST OPT_GLOBAL + VERILATOR_ROOT VERILATOR_ARGS VERILATOR_SOURCES SYSTEMC VERBOSE VERILATION) foreach(var ${TEST_REQUIRED_VARS}) if (NOT DEFINED TEST_${var}) @@ -74,6 +75,9 @@ endif() if(TEST_OPT_FAST) list(APPEND verilate_ARGS OPT_FAST ${TEST_OPT_FAST}) endif() +if(TEST_OPT_GLOBAL) + list(APPEND verilate_ARGS OPT_GLOBAL ${TEST_OPT_GLOBAL}) +endif() if(TEST_THREADS) list(APPEND verilate_ARGS THREADS ${TEST_THREADS}) endif() diff --git a/test_regress/Makefile b/test_regress/Makefile index 6f36732e7..f230222d8 100644 --- a/test_regress/Makefile +++ b/test_regress/Makefile @@ -88,3 +88,4 @@ print-cxx-version: maintainer-copy:: clean mostlyclean distclean maintainer-clean:: -rm -rf obj_* simv* simx* csrc cov_work INCA_libs *.log *.key logs vc_hdrs.h + -rm -rf t/obj_* diff --git a/test_regress/driver.pl b/test_regress/driver.pl index 9e3733dfa..8d1260cf8 100755 --- a/test_regress/driver.pl +++ b/test_regress/driver.pl @@ -9,6 +9,7 @@ BEGIN { if (!$ENV{VERILATOR_ROOT} && -x "../bin/verilator") { $ENV{VERILATOR_ROOT} = Cwd::getcwd()."/.."; } + $ENV{MAKE} ||= "make" } use Getopt::Long; @@ -22,12 +23,18 @@ use version; use POSIX qw(strftime); use lib "."; use Time::HiRes qw(usleep); +use Digest::MD5 qw(md5); $::Driver = 1; $::Have_Forker = 0; -eval "use Parallel::Forker; \$Fork=Parallel::Forker->new(use_sig_child=>1); \$::Have_Forker=1;"; +eval "use Parallel::Forker; \$Fork=Parallel::Forker->new(use_sig_child=>1, poll_interval=>10*1000); \$::Have_Forker=1;"; $Fork = Forker->new(use_sig_child=>1) if !$Fork; +my $forker_Min_Version = 1.258; +if ($::Have_Forker && $Parallel::Forker::VERSION < $forker_Min_Version) { + print STDERR "driver.pl: Parallel::Forker is older than $forker_Min_Version, suggest 'cpan install Parallel::Forker'\n"; + $::Have_Forker = 0; +} $SIG{CHLD} = sub { $Fork->sig_child() if $Fork; }; $SIG{TERM} = sub { $Fork->kill_tree_all('TERM') if $Fork; die "Quitting...\n"; }; @@ -269,10 +276,7 @@ sub _calc_hashset { my ($set, $nsets) = ($1, $2); my @new; foreach my $t (@opt_tests) { - my $checksum = do { - local $/; - unpack("%32W*", $t); - }; + my $checksum = unpack('L', substr(md5($t), 0, 4)); if (($set % $nsets) == ($checksum % $nsets)) { push @new, $t; } @@ -306,6 +310,8 @@ sub new { skip_msgs => [], fail_msgs => [], fail_tests => [], + # Per-task identifiers + running_ids => {}, @_}; bless $self, $class; return $self; @@ -322,14 +328,24 @@ sub one_test { $::Fork->schedule ( test_pl_filename => $params{pl_filename}, + run_pre_start => sub { + my $process = shift; + # Running in context of parent, before run_on_start + # Make an identifier that is unique across all current running jobs + my $i = 1; while (exists $self->{running_ids}{$i}) { ++$i; } + $process->{running_id} = $i; + $self->{running_ids}{$process->{running_id}} = 1; + }, run_on_start => sub { + my $process = shift; # Running in context of child, so can't pass data to parent directly if ($self->{quiet}) { open(STDOUT, ">/dev/null"); open(STDERR, ">&STDOUT"); } print("="x70,"\n"); - my $test = VTest->new(@params); + my $test = VTest->new(@params, + running_id => $process->{running_id}); $test->oprint("="x50,"\n"); unlink $test->{status_filename}; $test->_prep; @@ -340,7 +356,9 @@ sub one_test { }, run_on_finish => sub { # Running in context of parent - my $test = VTest->new(@params); + my $process = shift; + my $test = VTest->new(@params, + running_id => $process->{running_id}); $test->_read_status; if ($test->ok) { $self->{ok_cnt}++; @@ -354,11 +372,13 @@ sub one_test { } else { $test->oprint("FAILED: $test->{errors}\n"); my $j = ($opt_jobs>1?" -j":""); - my $makecmd = $ENV{VERILATOR_MAKE} || "make$j &&"; + my $makecmd = $ENV{VERILATOR_MAKE} || "$ENV{MAKE}$j &&"; + my $upperdir = (Cwd::getcwd() =~ /test_regress/ + ? 'test_regress/' : ''); push @{$self->{fail_msgs}}, ("\t#".$test->soprint("%Error: $test->{errors}\n") - ."\t\t$makecmd test_regress/" - .$test->{pl_filename} + ."\t\t$makecmd " + .$upperdir.$test->{pl_filename} ." ".join(' ', _manual_args()) ." --".$test->{scenario}."\n"); push @{$self->{fail_tests}}, $test; @@ -374,6 +394,7 @@ sub one_test { } $self->{left_cnt}--; $self->print_summary; + delete $self->{running_ids}{$process->{running_id}} if $process->{running_id}; }, )->ready(); } @@ -444,7 +465,7 @@ sub sprint_summary { my $delta = time() - $::Start; my $leftmsg = $::Have_Forker ? $self->{left_cnt} : "NO-FORKER"; - my $pct = int(100*($self->{left_cnt} / $self->{all_cnt}) + 0.999); + my $pct = int(100*($self->{left_cnt} / ($self->{all_cnt} + 0.001)) + 0.999); my $eta = ($self->{all_cnt} * ($delta / (($self->{all_cnt} - $self->{left_cnt})+0.001))) - $delta; $eta = 0 if $delta < 10; @@ -885,11 +906,16 @@ sub compile_vlt_flags { @{$param{v_flags2}}, # Flags from driver cmdline override default flags and # flags from the test itself - @Opt_Driver_Verilator_Flags, + driver_verilator_flags(), ); return @cmdargs; } +sub driver_verilator_flags { + #my $self = (ref $_[0] ? shift : $Self); + return @Opt_Driver_Verilator_Flags +} + sub lint { my $self = (ref $_[0] ? shift : $Self); my %param = (# @@ -1062,6 +1088,7 @@ sub compile { tee => $param{tee}, expect => $param{expect}, expect_filename => $param{expect_filename}, + verilator_run => 1, cmd => \@vlt_cmd) if $::Opt_Verilation; return 1 if $self->errors || $self->skips || $self->unsupporteds; } @@ -1077,6 +1104,7 @@ sub compile { tee => $param{tee}, expect => $param{expect}, expect_filename => $param{expect_filename}, + verilator_run => 1, cmd => ["cd \"".$self->{obj_dir}."\" && cmake", "\"".$self->{t_dir}."/..\"", "-DTEST_VERILATOR_ROOT=$ENV{VERILATOR_ROOT}", @@ -1087,7 +1115,8 @@ sub compile { "-DTEST_VERBOSE=\"".($self->{verbose} ? 1 : 0)."\"", "-DTEST_SYSTEMC=\"" .($self->sc ? 1 : 0). "\"", "-DCMAKE_PREFIX_PATH=\"".(($ENV{SYSTEMC_INCLUDE}||$ENV{SYSTEMC}||'')."/..\""), - "-DTEST_OPT_FAST=\"" . ($param{benchmark} ? "-Os" : "") . "\"", + "-DTEST_OPT_FAST=\"" . ($param{benchmark} ? "-Os" : "-O0") . "\"", + "-DTEST_OPT_GLOBAL=\"" . ($param{benchmark} ? "-Os" : "-O0") . "\"", "-DTEST_VERILATION=\"" . $::Opt_Verilation . "\"", ]); return 1 if $self->errors || $self->skips || $self->unsupporteds; @@ -1097,7 +1126,7 @@ sub compile { $self->oprint("Running make (gmake)\n") if $self->{verbose}; $self->_run(logfile => "$self->{obj_dir}/vlt_gcc.log", entering => "$self->{obj_dir}", - cmd => ["make", + cmd => [$ENV{MAKE}, "-C ".$self->{obj_dir}, "-f ".$::RealBin."/Makefile_obj", ($self->{verbose} ? "" : "--no-print-directory"), @@ -1105,7 +1134,8 @@ sub compile { "TEST_OBJ_DIR=$self->{obj_dir}", "CPPFLAGS_DRIVER=-D".uc($self->{name}), ($self->{verbose} ? "CPPFLAGS_DRIVER2=-DTEST_VERBOSE=1":""), - ($param{benchmark} ? "OPT_FAST=-Os" : ""), + ($param{benchmark} ? "" : "OPT_FAST=-O0"), + ($param{benchmark} ? "" : "OPT_GLOBAL=-O0"), "$self->{VM_PREFIX}", # bypass default rule, as we don't need archive ($param{make_flags}||""), ]); @@ -1276,6 +1306,14 @@ sub execute { } } +sub setenv { + my $self = (ref $_[0]? shift : $Self); + my $var = shift; + my $val = shift; + print "\texport $var='$val'\n"; + $ENV{$var} = $val; +} + sub inline_checks { my $self = (ref $_[0]? shift : $Self); return 1 if $self->errors || $self->skips || $self->unsupporteds; @@ -1291,10 +1329,10 @@ sub inline_checks { while (defined(my $line = $fh->getline)) { if ($line =~ /CHECK/) { if ($line =~ /CHECK_COVER *\( *([---0-9]+) *, *"([^"]+)" *, *("([^"]+)" *,|) *(\d+) *\)/) { - my $lineno=($. + $1); my $hier=$2; my $comment=$4; my $count=$5; + my $lineno = ($. + $1); my $hier=$2; my $comment=$4; my $count=$5; my $regexp = "\001l\002".$lineno; $regexp .= ".*\001o\002".quotemeta($comment) if $comment; - $regexp .= ".*\001h\002".quotemeta($hier); + $regexp .= ".*\001h\002".quotemeta($hier) if $hier; $regexp .= ".*' ".$count; if ($contents !~ /$regexp/) { $self->error("CHECK_COVER: $covfn: Regexp not found: $regexp\n". @@ -1302,7 +1340,7 @@ sub inline_checks { } } elsif ($line =~ /CHECK_COVER_MISSING *\( *([---0-9]+) *\)/) { - my $lineno=($. + $1); + my $lineno = ($. + $1); my $regexp = "\001l\002".$lineno; if ($contents =~ /$regexp/) { $self->error("CHECK_COVER_MISSING: $covfn: Regexp found: $regexp\n". @@ -1379,11 +1417,21 @@ sub sc { } sub have_sc { - #my $self = shift; - return 1 if (defined $ENV{SYSTEMC} || defined $ENV{SYSTEMC_INCLUDE}); + my $self = (ref $_[0]? shift : $Self); + return 1 if (defined $ENV{SYSTEMC} || defined $ENV{SYSTEMC_INCLUDE} || $ENV{CFG_HAVE_SYSTEMC}); + return 1 if $self->verilator_version =~ /systemc found *= *1/i; return 0; } +sub make_version { + my $ver = `$ENV{MAKE} --version`; + if ($ver =~ /make ([0-9]+\.[0-9]+)/i) { + return $1; + } else { + return -1; + } +} + sub have_cmake { return cmake_version() >= version->declare("3.8"); } @@ -1458,6 +1506,7 @@ sub _run { my $self = (ref $_[0]? shift : $Self); my %param = (tee => 1, #entering => # Print entering directory information + #verilator_run => # Move gcov data to parallel area @_); my $command = join(' ',@{$param{cmd}}); $command = "time $command" if $opt_benchmark && $command !~ /^cd /; @@ -1465,6 +1514,17 @@ sub _run { print " > $param{logfile}" if $param{logfile}; print "\n"; + if ($param{verilator_run}) { + # Gcov fails when parallel jobs write same data file, + # so we make sure output dir is unique across all running jobs. + # We can't just put each one in obj_dir as it uses too much disk. + $ENV{GCOV_PREFIX_STRIP} = 99; + $ENV{GCOV_PREFIX} = "$self->{t_dir}/obj_dist/gcov_$self->{running_id}"; + } else { + delete $ENV{GCOV_PREFIX_STRIP}; + delete $ENV{GCOV_PREFIX}; + } + # Execute command redirecting output, keeping order between stderr and stdout. # Must do low-level IO so GCC interaction works (can't be line-based) my $status; @@ -1975,8 +2035,9 @@ sub _read_inputs_vhdl { our $_Verilator_Version; sub verilator_version { + # Returns verbose version, line 1 contains actual version if (!defined $_Verilator_Version) { - my @args = ("perl", "$ENV{VERILATOR_ROOT}/bin/verilator", "--version"); + my @args = ("perl", "$ENV{VERILATOR_ROOT}/bin/verilator", "-V"); my $args = join(' ',@args); $_Verilator_Version = `$args`; $_Verilator_Version or die "can't fork: $! ".join(' ',@args); @@ -2060,6 +2121,20 @@ sub files_identical { } } +sub files_identical_sorted { + my $self = (ref $_[0]? shift : $Self); + my $fn1 = shift; + my $fn2 = shift; + my $fn1_is_logfile = shift; + return 1 if $self->errors || $self->skips || $self->unsupporteds; + # Set LC_ALL as suggested in the sort manpage to avoid sort order + # changes from the locale. + setenv('LC_ALL', "C"); + my $fn1sort = "$fn1.sort"; + run(cmd => ["sort", "$fn1", "> $fn1sort"]); + return $self->files_identical($fn1sort, $fn2, $fn1_is_logfile); +} + sub copy_if_golden { my $self = (ref $_[0]? shift : $Self); my $fn1 = shift; @@ -2169,13 +2244,13 @@ sub _vcd_read { our $_Cxx_Version; sub cxx_version { - $_Cxx_Version ||= `make -C $ENV{VERILATOR_ROOT}/test_regress -f Makefile print-cxx-version`; + $_Cxx_Version ||= `$ENV{MAKE} -C $ENV{VERILATOR_ROOT}/test_regress -f Makefile print-cxx-version`; return $_Cxx_Version; } our $_Cfg_With_Threaded; sub cfg_with_threaded { - $_Cfg_With_Threaded ||= `make -C $ENV{VERILATOR_ROOT} -f Makefile print-cfg-with-threaded`; + $_Cfg_With_Threaded ||= `$ENV{MAKE} -C $ENV{VERILATOR_ROOT} -f Makefile print-cfg-with-threaded`; return ($_Cfg_With_Threaded =~ /yes/i) ? 1:0; } @@ -2271,6 +2346,7 @@ sub schedule { my $self = shift; my %params = (@_); + $params{run_pre_start}->($self); if (my $pid = fork()) { # Parent waitpid($pid, 0); } else { # Child diff --git a/test_regress/t/t_EXAMPLE.pl b/test_regress/t/t_EXAMPLE.pl index e02817219..9a15dd2cc 100755 --- a/test_regress/t/t_EXAMPLE.pl +++ b/test_regress/t/t_EXAMPLE.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_a1_first_cc.pl b/test_regress/t/t_a1_first_cc.pl index 08bcb4345..50fc6fcd9 100755 --- a/test_regress/t/t_a1_first_cc.pl +++ b/test_regress/t/t_a1_first_cc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -16,7 +16,9 @@ scenarios(simulator => 1); $DEBUG_QUIET = "--debug --debugi 0 --gdbbt --no-dump-tree"; -run(cmd => ["perl", "../bin/verilator", $DEBUG_QUIET, "-V"]); +run(cmd => ["perl", "../bin/verilator", $DEBUG_QUIET, "-V"], + verilator_run => 1, + ); compile( verilator_flags2 => [$DEBUG_QUIET, "--trace"], diff --git a/test_regress/t/t_a2_first_sc.pl b/test_regress/t/t_a2_first_sc.pl index 208b206ea..5a2abf87c 100755 --- a/test_regress/t/t_a2_first_sc.pl +++ b/test_regress/t/t_a2_first_sc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_a3_selftest.pl b/test_regress/t/t_a3_selftest.pl index 8f89936ed..a0a71531c 100755 --- a/test_regress/t/t_a3_selftest.pl +++ b/test_regress/t/t_a3_selftest.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_a4_examples.pl b/test_regress/t/t_a4_examples.pl index a4b6bdcde..0859499b3 100755 --- a/test_regress/t/t_a4_examples.pl +++ b/test_regress/t/t_a4_examples.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -14,7 +14,7 @@ $Self->{clean_command} = 'rm -rf ../examples/*/build ../examples/*/obj*'; my @examples = sort(glob("../examples/*")); for my $example (@examples) { - run(cmd=>["make -C $example"]); + run(cmd=>["$ENV{MAKE} -C $example"]); } ok(1); diff --git a/test_regress/t/t_alias2_unsup.out b/test_regress/t/t_alias2_unsup.out new file mode 100644 index 000000000..3e8c1e581 --- /dev/null +++ b/test_regress/t/t_alias2_unsup.out @@ -0,0 +1,4 @@ +%Error: t/t_alias2_unsup.v:39:4: Unsupported: alias statements + 39 | alias b = {a[3:0],a[7:4]}; + | ^~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_alias2_unsup.pl b/test_regress/t/t_alias2_unsup.pl new file mode 100755 index 000000000..ce380f717 --- /dev/null +++ b/test_regress/t/t_alias2_unsup.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(simulator => 1); + +lint( + fails => $Self->{vlt_all}, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_alias2_unsup.v b/test_regress/t/t_alias2_unsup.v new file mode 100644 index 000000000..e451eebb3 --- /dev/null +++ b/test_regress/t/t_alias2_unsup.v @@ -0,0 +1,41 @@ +// DESCRIPTION: Verilator: Verilog Test module for SystemVerilog 'alias' +// +// Simple bi-directional alias test. +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2013 by Jeremy Bennett. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + // Values to swap and locations for the swapped values. + reg [31:0] x = 32'ha5a5a5a5; + wire [31:0] y; + + testit testi_i (.a (x[7:0]), + .b (y[31:24])); + + always @ (posedge clk) begin + x <= {x[30:0],1'b0}; + $write("x = %x, y = %x\n", x, y); + + if (x[3:0] != 4'h0) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule + + +// Swap the byte order of two args. +module testit (input wire [7:0] a, + output wire [7:0] b + ); + + alias b = {a[3:0],a[7:4]}; + +endmodule diff --git a/test_regress/t/t_alias_unsup.out b/test_regress/t/t_alias_unsup.out new file mode 100644 index 000000000..2cee74f3f --- /dev/null +++ b/test_regress/t/t_alias_unsup.out @@ -0,0 +1,4 @@ +%Error: t/t_alias_unsup.v:46:4: Unsupported: alias statements + 46 | alias {a[7:0],a[15:8],a[23:16],a[31:24]} = b; + | ^~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_alias_unsup.pl b/test_regress/t/t_alias_unsup.pl new file mode 100755 index 000000000..ce380f717 --- /dev/null +++ b/test_regress/t/t_alias_unsup.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(simulator => 1); + +lint( + fails => $Self->{vlt_all}, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_alias_unsup.v b/test_regress/t/t_alias_unsup.v new file mode 100644 index 000000000..6b84b4570 --- /dev/null +++ b/test_regress/t/t_alias_unsup.v @@ -0,0 +1,58 @@ +// DESCRIPTION: Verilator: Verilog Test module for SystemVerilog 'alias' +// +// Simple bi-directional alias test. +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2013 by Jeremy Bennett. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + // Values to swap and locations for the swapped values. + wire [31:0] x_fwd = 32'hdeadbeef; + wire [31:0] y_fwd; + wire [31:0] x_bwd; + wire [31:0] y_bwd = 32'hfeedface; + + swap swap_fwd_i (.a (x_fwd), + .b (y_fwd)); + swap swap_bwd_i (.a (x_bwd), + .b (y_bwd)); + + always @ (posedge clk) begin +`ifdef TEST_VERBOSE + $write ("x_fwd = %x, y_fwd = %x\n", x_fwd, y_fwd); + $write ("x_bwd = %x, y_bwd = %x\n", x_bwd, y_bwd); +`endif + if (y_fwd != 32'hefbeadde) $stop; + if (x_bwd == 32'hcefaedfe) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule + + +// Swap the byte order of two args. +module swap ( + inout wire [31:0] a, + inout wire [31:0] b + ); + + alias {a[7:0],a[15:8],a[23:16],a[31:24]} = b; + + // Equivalent to + + // wire [31:0] a_prime; + // wire [31:0] b_prime; + + // assign b_prime = {a[7:0],a[15:8],a[23:16],a[31:24]}; + // assign {a_prime[7:0],a_prime[15:8],a_prime[23:16],a_prime[31:24]} = b; + // assign b = b_prime; + // assign a = a_prime; + +endmodule diff --git a/test_regress/t/t_altera_lpm_abs.pl b/test_regress/t/t_altera_lpm_abs.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_abs.pl +++ b/test_regress/t/t_altera_lpm_abs.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_add_sub.pl b/test_regress/t/t_altera_lpm_add_sub.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_add_sub.pl +++ b/test_regress/t/t_altera_lpm_add_sub.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_and.pl b/test_regress/t/t_altera_lpm_and.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_and.pl +++ b/test_regress/t/t_altera_lpm_and.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_bustri.pl b/test_regress/t/t_altera_lpm_bustri.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_bustri.pl +++ b/test_regress/t/t_altera_lpm_bustri.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_clshift.pl b/test_regress/t/t_altera_lpm_clshift.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_clshift.pl +++ b/test_regress/t/t_altera_lpm_clshift.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_compare.pl b/test_regress/t/t_altera_lpm_compare.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_compare.pl +++ b/test_regress/t/t_altera_lpm_compare.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_constant.pl b/test_regress/t/t_altera_lpm_constant.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_constant.pl +++ b/test_regress/t/t_altera_lpm_constant.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_counter.pl b/test_regress/t/t_altera_lpm_counter.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_counter.pl +++ b/test_regress/t/t_altera_lpm_counter.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_decode.pl b/test_regress/t/t_altera_lpm_decode.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_decode.pl +++ b/test_regress/t/t_altera_lpm_decode.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_divide.pl b/test_regress/t/t_altera_lpm_divide.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_divide.pl +++ b/test_regress/t/t_altera_lpm_divide.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_ff.pl b/test_regress/t/t_altera_lpm_ff.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_ff.pl +++ b/test_regress/t/t_altera_lpm_ff.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_fifo.pl b/test_regress/t/t_altera_lpm_fifo.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_fifo.pl +++ b/test_regress/t/t_altera_lpm_fifo.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_fifo_dc.pl b/test_regress/t/t_altera_lpm_fifo_dc.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_fifo_dc.pl +++ b/test_regress/t/t_altera_lpm_fifo_dc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_inv.pl b/test_regress/t/t_altera_lpm_inv.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_inv.pl +++ b/test_regress/t/t_altera_lpm_inv.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_latch.pl b/test_regress/t/t_altera_lpm_latch.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_latch.pl +++ b/test_regress/t/t_altera_lpm_latch.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_mult.pl b/test_regress/t/t_altera_lpm_mult.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_mult.pl +++ b/test_regress/t/t_altera_lpm_mult.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_mux.pl b/test_regress/t/t_altera_lpm_mux.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_mux.pl +++ b/test_regress/t/t_altera_lpm_mux.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_or.pl b/test_regress/t/t_altera_lpm_or.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_or.pl +++ b/test_regress/t/t_altera_lpm_or.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_ram_dp.pl b/test_regress/t/t_altera_lpm_ram_dp.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_ram_dp.pl +++ b/test_regress/t/t_altera_lpm_ram_dp.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_ram_dq.pl b/test_regress/t/t_altera_lpm_ram_dq.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_ram_dq.pl +++ b/test_regress/t/t_altera_lpm_ram_dq.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_ram_io.pl b/test_regress/t/t_altera_lpm_ram_io.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_ram_io.pl +++ b/test_regress/t/t_altera_lpm_ram_io.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_rom.pl b/test_regress/t/t_altera_lpm_rom.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_rom.pl +++ b/test_regress/t/t_altera_lpm_rom.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_shiftreg.pl b/test_regress/t/t_altera_lpm_shiftreg.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_shiftreg.pl +++ b/test_regress/t/t_altera_lpm_shiftreg.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_altera_lpm_xor.pl b/test_regress/t/t_altera_lpm_xor.pl index 65defb5b2..e079ef062 100755 --- a/test_regress/t/t_altera_lpm_xor.pl +++ b/test_regress/t/t_altera_lpm_xor.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_alw_combdly.pl b/test_regress/t/t_alw_combdly.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_alw_combdly.pl +++ b/test_regress/t/t_alw_combdly.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_alw_dly.pl b/test_regress/t/t_alw_dly.pl index 8dff4ed0c..102ff669d 100755 --- a/test_regress/t/t_alw_dly.pl +++ b/test_regress/t/t_alw_dly.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_alw_noreorder.pl b/test_regress/t/t_alw_noreorder.pl index 140987464..392808699 100755 --- a/test_regress/t/t_alw_noreorder.pl +++ b/test_regress/t/t_alw_noreorder.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_alw_nosplit.pl b/test_regress/t/t_alw_nosplit.pl index 269e7d577..ae8fcb03f 100755 --- a/test_regress/t/t_alw_nosplit.pl +++ b/test_regress/t/t_alw_nosplit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_alw_reorder.pl b/test_regress/t/t_alw_reorder.pl index 9dc659d01..1335722ca 100755 --- a/test_regress/t/t_alw_reorder.pl +++ b/test_regress/t/t_alw_reorder.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_alw_split.pl b/test_regress/t/t_alw_split.pl index c1e43c8d2..ba9c8f933 100755 --- a/test_regress/t/t_alw_split.pl +++ b/test_regress/t/t_alw_split.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_alw_split_cond.pl b/test_regress/t/t_alw_split_cond.pl index d1bf185c9..552bd97db 100755 --- a/test_regress/t/t_alw_split_cond.pl +++ b/test_regress/t/t_alw_split_cond.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_alw_split_rst.pl b/test_regress/t/t_alw_split_rst.pl index 4ef955903..87d186513 100755 --- a/test_regress/t/t_alw_split_rst.pl +++ b/test_regress/t/t_alw_split_rst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_alw_splitord.pl b/test_regress/t/t_alw_splitord.pl index e4e7ec5d6..a1d66aaad 100755 --- a/test_regress/t/t_alw_splitord.pl +++ b/test_regress/t/t_alw_splitord.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_backw_index_bad.pl b/test_regress/t/t_array_backw_index_bad.pl index dba098eb6..a60503a1f 100755 --- a/test_regress/t/t_array_backw_index_bad.pl +++ b/test_regress/t/t_array_backw_index_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_array_compare.pl b/test_regress/t/t_array_compare.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_array_compare.pl +++ b/test_regress/t/t_array_compare.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_index_increment.pl b/test_regress/t/t_array_index_increment.pl new file mode 100755 index 000000000..89a4e77d9 --- /dev/null +++ b/test_regress/t/t_array_index_increment.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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. + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_array_index_increment.v b/test_regress/t/t_array_index_increment.v new file mode 100644 index 000000000..67732b596 --- /dev/null +++ b/test_regress/t/t_array_index_increment.v @@ -0,0 +1,125 @@ +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + string test_string = "abcd"; + + int array3d[2][3][4] = '{ + '{ + '{ 0, 1, 2, 3}, + '{ 4, 5, 6, 7}, + '{ 8, 9, 10, 11} + }, + '{ + '{ 12, 13, 14, 15}, + '{ 16, 17, 18, 19}, + '{ 20, 21, 22, 23} + } + }; + int pos; + int val; + int i; + byte b; + + int data[4] = '{1, 2, 3, 4}; + + generate + genvar j; + int gdata[4]; + for (j=0; j < 5; j++) begin + initial if (j >= 5) $stop; + end + + for (j=0; j < 5; ++j) begin + initial if (j >= 5) $stop; + end + + for (j=10; j >= 5; j--) begin + initial if (j < 5) $stop; + end + + for (j=10; j >= 5; --j) begin + initial if (j < 5) $stop; + end + endgenerate + + initial begin + pos = 0; + pos++; + if (pos != 1) $stop; + + array3d[0][0][0]++; + if (array3d[0][0][0] != 1) $stop; + + --array3d[0][0][0]; + if (array3d[0][0][0] != 0) $stop; + + pos = 2; + b = test_string[--pos]; + if (b !== "b") $stop; + if (pos !== 1) $stop; + + pos = 1; + b = test_string[++pos]; + if (b !== "c") $stop; + if (pos !== 2) $stop; + + pos = 3; + b = test_string[pos--]; + if (b !== "d") $stop; + if (pos !== 2) $stop; + + pos = 0; + b = test_string[pos++]; + if (b !== "a") $stop; + if (pos !== 1) $stop; + + pos = 0; + val = array3d[++pos][--pos][++pos]; + if (pos !== 1) $stop; + if (val !== 13) $stop; + + pos = 0; + val = array3d[++pos][pos--][++pos]; + if (pos !== 1) $stop; + if (val !== 17) $stop; + + for (i=0; data[++i]<4;) begin + // loop with multiple statements + pos = i; + val = data[i]; + end + + if (pos !== 2) $stop; + if (i !== 3) $stop; + if (val !== 3) $stop; + + i = 0; + while (data[i++]<4) begin + // loop with multiple statements + pos = i; + val = data[i]; + end + + if (pos !== 3) $stop; + if (i !== 4) $stop; + if (val !== 4) $stop; + + + pos = 0; + if (1 == 1) begin + pos++; + end + if (pos != 1) $stop; + + pos = 0; + if (1 == 1) pos++; + if (pos != 1) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + + end +endmodule diff --git a/test_regress/t/t_array_interface.pl b/test_regress/t/t_array_interface.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_array_interface.pl +++ b/test_regress/t/t_array_interface.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_interface_noinl.pl b/test_regress/t/t_array_interface_noinl.pl index 0fdd2e40a..3b2379a98 100755 --- a/test_regress/t/t_array_interface_noinl.pl +++ b/test_regress/t/t_array_interface_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_list_bad.pl b/test_regress/t/t_array_list_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_array_list_bad.pl +++ b/test_regress/t/t_array_list_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_mda.pl b/test_regress/t/t_array_mda.pl index e02817219..9a15dd2cc 100755 --- a/test_regress/t/t_array_mda.pl +++ b/test_regress/t/t_array_mda.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_packed_sysfunct.pl b/test_regress/t/t_array_packed_sysfunct.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_array_packed_sysfunct.pl +++ b/test_regress/t/t_array_packed_sysfunct.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_packed_write_read.pl b/test_regress/t/t_array_packed_write_read.pl index f9888b6ba..d0de24f1c 100755 --- a/test_regress/t/t_array_packed_write_read.pl +++ b/test_regress/t/t_array_packed_write_read.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_pattern_2d.pl b/test_regress/t/t_array_pattern_2d.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_array_pattern_2d.pl +++ b/test_regress/t/t_array_pattern_2d.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_pattern_bad.pl b/test_regress/t/t_array_pattern_bad.pl index dba098eb6..a60503a1f 100755 --- a/test_regress/t/t_array_pattern_bad.pl +++ b/test_regress/t/t_array_pattern_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_array_pattern_packed.pl b/test_regress/t/t_array_pattern_packed.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_array_pattern_packed.pl +++ b/test_regress/t/t_array_pattern_packed.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_pattern_unpacked.pl b/test_regress/t/t_array_pattern_unpacked.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_array_pattern_unpacked.pl +++ b/test_regress/t/t_array_pattern_unpacked.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_query.pl b/test_regress/t/t_array_query.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_array_query.pl +++ b/test_regress/t/t_array_query.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_rev.pl b/test_regress/t/t_array_rev.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_array_rev.pl +++ b/test_regress/t/t_array_rev.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_type_methods.pl b/test_regress/t/t_array_type_methods.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_array_type_methods.pl +++ b/test_regress/t/t_array_type_methods.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_array_type_methods.v b/test_regress/t/t_array_type_methods.v index 48429bdd9..1ee503146 100644 --- a/test_regress/t/t_array_type_methods.v +++ b/test_regress/t/t_array_type_methods.v @@ -13,14 +13,16 @@ module t (/*AUTOARG*/ ); input clk; - logic [2:0] foo [1:0]; + logic [3:0] foo [1:0]; initial begin - foo[0] = 3'b101; - foo[1] = 3'b011; + foo[0] = 4'b0101; + foo[1] = 4'b0011; - `checkh(foo.or, 3'b111); - `checkh(foo.and, 3'b001); - `checkh(foo.xor, 3'b110); + `checkh(foo.or, 4'b0111); + `checkh(foo.and, 4'b0001); + `checkh(foo.xor, 4'b0110); + `checkh(foo.sum, 4'b1000); + `checkh(foo.product, 4'b1111); $write("*-* All Finished *-*\n"); $finish; diff --git a/test_regress/t/t_array_unpacked_public.pl b/test_regress/t/t_array_unpacked_public.pl index cc9e72798..a45993904 100755 --- a/test_regress/t/t_array_unpacked_public.pl +++ b/test_regress/t/t_array_unpacked_public.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_arraysel_wide.pl b/test_regress/t/t_arraysel_wide.pl index d1bf185c9..552bd97db 100755 --- a/test_regress/t/t_arraysel_wide.pl +++ b/test_regress/t/t_arraysel_wide.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_basic.pl b/test_regress/t/t_assert_basic.pl index 4c0a46a1c..59aeed76c 100755 --- a/test_regress/t/t_assert_basic.pl +++ b/test_regress/t/t_assert_basic.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_basic_cover.pl b/test_regress/t/t_assert_basic_cover.pl index edbd8eae1..245e17e68 100755 --- a/test_regress/t/t_assert_basic_cover.pl +++ b/test_regress/t/t_assert_basic_cover.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_basic_fail.pl b/test_regress/t/t_assert_basic_fail.pl index 20b8a4bb5..6e51b415d 100755 --- a/test_regress/t/t_assert_basic_fail.pl +++ b/test_regress/t/t_assert_basic_fail.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_basic_off.pl b/test_regress/t/t_assert_basic_off.pl index ce432c44f..15cc14b28 100755 --- a/test_regress/t/t_assert_basic_off.pl +++ b/test_regress/t/t_assert_basic_off.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_casez.pl b/test_regress/t/t_assert_casez.pl index 0d28d8ef2..b3a7f940f 100755 --- a/test_regress/t/t_assert_casez.pl +++ b/test_regress/t/t_assert_casez.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_comp.pl b/test_regress/t/t_assert_comp.pl index 4c0a46a1c..59aeed76c 100755 --- a/test_regress/t/t_assert_comp.pl +++ b/test_regress/t/t_assert_comp.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_comp_bad.pl b/test_regress/t/t_assert_comp_bad.pl index 3ec9bc8ca..b9699fb8a 100755 --- a/test_regress/t/t_assert_comp_bad.pl +++ b/test_regress/t/t_assert_comp_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_cover.pl b/test_regress/t/t_assert_cover.pl index 27417ed8a..f308ab3df 100755 --- a/test_regress/t/t_assert_cover.pl +++ b/test_regress/t/t_assert_cover.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_cover_off.pl b/test_regress/t/t_assert_cover_off.pl index d0720ac25..3f40bb5e8 100755 --- a/test_regress/t/t_assert_cover_off.pl +++ b/test_regress/t/t_assert_cover_off.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_disable_iff.pl b/test_regress/t/t_assert_disable_iff.pl old mode 100644 new mode 100755 index 8b6c4232e..63d2a42a6 --- a/test_regress/t/t_assert_disable_iff.pl +++ b/test_regress/t/t_assert_disable_iff.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_disabled.pl b/test_regress/t/t_assert_disabled.pl index 0fd1a2ed2..1b8f06b8b 100755 --- a/test_regress/t/t_assert_disabled.pl +++ b/test_regress/t/t_assert_disabled.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_dup_bad.pl b/test_regress/t/t_assert_dup_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_assert_dup_bad.pl +++ b/test_regress/t/t_assert_dup_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_elab.pl b/test_regress/t/t_assert_elab.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_assert_elab.pl +++ b/test_regress/t/t_assert_elab.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_elab_bad.pl b/test_regress/t/t_assert_elab_bad.pl index e4646c599..586badd6b 100755 --- a/test_regress/t/t_assert_elab_bad.pl +++ b/test_regress/t/t_assert_elab_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_enabled_bad.pl b/test_regress/t/t_assert_enabled_bad.pl index f9b49a910..689a3b7e2 100755 --- a/test_regress/t/t_assert_enabled_bad.pl +++ b/test_regress/t/t_assert_enabled_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_enabled_off.pl b/test_regress/t/t_assert_enabled_off.pl index 332a16068..13894bf05 100755 --- a/test_regress/t/t_assert_enabled_off.pl +++ b/test_regress/t/t_assert_enabled_off.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_enabled_on_bad.pl b/test_regress/t/t_assert_enabled_on_bad.pl index 34d22352e..6e1aa5190 100755 --- a/test_regress/t/t_assert_enabled_on_bad.pl +++ b/test_regress/t/t_assert_enabled_on_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_implication.pl b/test_regress/t/t_assert_implication.pl index fcfd1a86d..1564fe383 100755 --- a/test_regress/t/t_assert_implication.pl +++ b/test_regress/t/t_assert_implication.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_implication_bad.pl b/test_regress/t/t_assert_implication_bad.pl index 3fd3170f3..9b934c0ec 100755 --- a/test_regress/t/t_assert_implication_bad.pl +++ b/test_regress/t/t_assert_implication_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_inside_cond.pl b/test_regress/t/t_assert_inside_cond.pl index 90950ed85..1b42241ea 100755 --- a/test_regress/t/t_assert_inside_cond.pl +++ b/test_regress/t/t_assert_inside_cond.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_inside_cond_bad.pl b/test_regress/t/t_assert_inside_cond_bad.pl index d715dbf2e..59d4ea08c 100755 --- a/test_regress/t/t_assert_inside_cond_bad.pl +++ b/test_regress/t/t_assert_inside_cond_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_property.pl b/test_regress/t/t_assert_property.pl index fcfd1a86d..1564fe383 100755 --- a/test_regress/t/t_assert_property.pl +++ b/test_regress/t/t_assert_property.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_property_fail_1.pl b/test_regress/t/t_assert_property_fail_1.pl index 8637b2865..e3ba3d21e 100755 --- a/test_regress/t/t_assert_property_fail_1.pl +++ b/test_regress/t/t_assert_property_fail_1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_property_fail_2.pl b/test_regress/t/t_assert_property_fail_2.pl index c640ba27a..f12587b25 100755 --- a/test_regress/t/t_assert_property_fail_2.pl +++ b/test_regress/t/t_assert_property_fail_2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_question.pl b/test_regress/t/t_assert_question.pl index 0d28d8ef2..b3a7f940f 100755 --- a/test_regress/t/t_assert_question.pl +++ b/test_regress/t/t_assert_question.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_synth.pl b/test_regress/t/t_assert_synth.pl index 4c0a46a1c..59aeed76c 100755 --- a/test_regress/t/t_assert_synth.pl +++ b/test_regress/t/t_assert_synth.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_synth_full.pl b/test_regress/t/t_assert_synth_full.pl index 9cbec7d08..be8b7d192 100755 --- a/test_regress/t/t_assert_synth_full.pl +++ b/test_regress/t/t_assert_synth_full.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_synth_full_vlt.pl b/test_regress/t/t_assert_synth_full_vlt.pl index ad39b7dc0..14827a677 100755 --- a/test_regress/t/t_assert_synth_full_vlt.pl +++ b/test_regress/t/t_assert_synth_full_vlt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_synth_off.pl b/test_regress/t/t_assert_synth_off.pl index c75ee9028..5d352ebe2 100755 --- a/test_regress/t/t_assert_synth_off.pl +++ b/test_regress/t/t_assert_synth_off.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_synth_parallel.pl b/test_regress/t/t_assert_synth_parallel.pl index df87d5e21..40cb662f1 100755 --- a/test_regress/t/t_assert_synth_parallel.pl +++ b/test_regress/t/t_assert_synth_parallel.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assert_synth_parallel_vlt.pl b/test_regress/t/t_assert_synth_parallel_vlt.pl index 16ede2a0e..782d98d15 100755 --- a/test_regress/t/t_assert_synth_parallel_vlt.pl +++ b/test_regress/t/t_assert_synth_parallel_vlt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assign_inline.pl b/test_regress/t/t_assign_inline.pl index 5e67daa36..27414cae0 100755 --- a/test_regress/t/t_assign_inline.pl +++ b/test_regress/t/t_assign_inline.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assoc.pl b/test_regress/t/t_assoc.pl index e02817219..9a15dd2cc 100755 --- a/test_regress/t/t_assoc.pl +++ b/test_regress/t/t_assoc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assoc_meth_bad.pl b/test_regress/t/t_assoc_meth_bad.pl index 2365c113e..63947fd00 100755 --- a/test_regress/t/t_assoc_meth_bad.pl +++ b/test_regress/t/t_assoc_meth_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assoc_pattern_unsup.pl b/test_regress/t/t_assoc_pattern_unsup.pl index 2365c113e..63947fd00 100755 --- a/test_regress/t/t_assoc_pattern_unsup.pl +++ b/test_regress/t/t_assoc_pattern_unsup.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_assoc_wildcard_unsup.pl b/test_regress/t/t_assoc_wildcard_unsup.pl index 2365c113e..63947fd00 100755 --- a/test_regress/t/t_assoc_wildcard_unsup.pl +++ b/test_regress/t/t_assoc_wildcard_unsup.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_attr_parenstar.pl b/test_regress/t/t_attr_parenstar.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_attr_parenstar.pl +++ b/test_regress/t/t_attr_parenstar.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_bench_mux4k.pl b/test_regress/t/t_bench_mux4k.pl index be3b43873..cc9340de4 100755 --- a/test_regress/t/t_bench_mux4k.pl +++ b/test_regress/t/t_bench_mux4k.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_bench_mux4k_onecpu.pl b/test_regress/t/t_bench_mux4k_onecpu.pl index c56ecd683..832b8d6a4 100755 --- a/test_regress/t/t_bench_mux4k_onecpu.pl +++ b/test_regress/t/t_bench_mux4k_onecpu.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_bind.pl b/test_regress/t/t_bind.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_bind.pl +++ b/test_regress/t/t_bind.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_bind2.pl b/test_regress/t/t_bind2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_bind2.pl +++ b/test_regress/t/t_bind2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_bitsel_const_bad.pl b/test_regress/t/t_bitsel_const_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_bitsel_const_bad.pl +++ b/test_regress/t/t_bitsel_const_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_bitsel_enum.pl b/test_regress/t/t_bitsel_enum.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_bitsel_enum.pl +++ b/test_regress/t/t_bitsel_enum.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_bitsel_slice.pl b/test_regress/t/t_bitsel_slice.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_bitsel_slice.pl +++ b/test_regress/t/t_bitsel_slice.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_bitsel_struct.pl b/test_regress/t/t_bitsel_struct.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_bitsel_struct.pl +++ b/test_regress/t/t_bitsel_struct.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_bitsel_struct2.pl b/test_regress/t/t_bitsel_struct2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_bitsel_struct2.pl +++ b/test_regress/t/t_bitsel_struct2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_bitsel_struct3.pl b/test_regress/t/t_bitsel_struct3.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_bitsel_struct3.pl +++ b/test_regress/t/t_bitsel_struct3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_bitsel_wire_array_bad.pl b/test_regress/t/t_bitsel_wire_array_bad.pl index c6036e2f3..2d59ce73a 100755 --- a/test_regress/t/t_bitsel_wire_array_bad.pl +++ b/test_regress/t/t_bitsel_wire_array_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_blocking.pl b/test_regress/t/t_blocking.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_blocking.pl +++ b/test_regress/t/t_blocking.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_bug3180.pl b/test_regress/t/t_bug3180.pl index 53a8b0126..79556a789 100755 --- a/test_regress/t/t_bug3180.pl +++ b/test_regress/t/t_bug3180.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_66bits.pl b/test_regress/t/t_case_66bits.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_case_66bits.pl +++ b/test_regress/t/t_case_66bits.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_auto1.pl b/test_regress/t/t_case_auto1.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_case_auto1.pl +++ b/test_regress/t/t_case_auto1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_deep.pl b/test_regress/t/t_case_deep.pl index d6841bed0..7d49cd2cd 100755 --- a/test_regress/t/t_case_deep.pl +++ b/test_regress/t/t_case_deep.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_deep.v b/test_regress/t/t_case_deep.v index 1883d5af8..12335f6ac 100644 --- a/test_regress/t/t_case_deep.v +++ b/test_regress/t/t_case_deep.v @@ -88,7 +88,8 @@ module Test (/*AUTOARG*/ // End of automatics /* -#!/usr/bin/perl -w +#!/usr/bin/env perl +use warnings; srand(5); my @used; pat: diff --git a/test_regress/t/t_case_default_bad.pl b/test_regress/t/t_case_default_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_case_default_bad.pl +++ b/test_regress/t/t_case_default_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_dupitems.pl b/test_regress/t/t_case_dupitems.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_case_dupitems.pl +++ b/test_regress/t/t_case_dupitems.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_genx_bad.pl b/test_regress/t/t_case_genx_bad.pl index f3dd1d2a1..35d749208 100755 --- a/test_regress/t/t_case_genx_bad.pl +++ b/test_regress/t/t_case_genx_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_group.pl b/test_regress/t/t_case_group.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_case_group.pl +++ b/test_regress/t/t_case_group.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_huge.pl b/test_regress/t/t_case_huge.pl index 423f9f2c3..b8b37ebdc 100755 --- a/test_regress/t/t_case_huge.pl +++ b/test_regress/t/t_case_huge.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_huge_prof.pl b/test_regress/t/t_case_huge_prof.pl index d12633181..2514ab53e 100755 --- a/test_regress/t/t_case_huge_prof.pl +++ b/test_regress/t/t_case_huge_prof.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -20,7 +20,7 @@ file_grep($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10); file_grep($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 10); unlink $_ foreach (glob "$Self->{obj_dir}/gmon.out.*"); -$ENV{GMON_OUT_PREFIX} = "$Self->{obj_dir}/gmon.out"; +setenv('GMON_OUT_PREFIX', "$Self->{obj_dir}/gmon.out"); execute( check_finished => 1, diff --git a/test_regress/t/t_case_inside.pl b/test_regress/t/t_case_inside.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_case_inside.pl +++ b/test_regress/t/t_case_inside.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_itemwidth.pl b/test_regress/t/t_case_itemwidth.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_case_itemwidth.pl +++ b/test_regress/t/t_case_itemwidth.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_nest.pl b/test_regress/t/t_case_nest.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_case_nest.pl +++ b/test_regress/t/t_case_nest.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_onehot.pl b/test_regress/t/t_case_onehot.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_case_onehot.pl +++ b/test_regress/t/t_case_onehot.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_orig.pl b/test_regress/t/t_case_orig.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_case_orig.pl +++ b/test_regress/t/t_case_orig.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_reducer.pl b/test_regress/t/t_case_reducer.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_case_reducer.pl +++ b/test_regress/t/t_case_reducer.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_string.pl b/test_regress/t/t_case_string.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_case_string.pl +++ b/test_regress/t/t_case_string.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_wild.pl b/test_regress/t/t_case_wild.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_case_wild.pl +++ b/test_regress/t/t_case_wild.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_write1.pl b/test_regress/t/t_case_write1.pl index f108b9a2c..4fa36576d 100755 --- a/test_regress/t/t_case_write1.pl +++ b/test_regress/t/t_case_write1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_write2.pl b/test_regress/t/t_case_write2.pl index f108b9a2c..4fa36576d 100755 --- a/test_regress/t/t_case_write2.pl +++ b/test_regress/t/t_case_write2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_x.pl b/test_regress/t/t_case_x.pl index d67e81f2e..005873da6 100755 --- a/test_regress/t/t_case_x.pl +++ b/test_regress/t/t_case_x.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_x_bad.pl b/test_regress/t/t_case_x_bad.pl index f3dd1d2a1..35d749208 100755 --- a/test_regress/t/t_case_x_bad.pl +++ b/test_regress/t/t_case_x_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_case_zx_bad.pl b/test_regress/t/t_case_zx_bad.pl index f3dd1d2a1..35d749208 100755 --- a/test_regress/t/t_case_zx_bad.pl +++ b/test_regress/t/t_case_zx_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_cast.pl b/test_regress/t/t_cast.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_cast.pl +++ b/test_regress/t/t_cast.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_cast.v b/test_regress/t/t_cast.v index 51ea9b240..baccee871 100644 --- a/test_regress/t/t_cast.v +++ b/test_regress/t/t_cast.v @@ -46,6 +46,7 @@ module t; if (signed'(4'hf) > 4'sh0) $stop; if (4'hf < 4'h0) $stop; if (unsigned'(4'shf) < 4'h0) $stop; + if (const'(4'shf) !== 4'shf) $stop; if (4'(allones) !== 4'hf) $stop; if (6'(allones) !== 6'h3f) $stop; if ((4)'(allones) !== 4'hf) $stop; diff --git a/test_regress/t/t_cdc_async_bad.pl b/test_regress/t/t_cdc_async_bad.pl index 86f83c981..d1b47ec05 100755 --- a/test_regress/t/t_cdc_async_bad.pl +++ b/test_regress/t/t_cdc_async_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_cdc_async_debug_bad.out b/test_regress/t/t_cdc_async_debug_bad.out new file mode 100644 index 000000000..2a6956531 --- /dev/null +++ b/test_regress/t/t_cdc_async_debug_bad.out @@ -0,0 +1,20 @@ +Edge Report for Vt_cdc_async_debug_bad + t_cdc_async_bad.v: input clk SRC=@(*) DST=@(posedge clk or negedge rst0_n or negedge t.__Vcellinp__flop4__rst_n or negedge t.rst1_n or negedge t.rst2_bad_n or negedge t.rst5_waive_n or negedge t.rst6a_bad_n or negedge t.rst6b_bad_n) + t_cdc_async_bad.v: input d SRC=@(*) DST=@(posedge clk or negedge rst0_n or negedge t.__Vcellinp__flop4__rst_n or negedge t.rst1_n or negedge t.rst2_bad_n or negedge t.rst5_waive_n or negedge t.rst6a_bad_n or negedge t.rst6b_bad_n) + t_cdc_async_bad.v: input rst0_n SRC=@(*) DST=@(posedge clk or negedge rst0_n or negedge t.rst2_bad_n or negedge t.rst5_waive_n or negedge t.rst6a_bad_n or negedge t.rst6b_bad_n) + t_cdc_async_bad.v: output q0 SRC=@(posedge clk or negedge rst0_n) DST= + t_cdc_async_bad.v: output q1 SRC=@(posedge clk or negedge t.rst1_n) DST= + t_cdc_async_bad.v: output q2 SRC=@(posedge clk or negedge t.rst2_bad_n) DST= + t_cdc_async_bad.v: output q3 SRC=@(posedge clk or negedge t.rst2_bad_n) DST= + t_cdc_async_bad.v: output q4 SRC=@(posedge clk or negedge t.__Vcellinp__flop4__rst_n) DST= + t_cdc_async_bad.v: output q5 SRC=@(posedge clk or negedge t.rst5_waive_n) DST= + t_cdc_async_bad.v: output q6a SRC=@(posedge clk or negedge t.rst6a_bad_n) DST= + t_cdc_async_bad.v: output q6b SRC=@(posedge clk or negedge t.rst6b_bad_n) DST= + t_cdc_async_bad.v: wire t.__Vcellinp__flop4__rst_n SRC=@(posedge clk) DST=@(posedge clk or negedge t.__Vcellinp__flop4__rst_n) + t_cdc_async_bad.v: wire t.rst1_n SRC=@(posedge clk) DST=@(posedge clk or negedge t.rst1_n or negedge t.rst2_bad_n or negedge t.rst5_waive_n or negedge t.rst6a_bad_n or negedge t.rst6b_bad_n) + t_cdc_async_bad.v: wire t.rst2_bad_n SRC=@(* or posedge clk) DST=@(posedge clk or negedge t.rst2_bad_n) + t_cdc_async_bad.v: wire t.rst4_n SRC=@(posedge clk) DST=@(posedge clk or negedge t.__Vcellinp__flop4__rst_n) + t_cdc_async_bad.v: wire t.rst5_waive_n SRC=@(* or posedge clk) DST=@(posedge clk or negedge t.rst5_waive_n) + t_cdc_async_bad.v: wire t.rst6_bad_n SRC=@(* or posedge clk) DST=@(posedge clk or negedge t.rst6a_bad_n or negedge t.rst6b_bad_n) + t_cdc_async_bad.v: wire t.rst6a_bad_n SRC=@(* or posedge clk) DST=@(posedge clk or negedge t.rst6a_bad_n) + t_cdc_async_bad.v: wire t.rst6b_bad_n SRC=@(* or posedge clk) DST=@(posedge clk or negedge t.rst6b_bad_n) diff --git a/test_regress/t/t_cdc_async_debug_bad.pl b/test_regress/t/t_cdc_async_debug_bad.pl new file mode 100755 index 000000000..5634177a8 --- /dev/null +++ b/test_regress/t/t_cdc_async_debug_bad.pl @@ -0,0 +1,27 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2009 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 + +scenarios(vlt => 1); + +top_filename("t/t_cdc_async_bad.v"); + +compile( + # --debug so we get code coverage of Cdc + v_flags => ['--cdc --debug'], + verilator_make_gmake => 0, + make_top_shell => 0, + make_main => 0, + fails => 1, + ); + +files_identical("$Self->{obj_dir}/V$Self->{name}__cdc_edges.txt", $Self->{golden_filename}); + +ok(1); +1; diff --git a/test_regress/t/t_cellarray.pl b/test_regress/t/t_cellarray.pl index f4e5d2f0a..78f9ca462 100755 --- a/test_regress/t/t_cellarray.pl +++ b/test_regress/t/t_cellarray.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_chg_first.pl b/test_regress/t/t_chg_first.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_chg_first.pl +++ b/test_regress/t/t_chg_first.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class1.pl b/test_regress/t/t_class1.pl index 2ba855492..6247bd126 100755 --- a/test_regress/t/t_class1.pl +++ b/test_regress/t/t_class1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class2.pl b/test_regress/t/t_class2.pl index fc2b215fb..61eb2deec 100755 --- a/test_regress/t/t_class2.pl +++ b/test_regress/t/t_class2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_class.pl b/test_regress/t/t_class_class.pl index c08fc990a..6ad7137de 100755 --- a/test_regress/t/t_class_class.pl +++ b/test_regress/t/t_class_class.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_copy.pl b/test_regress/t/t_class_copy.pl index 27b3049d2..aabcde63e 100755 --- a/test_regress/t/t_class_copy.pl +++ b/test_regress/t/t_class_copy.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_copy_bad.pl b/test_regress/t/t_class_copy_bad.pl index 43e2f6762..7be596e0f 100755 --- a/test_regress/t/t_class_copy_bad.pl +++ b/test_regress/t/t_class_copy_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_dead.pl b/test_regress/t/t_class_dead.pl index d720a09b2..fd702254d 100755 --- a/test_regress/t/t_class_dead.pl +++ b/test_regress/t/t_class_dead.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_enum.pl b/test_regress/t/t_class_enum.pl index 27b3049d2..aabcde63e 100755 --- a/test_regress/t/t_class_enum.pl +++ b/test_regress/t/t_class_enum.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_extends.out b/test_regress/t/t_class_extends.out index 9d4b05199..932119d8a 100644 --- a/test_regress/t/t_class_extends.out +++ b/test_regress/t/t_class_extends.out @@ -1,10 +1,19 @@ %Error: t/t_class_extends.v:13:21: Unsupported: class extends 13 | class Base1 extends Base0; | ^~~~~ +%Error: t/t_class_extends.v:13:21: Found definition of 'Base0' as a CLASS but expected a variable + 13 | class Base1 extends Base0; + | ^~~~~ %Error: t/t_class_extends.v:17:21: Unsupported: class extends 17 | class Base2 extends Base1; | ^~~~~ +%Error: t/t_class_extends.v:17:21: Found definition of 'Base1' as a CLASS but expected a variable + 17 | class Base2 extends Base1; + | ^~~~~ %Error: t/t_class_extends.v:21:19: Unsupported: class extends 21 | class Cls extends Base2; | ^~~~~ +%Error: t/t_class_extends.v:21:19: Found definition of 'Base2' as a CLASS but expected a variable + 21 | class Cls extends Base2; + | ^~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_class_extends.pl b/test_regress/t/t_class_extends.pl index 64b3d2dde..b8b56e6f0 100755 --- a/test_regress/t/t_class_extends.pl +++ b/test_regress/t/t_class_extends.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_extends_bad.pl b/test_regress/t/t_class_extends_bad.pl index 43e2f6762..7be596e0f 100755 --- a/test_regress/t/t_class_extends_bad.pl +++ b/test_regress/t/t_class_extends_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_forward.pl b/test_regress/t/t_class_forward.pl index 27b3049d2..aabcde63e 100755 --- a/test_regress/t/t_class_forward.pl +++ b/test_regress/t/t_class_forward.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_local.pl b/test_regress/t/t_class_local.pl index 27b3049d2..aabcde63e 100755 --- a/test_regress/t/t_class_local.pl +++ b/test_regress/t/t_class_local.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_member_bad.out b/test_regress/t/t_class_member_bad.out index 5e0cb3ddd..22a47741b 100644 --- a/test_regress/t/t_class_member_bad.out +++ b/test_regress/t/t_class_member_bad.out @@ -1,4 +1,7 @@ %Error: t/t_class_member_bad.v:11:20: Unsupported: class extends 11 | class Cls2 extends Base1; | ^~~~~ +%Error: t/t_class_member_bad.v:11:20: Found definition of 'Base1' as a CLASS but expected a variable + 11 | class Cls2 extends Base1; + | ^~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_class_member_bad.pl b/test_regress/t/t_class_member_bad.pl index 43e2f6762..7be596e0f 100755 --- a/test_regress/t/t_class_member_bad.pl +++ b/test_regress/t/t_class_member_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_method.pl b/test_regress/t/t_class_method.pl index 27b3049d2..aabcde63e 100755 --- a/test_regress/t/t_class_method.pl +++ b/test_regress/t/t_class_method.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_method_bad.out b/test_regress/t/t_class_method_bad.out index 3417f3ebb..67d0928c8 100644 --- a/test_regress/t/t_class_method_bad.out +++ b/test_regress/t/t_class_method_bad.out @@ -1,4 +1,7 @@ %Error: t/t_class_method_bad.v:11:20: Unsupported: class extends 11 | class Cls2 extends Base1; | ^~~~~ +%Error: t/t_class_method_bad.v:11:20: Found definition of 'Base1' as a CLASS but expected a variable + 11 | class Cls2 extends Base1; + | ^~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_class_method_bad.pl b/test_regress/t/t_class_method_bad.pl index 43e2f6762..7be596e0f 100755 --- a/test_regress/t/t_class_method_bad.pl +++ b/test_regress/t/t_class_method_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_module.pl b/test_regress/t/t_class_module.pl index 27b3049d2..aabcde63e 100755 --- a/test_regress/t/t_class_module.pl +++ b/test_regress/t/t_class_module.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_name.pl b/test_regress/t/t_class_name.pl index 64b3d2dde..b8b56e6f0 100755 --- a/test_regress/t/t_class_name.pl +++ b/test_regress/t/t_class_name.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_new.pl b/test_regress/t/t_class_new.pl index 27b3049d2..aabcde63e 100755 --- a/test_regress/t/t_class_new.pl +++ b/test_regress/t/t_class_new.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_new_bad.pl b/test_regress/t/t_class_new_bad.pl index 43e2f6762..7be596e0f 100755 --- a/test_regress/t/t_class_new_bad.pl +++ b/test_regress/t/t_class_new_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_null_bad.pl b/test_regress/t/t_class_null_bad.pl index 758049687..8b1946a7b 100755 --- a/test_regress/t/t_class_null_bad.pl +++ b/test_regress/t/t_class_null_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_package.pl b/test_regress/t/t_class_package.pl index 27b3049d2..aabcde63e 100755 --- a/test_regress/t/t_class_package.pl +++ b/test_regress/t/t_class_package.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_param.pl b/test_regress/t/t_class_param.pl index 64b3d2dde..b8b56e6f0 100755 --- a/test_regress/t/t_class_param.pl +++ b/test_regress/t/t_class_param.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_static_order.pl b/test_regress/t/t_class_static_order.pl index 64b3d2dde..b8b56e6f0 100755 --- a/test_regress/t/t_class_static_order.pl +++ b/test_regress/t/t_class_static_order.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_class_unsup_bad.pl b/test_regress/t/t_class_unsup_bad.pl index be57f782a..009248fc5 100755 --- a/test_regress/t/t_class_unsup_bad.pl +++ b/test_regress/t/t_class_unsup_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_2in.pl b/test_regress/t/t_clk_2in.pl index 1ed3b6e8b..aa918c4cb 100755 --- a/test_regress/t/t_clk_2in.pl +++ b/test_regress/t/t_clk_2in.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_2in_vec.pl b/test_regress/t/t_clk_2in_vec.pl index efc390c54..5950dcac8 100755 --- a/test_regress/t/t_clk_2in_vec.pl +++ b/test_regress/t/t_clk_2in_vec.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_concat.pl b/test_regress/t/t_clk_concat.pl index 2f675ed7b..20e02184d 100755 --- a/test_regress/t/t_clk_concat.pl +++ b/test_regress/t/t_clk_concat.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_concat2.pl b/test_regress/t/t_clk_concat2.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_clk_concat2.pl +++ b/test_regress/t/t_clk_concat2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_concat3.pl b/test_regress/t/t_clk_concat3.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_clk_concat3.pl +++ b/test_regress/t/t_clk_concat3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_concat4.pl b/test_regress/t/t_clk_concat4.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_clk_concat4.pl +++ b/test_regress/t/t_clk_concat4.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_concat5.pl b/test_regress/t/t_clk_concat5.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_clk_concat5.pl +++ b/test_regress/t/t_clk_concat5.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_concat6.pl b/test_regress/t/t_clk_concat6.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_clk_concat6.pl +++ b/test_regress/t/t_clk_concat6.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_concat_vlt.pl b/test_regress/t/t_clk_concat_vlt.pl index 815b1b4a4..4aae842ef 100755 --- a/test_regress/t/t_clk_concat_vlt.pl +++ b/test_regress/t/t_clk_concat_vlt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_condflop.pl b/test_regress/t/t_clk_condflop.pl index bd78435f2..ce1f8586f 100755 --- a/test_regress/t/t_clk_condflop.pl +++ b/test_regress/t/t_clk_condflop.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_condflop_nord.pl b/test_regress/t/t_clk_condflop_nord.pl index 09fdf4760..57e493fa0 100755 --- a/test_regress/t/t_clk_condflop_nord.pl +++ b/test_regress/t/t_clk_condflop_nord.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_dpulse.pl b/test_regress/t/t_clk_dpulse.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_clk_dpulse.pl +++ b/test_regress/t/t_clk_dpulse.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_dsp.pl b/test_regress/t/t_clk_dsp.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_clk_dsp.pl +++ b/test_regress/t/t_clk_dsp.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_first.pl b/test_regress/t/t_clk_first.pl index 89850c37d..48b4e6fd3 100755 --- a/test_regress/t/t_clk_first.pl +++ b/test_regress/t/t_clk_first.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_first_bad.pl b/test_regress/t/t_clk_first_bad.pl index 823cd4300..7061aebc4 100755 --- a/test_regress/t/t_clk_first_bad.pl +++ b/test_regress/t/t_clk_first_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_first_deprecated.pl b/test_regress/t/t_clk_first_deprecated.pl index 4d96fac7d..600551635 100755 --- a/test_regress/t/t_clk_first_deprecated.pl +++ b/test_regress/t/t_clk_first_deprecated.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_gate_ext.pl b/test_regress/t/t_clk_gate_ext.pl index e02817219..9a15dd2cc 100755 --- a/test_regress/t/t_clk_gate_ext.pl +++ b/test_regress/t/t_clk_gate_ext.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_gater.pl b/test_regress/t/t_clk_gater.pl index 5bba9e07e..80eb32da7 100755 --- a/test_regress/t/t_clk_gater.pl +++ b/test_regress/t/t_clk_gater.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_gen.pl b/test_regress/t/t_clk_gen.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_clk_gen.pl +++ b/test_regress/t/t_clk_gen.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_inp_init.pl b/test_regress/t/t_clk_inp_init.pl index b2191a176..079c16ec0 100755 --- a/test_regress/t/t_clk_inp_init.pl +++ b/test_regress/t/t_clk_inp_init.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_latch.pl b/test_regress/t/t_clk_latch.pl index a8a66f6ba..1f8ac0132 100755 --- a/test_regress/t/t_clk_latch.pl +++ b/test_regress/t/t_clk_latch.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(simulator => 1); -my $fail = ($Self->{vlt_all} && verilator_version() !~ /\(ord\)/); +my $fail = $Self->{vlt_all}; compile( ); diff --git a/test_regress/t/t_clk_latch_edgestyle.pl b/test_regress/t/t_clk_latch_edgestyle.pl index ad463440f..ca72a6975 100755 --- a/test_regress/t/t_clk_latch_edgestyle.pl +++ b/test_regress/t/t_clk_latch_edgestyle.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -12,7 +12,7 @@ scenarios(simulator => 1); top_filename("t/t_clk_latch.v"); -my $fail = ($Self->{vlt_all} && verilator_version() !~ /\(ord\)/); +my $fail = $Self->{vlt_all}; compile( v_flags2 => ['+define+EDGE_DETECT_STYLE'], diff --git a/test_regress/t/t_clk_latchgate.pl b/test_regress/t/t_clk_latchgate.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_clk_latchgate.pl +++ b/test_regress/t/t_clk_latchgate.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_powerdn.pl b/test_regress/t/t_clk_powerdn.pl index bd78435f2..ce1f8586f 100755 --- a/test_regress/t/t_clk_powerdn.pl +++ b/test_regress/t/t_clk_powerdn.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_scope_bad.pl b/test_regress/t/t_clk_scope_bad.pl index f3dd1d2a1..35d749208 100755 --- a/test_regress/t/t_clk_scope_bad.pl +++ b/test_regress/t/t_clk_scope_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_vecgen1.pl b/test_regress/t/t_clk_vecgen1.pl index 90908ae96..35ae37fc6 100755 --- a/test_regress/t/t_clk_vecgen1.pl +++ b/test_regress/t/t_clk_vecgen1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_vecgen2.pl b/test_regress/t/t_clk_vecgen2.pl index 920605c09..a6c215d47 100755 --- a/test_regress/t/t_clk_vecgen2.pl +++ b/test_regress/t/t_clk_vecgen2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clk_vecgen3.pl b/test_regress/t/t_clk_vecgen3.pl index ee3dda24e..2ffc58208 100755 --- a/test_regress/t/t_clk_vecgen3.pl +++ b/test_regress/t/t_clk_vecgen3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_clocker.pl b/test_regress/t/t_clocker.pl index 6a31da87a..1af79252d 100755 --- a/test_regress/t/t_clocker.pl +++ b/test_regress/t/t_clocker.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_concat_large.pl b/test_regress/t/t_concat_large.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_concat_large.pl +++ b/test_regress/t/t_concat_large.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_concat_large_bad.pl b/test_regress/t/t_concat_large_bad.pl index fad9da3fe..53e145105 100755 --- a/test_regress/t/t_concat_large_bad.pl +++ b/test_regress/t/t_concat_large_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_concat_link_bad.pl b/test_regress/t/t_concat_link_bad.pl index e2ea28d29..27159da5b 100755 --- a/test_regress/t/t_concat_link_bad.pl +++ b/test_regress/t/t_concat_link_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_concat_opt.pl b/test_regress/t/t_concat_opt.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_concat_opt.pl +++ b/test_regress/t/t_concat_opt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_const.pl b/test_regress/t/t_const.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_const.pl +++ b/test_regress/t/t_const.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_const_bad.pl b/test_regress/t/t_const_bad.pl index fad9da3fe..53e145105 100755 --- a/test_regress/t/t_const_bad.pl +++ b/test_regress/t/t_const_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_const_dec_mixed_bad.pl b/test_regress/t/t_const_dec_mixed_bad.pl index f3dd1d2a1..35d749208 100755 --- a/test_regress/t/t_const_dec_mixed_bad.pl +++ b/test_regress/t/t_const_dec_mixed_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_const_overflow_bad.pl b/test_regress/t/t_const_overflow_bad.pl index f3dd1d2a1..35d749208 100755 --- a/test_regress/t/t_const_overflow_bad.pl +++ b/test_regress/t/t_const_overflow_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_cover_line.out b/test_regress/t/t_cover_line.out index 567dd70ca..579327102 100644 --- a/test_regress/t/t_cover_line.out +++ b/test_regress/t/t_cover_line.out @@ -12,60 +12,136 @@ input clk; - reg toggle; initial toggle=0; + reg toggle; +%000002 initial toggle=0; + + integer cyc; +%000002 initial cyc=1; - integer cyc; initial cyc=1; wire [7:0] cyc_copy = cyc[7:0]; alpha a1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); alpha a2 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); beta b1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); beta b2 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); tsk t1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); off o1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); - always @ (posedge clk) begin - 000010 if (cyc!=0) begin - cyc <= cyc + 1; - toggle <= '0; -%000001 if (cyc==3) begin - toggle <= '1; - end -%000001 else if (cyc==5) begin + 000020 always @ (posedge clk) begin + 000020 if (cyc!=0) begin +%000000 verilator_coverage: (next point on previous line) + + 000010 cyc <= cyc + 1; + 000010 toggle <= '0; + // Single and multiline if +%000002 if (cyc==3) $write(""); +%000009 verilator_coverage: (next point on previous line) + +%000002 if (cyc==3) +%000009 verilator_coverage: (next point on previous line) + +%000001 begin +%000001 $write(""); + end + // Single and multiline else +%000002 if (cyc==3) ; else $write(""); +%000018 verilator_coverage: (next point on previous line) + +%000002 if (cyc==3) ; +%000009 verilator_coverage: (next point on previous line) + + else +%000009 begin +%000009 $write(""); + end + // Single and multiline if else +%000002 if (cyc==3) $write(""); else $write(""); +%000018 verilator_coverage: (next point on previous line) + +%000002 if (cyc==3) +%000009 verilator_coverage: (next point on previous line) + +%000001 begin +%000001 $write(""); + end + else +%000009 begin +%000009 $write(""); + end + // multiline elseif +%000002 if (cyc==3) +%000001 begin +%000001 $write(""); + end +%000002 else if (cyc==4) +%000001 begin +%000001 $write(""); + end +%000002 else if (cyc==5) +%000007 verilator_coverage: (next point on previous line) + +%000001 begin +%000001 $write(""); + end + else +%000007 begin +%000007 $write(""); + end + // Single and multiline while +%000000 while (0); +%000000 while (0) begin +%000000 $write(""); + end +%000000 do ; while (0); + 000010 do begin +%000000 verilator_coverage: (next point on previous line) + + 000010 $write(""); +%000000 verilator_coverage: (next point on previous line) + +%000000 end while (0); + //=== + // Task and complicated +%000002 if (cyc==3) begin +%000001 toggle <= '1; + end +%000002 else if (cyc==5) begin `ifdef VERILATOR - $c("call_task();"); +%000001 $c("call_task();"); `else - call_task(); + call_task(); `endif - end -%000001 else if (cyc==10) begin - $write("*-* All Finished *-*\n"); - $finish; - end + end +%000002 else if (cyc==10) begin +%000007 verilator_coverage: (next point on previous line) + +%000001 $write("*-* All Finished *-*\n"); +%000001 $finish; + end end end - task call_task; +%000002 task call_task; /* verilator public */ - t1.center_task(1'b1); +%000001 t1.center_task(1'b1); endtask endmodule @@ -76,18 +152,19 @@ ); input clk; input toggle; - always @ (posedge clk) begin -%000002 if (toggle) begin - // CHECK_COVER(-1,"top.t.a*",2) - // t.a1 and t.a2 collapse to a count of 2 + 000040 always @ (posedge clk) begin +%000004 if (toggle) begin // CHECK_COVER(0,"top.t.a*",2) + 000018 verilator_coverage: (next point on previous line) + +%000002 $write(""); + // t.a1 and t.a2 collapse to a count of 2 end - if (toggle) begin - // CHECK_COVER_MISSING(-1) - // This doesn't even get added + 000018 if (toggle) begin + $write(""); // CHECK_COVER_MISSING(0) + // This doesn't even get added `ifdef ATTRIBUTE - // verilator coverage_block_off + // verilator coverage_block_off `endif - $write(""); end end endmodule @@ -101,22 +178,28 @@ /* verilator public_module */ - always @ (posedge clk) begin -%000000 if (0) begin - // CHECK_COVER(-1,"top.t.b*",0) - // Make sure that we don't optimize away zero buckets + 000040 always @ (posedge clk) begin + 000020 $write(""); // Always covered +%000000 if (0) begin // CHECK_COVER(0,"top.t.b*",0) + 000020 verilator_coverage: (next point on previous line) + + // Make sure that we don't optimize away zero buckets +%000000 $write(""); end -%000002 if (toggle) begin - // CHECK_COVER(-1,"top.t.b*",2) - // t.b1 and t.b2 collapse to a count of 2 +%000004 if (toggle) begin // CHECK_COVER(0,"top.t.b*",2) + 000018 verilator_coverage: (next point on previous line) + + // t.b1 and t.b2 collapse to a count of 2 +%000002 $write(""); end - if (toggle) begin : block - // CHECK_COVER_MISSING(-1) - // This doesn't + 000018 if (toggle) begin : block + // This doesn't `ifdef ATTRIBUTE - // verilator coverage_block_off + // verilator coverage_block_off `endif - $write(""); + begin end // Needed for .vlt to attach coverage_block_off + if (1) begin end // CHECK_COVER_MISSING(0) + $write(""); // CHECK_COVER_MISSING(0) end end endmodule @@ -130,20 +213,23 @@ /* verilator public_module */ - always @ (posedge clk) begin - center_task(1'b0); + 000020 always @ (posedge clk) begin + 000010 center_task(1'b0); end - task center_task; + 000022 task center_task; input external; - begin -%000001 if (toggle) begin - // CHECK_COVER(-1,"top.t.t1",1) - end -%000001 if (external) begin - // CHECK_COVER(-1,"top.t.t1",1) - $write("[%0t] Got external pulse\n", $time); - end + 000011 begin +%000002 if (toggle) begin // CHECK_COVER(0,"top.t.t1",1) + 000010 verilator_coverage: (next point on previous line) + +%000001 $write(""); + end +%000002 if (external) begin // CHECK_COVER(0,"top.t.t1",1) + 000010 verilator_coverage: (next point on previous line) + +%000001 $write("[%0t] Got external pulse\n", $time); + end end endtask @@ -159,15 +245,20 @@ // verilator coverage_off always @ (posedge clk) begin if (toggle) begin - // CHECK_COVER_MISSING(-1) - // because under coverage_module_off + $write(""); // CHECK_COVER_MISSING(0) + // because under coverage_module_off end end // verilator coverage_on - always @ (posedge clk) begin -%000001 if (toggle) begin - // CHECK_COVER(-1,"top.t.o1",1) - // because under coverage_module_off + 000020 always @ (posedge clk) begin +%000002 if (toggle) begin +%000009 verilator_coverage: (next point on previous line) + + // because under coverage_module_off +%000001 $write(""); +%000000 if (0) ; // CHECK_COVER(0,"top.t.o1",1) +%000001 verilator_coverage: (next point on previous line) + end end diff --git a/test_regress/t/t_cover_line.v b/test_regress/t/t_cover_line.v index 887c02c14..580e31061 100644 --- a/test_regress/t/t_cover_line.v +++ b/test_regress/t/t_cover_line.v @@ -11,54 +11,108 @@ module t (/*AUTOARG*/ input clk; - reg toggle; initial toggle=0; + reg toggle; + initial toggle=0; + + integer cyc; + initial cyc=1; - integer cyc; initial cyc=1; wire [7:0] cyc_copy = cyc[7:0]; alpha a1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); alpha a2 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); beta b1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); beta b2 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); tsk t1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); off o1 (/*AUTOINST*/ - // Inputs - .clk (clk), - .toggle (toggle)); + // Inputs + .clk (clk), + .toggle (toggle)); always @ (posedge clk) begin if (cyc!=0) begin - cyc <= cyc + 1; - toggle <= '0; - if (cyc==3) begin - toggle <= '1; - end - else if (cyc==5) begin + cyc <= cyc + 1; + toggle <= '0; + // Single and multiline if + if (cyc==3) $write(""); + if (cyc==3) + begin + $write(""); + end + // Single and multiline else + if (cyc==3) ; else $write(""); + if (cyc==3) ; + else + begin + $write(""); + end + // Single and multiline if else + if (cyc==3) $write(""); else $write(""); + if (cyc==3) + begin + $write(""); + end + else + begin + $write(""); + end + // multiline elseif + if (cyc==3) + begin + $write(""); + end + else if (cyc==4) + begin + $write(""); + end + else if (cyc==5) + begin + $write(""); + end + else + begin + $write(""); + end + // Single and multiline while + while (0); + while (0) begin + $write(""); + end + do ; while (0); + do begin + $write(""); + end while (0); + //=== + // Task and complicated + if (cyc==3) begin + toggle <= '1; + end + else if (cyc==5) begin `ifdef VERILATOR - $c("call_task();"); + $c("call_task();"); `else - call_task(); + call_task(); `endif - end - else if (cyc==10) begin - $write("*-* All Finished *-*\n"); - $finish; - end + end + else if (cyc==10) begin + $write("*-* All Finished *-*\n"); + $finish; + end end end @@ -76,17 +130,16 @@ module alpha (/*AUTOARG*/ input clk; input toggle; always @ (posedge clk) begin - if (toggle) begin - // CHECK_COVER(-1,"top.t.a*",2) - // t.a1 and t.a2 collapse to a count of 2 + if (toggle) begin // CHECK_COVER(0,"top.t.a*",2) + $write(""); + // t.a1 and t.a2 collapse to a count of 2 end if (toggle) begin - // CHECK_COVER_MISSING(-1) - // This doesn't even get added + $write(""); // CHECK_COVER_MISSING(0) + // This doesn't even get added `ifdef ATTRIBUTE - // verilator coverage_block_off + // verilator coverage_block_off `endif - $write(""); end end endmodule @@ -101,21 +154,23 @@ module beta (/*AUTOARG*/ /* verilator public_module */ always @ (posedge clk) begin - if (0) begin - // CHECK_COVER(-1,"top.t.b*",0) - // Make sure that we don't optimize away zero buckets + $write(""); // Always covered + if (0) begin // CHECK_COVER(0,"top.t.b*",0) + // Make sure that we don't optimize away zero buckets + $write(""); end - if (toggle) begin - // CHECK_COVER(-1,"top.t.b*",2) - // t.b1 and t.b2 collapse to a count of 2 + if (toggle) begin // CHECK_COVER(0,"top.t.b*",2) + // t.b1 and t.b2 collapse to a count of 2 + $write(""); end if (toggle) begin : block - // CHECK_COVER_MISSING(-1) - // This doesn't + // This doesn't `ifdef ATTRIBUTE - // verilator coverage_block_off + // verilator coverage_block_off `endif - $write(""); + begin end // Needed for .vlt to attach coverage_block_off + if (1) begin end // CHECK_COVER_MISSING(0) + $write(""); // CHECK_COVER_MISSING(0) end end endmodule @@ -136,13 +191,12 @@ module tsk (/*AUTOARG*/ task center_task; input external; begin - if (toggle) begin - // CHECK_COVER(-1,"top.t.t1",1) - end - if (external) begin - // CHECK_COVER(-1,"top.t.t1",1) - $write("[%0t] Got external pulse\n", $time); - end + if (toggle) begin // CHECK_COVER(0,"top.t.t1",1) + $write(""); + end + if (external) begin // CHECK_COVER(0,"top.t.t1",1) + $write("[%0t] Got external pulse\n", $time); + end end endtask @@ -158,15 +212,16 @@ module off (/*AUTOARG*/ // verilator coverage_off always @ (posedge clk) begin if (toggle) begin - // CHECK_COVER_MISSING(-1) - // because under coverage_module_off + $write(""); // CHECK_COVER_MISSING(0) + // because under coverage_module_off end end // verilator coverage_on always @ (posedge clk) begin if (toggle) begin - // CHECK_COVER(-1,"top.t.o1",1) - // because under coverage_module_off + // because under coverage_module_off + $write(""); + if (0) ; // CHECK_COVER(0,"top.t.o1",1) end end diff --git a/test_regress/t/t_cover_line.vlt b/test_regress/t/t_cover_line.vlt index 898f27d9c..a7303b6b5 100644 --- a/test_regress/t/t_cover_line.vlt +++ b/test_regress/t/t_cover_line.vlt @@ -6,5 +6,6 @@ `verilator_config -coverage_block_off -file "t/t_cover_line.v" -lines 83 +coverage_block_off -file "t/t_cover_line.v" -lines 137 +coverage_block_off -file "t/t_cover_line.v" -lines 171 coverage_block_off -module "beta" -block "block" diff --git a/test_regress/t/t_cover_line_cc.pl b/test_regress/t/t_cover_line_cc.pl index a583cabb2..08a0a6f03 100755 --- a/test_regress/t/t_cover_line_cc.pl +++ b/test_regress/t/t_cover_line_cc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -25,10 +25,32 @@ inline_checks(); run(cmd => ["../bin/verilator_coverage", "--annotate", "$Self->{obj_dir}/annotated", - "$Self->{obj_dir}/coverage.dat", - ]); + "$Self->{obj_dir}/coverage.dat"], + verilator_run => 1, + ); files_identical("$Self->{obj_dir}/annotated/t_cover_line.v", "t/t_cover_line.out"); +# Also try lcov +run(cmd => ["../bin/verilator_coverage", + "--write-info", "$Self->{obj_dir}/coverage.info", + "$Self->{obj_dir}/coverage.dat"], + verilator_run => 1, + ); + +# If installed +if (`lcov --version` !~ /version/i + || `genhtml --version` !~ /version ([0-9.]+)/i) { + skip("lcov or genhtml not installed"); +} elsif ($1 < 1.14) { + skip("lcov or genhtml too old (version $1), need version >= 1.14"); +} else { + run(cmd => ["genhtml", + "$Self->{obj_dir}/coverage.info", + "--output-directory $Self->{obj_dir}/html", + ]); +} + + ok(1); 1; diff --git a/test_regress/t/t_cover_line_cc_vlt.pl b/test_regress/t/t_cover_line_cc_vlt.pl index 0d9234f4a..1d21931e1 100755 --- a/test_regress/t/t_cover_line_cc_vlt.pl +++ b/test_regress/t/t_cover_line_cc_vlt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -26,7 +26,9 @@ inline_checks(); run(cmd => ["../bin/verilator_coverage", "--annotate", "$Self->{obj_dir}/annotated", "$Self->{obj_dir}/coverage.dat", - ]); + ], + verilator_run => 1, + ); files_identical("$Self->{obj_dir}/annotated/t_cover_line.v", "t/t_cover_line.out"); diff --git a/test_regress/t/t_cover_line_sc.pl b/test_regress/t/t_cover_line_sc.pl index e22105fb5..6fb074bfb 100755 --- a/test_regress/t/t_cover_line_sc.pl +++ b/test_regress/t/t_cover_line_sc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_cover_line_trace.out b/test_regress/t/t_cover_line_trace.out index d328b8b1b..56c0bd1d1 100644 --- a/test_regress/t/t_cover_line_trace.out +++ b/test_regress/t/t_cover_line_trace.out @@ -1,51 +1,99 @@ $version Generated by VerilatedVcd $end -$date Thu Mar 19 18:37:02 2020 +$date Sun May 31 15:48:42 2020 $end $timescale 1ps $end $scope module top $end - $var wire 1 5! clk $end + $var wire 1 W clk $end $scope module t $end - $var wire 1 5! clk $end - $var wire 32 + cyc [31:0] $end - $var wire 8 3 cyc_copy [7:0] $end - $var wire 1 # toggle $end - $var wire 32 S vlCoverageLineTrace_t_cover_line__45_if [31:0] $end - $var wire 32 ; vlCoverageLineTrace_t_cover_line__48_if [31:0] $end - $var wire 32 C vlCoverageLineTrace_t_cover_line__51_elsif [31:0] $end - $var wire 32 K vlCoverageLineTrace_t_cover_line__58_elsif [31:0] $end + $var wire 1 W clk $end + $var wire 32 & cyc [31:0] $end + $var wire 8 ' cyc_copy [7:0] $end + $var wire 1 % toggle $end + $var wire 32 ; vlCoverageLineTrace_t_cover_line__102_elsif [31:0] $end + $var wire 32 : vlCoverageLineTrace_t_cover_line__105_elsif [31:0] $end + $var wire 32 9 vlCoverageLineTrace_t_cover_line__112_else [31:0] $end + $var wire 32 8 vlCoverageLineTrace_t_cover_line__112_if [31:0] $end + $var wire 32 X vlCoverageLineTrace_t_cover_line__119_block [31:0] $end + $var wire 32 # vlCoverageLineTrace_t_cover_line__15_block [31:0] $end + $var wire 32 $ vlCoverageLineTrace_t_cover_line__18_block [31:0] $end + $var wire 32 > vlCoverageLineTrace_t_cover_line__47_block [31:0] $end + $var wire 32 = vlCoverageLineTrace_t_cover_line__48_else [31:0] $end + $var wire 32 < vlCoverageLineTrace_t_cover_line__48_if [31:0] $end + $var wire 32 ) vlCoverageLineTrace_t_cover_line__52_else [31:0] $end + $var wire 32 ( vlCoverageLineTrace_t_cover_line__52_if [31:0] $end + $var wire 32 + vlCoverageLineTrace_t_cover_line__53_else [31:0] $end + $var wire 32 * vlCoverageLineTrace_t_cover_line__53_if [31:0] $end + $var wire 32 - vlCoverageLineTrace_t_cover_line__58_else [31:0] $end + $var wire 32 , vlCoverageLineTrace_t_cover_line__58_if [31:0] $end + $var wire 32 / vlCoverageLineTrace_t_cover_line__59_else [31:0] $end + $var wire 32 . vlCoverageLineTrace_t_cover_line__59_if [31:0] $end + $var wire 32 1 vlCoverageLineTrace_t_cover_line__65_else [31:0] $end + $var wire 32 0 vlCoverageLineTrace_t_cover_line__65_if [31:0] $end + $var wire 32 3 vlCoverageLineTrace_t_cover_line__66_else [31:0] $end + $var wire 32 2 vlCoverageLineTrace_t_cover_line__66_if [31:0] $end + $var wire 32 7 vlCoverageLineTrace_t_cover_line__75_elsif [31:0] $end + $var wire 32 6 vlCoverageLineTrace_t_cover_line__79_elsif [31:0] $end + $var wire 32 5 vlCoverageLineTrace_t_cover_line__83_else [31:0] $end + $var wire 32 4 vlCoverageLineTrace_t_cover_line__83_if [31:0] $end + $var wire 32 ] vlCoverageLineTrace_t_cover_line__92_block [31:0] $end + $var wire 32 ^ vlCoverageLineTrace_t_cover_line__93_block [31:0] $end + $var wire 32 _ vlCoverageLineTrace_t_cover_line__96_block [31:0] $end + $var wire 32 ` vlCoverageLineTrace_t_cover_line__97_block [31:0] $end $scope module a1 $end - $var wire 1 5! clk $end - $var wire 1 # toggle $end - $var wire 32 [ vlCoverageLineTrace_t_cover_line__79_if [31:0] $end + $var wire 1 W clk $end + $var wire 1 % toggle $end + $var wire 32 B vlCoverageLineTrace_t_cover_line__132_block [31:0] $end + $var wire 32 @ vlCoverageLineTrace_t_cover_line__133_else [31:0] $end + $var wire 32 ? vlCoverageLineTrace_t_cover_line__133_if [31:0] $end + $var wire 32 A vlCoverageLineTrace_t_cover_line__137_else [31:0] $end $upscope $end $scope module a2 $end - $var wire 1 5! clk $end - $var wire 1 # toggle $end - $var wire 32 c vlCoverageLineTrace_t_cover_line__79_if [31:0] $end + $var wire 1 W clk $end + $var wire 1 % toggle $end + $var wire 32 F vlCoverageLineTrace_t_cover_line__132_block [31:0] $end + $var wire 32 D vlCoverageLineTrace_t_cover_line__133_else [31:0] $end + $var wire 32 C vlCoverageLineTrace_t_cover_line__133_if [31:0] $end + $var wire 32 E vlCoverageLineTrace_t_cover_line__137_else [31:0] $end $upscope $end $scope module b1 $end - $var wire 1 5! clk $end - $var wire 1 # toggle $end - $var wire 32 =! vlCoverageLineTrace_t_cover_line__104_if [31:0] $end - $var wire 32 s vlCoverageLineTrace_t_cover_line__108_if [31:0] $end + $var wire 1 W clk $end + $var wire 1 % toggle $end + $var wire 32 O vlCoverageLineTrace_t_cover_line__156_block [31:0] $end + $var wire 32 K vlCoverageLineTrace_t_cover_line__158_else [31:0] $end + $var wire 32 b vlCoverageLineTrace_t_cover_line__158_if [31:0] $end + $var wire 32 M vlCoverageLineTrace_t_cover_line__162_else [31:0] $end + $var wire 32 L vlCoverageLineTrace_t_cover_line__162_if [31:0] $end + $var wire 32 N vlCoverageLineTrace_t_cover_line__166_else [31:0] $end $upscope $end $scope module b2 $end - $var wire 1 5! clk $end - $var wire 1 # toggle $end - $var wire 32 E! vlCoverageLineTrace_t_cover_line__104_if [31:0] $end - $var wire 32 { vlCoverageLineTrace_t_cover_line__108_if [31:0] $end + $var wire 1 W clk $end + $var wire 1 % toggle $end + $var wire 32 T vlCoverageLineTrace_t_cover_line__156_block [31:0] $end + $var wire 32 P vlCoverageLineTrace_t_cover_line__158_else [31:0] $end + $var wire 32 c vlCoverageLineTrace_t_cover_line__158_if [31:0] $end + $var wire 32 R vlCoverageLineTrace_t_cover_line__162_else [31:0] $end + $var wire 32 Q vlCoverageLineTrace_t_cover_line__162_if [31:0] $end + $var wire 32 S vlCoverageLineTrace_t_cover_line__166_else [31:0] $end $upscope $end $scope module o1 $end - $var wire 1 5! clk $end - $var wire 1 # toggle $end - $var wire 32 k vlCoverageLineTrace_t_cover_line__167_if [31:0] $end + $var wire 1 W clk $end + $var wire 1 % toggle $end + $var wire 32 J vlCoverageLineTrace_t_cover_line__220_block [31:0] $end + $var wire 32 I vlCoverageLineTrace_t_cover_line__221_else [31:0] $end + $var wire 32 H vlCoverageLineTrace_t_cover_line__221_if [31:0] $end + $var wire 32 G vlCoverageLineTrace_t_cover_line__224_else [31:0] $end + $var wire 32 a vlCoverageLineTrace_t_cover_line__224_if [31:0] $end $upscope $end $scope module t1 $end - $var wire 1 5! clk $end - $var wire 1 # toggle $end - $var wire 32 %! vlCoverageLineTrace_t_cover_line__139_if [31:0] $end - $var wire 32 -! vlCoverageLineTrace_t_cover_line__142_if [31:0] $end + $var wire 1 W clk $end + $var wire 1 % toggle $end + $var wire 32 U vlCoverageLineTrace_t_cover_line__187_block [31:0] $end + $var wire 32 \ vlCoverageLineTrace_t_cover_line__191_block [31:0] $end + $var wire 32 Z vlCoverageLineTrace_t_cover_line__194_else [31:0] $end + $var wire 32 Y vlCoverageLineTrace_t_cover_line__194_if [31:0] $end + $var wire 32 V vlCoverageLineTrace_t_cover_line__197_else [31:0] $end + $var wire 32 [ vlCoverageLineTrace_t_cover_line__197_if [31:0] $end $upscope $end $upscope $end $upscope $end @@ -53,100 +101,427 @@ $enddefinitions $end #0 -0# -b00000000000000000000000000000001 + -b00000001 3 +b00000000000000000000000000000001 # +b00000000000000000000000000000001 $ +0% +b00000000000000000000000000000001 & +b00000001 ' +b00000000000000000000000000000000 ( +b00000000000000000000000000000000 ) +b00000000000000000000000000000000 * +b00000000000000000000000000000000 + +b00000000000000000000000000000000 , +b00000000000000000000000000000000 - +b00000000000000000000000000000000 . +b00000000000000000000000000000000 / +b00000000000000000000000000000000 0 +b00000000000000000000000000000000 1 +b00000000000000000000000000000000 2 +b00000000000000000000000000000000 3 +b00000000000000000000000000000000 4 +b00000000000000000000000000000000 5 +b00000000000000000000000000000000 6 +b00000000000000000000000000000000 7 +b00000000000000000000000000000000 8 +b00000000000000000000000000000000 9 +b00000000000000000000000000000000 : b00000000000000000000000000000000 ; +b00000000000000000000000000000000 < +b00000000000000000000000000000000 = +b00000000000000000000000000000000 > +b00000000000000000000000000000000 ? +b00000000000000000000000000000000 @ +b00000000000000000000000000000000 A +b00000000000000000000000000000000 B b00000000000000000000000000000000 C +b00000000000000000000000000000000 D +b00000000000000000000000000000000 E +b00000000000000000000000000000000 F +b00000000000000000000000000000000 G +b00000000000000000000000000000000 H +b00000000000000000000000000000000 I +b00000000000000000000000000000000 J b00000000000000000000000000000000 K +b00000000000000000000000000000000 L +b00000000000000000000000000000000 M +b00000000000000000000000000000000 N +b00000000000000000000000000000000 O +b00000000000000000000000000000000 P +b00000000000000000000000000000000 Q +b00000000000000000000000000000000 R b00000000000000000000000000000000 S +b00000000000000000000000000000000 T +b00000000000000000000000000000000 U +b00000000000000000000000000000000 V +0W +b00000000000000000000000000000000 X +b00000000000000000000000000000000 Y +b00000000000000000000000000000000 Z b00000000000000000000000000000000 [ +b00000000000000000000000000000000 \ +b00000000000000000000000000000000 ] +b00000000000000000000000000000000 ^ +b00000000000000000000000000000000 _ +b00000000000000000000000000000000 ` +b00000000000000000000000000000000 a +b00000000000000000000000000000000 b b00000000000000000000000000000000 c -b00000000000000000000000000000000 k -b00000000000000000000000000000000 s -b00000000000000000000000000000000 { -b00000000000000000000000000000000 %! -b00000000000000000000000000000000 -! -05! -b00000000000000000000000000000000 =! -b00000000000000000000000000000000 E! #10 -b00000000000000000000000000000010 + -b00000010 3 -b00000000000000000000000000000001 S -15! -#15 -05! -#20 -b00000000000000000000000000000011 + -b00000011 3 -b00000000000000000000000000000010 S -15! -#25 -05! -#30 -1# -b00000000000000000000000000000100 + -b00000100 3 -b00000000000000000000000000000001 ; -b00000000000000000000000000000011 S -15! -#35 -05! -#40 -0# -b00000000000000000000000000000101 + -b00000101 3 -b00000000000000000000000000000100 S -b00000000000000000000000000000001 [ -b00000000000000000000000000000001 c -b00000000000000000000000000000001 k -b00000000000000000000000000000001 s -b00000000000000000000000000000001 { -b00000000000000000000000000000001 %! -15! -#45 -05! -#50 -b00000000000000000000000000000110 + -b00000110 3 -b00000000000000000000000000000001 C -b00000000000000000000000000000101 S -b00000000000000000000000000000001 -! -15! -#55 -05! -#60 -b00000000000000000000000000000111 + -b00000111 3 -b00000000000000000000000000000110 S -15! -#65 -05! -#70 -b00000000000000000000000000001000 + -b00001000 3 -b00000000000000000000000000000111 S -15! -#75 -05! -#80 -b00000000000000000000000000001001 + -b00001001 3 -b00000000000000000000000000001000 S -15! -#85 -05! -#90 -b00000000000000000000000000001010 + -b00001010 3 -b00000000000000000000000000001001 S -15! -#95 -05! -#100 -b00000000000000000000000000001011 + -b00001011 3 +b00000000000000000000000000000010 & +b00000010 ' +b00000000000000000000000000000001 ) +b00000000000000000000000000000001 + +b00000000000000000000000000000001 - +b00000000000000000000000000000001 / +b00000000000000000000000000000001 1 +b00000000000000000000000000000001 3 +b00000000000000000000000000000001 5 +b00000000000000000000000000000001 9 +b00000000000000000000000000000001 < +b00000000000000000000000000000001 > +b00000000000000000000000000000001 @ +b00000000000000000000000000000001 A +b00000000000000000000000000000001 B +b00000000000000000000000000000001 D +b00000000000000000000000000000001 E +b00000000000000000000000000000001 F +b00000000000000000000000000000001 I +b00000000000000000000000000000001 J b00000000000000000000000000000001 K -b00000000000000000000000000001010 S -15! +b00000000000000000000000000000001 M +b00000000000000000000000000000001 N +b00000000000000000000000000000001 O +b00000000000000000000000000000001 P +b00000000000000000000000000000001 R +b00000000000000000000000000000001 S +b00000000000000000000000000000001 T +b00000000000000000000000000000001 U +b00000000000000000000000000000001 V +1W +b00000000000000000000000000000001 Z +b00000000000000000000000000000001 \ +#15 +0W +#20 +b00000000000000000000000000000011 & +b00000011 ' +b00000000000000000000000000000010 ) +b00000000000000000000000000000010 + +b00000000000000000000000000000010 - +b00000000000000000000000000000010 / +b00000000000000000000000000000010 1 +b00000000000000000000000000000010 3 +b00000000000000000000000000000010 5 +b00000000000000000000000000000010 9 +b00000000000000000000000000000010 < +b00000000000000000000000000000010 > +b00000000000000000000000000000010 @ +b00000000000000000000000000000010 A +b00000000000000000000000000000010 B +b00000000000000000000000000000010 D +b00000000000000000000000000000010 E +b00000000000000000000000000000010 F +b00000000000000000000000000000010 I +b00000000000000000000000000000010 J +b00000000000000000000000000000010 K +b00000000000000000000000000000010 M +b00000000000000000000000000000010 N +b00000000000000000000000000000010 O +b00000000000000000000000000000010 P +b00000000000000000000000000000010 R +b00000000000000000000000000000010 S +b00000000000000000000000000000010 T +b00000000000000000000000000000010 U +b00000000000000000000000000000010 V +1W +b00000000000000000000000000000010 Z +b00000000000000000000000000000010 \ +#25 +0W +#30 +1% +b00000000000000000000000000000100 & +b00000100 ' +b00000000000000000000000000000001 ( +b00000000000000000000000000000001 * +b00000000000000000000000000000001 , +b00000000000000000000000000000001 . +b00000000000000000000000000000001 0 +b00000000000000000000000000000001 2 +b00000000000000000000000000000001 7 +b00000000000000000000000000000001 ; +b00000000000000000000000000000011 < +b00000000000000000000000000000011 > +b00000000000000000000000000000011 @ +b00000000000000000000000000000011 A +b00000000000000000000000000000011 B +b00000000000000000000000000000011 D +b00000000000000000000000000000011 E +b00000000000000000000000000000011 F +b00000000000000000000000000000011 I +b00000000000000000000000000000011 J +b00000000000000000000000000000011 K +b00000000000000000000000000000011 M +b00000000000000000000000000000011 N +b00000000000000000000000000000011 O +b00000000000000000000000000000011 P +b00000000000000000000000000000011 R +b00000000000000000000000000000011 S +b00000000000000000000000000000011 T +b00000000000000000000000000000011 U +b00000000000000000000000000000011 V +1W +b00000000000000000000000000000011 Z +b00000000000000000000000000000011 \ +#35 +0W +#40 +0% +b00000000000000000000000000000101 & +b00000101 ' +b00000000000000000000000000000011 ) +b00000000000000000000000000000011 + +b00000000000000000000000000000011 - +b00000000000000000000000000000011 / +b00000000000000000000000000000011 1 +b00000000000000000000000000000011 3 +b00000000000000000000000000000001 6 +b00000000000000000000000000000011 9 +b00000000000000000000000000000100 < +b00000000000000000000000000000100 > +b00000000000000000000000000000001 ? +b00000000000000000000000000000100 B +b00000000000000000000000000000001 C +b00000000000000000000000000000100 F +b00000000000000000000000000000001 G +b00000000000000000000000000000001 H +b00000000000000000000000000000100 J +b00000000000000000000000000000100 K +b00000000000000000000000000000001 L +b00000000000000000000000000000100 O +b00000000000000000000000000000100 P +b00000000000000000000000000000001 Q +b00000000000000000000000000000100 T +b00000000000000000000000000000100 U +b00000000000000000000000000000100 V +1W +b00000000000000000000000000000001 Y +b00000000000000000000000000000100 \ +#45 +0W +#50 +b00000000000000000000000000000110 & +b00000110 ' +b00000000000000000000000000000100 ) +b00000000000000000000000000000100 + +b00000000000000000000000000000100 - +b00000000000000000000000000000100 / +b00000000000000000000000000000100 1 +b00000000000000000000000000000100 3 +b00000000000000000000000000000001 4 +b00000000000000000000000000000001 : +b00000000000000000000000000000101 < +b00000000000000000000000000000101 > +b00000000000000000000000000000100 @ +b00000000000000000000000000000100 A +b00000000000000000000000000000101 B +b00000000000000000000000000000100 D +b00000000000000000000000000000100 E +b00000000000000000000000000000101 F +b00000000000000000000000000000100 I +b00000000000000000000000000000101 J +b00000000000000000000000000000101 K +b00000000000000000000000000000100 M +b00000000000000000000000000000100 N +b00000000000000000000000000000101 O +b00000000000000000000000000000101 P +b00000000000000000000000000000100 R +b00000000000000000000000000000100 S +b00000000000000000000000000000101 T +b00000000000000000000000000000101 U +b00000000000000000000000000000101 V +1W +b00000000000000000000000000000001 X +b00000000000000000000000000000101 Z +b00000000000000000000000000000001 [ +b00000000000000000000000000000110 \ +#55 +0W +#60 +b00000000000000000000000000000111 & +b00000111 ' +b00000000000000000000000000000101 ) +b00000000000000000000000000000101 + +b00000000000000000000000000000101 - +b00000000000000000000000000000101 / +b00000000000000000000000000000101 1 +b00000000000000000000000000000101 3 +b00000000000000000000000000000011 5 +b00000000000000000000000000000100 9 +b00000000000000000000000000000110 < +b00000000000000000000000000000110 > +b00000000000000000000000000000101 @ +b00000000000000000000000000000101 A +b00000000000000000000000000000110 B +b00000000000000000000000000000101 D +b00000000000000000000000000000101 E +b00000000000000000000000000000110 F +b00000000000000000000000000000101 I +b00000000000000000000000000000110 J +b00000000000000000000000000000110 K +b00000000000000000000000000000101 M +b00000000000000000000000000000101 N +b00000000000000000000000000000110 O +b00000000000000000000000000000110 P +b00000000000000000000000000000101 R +b00000000000000000000000000000101 S +b00000000000000000000000000000110 T +b00000000000000000000000000000110 U +b00000000000000000000000000000110 V +1W +b00000000000000000000000000000110 Z +b00000000000000000000000000000111 \ +#65 +0W +#70 +b00000000000000000000000000001000 & +b00001000 ' +b00000000000000000000000000000110 ) +b00000000000000000000000000000110 + +b00000000000000000000000000000110 - +b00000000000000000000000000000110 / +b00000000000000000000000000000110 1 +b00000000000000000000000000000110 3 +b00000000000000000000000000000100 5 +b00000000000000000000000000000101 9 +b00000000000000000000000000000111 < +b00000000000000000000000000000111 > +b00000000000000000000000000000110 @ +b00000000000000000000000000000110 A +b00000000000000000000000000000111 B +b00000000000000000000000000000110 D +b00000000000000000000000000000110 E +b00000000000000000000000000000111 F +b00000000000000000000000000000110 I +b00000000000000000000000000000111 J +b00000000000000000000000000000111 K +b00000000000000000000000000000110 M +b00000000000000000000000000000110 N +b00000000000000000000000000000111 O +b00000000000000000000000000000111 P +b00000000000000000000000000000110 R +b00000000000000000000000000000110 S +b00000000000000000000000000000111 T +b00000000000000000000000000000111 U +b00000000000000000000000000000111 V +1W +b00000000000000000000000000000111 Z +b00000000000000000000000000001000 \ +#75 +0W +#80 +b00000000000000000000000000001001 & +b00001001 ' +b00000000000000000000000000000111 ) +b00000000000000000000000000000111 + +b00000000000000000000000000000111 - +b00000000000000000000000000000111 / +b00000000000000000000000000000111 1 +b00000000000000000000000000000111 3 +b00000000000000000000000000000101 5 +b00000000000000000000000000000110 9 +b00000000000000000000000000001000 < +b00000000000000000000000000001000 > +b00000000000000000000000000000111 @ +b00000000000000000000000000000111 A +b00000000000000000000000000001000 B +b00000000000000000000000000000111 D +b00000000000000000000000000000111 E +b00000000000000000000000000001000 F +b00000000000000000000000000000111 I +b00000000000000000000000000001000 J +b00000000000000000000000000001000 K +b00000000000000000000000000000111 M +b00000000000000000000000000000111 N +b00000000000000000000000000001000 O +b00000000000000000000000000001000 P +b00000000000000000000000000000111 R +b00000000000000000000000000000111 S +b00000000000000000000000000001000 T +b00000000000000000000000000001000 U +b00000000000000000000000000001000 V +1W +b00000000000000000000000000001000 Z +b00000000000000000000000000001001 \ +#85 +0W +#90 +b00000000000000000000000000001010 & +b00001010 ' +b00000000000000000000000000001000 ) +b00000000000000000000000000001000 + +b00000000000000000000000000001000 - +b00000000000000000000000000001000 / +b00000000000000000000000000001000 1 +b00000000000000000000000000001000 3 +b00000000000000000000000000000110 5 +b00000000000000000000000000000111 9 +b00000000000000000000000000001001 < +b00000000000000000000000000001001 > +b00000000000000000000000000001000 @ +b00000000000000000000000000001000 A +b00000000000000000000000000001001 B +b00000000000000000000000000001000 D +b00000000000000000000000000001000 E +b00000000000000000000000000001001 F +b00000000000000000000000000001000 I +b00000000000000000000000000001001 J +b00000000000000000000000000001001 K +b00000000000000000000000000001000 M +b00000000000000000000000000001000 N +b00000000000000000000000000001001 O +b00000000000000000000000000001001 P +b00000000000000000000000000001000 R +b00000000000000000000000000001000 S +b00000000000000000000000000001001 T +b00000000000000000000000000001001 U +b00000000000000000000000000001001 V +1W +b00000000000000000000000000001001 Z +b00000000000000000000000000001010 \ +#95 +0W +#100 +b00000000000000000000000000001011 & +b00001011 ' +b00000000000000000000000000001001 ) +b00000000000000000000000000001001 + +b00000000000000000000000000001001 - +b00000000000000000000000000001001 / +b00000000000000000000000000001001 1 +b00000000000000000000000000001001 3 +b00000000000000000000000000000111 5 +b00000000000000000000000000000001 8 +b00000000000000000000000000001010 < +b00000000000000000000000000001010 > +b00000000000000000000000000001001 @ +b00000000000000000000000000001001 A +b00000000000000000000000000001010 B +b00000000000000000000000000001001 D +b00000000000000000000000000001001 E +b00000000000000000000000000001010 F +b00000000000000000000000000001001 I +b00000000000000000000000000001010 J +b00000000000000000000000000001010 K +b00000000000000000000000000001001 M +b00000000000000000000000000001001 N +b00000000000000000000000000001010 O +b00000000000000000000000000001010 P +b00000000000000000000000000001001 R +b00000000000000000000000000001001 S +b00000000000000000000000000001010 T +b00000000000000000000000000001010 U +b00000000000000000000000000001010 V +1W +b00000000000000000000000000001010 Z +b00000000000000000000000000001011 \ diff --git a/test_regress/t/t_cover_line_trace.pl b/test_regress/t/t_cover_line_trace.pl index 06b2e755b..a3763b8c5 100755 --- a/test_regress/t/t_cover_line_trace.pl +++ b/test_regress/t/t_cover_line_trace.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -23,7 +23,9 @@ execute( run(cmd => ["../bin/verilator_coverage", "--annotate", "$Self->{obj_dir}/annotated", "$Self->{obj_dir}/coverage.dat", - ]); + ], + verilator_run => 1, + ); files_identical("$Self->{obj_dir}/annotated/t_cover_line.v", "t/t_cover_line.out"); vcd_identical("$Self->{obj_dir}/simx.vcd", $Self->{golden_filename}); diff --git a/test_regress/t/t_cover_sva_notflat.pl b/test_regress/t/t_cover_sva_notflat.pl index 25cb59609..a509d42b8 100755 --- a/test_regress/t/t_cover_sva_notflat.pl +++ b/test_regress/t/t_cover_sva_notflat.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_cover_sva_trace.pl b/test_regress/t/t_cover_sva_trace.pl index 9125fabc2..aea072add 100755 --- a/test_regress/t/t_cover_sva_trace.pl +++ b/test_regress/t/t_cover_sva_trace.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_cover_toggle.pl b/test_regress/t/t_cover_toggle.pl index 2bbb41827..e0feb7514 100755 --- a/test_regress/t/t_cover_toggle.pl +++ b/test_regress/t/t_cover_toggle.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_crazy_sel.pl b/test_regress/t/t_crazy_sel.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_crazy_sel.pl +++ b/test_regress/t/t_crazy_sel.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_debug_fatalsrc_bad.pl b/test_regress/t/t_debug_fatalsrc_bad.pl index 9acad386f..6f50286a8 100755 --- a/test_regress/t/t_debug_fatalsrc_bad.pl +++ b/test_regress/t/t_debug_fatalsrc_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(vlt => 1); -compile( +lint( verilator_flags2 => ["--debug-fatalsrc"], fails => $Self->{vlt_all}, expect => diff --git a/test_regress/t/t_debug_fatalsrc_bt_bad.pl b/test_regress/t/t_debug_fatalsrc_bt_bad.pl index 9a9d2071b..ad5a9ae03 100755 --- a/test_regress/t/t_debug_fatalsrc_bt_bad.pl +++ b/test_regress/t/t_debug_fatalsrc_bt_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_debug_graph_test.pl b/test_regress/t/t_debug_graph_test.pl new file mode 100755 index 000000000..5ae25d7f3 --- /dev/null +++ b/test_regress/t/t_debug_graph_test.pl @@ -0,0 +1,20 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(vlt => 1); +$ENV{VERILATOR_TEST_NO_GDB} and skip("Skipping due to VERILATOR_TEST_NO_GDB"); + +lint( + # Check we can call dump() on graph, and other things + v_flags => ["--lint-only --debug --debugi-V3GraphTest 9 --debugi-V3GraphDfa 9"], + ); + +ok(1); +1; diff --git a/test_regress/t/t_debug_graph_test.v b/test_regress/t/t_debug_graph_test.v new file mode 100644 index 000000000..ff9763b1b --- /dev/null +++ b/test_regress/t/t_debug_graph_test.v @@ -0,0 +1,9 @@ +// DESCRIPTION: Verilator: Dotted reference that uses another dotted reference +// as the select expression +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2015 by Todd Strader. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/); +endmodule diff --git a/test_regress/t/t_debug_sigsegv_bad.pl b/test_regress/t/t_debug_sigsegv_bad.pl index cd6886e34..07e71bd60 100755 --- a/test_regress/t/t_debug_sigsegv_bad.pl +++ b/test_regress/t/t_debug_sigsegv_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -11,7 +11,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(vlt => 1); $ENV{VERILATOR_TEST_NO_GDB} and skip("Skipping due to VERILATOR_TEST_NO_GDB"); -compile( +lint( v_flags => ["--debug-sigsegv"], fails => 1, expect => diff --git a/test_regress/t/t_debug_sigsegv_bt_bad.pl b/test_regress/t/t_debug_sigsegv_bt_bad.pl index 65557c355..1b1ca012c 100755 --- a/test_regress/t/t_debug_sigsegv_bt_bad.pl +++ b/test_regress/t/t_debug_sigsegv_bt_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dedupe_clk_gate.pl b/test_regress/t/t_dedupe_clk_gate.pl index ecacecec3..229d1186d 100755 --- a/test_regress/t/t_dedupe_clk_gate.pl +++ b/test_regress/t/t_dedupe_clk_gate.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dedupe_seq_logic.pl b/test_regress/t/t_dedupe_seq_logic.pl index 0601df48c..e6f7ecd72 100755 --- a/test_regress/t/t_dedupe_seq_logic.pl +++ b/test_regress/t/t_dedupe_seq_logic.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_delay.pl b/test_regress/t/t_delay.pl index 6111d84c6..cf79784fb 100755 --- a/test_regress/t/t_delay.pl +++ b/test_regress/t/t_delay.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_delay_func_bad.out b/test_regress/t/t_delay_func_bad.out new file mode 100644 index 000000000..dd63449c5 --- /dev/null +++ b/test_regress/t/t_delay_func_bad.out @@ -0,0 +1,9 @@ +%Error: t/t_delay_func_bad.v:10:8: Delays are not legal in functions. Suggest use a task (IEEE 1800-2017 13.4.4) + : ... In instance t + 10 | #1 $stop; + | ^ +%Error: t/t_delay_func_bad.v:23:8: Delays are not legal in final blocks (IEEE 1800-2017 9.2.3) + : ... In instance t + 23 | #1; + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_delay_func_bad.pl b/test_regress/t/t_delay_func_bad.pl new file mode 100755 index 000000000..27159da5b --- /dev/null +++ b/test_regress/t/t_delay_func_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 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 + +scenarios(linter => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_delay_func_bad.v b/test_regress/t/t_delay_func_bad.v new file mode 100644 index 000000000..aa7ceddfc --- /dev/null +++ b/test_regress/t/t_delay_func_bad.v @@ -0,0 +1,27 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/); + + function int f; + #1 $stop; + f = 0; + endfunction + + int i; + + initial begin + i = f(); + $write("*-* All Finished *-*\n"); + $finish; + end + + final begin + #1; + $stop; + end + +endmodule diff --git a/test_regress/t/t_delay_stmtdly_bad.pl b/test_regress/t/t_delay_stmtdly_bad.pl index 1d17ceca2..85ea0432b 100755 --- a/test_regress/t/t_delay_stmtdly_bad.pl +++ b/test_regress/t/t_delay_stmtdly_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,11 +8,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(vlt_all => 1); +scenarios(vlt => 1); top_filename("t/t_delay.v"); -compile( +lint( verilator_flags2 => ['-Wall -Wno-DECLFILENAME'], fails => 1, expect_filename => $Self->{golden_filename}, diff --git a/test_regress/t/t_detectarray_1.pl b/test_regress/t/t_detectarray_1.pl index 178edc13d..82fae48f0 100755 --- a/test_regress/t/t_detectarray_1.pl +++ b/test_regress/t/t_detectarray_1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_detectarray_2.pl b/test_regress/t/t_detectarray_2.pl index 178edc13d..82fae48f0 100755 --- a/test_regress/t/t_detectarray_2.pl +++ b/test_regress/t/t_detectarray_2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_detectarray_3.pl b/test_regress/t/t_detectarray_3.pl index dbb7b20c5..4294291d7 100755 --- a/test_regress/t/t_detectarray_3.pl +++ b/test_regress/t/t_detectarray_3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display.out b/test_regress/t/t_display.out index 7102f4108..3825f5ad7 100644 --- a/test_regress/t/t_display.out +++ b/test_regress/t/t_display.out @@ -51,8 +51,8 @@ b: 000001100 000001100 hello, from a concatenated string. hello, from a concatenated format string [0]. extra argument: 0 - 0: pre argument -[0] Embedded <#013> return + 0 : pre argument after +[0] Embedded tab ' ' and <#013> return [0] Embedded multiline '23 23 23' diff --git a/test_regress/t/t_display.pl b/test_regress/t/t_display.pl index 2934909ea..88b7809fc 100755 --- a/test_regress/t/t_display.pl +++ b/test_regress/t/t_display.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display.v b/test_regress/t/t_display.v index cfdeea257..c13999c87 100644 --- a/test_regress/t/t_display.v +++ b/test_regress/t/t_display.v @@ -144,8 +144,8 @@ module t; $display("hel", "lo, fr", "om a concatenated string."); $write("hel", "lo, fr", "om a concatenated format string [%0t].\n", $time); $display("extra argument: ", $time); - $display($time, ": pre argument"); - $write("[%0t] Embedded \r return\n", $time); + $display($time,, ": pre argument",, "after"); + $write("[%0t] Embedded tab '\t' and \r return\n", $time); $display("[%0t] Embedded\ multiline", $time); diff --git a/test_regress/t/t_display_bad.pl b/test_regress/t/t_display_bad.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_display_bad.pl +++ b/test_regress/t/t_display_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display_esc_bad.pl b/test_regress/t/t_display_esc_bad.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_display_esc_bad.pl +++ b/test_regress/t/t_display_esc_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display_l.pl b/test_regress/t/t_display_l.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_display_l.pl +++ b/test_regress/t/t_display_l.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display_mcd.pl b/test_regress/t/t_display_mcd.pl index 2934909ea..88b7809fc 100755 --- a/test_regress/t/t_display_mcd.pl +++ b/test_regress/t/t_display_mcd.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display_merge.pl b/test_regress/t/t_display_merge.pl index 940d1ea85..67b3d10f3 100755 --- a/test_regress/t/t_display_merge.pl +++ b/test_regress/t/t_display_merge.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display_noopt.pl b/test_regress/t/t_display_noopt.pl index 836ade5ab..795598e65 100755 --- a/test_regress/t/t_display_noopt.pl +++ b/test_regress/t/t_display_noopt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display_real.pl b/test_regress/t/t_display_real.pl index b4e259e0a..1576259ea 100755 --- a/test_regress/t/t_display_real.pl +++ b/test_regress/t/t_display_real.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display_real_noopt.pl b/test_regress/t/t_display_real_noopt.pl index 10a283c91..04d0a8222 100755 --- a/test_regress/t/t_display_real_noopt.pl +++ b/test_regress/t/t_display_real_noopt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display_realtime.pl b/test_regress/t/t_display_realtime.pl index d2d6934bc..4e42b8db0 100755 --- a/test_regress/t/t_display_realtime.pl +++ b/test_regress/t/t_display_realtime.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display_signed.pl b/test_regress/t/t_display_signed.pl index b4e259e0a..1576259ea 100755 --- a/test_regress/t/t_display_signed.pl +++ b/test_regress/t/t_display_signed.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display_signed_noopt.pl b/test_regress/t/t_display_signed_noopt.pl index ebbb3d572..669394f5f 100755 --- a/test_regress/t/t_display_signed_noopt.pl +++ b/test_regress/t/t_display_signed_noopt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display_string.pl b/test_regress/t/t_display_string.pl index ec985d291..56cc415df 100755 --- a/test_regress/t/t_display_string.pl +++ b/test_regress/t/t_display_string.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display_time.pl b/test_regress/t/t_display_time.pl index b4e259e0a..1576259ea 100755 --- a/test_regress/t/t_display_time.pl +++ b/test_regress/t/t_display_time.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_display_wide.pl b/test_regress/t/t_display_wide.pl index b4e259e0a..1576259ea 100755 --- a/test_regress/t/t_display_wide.pl +++ b/test_regress/t/t_display_wide.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dist_cinclude.pl b/test_regress/t/t_dist_cinclude.pl index a7737fc12..873380dce 100755 --- a/test_regress/t/t_dist_cinclude.pl +++ b/test_regress/t/t_dist_cinclude.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dist_contributors.pl b/test_regress/t/t_dist_contributors.pl index 5f5338991..7f2764f91 100755 --- a/test_regress/t/t_dist_contributors.pl +++ b/test_regress/t/t_dist_contributors.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dist_error_format.pl b/test_regress/t/t_dist_error_format.pl index ce5b544ec..546883f47 100755 --- a/test_regress/t/t_dist_error_format.pl +++ b/test_regress/t/t_dist_error_format.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dist_fixme.pl b/test_regress/t/t_dist_fixme.pl index 1f72d5ce5..cbceb52c9 100755 --- a/test_regress/t/t_dist_fixme.pl +++ b/test_regress/t/t_dist_fixme.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dist_inctree.pl b/test_regress/t/t_dist_inctree.pl index 2ecddacb1..8b579db84 100755 --- a/test_regress/t/t_dist_inctree.pl +++ b/test_regress/t/t_dist_inctree.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dist_install.pl b/test_regress/t/t_dist_install.pl index e2409251a..67c6d5b2a 100755 --- a/test_regress/t/t_dist_install.pl +++ b/test_regress/t/t_dist_install.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -25,7 +25,7 @@ if (!-r "$root/.git") { check_finished => 0); # Install into temp area print "Install...\n"; - run(cmd => ["cd $root && make DESTDIR=$destdir install-all"], + run(cmd => ["cd $root && $ENV{MAKE} DESTDIR=$destdir install-all"], check_finished => 0); # Check we can run a test @@ -35,7 +35,7 @@ if (!-r "$root/.git") { # Uninstall print "Uninstall...\n"; - run(cmd => ["cd $root && make DESTDIR=$destdir uninstall"], + run(cmd => ["cd $root && $ENV{MAKE} DESTDIR=$destdir uninstall"], check_finished => 0); # Check empty diff --git a/test_regress/t/t_dist_manifest.pl b/test_regress/t/t_dist_manifest.pl index ddb42a925..dcd6ef8f3 100755 --- a/test_regress/t/t_dist_manifest.pl +++ b/test_regress/t/t_dist_manifest.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -83,8 +83,8 @@ ok(1); sub get_manifest_files { my $root = shift; - `cd $root && make dist-file-list`; - my $manifest_files = `cd $root && make dist-file-list`; + `cd $root && $ENV{MAKE} dist-file-list`; + my $manifest_files = `cd $root && $ENV{MAKE} dist-file-list`; $manifest_files =~ s!.*begin-dist-file-list:!!sg; $manifest_files =~ s!end-dist-file-list:.*$!!sg; print "MF $manifest_files\n" if $Self->{verbose}; diff --git a/test_regress/t/t_dist_portability.pl b/test_regress/t/t_dist_portability.pl index d905f2ab5..5b6a8e037 100755 --- a/test_regress/t/t_dist_portability.pl +++ b/test_regress/t/t_dist_portability.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dist_tabs.pl b/test_regress/t/t_dist_tabs.pl index 869f0e8f6..a7279d2b0 100755 --- a/test_regress/t/t_dist_tabs.pl +++ b/test_regress/t/t_dist_tabs.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -12,7 +12,7 @@ scenarios(dist => 1); my $root = ".."; -my $Tabs_Exempt_Re = qr!(\.out$)|(/gtkwave)|(Makefile)|(\.mk$)!; +my $Tabs_Exempt_Re = qr!(\.out$)|(/gtkwave)|(Makefile)|(\.mk$)|(nodist/fastcov.py)!; if (!-r "$root/.git") { skip("Not in a git repository"); @@ -68,7 +68,7 @@ if (!-r "$root/.git") { } my $len = length($1); if ($len >= 100 - && $file !~ /\.out$/) { + && $file !~ $Tabs_Exempt_Re) { print" Wide $line\n" if $Self->{verbose}; $summary = "File modification adds a new >100 column line:" if !$summary; $warns{$file} = "File modification adds a new >100 column line: $file:$lineno"; diff --git a/test_regress/t/t_dist_untracked.pl b/test_regress/t/t_dist_untracked.pl index b711c5e5b..9f25d1622 100755 --- a/test_regress/t/t_dist_untracked.pl +++ b/test_regress/t/t_dist_untracked.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dist_whitespace.pl b/test_regress/t/t_dist_whitespace.pl index afd5174e1..36e515a27 100755 --- a/test_regress/t/t_dist_whitespace.pl +++ b/test_regress/t/t_dist_whitespace.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -80,8 +80,8 @@ ok(1); sub get_manifest_files { my $root = shift; - `cd $root && make dist-file-list`; - my $manifest_files = `cd $root && make dist-file-list`; + `cd $root && $ENV{MAKE} dist-file-list`; + my $manifest_files = `cd $root && $ENV{MAKE} dist-file-list`; $manifest_files =~ s!.*begin-dist-file-list:!!sg; $manifest_files =~ s!end-dist-file-list:.*$!!sg; print "MF $manifest_files\n" if $Self->{verbose}; diff --git a/test_regress/t/t_dos.pl b/test_regress/t/t_dos.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_dos.pl +++ b/test_regress/t/t_dos.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_2exp_bad.pl b/test_regress/t/t_dpi_2exp_bad.pl index 056b9974f..59ba0d6c6 100755 --- a/test_regress/t/t_dpi_2exp_bad.pl +++ b/test_regress/t/t_dpi_2exp_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_accessors.pl b/test_regress/t/t_dpi_accessors.pl index 91ee59ecb..c48a8a2ba 100755 --- a/test_regress/t/t_dpi_accessors.pl +++ b/test_regress/t/t_dpi_accessors.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_arg_inout_type.pl b/test_regress/t/t_dpi_arg_inout_type.pl index dadb11a8e..68d9c487c 100755 --- a/test_regress/t/t_dpi_arg_inout_type.pl +++ b/test_regress/t/t_dpi_arg_inout_type.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_arg_input_type.pl b/test_regress/t/t_dpi_arg_input_type.pl index 7b2d8aa9a..16fc1abc3 100755 --- a/test_regress/t/t_dpi_arg_input_type.pl +++ b/test_regress/t/t_dpi_arg_input_type.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_arg_output_type.pl b/test_regress/t/t_dpi_arg_output_type.pl index 74588e732..b611513a8 100755 --- a/test_regress/t/t_dpi_arg_output_type.pl +++ b/test_regress/t/t_dpi_arg_output_type.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_context.pl b/test_regress/t/t_dpi_context.pl index 2113d8cb2..c0096e960 100755 --- a/test_regress/t/t_dpi_context.pl +++ b/test_regress/t/t_dpi_context.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_context_noopt.pl b/test_regress/t/t_dpi_context_noopt.pl index 54b35dbf7..cff6b4ed4 100755 --- a/test_regress/t/t_dpi_context_noopt.pl +++ b/test_regress/t/t_dpi_context_noopt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_display.pl b/test_regress/t/t_dpi_display.pl index 101403671..5babe0a06 100755 --- a/test_regress/t/t_dpi_display.pl +++ b/test_regress/t/t_dpi_display.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_dup_bad.pl b/test_regress/t/t_dpi_dup_bad.pl index 056b9974f..59ba0d6c6 100755 --- a/test_regress/t/t_dpi_dup_bad.pl +++ b/test_regress/t/t_dpi_dup_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_export.pl b/test_regress/t/t_dpi_export.pl index 927a685e9..57bdaf055 100755 --- a/test_regress/t/t_dpi_export.pl +++ b/test_regress/t/t_dpi_export.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_export_bad.out b/test_regress/t/t_dpi_export_bad.out new file mode 100644 index 000000000..36f9b09d2 --- /dev/null +++ b/test_regress/t/t_dpi_export_bad.out @@ -0,0 +1,4 @@ +%Error: t/t_dpi_export_bad.v:10:24: Can't find definition of exported task/function: 'dpix_bad_missing' + 10 | export "DPI-C" task dpix_bad_missing; + | ^~~~~~~~~~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_dpi_export_bad.pl b/test_regress/t/t_dpi_export_bad.pl new file mode 100755 index 000000000..a5846c699 --- /dev/null +++ b/test_regress/t/t_dpi_export_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(vlt => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_dpi_export_bad.v b/test_regress/t/t_dpi_export_bad.v new file mode 100644 index 000000000..33a25fe95 --- /dev/null +++ b/test_regress/t/t_dpi_export_bad.v @@ -0,0 +1,11 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2009 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 + +module t; + export "DPI-C" task dpix_bad_missing; +endmodule diff --git a/test_regress/t/t_dpi_export_context_bad.pl b/test_regress/t/t_dpi_export_context_bad.pl index af0dcdbd9..3bf347339 100755 --- a/test_regress/t/t_dpi_export_context_bad.pl +++ b/test_regress/t/t_dpi_export_context_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_export_noopt.pl b/test_regress/t/t_dpi_export_noopt.pl index 1a4e6297e..4ad49a952 100755 --- a/test_regress/t/t_dpi_export_noopt.pl +++ b/test_regress/t/t_dpi_export_noopt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_imp_gen.pl b/test_regress/t/t_dpi_imp_gen.pl index fc14166a9..fd2d1a9f3 100755 --- a/test_regress/t/t_dpi_imp_gen.pl +++ b/test_regress/t/t_dpi_imp_gen.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_import.pl b/test_regress/t/t_dpi_import.pl index c1f710bda..ecb8a264f 100755 --- a/test_regress/t/t_dpi_import.pl +++ b/test_regress/t/t_dpi_import.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_import_hdr_only.pl b/test_regress/t/t_dpi_import_hdr_only.pl index dd4b84fde..92c6227ed 100755 --- a/test_regress/t/t_dpi_import_hdr_only.pl +++ b/test_regress/t/t_dpi_import_hdr_only.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_lib.pl b/test_regress/t/t_dpi_lib.pl index e31f5e846..896a5502c 100755 --- a/test_regress/t/t_dpi_lib.pl +++ b/test_regress/t/t_dpi_lib.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_name_bad.pl b/test_regress/t/t_dpi_name_bad.pl index 056b9974f..59ba0d6c6 100755 --- a/test_regress/t/t_dpi_name_bad.pl +++ b/test_regress/t/t_dpi_name_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_open.pl b/test_regress/t/t_dpi_open.pl index 38e58ef3c..099d9a2e7 100755 --- a/test_regress/t/t_dpi_open.pl +++ b/test_regress/t/t_dpi_open.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_open_query.cpp b/test_regress/t/t_dpi_open_query.cpp new file mode 100644 index 000000000..21f7eab1c --- /dev/null +++ b/test_regress/t/t_dpi_open_query.cpp @@ -0,0 +1,72 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2020 by Geza Lore. 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 +// +//************************************************************************* + +// clang-format off + +#include "svdpi.h" + +#if defined(VERILATOR) // Verilator +# include "Vt_dpi_open_query__Dpi.h" +#elif defined(VCS) // VCS +# include "../vc_hdrs.h" +#elif defined(NCSC) // NC +# include "dpi-imp.h" +#elif defined(MS) // ModelSim +# include "dpi.h" +#else +# error "Unknown simulator for DPI test" +#endif + +// clang-format on + +//====================================================================== +// Implementations of imported functions +//====================================================================== + +// These are simple wrappers for the array querying functions themselves, +// see IEEE 1800-2017 H.12.2. Sadly on the SV side these have different +// signagures, and hence need to have different names here as well. + +// 1 open dimension +int cSvLeft1(const svOpenArrayHandle h, int d) { return svLeft(h, d); } +int cSvRight1(const svOpenArrayHandle h, int d) { return svRight(h, d); } +int cSvLow1(const svOpenArrayHandle h, int d) { return svLow(h, d); } +int cSvHigh1(const svOpenArrayHandle h, int d) { return svHigh(h, d); } +int cSvIncrement1(const svOpenArrayHandle h, int d) { return svIncrement(h, d); } +int cSvSize1(const svOpenArrayHandle h, int d) { return svSize(h, d); } +int cSvDimensions1(const svOpenArrayHandle h) { return svDimensions(h); } + +// 2 open dimensions +int cSvLeft2(const svOpenArrayHandle h, int d) { return svLeft(h, d); } +int cSvRight2(const svOpenArrayHandle h, int d) { return svRight(h, d); } +int cSvLow2(const svOpenArrayHandle h, int d) { return svLow(h, d); } +int cSvHigh2(const svOpenArrayHandle h, int d) { return svHigh(h, d); } +int cSvIncrement2(const svOpenArrayHandle h, int d) { return svIncrement(h, d); } +int cSvSize2(const svOpenArrayHandle h, int d) { return svSize(h, d); } +int cSvDimensions2(const svOpenArrayHandle h) { return svDimensions(h); } + +// 3 open dimensions +int cSvLeft3(const svOpenArrayHandle h, int d) { return svLeft(h, d); } +int cSvRight3(const svOpenArrayHandle h, int d) { return svRight(h, d); } +int cSvLow3(const svOpenArrayHandle h, int d) { return svLow(h, d); } +int cSvHigh3(const svOpenArrayHandle h, int d) { return svHigh(h, d); } +int cSvIncrement3(const svOpenArrayHandle h, int d) { return svIncrement(h, d); } +int cSvSize3(const svOpenArrayHandle h, int d) { return svSize(h, d); } +int cSvDimensions3(const svOpenArrayHandle h) { return svDimensions(h); } + +// 4 open dimensions +int cSvLeft4(const svOpenArrayHandle h, int d) { return svLeft(h, d); } +int cSvRight4(const svOpenArrayHandle h, int d) { return svRight(h, d); } +int cSvLow4(const svOpenArrayHandle h, int d) { return svLow(h, d); } +int cSvHigh4(const svOpenArrayHandle h, int d) { return svHigh(h, d); } +int cSvIncrement4(const svOpenArrayHandle h, int d) { return svIncrement(h, d); } +int cSvSize4(const svOpenArrayHandle h, int d) { return svSize(h, d); } +int cSvDimensions4(const svOpenArrayHandle h) { return svDimensions(h); } diff --git a/test_regress/t/t_dpi_open_query.pl b/test_regress/t/t_dpi_open_query.pl new file mode 100755 index 000000000..8a94dbf67 --- /dev/null +++ b/test_regress/t/t_dpi_open_query.pl @@ -0,0 +1,36 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Geza Lore. 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 + +scenarios(simulator => 1); + +if ($Self->{nc}) { + # For NC, compile twice, first just to generate DPI headers + compile( + nc_flags2 => ["+ncdpiimpheader+$Self->{obj_dir}/dpi-imp.h"] + ); +} + +compile( + v_flags2 => ["t/t_dpi_open_query.cpp"], + verilator_flags2 => ["-Wall -Wno-DECLFILENAME"], + # NC: Gdd the obj_dir to the C include path + nc_flags2 => ["+ncscargs+-I$Self->{obj_dir}"], + # ModelSim: Generate DPI header, add obj_dir to the C include path + ms_flags2 => ["-dpiheader $Self->{obj_dir}/dpi.h", + "-ccflags -I$Self->{obj_dir}"], + ); + +execute( + check_finished => 1, + ms_pli => 0 + ); + +ok(1); +1; diff --git a/test_regress/t/t_dpi_open_query.v b/test_regress/t/t_dpi_open_query.v new file mode 100644 index 000000000..9da5579f2 --- /dev/null +++ b/test_regress/t/t_dpi_open_query.v @@ -0,0 +1,314 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2020 by Geza Lore. 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 + +`define check(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 unless(cond,gotv,expv) do if (!(cond)) `check(gotv, expv); while(0) + +`ifdef VERILATOR + `define NO_DYNAMIC + `define NO_QUEUE +`endif + +`ifdef VCS + `define NO_QUEUE +`endif + +`ifdef NC + `define NO_DYNAMIC + `define NO_QUEUE +`endif + +`ifdef NC + `define ONNC 1 +`else + `define ONNC 0 +`endif + +`ifdef MS + `define ONMS 1 +`else + `define ONMS 0 +`endif + +module t; + + // 1 open dimension + import "DPI-C" function int cSvLeft1( input bit h [], int d); + import "DPI-C" function int cSvRight1( input bit h [], int d); + import "DPI-C" function int cSvLow1( input bit h [], int d); + import "DPI-C" function int cSvHigh1( input bit h [], int d); + import "DPI-C" function int cSvIncrement1( input bit h [], int d); + import "DPI-C" function int cSvSize1( input bit h [], int d); + import "DPI-C" function int cSvDimensions1( input bit h []); + + // 2 open dimensions + import "DPI-C" function int cSvLeft2( input bit h [][], int d); + import "DPI-C" function int cSvRight2( input bit h [][], int d); + import "DPI-C" function int cSvLow2( input bit h [][], int d); + import "DPI-C" function int cSvHigh2( input bit h [][], int d); + import "DPI-C" function int cSvIncrement2( input bit h [][], int d); + import "DPI-C" function int cSvSize2( input bit h [][], int d); + import "DPI-C" function int cSvDimensions2( input bit h [][]); + + // 3 open dimensions + import "DPI-C" function int cSvLeft3( input bit h [][][], int d); + import "DPI-C" function int cSvRight3( input bit h [][][], int d); + import "DPI-C" function int cSvLow3( input bit h [][][], int d); + import "DPI-C" function int cSvHigh3( input bit h [][][], int d); + import "DPI-C" function int cSvIncrement3( input bit h [][][], int d); + import "DPI-C" function int cSvSize3( input bit h [][][], int d); + import "DPI-C" function int cSvDimensions3( input bit h [][][]); + + // 4 open dimensions + import "DPI-C" function int cSvLeft4( input bit h [][][][], int d); + import "DPI-C" function int cSvRight4( input bit h [][][][], int d); + import "DPI-C" function int cSvLow4( input bit h [][][][], int d); + import "DPI-C" function int cSvHigh4( input bit h [][][][], int d); + import "DPI-C" function int cSvIncrement4( input bit h [][][][], int d); + import "DPI-C" function int cSvSize4( input bit h [][][][], int d); + import "DPI-C" function int cSvDimensions4( input bit h [][][][]); + + // verilator lint_off UNDRIVEN + bit a1 [1:0]; + bit a2 [1:0][2:0]; + bit a3 [1:0][2:0][3:0]; + bit a4 [1:0][2:0][3:0][4:0]; + + bit b1 [0:1]; + bit b2 [0:1][0:2]; + bit b3 [0:1][0:2][0:3]; + bit b4 [0:1][0:2][0:3][0:4]; + + bit c1 [-1:1]; + bit c2 [-1:1][-2:2]; + bit c3 [-1:1][-2:2][-3:3]; + bit c4 [-1:1][-2:2][-3:3][-4:4]; + +`ifndef NO_DYNAMIC + bit d1 []; + bit d2 [][-2:2]; + bit d3 [][-2:2][-3:3]; + bit d4 [][-2:2][-3:3][-4:4]; +`endif + +`ifndef NO_QUEUE + bit e1 [$]; +`endif + // verilator lint_on UNDRIVEN + + initial begin +`ifndef NO_DYNAMIC + d1 = new[3]; + d2 = new[3]; + d3 = new[3]; + d4 = new[3]; +`endif + +`ifndef NO_QUEUE + e1.push_back(0); + e1.push_back(0); + e1.push_back(0); +`endif + + // 1 open dimension + `check(cSvDimensions1(a1), 1); + `check(cSvDimensions1(b1), 1); + `check(cSvDimensions1(c1), 1); +`ifndef NO_DYNAMIC + `check(cSvDimensions1(d1), 1); +`endif +`ifndef NO_QUEUE + `check(cSvDimensions1(e1), 1); +`endif + for (int d = 0 ; d < 2 ; d++) begin + if (`ONNC && d == 0) continue; + + `check(cSvLeft1(a1, d), d); + `check(cSvRight1(a1, d), 0); + `check(cSvLow1(a1, d), 0); + `check(cSvHigh1(a1, d), d); + `unless(`ONMS && d == 0, cSvIncrement1(a1, d), 1); + `check(cSvSize1(a1, d), d+1); + + `check(cSvLeft1(b1, d), 0); + `check(cSvRight1(b1, d), d); + `check(cSvLow1(b1, d), 0); + `check(cSvHigh1(b1, d), d); +`ifndef NC + `unless(`ONMS && d == 0, cSvIncrement1(b1, d), d == 0 ? 1 : -1); +`endif + `check(cSvSize1(b1, d), d+1); + + `check(cSvLeft1(c1, d), -d); + `check(cSvRight1(c1, d), d); + `check(cSvLow1(c1, d), -d); + `check(cSvHigh1(c1, d), d); +`ifndef NC + `unless(`ONMS && d == 0, cSvIncrement1(c1, d), d == 0 ? 1 : -1); +`endif + `check(cSvSize1(c1, d), 2*d+1); + +`ifndef NO_DYNAMIC + `check(cSvLeft1(d1, d), d == 1 ? 0 : -d); + `check(cSvRight1(d1, d), d == 1 ? 2 : d); + `check(cSvLow1(d1, d), d == 1 ? 0 : -d); + `check(cSvHigh1(d1, d), d == 1 ? 2 : d); + `unless(`ONMS && d == 0, cSvIncrement1(d1, d), d == 0 ? 1 : -1); + `check(cSvSize1(d1, d), 2*d+1); +`endif + +`ifndef NO_QUEUE + `check(cSvLeft1(e1, d), d == 1 ? 0 : -d); + `check(cSvRight1(e1, d), d == 1 ? 2 : d); + `check(cSvLow1(e1, d), d == 1 ? 0 : -d); + `check(cSvHigh1(e1, d), d == 1 ? 2 : d); + `unless(`ONMS && d == 0, cSvIncrement1(e1, d), d == 0 ? 1 : -1); + `check(cSvSize1(e1, d), 2*d+1); +`endif + end + + // 2 open dimensions + `check(cSvDimensions2(a2), 2); + `check(cSvDimensions2(b2), 2); + `check(cSvDimensions2(c2), 2); +`ifndef NO_DYNAMIC + `check(cSvDimensions2(d2), 2); +`endif + for (int d = 0 ; d < 3 ; d++) begin + if (`ONNC && d == 0) continue; + + `check(cSvLeft2(a2, d), d); + `check(cSvRight2(a2, d), 0); + `check(cSvLow2(a2, d), 0); + `check(cSvHigh2(a2, d), d); + `unless(`ONMS && d == 0, cSvIncrement2(a2, d), 1); + `check(cSvSize2(a2, d), d+1); + + `check(cSvLeft2(b2, d), 0); + `check(cSvRight2(b2, d), d); + `check(cSvLow2(b2, d), 0); + `check(cSvHigh2(b2, d), d); +`ifndef NC + `unless(`ONMS && d == 0, cSvIncrement2(b2, d), d == 0 ? 1 : -1); +`endif + `check(cSvSize2(b2, d), d+1); + + `check(cSvLeft2(c2, d), -d); + `check(cSvRight2(c2, d), d); + `check(cSvLow2(c2, d), -d); + `check(cSvHigh2(c2, d), d); +`ifndef NC + `unless(`ONMS && d == 0, cSvIncrement2(c2, d), d == 0 ? 1 : -1); +`endif + `check(cSvSize2(c2, d), 2*d+1); + +`ifndef NO_DYNAMIC + `check(cSvLeft2(d2, d), d == 1 ? 0 : -d); + `check(cSvRight2(d2, d), d == 1 ? 2 : d); + `check(cSvLow2(d2, d), d == 1 ? 0 : -d); + `check(cSvHigh2(d2, d), d == 1 ? 2 : d); + `unless(`ONMS && d == 0, cSvIncrement2(d2, d), d == 0 ? 1 : -1); + `check(cSvSize2(d2, d), 2*d+1); +`endif + end + + // 3 open dimensions + `check(cSvDimensions3(a3), 3); + `check(cSvDimensions3(b3), 3); + `check(cSvDimensions3(c3), 3); +`ifndef NO_DYNAMIC + `check(cSvDimensions3(d3), 3); +`endif + for (int d = 0 ; d < 4 ; d++) begin + if (`ONNC && d == 0) continue; + + `check(cSvLeft3(a3, d), d); + `check(cSvRight3(a3, d), 0); + `check(cSvLow3(a3, d), 0); + `check(cSvHigh3(a3, d), d); + `unless(`ONMS && d == 0, cSvIncrement3(a3, d), 1); + `check(cSvSize3(a3, d), d+1); + + `check(cSvLeft3(b3, d), 0); + `check(cSvRight3(b3, d), d); + `check(cSvLow3(b3, d), 0); + `check(cSvHigh3(b3, d), d); +`ifndef NC + `unless(`ONMS && d == 0, cSvIncrement3(b3, d), d == 0 ? 1 : -1); +`endif + `check(cSvSize3(b3, d), d+1); + + `check(cSvLeft3(c3, d), -d); + `check(cSvRight3(c3, d), d); + `check(cSvLow3(c3, d), -d); + `check(cSvHigh3(c3, d), d); +`ifndef NC + `unless(`ONMS && d == 0, cSvIncrement3(c3, d), d == 0 ? 1 : -1); +`endif + `check(cSvSize3(c3, d), 2*d+1); + +`ifndef NO_DYNAMIC + `check(cSvLeft3(d3, d), d == 1 ? 0 : -d); + `check(cSvRight3(d3, d), d == 1 ? 2 : d); + `check(cSvLow3(d3, d), d == 1 ? 0 : -d); + `check(cSvHigh3(d3, d), d == 1 ? 2 : d); + `unless(`ONMS && d == 0, cSvIncrement3(d3, d), d == 0 ? 1 : -1); + `check(cSvSize3(d3, d), 2*d+1); +`endif + end + + // 4 open dimension + `check(cSvDimensions4(a4), 4); + `check(cSvDimensions4(b4), 4); + `check(cSvDimensions4(c4), 4); +`ifndef NO_DYNAMIC + `check(cSvDimensions4(d4), 4); +`endif + for (int d = 0 ; d < 5 ; d++) begin + if (`ONNC && d == 0) continue; + + `check(cSvLeft4(a4, d), d); + `check(cSvRight4(a4, d), 0); + `check(cSvLow4(a4, d), 0); + `check(cSvHigh4(a4, d), d); + `unless(`ONMS && d == 0, cSvIncrement4(a4, d), 1); + `check(cSvSize4(a4, d), d+1); + + `check(cSvLeft4(b4, d), 0); + `check(cSvRight4(b4, d), d); + `check(cSvLow4(b4, d), 0); + `check(cSvHigh4(b4, d), d); +`ifndef NC + `unless(`ONMS && d == 0, cSvIncrement4(b4, d), d == 0 ? 1 : -1); +`endif + `check(cSvSize4(b4, d), d+1); + + `check(cSvLeft4(c4, d), -d); + `check(cSvRight4(c4, d), d); + `check(cSvLow4(c4, d), -d); + `check(cSvHigh4(c4, d), d); +`ifndef NC + `unless(`ONMS && d == 0, cSvIncrement4(c4, d), d == 0 ? 1 : -1); +`endif + `check(cSvSize4(c4, d), 2*d+1); + +`ifndef NO_DYNAMIC + `check(cSvLeft4(d4, d), d == 1 ? 0 : -d); + `check(cSvRight4(d4, d), d == 1 ? 2 : d); + `check(cSvLow4(d4, d), d == 1 ? 0 : -d); + `check(cSvHigh4(d4, d), d == 1 ? 2 : d); + `unless(`ONMS && d == 0, cSvIncrement4(d4, d), d == 0 ? 1 : -1); + `check(cSvSize4(d4, d), 2*d+1); +`endif + end + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_dpi_openfirst.pl b/test_regress/t/t_dpi_openfirst.pl index e2e88b0b3..c8f69c0fe 100755 --- a/test_regress/t/t_dpi_openfirst.pl +++ b/test_regress/t/t_dpi_openfirst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_qw.pl b/test_regress/t/t_dpi_qw.pl index bb25c3c8c..74e3bae58 100755 --- a/test_regress/t/t_dpi_qw.pl +++ b/test_regress/t/t_dpi_qw.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_result_type.pl b/test_regress/t/t_dpi_result_type.pl index b876371e8..76761b85a 100755 --- a/test_regress/t/t_dpi_result_type.pl +++ b/test_regress/t/t_dpi_result_type.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_result_type_bad.pl b/test_regress/t/t_dpi_result_type_bad.pl index 9979ce572..4d9f82122 100755 --- a/test_regress/t/t_dpi_result_type_bad.pl +++ b/test_regress/t/t_dpi_result_type_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_shortcircuit.pl b/test_regress/t/t_dpi_shortcircuit.pl index 1e00f07ea..d0b657ca1 100755 --- a/test_regress/t/t_dpi_shortcircuit.pl +++ b/test_regress/t/t_dpi_shortcircuit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_shortcircuit2.pl b/test_regress/t/t_dpi_shortcircuit2.pl index 1c4266501..e53f3f9eb 100755 --- a/test_regress/t/t_dpi_shortcircuit2.pl +++ b/test_regress/t/t_dpi_shortcircuit2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_string.pl b/test_regress/t/t_dpi_string.pl index d24f298c7..f694b5065 100755 --- a/test_regress/t/t_dpi_string.pl +++ b/test_regress/t/t_dpi_string.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_sys.pl b/test_regress/t/t_dpi_sys.pl index 797a29407..d47ed0147 100755 --- a/test_regress/t/t_dpi_sys.pl +++ b/test_regress/t/t_dpi_sys.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_threads.pl b/test_regress/t/t_dpi_threads.pl index d936d07c8..9529c0495 100755 --- a/test_regress/t/t_dpi_threads.pl +++ b/test_regress/t/t_dpi_threads.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_threads_collide.pl b/test_regress/t/t_dpi_threads_collide.pl index 8e9c07e4d..dff046d94 100755 --- a/test_regress/t/t_dpi_threads_collide.pl +++ b/test_regress/t/t_dpi_threads_collide.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_vams.pl b/test_regress/t/t_dpi_vams.pl index 04b9aeb1c..68cbf7858 100755 --- a/test_regress/t/t_dpi_vams.pl +++ b/test_regress/t/t_dpi_vams.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_var.pl b/test_regress/t/t_dpi_var.pl index a9210bf25..e7f19cd2a 100755 --- a/test_regress/t/t_dpi_var.pl +++ b/test_regress/t/t_dpi_var.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dpi_var_vlt.pl b/test_regress/t/t_dpi_var_vlt.pl index bc97cc595..a9d16c3c4 100755 --- a/test_regress/t/t_dpi_var_vlt.pl +++ b/test_regress/t/t_dpi_var_vlt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_driver_random.pl b/test_regress/t/t_driver_random.pl index cf3611fb2..29eeb00a9 100755 --- a/test_regress/t/t_driver_random.pl +++ b/test_regress/t/t_driver_random.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dynarray.pl b/test_regress/t/t_dynarray.pl index e02817219..9a15dd2cc 100755 --- a/test_regress/t/t_dynarray.pl +++ b/test_regress/t/t_dynarray.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_dynarray.v b/test_regress/t/t_dynarray.v index 584707bb0..166cc48f3 100644 --- a/test_regress/t/t_dynarray.v +++ b/test_regress/t/t_dynarray.v @@ -27,6 +27,15 @@ module t (/*AUTOARG*/ byte_t a[]; byte_t b[]; + // wide data array + typedef struct packed { + logic [15:0] header; + logic [223:0] payload; + logic [15:0] checksum; + } pck256_t; + + pck256_t p256[]; + always @ (posedge clk) begin cyc <= cyc + 1; begin @@ -100,6 +109,33 @@ module t (/*AUTOARG*/ `checkh(b[1], 0); `checkh(b[2], 0); `checkh(b[4], 0); + + // test wide dynamic array + p256 = new [11]; + `checkh(p256.size, 11); + `checkh(p256.size(), 11); + + p256[1].header = 16'hcafe; + p256[1].payload = {14{16'hbabe}}; + p256[1].checksum = 16'hdead; + `checkh(p256[1].header, 16'hcafe); + `checkh(p256[1], {16'hcafe,{14{16'hbabe}},16'hdead}); + + `checkh(p256[0], '0); + + p256[5] = '1; + `checkh(p256[5], {32{8'hff}}); + + p256[5].header = 16'h2; + `checkh(p256[5], {16'h2,{30{8'hff}}}); + + p256[2] = ( p256[5].header == 2 ) ? p256[1] : p256[5]; + `checkh(p256[2], {16'hcafe,{14{16'hbabe}},16'hdead}); + + + p256.delete(); + `checkh(p256.size, 0); + end $write("*-* All Finished *-*\n"); diff --git a/test_regress/t/t_dynarray_bad.out b/test_regress/t/t_dynarray_bad.out index 7bb4e86b5..ad5729bd3 100644 --- a/test_regress/t/t_dynarray_bad.out +++ b/test_regress/t/t_dynarray_bad.out @@ -3,4 +3,6 @@ 15 | a = new [s]; | ^~~ ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message. -%Error: Internal Error: ../V3Number.cpp:#: Number operation called with non-logic (double or string) argument: '"str"" +%Error: Internal Error: t/t_dynarray_bad.v:15:16: ../V3Number.cpp:#: Number operation called with non-logic (double or string) argument: '"str"" + 15 | a = new [s]; + | ^ diff --git a/test_regress/t/t_dynarray_bad.pl b/test_regress/t/t_dynarray_bad.pl index e2ea28d29..27159da5b 100755 --- a/test_regress/t/t_dynarray_bad.pl +++ b/test_regress/t/t_dynarray_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_embed1.pl b/test_regress/t/t_embed1.pl index 87e3fbcd3..1b298a9be 100755 --- a/test_regress/t/t_embed1.pl +++ b/test_regress/t/t_embed1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -29,7 +29,7 @@ mkdir $child_dir; run(logfile => "${child_dir}/vlt_gcc.log", cmd => ["cd ${child_dir} && ", - "make", "-f".getcwd()."/Makefile_obj", + $ENV{MAKE}, "-f".getcwd()."/Makefile_obj", "CPPFLAGS_DRIVER=-D".uc($self->{name}), ($opt_verbose ? "CPPFLAGS_DRIVER2=-DTEST_VERBOSE=1":""), "VM_PREFIX=$self->{VM_PREFIX}_child", diff --git a/test_regress/t/t_emit_constw.pl b/test_regress/t/t_emit_constw.pl index ad1b43680..9b1487fcd 100755 --- a/test_regress/t/t_emit_constw.pl +++ b/test_regress/t/t_emit_constw.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_emit_memb_limit.pl b/test_regress/t/t_emit_memb_limit.pl index 9cef22356..931ba7569 100755 --- a/test_regress/t/t_emit_memb_limit.pl +++ b/test_regress/t/t_emit_memb_limit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enum.pl b/test_regress/t/t_enum.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_enum.pl +++ b/test_regress/t/t_enum.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enum_bad_hide.pl b/test_regress/t/t_enum_bad_hide.pl index b76ca20f1..f1eef1686 100755 --- a/test_regress/t/t_enum_bad_hide.pl +++ b/test_regress/t/t_enum_bad_hide.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enum_func.pl b/test_regress/t/t_enum_func.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_enum_func.pl +++ b/test_regress/t/t_enum_func.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enum_int.pl b/test_regress/t/t_enum_int.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_enum_int.pl +++ b/test_regress/t/t_enum_int.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enum_large_methods.pl b/test_regress/t/t_enum_large_methods.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_enum_large_methods.pl +++ b/test_regress/t/t_enum_large_methods.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enum_name2.pl b/test_regress/t/t_enum_name2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_enum_name2.pl +++ b/test_regress/t/t_enum_name2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enum_name3.pl b/test_regress/t/t_enum_name3.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_enum_name3.pl +++ b/test_regress/t/t_enum_name3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enum_overlap_bad.pl b/test_regress/t/t_enum_overlap_bad.pl index 8e4fecbdb..a82cf66cb 100755 --- a/test_regress/t/t_enum_overlap_bad.pl +++ b/test_regress/t/t_enum_overlap_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enum_public.pl b/test_regress/t/t_enum_public.pl index ae7a261c5..345560283 100755 --- a/test_regress/t/t_enum_public.pl +++ b/test_regress/t/t_enum_public.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enum_recurse_bad.pl b/test_regress/t/t_enum_recurse_bad.pl index b1b5983b1..53e145105 100755 --- a/test_regress/t/t_enum_recurse_bad.pl +++ b/test_regress/t/t_enum_recurse_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_enum_recurse_bad2.out b/test_regress/t/t_enum_recurse_bad2.out new file mode 100644 index 000000000..ad9d188b5 --- /dev/null +++ b/test_regress/t/t_enum_recurse_bad2.out @@ -0,0 +1,4 @@ +%Error: t/t_enum_recurse_bad2.v:7:14: Self-referential enumerated type definition + 7 | typedef enum foo_t { A = 'b0, B = 'b1 } foo_t; + | ^~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_enum_recurse_bad2.pl b/test_regress/t/t_enum_recurse_bad2.pl new file mode 100755 index 000000000..53e145105 --- /dev/null +++ b/test_regress/t/t_enum_recurse_bad2.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2004 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 + +scenarios(linter => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_enum_recurse_bad2.v b/test_regress/t/t_enum_recurse_bad2.v new file mode 100644 index 000000000..8cec4c4e0 --- /dev/null +++ b/test_regress/t/t_enum_recurse_bad2.v @@ -0,0 +1,7 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2019 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +typedef enum foo_t { A = 'b0, B = 'b1 } foo_t; diff --git a/test_regress/t/t_enum_size.pl b/test_regress/t/t_enum_size.pl index e02817219..9a15dd2cc 100755 --- a/test_regress/t/t_enum_size.pl +++ b/test_regress/t/t_enum_size.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enum_type_methods.pl b/test_regress/t/t_enum_type_methods.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_enum_type_methods.pl +++ b/test_regress/t/t_enum_type_methods.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enum_type_methods_bad.pl b/test_regress/t/t_enum_type_methods_bad.pl index f38979026..3c938d615 100755 --- a/test_regress/t/t_enum_type_methods_bad.pl +++ b/test_regress/t/t_enum_type_methods_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename} ); diff --git a/test_regress/t/t_enum_type_pins.pl b/test_regress/t/t_enum_type_pins.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_enum_type_pins.pl +++ b/test_regress/t/t_enum_type_pins.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enum_x_bad.pl b/test_regress/t/t_enum_x_bad.pl index 8e4fecbdb..a82cf66cb 100755 --- a/test_regress/t/t_enum_x_bad.pl +++ b/test_regress/t/t_enum_x_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_enumeration.pl b/test_regress/t/t_enumeration.pl index 60a0147f8..9d56f5047 100755 --- a/test_regress/t/t_enumeration.pl +++ b/test_regress/t/t_enumeration.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_event.pl b/test_regress/t/t_event.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_event.pl +++ b/test_regress/t/t_event.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_event_copy.pl b/test_regress/t/t_event_copy.pl index 052947d96..f4321c541 100755 --- a/test_regress/t/t_event_copy.pl +++ b/test_regress/t/t_event_copy.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_extend.pl b/test_regress/t/t_extend.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_extend.pl +++ b/test_regress/t/t_extend.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_extend_class.pl b/test_regress/t/t_extend_class.pl index 2dad80579..d14b969d1 100755 --- a/test_regress/t/t_extend_class.pl +++ b/test_regress/t/t_extend_class.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_f_bad.out b/test_regress/t/t_f_bad.out new file mode 100644 index 000000000..5de3d32b9 --- /dev/null +++ b/test_regress/t/t_f_bad.out @@ -0,0 +1,2 @@ +%Error: Cannot open -f command file: file_will_not_exist.vc +%Error: Exiting due to diff --git a/test_regress/t/t_f_bad.pl b/test_regress/t/t_f_bad.pl new file mode 100755 index 000000000..bebe33c0c --- /dev/null +++ b/test_regress/t/t_f_bad.pl @@ -0,0 +1,20 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2008 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 + +scenarios(vlt => 1); + +lint( + verilator_flags2 => ["--lint-only -f file_will_not_exist.vc"], + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_final.pl b/test_regress/t/t_final.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_final.pl +++ b/test_regress/t/t_final.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_final.v b/test_regress/t/t_final.v index c3d4eb588..8d29e3e38 100644 --- a/test_regress/t/t_final.v +++ b/test_regress/t/t_final.v @@ -13,6 +13,7 @@ module submodule (); final begin $write("d"); end + final ; // Empty test endmodule module t (); diff --git a/test_regress/t/t_flag_bboxsys.pl b/test_regress/t/t_flag_bboxsys.pl index c34d556d0..f3d98428b 100755 --- a/test_regress/t/t_flag_bboxsys.pl +++ b/test_regress/t/t_flag_bboxsys.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_build.pl b/test_regress/t/t_flag_build.pl index d5278d93f..7076e8443 100755 --- a/test_regress/t/t_flag_build.pl +++ b/test_regress/t/t_flag_build.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_build_bad.pl b/test_regress/t/t_flag_build_bad.pl index 8b792ff9c..a1ce4734f 100755 --- a/test_regress/t/t_flag_build_bad.pl +++ b/test_regress/t/t_flag_build_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_build_bad2.pl b/test_regress/t/t_flag_build_bad2.pl new file mode 100755 index 000000000..a28ddb9a1 --- /dev/null +++ b/test_regress/t/t_flag_build_bad2.pl @@ -0,0 +1,26 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(vlt => 1); +top_filename("t/t_flag_make_cmake.v"); + +compile( + verilator_make_cmake => 0, + verilator_make_gmake => 0, + # Need --no-print-directory so golden file doesn't compare directory names + verilator_flags2 => ["--build --MAKEFLAGS --no-print-directory" + ." --MAKEFLAGS illegal-flag-to-fail-make"], + fails => 1, + # Recursive make breaks the golden compare + #expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_context_bad.pl b/test_regress/t/t_flag_context_bad.pl index 2e4055cc0..054b31aac 100755 --- a/test_regress/t/t_flag_context_bad.pl +++ b/test_regress/t/t_flag_context_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_csplit.pl b/test_regress/t/t_flag_csplit.pl index 1a42472ea..e31f96ab9 100755 --- a/test_regress/t/t_flag_csplit.pl +++ b/test_regress/t/t_flag_csplit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -28,17 +28,17 @@ while (1) { # properly build run(logfile => "$Self->{obj_dir}/vlt_gcc.log", tee => $self->{verbose}, - cmd=>["make", + cmd=>[$ENV{MAKE}, "-C ".$Self->{obj_dir}, "-f $Self->{VM_PREFIX}.mk", "-j 4", - #"VM_PARALLEL_BUILDS=1", # Check is set by makefile "VM_PREFIX=$Self->{VM_PREFIX}", "TEST_OBJ_DIR=$Self->{obj_dir}", "CPPFLAGS_DRIVER=-D".uc($Self->{name}), ($opt_verbose ? "CPPFLAGS_DRIVER2=-DTEST_VERBOSE=1":""), "OPT_FAST=-O2", "OPT_SLOW=-O0", + "OPT_GLOBAL=-Os", ($param{make_flags}||""), ]); @@ -46,7 +46,10 @@ while (1) { check_finished => 1, ); + # Splitting should set VM_PARALLEL_BUILDS to 1 by default + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}_classes.mk", qr/VM_PARALLEL_BUILDS\s*=\s*1/); check_splits(); + check_no_all_file(); check_gcc_flags("$Self->{obj_dir}/vlt_gcc.log"); ok(1); @@ -54,15 +57,6 @@ while (1) { } 1; -sub make_version { - my $ver = `make --version`; - if ($ver =~ /make ([0-9]+\.[0-9]+)/i) { - return $1; - } else { - return -1; - } -} - sub check_splits { my $got1; my $gotSyms1; @@ -78,6 +72,14 @@ sub check_splits { $gotSyms1 or error("No Syms__1 split file found"); } +sub check_no_all_file { + foreach my $file (glob("$Self->{obj_dir}/*.cpp")) { + if ($file =~ qr/__ALL.cpp/) { + error("__ALL.cpp file found: $file"); + } + } +} + sub check_cpp { my $filename = shift; my $size = -s $filename; @@ -110,13 +112,15 @@ sub check_gcc_flags { while (defined (my $line = $fh->getline)) { chomp $line; print ":log: $line\n" if $Self->{verbose}; - if ($line =~ /\.cpp/) { - my $filetype = ($line =~ /Slow/) ? "slow":"fast"; + if ($line =~ /$Self->{VM_PREFIX}\S*\.cpp/) { + my $filetype = ($line =~ /Slow|Syms/) ? "slow":"fast"; my $opt = ($line !~ /-O2/) ? "slow":"fast"; print "$filetype, $opt, $line\n" if $Self->{verbose}; if ($filetype ne $opt) { error("${filetype} file compiled as if was ${opt}: $line"); } + } elsif ($line =~ /\.cpp/ and $line !~ /-Os/) { + error("library file not compiled with OPT_GLOBAL: $line"); } } } diff --git a/test_regress/t/t_flag_csplit_off.pl b/test_regress/t/t_flag_csplit_off.pl new file mode 100755 index 000000000..17c865a6a --- /dev/null +++ b/test_regress/t/t_flag_csplit_off.pl @@ -0,0 +1,88 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(vlt_all => 1); + +top_filename("t/t_flag_csplit.v"); + +while (1) { + # Thi rule requires GNU make > 4.1 (or so, known broken in 3.81) + #%__Slow.o: %__Slow.cpp + # $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $< + if (make_version() < 4.1) { + skip("Test requires GNU Make version >= 4.1"); + last; + } + + compile( + v_flags2 => ["--trace --output-split 0 --exe ../$Self->{main_filename}"], + verilator_make_gmake => 0, + ); + + # We don't use the standard test_regress rules, as want to test the rules + # properly build + run(logfile => "$Self->{obj_dir}/vlt_gcc.log", + tee => $self->{verbose}, + cmd=>[$ENV{MAKE}, + "-C ".$Self->{obj_dir}, + "-f $Self->{VM_PREFIX}.mk", + "-j 4", + "VM_PREFIX=$Self->{VM_PREFIX}", + "TEST_OBJ_DIR=$Self->{obj_dir}", + "CPPFLAGS_DRIVER=-D".uc($Self->{name}), + ($opt_verbose ? "CPPFLAGS_DRIVER2=-DTEST_VERBOSE=1":""), + "OPT_FAST=-O2", + "OPT_SLOW=-O0", + ($param{make_flags}||""), + ]); + + execute( + check_finished => 1, + ); + + # Never spliting, so should set VM_PARALLEL_BUILDS to 0 by default + file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}_classes.mk", qr/VM_PARALLEL_BUILDS\s*=\s*0/); + check_no_splits(); + check_all_file(); + check_gcc_flags("$Self->{obj_dir}/vlt_gcc.log"); + + ok(1); + last; +} +1; + +sub check_no_splits { + foreach my $file (glob("$Self->{obj_dir}/*.cpp")) { + if ($file =~ qr/__\d/) { + error("Split file found: $file"); + } + } +} + +sub check_all_file { + foreach my $file (glob("$Self->{obj_dir}/*.cpp")) { + if ($file =~ qr/__ALL.cpp/) { + return; + } + } + error("__ALL.cpp file not found"); +} + +sub check_gcc_flags { + my $filename = shift; + my $fh = IO::File->new("<$filename") or error("$! $filenme"); + while (defined (my $line = $fh->getline)) { + chomp $line; + print ":log: $line\n" if $Self->{verbose}; + if ($line =~ /\.cpp/ && $line =~ qr/-O0/) { + error("File built as slow (should be in __ALL.cpp) : $line"); + } + } +} diff --git a/test_regress/t/t_flag_debug_noleak.pl b/test_regress/t/t_flag_debug_noleak.pl index c9332269f..aad25c780 100755 --- a/test_regress/t/t_flag_debug_noleak.pl +++ b/test_regress/t/t_flag_debug_noleak.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_debugi9.pl b/test_regress/t/t_flag_debugi9.pl index b1b26e37e..6db7a5c95 100755 --- a/test_regress/t/t_flag_debugi9.pl +++ b/test_regress/t/t_flag_debugi9.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_define.pl b/test_regress/t/t_flag_define.pl index 59730598d..35f485834 100755 --- a/test_regress/t/t_flag_define.pl +++ b/test_regress/t/t_flag_define.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -11,7 +11,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(vlt => 1); compile( - v_flags2 => ["-f t/t_flag_define.vc"], + v_flags2 => ["-f t/t_flag_define.vc -DCMD_DEF -DCMD_UNDEF -UCMD_UNDEF +define+CMD_DEF2"], ); execute( diff --git a/test_regress/t/t_flag_define.v b/test_regress/t/t_flag_define.v index f837114b6..1c1073eb4 100644 --- a/test_regress/t/t_flag_define.v +++ b/test_regress/t/t_flag_define.v @@ -108,6 +108,16 @@ module t; $write("%%Error: Missing define\n"); $stop; `endif +`ifndef CMD_DEF + $write("%%Error: Missing define\n"); $stop; +`endif +`ifndef CMD_DEF2 + $write("%%Error: Missing define\n"); $stop; +`endif +`ifdef CMD_UNDEF + $write("%%Error: Extra define\n"); $stop; +`endif + $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_flag_errorlimit_bad.pl b/test_regress/t/t_flag_errorlimit_bad.pl index 653eef863..6f645f2c0 100755 --- a/test_regress/t/t_flag_errorlimit_bad.pl +++ b/test_regress/t/t_flag_errorlimit_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_f.pl b/test_regress/t/t_flag_f.pl index 7bd3df43d..d2925619a 100755 --- a/test_regress/t/t_flag_f.pl +++ b/test_regress/t/t_flag_f.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_fi.pl b/test_regress/t/t_flag_fi.pl index 5c9a2eb79..b8bc97594 100755 --- a/test_regress/t/t_flag_fi.pl +++ b/test_regress/t/t_flag_fi.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_future.pl b/test_regress/t/t_flag_future.pl index 79d997082..c6b72116c 100755 --- a/test_regress/t/t_flag_future.pl +++ b/test_regress/t/t_flag_future.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_generate_key.pl b/test_regress/t/t_flag_generate_key.pl index 75e3e2ae5..3458cfd36 100755 --- a/test_regress/t/t_flag_generate_key.pl +++ b/test_regress/t/t_flag_generate_key.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_getenv.pl b/test_regress/t/t_flag_getenv.pl index c3a98bf4c..638a6ed5f 100755 --- a/test_regress/t/t_flag_getenv.pl +++ b/test_regress/t/t_flag_getenv.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,17 +10,23 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(vlt => 1); -$ENV{FOOBARTEST} = "gotit"; +setenv('FOOBARTEST', "gotit"); -compile( - v_flags2 => ["--getenv FOOBARTEST"], - expect => -'gotit +run( + cmd => ["../bin/verilator --getenv FOOBARTEST"], + expect => 'gotit ', - verilator_make_gmake => 0, - make_top_shell => 0, - make_main => 0, + logfile => "$Self->{obj_dir}/simx.log", + verilator_run => 1, ); +foreach my $var (qw(MAKE PERL SYSTEMC SYSTEMC_ARCH SYSTEMC_LIBDIR VERILATOR_ROOT)) { + run( + cmd => ["../bin/verilator --getenv ${var}"], + logfile => "$Self->{obj_dir}/simx.log", + verilator_run => 1, + ); +} + ok(1); 1; diff --git a/test_regress/t/t_flag_help.pl b/test_regress/t/t_flag_help.pl index 892719b3d..f3dc0cca4 100755 --- a/test_regress/t/t_flag_help.pl +++ b/test_regress/t/t_flag_help.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -23,6 +23,7 @@ foreach my $prog ( "--help"], logfile => "$Self->{obj_dir}/t_help.log", tee => 0, + verilator_run => 1, ); file_grep("$Self->{obj_dir}/t_help.log", qr/DISTRIBUTION/i); } diff --git a/test_regress/t/t_flag_invalid2_bad.pl b/test_regress/t/t_flag_invalid2_bad.pl index 42e60b698..7aae03f4b 100755 --- a/test_regress/t/t_flag_invalid2_bad.pl +++ b/test_regress/t/t_flag_invalid2_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(vlt => 1); -compile( +lint( fails => 1, verilator_flags2 => ['+invalid-plus'], expect_filename => $Self->{golden_filename}, diff --git a/test_regress/t/t_flag_invalid_bad.pl b/test_regress/t/t_flag_invalid_bad.pl index 71aee1a28..ac8693b64 100755 --- a/test_regress/t/t_flag_invalid_bad.pl +++ b/test_regress/t/t_flag_invalid_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(vlt => 1); -compile( +lint( fails => 1, verilator_flags2 => ['--invalid-dash'], expect_filename => $Self->{golden_filename}, diff --git a/test_regress/t/t_flag_language.pl b/test_regress/t/t_flag_language.pl index e38b29c49..b6ccf5eef 100755 --- a/test_regress/t/t_flag_language.pl +++ b/test_regress/t/t_flag_language.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_language_bad.pl b/test_regress/t/t_flag_language_bad.pl new file mode 100755 index 000000000..bfd78a9ab --- /dev/null +++ b/test_regress/t/t_flag_language_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2008 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 + +scenarios(vlt => 1); + +lint( + verilator_flags2 => ['--language 1-2-3-4'], + fails => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_ldflags.pl b/test_regress/t/t_flag_ldflags.pl index 11db30326..afb1ad462 100755 --- a/test_regress/t/t_flag_ldflags.pl +++ b/test_regress/t/t_flag_ldflags.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_lib.pl b/test_regress/t/t_flag_lib.pl index 9d7f3a43d..d2c9d5c46 100755 --- a/test_regress/t/t_flag_lib.pl +++ b/test_regress/t/t_flag_lib.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_main.pl b/test_regress/t/t_flag_main.pl index e68010553..397fea235 100755 --- a/test_regress/t/t_flag_main.pl +++ b/test_regress/t/t_flag_main.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -15,7 +15,6 @@ compile( verilator_make_cmake => 0, verilator_make_gmake => 0, make_main => 0, - make_top => 1, ); execute( diff --git a/test_regress/t/t_flag_main_sc_bad.out b/test_regress/t/t_flag_main_sc_bad.out new file mode 100644 index 000000000..aa5c05318 --- /dev/null +++ b/test_regress/t/t_flag_main_sc_bad.out @@ -0,0 +1,2 @@ +%Error: --main not usable with SystemC. Suggest see examples for sc_main(). +%Error: Exiting due to diff --git a/test_regress/t/t_flag_main_sc_bad.pl b/test_regress/t/t_flag_main_sc_bad.pl new file mode 100755 index 000000000..8c8eb97ca --- /dev/null +++ b/test_regress/t/t_flag_main_sc_bad.pl @@ -0,0 +1,23 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 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 + +scenarios(vlt => 1); + +compile( + verilator_flags2 => ['--exe --build --main --sc'], + verilator_make_cmake => 0, + verilator_make_gmake => 0, + make_main => 0, + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_make_cmake.pl b/test_regress/t/t_flag_make_cmake.pl index 57d2f2d05..c4b3d0ebe 100755 --- a/test_regress/t/t_flag_make_cmake.pl +++ b/test_regress/t/t_flag_make_cmake.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_make_cmake_sc.pl b/test_regress/t/t_flag_make_cmake_sc.pl index da8bc690f..c94d61d8c 100755 --- a/test_regress/t/t_flag_make_cmake_sc.pl +++ b/test_regress/t/t_flag_make_cmake_sc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_names.pl b/test_regress/t/t_flag_names.pl index ed0b5ca60..4a878bda8 100755 --- a/test_regress/t/t_flag_names.pl +++ b/test_regress/t/t_flag_names.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_nofile_bad.out b/test_regress/t/t_flag_nofile_bad.out new file mode 100644 index 000000000..f73aa067d --- /dev/null +++ b/test_regress/t/t_flag_nofile_bad.out @@ -0,0 +1 @@ +%Error: verilator: No Input Verilog file specified on command line, see verilator --help for more information diff --git a/test_regress/t/t_flag_nofile_bad.pl b/test_regress/t/t_flag_nofile_bad.pl new file mode 100755 index 000000000..d7a09e4a2 --- /dev/null +++ b/test_regress/t/t_flag_nofile_bad.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(vlt => 1); + +run(cmd => ["../bin/verilator --lint-only"], + fails => 1, + logfile => "$Self->{obj_dir}/sim.log", + expect_filename => $Self->{golden_filename}, + verilator_run => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_nomod_bad.pl b/test_regress/t/t_flag_nomod_bad.pl index 30a536839..b5861b2ab 100755 --- a/test_regress/t/t_flag_nomod_bad.pl +++ b/test_regress/t/t_flag_nomod_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_noop_bad.out b/test_regress/t/t_flag_noop_bad.out new file mode 100644 index 000000000..3f89e26a3 --- /dev/null +++ b/test_regress/t/t_flag_noop_bad.out @@ -0,0 +1 @@ +%Error: verilator: Need --cc, --sc, --cdc, --dpi-hdr-only, --lint-only, --xml-only or --E option diff --git a/test_regress/t/t_flag_noop_bad.pl b/test_regress/t/t_flag_noop_bad.pl new file mode 100755 index 000000000..f6fe2bbb8 --- /dev/null +++ b/test_regress/t/t_flag_noop_bad.pl @@ -0,0 +1,22 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(vlt => 1); + +run(cmd => ["../bin/verilator", + "t_flag_noop_bad.v"], + fails => 1, + logfile => "$Self->{obj_dir}/sim.log", + expect_filename => $Self->{golden_filename}, + verilator_run => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_noop_bad.v b/test_regress/t/t_flag_noop_bad.v new file mode 100644 index 000000000..112d2a878 --- /dev/null +++ b/test_regress/t/t_flag_noop_bad.v @@ -0,0 +1,17 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2019 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/); + + int u1; + int u1; + int u1; + int u1; + int u1; + int u1; + int u1; + +endmodule diff --git a/test_regress/t/t_flag_parameter.pl b/test_regress/t/t_flag_parameter.pl index a993d37e9..fc20a6898 100755 --- a/test_regress/t/t_flag_parameter.pl +++ b/test_regress/t/t_flag_parameter.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_parameter.v b/test_regress/t/t_flag_parameter.v index 0ac314b7f..33f1c102e 100644 --- a/test_regress/t/t_flag_parameter.v +++ b/test_regress/t/t_flag_parameter.v @@ -36,6 +36,10 @@ module t; parameter real22 = 0.1; parameter real31 = 0.1; parameter real32 = 0.1; + parameter real41 = 0.1; + parameter real42 = 0.1; + parameter real51 = 0.1; + parameter real52 = 0.1; parameter int11 = 1; parameter int12 = 1; @@ -63,6 +67,10 @@ module t; `check(real22,400); `check(real31,20); `check(real32,20); + `check(real41,582.5); + `check(real42,582.5); + `check(real51,145.5); + `check(real52,145.5); `check(int11,16); `check(int12,16); `check(int21,16); diff --git a/test_regress/t/t_flag_parameter.vc b/test_regress/t/t_flag_parameter.vc index 49e71571d..955540440 100644 --- a/test_regress/t/t_flag_parameter.vc +++ b/test_regress/t/t_flag_parameter.vc @@ -6,10 +6,14 @@ -pvalue+string22=\"New\ String\" -Greal11=0.2 -pvalue+real12=0.2 --Greal21=4e2 +-Greal21=4E2 -pvalue+real22=4e2 -Greal31=0.2e2 -pvalue+real32=0.2e2 +-Greal41=0x123.4p1 +-pvalue+real42=0X123.4P1 +-Greal51=0x123p-1 +-pvalue+real52=0X123P-1 -Gint11=0x10 -pvalue+int12=0x10 -Gint21=020 diff --git a/test_regress/t/t_flag_parameter_bad.pl b/test_regress/t/t_flag_parameter_bad.pl index 9e7b3230a..ec91b7170 100755 --- a/test_regress/t/t_flag_parameter_bad.pl +++ b/test_regress/t/t_flag_parameter_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_parameter_hier.pl b/test_regress/t/t_flag_parameter_hier.pl index 0bf458d34..c4d9c9bbd 100755 --- a/test_regress/t/t_flag_parameter_hier.pl +++ b/test_regress/t/t_flag_parameter_hier.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_quiet_exit.pl b/test_regress/t/t_flag_quiet_exit.pl index c4334956d..cb3d6bedd 100755 --- a/test_regress/t/t_flag_quiet_exit.pl +++ b/test_regress/t/t_flag_quiet_exit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_relinc.pl b/test_regress/t/t_flag_relinc.pl index de6aff6d2..38fc1bf91 100755 --- a/test_regress/t/t_flag_relinc.pl +++ b/test_regress/t/t_flag_relinc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_skipidentical.pl b/test_regress/t/t_flag_skipidentical.pl index 9ac3f346f..f3be1255c 100755 --- a/test_regress/t/t_flag_skipidentical.pl +++ b/test_regress/t/t_flag_skipidentical.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -22,7 +22,7 @@ scenarios(vlt => 1); sleep(2); # Or else it might take < 1 second to compile and see no diff. - $ENV{VERILATOR_DEBUG_SKIP_IDENTICAL} = 1; + setenv('VERILATOR_DEBUG_SKIP_IDENTICAL', 1); compile(); my @newstats = stat($outfile); diff --git a/test_regress/t/t_flag_stats.pl b/test_regress/t/t_flag_stats.pl index 180d46aef..854fb2b62 100755 --- a/test_regress/t/t_flag_stats.pl +++ b/test_regress/t/t_flag_stats.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_timescale.pl b/test_regress/t/t_flag_timescale.pl index ba5fd3fa2..98ff5cfe2 100755 --- a/test_regress/t/t_flag_timescale.pl +++ b/test_regress/t/t_flag_timescale.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_timescale_override.pl b/test_regress/t/t_flag_timescale_override.pl index b4f4fe235..1cb5ff133 100755 --- a/test_regress/t/t_flag_timescale_override.pl +++ b/test_regress/t/t_flag_timescale_override.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_timescale_override2.pl b/test_regress/t/t_flag_timescale_override2.pl index 458364b16..58b219698 100755 --- a/test_regress/t/t_flag_timescale_override2.pl +++ b/test_regress/t/t_flag_timescale_override2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_topmod2_bad.pl b/test_regress/t/t_flag_topmod2_bad.pl index a9293d164..8835ebd9c 100755 --- a/test_regress/t/t_flag_topmod2_bad.pl +++ b/test_regress/t/t_flag_topmod2_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(vlt => 1); -compile( +lint( v_flags2 => ["--top-module a "], fails => 1, expect_filename => $Self->{golden_filename}, diff --git a/test_regress/t/t_flag_topmodule.pl b/test_regress/t/t_flag_topmodule.pl index 6bb6f3756..c8e5ea2a6 100755 --- a/test_regress/t/t_flag_topmodule.pl +++ b/test_regress/t/t_flag_topmodule.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_topmodule_bad.pl b/test_regress/t/t_flag_topmodule_bad.pl index 578dc7df5..856e31ae4 100755 --- a/test_regress/t/t_flag_topmodule_bad.pl +++ b/test_regress/t/t_flag_topmodule_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -12,7 +12,7 @@ scenarios(vlt => 1); top_filename("t/t_flag_topmodule.v"); -compile( +lint( fails => 1, nc => 0, # Need to get it not to give the prompt expect_filename => $Self->{golden_filename}, diff --git a/test_regress/t/t_flag_topmodule_bad2.pl b/test_regress/t/t_flag_topmodule_bad2.pl index f0bd89460..c3f6245ff 100755 --- a/test_regress/t/t_flag_topmodule_bad2.pl +++ b/test_regress/t/t_flag_topmodule_bad2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -12,7 +12,7 @@ scenarios(vlt => 1); top_filename("t/t_flag_topmodule.v"); -compile( +lint( fails => 1, v_flags2 => ["--top-module notfound"], nc => 0, # Need to get it not to give the prompt diff --git a/test_regress/t/t_flag_topmodule_inline.pl b/test_regress/t/t_flag_topmodule_inline.pl index 89b5d9b8b..aab9ba97c 100755 --- a/test_regress/t/t_flag_topmodule_inline.pl +++ b/test_regress/t/t_flag_topmodule_inline.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_verilate.pl b/test_regress/t/t_flag_verilate.pl index f4b0081eb..59b78738a 100755 --- a/test_regress/t/t_flag_verilate.pl +++ b/test_regress/t/t_flag_verilate.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -48,7 +48,7 @@ compile( # Don't call cmake nor gmake from driver.pl. Just build here verilator_make_gmake => 0, verilator_flags2 => ['--exe --cc --build --no-verilate', '../' . $Self->{main_filename}, - '--debugi 1 --dump-tree'], + '--debugi 1 --dump-tree --dump-tree-addrids'], ); # The previous run must not verilated, only build is expected. diff --git a/test_regress/t/t_flag_version.pl b/test_regress/t/t_flag_version.pl index 0c6cd25d4..2b145b855 100755 --- a/test_regress/t/t_flag_version.pl +++ b/test_regress/t/t_flag_version.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -24,6 +24,7 @@ foreach my $prog ( tee => $self->{verbose}, logfile => "$Self->{obj_dir}/t_help.log", expect => qr/^Verilator/, + verilator_run => 1, ); run(fails => 0, @@ -32,6 +33,7 @@ foreach my $prog ( tee => $self->{verbose}, logfile => "$Self->{obj_dir}/t_help.log", expect => qr/^Verilator/, + verilator_run => 1, ); run(fails => 0, @@ -39,6 +41,7 @@ foreach my $prog ( "-V"], logfile => "$Self->{obj_dir}/t_help.log", expect => qr/^Verilator/, + verilator_run => 1, ); } diff --git a/test_regress/t/t_flag_werror_bad1.pl b/test_regress/t/t_flag_werror_bad1.pl index 7ad23029f..c9a9614cc 100755 --- a/test_regress/t/t_flag_werror_bad1.pl +++ b/test_regress/t/t_flag_werror_bad1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_werror_bad2.pl b/test_regress/t/t_flag_werror_bad2.pl index c78346b14..e3044056a 100755 --- a/test_regress/t/t_flag_werror_bad2.pl +++ b/test_regress/t/t_flag_werror_bad2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_werror_bad3.out b/test_regress/t/t_flag_werror_bad3.out new file mode 100644 index 000000000..8b2a23cf5 --- /dev/null +++ b/test_regress/t/t_flag_werror_bad3.out @@ -0,0 +1 @@ +%Error: Unknown warning specified: -Werror-NOSUCHERRORASTHIS diff --git a/test_regress/t/t_flag_werror_bad3.pl b/test_regress/t/t_flag_werror_bad3.pl new file mode 100755 index 000000000..d031c654f --- /dev/null +++ b/test_regress/t/t_flag_werror_bad3.pl @@ -0,0 +1,22 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(vlt => 1); + +top_filename("t/t_flag_werror.v"); + +lint( + fails => 1, + verilator_flags => [qw(-cc -Werror-NOSUCHERRORASTHIS)], + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_wfatal.pl b/test_regress/t/t_flag_wfatal.pl index c56ff93f2..e480941ab 100755 --- a/test_regress/t/t_flag_wfatal.pl +++ b/test_regress/t/t_flag_wfatal.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_woff.pl b/test_regress/t/t_flag_woff.pl index 5a203983f..17c128753 100755 --- a/test_regress/t/t_flag_woff.pl +++ b/test_regress/t/t_flag_woff.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_woff_bad.out b/test_regress/t/t_flag_woff_bad.out new file mode 100644 index 000000000..25c278a31 --- /dev/null +++ b/test_regress/t/t_flag_woff_bad.out @@ -0,0 +1 @@ +%Error: Unknown warning specified: -Wno-NOSUCHERRORASTHIS diff --git a/test_regress/t/t_flag_woff_bad.pl b/test_regress/t/t_flag_woff_bad.pl new file mode 100755 index 000000000..d1c151c64 --- /dev/null +++ b/test_regress/t/t_flag_woff_bad.pl @@ -0,0 +1,20 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2008 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 + +scenarios(vlt => 1); + +lint( + verilator_flags2 => ["--lint-only -Wno-NOSUCHERRORASTHIS"], + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_wpedantic_bad.pl b/test_regress/t/t_flag_wpedantic_bad.pl index bbd90df9f..9de6b85ee 100755 --- a/test_regress/t/t_flag_wpedantic_bad.pl +++ b/test_regress/t/t_flag_wpedantic_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_flag_wwarn_bad.out b/test_regress/t/t_flag_wwarn_bad.out new file mode 100644 index 000000000..4913b9bb2 --- /dev/null +++ b/test_regress/t/t_flag_wwarn_bad.out @@ -0,0 +1 @@ +%Error: Unknown warning specified: -Wwarn-NOSUCHERRORASTHIS diff --git a/test_regress/t/t_flag_wwarn_bad.pl b/test_regress/t/t_flag_wwarn_bad.pl new file mode 100755 index 000000000..541ce84cf --- /dev/null +++ b/test_regress/t/t_flag_wwarn_bad.pl @@ -0,0 +1,22 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(vlt => 1); + +top_filename("t/t_flag_werror.v"); + +lint( + fails => 1, + verilator_flags => [qw(-cc -Wwarn-NOSUCHERRORASTHIS)], + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_xinitial_0.pl b/test_regress/t/t_flag_xinitial_0.pl index 4ef44eb49..c14556cdc 100755 --- a/test_regress/t/t_flag_xinitial_0.pl +++ b/test_regress/t/t_flag_xinitial_0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -18,7 +18,7 @@ execute( check_finished => 1, ); -file_grep_not("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/VL_RAND_RESET/); +file_grep_not("$Self->{obj_dir}/$Self->{VM_PREFIX}__Slow.cpp", qr/VL_RAND_RESET/); ok(1); 1; diff --git a/test_regress/t/t_flag_xinitial_unique.pl b/test_regress/t/t_flag_xinitial_unique.pl index 9cc7391f5..b94639b4e 100755 --- a/test_regress/t/t_flag_xinitial_unique.pl +++ b/test_regress/t/t_flag_xinitial_unique.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -18,7 +18,7 @@ execute( check_finished => 1, ); -file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/VL_RAND_RESET/); +file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}__Slow.cpp", qr/VL_RAND_RESET/); ok(1); 1; diff --git a/test_regress/t/t_for_break.pl b/test_regress/t/t_for_break.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_for_break.pl +++ b/test_regress/t/t_for_break.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_for_comma_bad.pl b/test_regress/t/t_for_comma_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_for_comma_bad.pl +++ b/test_regress/t/t_for_comma_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_for_count.pl b/test_regress/t/t_for_count.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_for_count.pl +++ b/test_regress/t/t_for_count.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_for_funcbound.pl b/test_regress/t/t_for_funcbound.pl index 5325f14e3..06c985de2 100755 --- a/test_regress/t/t_for_funcbound.pl +++ b/test_regress/t/t_for_funcbound.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_for_init_bug.pl b/test_regress/t/t_for_init_bug.pl index 3d67ac05c..300cb0b09 100755 --- a/test_regress/t/t_for_init_bug.pl +++ b/test_regress/t/t_for_init_bug.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_for_local.pl b/test_regress/t/t_for_local.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_for_local.pl +++ b/test_regress/t/t_for_local.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_for_loop.pl b/test_regress/t/t_for_loop.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_for_loop.pl +++ b/test_regress/t/t_for_loop.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_foreach.pl b/test_regress/t/t_foreach.pl index 57f86352f..f5e2135cc 100755 --- a/test_regress/t/t_foreach.pl +++ b/test_regress/t/t_foreach.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -21,11 +21,13 @@ execute( # We expect all loops should be unrolled by verilator, # none of the loop variables should exist in the output: file_grep_not("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/index_/); +file_grep_not("$Self->{obj_dir}/$Self->{VM_PREFIX}__Slow.cpp", qr/index_/); # Further, we expect that all logic within the loop should # have been evaluated inside the compiler. So there should be # no references to 'sum' in the .cpp. file_grep_not("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/sum/); +file_grep_not("$Self->{obj_dir}/$Self->{VM_PREFIX}__Slow.cpp", qr/sum/); ok(1); 1; diff --git a/test_regress/t/t_fork.out b/test_regress/t/t_fork.out index 1f9b98a83..5d76dd536 100644 --- a/test_regress/t/t_fork.out +++ b/test_regress/t/t_fork.out @@ -1,4 +1,5 @@ %Error: t/t_fork.v:10:14: Unsupported: fork statements + : ... In instance t 10 | fork : fblk | ^~~~ %Error: Exiting due to diff --git a/test_regress/t/t_fork.pl b/test_regress/t/t_fork.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_fork.pl +++ b/test_regress/t/t_fork.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_fork_bbox.pl b/test_regress/t/t_fork_bbox.pl index 4bf13ff24..3a83673be 100755 --- a/test_regress/t/t_fork_bbox.pl +++ b/test_regress/t/t_fork_bbox.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_fork_func2_bad.out b/test_regress/t/t_fork_func2_bad.out new file mode 100644 index 000000000..16cdd6242 --- /dev/null +++ b/test_regress/t/t_fork_func2_bad.out @@ -0,0 +1,5 @@ +%Error: t/t_fork_func2_bad.v:10:7: Only fork .. join_none is legal in functions. (IEEE 1800-2017 13.4.4) + : ... In instance t + 10 | fork + | ^~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_fork_func2_bad.pl b/test_regress/t/t_fork_func2_bad.pl new file mode 100755 index 000000000..89ffd046b --- /dev/null +++ b/test_regress/t/t_fork_func2_bad.pl @@ -0,0 +1,20 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 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 + +scenarios(linter => 1); + +lint( + verilator_flags2 => ['--lint-only'], + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_fork_func2_bad.v b/test_regress/t/t_fork_func2_bad.v new file mode 100644 index 000000000..c777a5c58 --- /dev/null +++ b/test_regress/t/t_fork_func2_bad.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/); + + function int f; + fork + ; + join_any // Illegal 13.4.4 + endfunction + + int i; + + initial begin + i = f(); + end + +endmodule diff --git a/test_regress/t/t_fork_func_bad.out b/test_regress/t/t_fork_func_bad.out new file mode 100644 index 000000000..0fdf968a9 --- /dev/null +++ b/test_regress/t/t_fork_func_bad.out @@ -0,0 +1,4 @@ +%Error: t/t_fork_func_bad.v:11:10: Return isn't legal under fork (IEEE 1800-2017 9.2.3) + 11 | return 0; + | ^~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_fork_func_bad.pl b/test_regress/t/t_fork_func_bad.pl new file mode 100755 index 000000000..89ffd046b --- /dev/null +++ b/test_regress/t/t_fork_func_bad.pl @@ -0,0 +1,20 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 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 + +scenarios(linter => 1); + +lint( + verilator_flags2 => ['--lint-only'], + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_fork_func_bad.v b/test_regress/t/t_fork_func_bad.v new file mode 100644 index 000000000..c4a67a6f1 --- /dev/null +++ b/test_regress/t/t_fork_func_bad.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/); + + function int f; + fork + return 0; // Illegal 9.3.2 + join_none + endfunction + + int i; + + initial begin + i = f(); + end + +endmodule diff --git a/test_regress/t/t_format_wide_decimal.pl b/test_regress/t/t_format_wide_decimal.pl index 81690404c..b949e06e1 100755 --- a/test_regress/t/t_format_wide_decimal.pl +++ b/test_regress/t/t_format_wide_decimal.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func.pl b/test_regress/t/t_func.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func.pl +++ b/test_regress/t/t_func.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_bad.pl b/test_regress/t/t_func_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_func_bad.pl +++ b/test_regress/t/t_func_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_bad2.pl b/test_regress/t/t_func_bad2.pl index c1dba4c49..877e6133a 100755 --- a/test_regress/t/t_func_bad2.pl +++ b/test_regress/t/t_func_bad2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_bad_width.pl b/test_regress/t/t_func_bad_width.pl index 056b9974f..59ba0d6c6 100755 --- a/test_regress/t/t_func_bad_width.pl +++ b/test_regress/t/t_func_bad_width.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_begin2.pl b/test_regress/t/t_func_begin2.pl index 204f3112f..0f2fb4862 100755 --- a/test_regress/t/t_func_begin2.pl +++ b/test_regress/t/t_func_begin2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_check.pl b/test_regress/t/t_func_check.pl index 623d7bbeb..db885e46d 100755 --- a/test_regress/t/t_func_check.pl +++ b/test_regress/t/t_func_check.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_const.pl b/test_regress/t/t_func_const.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_const.pl +++ b/test_regress/t/t_func_const.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_const2_bad.pl b/test_regress/t/t_func_const2_bad.pl index 52ccee872..ad607fff5 100755 --- a/test_regress/t/t_func_const2_bad.pl +++ b/test_regress/t/t_func_const2_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_const3_bad.pl b/test_regress/t/t_func_const3_bad.pl index d49d2e341..475b114ec 100755 --- a/test_regress/t/t_func_const3_bad.pl +++ b/test_regress/t/t_func_const3_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(vlt => 1); -compile( +lint( v_flags2 => ["--lint-only"], fails => 1, expect_filename => $Self->{golden_filename}, diff --git a/test_regress/t/t_func_const_bad.pl b/test_regress/t/t_func_const_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_func_const_bad.pl +++ b/test_regress/t/t_func_const_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_const_packed_array_bad.pl b/test_regress/t/t_func_const_packed_array_bad.pl index 52ccee872..ad607fff5 100755 --- a/test_regress/t/t_func_const_packed_array_bad.pl +++ b/test_regress/t/t_func_const_packed_array_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_const_packed_struct_bad.pl b/test_regress/t/t_func_const_packed_struct_bad.pl index 52ccee872..ad607fff5 100755 --- a/test_regress/t/t_func_const_packed_struct_bad.pl +++ b/test_regress/t/t_func_const_packed_struct_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_const_packed_struct_bad2.pl b/test_regress/t/t_func_const_packed_struct_bad2.pl index 52ccee872..ad607fff5 100755 --- a/test_regress/t/t_func_const_packed_struct_bad2.pl +++ b/test_regress/t/t_func_const_packed_struct_bad2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_const_struct_bad.pl b/test_regress/t/t_func_const_struct_bad.pl index 52ccee872..ad607fff5 100755 --- a/test_regress/t/t_func_const_struct_bad.pl +++ b/test_regress/t/t_func_const_struct_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_crc.pl b/test_regress/t/t_func_crc.pl index d6841bed0..7d49cd2cd 100755 --- a/test_regress/t/t_func_crc.pl +++ b/test_regress/t/t_func_crc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_default_warn.pl b/test_regress/t/t_func_default_warn.pl index f142cc952..e355c477c 100755 --- a/test_regress/t/t_func_default_warn.pl +++ b/test_regress/t/t_func_default_warn.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_defaults.pl b/test_regress/t/t_func_defaults.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_defaults.pl +++ b/test_regress/t/t_func_defaults.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_dotted_inl0.pl b/test_regress/t/t_func_dotted_inl0.pl index c52fcacdb..000ae222d 100755 --- a/test_regress/t/t_func_dotted_inl0.pl +++ b/test_regress/t/t_func_dotted_inl0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_dotted_inl0_vlt.pl b/test_regress/t/t_func_dotted_inl0_vlt.pl index 57499e1bd..321df222d 100755 --- a/test_regress/t/t_func_dotted_inl0_vlt.pl +++ b/test_regress/t/t_func_dotted_inl0_vlt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_dotted_inl1.pl b/test_regress/t/t_func_dotted_inl1.pl index 0e727a4a2..755d44d31 100755 --- a/test_regress/t/t_func_dotted_inl1.pl +++ b/test_regress/t/t_func_dotted_inl1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_dotted_inl1_vlt.pl b/test_regress/t/t_func_dotted_inl1_vlt.pl index beea5f392..731245f96 100755 --- a/test_regress/t/t_func_dotted_inl1_vlt.pl +++ b/test_regress/t/t_func_dotted_inl1_vlt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_dotted_inl2.pl b/test_regress/t/t_func_dotted_inl2.pl index c958969e5..6f6d98c4c 100755 --- a/test_regress/t/t_func_dotted_inl2.pl +++ b/test_regress/t/t_func_dotted_inl2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_dotted_inl2_vlt.pl b/test_regress/t/t_func_dotted_inl2_vlt.pl index 4d31f5ec9..378a9e7ae 100755 --- a/test_regress/t/t_func_dotted_inl2_vlt.pl +++ b/test_regress/t/t_func_dotted_inl2_vlt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_endian.pl b/test_regress/t/t_func_endian.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_endian.pl +++ b/test_regress/t/t_func_endian.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_first.pl b/test_regress/t/t_func_first.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_first.pl +++ b/test_regress/t/t_func_first.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_flip.pl b/test_regress/t/t_func_flip.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_flip.pl +++ b/test_regress/t/t_func_flip.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_gen.pl b/test_regress/t/t_func_gen.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_gen.pl +++ b/test_regress/t/t_func_gen.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_graphcirc.pl b/test_regress/t/t_func_graphcirc.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_graphcirc.pl +++ b/test_regress/t/t_func_graphcirc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_grey.pl b/test_regress/t/t_func_grey.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_grey.pl +++ b/test_regress/t/t_func_grey.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_inconly.pl b/test_regress/t/t_func_inconly.pl new file mode 100755 index 000000000..9a15dd2cc --- /dev/null +++ b/test_regress/t/t_func_inconly.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 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 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_func_inconly.v b/test_regress/t/t_func_inconly.v new file mode 100644 index 000000000..af4eb9a42 --- /dev/null +++ b/test_regress/t/t_func_inconly.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t; + task main; + integer varintask; + varintask = 0; + while (varintask < 4) begin + varintask = varintask + 1; + end + if (varintask != 4) $stop; + endtask + initial begin + main; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_func_lib.pl b/test_regress/t/t_func_lib.pl index 2142a98cd..3f293390f 100755 --- a/test_regress/t/t_func_lib.pl +++ b/test_regress/t/t_func_lib.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_lib_sub.pl b/test_regress/t/t_func_lib_sub.pl index 6c7c759a8..6c38477cd 100755 --- a/test_regress/t/t_func_lib_sub.pl +++ b/test_regress/t/t_func_lib_sub.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_mlog2.pl b/test_regress/t/t_func_mlog2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_mlog2.pl +++ b/test_regress/t/t_func_mlog2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_named.pl b/test_regress/t/t_func_named.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_named.pl +++ b/test_regress/t/t_func_named.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_noinl.pl b/test_regress/t/t_func_noinl.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_noinl.pl +++ b/test_regress/t/t_func_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_numones.pl b/test_regress/t/t_func_numones.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_numones.pl +++ b/test_regress/t/t_func_numones.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_outfirst.pl b/test_regress/t/t_func_outfirst.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_outfirst.pl +++ b/test_regress/t/t_func_outfirst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_outp.pl b/test_regress/t/t_func_outp.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_outp.pl +++ b/test_regress/t/t_func_outp.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_paramed.pl b/test_regress/t/t_func_paramed.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_paramed.pl +++ b/test_regress/t/t_func_paramed.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_plog.pl b/test_regress/t/t_func_plog.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_plog.pl +++ b/test_regress/t/t_func_plog.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_public.pl b/test_regress/t/t_func_public.pl index 3ba182f70..cb925f76f 100755 --- a/test_regress/t/t_func_public.pl +++ b/test_regress/t/t_func_public.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_public.v b/test_regress/t/t_func_public.v index 60ddfbc28..c0d1e1e47 100644 --- a/test_regress/t/t_func_public.v +++ b/test_regress/t/t_func_public.v @@ -87,14 +87,14 @@ module tpub ( $c("publicNoArgs();"); $c("publicSetBool(true);"); $c("publicSetLong(0x11bca);"); - $c("publicSetQuad(VL_ULL(0x66655554444));"); + $c("publicSetQuad(0x66655554444ULL);"); $c("publicSetFlop(0x321);"); //Unsupported: $c("WData w[3] = {0x12, 0x5678_9123, 0x1245_2352}; publicSetWide(w);"); end if (cyc==12) begin $c("got_bool = publicGetSetBool(true);"); $c("got_long = publicGetSetLong(0x11bca);"); - $c("got_quad = publicGetSetQuad(VL_ULL(0xaaaabbbbcccc));"); + $c("got_quad = publicGetSetQuad(0xaaaabbbbccccULL);"); end if (cyc==13) begin $c("{ bool gb; publicGetBool(gb); got_bool=gb; }"); diff --git a/test_regress/t/t_func_public_trace.pl b/test_regress/t/t_func_public_trace.pl index df1660cce..a8afb6674 100755 --- a/test_regress/t/t_func_public_trace.pl +++ b/test_regress/t/t_func_public_trace.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,12 +10,10 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(simulator => 1); -my $pubtask = ($Self->{vlt_all} && verilator_version() =~ /\(public_tasks\)/); # TBD - top_filename("t/t_func_public.v"); compile( - verilator_flags2 => [($pubtask?'-DVERILATOR_PUBLIC_TASKS':''), "--trace"], + verilator_flags2 => ["--trace"], fails => $fail, ); diff --git a/test_regress/t/t_func_rand.pl b/test_regress/t/t_func_rand.pl index 4d136dc52..ce5a6dd80 100755 --- a/test_regress/t/t_func_rand.pl +++ b/test_regress/t/t_func_rand.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_range.pl b/test_regress/t/t_func_range.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_range.pl +++ b/test_regress/t/t_func_range.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_real_abs.pl b/test_regress/t/t_func_real_abs.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_real_abs.pl +++ b/test_regress/t/t_func_real_abs.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_real_param.pl b/test_regress/t/t_func_real_param.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_real_param.pl +++ b/test_regress/t/t_func_real_param.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_redef.pl b/test_regress/t/t_func_redef.pl index d1bf185c9..552bd97db 100755 --- a/test_regress/t/t_func_redef.pl +++ b/test_regress/t/t_func_redef.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_regfirst.pl b/test_regress/t/t_func_regfirst.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_regfirst.pl +++ b/test_regress/t/t_func_regfirst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_return.pl b/test_regress/t/t_func_return.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_return.pl +++ b/test_regress/t/t_func_return.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_return_bad.out b/test_regress/t/t_func_return_bad.out new file mode 100644 index 000000000..64a547a1a --- /dev/null +++ b/test_regress/t/t_func_return_bad.out @@ -0,0 +1,19 @@ +%Error: t/t_func_return_bad.v:10:7: Return underneath a task shouldn't have return value + 10 | return 1; + | ^~~~~~ +%Error: t/t_func_return_bad.v:13:7: Return underneath a function should have return value + 13 | return; + | ^~~~~~ +%Error: t/t_func_return_bad.v:17:7: Return isn't underneath a task or function + 17 | return; + | ^~~~~~ +%Error: t/t_func_return_bad.v:18:7: continue isn't underneath a loop + 18 | continue; + | ^~~~~~~~ +%Error: t/t_func_return_bad.v:19:7: break isn't underneath a loop + 19 | break; + | ^~~~~ +%Error: t/t_func_return_bad.v:22:7: disable isn't underneath a begin with name: 'foo' + 22 | disable foo; + | ^~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_func_return_bad.pl b/test_regress/t/t_func_return_bad.pl new file mode 100755 index 000000000..0c0e3ac70 --- /dev/null +++ b/test_regress/t/t_func_return_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2011 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 + +scenarios(linter => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_func_return_bad.v b/test_regress/t/t_func_return_bad.v new file mode 100644 index 000000000..bbdcf6ffd --- /dev/null +++ b/test_regress/t/t_func_return_bad.v @@ -0,0 +1,24 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2011 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/); + + task t1; + return 1; // Shouldn't return value + endtask + function int f1; + return; // Should return value + endfunction + + initial begin + return; // Not under function + continue; // Not under loop + break; // Not under loop + begin : foo + end + disable foo; // Disabling outside block + end +endmodule diff --git a/test_regress/t/t_func_sum.pl b/test_regress/t/t_func_sum.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_sum.pl +++ b/test_regress/t/t_func_sum.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_task_bad.pl b/test_regress/t/t_func_task_bad.pl index 1de2d764d..0c0e3ac70 100755 --- a/test_regress/t/t_func_task_bad.pl +++ b/test_regress/t/t_func_task_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_tie_bad.pl b/test_regress/t/t_func_tie_bad.pl index 1de2d764d..0c0e3ac70 100755 --- a/test_regress/t/t_func_tie_bad.pl +++ b/test_regress/t/t_func_tie_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_twocall.pl b/test_regress/t/t_func_twocall.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_twocall.pl +++ b/test_regress/t/t_func_twocall.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_types.pl b/test_regress/t/t_func_types.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_types.pl +++ b/test_regress/t/t_func_types.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_under.pl b/test_regress/t/t_func_under.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_under.pl +++ b/test_regress/t/t_func_under.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_under2.pl b/test_regress/t/t_func_under2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_under2.pl +++ b/test_regress/t/t_func_under2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_unit.pl b/test_regress/t/t_func_unit.pl index e02817219..9a15dd2cc 100755 --- a/test_regress/t/t_func_unit.pl +++ b/test_regress/t/t_func_unit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_v.pl b/test_regress/t/t_func_v.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_v.pl +++ b/test_regress/t/t_func_v.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_v_noinl.pl b/test_regress/t/t_func_v_noinl.pl index c0bccceac..818d754c1 100755 --- a/test_regress/t/t_func_v_noinl.pl +++ b/test_regress/t/t_func_v_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_void.pl b/test_regress/t/t_func_void.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_void.pl +++ b/test_regress/t/t_func_void.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_void_bad.pl b/test_regress/t/t_func_void_bad.pl index dba098eb6..a60503a1f 100755 --- a/test_regress/t/t_func_void_bad.pl +++ b/test_regress/t/t_func_void_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_func_while.pl b/test_regress/t/t_func_while.pl index 7a2f89aa9..886645acd 100755 --- a/test_regress/t/t_func_while.pl +++ b/test_regress/t/t_func_while.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_wide.pl b/test_regress/t/t_func_wide.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_func_wide.pl +++ b/test_regress/t/t_func_wide.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_func_wide_out_bad.pl b/test_regress/t/t_func_wide_out_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_func_wide_out_bad.pl +++ b/test_regress/t/t_func_wide_out_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_fuzz_always_bad.pl b/test_regress/t/t_fuzz_always_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_fuzz_always_bad.pl +++ b/test_regress/t/t_fuzz_always_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_fuzz_eof_bad.pl b/test_regress/t/t_fuzz_eof_bad.pl index b3e120653..3be843059 100755 --- a/test_regress/t/t_fuzz_eof_bad.pl +++ b/test_regress/t/t_fuzz_eof_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_fuzz_eqne_bad.pl b/test_regress/t/t_fuzz_eqne_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_fuzz_eqne_bad.pl +++ b/test_regress/t/t_fuzz_eqne_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_fuzz_genintf_bad.pl b/test_regress/t/t_fuzz_genintf_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_fuzz_genintf_bad.pl +++ b/test_regress/t/t_fuzz_genintf_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_fuzz_negwidth_bad.pl b/test_regress/t/t_fuzz_negwidth_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_fuzz_negwidth_bad.pl +++ b/test_regress/t/t_fuzz_negwidth_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_fuzz_triand_bad.pl b/test_regress/t/t_fuzz_triand_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_fuzz_triand_bad.pl +++ b/test_regress/t/t_fuzz_triand_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gantt.pl b/test_regress/t/t_gantt.pl index 1f62a459f..e38cd63b7 100755 --- a/test_regress/t/t_gantt.pl +++ b/test_regress/t/t_gantt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -40,7 +40,9 @@ execute( run(cmd => ["$ENV{VERILATOR_ROOT}/bin/verilator_gantt", "$Self->{obj_dir}/profile_threads.dat", "--vcd $Self->{obj_dir}/profile_threads.vcd", - "> $Self->{obj_dir}/gantt.log"]); + "> $Self->{obj_dir}/gantt.log"], + verilator_run => 1, + ); # We should have three lines of gantt chart, each with # an even number of mtask-bars (eg "[123--]") diff --git a/test_regress/t/t_gate_array.pl b/test_regress/t/t_gate_array.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_gate_array.pl +++ b/test_regress/t/t_gate_array.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gate_basic.pl b/test_regress/t/t_gate_basic.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_gate_basic.pl +++ b/test_regress/t/t_gate_basic.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gate_chained.pl b/test_regress/t/t_gate_chained.pl index 2ccf6c4d3..3b151b61f 100755 --- a/test_regress/t/t_gate_chained.pl +++ b/test_regress/t/t_gate_chained.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gate_delref.pl b/test_regress/t/t_gate_delref.pl index 86f045021..2eb6a63bc 100755 --- a/test_regress/t/t_gate_delref.pl +++ b/test_regress/t/t_gate_delref.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gate_elim.pl b/test_regress/t/t_gate_elim.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_gate_elim.pl +++ b/test_regress/t/t_gate_elim.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gate_fdup.pl b/test_regress/t/t_gate_fdup.pl index 86f045021..2eb6a63bc 100755 --- a/test_regress/t/t_gate_fdup.pl +++ b/test_regress/t/t_gate_fdup.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gate_implicit.pl b/test_regress/t/t_gate_implicit.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gate_implicit.pl +++ b/test_regress/t/t_gate_implicit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gate_lvalue_const.pl b/test_regress/t/t_gate_lvalue_const.pl index e02817219..9a15dd2cc 100755 --- a/test_regress/t/t_gate_lvalue_const.pl +++ b/test_regress/t/t_gate_lvalue_const.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gate_ormux.pl b/test_regress/t/t_gate_ormux.pl index 7ecf561f6..a2b95b689 100755 --- a/test_regress/t/t_gate_ormux.pl +++ b/test_regress/t/t_gate_ormux.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gate_tree.pl b/test_regress/t/t_gate_tree.pl index eb24dd880..568c1868c 100755 --- a/test_regress/t/t_gate_tree.pl +++ b/test_regress/t/t_gate_tree.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gate_unsup.pl b/test_regress/t/t_gate_unsup.pl index fceb65618..f32089412 100755 --- a/test_regress/t/t_gate_unsup.pl +++ b/test_regress/t/t_gate_unsup.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gated_clk_1.pl b/test_regress/t/t_gated_clk_1.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gated_clk_1.pl +++ b/test_regress/t/t_gated_clk_1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_alw.pl b/test_regress/t/t_gen_alw.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_alw.pl +++ b/test_regress/t/t_gen_alw.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_assign.pl b/test_regress/t/t_gen_assign.pl index 4262e4aea..7c611fc4c 100755 --- a/test_regress/t/t_gen_assign.pl +++ b/test_regress/t/t_gen_assign.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_cond_bitrange.pl b/test_regress/t/t_gen_cond_bitrange.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_cond_bitrange.pl +++ b/test_regress/t/t_gen_cond_bitrange.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_cond_bitrange_bad.pl b/test_regress/t/t_gen_cond_bitrange_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_gen_cond_bitrange_bad.pl +++ b/test_regress/t/t_gen_cond_bitrange_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_cond_const.pl b/test_regress/t/t_gen_cond_const.pl index 2785bec68..680071db4 100755 --- a/test_regress/t/t_gen_cond_const.pl +++ b/test_regress/t/t_gen_cond_const.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_defparam.pl b/test_regress/t/t_gen_defparam.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_defparam.pl +++ b/test_regress/t/t_gen_defparam.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_defparam_unsup_bad.out b/test_regress/t/t_gen_defparam_unsup_bad.out new file mode 100644 index 000000000..663a56e5c --- /dev/null +++ b/test_regress/t/t_gen_defparam_unsup_bad.out @@ -0,0 +1,7 @@ +%Error: t/t_gen_defparam_unsup_bad.v:9:16: Unsupported: defparam with more than one dot + 9 | defparam a.b.W = 3; + | ^ +%Error: t/t_gen_defparam_unsup_bad.v:9:17: syntax error, unexpected IDENTIFIER, expecting ',' or ';' + 9 | defparam a.b.W = 3; + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_gen_defparam_unsup_bad.pl b/test_regress/t/t_gen_defparam_unsup_bad.pl new file mode 100755 index 000000000..a5846c699 --- /dev/null +++ b/test_regress/t/t_gen_defparam_unsup_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(vlt => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_gen_defparam_unsup_bad.v b/test_regress/t/t_gen_defparam_unsup_bad.v new file mode 100644 index 000000000..2d2842552 --- /dev/null +++ b/test_regress/t/t_gen_defparam_unsup_bad.v @@ -0,0 +1,18 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2012 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/); + a a (); + defparam a.b.W = 3; +endmodule + +module a; + b b(); +endmodule + +module b; + parameter W = 0; +endmodule diff --git a/test_regress/t/t_gen_div0.pl b/test_regress/t/t_gen_div0.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_div0.pl +++ b/test_regress/t/t_gen_div0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_for.pl b/test_regress/t/t_gen_for.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_for.pl +++ b/test_regress/t/t_gen_for.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_for0.pl b/test_regress/t/t_gen_for0.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_for0.pl +++ b/test_regress/t/t_gen_for0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_for1.pl b/test_regress/t/t_gen_for1.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_for1.pl +++ b/test_regress/t/t_gen_for1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_for2.pl b/test_regress/t/t_gen_for2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_for2.pl +++ b/test_regress/t/t_gen_for2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_for_overlap.pl b/test_regress/t/t_gen_for_overlap.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_for_overlap.pl +++ b/test_regress/t/t_gen_for_overlap.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_for_shuffle.pl b/test_regress/t/t_gen_for_shuffle.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_for_shuffle.pl +++ b/test_regress/t/t_gen_for_shuffle.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_forif.pl b/test_regress/t/t_gen_forif.pl index 814486756..bc8663a80 100755 --- a/test_regress/t/t_gen_forif.pl +++ b/test_regress/t/t_gen_forif.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_genblk.pl b/test_regress/t/t_gen_genblk.pl index ec985d291..56cc415df 100755 --- a/test_regress/t/t_gen_genblk.pl +++ b/test_regress/t/t_gen_genblk.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_genblk_noinl.pl b/test_regress/t/t_gen_genblk_noinl.pl index a9d24cab5..08623e342 100755 --- a/test_regress/t/t_gen_genblk_noinl.pl +++ b/test_regress/t/t_gen_genblk_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_if.pl b/test_regress/t/t_gen_if.pl index e847dac87..1f3b9a577 100755 --- a/test_regress/t/t_gen_if.pl +++ b/test_regress/t/t_gen_if.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_inc.pl b/test_regress/t/t_gen_inc.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_inc.pl +++ b/test_regress/t/t_gen_inc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_inc.v b/test_regress/t/t_gen_inc.v index eaa7ccc3d..e2fbbce2d 100644 --- a/test_regress/t/t_gen_inc.v +++ b/test_regress/t/t_gen_inc.v @@ -39,7 +39,6 @@ module t (/*AUTOARG*/ for (g=16; g>=8; g--) always @(posedge clk) gen_post_MINUSMINUS[g] = 1'b1; for (g=8; g<=16; g+=2) always @(posedge clk) gen_PLUSEQ[g] = 1'b1; for (g=16; g>=8; g-=2) always @(posedge clk) gen_MINUSEQ[g] = 1'b1; -`ifndef verilator //UNSUPPORTED for (g=8; g<=16; g*=2) always @(posedge clk) gen_TIMESEQ[g] = 1'b1; for (g=16; g>=8; g/=2) always @(posedge clk) gen_DIVEQ[g] = 1'b1; for (g=15; g>8; g%=8) always @(posedge clk) gen_MODEQ[g] = 1'b1; @@ -49,7 +48,6 @@ module t (/*AUTOARG*/ for (g=8; g<=16; g<<=2) always @(posedge clk) gen_SLEFTEQ[g] = 1'b1; for (g=16; g>=8; g>>=2) always @(posedge clk) gen_SRIGHTEQ[g] = 1'b1; for (g=16; g>=8; g>>>=2) always @(posedge clk) gen_SSRIGHTEQ[g] = 1'b1; -`endif endgenerate always @ (posedge clk) begin @@ -78,7 +76,6 @@ module t (/*AUTOARG*/ if (gen_post_MINUSMINUS!== 32'b00000000000000011111111100000000) $stop; if (gen_PLUSEQ !== 32'b00000000000000010101010100000000) $stop; if (gen_MINUSEQ !== 32'b00000000000000010101010100000000) $stop; -`ifndef verilator //UNSUPPORTED if (gen_TIMESEQ !== 32'b00000000000000010000000100000000) $stop; if (gen_DIVEQ !== 32'b00000000000000010000000100000000) $stop; if (gen_MODEQ !== 32'b00000000000000001000000000000000) $stop; @@ -88,7 +85,6 @@ module t (/*AUTOARG*/ if (gen_SLEFTEQ !== 32'b00000000000000000000000100000000) $stop; if (gen_SRIGHTEQ !== 32'b00000000000000010000000000000000) $stop; if (gen_SSRIGHTEQ !== 32'b00000000000000010000000000000000) $stop; -`endif v=0; for (i=8; i<=16; ++i) v[i] = 1'b1; if (v !== 32'b00000000000000011111111100000000) $stop; v=0; for (i=16; i>=8; --i) v[i] = 1'b1; if (v !== 32'b00000000000000011111111100000000) $stop; @@ -96,7 +92,6 @@ module t (/*AUTOARG*/ v=0; for (i=16; i>=8; i--) v[i] = 1'b1; if (v !== 32'b00000000000000011111111100000000) $stop; v=0; for (i=8; i<=16; i+=2) v[i] = 1'b1; if (v !== 32'b00000000000000010101010100000000) $stop; v=0; for (i=16; i>=8; i-=2) v[i] = 1'b1; if (v !== 32'b00000000000000010101010100000000) $stop; -`ifndef verilator //UNSUPPORTED v=0; for (i=8; i<=16; i*=2) v[i] = 1'b1; if (v !== 32'b00000000000000010000000100000000) $stop; v=0; for (i=16; i>=8; i/=2) v[i] = 1'b1; if (v !== 32'b00000000000000010000000100000000) $stop; v=0; for (i=15; i>8; i%=8) v[i] = 1'b1; if (v !== 32'b00000000000000001000000000000000) $stop; @@ -106,7 +101,6 @@ module t (/*AUTOARG*/ v=0; for (i=8; i<=16; i<<=2) v[i] =1'b1; if (v !== 32'b00000000000000000000000100000000) $stop; v=0; for (i=16; i>=8; i>>=2) v[i] =1'b1; if (v !== 32'b00000000000000010000000000000000) $stop; v=0; for (i=16; i>=8; i>>>=2) v[i]=1'b1; if (v !== 32'b00000000000000010000000000000000) $stop; -`endif $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_gen_index.pl b/test_regress/t/t_gen_index.pl index 0a43d363c..6d131b585 100755 --- a/test_regress/t/t_gen_index.pl +++ b/test_regress/t/t_gen_index.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_intdot.pl b/test_regress/t/t_gen_intdot.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_intdot.pl +++ b/test_regress/t/t_gen_intdot.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_intdot2.pl b/test_regress/t/t_gen_intdot2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_intdot2.pl +++ b/test_regress/t/t_gen_intdot2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_local.pl b/test_regress/t/t_gen_local.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_local.pl +++ b/test_regress/t/t_gen_local.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_lsb.pl b/test_regress/t/t_gen_lsb.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_lsb.pl +++ b/test_regress/t/t_gen_lsb.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_mislevel.pl b/test_regress/t/t_gen_mislevel.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_gen_mislevel.pl +++ b/test_regress/t/t_gen_mislevel.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_missing.pl b/test_regress/t/t_gen_missing.pl index 2ede305ee..5b0c42469 100755 --- a/test_regress/t/t_gen_missing.pl +++ b/test_regress/t/t_gen_missing.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_missing_bad.pl b/test_regress/t/t_gen_missing_bad.pl index 7567f33fe..7cd5ea1e5 100755 --- a/test_regress/t/t_gen_missing_bad.pl +++ b/test_regress/t/t_gen_missing_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -12,7 +12,7 @@ scenarios(vlt => 1); top_filename("t/t_gen_missing.v"); -compile( +lint( v_flags2 => ['+define+T_GEN_MISSING_BAD'], fails => 1, expect_filename => $Self->{golden_filename}, diff --git a/test_regress/t/t_gen_self_return.pl b/test_regress/t/t_gen_self_return.pl index e02817219..9a15dd2cc 100755 --- a/test_regress/t/t_gen_self_return.pl +++ b/test_regress/t/t_gen_self_return.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_upscope.pl b/test_regress/t/t_gen_upscope.pl index b4e259e0a..1576259ea 100755 --- a/test_regress/t/t_gen_upscope.pl +++ b/test_regress/t/t_gen_upscope.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_gen_var_bad.pl b/test_regress/t/t_gen_var_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_gen_var_bad.pl +++ b/test_regress/t/t_gen_var_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_generate_fatal_bad.pl b/test_regress/t/t_generate_fatal_bad.pl index 0ac2cd697..0a88b22ae 100755 --- a/test_regress/t/t_generate_fatal_bad.pl +++ b/test_regress/t/t_generate_fatal_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_genfor_hier.pl b/test_regress/t/t_genfor_hier.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_genfor_hier.pl +++ b/test_regress/t/t_genfor_hier.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_genvar_for_bad.pl b/test_regress/t/t_genvar_for_bad.pl index e2ea28d29..27159da5b 100755 --- a/test_regress/t/t_genvar_for_bad.pl +++ b/test_regress/t/t_genvar_for_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_genvar_misuse_bad.pl b/test_regress/t/t_genvar_misuse_bad.pl index 31116e9bd..73b58f253 100755 --- a/test_regress/t/t_genvar_misuse_bad.pl +++ b/test_regress/t/t_genvar_misuse_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_hierarchy_identifier.pl b/test_regress/t/t_hierarchy_identifier.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_hierarchy_identifier.pl +++ b/test_regress/t/t_hierarchy_identifier.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_hierarchy_identifier_bad.pl b/test_regress/t/t_hierarchy_identifier_bad.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_hierarchy_identifier_bad.pl +++ b/test_regress/t/t_hierarchy_identifier_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_hierarchy_unnamed.pl b/test_regress/t/t_hierarchy_unnamed.pl index a4d74c0ba..13c6e2b71 100755 --- a/test_regress/t/t_hierarchy_unnamed.pl +++ b/test_regress/t/t_hierarchy_unnamed.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_if_deep.pl b/test_regress/t/t_if_deep.pl index d6841bed0..7d49cd2cd 100755 --- a/test_regress/t/t_if_deep.pl +++ b/test_regress/t/t_if_deep.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_if_swap.pl b/test_regress/t/t_if_swap.pl index 29a7fc65c..da2e37bda 100755 --- a/test_regress/t/t_if_swap.pl +++ b/test_regress/t/t_if_swap.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_iff.pl b/test_regress/t/t_iff.pl index 63ac7c585..23d25a694 100755 --- a/test_regress/t/t_iff.pl +++ b/test_regress/t/t_iff.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_increment_bad.out b/test_regress/t/t_increment_bad.out new file mode 100644 index 000000000..5664201ed --- /dev/null +++ b/test_regress/t/t_increment_bad.out @@ -0,0 +1,22 @@ +%Error: t/t_increment_bad.v:15:31: Unsupported: Incrementation in this context. + 15 | if (0 && test_string[pos++] != "e"); + | ^~ +%Error: t/t_increment_bad.v:16:19: Unsupported: Incrementation in this context. + 16 | if (1 || pos-- != 1); + | ^~ +%Error: t/t_increment_bad.v:18:17: Unsupported: Incrementation in this context. + 18 | if (a <-> --b); + | ^~ +%Error: t/t_increment_bad.v:19:16: Unsupported: Incrementation in this context. + 19 | if (0 -> ++b); + | ^~ +%Error: t/t_increment_bad.v:21:24: Unsupported: Incrementation in this context. + 21 | pos = (a > 0) ? a++ : --b; + | ^~ +%Error: t/t_increment_bad.v:21:29: Unsupported: Incrementation in this context. + 21 | pos = (a > 0) ? a++ : --b; + | ^~ +%Error: t/t_increment_bad.v:23:24: Unsupported: Incrementation in this context. + 23 | pos = array[0][0]++; + | ^~ +%Error: Exiting due to diff --git a/test_regress/t/t_increment_bad.pl b/test_regress/t/t_increment_bad.pl new file mode 100755 index 000000000..385b304e3 --- /dev/null +++ b/test_regress/t/t_increment_bad.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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. + +scenarios(vlt => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_increment_bad.v b/test_regress/t/t_increment_bad.v new file mode 100644 index 000000000..7ce03d704 --- /dev/null +++ b/test_regress/t/t_increment_bad.v @@ -0,0 +1,25 @@ +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + int pos; + int a; + int b; + int array[2][2] = '{ '{0, 1}, '{2, 3}}; + + string test_string = "abcd"; + + initial begin + if (0 && test_string[pos++] != "e"); + if (1 || pos-- != 1); + + if (a <-> --b); + if (0 -> ++b); + + pos = (a > 0) ? a++ : --b; + + pos = array[0][0]++; + end +endmodule diff --git a/test_regress/t/t_init_concat.pl b/test_regress/t/t_init_concat.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_init_concat.pl +++ b/test_regress/t/t_init_concat.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_initarray_nonarray.pl b/test_regress/t/t_initarray_nonarray.pl index d1bf185c9..552bd97db 100755 --- a/test_regress/t/t_initarray_nonarray.pl +++ b/test_regress/t/t_initarray_nonarray.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_initial.pl b/test_regress/t/t_initial.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_initial.pl +++ b/test_regress/t/t_initial.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_initial_dlyass.pl b/test_regress/t/t_initial_dlyass.pl index e1c047468..b15591906 100755 --- a/test_regress/t/t_initial_dlyass.pl +++ b/test_regress/t/t_initial_dlyass.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_initial_dlyass_bad.pl b/test_regress/t/t_initial_dlyass_bad.pl index 073d596ca..e9702830c 100755 --- a/test_regress/t/t_initial_dlyass_bad.pl +++ b/test_regress/t/t_initial_dlyass_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_initial_edge.pl b/test_regress/t/t_initial_edge.pl index 2290dcdab..3c491f443 100755 --- a/test_regress/t/t_initial_edge.pl +++ b/test_regress/t/t_initial_edge.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_initial_edge_bad.pl b/test_regress/t/t_initial_edge_bad.pl index 713dcb8e1..8d882c587 100755 --- a/test_regress/t/t_initial_edge_bad.pl +++ b/test_regress/t/t_initial_edge_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inside.pl b/test_regress/t/t_inside.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_inside.pl +++ b/test_regress/t/t_inside.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inside_wild.pl b/test_regress/t/t_inside_wild.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_inside_wild.pl +++ b/test_regress/t/t_inside_wild.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_aport.pl b/test_regress/t/t_inst_aport.pl index 0a056ddda..9a383863d 100755 --- a/test_regress/t/t_inst_aport.pl +++ b/test_regress/t/t_inst_aport.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_array_bad.pl b/test_regress/t/t_inst_array_bad.pl index f3dd1d2a1..35d749208 100755 --- a/test_regress/t/t_inst_array_bad.pl +++ b/test_regress/t/t_inst_array_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_array_connect.pl b/test_regress/t/t_inst_array_connect.pl index e02817219..9a15dd2cc 100755 --- a/test_regress/t/t_inst_array_connect.pl +++ b/test_regress/t/t_inst_array_connect.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_array_inl0.pl b/test_regress/t/t_inst_array_inl0.pl index 2f246d648..98f84bb24 100755 --- a/test_regress/t/t_inst_array_inl0.pl +++ b/test_regress/t/t_inst_array_inl0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_array_inl1.pl b/test_regress/t/t_inst_array_inl1.pl index d92c6d47e..024282cc4 100755 --- a/test_regress/t/t_inst_array_inl1.pl +++ b/test_regress/t/t_inst_array_inl1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_array_partial.pl b/test_regress/t/t_inst_array_partial.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_inst_array_partial.pl +++ b/test_regress/t/t_inst_array_partial.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_ccall.pl b/test_regress/t/t_inst_ccall.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_inst_ccall.pl +++ b/test_regress/t/t_inst_ccall.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_comma_inl0.pl b/test_regress/t/t_inst_comma_inl0.pl index 426de0c8a..9e566919a 100755 --- a/test_regress/t/t_inst_comma_inl0.pl +++ b/test_regress/t/t_inst_comma_inl0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_comma_inl1.pl b/test_regress/t/t_inst_comma_inl1.pl index 3619a2a4a..a083d104c 100755 --- a/test_regress/t/t_inst_comma_inl1.pl +++ b/test_regress/t/t_inst_comma_inl1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_darray.pl b/test_regress/t/t_inst_darray.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_inst_darray.pl +++ b/test_regress/t/t_inst_darray.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_dearray_slice.pl b/test_regress/t/t_inst_dearray_slice.pl index e02817219..9a15dd2cc 100755 --- a/test_regress/t/t_inst_dearray_slice.pl +++ b/test_regress/t/t_inst_dearray_slice.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_dff.pl b/test_regress/t/t_inst_dff.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_inst_dff.pl +++ b/test_regress/t/t_inst_dff.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_dtree_inla.pl b/test_regress/t/t_inst_dtree_inla.pl index 12a6bfa87..01bccbe35 100755 --- a/test_regress/t/t_inst_dtree_inla.pl +++ b/test_regress/t/t_inst_dtree_inla.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_dtree_inlab.pl b/test_regress/t/t_inst_dtree_inlab.pl index 0d3968897..b12d4ee12 100755 --- a/test_regress/t/t_inst_dtree_inlab.pl +++ b/test_regress/t/t_inst_dtree_inlab.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_dtree_inlac.pl b/test_regress/t/t_inst_dtree_inlac.pl index 266c21e6a..717db06d6 100755 --- a/test_regress/t/t_inst_dtree_inlac.pl +++ b/test_regress/t/t_inst_dtree_inlac.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_dtree_inlad.pl b/test_regress/t/t_inst_dtree_inlad.pl index a3252aac2..49cf78d93 100755 --- a/test_regress/t/t_inst_dtree_inlad.pl +++ b/test_regress/t/t_inst_dtree_inlad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_dtree_inlb.pl b/test_regress/t/t_inst_dtree_inlb.pl index 37140d54c..5db311cbc 100755 --- a/test_regress/t/t_inst_dtree_inlb.pl +++ b/test_regress/t/t_inst_dtree_inlb.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_dtree_inlbc.pl b/test_regress/t/t_inst_dtree_inlbc.pl index 220cff813..935883d92 100755 --- a/test_regress/t/t_inst_dtree_inlbc.pl +++ b/test_regress/t/t_inst_dtree_inlbc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_dtree_inlbd.pl b/test_regress/t/t_inst_dtree_inlbd.pl index a1922dee7..381918f5c 100755 --- a/test_regress/t/t_inst_dtree_inlbd.pl +++ b/test_regress/t/t_inst_dtree_inlbd.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_dtree_inlc.pl b/test_regress/t/t_inst_dtree_inlc.pl index 6aec14efe..f86b44eef 100755 --- a/test_regress/t/t_inst_dtree_inlc.pl +++ b/test_regress/t/t_inst_dtree_inlc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_dtree_inlcd.pl b/test_regress/t/t_inst_dtree_inlcd.pl index 3ea63c940..67ad049e5 100755 --- a/test_regress/t/t_inst_dtree_inlcd.pl +++ b/test_regress/t/t_inst_dtree_inlcd.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_dtree_inld.pl b/test_regress/t/t_inst_dtree_inld.pl index 73cd4b063..f61782a04 100755 --- a/test_regress/t/t_inst_dtree_inld.pl +++ b/test_regress/t/t_inst_dtree_inld.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_first.pl b/test_regress/t/t_inst_first.pl index 214a71ff8..987de13d5 100755 --- a/test_regress/t/t_inst_first.pl +++ b/test_regress/t/t_inst_first.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_implicit.pl b/test_regress/t/t_inst_implicit.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_inst_implicit.pl +++ b/test_regress/t/t_inst_implicit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_long_bad.pl b/test_regress/t/t_inst_long_bad.pl index 85fe7605d..73eaa142a 100755 --- a/test_regress/t/t_inst_long_bad.pl +++ b/test_regress/t/t_inst_long_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_misarray2_bad.pl b/test_regress/t/t_inst_misarray2_bad.pl index 32c62a917..7df095a97 100755 --- a/test_regress/t/t_inst_misarray2_bad.pl +++ b/test_regress/t/t_inst_misarray2_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_misarray_bad.pl b/test_regress/t/t_inst_misarray_bad.pl index 32c62a917..7df095a97 100755 --- a/test_regress/t/t_inst_misarray_bad.pl +++ b/test_regress/t/t_inst_misarray_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_mism.pl b/test_regress/t/t_inst_mism.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_inst_mism.pl +++ b/test_regress/t/t_inst_mism.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_missing.pl b/test_regress/t/t_inst_missing.pl index 1be9716bd..47e83b415 100755 --- a/test_regress/t/t_inst_missing.pl +++ b/test_regress/t/t_inst_missing.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_missing_bad.pl b/test_regress/t/t_inst_missing_bad.pl index 94c7e9d90..ebce1e9f0 100755 --- a/test_regress/t/t_inst_missing_bad.pl +++ b/test_regress/t/t_inst_missing_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_mnpipe.pl b/test_regress/t/t_inst_mnpipe.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_inst_mnpipe.pl +++ b/test_regress/t/t_inst_mnpipe.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_notunsized.pl b/test_regress/t/t_inst_notunsized.pl index f36d03dff..4f4923342 100755 --- a/test_regress/t/t_inst_notunsized.pl +++ b/test_regress/t/t_inst_notunsized.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_overwide.pl b/test_regress/t/t_inst_overwide.pl index 9fe760e8d..741f0f044 100755 --- a/test_regress/t/t_inst_overwide.pl +++ b/test_regress/t/t_inst_overwide.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_overwide_bad.pl b/test_regress/t/t_inst_overwide_bad.pl index 3226e8e46..9bb70c819 100755 --- a/test_regress/t/t_inst_overwide_bad.pl +++ b/test_regress/t/t_inst_overwide_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_port_array.pl b/test_regress/t/t_inst_port_array.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_inst_port_array.pl +++ b/test_regress/t/t_inst_port_array.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_prepost.pl b/test_regress/t/t_inst_prepost.pl index d1bf185c9..552bd97db 100755 --- a/test_regress/t/t_inst_prepost.pl +++ b/test_regress/t/t_inst_prepost.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_recurse2_bad.pl b/test_regress/t/t_inst_recurse2_bad.pl index b1b5983b1..53e145105 100755 --- a/test_regress/t/t_inst_recurse2_bad.pl +++ b/test_regress/t/t_inst_recurse2_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_inst_recurse_bad.pl b/test_regress/t/t_inst_recurse_bad.pl index b1b5983b1..53e145105 100755 --- a/test_regress/t/t_inst_recurse_bad.pl +++ b/test_regress/t/t_inst_recurse_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_inst_signed.pl b/test_regress/t/t_inst_signed.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_inst_signed.pl +++ b/test_regress/t/t_inst_signed.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_signed1.pl b/test_regress/t/t_inst_signed1.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_inst_signed1.pl +++ b/test_regress/t/t_inst_signed1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_slice.pl b/test_regress/t/t_inst_slice.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_inst_slice.pl +++ b/test_regress/t/t_inst_slice.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_slice_noinl.pl b/test_regress/t/t_inst_slice_noinl.pl index e0808c054..11f75c752 100755 --- a/test_regress/t/t_inst_slice_noinl.pl +++ b/test_regress/t/t_inst_slice_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_slice_part_select.pl b/test_regress/t/t_inst_slice_part_select.pl new file mode 100755 index 000000000..9a15dd2cc --- /dev/null +++ b/test_regress/t/t_inst_slice_part_select.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 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 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_inst_slice_part_select.v b/test_regress/t/t_inst_slice_part_select.v new file mode 100644 index 000000000..3c837e0df --- /dev/null +++ b/test_regress/t/t_inst_slice_part_select.v @@ -0,0 +1,93 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by engr248. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + wire [31:0] in = 0; + wire [31:0] out; + + Test test( + .out(out[31:0]), + .clk(clk), + .in (in[31:0]) + ); + + always @ (posedge clk) begin + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule + +interface Intf (); +endinterface + +module Select + #( + parameter int NUM_MASTER = 1 + ) + ( + Intf Upstream, + Intf Downstream[NUM_MASTER] + ); +endmodule + +module Crossbar + #( + parameter int NUM_MASTER = 1, + parameter int NUM_SLAVE = 1 + ) + ( + Intf Masters[NUM_MASTER] + ); + + Intf selectOut[(NUM_MASTER * (NUM_SLAVE))-1 : 0](); + + + genvar i; + + for (i = 0; i < NUM_MASTER; i = i + 1) begin + Select #( + .NUM_MASTER(NUM_SLAVE) + ) + select_inst ( + .Upstream(Masters[i]), + // Following line seems to trigger a bad calculation for dimension where port + // is calculated as width 1 (correctly) and expression is calculated as NUM_MASTER*NUM_SLAVE rather than NUM_SLAVE + .Downstream(selectOut[(i)*(NUM_SLAVE) +: (NUM_SLAVE)]) + // The following line works as intended and should be functionally identical to the above line +// .Downstream(selectOut[(i+1)*(NUM_SLAVE)-1 : i*(NUM_SLAVE)]) + ); + end + +endmodule + +module Test + ( + input clk, + input [31:0] in, + output reg [31:0] out + ); + + always @(posedge clk) begin + out <= in; + end + + Intf MST[10](); + + Crossbar #( + .NUM_MASTER(10), + .NUM_SLAVE(1) + ) + xbar_inst ( + .Masters(MST) + ); + +endmodule diff --git a/test_regress/t/t_inst_sv.pl b/test_regress/t/t_inst_sv.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_inst_sv.pl +++ b/test_regress/t/t_inst_sv.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_tree_inl0_pub0.pl b/test_regress/t/t_inst_tree_inl0_pub0.pl index cdc077d31..6037619f7 100755 --- a/test_regress/t/t_inst_tree_inl0_pub0.pl +++ b/test_regress/t/t_inst_tree_inl0_pub0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_tree_inl0_pub1.pl b/test_regress/t/t_inst_tree_inl0_pub1.pl index d3958b0fa..182cfc40e 100755 --- a/test_regress/t/t_inst_tree_inl0_pub1.pl +++ b/test_regress/t/t_inst_tree_inl0_pub1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_tree_inl0_pub1_norelcfuncs.pl b/test_regress/t/t_inst_tree_inl0_pub1_norelcfuncs.pl index 4a0c82b5a..679b4369f 100755 --- a/test_regress/t/t_inst_tree_inl0_pub1_norelcfuncs.pl +++ b/test_regress/t/t_inst_tree_inl0_pub1_norelcfuncs.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_tree_inl1_pub0.pl b/test_regress/t/t_inst_tree_inl1_pub0.pl index 9e0524e89..ec48a4e06 100755 --- a/test_regress/t/t_inst_tree_inl1_pub0.pl +++ b/test_regress/t/t_inst_tree_inl1_pub0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_tree_inl1_pub1.pl b/test_regress/t/t_inst_tree_inl1_pub1.pl index ed3c5580e..624135b06 100755 --- a/test_regress/t/t_inst_tree_inl1_pub1.pl +++ b/test_regress/t/t_inst_tree_inl1_pub1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_v2k.pl b/test_regress/t/t_inst_v2k.pl index 8e2ba933f..377bc93b2 100755 --- a/test_regress/t/t_inst_v2k.pl +++ b/test_regress/t/t_inst_v2k.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_inst_wideconst.pl b/test_regress/t/t_inst_wideconst.pl index 0373cc976..83fe0eda2 100755 --- a/test_regress/t/t_inst_wideconst.pl +++ b/test_regress/t/t_inst_wideconst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface.pl b/test_regress/t/t_interface.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_interface.pl +++ b/test_regress/t/t_interface.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface1.pl b/test_regress/t/t_interface1.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface1.pl +++ b/test_regress/t/t_interface1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface1_modport.pl b/test_regress/t/t_interface1_modport.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface1_modport.pl +++ b/test_regress/t/t_interface1_modport.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface1_modport_nansi.pl b/test_regress/t/t_interface1_modport_nansi.pl index 9a17be84f..3f71acf60 100755 --- a/test_regress/t/t_interface1_modport_nansi.pl +++ b/test_regress/t/t_interface1_modport_nansi.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface1_modport_noinl.pl b/test_regress/t/t_interface1_modport_noinl.pl index 9ccb327da..b077bef4e 100755 --- a/test_regress/t/t_interface1_modport_noinl.pl +++ b/test_regress/t/t_interface1_modport_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface1_modport_trace.pl b/test_regress/t/t_interface1_modport_trace.pl index 54ac1c910..cb728321b 100755 --- a/test_regress/t/t_interface1_modport_trace.pl +++ b/test_regress/t/t_interface1_modport_trace.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface1_noinl.pl b/test_regress/t/t_interface1_noinl.pl index 18fdf1bc2..3c9d8d316 100755 --- a/test_regress/t/t_interface1_noinl.pl +++ b/test_regress/t/t_interface1_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface2.pl b/test_regress/t/t_interface2.pl index 3921afc0f..c2f17b6ac 100755 --- a/test_regress/t/t_interface2.pl +++ b/test_regress/t/t_interface2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface2_noinl.pl b/test_regress/t/t_interface2_noinl.pl index 3ed910af1..57b72e7a7 100755 --- a/test_regress/t/t_interface2_noinl.pl +++ b/test_regress/t/t_interface2_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_array.pl b/test_regress/t/t_interface_array.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_interface_array.pl +++ b/test_regress/t/t_interface_array.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_array_bad.pl b/test_regress/t/t_interface_array_bad.pl index dba098eb6..a60503a1f 100755 --- a/test_regress/t/t_interface_array_bad.pl +++ b/test_regress/t/t_interface_array_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_interface_array_modport.pl b/test_regress/t/t_interface_array_modport.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_interface_array_modport.pl +++ b/test_regress/t/t_interface_array_modport.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_array_nocolon.pl b/test_regress/t/t_interface_array_nocolon.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_interface_array_nocolon.pl +++ b/test_regress/t/t_interface_array_nocolon.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_array_nocolon_bad.pl b/test_regress/t/t_interface_array_nocolon_bad.pl index 056b9974f..59ba0d6c6 100755 --- a/test_regress/t/t_interface_array_nocolon_bad.pl +++ b/test_regress/t/t_interface_array_nocolon_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_array_noinl.pl b/test_regress/t/t_interface_array_noinl.pl index 90b52bc1a..02bf8fd89 100755 --- a/test_regress/t/t_interface_array_noinl.pl +++ b/test_regress/t/t_interface_array_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_arraymux.pl b/test_regress/t/t_interface_arraymux.pl index a4d74c0ba..13c6e2b71 100755 --- a/test_regress/t/t_interface_arraymux.pl +++ b/test_regress/t/t_interface_arraymux.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_asvar_bad.pl b/test_regress/t/t_interface_asvar_bad.pl index 8f0a03228..df9afd1d4 100755 --- a/test_regress/t/t_interface_asvar_bad.pl +++ b/test_regress/t/t_interface_asvar_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_interface_bind_public.pl b/test_regress/t/t_interface_bind_public.pl index 0373cc976..83fe0eda2 100755 --- a/test_regress/t/t_interface_bind_public.pl +++ b/test_regress/t/t_interface_bind_public.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_down.pl b/test_regress/t/t_interface_down.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_down.pl +++ b/test_regress/t/t_interface_down.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_down_gen.pl b/test_regress/t/t_interface_down_gen.pl index b0147e5ba..d0a85e8ea 100755 --- a/test_regress/t/t_interface_down_gen.pl +++ b/test_regress/t/t_interface_down_gen.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_down_inla.pl b/test_regress/t/t_interface_down_inla.pl index 94da72fa9..9a06eafa5 100755 --- a/test_regress/t/t_interface_down_inla.pl +++ b/test_regress/t/t_interface_down_inla.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_down_inlab.pl b/test_regress/t/t_interface_down_inlab.pl index e3058afb3..9ea954b1b 100755 --- a/test_regress/t/t_interface_down_inlab.pl +++ b/test_regress/t/t_interface_down_inlab.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_down_inlac.pl b/test_regress/t/t_interface_down_inlac.pl index 87c1d0557..4ca7f2496 100755 --- a/test_regress/t/t_interface_down_inlac.pl +++ b/test_regress/t/t_interface_down_inlac.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_down_inlad.pl b/test_regress/t/t_interface_down_inlad.pl index 5c1aa70b5..0071e1864 100755 --- a/test_regress/t/t_interface_down_inlad.pl +++ b/test_regress/t/t_interface_down_inlad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_down_inlb.pl b/test_regress/t/t_interface_down_inlb.pl index 12252f189..ef94ea94f 100755 --- a/test_regress/t/t_interface_down_inlb.pl +++ b/test_regress/t/t_interface_down_inlb.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_down_inlbc.pl b/test_regress/t/t_interface_down_inlbc.pl index 71ec4de4e..a2a12be41 100755 --- a/test_regress/t/t_interface_down_inlbc.pl +++ b/test_regress/t/t_interface_down_inlbc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_down_inlbd.pl b/test_regress/t/t_interface_down_inlbd.pl index 3b0825c62..609238c88 100755 --- a/test_regress/t/t_interface_down_inlbd.pl +++ b/test_regress/t/t_interface_down_inlbd.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_down_inlc.pl b/test_regress/t/t_interface_down_inlc.pl index 3ca34b12c..d7f77f2c9 100755 --- a/test_regress/t/t_interface_down_inlc.pl +++ b/test_regress/t/t_interface_down_inlc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_down_inlcd.pl b/test_regress/t/t_interface_down_inlcd.pl index 097f7d332..22d785305 100755 --- a/test_regress/t/t_interface_down_inlcd.pl +++ b/test_regress/t/t_interface_down_inlcd.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_down_inld.pl b/test_regress/t/t_interface_down_inld.pl index 93712a32c..b484ee157 100755 --- a/test_regress/t/t_interface_down_inld.pl +++ b/test_regress/t/t_interface_down_inld.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_down_noinl.pl b/test_regress/t/t_interface_down_noinl.pl index a1f024b08..fb03fc988 100755 --- a/test_regress/t/t_interface_down_noinl.pl +++ b/test_regress/t/t_interface_down_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_dups.pl b/test_regress/t/t_interface_dups.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_dups.pl +++ b/test_regress/t/t_interface_dups.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen.pl b/test_regress/t/t_interface_gen.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_gen.pl +++ b/test_regress/t/t_interface_gen.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen10.pl b/test_regress/t/t_interface_gen10.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_gen10.pl +++ b/test_regress/t/t_interface_gen10.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen10_noinl.pl b/test_regress/t/t_interface_gen10_noinl.pl index 89cfa9d60..e5c3f22c5 100755 --- a/test_regress/t/t_interface_gen10_noinl.pl +++ b/test_regress/t/t_interface_gen10_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen11.pl b/test_regress/t/t_interface_gen11.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_gen11.pl +++ b/test_regress/t/t_interface_gen11.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen11_noinl.pl b/test_regress/t/t_interface_gen11_noinl.pl index 378bfeff4..82a6a9a27 100755 --- a/test_regress/t/t_interface_gen11_noinl.pl +++ b/test_regress/t/t_interface_gen11_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen12.pl b/test_regress/t/t_interface_gen12.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_gen12.pl +++ b/test_regress/t/t_interface_gen12.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen12_noinl.pl b/test_regress/t/t_interface_gen12_noinl.pl index 32dfbfb7a..c3f59ba19 100755 --- a/test_regress/t/t_interface_gen12_noinl.pl +++ b/test_regress/t/t_interface_gen12_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen2.pl b/test_regress/t/t_interface_gen2.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_gen2.pl +++ b/test_regress/t/t_interface_gen2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen2_collision.pl b/test_regress/t/t_interface_gen2_collision.pl index 38e9eed6b..93d1979f9 100755 --- a/test_regress/t/t_interface_gen2_collision.pl +++ b/test_regress/t/t_interface_gen2_collision.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen2_noinl.pl b/test_regress/t/t_interface_gen2_noinl.pl index 477887775..fc7c4bfb1 100755 --- a/test_regress/t/t_interface_gen2_noinl.pl +++ b/test_regress/t/t_interface_gen2_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen3.pl b/test_regress/t/t_interface_gen3.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_gen3.pl +++ b/test_regress/t/t_interface_gen3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen3_collision.pl b/test_regress/t/t_interface_gen3_collision.pl index efbdcc7f8..9a52345e3 100755 --- a/test_regress/t/t_interface_gen3_collision.pl +++ b/test_regress/t/t_interface_gen3_collision.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen3_noinl.pl b/test_regress/t/t_interface_gen3_noinl.pl index 1895ad227..e49dfc39a 100755 --- a/test_regress/t/t_interface_gen3_noinl.pl +++ b/test_regress/t/t_interface_gen3_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen4.pl b/test_regress/t/t_interface_gen4.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_gen4.pl +++ b/test_regress/t/t_interface_gen4.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen4_noinl.pl b/test_regress/t/t_interface_gen4_noinl.pl index 4e1616c21..4a0b00930 100755 --- a/test_regress/t/t_interface_gen4_noinl.pl +++ b/test_regress/t/t_interface_gen4_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen5.pl b/test_regress/t/t_interface_gen5.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_gen5.pl +++ b/test_regress/t/t_interface_gen5.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen5_noinl.pl b/test_regress/t/t_interface_gen5_noinl.pl index a3a82fe7f..0873ce9c5 100755 --- a/test_regress/t/t_interface_gen5_noinl.pl +++ b/test_regress/t/t_interface_gen5_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen6.pl b/test_regress/t/t_interface_gen6.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_gen6.pl +++ b/test_regress/t/t_interface_gen6.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen6_noinl.pl b/test_regress/t/t_interface_gen6_noinl.pl index af6821514..4c42c6797 100755 --- a/test_regress/t/t_interface_gen6_noinl.pl +++ b/test_regress/t/t_interface_gen6_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen7.pl b/test_regress/t/t_interface_gen7.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_gen7.pl +++ b/test_regress/t/t_interface_gen7.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen7_noinl.pl b/test_regress/t/t_interface_gen7_noinl.pl index f0b6c523c..27cb3ea61 100755 --- a/test_regress/t/t_interface_gen7_noinl.pl +++ b/test_regress/t/t_interface_gen7_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen8.pl b/test_regress/t/t_interface_gen8.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_gen8.pl +++ b/test_regress/t/t_interface_gen8.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen8_noinl.pl b/test_regress/t/t_interface_gen8_noinl.pl index 0275b2504..ba3b2b132 100755 --- a/test_regress/t/t_interface_gen8_noinl.pl +++ b/test_regress/t/t_interface_gen8_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen9.pl b/test_regress/t/t_interface_gen9.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_gen9.pl +++ b/test_regress/t/t_interface_gen9.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen9_noinl.pl b/test_regress/t/t_interface_gen9_noinl.pl index e3f52153b..48f4eb8be 100755 --- a/test_regress/t/t_interface_gen9_noinl.pl +++ b/test_regress/t/t_interface_gen9_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_gen_noinl.pl b/test_regress/t/t_interface_gen_noinl.pl index cefc49c45..5813d42eb 100755 --- a/test_regress/t/t_interface_gen_noinl.pl +++ b/test_regress/t/t_interface_gen_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_inl.pl b/test_regress/t/t_interface_inl.pl index abb511f5e..efb67ed7f 100755 --- a/test_regress/t/t_interface_inl.pl +++ b/test_regress/t/t_interface_inl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_mismodport_bad.pl b/test_regress/t/t_interface_mismodport_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_interface_mismodport_bad.pl +++ b/test_regress/t/t_interface_mismodport_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_missing_bad.pl b/test_regress/t/t_interface_missing_bad.pl index dba098eb6..1362bf74f 100755 --- a/test_regress/t/t_interface_missing_bad.pl +++ b/test_regress/t/t_interface_missing_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_modport.pl b/test_regress/t/t_interface_modport.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_modport.pl +++ b/test_regress/t/t_interface_modport.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_modport_bad.pl b/test_regress/t/t_interface_modport_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_interface_modport_bad.pl +++ b/test_regress/t/t_interface_modport_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_modport_dir_bad.pl b/test_regress/t/t_interface_modport_dir_bad.pl index 1f547e042..f6a127931 100755 --- a/test_regress/t/t_interface_modport_dir_bad.pl +++ b/test_regress/t/t_interface_modport_dir_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_modport_export.pl b/test_regress/t/t_interface_modport_export.pl index 4513b2353..6d4d94235 100755 --- a/test_regress/t/t_interface_modport_export.pl +++ b/test_regress/t/t_interface_modport_export.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_modport_import.pl b/test_regress/t/t_interface_modport_import.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_interface_modport_import.pl +++ b/test_regress/t/t_interface_modport_import.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_modport_import_noinl.pl b/test_regress/t/t_interface_modport_import_noinl.pl index e78a0753f..3821fef11 100755 --- a/test_regress/t/t_interface_modport_import_noinl.pl +++ b/test_regress/t/t_interface_modport_import_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_modport_inl.pl b/test_regress/t/t_interface_modport_inl.pl index 88a6d9a1e..9afcd9cdd 100755 --- a/test_regress/t/t_interface_modport_inl.pl +++ b/test_regress/t/t_interface_modport_inl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_modport_noinl.pl b/test_regress/t/t_interface_modport_noinl.pl index 0c34a3249..4c051df1a 100755 --- a/test_regress/t/t_interface_modport_noinl.pl +++ b/test_regress/t/t_interface_modport_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_modportlist.pl b/test_regress/t/t_interface_modportlist.pl index 21d10121b..f3e6a6cf4 100755 --- a/test_regress/t/t_interface_modportlist.pl +++ b/test_regress/t/t_interface_modportlist.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_mp_func.pl b/test_regress/t/t_interface_mp_func.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_interface_mp_func.pl +++ b/test_regress/t/t_interface_mp_func.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_mp_func_noinl.pl b/test_regress/t/t_interface_mp_func_noinl.pl index d2a19c1bb..432a7308a 100755 --- a/test_regress/t/t_interface_mp_func_noinl.pl +++ b/test_regress/t/t_interface_mp_func_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_nest.pl b/test_regress/t/t_interface_nest.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_interface_nest.pl +++ b/test_regress/t/t_interface_nest.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_nest_noinl.pl b/test_regress/t/t_interface_nest_noinl.pl index f2544ca38..9d88a39a0 100755 --- a/test_regress/t/t_interface_nest_noinl.pl +++ b/test_regress/t/t_interface_nest_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_noinl.pl b/test_regress/t/t_interface_noinl.pl index 3c5d31d75..52cb09c98 100755 --- a/test_regress/t/t_interface_noinl.pl +++ b/test_regress/t/t_interface_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_param1.pl b/test_regress/t/t_interface_param1.pl index a4d74c0ba..13c6e2b71 100755 --- a/test_regress/t/t_interface_param1.pl +++ b/test_regress/t/t_interface_param1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_param2.pl b/test_regress/t/t_interface_param2.pl index d275261b6..2319ed539 100755 --- a/test_regress/t/t_interface_param2.pl +++ b/test_regress/t/t_interface_param2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_param_acc_bits.pl b/test_regress/t/t_interface_param_acc_bits.pl index 40b4c78de..1c9cd303c 100755 --- a/test_regress/t/t_interface_param_acc_bits.pl +++ b/test_regress/t/t_interface_param_acc_bits.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_param_another_bad.pl b/test_regress/t/t_interface_param_another_bad.pl index dba098eb6..a60503a1f 100755 --- a/test_regress/t/t_interface_param_another_bad.pl +++ b/test_regress/t/t_interface_param_another_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_interface_param_loop_bad.pl b/test_regress/t/t_interface_param_loop_bad.pl index 7b55cbb24..538506b75 100755 --- a/test_regress/t/t_interface_param_loop_bad.pl +++ b/test_regress/t/t_interface_param_loop_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,9 +10,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di $Self->{vlt_all} and unsupported("Verilator unsupported, bug1626"); -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_interface_parameter_access.pl b/test_regress/t/t_interface_parameter_access.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_interface_parameter_access.pl +++ b/test_regress/t/t_interface_parameter_access.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_parent_scope_bad.pl b/test_regress/t/t_interface_parent_scope_bad.pl index c68596a09..85d8dd9a3 100755 --- a/test_regress/t/t_interface_parent_scope_bad.pl +++ b/test_regress/t/t_interface_parent_scope_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_ref_trace.pl b/test_regress/t/t_interface_ref_trace.pl index 0614cda35..8d5e2c07a 100755 --- a/test_regress/t/t_interface_ref_trace.pl +++ b/test_regress/t/t_interface_ref_trace.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_ref_trace_fst.pl b/test_regress/t/t_interface_ref_trace_fst.pl index c4aed592a..69b5cc2a3 100755 --- a/test_regress/t/t_interface_ref_trace_fst.pl +++ b/test_regress/t/t_interface_ref_trace_fst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_ref_trace_inla.pl b/test_regress/t/t_interface_ref_trace_inla.pl index a07280688..bbcf8c7d1 100755 --- a/test_regress/t/t_interface_ref_trace_inla.pl +++ b/test_regress/t/t_interface_ref_trace_inla.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_ref_trace_inlab.pl b/test_regress/t/t_interface_ref_trace_inlab.pl index ad9f1c195..35e91ccf0 100755 --- a/test_regress/t/t_interface_ref_trace_inlab.pl +++ b/test_regress/t/t_interface_ref_trace_inlab.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_ref_trace_inlb.pl b/test_regress/t/t_interface_ref_trace_inlb.pl index 570742b4b..fd06fd865 100755 --- a/test_regress/t/t_interface_ref_trace_inlb.pl +++ b/test_regress/t/t_interface_ref_trace_inlb.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_size_bad.pl b/test_regress/t/t_interface_size_bad.pl index dba098eb6..a60503a1f 100755 --- a/test_regress/t/t_interface_size_bad.pl +++ b/test_regress/t/t_interface_size_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_interface_star.pl b/test_regress/t/t_interface_star.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_star.pl +++ b/test_regress/t/t_interface_star.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_top_bad.pl b/test_regress/t/t_interface_top_bad.pl index ddbffc478..07964a1b5 100755 --- a/test_regress/t/t_interface_top_bad.pl +++ b/test_regress/t/t_interface_top_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_twod.pl b/test_regress/t/t_interface_twod.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_interface_twod.pl +++ b/test_regress/t/t_interface_twod.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_twod_noinl.pl b/test_regress/t/t_interface_twod_noinl.pl index d1fcc0f24..18f0adf62 100755 --- a/test_regress/t/t_interface_twod_noinl.pl +++ b/test_regress/t/t_interface_twod_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_typo_bad.pl b/test_regress/t/t_interface_typo_bad.pl index a6e92b237..e30ce1ac9 100755 --- a/test_regress/t/t_interface_typo_bad.pl +++ b/test_regress/t/t_interface_typo_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_interface_wrong_bad.pl b/test_regress/t/t_interface_wrong_bad.pl index dba098eb6..a60503a1f 100755 --- a/test_regress/t/t_interface_wrong_bad.pl +++ b/test_regress/t/t_interface_wrong_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_langext_1.pl b/test_regress/t/t_langext_1.pl index 5960a700c..98a9e0a4a 100755 --- a/test_regress/t/t_langext_1.pl +++ b/test_regress/t/t_langext_1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_langext_1_bad.pl b/test_regress/t/t_langext_1_bad.pl index 8eafb0e35..9929990a7 100755 --- a/test_regress/t/t_langext_1_bad.pl +++ b/test_regress/t/t_langext_1_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,12 +8,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); top_filename("t/t_langext_1.v"); -# This is a compile only test. -compile( +# This is a lint only test. +lint( v_flags2 => ["+verilog1995ext+v"], fails => 1 ); diff --git a/test_regress/t/t_langext_2.pl b/test_regress/t/t_langext_2.pl index 3164380b9..9cade2ddb 100755 --- a/test_regress/t/t_langext_2.pl +++ b/test_regress/t/t_langext_2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_langext_2_bad.pl b/test_regress/t/t_langext_2_bad.pl index 05fc58fcd..4e8700380 100755 --- a/test_regress/t/t_langext_2_bad.pl +++ b/test_regress/t/t_langext_2_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,12 +8,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); top_filename("t/t_langext_2.v"); -# This is a compile only test. -compile( +# This is a lint only test. +lint( v_flags2 => ["+1364-1995ext+v"], fails => 1 ); diff --git a/test_regress/t/t_langext_3.pl b/test_regress/t/t_langext_3.pl index 8e7c2ae5e..6286db1d6 100755 --- a/test_regress/t/t_langext_3.pl +++ b/test_regress/t/t_langext_3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_langext_3_bad.pl b/test_regress/t/t_langext_3_bad.pl index 68d1172d1..f6e5e2b52 100755 --- a/test_regress/t/t_langext_3_bad.pl +++ b/test_regress/t/t_langext_3_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,12 +8,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); top_filename("t/t_langext_3.v"); -# This is a compile only test. -compile( +# This is a lint only test. +lint( v_flags2 => ["+1364-2001ext+v"], fails => 1 ); diff --git a/test_regress/t/t_langext_4.pl b/test_regress/t/t_langext_4.pl index 244788f32..dc5b8030c 100755 --- a/test_regress/t/t_langext_4.pl +++ b/test_regress/t/t_langext_4.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_langext_4_bad.pl b/test_regress/t/t_langext_4_bad.pl index b935c2cce..ed58832e3 100755 --- a/test_regress/t/t_langext_4_bad.pl +++ b/test_regress/t/t_langext_4_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,12 +8,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); top_filename("t/t_langext_2.v"); -# This is a compile only test. -compile( +# This is a lint only test. +lint( v_flags2 => ["+1800-2005ext+v"], fails => 1 ); diff --git a/test_regress/t/t_langext_order.pl b/test_regress/t/t_langext_order.pl index 8e7c2ae5e..6286db1d6 100755 --- a/test_regress/t/t_langext_order.pl +++ b/test_regress/t/t_langext_order.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_leak.pl b/test_regress/t/t_leak.pl index ba352d9dd..6e0507280 100755 --- a/test_regress/t/t_leak.pl +++ b/test_regress/t/t_leak.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_always_comb_bad.pl b/test_regress/t/t_lint_always_comb_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_lint_always_comb_bad.pl +++ b/test_regress/t/t_lint_always_comb_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_always_comb_iface.pl b/test_regress/t/t_lint_always_comb_iface.pl index f7cc66737..7918d5f13 100755 --- a/test_regress/t/t_lint_always_comb_iface.pl +++ b/test_regress/t/t_lint_always_comb_iface.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_blksync_bad.pl b/test_regress/t/t_lint_blksync_bad.pl index bf192ff4c..57bd2d964 100755 --- a/test_regress/t/t_lint_blksync_bad.pl +++ b/test_regress/t/t_lint_blksync_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_blksync_loop.pl b/test_regress/t/t_lint_blksync_loop.pl index 58912617c..8a474235a 100755 --- a/test_regress/t/t_lint_blksync_loop.pl +++ b/test_regress/t/t_lint_blksync_loop.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_block_redecl_bad.pl b/test_regress/t/t_lint_block_redecl_bad.pl index 70003325c..30201602c 100755 --- a/test_regress/t/t_lint_block_redecl_bad.pl +++ b/test_regress/t/t_lint_block_redecl_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_bsspace_bad.pl b/test_regress/t/t_lint_bsspace_bad.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_lint_bsspace_bad.pl +++ b/test_regress/t/t_lint_bsspace_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_colonplus_bad.pl b/test_regress/t/t_lint_colonplus_bad.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_lint_colonplus_bad.pl +++ b/test_regress/t/t_lint_colonplus_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_comb_bad.pl b/test_regress/t/t_lint_comb_bad.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_lint_comb_bad.pl +++ b/test_regress/t/t_lint_comb_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_comb_use.pl b/test_regress/t/t_lint_comb_use.pl index 4052d7162..9c58f64a3 100755 --- a/test_regress/t/t_lint_comb_use.pl +++ b/test_regress/t/t_lint_comb_use.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -12,7 +12,6 @@ scenarios(vlt => 1); lint( verilator_flags2 => ["--lint-only --bbox-sys"], - fails => 0, ); ok(1); diff --git a/test_regress/t/t_lint_declfilename.pl b/test_regress/t/t_lint_declfilename.pl index e0297030b..1366501ca 100755 --- a/test_regress/t/t_lint_declfilename.pl +++ b/test_regress/t/t_lint_declfilename.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_declfilename_bad.pl b/test_regress/t/t_lint_declfilename_bad.pl index 92de58405..a884e811f 100755 --- a/test_regress/t/t_lint_declfilename_bad.pl +++ b/test_regress/t/t_lint_declfilename_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_defparam.pl b/test_regress/t/t_lint_defparam.pl index e0297030b..1366501ca 100755 --- a/test_regress/t/t_lint_defparam.pl +++ b/test_regress/t/t_lint_defparam.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_defparam_bad.pl b/test_regress/t/t_lint_defparam_bad.pl index ac8b05b6d..9b7fa451e 100755 --- a/test_regress/t/t_lint_defparam_bad.pl +++ b/test_regress/t/t_lint_defparam_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_ifdepth_bad.pl b/test_regress/t/t_lint_ifdepth_bad.pl index 8af5bfd40..54a0ed3d1 100755 --- a/test_regress/t/t_lint_ifdepth_bad.pl +++ b/test_regress/t/t_lint_ifdepth_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_implicit.pl b/test_regress/t/t_lint_implicit.pl index 9f98be06b..f6e2fa210 100755 --- a/test_regress/t/t_lint_implicit.pl +++ b/test_regress/t/t_lint_implicit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_implicit_bad.pl b/test_regress/t/t_lint_implicit_bad.pl index e0cf4c95a..abf5d91f2 100755 --- a/test_regress/t/t_lint_implicit_bad.pl +++ b/test_regress/t/t_lint_implicit_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_implicit_def_bad.pl b/test_regress/t/t_lint_implicit_def_bad.pl index c2452eff5..860de7fd2 100755 --- a/test_regress/t/t_lint_implicit_def_bad.pl +++ b/test_regress/t/t_lint_implicit_def_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_implicit_port.pl b/test_regress/t/t_lint_implicit_port.pl index 9f98be06b..f6e2fa210 100755 --- a/test_regress/t/t_lint_implicit_port.pl +++ b/test_regress/t/t_lint_implicit_port.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_import_name2_bad.out b/test_regress/t/t_lint_import_name2_bad.out new file mode 100644 index 000000000..b95efdba7 --- /dev/null +++ b/test_regress/t/t_lint_import_name2_bad.out @@ -0,0 +1,7 @@ +%Error: t/t_lint_import_name2_bad.v:7:8: Importing from missing package 'missing' + 7 | import missing::sigs; + | ^~~~~~~ +%Error: t/t_lint_import_name2_bad.v:9:8: Importing from missing package 'missing' + 9 | import missing::*; + | ^~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_lint_import_name2_bad.pl b/test_regress/t/t_lint_import_name2_bad.pl new file mode 100755 index 000000000..7539b1bd9 --- /dev/null +++ b/test_regress/t/t_lint_import_name2_bad.pl @@ -0,0 +1,20 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2008 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 + +scenarios(vlt => 1); + +lint( + verilator_flags2 => ["--lint-only -Wall -Wno-DECLFILENAME"], + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_lint_import_name2_bad.v b/test_regress/t/t_lint_import_name2_bad.v new file mode 100644 index 000000000..62b8845c8 --- /dev/null +++ b/test_regress/t/t_lint_import_name2_bad.v @@ -0,0 +1,9 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2018 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +import missing::sigs; + +import missing::*; diff --git a/test_regress/t/t_lint_import_name_bad.pl b/test_regress/t/t_lint_import_name_bad.pl index 6a24a9424..7539b1bd9 100755 --- a/test_regress/t/t_lint_import_name_bad.pl +++ b/test_regress/t/t_lint_import_name_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_importstar_bad.pl b/test_regress/t/t_lint_importstar_bad.pl index 6a24a9424..7539b1bd9 100755 --- a/test_regress/t/t_lint_importstar_bad.pl +++ b/test_regress/t/t_lint_importstar_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_in_inc_bad.pl b/test_regress/t/t_lint_in_inc_bad.pl index e012834b1..0661a705e 100755 --- a/test_regress/t/t_lint_in_inc_bad.pl +++ b/test_regress/t/t_lint_in_inc_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,14 +8,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(vlt_all => 1); +scenarios(vlt => 1); -compile( - v_flags2 => ["--lint-only -Wall -Wno-DECLFILENAME --if-depth 10"], +lint( + v_flags2 => ["-Wall -Wno-DECLFILENAME --if-depth 10"], fails => 1, - verilator_make_gmake => 0, - make_top_shell => 0, - make_main => 0, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_lint_incabspath.pl b/test_regress/t/t_lint_incabspath.pl index e0297030b..1366501ca 100755 --- a/test_regress/t/t_lint_incabspath.pl +++ b/test_regress/t/t_lint_incabspath.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_incabspath_bad.pl b/test_regress/t/t_lint_incabspath_bad.pl index f9d3031a7..80a2b601f 100755 --- a/test_regress/t/t_lint_incabspath_bad.pl +++ b/test_regress/t/t_lint_incabspath_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_infinite.pl b/test_regress/t/t_lint_infinite.pl index ddbffc478..07964a1b5 100755 --- a/test_regress/t/t_lint_infinite.pl +++ b/test_regress/t/t_lint_infinite.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_inherit.pl b/test_regress/t/t_lint_inherit.pl index d1bf185c9..552bd97db 100755 --- a/test_regress/t/t_lint_inherit.pl +++ b/test_regress/t/t_lint_inherit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_input_eq_bad.pl b/test_regress/t/t_lint_input_eq_bad.pl index 30a536839..b5861b2ab 100755 --- a/test_regress/t/t_lint_input_eq_bad.pl +++ b/test_regress/t/t_lint_input_eq_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_latch_bad.pl b/test_regress/t/t_lint_latch_bad.pl index 2485f55da..6755217bb 100755 --- a/test_regress/t/t_lint_latch_bad.pl +++ b/test_regress/t/t_lint_latch_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_literal_bad.pl b/test_regress/t/t_lint_literal_bad.pl index 5d4fb2e96..506f62c09 100755 --- a/test_regress/t/t_lint_literal_bad.pl +++ b/test_regress/t/t_lint_literal_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(vlt_all => 1); +scenarios(vlt => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_lint_mod_paren_bad.pl b/test_regress/t/t_lint_mod_paren_bad.pl index dd76f697c..0b0675898 100755 --- a/test_regress/t/t_lint_mod_paren_bad.pl +++ b/test_regress/t/t_lint_mod_paren_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_modport_dir_bad.pl b/test_regress/t/t_lint_modport_dir_bad.pl index 2a6951323..abf587bd3 100755 --- a/test_regress/t/t_lint_modport_dir_bad.pl +++ b/test_regress/t/t_lint_modport_dir_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_multidriven_bad.pl b/test_regress/t/t_lint_multidriven_bad.pl index 8e4fecbdb..a82cf66cb 100755 --- a/test_regress/t/t_lint_multidriven_bad.pl +++ b/test_regress/t/t_lint_multidriven_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_numwidth.pl b/test_regress/t/t_lint_numwidth.pl index 1f038cd03..9fe706c85 100755 --- a/test_regress/t/t_lint_numwidth.pl +++ b/test_regress/t/t_lint_numwidth.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_once_bad.pl b/test_regress/t/t_lint_once_bad.pl index 8bd893a71..4937974bc 100755 --- a/test_regress/t/t_lint_once_bad.pl +++ b/test_regress/t/t_lint_once_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_only.pl b/test_regress/t/t_lint_only.pl index 0b111f8e8..d1e2ac8bc 100755 --- a/test_regress/t/t_lint_only.pl +++ b/test_regress/t/t_lint_only.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -13,8 +13,9 @@ scenarios(vlt => 1); lint(); foreach my $file (glob("$Self->{obj_dir}/*")) { - next if $file =~ /\.log/; # Made by driver.pl, not Verilator - next if $file =~ /\.status/; # Made by driver.pl, not Verilator + next if $file =~ /\.log/; # Made by driver.pl, not Verilator sources + next if $file =~ /\.status/; # Made by driver.pl, not Verilator sources + next if $file =~ /\.gcda/; # Made by gcov, not Verilator sources error("%Error: Created $file, but --lint-only shouldn't create files"); } diff --git a/test_regress/t/t_lint_pindup_bad.pl b/test_regress/t/t_lint_pindup_bad.pl index 8e4fecbdb..a82cf66cb 100755 --- a/test_regress/t/t_lint_pindup_bad.pl +++ b/test_regress/t/t_lint_pindup_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_pkg_colon_bad.pl b/test_regress/t/t_lint_pkg_colon_bad.pl index 8e4fecbdb..a82cf66cb 100755 --- a/test_regress/t/t_lint_pkg_colon_bad.pl +++ b/test_regress/t/t_lint_pkg_colon_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_realcvt_bad.pl b/test_regress/t/t_lint_realcvt_bad.pl index 91afccfab..49de1747e 100755 --- a/test_regress/t/t_lint_realcvt_bad.pl +++ b/test_regress/t/t_lint_realcvt_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_repeat_bad.pl b/test_regress/t/t_lint_repeat_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_lint_repeat_bad.pl +++ b/test_regress/t/t_lint_repeat_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_restore_bad.pl b/test_regress/t/t_lint_restore_bad.pl index ddbffc478..07964a1b5 100755 --- a/test_regress/t/t_lint_restore_bad.pl +++ b/test_regress/t/t_lint_restore_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_restore_prag_bad.out b/test_regress/t/t_lint_restore_prag_bad.out new file mode 100644 index 000000000..00ac14fc0 --- /dev/null +++ b/test_regress/t/t_lint_restore_prag_bad.out @@ -0,0 +1,4 @@ +%Error: t/t_lint_restore_prag_bad.v:10:4: /*verilator lint_restore*/ without matching save. + 10 | /*verilator lint_restore*/ + | ^~~~~~~~~~~~~~~~~~~~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_lint_restore_prag_bad.pl b/test_regress/t/t_lint_restore_prag_bad.pl new file mode 100755 index 000000000..07964a1b5 --- /dev/null +++ b/test_regress/t/t_lint_restore_prag_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003-2009 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 + +scenarios(vlt => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_lint_restore_prag_bad.v b/test_regress/t/t_lint_restore_prag_bad.v new file mode 100644 index 000000000..643b001d5 --- /dev/null +++ b/test_regress/t/t_lint_restore_prag_bad.v @@ -0,0 +1,12 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2007 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (); + + // No matching save + // verilator lint_restore + +endmodule diff --git a/test_regress/t/t_lint_rsvd_bad.pl b/test_regress/t/t_lint_rsvd_bad.pl index 91afccfab..49de1747e 100755 --- a/test_regress/t/t_lint_rsvd_bad.pl +++ b/test_regress/t/t_lint_rsvd_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_setout_bad.pl b/test_regress/t/t_lint_setout_bad.pl index 8e4fecbdb..a82cf66cb 100755 --- a/test_regress/t/t_lint_setout_bad.pl +++ b/test_regress/t/t_lint_setout_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_setout_bad_noinl.pl b/test_regress/t/t_lint_setout_bad_noinl.pl index 885402cc2..4b5131821 100755 --- a/test_regress/t/t_lint_setout_bad_noinl.pl +++ b/test_regress/t/t_lint_setout_bad_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_subout_bad.pl b/test_regress/t/t_lint_subout_bad.pl index 31eb2c003..1483c9cd2 100755 --- a/test_regress/t/t_lint_subout_bad.pl +++ b/test_regress/t/t_lint_subout_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_syncasyncnet_bad.pl b/test_regress/t/t_lint_syncasyncnet_bad.pl index 91b01543a..a40f3dab1 100755 --- a/test_regress/t/t_lint_syncasyncnet_bad.pl +++ b/test_regress/t/t_lint_syncasyncnet_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_unsized_bad.pl b/test_regress/t/t_lint_unsized_bad.pl index 8e4fecbdb..a82cf66cb 100755 --- a/test_regress/t/t_lint_unsized_bad.pl +++ b/test_regress/t/t_lint_unsized_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_unsup_deassign.pl b/test_regress/t/t_lint_unsup_deassign.pl index fc2bfc33a..d4a6fe9d8 100755 --- a/test_regress/t/t_lint_unsup_deassign.pl +++ b/test_regress/t/t_lint_unsup_deassign.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_unsup_mixed.pl b/test_regress/t/t_lint_unsup_mixed.pl index fc2bfc33a..d4a6fe9d8 100755 --- a/test_regress/t/t_lint_unsup_mixed.pl +++ b/test_regress/t/t_lint_unsup_mixed.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_unused.pl b/test_regress/t/t_lint_unused.pl index fedb2b1f8..ab8a6023e 100755 --- a/test_regress/t/t_lint_unused.pl +++ b/test_regress/t/t_lint_unused.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -12,7 +12,6 @@ scenarios(vlt => 1); lint( verilator_flags2 => ["--lint-only --bbox-sys --bbox-unsup -Wall -Wno-DECLFILENAME"], - fails => 0, ); ok(1); diff --git a/test_regress/t/t_lint_unused_bad.pl b/test_regress/t/t_lint_unused_bad.pl index 545ee3858..ca7a27539 100755 --- a/test_regress/t/t_lint_unused_bad.pl +++ b/test_regress/t/t_lint_unused_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_unused_iface.pl b/test_regress/t/t_lint_unused_iface.pl index 5980d5141..3679f5264 100755 --- a/test_regress/t/t_lint_unused_iface.pl +++ b/test_regress/t/t_lint_unused_iface.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -12,7 +12,6 @@ scenarios(vlt => 1); lint( verilator_flags2 => ["--lint-only -Wall -Wno-DECLFILENAME"], - fails => 0, ); ok(1); diff --git a/test_regress/t/t_lint_unused_iface_bad.pl b/test_regress/t/t_lint_unused_iface_bad.pl index 2d0d72931..1c2a82989 100755 --- a/test_regress/t/t_lint_unused_iface_bad.pl +++ b/test_regress/t/t_lint_unused_iface_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_vcmarker_bad.pl b/test_regress/t/t_lint_vcmarker_bad.pl index ddbffc478..07964a1b5 100755 --- a/test_regress/t/t_lint_vcmarker_bad.pl +++ b/test_regress/t/t_lint_vcmarker_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_width.pl b/test_regress/t/t_lint_width.pl index 793cc4cb1..cc34dc85f 100755 --- a/test_regress/t/t_lint_width.pl +++ b/test_regress/t/t_lint_width.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_width_bad.pl b/test_regress/t/t_lint_width_bad.pl index ddbffc478..07964a1b5 100755 --- a/test_regress/t/t_lint_width_bad.pl +++ b/test_regress/t/t_lint_width_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_width_genfor.pl b/test_regress/t/t_lint_width_genfor.pl index 0b00f8646..d4dec648c 100755 --- a/test_regress/t/t_lint_width_genfor.pl +++ b/test_regress/t/t_lint_width_genfor.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_lint_width_genfor_bad.pl b/test_regress/t/t_lint_width_genfor_bad.pl index f3dd1d2a1..35d749208 100755 --- a/test_regress/t/t_lint_width_genfor_bad.pl +++ b/test_regress/t/t_lint_width_genfor_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_arith.pl b/test_regress/t/t_math_arith.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_arith.pl +++ b/test_regress/t/t_math_arith.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_clog2.pl b/test_regress/t/t_math_clog2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_clog2.pl +++ b/test_regress/t/t_math_clog2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_cmp.pl b/test_regress/t/t_math_cmp.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_cmp.pl +++ b/test_regress/t/t_math_cmp.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_concat.pl b/test_regress/t/t_math_concat.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_concat.pl +++ b/test_regress/t/t_math_concat.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_concat0.pl b/test_regress/t/t_math_concat0.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_concat0.pl +++ b/test_regress/t/t_math_concat0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_concat64.pl b/test_regress/t/t_math_concat64.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_concat64.pl +++ b/test_regress/t/t_math_concat64.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_concat_sel_bad.pl b/test_regress/t/t_math_concat_sel_bad.pl index 54363604a..f3e3b1181 100755 --- a/test_regress/t/t_math_concat_sel_bad.pl +++ b/test_regress/t/t_math_concat_sel_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, ); diff --git a/test_regress/t/t_math_cond_clean.pl b/test_regress/t/t_math_cond_clean.pl index e02817219..9a15dd2cc 100755 --- a/test_regress/t/t_math_cond_clean.pl +++ b/test_regress/t/t_math_cond_clean.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_cond_huge.pl b/test_regress/t/t_math_cond_huge.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_cond_huge.pl +++ b/test_regress/t/t_math_cond_huge.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_const.pl b/test_regress/t/t_math_const.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_const.pl +++ b/test_regress/t/t_math_const.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_countbits.pl b/test_regress/t/t_math_countbits.pl new file mode 100755 index 000000000..9a15dd2cc --- /dev/null +++ b/test_regress/t/t_math_countbits.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 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 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_math_countbits.v b/test_regress/t/t_math_countbits.v new file mode 100644 index 000000000..617d2b47d --- /dev/null +++ b/test_regress/t/t_math_countbits.v @@ -0,0 +1,134 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 Yossi Nivin. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + reg [15:0] in16; + reg [31:0] in32; + reg [63:0] in64; + // Non-standard size + reg [9:0] in10; + reg [20:0] in21; + reg [58:0] in59; + reg [69:0] in70; + + reg [31:0] ctrl0; + reg [31:0] ctrl1; + reg [31:0] ctrl2; + + reg [4:0] result_16_1; + reg [4:0] result_16_2; + reg [4:0] result_16_3; + reg [5:0] result_32_1; + reg [5:0] result_32_2; + reg [5:0] result_32_3; + reg [6:0] result_64_1; + reg [6:0] result_64_2; + reg [6:0] result_64_3; + reg [3:0] result_10_3; + reg [4:0] result_21_3; + reg [5:0] result_59_3; + reg [6:0] result_70_3; + + always @* begin + result_16_1 = $countbits(in16, ctrl0); + result_16_2 = $countbits(in16, ctrl0, ctrl1); + result_16_3 = $countbits(in16, ctrl0, ctrl1, ctrl2); + + result_32_1 = $countbits(in32, ctrl0); + result_32_2 = $countbits(in32, ctrl0, ctrl1); + result_32_3 = $countbits(in32, ctrl0, ctrl1, ctrl2); + + result_64_1 = $countbits(in64, ctrl0); + result_64_2 = $countbits(in64, ctrl0, ctrl1); + result_64_3 = $countbits(in64, ctrl0, ctrl1, ctrl2); + + result_10_3 = $countbits(in10, ctrl0, ctrl1, ctrl2); + result_21_3 = $countbits(in21, ctrl0, ctrl1, ctrl2); + result_59_3 = $countbits(in59, ctrl0, ctrl1, ctrl2); + result_70_3 = $countbits(in70, ctrl0, ctrl1, ctrl2); + end + + integer cyc=0; + // Test loop + always @ (posedge clk) begin + cyc <= cyc + 1; + if (cyc == 0) begin + // Constants + if ($countbits(32'b11001011101, '1) != 7) $stop; + if ($countbits(32'b11001011101, '1, 'z) != 7) $stop; + if ($countbits(32'b11001011101, '1, '0) != 32) $stop; + if ($countbits(20'b11001011101, '1, '0) != 20) $stop; + if ($countbits(20'b1100x01z101, '1, '0) != 18) $stop; + if ($countbits(20'b1100x01z101, 2, 2'bx1) != 18) $stop; + if ($countbits(32'b1100x01z101, 'x, 'z) != 2) $stop; + if ($countbits(32'b1100x01z101, 'x, 'z, '1) != 7) $stop; + end + else if (cyc == 1) begin + in16 <= 16'h0AF0; + in32 <= 32'hA0F300; + in64 <= 64'hA5A5A5A5A5A5A5A5; + in10 <= 10'b1010_1011; + in21 <= 21'h10F102; + in59 <= 59'h7050137210; + in70 <= 70'hF00030008000; + ctrl0 <= '0; + ctrl1 <= '1; + ctrl2 <= '1; + end + else if (cyc == 2) begin + if (result_16_1 != 10) $stop; + if (result_16_2 != 16) $stop; + if (result_16_3 != 16) $stop; + if (result_32_1 != 24) $stop; + if (result_32_2 != 32) $stop; + if (result_32_3 != 32) $stop; + if (result_64_1 != 32) $stop; + if (result_64_2 != 64) $stop; + if (result_64_3 != 64) $stop; + if (result_10_3 != 10) $stop; + if (result_21_3 != 21) $stop; + if (result_59_3 != 59) $stop; + if (result_70_3 != 70) $stop; + + in16 <= 16'h82B; + in32 <= 32'h305372; + in64 <= 64'h7777777777777777; + in10 <= 10'b1001_0111; + in21 <= 21'h91040C; + in59 <= 59'h12345678; + in70 <= 70'hF11111111; + // Confirm upper bits of the control arguments are ignored + ctrl0 <= 5; + ctrl1 <= 3; + ctrl2 <= 2; + end + else if (cyc == 3) begin + if (result_16_1 != 5) $stop; + if (result_16_2 != 5) $stop; + if (result_16_3 != 16) $stop; + if (result_32_1 != 10) $stop; + if (result_32_2 != 10) $stop; + if (result_32_3 != 32) $stop; + if (result_64_1 != 48) $stop; + if (result_64_2 != 48) $stop; + if (result_64_3 != 64) $stop; + if (result_10_3 != 10) $stop; + if (result_21_3 != 21) $stop; + if (result_59_3 != 59) $stop; + if (result_70_3 != 70) $stop; + end + else if (cyc == 4) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + +endmodule diff --git a/test_regress/t/t_math_countbits_bad.out b/test_regress/t/t_math_countbits_bad.out new file mode 100755 index 000000000..9e676ad75 --- /dev/null +++ b/test_regress/t/t_math_countbits_bad.out @@ -0,0 +1,4 @@ +%Error: t/t_math_countbits_bad.v:14:54: Unsupported: $countbits with more than 3 control fields + 14 | assign count = $countbits(32'h123456, '0, '1, 'x, 'z); + | ^~ +%Error: Exiting due to diff --git a/test_regress/t/t_math_countbits_bad.pl b/test_regress/t/t_math_countbits_bad.pl new file mode 100755 index 000000000..487e3aadf --- /dev/null +++ b/test_regress/t/t_math_countbits_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 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 + +scenarios(linter => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename} + ); + +ok(1); +1; diff --git a/test_regress/t/t_math_countbits_bad.v b/test_regress/t/t_math_countbits_bad.v new file mode 100644 index 000000000..6560d2303 --- /dev/null +++ b/test_regress/t/t_math_countbits_bad.v @@ -0,0 +1,16 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 Yossi Nivin. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + integer count; + assign count = $countbits(32'h123456, '0, '1, 'x, 'z); + +endmodule diff --git a/test_regress/t/t_math_div.pl b/test_regress/t/t_math_div.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_div.pl +++ b/test_regress/t/t_math_div.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_div0.pl b/test_regress/t/t_math_div0.pl index 5f57f767d..20346f7b4 100755 --- a/test_regress/t/t_math_div0.pl +++ b/test_regress/t/t_math_div0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_divw.pl b/test_regress/t/t_math_divw.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_divw.pl +++ b/test_regress/t/t_math_divw.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_eq.pl b/test_regress/t/t_math_eq.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_eq.pl +++ b/test_regress/t/t_math_eq.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_equal.pl b/test_regress/t/t_math_equal.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_math_equal.pl +++ b/test_regress/t/t_math_equal.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_equal.v b/test_regress/t/t_math_equal.v index d9afe52f5..7346c86c4 100644 --- a/test_regress/t/t_math_equal.v +++ b/test_regress/t/t_math_equal.v @@ -51,6 +51,10 @@ module t (/*AUTOARG*/ if (5'd10 != 5'D10) $stop; if (5'd10 != 5'H a) $stop; if (5'd10 != 5 'O 12) $stop; + if (24'h29cbb8 != 24'o12345670) $stop; + if (6'b111xxx !== 6'o7x) $stop; + if (6'b111??? !== 6'o7?) $stop; + if (6'b111zzz !== 6'o7z) $stop; // if (r_wide0 !== {32'haa111111,32'hbb222222,32'hcc333333,32'hdd444444}) $stop; if (r_wide1 !== {32'haa111111,32'hbb222222}) $stop; diff --git a/test_regress/t/t_math_imm.pl b/test_regress/t/t_math_imm.pl index d6841bed0..7d49cd2cd 100755 --- a/test_regress/t/t_math_imm.pl +++ b/test_regress/t/t_math_imm.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_imm2.pl b/test_regress/t/t_math_imm2.pl index f2624d772..19193485f 100755 --- a/test_regress/t/t_math_imm2.pl +++ b/test_regress/t/t_math_imm2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_msvc_64.pl b/test_regress/t/t_math_msvc_64.pl index c1a964fed..2769c27e2 100755 --- a/test_regress/t/t_math_msvc_64.pl +++ b/test_regress/t/t_math_msvc_64.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_mul.pl b/test_regress/t/t_math_mul.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_mul.pl +++ b/test_regress/t/t_math_mul.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_pick.pl b/test_regress/t/t_math_pick.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_pick.pl +++ b/test_regress/t/t_math_pick.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_pow.pl b/test_regress/t/t_math_pow.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_pow.pl +++ b/test_regress/t/t_math_pow.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_pow2.pl b/test_regress/t/t_math_pow2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_pow2.pl +++ b/test_regress/t/t_math_pow2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_pow3.pl b/test_regress/t/t_math_pow3.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_pow3.pl +++ b/test_regress/t/t_math_pow3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_pow4.pl b/test_regress/t/t_math_pow4.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_pow4.pl +++ b/test_regress/t/t_math_pow4.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_pow5.pl b/test_regress/t/t_math_pow5.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_pow5.pl +++ b/test_regress/t/t_math_pow5.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_pow6.pl b/test_regress/t/t_math_pow6.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_pow6.pl +++ b/test_regress/t/t_math_pow6.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_precedence.pl b/test_regress/t/t_math_precedence.pl index 88a9f757e..7cb68e14d 100755 --- a/test_regress/t/t_math_precedence.pl +++ b/test_regress/t/t_math_precedence.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_real.pl b/test_regress/t/t_math_real.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_real.pl +++ b/test_regress/t/t_math_real.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_real.v b/test_regress/t/t_math_real.v index 17bc0221c..167bd9fbf 100644 --- a/test_regress/t/t_math_real.v +++ b/test_regress/t/t_math_real.v @@ -85,6 +85,9 @@ module t (/*AUTOARG*/ // bug r = 32'bxz000_111; // 7 accoding to IEEE if (r != 7) $stop; + // bug + b = 64'h7fe8000000000000; + $display("%6.3f", $bitstoreal(b)); end // Test loop diff --git a/test_regress/t/t_math_real_public.pl b/test_regress/t/t_math_real_public.pl index af34581d9..c8654558c 100755 --- a/test_regress/t/t_math_real_public.pl +++ b/test_regress/t/t_math_real_public.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_real_round.pl b/test_regress/t/t_math_real_round.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_real_round.pl +++ b/test_regress/t/t_math_real_round.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_red.pl b/test_regress/t/t_math_red.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_red.pl +++ b/test_regress/t/t_math_red.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_repl.pl b/test_regress/t/t_math_repl.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_repl.pl +++ b/test_regress/t/t_math_repl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_reverse.pl b/test_regress/t/t_math_reverse.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_reverse.pl +++ b/test_regress/t/t_math_reverse.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_shift.pl b/test_regress/t/t_math_shift.pl index 4a908581b..757e26425 100755 --- a/test_regress/t/t_math_shift.pl +++ b/test_regress/t/t_math_shift.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_shift_over_bad.pl b/test_regress/t/t_math_shift_over_bad.pl index 72a231777..9c9fb65a0 100755 --- a/test_regress/t/t_math_shift_over_bad.pl +++ b/test_regress/t/t_math_shift_over_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_shift_rep.pl b/test_regress/t/t_math_shift_rep.pl index e64fd774a..664c428d8 100755 --- a/test_regress/t/t_math_shift_rep.pl +++ b/test_regress/t/t_math_shift_rep.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_shift_sel.pl b/test_regress/t/t_math_shift_sel.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_shift_sel.pl +++ b/test_regress/t/t_math_shift_sel.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_shiftrs.pl b/test_regress/t/t_math_shiftrs.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_shiftrs.pl +++ b/test_regress/t/t_math_shiftrs.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_shortreal.pl b/test_regress/t/t_math_shortreal.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_shortreal.pl +++ b/test_regress/t/t_math_shortreal.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_shortreal_unsup_bad.pl b/test_regress/t/t_math_shortreal_unsup_bad.pl index 72a231777..9c9fb65a0 100755 --- a/test_regress/t/t_math_shortreal_unsup_bad.pl +++ b/test_regress/t/t_math_shortreal_unsup_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_sign_extend.pl b/test_regress/t/t_math_sign_extend.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_sign_extend.pl +++ b/test_regress/t/t_math_sign_extend.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_signed.pl b/test_regress/t/t_math_signed.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_signed.pl +++ b/test_regress/t/t_math_signed.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_signed2.pl b/test_regress/t/t_math_signed2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_signed2.pl +++ b/test_regress/t/t_math_signed2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_signed3.pl b/test_regress/t/t_math_signed3.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_signed3.pl +++ b/test_regress/t/t_math_signed3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_signed4.pl b/test_regress/t/t_math_signed4.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_signed4.pl +++ b/test_regress/t/t_math_signed4.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_signed5.pl b/test_regress/t/t_math_signed5.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_signed5.pl +++ b/test_regress/t/t_math_signed5.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_signed6.pl b/test_regress/t/t_math_signed6.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_signed6.pl +++ b/test_regress/t/t_math_signed6.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_signed7.pl b/test_regress/t/t_math_signed7.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_signed7.pl +++ b/test_regress/t/t_math_signed7.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_signed_wire.pl b/test_regress/t/t_math_signed_wire.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_signed_wire.pl +++ b/test_regress/t/t_math_signed_wire.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_strwidth.pl b/test_regress/t/t_math_strwidth.pl index 8e6465d34..3940e9623 100755 --- a/test_regress/t/t_math_strwidth.pl +++ b/test_regress/t/t_math_strwidth.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_svl.pl b/test_regress/t/t_math_svl.pl index 89995f82e..3b0f6ade3 100755 --- a/test_regress/t/t_math_svl.pl +++ b/test_regress/t/t_math_svl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_svl.v b/test_regress/t/t_math_svl.v index 6ece121c7..5858e5b80 100644 --- a/test_regress/t/t_math_svl.v +++ b/test_regress/t/t_math_svl.v @@ -47,6 +47,23 @@ module t (/*AUTOARG*/ cyc_d1 <= cyc_com; end + initial begin + // Constification check + if ($countones(32'b11001011101) != 7) $stop; + if ($countones(32'b0) != 0) $stop; + if ($isunknown(32'b11101x11111) != 1) $stop; + if ($isunknown(32'b11101011111) != 0) $stop; + if ($isunknown(32'b10zzzzzzzzz) != 1) $stop; + if ($bits(0) != 32'd32) $stop; + if ($bits(lc) != 5) $stop; + if ($onehot(32'b00000001000000) != 1'b1) $stop; + if ($onehot(32'b00001001000000) != 1'b0) $stop; + if ($onehot(32'b0) != 1'b0) $stop; + if ($onehot0(32'b00000001000000) != 1'b1) $stop; + if ($onehot0(32'b00001001000000) != 1'b0) $stop; + if ($onehot0(32'b0) != 1'b1) $stop; + end + always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1; @@ -54,22 +71,6 @@ module t (/*AUTOARG*/ // cyc, l, lc, lo, l0, q,qc,qo,q0, w,wc,wo,w0); if (cyc_com != cyc_com) $stop; if (cyc_d1 != cyc-1) $stop; - if (cyc==0) begin - // Constification check - if ($countones(32'b11001011101) != 7) $stop; - if ($countones(32'b0) != 0) $stop; - if ($isunknown(32'b11101x11111) != 1) $stop; - if ($isunknown(32'b11101011111) != 0) $stop; - if ($isunknown(32'b10zzzzzzzzz) != 0) $stop; - if ($bits(0) != 32'd32) $stop; - if ($bits(lc) != 5) $stop; - if ($onehot(32'b00000001000000) != 1'b1) $stop; - if ($onehot(32'b00001001000000) != 1'b0) $stop; - if ($onehot(32'b0) != 1'b0) $stop; - if ($onehot0(32'b00000001000000) != 1'b1) $stop; - if ($onehot0(32'b00001001000000) != 1'b0) $stop; - if ($onehot0(32'b0) != 1'b1) $stop; - end if (cyc==1) begin l <= 16'b0; q <= 50'h0; @@ -135,6 +136,13 @@ module t (/*AUTOARG*/ end end + initial begin + if ($isunknown(4'b000x) !== 1'b1) $stop; + if ($isunknown(4'b000z) !== 1'b1) $stop; + if ($isunknown(4'b00xz) !== 1'b1) $stop; + if ($isunknown(4'b0000) !== 1'b0) $stop; + end + final begin $write("Goodbye world, at cycle %0d\n", cyc); end diff --git a/test_regress/t/t_math_svl2.pl b/test_regress/t/t_math_svl2.pl index 23acc7831..038e7a835 100755 --- a/test_regress/t/t_math_svl2.pl +++ b/test_regress/t/t_math_svl2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_swap.pl b/test_regress/t/t_math_swap.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_swap.pl +++ b/test_regress/t/t_math_swap.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_tri.pl b/test_regress/t/t_math_tri.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_tri.pl +++ b/test_regress/t/t_math_tri.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_trig.pl b/test_regress/t/t_math_trig.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_trig.pl +++ b/test_regress/t/t_math_trig.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_vgen.pl b/test_regress/t/t_math_vgen.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_vgen.pl +++ b/test_regress/t/t_math_vgen.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_vliw.pl b/test_regress/t/t_math_vliw.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_vliw.pl +++ b/test_regress/t/t_math_vliw.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_width.pl b/test_regress/t/t_math_width.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_math_width.pl +++ b/test_regress/t/t_math_width.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_math_yosys.pl b/test_regress/t/t_math_yosys.pl new file mode 100755 index 000000000..9a15dd2cc --- /dev/null +++ b/test_regress/t/t_math_yosys.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 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 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_math_yosys.v b/test_regress/t/t_math_yosys.v new file mode 100644 index 000000000..9fe06d075 --- /dev/null +++ b/test_regress/t/t_math_yosys.v @@ -0,0 +1,84 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 Claire Wolf. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + integer cyc=0; + + /*AUTOWIRE*/ + // Beginning of automatic wires (for undeclared instantiated-module outputs) + wire [7:0] y1; // From d1 of demo_001.v + wire [7:0] y2; // From d1 of demo_001.v + wire [7:0] y3; // From d1 of demo_001.v + wire [7:0] y4; // From d1 of demo_001.v + wire [31:0] z0; // From d2 of demo_002.v + wire [31:0] z1; // From d2 of demo_002.v + wire [31:0] z2; // From d2 of demo_002.v + wire [31:0] z3; // From d2 of demo_002.v + // End of automatics + + demo_001 d1(/*AUTOINST*/ + // Outputs + .y1 (y1[7:0]), + .y2 (y2[7:0]), + .y3 (y3[7:0]), + .y4 (y4[7:0])); + demo_002 d2(/*AUTOINST*/ + // Outputs + .z0 (z0[31:0]), + .z1 (z1[31:0]), + .z2 (z2[31:0]), + .z3 (z3[31:0])); + + // Test loop + always @ (posedge clk) begin + cyc <= cyc + 1; + if (y1 !== 8'h7b) $stop; + if (y2 !== 8'h7c) $stop; + if (y3 !== 8'h7b) $stop; + if (y4 !== 8'h7c) $stop; + if (z0 !== 32'h00000000) $stop; + if (z1 !== 32'hffffffff) $stop; + if (z2 !== 32'hffffffff) $stop; + if (z3 !== 32'hffffffff) $stop; + if (cyc == 99) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end +endmodule + +module demo_001(y1, y2, y3, y4); + output [7:0] y1, y2, y3, y4; + + // verilator lint_off REALCVT + localparam [7:0] p1 = 123.45; + localparam real p2 = 123.45; + localparam real p3 = 123; + localparam p4 = 123.45; + + // verilator lint_off WIDTH + assign y1 = p1 + 0.2; + assign y2 = p2 + 0.2; + assign y3 = p3 + 0.2; + assign y4 = p4 + 0.2; + // verilator lint_on WIDTH +endmodule + +module demo_002(z0, z1, z2, z3); + output [31:0] z0, z1, z2, z3; + + // verilator lint_off WIDTH + assign z0 = 1'bx >= (-1 * -1.17); + // verilator lint_on WIDTH + assign z1 = 1 ? 1 ? -1 : 'd0 : 0.0; + assign z2 = 1 ? -1 : 1 ? 'd0 : 0.0; + assign z3 = 1 ? -1 : 'd0; +endmodule diff --git a/test_regress/t/t_mem.pl b/test_regress/t/t_mem.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mem.pl +++ b/test_regress/t/t_mem.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_banks.pl b/test_regress/t/t_mem_banks.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mem_banks.pl +++ b/test_regress/t/t_mem_banks.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_bound_bad.pl b/test_regress/t/t_mem_bound_bad.pl new file mode 100755 index 000000000..6f9cc9875 --- /dev/null +++ b/test_regress/t/t_mem_bound_bad.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +$Self->{vlt_all} and unsupported("Verilator unsupported, bug528"); + +scenarios(linter => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_mem_bound_bad.v b/test_regress/t/t_mem_bound_bad.v new file mode 100644 index 000000000..c2ec5fa16 --- /dev/null +++ b/test_regress/t/t_mem_bound_bad.v @@ -0,0 +1,25 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2014 by Jie Xu +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/); + logic [1:0][31:0] tt; + logic [31:0] a; + logic [31:0] b; + logic [31:0] c; + + initial begin + a = 1; + b = 2; + c = 3; + tt[0] = a; + tt[1] = b; + tt[2] = c; // Out of bounds + if (tt[0]!=a) $stop; + if (tt[1]!=b) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_mem_cond.pl b/test_regress/t/t_mem_cond.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mem_cond.pl +++ b/test_regress/t/t_mem_cond.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_fifo.pl b/test_regress/t/t_mem_fifo.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mem_fifo.pl +++ b/test_regress/t/t_mem_fifo.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_file.pl b/test_regress/t/t_mem_file.pl index 214a71ff8..987de13d5 100755 --- a/test_regress/t/t_mem_file.pl +++ b/test_regress/t/t_mem_file.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_first.pl b/test_regress/t/t_mem_first.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mem_first.pl +++ b/test_regress/t/t_mem_first.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_func.pl b/test_regress/t/t_mem_func.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mem_func.pl +++ b/test_regress/t/t_mem_func.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_iforder.pl b/test_regress/t/t_mem_iforder.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_mem_iforder.pl +++ b/test_regress/t/t_mem_iforder.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_multi_io.pl b/test_regress/t/t_mem_multi_io.pl index 4f35f28e6..1691d75f1 100755 --- a/test_regress/t/t_mem_multi_io.pl +++ b/test_regress/t/t_mem_multi_io.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_multi_io2_cc.pl b/test_regress/t/t_mem_multi_io2_cc.pl index afd7676a5..3edda698b 100755 --- a/test_regress/t/t_mem_multi_io2_cc.pl +++ b/test_regress/t/t_mem_multi_io2_cc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_multi_io2_sc.pl b/test_regress/t/t_mem_multi_io2_sc.pl index 7fa5e3930..11ae8cbfc 100755 --- a/test_regress/t/t_mem_multi_io2_sc.pl +++ b/test_regress/t/t_mem_multi_io2_sc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_multi_io3_cc.pl b/test_regress/t/t_mem_multi_io3_cc.pl index 0e10b7948..4ad019dbf 100755 --- a/test_regress/t/t_mem_multi_io3_cc.pl +++ b/test_regress/t/t_mem_multi_io3_cc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_multi_io3_sc.pl b/test_regress/t/t_mem_multi_io3_sc.pl index cb1372c5e..5825c7845 100755 --- a/test_regress/t/t_mem_multi_io3_sc.pl +++ b/test_regress/t/t_mem_multi_io3_sc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_multi_ref_bad.out b/test_regress/t/t_mem_multi_ref_bad.out index d7aad1413..e37aa73f6 100644 --- a/test_regress/t/t_mem_multi_ref_bad.out +++ b/test_regress/t/t_mem_multi_ref_bad.out @@ -23,10 +23,10 @@ : ... In instance t 17 | dim1[1][1][1] = 0; | ^ -%Error: t/t_mem_multi_ref_bad.v:19:11: Illegal +: or -: select; type already selected, or bad dimension: data type is 'logic[1:0]$[1:0][1:0]' - : ... In instance t +%Warning-SELRANGE: t/t_mem_multi_ref_bad.v:19:19: Selection index out of range: 1 outside 0:0 + : ... In instance t 19 | dim2[0 +: 1][1] = 0; - | ^ + | ^ %Error: t/t_mem_multi_ref_bad.v:23:16: Illegal bit or array select; type does not have a bit range, or bad dimension: data type is 'logic' : ... In instance t 23 | dim0nv[1][1] = 0; diff --git a/test_regress/t/t_mem_multi_ref_bad.pl b/test_regress/t/t_mem_multi_ref_bad.pl index d334f74e1..7121b42e4 100755 --- a/test_regress/t/t_mem_multi_ref_bad.pl +++ b/test_regress/t/t_mem_multi_ref_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => $Self->{vlt_all}, nc => 0, # Need to get it not to give the prompt expect_filename => $Self->{golden_filename}, diff --git a/test_regress/t/t_mem_multidim.pl b/test_regress/t/t_mem_multidim.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mem_multidim.pl +++ b/test_regress/t/t_mem_multidim.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_multidim_Ox.pl b/test_regress/t/t_mem_multidim_Ox.pl index 04c6294a4..bb4dbc122 100755 --- a/test_regress/t/t_mem_multidim_Ox.pl +++ b/test_regress/t/t_mem_multidim_Ox.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_multidim_trace.pl b/test_regress/t/t_mem_multidim_trace.pl index c448302fd..4f4fed861 100755 --- a/test_regress/t/t_mem_multidim_trace.pl +++ b/test_regress/t/t_mem_multidim_trace.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_multiwire.pl b/test_regress/t/t_mem_multiwire.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mem_multiwire.pl +++ b/test_regress/t/t_mem_multiwire.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_packed.pl b/test_regress/t/t_mem_packed.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mem_packed.pl +++ b/test_regress/t/t_mem_packed.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_packed_assign.pl b/test_regress/t/t_mem_packed_assign.pl index 66f3a66cf..1d8540ca0 100755 --- a/test_regress/t/t_mem_packed_assign.pl +++ b/test_regress/t/t_mem_packed_assign.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_packed_bad.pl b/test_regress/t/t_mem_packed_bad.pl index 72a231777..9c9fb65a0 100755 --- a/test_regress/t/t_mem_packed_bad.pl +++ b/test_regress/t/t_mem_packed_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_shift.pl b/test_regress/t/t_mem_shift.pl index b1cd59018..7f4359712 100755 --- a/test_regress/t/t_mem_shift.pl +++ b/test_regress/t/t_mem_shift.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_slice.pl b/test_regress/t/t_mem_slice.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mem_slice.pl +++ b/test_regress/t/t_mem_slice.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_slice_bad.pl b/test_regress/t/t_mem_slice_bad.pl index 72a231777..9c9fb65a0 100755 --- a/test_regress/t/t_mem_slice_bad.pl +++ b/test_regress/t/t_mem_slice_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_slice_conc_bad.pl b/test_regress/t/t_mem_slice_conc_bad.pl index b3e120653..3be843059 100755 --- a/test_regress/t/t_mem_slice_conc_bad.pl +++ b/test_regress/t/t_mem_slice_conc_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_slice_dtype_bad.pl b/test_regress/t/t_mem_slice_dtype_bad.pl index dba098eb6..a60503a1f 100755 --- a/test_regress/t/t_mem_slice_dtype_bad.pl +++ b/test_regress/t/t_mem_slice_dtype_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_mem_slot.pl b/test_regress/t/t_mem_slot.pl index f2624d772..19193485f 100755 --- a/test_regress/t/t_mem_slot.pl +++ b/test_regress/t/t_mem_slot.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mem_twoedge.pl b/test_regress/t/t_mem_twoedge.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mem_twoedge.pl +++ b/test_regress/t/t_mem_twoedge.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_merge_cond.pl b/test_regress/t/t_merge_cond.pl new file mode 100755 index 000000000..529b23ff4 --- /dev/null +++ b/test_regress/t/t_merge_cond.pl @@ -0,0 +1,32 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(vlt_all => 1); + +compile( + verilator_flags2 => ["-unroll-count 64", "--stats"], + ); + +execute( + check_finished => 1, + ); + +if ($Self->{vlt}) { + # Note, with vltmt this might be split differently, so only checking vlt + file_grep($Self->{stats}, qr/Optimizations, MergeCond merges\s+(\d+)/i, + 10); + file_grep($Self->{stats}, qr/Optimizations, MergeCond merged items\s+(\d+)/i, + 640); + file_grep($Self->{stats}, qr/Optimizations, MergeCond longest merge\s+(\d+)/i, + 64); +} + +ok(1); +1; diff --git a/test_regress/t/t_merge_cond.v b/test_regress/t/t_merge_cond.v new file mode 100644 index 000000000..10a12bb29 --- /dev/null +++ b/test_regress/t/t_merge_cond.v @@ -0,0 +1,193 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Geza Lore. +// SPDX-License-Identifier: CC0-1.0 + +`define check(got ,exp) do if ((got) !== (exp)) begin $write("%%Error: %s:%0d: cyc=%0d got='h%x exp='h%x\n", `__FILE__,`__LINE__, cyc, (got), (exp)); $stop; end while(0) + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + integer cyc=0; + reg [63:0] crc= 64'h5aef0c8d_d70a4497; + reg [63:0] prev_crc; + + always @ (posedge clk) begin + cyc <= cyc + 1; + crc <= {crc[62:0], crc[63]^crc[2]^crc[0]}; + + prev_crc <= crc; + if (cyc==99) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + + wire cond2 = &crc[1:0]; + wire cond3 = &crc[2:0]; + + reg shuf_q [63:0]; + + always @(posedge clk) begin + reg bits [63:0]; + reg shuf_a [63:0]; + reg shuf_b [63:0]; + reg shuf_c [63:0]; + reg shuf_d [63:0]; + reg shuf_e [63:0]; + + // Unpack these to test core algorithm + for (int i = 0; i < 64; i = i + 1) begin + bits[i] = crc[i]; + end + + for (int i = 0; i < 64; i = i + 1) begin + shuf_a[i] = cyc[0] ? bits[i] : bits[63-i]; + end + + if (cyc[1]) begin + for (int i = 0; i < 64; i = i + 1) begin + shuf_b[i] = cyc[0] ? bits[i] : bits[63-i]; + end + end else begin + for (int i = 0; i < 64; i = i + 1) begin + shuf_b[i] = cyc[0] ? bits[63-i] : bits[i]; + end + end + + // Also test merge under clean/bit extract + for (int i = 0; i < 64; i = i + 1) begin + shuf_c[i] = cyc[0] ? crc[i] : crc[63-i]; + end + + // Merge with 'cond & value', 'value & cond', or 'cond' + shuf_d[0] = cond2 ? bits[0] : bits[63]; + for (int i = 1; i < 32; i = i + 2) begin + shuf_d[i] = cond2 & bits[i]; + end + for (int i = 2; i < 32; i = i + 2) begin + shuf_d[i] = bits[i] & cond2; + end + for (int i = 32; i < 64; i = i + 1) begin + shuf_d[i] = cond2; + end + + // Merge with an '&' also used for masking of LSB. + shuf_e[0] = cond3 ? bits[0] : bits[63]; + for (int i = 1; i < 64; i = i + 1) begin + shuf_e[i] = cond3 & crc[0]; + end + + // Also delayed.. + for (int i = 0; i < 64; i = i + 1) begin + shuf_q[i] <= cyc[0] ? crc[i] : crc[63-i]; + end + + // Check results + + if (cyc[0]) begin + for (int i = 0; i < 64; i = i + 1) `check(shuf_a[i], crc[i]); + end else begin + for (int i = 0; i < 64; i = i + 1) `check(shuf_a[i], crc[63-i]); + end + + if (cyc[0] ~^ cyc[1]) begin + for (int i = 0; i < 64; i = i + 1) `check(shuf_b[i], crc[i]); + end else begin + for (int i = 0; i < 64; i = i + 1) `check(shuf_b[i], crc[63-i]); + end + + if (cyc[0]) begin + for (int i = 0; i < 64; i = i + 1) `check(shuf_c[i], crc[i]); + end else begin + for (int i = 0; i < 64; i = i + 1) `check(shuf_c[i], crc[63-i]); + end + + if (cond2) begin + `check(shuf_d[0], crc[0]); + for (int i = 1; i < 32; i = i + 1) `check(shuf_d[i], crc[i]); + for (int i = 32; i < 63; i = i + 1) `check(shuf_d[i], 1'd1); + end else begin + `check(shuf_d[0], crc[63]); + for (int i = 1; i < 32; i = i + 1) `check(shuf_d[i], 1'b0); + for (int i = 32; i < 63; i = i + 1) `check(shuf_d[i], 1'd0); + end + + if (cond3) begin + `check(shuf_e[0], crc[0]); + for (int i = 1; i < 63; i = i + 1) `check(shuf_e[i], crc[0]); + end else begin + `check(shuf_e[0], crc[63]); + for (int i = 1; i < 63; i = i + 1) `check(shuf_e[i], 1'b0); + end + + if (cyc > 0) begin + if (~cyc[0]) begin + for (int i = 0; i < 64; i = i + 1) `check(shuf_q[i], prev_crc[i]); + end else begin + for (int i = 0; i < 64; i = i + 1) `check(shuf_q[i], prev_crc[63-i]); + end + + if (((cyc - 1) >> 1) % 2 == 1) begin + for (int i = 0; i < 64; i = i + 1) `check(shuf_g[i], prev_crc[i]); + end else begin + for (int i = 0; i < 64; i = i + 1) `check(shuf_g[i], prev_crc[63-i]); + end + end + + if (cyc[2]) begin + for (int i = 0; i < 64; i = i + 1) `check(shuf_w[i], crc[i]); + end else begin + for (int i = 0; i < 64; i = i + 1) `check(shuf_w[i], crc[63-i]); + end + end + + // Generated always + reg shuf_g [63:0]; + generate for (genvar i = 0 ; i < 64; i = i + 1) + always @(posedge clk) begin + shuf_g[i] <= cyc[1] ? crc[i] : crc[63-i]; + end + endgenerate + + // Generated assign + wire shuf_w [63:0]; + generate for (genvar i = 0 ; i < 64; i = i + 1) + assign shuf_w[i] = cyc[2] ? crc[i] : crc[63-i]; + endgenerate + + // Things not to merge + always @(posedge clk) begin + reg x; + reg y; + reg z; + reg w; + + // Do not merge if condition appears in an LVALUE + x = crc[0]; + y = x ? crc[2] : crc[1]; + x = x ? crc[3] : crc[4]; + x = x ? crc[5] : crc[6]; + + `check(x, (crc[0] ? crc[3] : crc[4]) ? crc[5] : crc[6]); + `check(y, crc[0] ? crc[2] : crc[1]); + + // Do not merge if condition is not a pure expression + $c("int _cnt = 0;"); + x = $c("_cnt++") ? crc[0] : crc[1]; + y = $c("_cnt++") ? crc[2] : crc[3]; + z = $c("_cnt++") ? crc[4] : crc[5]; + w = $c("_cnt++") ? crc[6] : crc[7]; + $c("if (_cnt != 4) abort();"); + + `check(x, crc[1]); + `check(y, crc[2]); + `check(z, crc[4]); + `check(w, crc[6]); + end + +endmodule diff --git a/test_regress/t/t_metacmt_onoff.pl b/test_regress/t/t_metacmt_onoff.pl index 4e13d3fc5..674687687 100755 --- a/test_regress/t/t_metacmt_onoff.pl +++ b/test_regress/t/t_metacmt_onoff.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mod_dup_bad.pl b/test_regress/t/t_mod_dup_bad.pl index 527a39935..b5861b2ab 100755 --- a/test_regress/t/t_mod_dup_bad.pl +++ b/test_regress/t/t_mod_dup_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(vlt => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_mod_dup_ign.pl b/test_regress/t/t_mod_dup_ign.pl index 193a62348..8b318d39c 100755 --- a/test_regress/t/t_mod_dup_ign.pl +++ b/test_regress/t/t_mod_dup_ign.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mod_interface_array0.pl b/test_regress/t/t_mod_interface_array0.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mod_interface_array0.pl +++ b/test_regress/t/t_mod_interface_array0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mod_interface_array0_noinl.pl b/test_regress/t/t_mod_interface_array0_noinl.pl index ec6f350af..3c74fd016 100755 --- a/test_regress/t/t_mod_interface_array0_noinl.pl +++ b/test_regress/t/t_mod_interface_array0_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mod_interface_array1.pl b/test_regress/t/t_mod_interface_array1.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mod_interface_array1.pl +++ b/test_regress/t/t_mod_interface_array1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mod_interface_array1_noinl.pl b/test_regress/t/t_mod_interface_array1_noinl.pl index c13ae3a86..34871282a 100755 --- a/test_regress/t/t_mod_interface_array1_noinl.pl +++ b/test_regress/t/t_mod_interface_array1_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mod_interface_array2.pl b/test_regress/t/t_mod_interface_array2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mod_interface_array2.pl +++ b/test_regress/t/t_mod_interface_array2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mod_interface_array2_noinl.pl b/test_regress/t/t_mod_interface_array2_noinl.pl index 15a876518..c19612e57 100755 --- a/test_regress/t/t_mod_interface_array2_noinl.pl +++ b/test_regress/t/t_mod_interface_array2_noinl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mod_interface_array3.pl b/test_regress/t/t_mod_interface_array3.pl index dba098eb6..1362bf74f 100755 --- a/test_regress/t/t_mod_interface_array3.pl +++ b/test_regress/t/t_mod_interface_array3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mod_longname.pl b/test_regress/t/t_mod_longname.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mod_longname.pl +++ b/test_regress/t/t_mod_longname.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mod_nomod.pl b/test_regress/t/t_mod_nomod.pl index a43fd86d3..e26d2aa31 100755 --- a/test_regress/t/t_mod_nomod.pl +++ b/test_regress/t/t_mod_nomod.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mod_recurse.pl b/test_regress/t/t_mod_recurse.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mod_recurse.pl +++ b/test_regress/t/t_mod_recurse.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mod_recurse1.pl b/test_regress/t/t_mod_recurse1.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_mod_recurse1.pl +++ b/test_regress/t/t_mod_recurse1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_mod_uselib.pl b/test_regress/t/t_mod_uselib.pl index b29350dd1..8fbc2f576 100755 --- a/test_regress/t/t_mod_uselib.pl +++ b/test_regress/t/t_mod_uselib.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_multitop1.pl b/test_regress/t/t_multitop1.pl index 446d729c9..e70f69cd0 100755 --- a/test_regress/t/t_multitop1.pl +++ b/test_regress/t/t_multitop1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_multitop_sig.pl b/test_regress/t/t_multitop_sig.pl index ed1fdcbc0..e53b59f79 100755 --- a/test_regress/t/t_multitop_sig.pl +++ b/test_regress/t/t_multitop_sig.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_multitop_sig_bad.pl b/test_regress/t/t_multitop_sig_bad.pl index baa0eb8f6..e5bc6cac7 100755 --- a/test_regress/t/t_multitop_sig_bad.pl +++ b/test_regress/t/t_multitop_sig_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -12,7 +12,7 @@ scenarios(simulator => 1); top_filename("t/t_multitop_sig.v"); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_noprot_lib.pl b/test_regress/t/t_noprot_lib.pl index 0f333cce1..ad155e829 100755 --- a/test_regress/t/t_noprot_lib.pl +++ b/test_regress/t/t_noprot_lib.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Makes the test run with tracing enabled by default, can be overridden # with --notrace unshift(@ARGV, "--trace"); diff --git a/test_regress/t/t_number_bad.out b/test_regress/t/t_number_bad.out index b88db4a1f..dedb6786d 100644 --- a/test_regress/t/t_number_bad.out +++ b/test_regress/t/t_number_bad.out @@ -7,4 +7,10 @@ %Error: t/t_number_bad.v:11:29: Number is missing value digits: 32'h 11 | parameter integer FOO4 = 32'h; | ^~~~ +%Error: t/t_number_bad.v:13:29: Illegal character in binary constant: 2 + 13 | parameter integer FOO5 = 32'b2; + | ^~~~~ +%Error: t/t_number_bad.v:14:29: Illegal character in octal constant + 14 | parameter integer FOO6 = 32'o8; + | ^~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_number_bad.pl b/test_regress/t/t_number_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_number_bad.pl +++ b/test_regress/t/t_number_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_number_bad.v b/test_regress/t/t_number_bad.v index b2c1ae547..0ed4ef7a2 100644 --- a/test_regress/t/t_number_bad.v +++ b/test_regress/t/t_number_bad.v @@ -10,4 +10,7 @@ module t (/*AUTOARG*/); parameter integer FOO3 = 32'd; parameter integer FOO4 = 32'h; + parameter integer FOO5 = 32'b2; + parameter integer FOO6 = 32'o8; + endmodule diff --git a/test_regress/t/t_optm_if_array.pl b/test_regress/t/t_optm_if_array.pl index 0a7853f4a..21408ee20 100755 --- a/test_regress/t/t_optm_if_array.pl +++ b/test_regress/t/t_optm_if_array.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -18,6 +18,7 @@ execute( ); file_grep_not("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/rstn_r/); +file_grep_not("$Self->{obj_dir}/$Self->{VM_PREFIX}__Slow.cpp", qr/rstn_r/); ok(1); 1; diff --git a/test_regress/t/t_optm_redor.pl b/test_regress/t/t_optm_redor.pl index 0a7853f4a..21408ee20 100755 --- a/test_regress/t/t_optm_redor.pl +++ b/test_regress/t/t_optm_redor.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -18,6 +18,7 @@ execute( ); file_grep_not("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/rstn_r/); +file_grep_not("$Self->{obj_dir}/$Self->{VM_PREFIX}__Slow.cpp", qr/rstn_r/); ok(1); 1; diff --git a/test_regress/t/t_order.pl b/test_regress/t/t_order.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_order.pl +++ b/test_regress/t/t_order.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_order_2d.pl b/test_regress/t/t_order_2d.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_order_2d.pl +++ b/test_regress/t/t_order_2d.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_order_clkinst.out b/test_regress/t/t_order_clkinst.out index 2c1d5771e..98e8e114b 100644 --- a/test_regress/t/t_order_clkinst.out +++ b/test_regress/t/t_order_clkinst.out @@ -72,5 +72,5 @@ b00000011 $ #35 0/ #40 -b00000100 $ 1/ +b00000100 $ diff --git a/test_regress/t/t_order_clkinst.pl b/test_regress/t/t_order_clkinst.pl index b7178dc92..bc216950a 100755 --- a/test_regress/t/t_order_clkinst.pl +++ b/test_regress/t/t_order_clkinst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_order_clkinst_bad.pl b/test_regress/t/t_order_clkinst_bad.pl index 2617e225b..165ed807a 100755 --- a/test_regress/t/t_order_clkinst_bad.pl +++ b/test_regress/t/t_order_clkinst_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_order_comboclkloop.pl b/test_regress/t/t_order_comboclkloop.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_order_comboclkloop.pl +++ b/test_regress/t/t_order_comboclkloop.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_order_comboloop.pl b/test_regress/t/t_order_comboloop.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_order_comboloop.pl +++ b/test_regress/t/t_order_comboloop.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_order_doubleloop.pl b/test_regress/t/t_order_doubleloop.pl index a8a66f6ba..1f8ac0132 100755 --- a/test_regress/t/t_order_doubleloop.pl +++ b/test_regress/t/t_order_doubleloop.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(simulator => 1); -my $fail = ($Self->{vlt_all} && verilator_version() !~ /\(ord\)/); +my $fail = $Self->{vlt_all}; compile( ); diff --git a/test_regress/t/t_order_first.pl b/test_regress/t/t_order_first.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_order_first.pl +++ b/test_regress/t/t_order_first.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_order_loop_bad.pl b/test_regress/t/t_order_loop_bad.pl index d73ccbb11..3d2c637a8 100755 --- a/test_regress/t/t_order_loop_bad.pl +++ b/test_regress/t/t_order_loop_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_order_multialways.pl b/test_regress/t/t_order_multialways.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_order_multialways.pl +++ b/test_regress/t/t_order_multialways.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_order_multidriven.pl b/test_regress/t/t_order_multidriven.pl index a2245ee51..b03a52169 100755 --- a/test_regress/t/t_order_multidriven.pl +++ b/test_regress/t/t_order_multidriven.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_order_quad.cpp b/test_regress/t/t_order_quad.cpp index 700e18ca5..fb9da0545 100644 --- a/test_regress/t/t_order_quad.cpp +++ b/test_regress/t/t_order_quad.cpp @@ -32,11 +32,11 @@ int main(int argc, char* argv[]) { topp->a0 = 0; topp->eval(); - check(topp->y, VL_ULL(0x0)); + check(topp->y, 0x0ULL); topp->a0 = 15; topp->eval(); - check(topp->y, VL_ULL(0x3c00000000)); + check(topp->y, 0x3c00000000ULL); topp->final(); if (!fail) { diff --git a/test_regress/t/t_order_quad.pl b/test_regress/t/t_order_quad.pl index 04b9aeb1c..68cbf7858 100755 --- a/test_regress/t/t_order_quad.pl +++ b/test_regress/t/t_order_quad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_order_wireloop.pl b/test_regress/t/t_order_wireloop.pl index 0fb5aa1b3..ffee37678 100755 --- a/test_regress/t/t_order_wireloop.pl +++ b/test_regress/t/t_order_wireloop.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_package.pl b/test_regress/t/t_package.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_package.pl +++ b/test_regress/t/t_package.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_package_abs.pl b/test_regress/t/t_package_abs.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_package_abs.pl +++ b/test_regress/t/t_package_abs.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_package_ddecl.pl b/test_regress/t/t_package_ddecl.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_package_ddecl.pl +++ b/test_regress/t/t_package_ddecl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_package_dimport.pl b/test_regress/t/t_package_dimport.pl index 02efadae6..1e8c14055 100755 --- a/test_regress/t/t_package_dimport.pl +++ b/test_regress/t/t_package_dimport.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_package_dot.pl b/test_regress/t/t_package_dot.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_package_dot.pl +++ b/test_regress/t/t_package_dot.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_package_enum.pl b/test_regress/t/t_package_enum.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_package_enum.pl +++ b/test_regress/t/t_package_enum.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_package_export.pl b/test_regress/t/t_package_export.pl index 8fe275fdc..97878d3f5 100755 --- a/test_regress/t/t_package_export.pl +++ b/test_regress/t/t_package_export.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_package_export.v b/test_regress/t/t_package_export.v index 4118f94ac..320261f3f 100644 --- a/test_regress/t/t_package_export.v +++ b/test_regress/t/t_package_export.v @@ -40,6 +40,9 @@ package pkg30; `ifdef T_PACKAGE_EXPORT export pkg1::PARAM2; export pkg1::PARAM3; +`endif +`ifdef T_PACKAGE_EXPORT_BAD + export pkg1::BAD_DOES_NOT_EXIST; `endif parameter PARAM1 = 8; endpackage diff --git a/test_regress/t/t_package_export_bad.out b/test_regress/t/t_package_export_bad.out index 94ff0920b..98c2ef9a9 100644 --- a/test_regress/t/t_package_export_bad.out +++ b/test_regress/t/t_package_export_bad.out @@ -1,25 +1,28 @@ -%Error: t/t_package_export.v:57:16: Can't find definition of scope/variable: 'PARAM2' +%Error: t/t_package_export.v:45:17: Export object not found: 'pkg1::BAD_DOES_NOT_EXIST' + 45 | export pkg1::BAD_DOES_NOT_EXIST; + | ^~~~~~~~~~~~~~~~~~ +%Error: t/t_package_export.v:60:16: Can't find definition of scope/variable: 'PARAM2' : ... Suggested alternative: 'PARAM1' - 57 | reg [pkg11::PARAM2 : 0] bus12; + 60 | reg [pkg11::PARAM2 : 0] bus12; | ^~~~~~ -%Error: t/t_package_export.v:58:16: Can't find definition of scope/variable: 'PARAM3' +%Error: t/t_package_export.v:61:16: Can't find definition of scope/variable: 'PARAM3' : ... Suggested alternative: 'PARAM1' - 58 | reg [pkg11::PARAM3 : 0] bus13; + 61 | reg [pkg11::PARAM3 : 0] bus13; | ^~~~~~ -%Error: t/t_package_export.v:61:16: Can't find definition of scope/variable: 'PARAM2' +%Error: t/t_package_export.v:64:16: Can't find definition of scope/variable: 'PARAM2' : ... Suggested alternative: 'PARAM1' - 61 | reg [pkg21::PARAM2 : 0] bus22; + 64 | reg [pkg21::PARAM2 : 0] bus22; | ^~~~~~ -%Error: t/t_package_export.v:62:16: Can't find definition of scope/variable: 'PARAM3' +%Error: t/t_package_export.v:65:16: Can't find definition of scope/variable: 'PARAM3' : ... Suggested alternative: 'PARAM1' - 62 | reg [pkg21::PARAM3 : 0] bus23; + 65 | reg [pkg21::PARAM3 : 0] bus23; | ^~~~~~ -%Error: t/t_package_export.v:65:16: Can't find definition of scope/variable: 'PARAM2' +%Error: t/t_package_export.v:68:16: Can't find definition of scope/variable: 'PARAM2' : ... Suggested alternative: 'PARAM1' - 65 | reg [pkg31::PARAM2 : 0] bus32; + 68 | reg [pkg31::PARAM2 : 0] bus32; | ^~~~~~ -%Error: t/t_package_export.v:66:16: Can't find definition of scope/variable: 'PARAM3' +%Error: t/t_package_export.v:69:16: Can't find definition of scope/variable: 'PARAM3' : ... Suggested alternative: 'PARAM1' - 66 | reg [pkg31::PARAM3 : 0] bus33; + 69 | reg [pkg31::PARAM3 : 0] bus33; | ^~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_package_export_bad.pl b/test_regress/t/t_package_export_bad.pl index ebec1a74f..e454e2252 100755 --- a/test_regress/t/t_package_export_bad.pl +++ b/test_regress/t/t_package_export_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_package_param.pl b/test_regress/t/t_package_param.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_package_param.pl +++ b/test_regress/t/t_package_param.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_package_twodeep.pl b/test_regress/t/t_package_twodeep.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_package_twodeep.pl +++ b/test_regress/t/t_package_twodeep.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_package_verb.pl b/test_regress/t/t_package_verb.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_package_verb.pl +++ b/test_regress/t/t_package_verb.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_packed_concat_bad.pl b/test_regress/t/t_packed_concat_bad.pl index 8bc59ae60..27159da5b 100755 --- a/test_regress/t/t_packed_concat_bad.pl +++ b/test_regress/t/t_packed_concat_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_param.pl b/test_regress/t/t_param.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param.pl +++ b/test_regress/t/t_param.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_array.pl b/test_regress/t/t_param_array.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_array.pl +++ b/test_regress/t/t_param_array.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_array2.pl b/test_regress/t/t_param_array2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_array2.pl +++ b/test_regress/t/t_param_array2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_array3.pl b/test_regress/t/t_param_array3.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_array3.pl +++ b/test_regress/t/t_param_array3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_array4.pl b/test_regress/t/t_param_array4.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_array4.pl +++ b/test_regress/t/t_param_array4.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_array5.pl b/test_regress/t/t_param_array5.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_array5.pl +++ b/test_regress/t/t_param_array5.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_avec.pl b/test_regress/t/t_param_avec.pl index 44c71cb71..9829facd7 100755 --- a/test_regress/t/t_param_avec.pl +++ b/test_regress/t/t_param_avec.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_bit_sel.pl b/test_regress/t/t_param_bit_sel.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_bit_sel.pl +++ b/test_regress/t/t_param_bit_sel.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_ceil.pl b/test_regress/t/t_param_ceil.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_ceil.pl +++ b/test_regress/t/t_param_ceil.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_chain.pl b/test_regress/t/t_param_chain.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_chain.pl +++ b/test_regress/t/t_param_chain.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_circ_bad.pl b/test_regress/t/t_param_circ_bad.pl index 8e4fecbdb..a82cf66cb 100755 --- a/test_regress/t/t_param_circ_bad.pl +++ b/test_regress/t/t_param_circ_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_concat.pl b/test_regress/t/t_param_concat.pl index 47a8cad0b..563fa5dd7 100755 --- a/test_regress/t/t_param_concat.pl +++ b/test_regress/t/t_param_concat.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_concat_bad.pl b/test_regress/t/t_param_concat_bad.pl index 550235b23..33177b739 100755 --- a/test_regress/t/t_param_concat_bad.pl +++ b/test_regress/t/t_param_concat_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_const_part.pl b/test_regress/t/t_param_const_part.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_const_part.pl +++ b/test_regress/t/t_param_const_part.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_ddeep_width.pl b/test_regress/t/t_param_ddeep_width.pl index a4d74c0ba..13c6e2b71 100755 --- a/test_regress/t/t_param_ddeep_width.pl +++ b/test_regress/t/t_param_ddeep_width.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_default.pl b/test_regress/t/t_param_default.pl index 333d76a24..371f9ce97 100755 --- a/test_regress/t/t_param_default.pl +++ b/test_regress/t/t_param_default.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_default_bad.pl b/test_regress/t/t_param_default_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_param_default_bad.pl +++ b/test_regress/t/t_param_default_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_default_presv_bad.pl b/test_regress/t/t_param_default_presv_bad.pl index abf6ec05e..7cc88a04c 100755 --- a/test_regress/t/t_param_default_presv_bad.pl +++ b/test_regress/t/t_param_default_presv_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_first.pl b/test_regress/t/t_param_first.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_first.pl +++ b/test_regress/t/t_param_first.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_func.pl b/test_regress/t/t_param_func.pl index d1bf185c9..552bd97db 100755 --- a/test_regress/t/t_param_func.pl +++ b/test_regress/t/t_param_func.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_if_blk.pl b/test_regress/t/t_param_if_blk.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_if_blk.pl +++ b/test_regress/t/t_param_if_blk.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_in_func_bad.pl b/test_regress/t/t_param_in_func_bad.pl index 1ea1f5c79..418f60621 100755 --- a/test_regress/t/t_param_in_func_bad.pl +++ b/test_regress/t/t_param_in_func_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_local.pl b/test_regress/t/t_param_local.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_local.pl +++ b/test_regress/t/t_param_local.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_long.pl b/test_regress/t/t_param_long.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_long.pl +++ b/test_regress/t/t_param_long.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_mem_attr.pl b/test_regress/t/t_param_mem_attr.pl index cec0590f8..184ceb13d 100755 --- a/test_regress/t/t_param_mem_attr.pl +++ b/test_regress/t/t_param_mem_attr.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_module.pl b/test_regress/t/t_param_module.pl index f0260d694..9270d7e08 100755 --- a/test_regress/t/t_param_module.pl +++ b/test_regress/t/t_param_module.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_named.pl b/test_regress/t/t_param_named.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_named.pl +++ b/test_regress/t/t_param_named.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_named_2.pl b/test_regress/t/t_param_named_2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_named_2.pl +++ b/test_regress/t/t_param_named_2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_no_parentheses.pl b/test_regress/t/t_param_no_parentheses.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_no_parentheses.pl +++ b/test_regress/t/t_param_no_parentheses.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_noval_bad.pl b/test_regress/t/t_param_noval_bad.pl index 8e4fecbdb..a82cf66cb 100755 --- a/test_regress/t/t_param_noval_bad.pl +++ b/test_regress/t/t_param_noval_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_package.pl b/test_regress/t/t_param_package.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_package.pl +++ b/test_regress/t/t_param_package.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_public.pl b/test_regress/t/t_param_public.pl index ae7a261c5..345560283 100755 --- a/test_regress/t/t_param_public.pl +++ b/test_regress/t/t_param_public.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_real.pl b/test_regress/t/t_param_real.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_real.pl +++ b/test_regress/t/t_param_real.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_real2.pl b/test_regress/t/t_param_real2.pl index ce21a8188..8d96a573a 100755 --- a/test_regress/t/t_param_real2.pl +++ b/test_regress/t/t_param_real2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_real2_collision.pl b/test_regress/t/t_param_real2_collision.pl index 8f0c687e0..bcb6b3d38 100755 --- a/test_regress/t/t_param_real2_collision.pl +++ b/test_regress/t/t_param_real2_collision.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_repl.pl b/test_regress/t/t_param_repl.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_repl.pl +++ b/test_regress/t/t_param_repl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_scope_bad.pl b/test_regress/t/t_param_scope_bad.pl index f3dd1d2a1..35d749208 100755 --- a/test_regress/t/t_param_scope_bad.pl +++ b/test_regress/t/t_param_scope_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_seg.pl b/test_regress/t/t_param_seg.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_seg.pl +++ b/test_regress/t/t_param_seg.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_sel.pl b/test_regress/t/t_param_sel.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_sel.pl +++ b/test_regress/t/t_param_sel.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_sel_range.pl b/test_regress/t/t_param_sel_range.pl index 6e59f9f23..0a78f9749 100755 --- a/test_regress/t/t_param_sel_range.pl +++ b/test_regress/t/t_param_sel_range.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_sel_range_bad.pl b/test_regress/t/t_param_sel_range_bad.pl index 25a5b6d0d..d1780f53f 100755 --- a/test_regress/t/t_param_sel_range_bad.pl +++ b/test_regress/t/t_param_sel_range_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_shift.pl b/test_regress/t/t_param_shift.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_shift.pl +++ b/test_regress/t/t_param_shift.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_type.pl b/test_regress/t/t_param_type.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_type.pl +++ b/test_regress/t/t_param_type.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_type.v b/test_regress/t/t_param_type.v index 9d6accc31..a61fb1b77 100644 --- a/test_regress/t/t_param_type.v +++ b/test_regress/t/t_param_type.v @@ -49,6 +49,10 @@ module t (/*AUTOARG*/ mod_typ #(.TYP (bit [23:0] )) mod_ar1d (clk, cnt_ar1d[24-1:0], siz_ar1d); mod_typ #(.TYP (bit [3:0][3:0])) mod_ar2d (clk, cnt_ar2d[16-1:0], siz_ar2d); + // double types + mod_typ2 #(.WIDTH1(3), .WIDTH2(3), .TYP1(bit [2:0])) mod2_3_3(); + mod_typ2 #(.WIDTH1(3), .WIDTH2(5), .TYP1(bit [2:0]), .TYP2(bit[4:0])) mod2_3_5(); + endmodule : t @@ -68,3 +72,21 @@ module mod_typ #( assign siz = $bits (cnt); endmodule + +module mod_typ2 #( + parameter int WIDTH1 = 0, + parameter int WIDTH2 = WIDTH1, + parameter type TYP1 = byte, + //UNSUP not needing 'parameter type' below and implying it + parameter type TYP2 = TYP1 + )(); + + TYP1 t1; + TYP2 t2; + + initial begin + if ($bits(t1) != WIDTH1) $stop; + if ($bits(t2) != WIDTH2) $stop; + end + +endmodule diff --git a/test_regress/t/t_param_type2.pl b/test_regress/t/t_param_type2.pl index 9abe0d581..00de9b0a7 100755 --- a/test_regress/t/t_param_type2.pl +++ b/test_regress/t/t_param_type2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_type3.pl b/test_regress/t/t_param_type3.pl index 9abe0d581..00de9b0a7 100755 --- a/test_regress/t/t_param_type3.pl +++ b/test_regress/t/t_param_type3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_type_bad.pl b/test_regress/t/t_param_type_bad.pl index 5cfa596fd..7e61cd843 100755 --- a/test_regress/t/t_param_type_bad.pl +++ b/test_regress/t/t_param_type_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_type_bad2.pl b/test_regress/t/t_param_type_bad2.pl index e749f6d6d..b12ecf9cf 100755 --- a/test_regress/t/t_param_type_bad2.pl +++ b/test_regress/t/t_param_type_bad2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_type_collision.pl b/test_regress/t/t_param_type_collision.pl index babaa90eb..b7dcfce11 100755 --- a/test_regress/t/t_param_type_collision.pl +++ b/test_regress/t/t_param_type_collision.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_up_bad.pl b/test_regress/t/t_param_up_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_param_up_bad.pl +++ b/test_regress/t/t_param_up_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_value.pl b/test_regress/t/t_param_value.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_value.pl +++ b/test_regress/t/t_param_value.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_while.pl b/test_regress/t/t_param_while.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_param_while.pl +++ b/test_regress/t/t_param_while.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_wide_io.pl b/test_regress/t/t_param_wide_io.pl index a96625ee7..bc18ea2b2 100755 --- a/test_regress/t/t_param_wide_io.pl +++ b/test_regress/t/t_param_wide_io.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_param_width_loc_bad.pl b/test_regress/t/t_param_width_loc_bad.pl index 9180cf4ec..1ce49be3f 100755 --- a/test_regress/t/t_param_width_loc_bad.pl +++ b/test_regress/t/t_param_width_loc_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_parse_delay.pl b/test_regress/t/t_parse_delay.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_parse_delay.pl +++ b/test_regress/t/t_parse_delay.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_past.pl b/test_regress/t/t_past.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_past.pl +++ b/test_regress/t/t_past.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_past_bad.pl b/test_regress/t/t_past_bad.pl index bfd1147c6..a5846c699 100755 --- a/test_regress/t/t_past_bad.pl +++ b/test_regress/t/t_past_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(vlt => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_past_unsup_bad.pl b/test_regress/t/t_past_unsup_bad.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_past_unsup_bad.pl +++ b/test_regress/t/t_past_unsup_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pipe_exit_bad.pf b/test_regress/t/t_pipe_exit_bad.pf index a1302b938..9aa87394d 100644 --- a/test_regress/t/t_pipe_exit_bad.pf +++ b/test_regress/t/t_pipe_exit_bad.pf @@ -1,4 +1,5 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl +use warnings; # DESCRIPTION: Verilator: Verilog Test example --pipe-filter script # # Copyright 2010 by Wilson Snyder. This program is free software; you diff --git a/test_regress/t/t_pipe_exit_bad.pl b/test_regress/t/t_pipe_exit_bad.pl index 59c3c659b..ed3afdee3 100755 --- a/test_regress/t/t_pipe_exit_bad.pl +++ b/test_regress/t/t_pipe_exit_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pipe_filter.pf b/test_regress/t/t_pipe_filter.pf index 82604c63b..4e602fd7c 100644 --- a/test_regress/t/t_pipe_filter.pf +++ b/test_regress/t/t_pipe_filter.pf @@ -1,4 +1,5 @@ -#!/usr/bin/perl -w +#!/usr/bin/env perl +use warnings; # DESCRIPTION: Verilator: Verilog Test example --pipe-filter script # # Copyright 2010 by Wilson Snyder. This program is free software; you diff --git a/test_regress/t/t_pipe_filter.pl b/test_regress/t/t_pipe_filter.pl index 24f7aa9bb..a85cf653e 100755 --- a/test_regress/t/t_pipe_filter.pl +++ b/test_regress/t/t_pipe_filter.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pli_bad.out b/test_regress/t/t_pli_bad.out new file mode 100644 index 000000000..b1f752c4f --- /dev/null +++ b/test_regress/t/t_pli_bad.out @@ -0,0 +1,13 @@ +%Error: t/t_pli_bad.v:10:7: Unsupported or unknown PLI call: '$unknown_pli_task' + 10 | $unknown_pli_task; + | ^~~~~~~~~~~~~~~~~ +%Error: t/t_pli_bad.v:11:7: Unsupported or unknown PLI call: '$unknown_pli_task' + 11 | $unknown_pli_task("arg", i); + | ^~~~~~~~~~~~~~~~~ +%Error: t/t_pli_bad.v:12:11: Unsupported or unknown PLI call: '$unknown_pli_function' + 12 | i = $unknown_pli_function; + | ^~~~~~~~~~~~~~~~~~~~~ +%Error: t/t_pli_bad.v:13:11: Unsupported or unknown PLI call: '$unknown_pli_function' + 13 | i = $unknown_pli_function("arg", i); + | ^~~~~~~~~~~~~~~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_pli_bad.pl b/test_regress/t/t_pli_bad.pl new file mode 100755 index 000000000..828e0df38 --- /dev/null +++ b/test_regress/t/t_pli_bad.pl @@ -0,0 +1,20 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(linter => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); + +1; diff --git a/test_regress/t/t_pli_bad.v b/test_regress/t/t_pli_bad.v new file mode 100644 index 000000000..5ae542377 --- /dev/null +++ b/test_regress/t/t_pli_bad.v @@ -0,0 +1,16 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2019 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t; + integer i; + initial begin + $unknown_pli_task; + $unknown_pli_task("arg", i); + i = $unknown_pli_function; + i = $unknown_pli_function("arg", i); + $stop; + end +endmodule diff --git a/test_regress/t/t_pli_bbox.pl b/test_regress/t/t_pli_bbox.pl new file mode 100755 index 000000000..b30ede91e --- /dev/null +++ b/test_regress/t/t_pli_bbox.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(vlt => 1); + +top_filename("t/t_pli_bad.v"); + +lint( + verilator_flags2 => ["--bbox-sys"], + ); + +ok(1); + +1; diff --git a/test_regress/t/t_pp_circ_subst_bad.pl b/test_regress/t/t_pp_circ_subst_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_pp_circ_subst_bad.pl +++ b/test_regress/t/t_pp_circ_subst_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pp_circdef_bad.pl b/test_regress/t/t_pp_circdef_bad.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_pp_circdef_bad.pl +++ b/test_regress/t/t_pp_circdef_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pp_defkwd_bad.pl b/test_regress/t/t_pp_defkwd_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_pp_defkwd_bad.pl +++ b/test_regress/t/t_pp_defkwd_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pp_defparen_bad.pl b/test_regress/t/t_pp_defparen_bad.pl index bbd90df9f..9de6b85ee 100755 --- a/test_regress/t/t_pp_defparen_bad.pl +++ b/test_regress/t/t_pp_defparen_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pp_display.pl b/test_regress/t/t_pp_display.pl index 4b7e1d16f..761258c0e 100755 --- a/test_regress/t/t_pp_display.pl +++ b/test_regress/t/t_pp_display.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pp_dupdef.pl b/test_regress/t/t_pp_dupdef.pl index cabafdf50..723508870 100755 --- a/test_regress/t/t_pp_dupdef.pl +++ b/test_regress/t/t_pp_dupdef.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pp_dupdef_bad.pl b/test_regress/t/t_pp_dupdef_bad.pl index e9a4794a7..b2d49e566 100755 --- a/test_regress/t/t_pp_dupdef_bad.pl +++ b/test_regress/t/t_pp_dupdef_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pp_lib.pl b/test_regress/t/t_pp_lib.pl index ca19fd9bf..921a3878f 100755 --- a/test_regress/t/t_pp_lib.pl +++ b/test_regress/t/t_pp_lib.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pp_line_bad.pl b/test_regress/t/t_pp_line_bad.pl index bbd90df9f..9de6b85ee 100755 --- a/test_regress/t/t_pp_line_bad.pl +++ b/test_regress/t/t_pp_line_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pp_misdef_bad.pl b/test_regress/t/t_pp_misdef_bad.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_pp_misdef_bad.pl +++ b/test_regress/t/t_pp_misdef_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pp_pragma_bad.pl b/test_regress/t/t_pp_pragma_bad.pl index 9e2158836..219eb9526 100755 --- a/test_regress/t/t_pp_pragma_bad.pl +++ b/test_regress/t/t_pp_pragma_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pp_pragmas.pl b/test_regress/t/t_pp_pragmas.pl index 3b6486e92..b26f9434f 100755 --- a/test_regress/t/t_pp_pragmas.pl +++ b/test_regress/t/t_pp_pragmas.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pp_resetall_bad.pl b/test_regress/t/t_pp_resetall_bad.pl index 1be077634..bfb6f2bb1 100755 --- a/test_regress/t/t_pp_resetall_bad.pl +++ b/test_regress/t/t_pp_resetall_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_pp_underline_bad.pl b/test_regress/t/t_pp_underline_bad.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_pp_underline_bad.pl +++ b/test_regress/t/t_pp_underline_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc.pl b/test_regress/t/t_preproc.pl index 625065541..930deb5d7 100755 --- a/test_regress/t/t_preproc.pl +++ b/test_regress/t/t_preproc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_cmtend_bad.pl b/test_regress/t/t_preproc_cmtend_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_preproc_cmtend_bad.pl +++ b/test_regress/t/t_preproc_cmtend_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_comments.pl b/test_regress/t/t_preproc_comments.pl index 1773d00f9..7aa405ee4 100755 --- a/test_regress/t/t_preproc_comments.pl +++ b/test_regress/t/t_preproc_comments.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_def09.pl b/test_regress/t/t_preproc_def09.pl index c31a87dbc..e0a41bb51 100755 --- a/test_regress/t/t_preproc_def09.pl +++ b/test_regress/t/t_preproc_def09.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_defines.pl b/test_regress/t/t_preproc_defines.pl index 936036834..c632aecf7 100755 --- a/test_regress/t/t_preproc_defines.pl +++ b/test_regress/t/t_preproc_defines.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_dos.pl b/test_regress/t/t_preproc_dos.pl index d203cf947..166adf78f 100755 --- a/test_regress/t/t_preproc_dos.pl +++ b/test_regress/t/t_preproc_dos.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_ifdef.pl b/test_regress/t/t_preproc_ifdef.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_preproc_ifdef.pl +++ b/test_regress/t/t_preproc_ifdef.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_inc_bad.pl b/test_regress/t/t_preproc_inc_bad.pl index 523cfcda1..cdeb5a8e1 100755 --- a/test_regress/t/t_preproc_inc_bad.pl +++ b/test_regress/t/t_preproc_inc_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_inc_notfound_bad.pl b/test_regress/t/t_preproc_inc_notfound_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_preproc_inc_notfound_bad.pl +++ b/test_regress/t/t_preproc_inc_notfound_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_inc_recurse_bad.pl b/test_regress/t/t_preproc_inc_recurse_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_preproc_inc_recurse_bad.pl +++ b/test_regress/t/t_preproc_inc_recurse_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_kwd.pl b/test_regress/t/t_preproc_kwd.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_preproc_kwd.pl +++ b/test_regress/t/t_preproc_kwd.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_noline.pl b/test_regress/t/t_preproc_noline.pl index 7d1bd17f1..6ecbb7651 100755 --- a/test_regress/t/t_preproc_noline.pl +++ b/test_regress/t/t_preproc_noline.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_persist.pl b/test_regress/t/t_preproc_persist.pl index e6025e6ab..4f6ffcf30 100755 --- a/test_regress/t/t_preproc_persist.pl +++ b/test_regress/t/t_preproc_persist.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_stringend_bad.pl b/test_regress/t/t_preproc_stringend_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_preproc_stringend_bad.pl +++ b/test_regress/t/t_preproc_stringend_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_ttempty.pl b/test_regress/t/t_preproc_ttempty.pl index 7c5e3d3c6..411276940 100755 --- a/test_regress/t/t_preproc_ttempty.pl +++ b/test_regress/t/t_preproc_ttempty.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_preproc_undefineall.pl b/test_regress/t/t_preproc_undefineall.pl index 5634c06de..26a1f8cbb 100755 --- a/test_regress/t/t_preproc_undefineall.pl +++ b/test_regress/t/t_preproc_undefineall.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_program.pl b/test_regress/t/t_program.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_program.pl +++ b/test_regress/t/t_program.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_prot_lib.pl b/test_regress/t/t_prot_lib.pl index fa5e18254..993d8fb75 100755 --- a/test_regress/t/t_prot_lib.pl +++ b/test_regress/t/t_prot_lib.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Makes the test run with tracing enabled by default, can be overridden # with --notrace unshift(@ARGV, "--trace"); @@ -35,11 +35,13 @@ while (1) { $secret_dir, "--protect-lib", $secret_prefix, - "t/t_prot_lib_secret.v"]); + "t/t_prot_lib_secret.v"], + verilator_run => 1, + ); last if $Self->{errors}; run(logfile => "$secret_dir/secret_gcc.log", - cmd=>["make", + cmd=>[$ENV{MAKE}, "-C", $secret_dir, "-f", diff --git a/test_regress/t/t_prot_lib_clk_gated.pl b/test_regress/t/t_prot_lib_clk_gated.pl index 9c89a6b89..69b9e9ccc 100755 --- a/test_regress/t/t_prot_lib_clk_gated.pl +++ b/test_regress/t/t_prot_lib_clk_gated.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Makes the test run with tracing enabled by default, can be overridden # with --notrace unshift(@ARGV, "--trace"); @@ -37,11 +37,13 @@ while (1) { "-GGATED_CLK=1", "--protect-lib", $secret_prefix, - "t/t_prot_lib_secret.v"]); + "t/t_prot_lib_secret.v"], + verilator_run => 1, + ); last if $Self->{errors}; run(logfile => "$secret_dir/secret_gcc.log", - cmd=>["make", + cmd=>[$ENV{MAKE}, "-C", $secret_dir, "-f", diff --git a/test_regress/t/t_prot_lib_inout_bad.pl b/test_regress/t/t_prot_lib_inout_bad.pl index 3969ea7f3..955f6793e 100755 --- a/test_regress/t/t_prot_lib_inout_bad.pl +++ b/test_regress/t/t_prot_lib_inout_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_prot_lib_secret.pl b/test_regress/t/t_prot_lib_secret.pl index 1a2556857..18efa9ff7 100755 --- a/test_regress/t/t_prot_lib_secret.pl +++ b/test_regress/t/t_prot_lib_secret.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,9 +10,6 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(vlt => 1); -$Self->{make_main} = 0; -$Self->{make_top_shell} = 0; - compile ( verilator_flags2 => ["--protect-lib", "secret", @@ -20,9 +17,11 @@ compile ( "SECRET_FAKE_KEY"], verilator_make_gcc => 0, verilator_make_gmake => 0, + make_main => 0, + make_top_shell => 0, ); -run(cmd=>["make", +run(cmd=>[$ENV{MAKE}, "-C", "$Self->{obj_dir}", "-f", diff --git a/test_regress/t/t_prot_lib_unpacked_bad.pl b/test_regress/t/t_prot_lib_unpacked_bad.pl index 3969ea7f3..955f6793e 100755 --- a/test_regress/t/t_prot_lib_unpacked_bad.pl +++ b/test_regress/t/t_prot_lib_unpacked_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_protect_ids.pl b/test_regress/t/t_protect_ids.pl index b4c0d2cd4..371f5e0a7 100755 --- a/test_regress/t/t_protect_ids.pl +++ b/test_regress/t/t_protect_ids.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_protect_ids_bad.pl b/test_regress/t/t_protect_ids_bad.pl index 11451f1f9..47ea4d4e1 100755 --- a/test_regress/t/t_protect_ids_bad.pl +++ b/test_regress/t/t_protect_ids_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_protect_ids_key.out b/test_regress/t/t_protect_ids_key.out index 036238fb8..cfb58b841 100644 --- a/test_regress/t/t_protect_ids_key.out +++ b/test_regress/t/t_protect_ids_key.out @@ -22,6 +22,7 @@ + diff --git a/test_regress/t/t_protect_ids_key.pl b/test_regress/t/t_protect_ids_key.pl index d00f7890d..e1dd48942 100755 --- a/test_regress/t/t_protect_ids_key.pl +++ b/test_regress/t/t_protect_ids_key.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_queue.pl b/test_regress/t/t_queue.pl index e02817219..9a15dd2cc 100755 --- a/test_regress/t/t_queue.pl +++ b/test_regress/t/t_queue.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_queue.v b/test_regress/t/t_queue.v index a590d33ae..a51ed63fe 100644 --- a/test_regress/t/t_queue.v +++ b/test_regress/t/t_queue.v @@ -19,6 +19,13 @@ module t (/*AUTOARG*/ integer i; + typedef integer q_t[$]; + + initial begin + q_t iq; + iq.push_back(42); + end + always @ (posedge clk) begin cyc <= cyc + 1; @@ -123,6 +130,7 @@ module t (/*AUTOARG*/ v = q[2]; `checks(v, "b1"); v = q[3]; `checks(v, "b2"); v = q[4]; `checks(v, ""); + //Unsup: `checkh(q[$], "b2"); v = $sformatf("%p", q); `checks(v, "'{\"f2\", \"f1\", \"b1\", \"b2\"} "); @@ -170,6 +178,7 @@ module t (/*AUTOARG*/ q.delete(0); i = q.size(); `checkh(i, 1); `checks(q[0], "front"); + //Unsup: `checks(q[$], "front"); end @@ -186,6 +195,45 @@ module t (/*AUTOARG*/ end + // testing a wide queue + begin + typedef struct packed { + bit [7:0] opcode; + bit [23:0] addr; + bit [127:0] data; + } instructionW; // named structure type + + instructionW inst_push; + instructionW inst_pop; + + instructionW q[$]; + `checkh($dimensions(q), 2); + + `checkh(q[0].opcode, 0); + `checkh(q[0].addr, 0); + `checkh(q[0].data, 0); + + inst_push.opcode = 1; + inst_push.addr = 42; + inst_push.data = {4{32'hdeadbeef}}; + q.push_back(inst_push); + `checkh(q[0].opcode, 1); + `checkh(q[0].addr, 42); + `checkh(q[0].data, {4{32'hdeadbeef}}); + + + inst_pop = q.pop_front(); + `checkh(inst_pop.opcode, 1); + `checkh(inst_pop.addr, 42); + `checkh(inst_pop.data, {4{32'hdeadbeef}}); + + `checkh(q.size(), 0); + + `checkh(q[0].opcode, 0); + `checkh(q[0].addr, 0); + `checkh(q[0].data, 0); + end + /* Unsup: begin int q[4][$]; diff --git a/test_regress/t/t_queue_bounded.pl b/test_regress/t/t_queue_bounded.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_queue_bounded.pl +++ b/test_regress/t/t_queue_bounded.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_queue_unsup_bad.out b/test_regress/t/t_queue_unsup_bad.out index 8c82b034b..7ba5976d4 100644 --- a/test_regress/t/t_queue_unsup_bad.out +++ b/test_regress/t/t_queue_unsup_bad.out @@ -34,10 +34,6 @@ : ... In instance t 38 | q = {q[0], q[2:$]}; | ^ -%Error: t/t_queue_unsup_bad.v:38:22: Expecting expression to be constant, but can't convert a UNBOUNDED to constant. - : ... In instance t - 38 | q = {q[0], q[2:$]}; - | ^ %Error: t/t_queue_unsup_bad.v:38:22: First value of [a:b] isn't a constant, maybe you want +: or -: : ... In instance t 38 | q = {q[0], q[2:$]}; diff --git a/test_regress/t/t_queue_unsup_bad.pl b/test_regress/t/t_queue_unsup_bad.pl index bfd1147c6..b9057722c 100755 --- a/test_regress/t/t_queue_unsup_bad.pl +++ b/test_regress/t/t_queue_unsup_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_real_param.pl b/test_regress/t/t_real_param.pl index f4ca8a9d8..ec4c9a6e4 100755 --- a/test_regress/t/t_real_param.pl +++ b/test_regress/t/t_real_param.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_reloop_cam.pl b/test_regress/t/t_reloop_cam.pl index 6136a1112..e6d8da916 100755 --- a/test_regress/t/t_reloop_cam.pl +++ b/test_regress/t/t_reloop_cam.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_repeat.pl b/test_regress/t/t_repeat.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_repeat.pl +++ b/test_regress/t/t_repeat.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_rnd.pl b/test_regress/t/t_rnd.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_rnd.pl +++ b/test_regress/t/t_rnd.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_runflag.pl b/test_regress/t/t_runflag.pl index 99dd267a6..f15ca2e20 100755 --- a/test_regress/t/t_runflag.pl +++ b/test_regress/t/t_runflag.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_runflag_errorlimit.pl b/test_regress/t/t_runflag_errorlimit.pl index 638425fb0..6651f9189 100755 --- a/test_regress/t/t_runflag_errorlimit.pl +++ b/test_regress/t/t_runflag_errorlimit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_runflag_seed.pl b/test_regress/t/t_runflag_seed.pl index d30b5a08d..84674f3e9 100755 --- a/test_regress/t/t_runflag_seed.pl +++ b/test_regress/t/t_runflag_seed.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_savable.pl b/test_regress/t/t_savable.pl index f693b79f4..87137cbe3 100755 --- a/test_regress/t/t_savable.pl +++ b/test_regress/t/t_savable.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_savable_class_bad.pl b/test_regress/t/t_savable_class_bad.pl index fdcacb7d3..3911aee04 100755 --- a/test_regress/t/t_savable_class_bad.pl +++ b/test_regress/t/t_savable_class_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_scope_map.pl b/test_regress/t/t_scope_map.pl index ac72b1aa1..03dbdc1fd 100755 --- a/test_regress/t/t_scope_map.pl +++ b/test_regress/t/t_scope_map.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_bad_msb.pl b/test_regress/t/t_select_bad_msb.pl index 92e61ce57..a5846c699 100755 --- a/test_regress/t/t_select_bad_msb.pl +++ b/test_regress/t/t_select_bad_msb.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(vlt_all => 1); +scenarios(vlt => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_select_bad_range.pl b/test_regress/t/t_select_bad_range.pl index 056b9974f..59ba0d6c6 100755 --- a/test_regress/t/t_select_bad_range.pl +++ b/test_regress/t/t_select_bad_range.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_bad_range2.pl b/test_regress/t/t_select_bad_range2.pl index 056b9974f..59ba0d6c6 100755 --- a/test_regress/t/t_select_bad_range2.pl +++ b/test_regress/t/t_select_bad_range2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_bad_range3.pl b/test_regress/t/t_select_bad_range3.pl index 056b9974f..59ba0d6c6 100755 --- a/test_regress/t/t_select_bad_range3.pl +++ b/test_regress/t/t_select_bad_range3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_bad_tri.out b/test_regress/t/t_select_bad_tri.out index fd015e9f8..2fd802546 100644 --- a/test_regress/t/t_select_bad_tri.out +++ b/test_regress/t/t_select_bad_tri.out @@ -1,5 +1,7 @@ -%Error: t/t_select_bad_tri.v:11:13: Selection index is constantly unknown or tristated: lsb=7'bxxxxxxx width=32'sh47 - : ... In instance t +%Error: t/t_select_bad_tri.v:11:24: Selection index is constantly unknown or tristated: 1'bx 11 | if (in[( (1'h0 / 1'b0) )+:71] != 71'h0) $stop; - | ^ -%Error: Exiting due to + | ^ +%Error: Internal Error: t/t_select_bad_tri.v:11:24: ../V3Number.cpp:#: toUInt with 4-state 1'bx + : ... In instance t + 11 | if (in[( (1'h0 / 1'b0) )+:71] != 71'h0) $stop; + | ^ diff --git a/test_regress/t/t_select_bad_tri.pl b/test_regress/t/t_select_bad_tri.pl index 056b9974f..59ba0d6c6 100755 --- a/test_regress/t/t_select_bad_tri.pl +++ b/test_regress/t/t_select_bad_tri.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_bound1.pl b/test_regress/t/t_select_bound1.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_bound1.pl +++ b/test_regress/t/t_select_bound1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_bound2.pl b/test_regress/t/t_select_bound2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_bound2.pl +++ b/test_regress/t/t_select_bound2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_index.pl b/test_regress/t/t_select_index.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_index.pl +++ b/test_regress/t/t_select_index.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_index2.pl b/test_regress/t/t_select_index2.pl index a4d74c0ba..13c6e2b71 100755 --- a/test_regress/t/t_select_index2.pl +++ b/test_regress/t/t_select_index2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_lhs_oob.pl b/test_regress/t/t_select_lhs_oob.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_lhs_oob.pl +++ b/test_regress/t/t_select_lhs_oob.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_lhs_oob2.pl b/test_regress/t/t_select_lhs_oob2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_lhs_oob2.pl +++ b/test_regress/t/t_select_lhs_oob2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_little.pl b/test_regress/t/t_select_little.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_little.pl +++ b/test_regress/t/t_select_little.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_little_pack.pl b/test_regress/t/t_select_little_pack.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_little_pack.pl +++ b/test_regress/t/t_select_little_pack.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_loop.pl b/test_regress/t/t_select_loop.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_loop.pl +++ b/test_regress/t/t_select_loop.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_negative.pl b/test_regress/t/t_select_negative.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_negative.pl +++ b/test_regress/t/t_select_negative.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_param.pl b/test_regress/t/t_select_param.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_param.pl +++ b/test_regress/t/t_select_param.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_plus.pl b/test_regress/t/t_select_plus.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_plus.pl +++ b/test_regress/t/t_select_plus.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_plus.v b/test_regress/t/t_select_plus.v index 9d9e55879..247f166f8 100644 --- a/test_regress/t/t_select_plus.v +++ b/test_regress/t/t_select_plus.v @@ -74,4 +74,19 @@ module t (/*AUTOARG*/ endcase end + // Additional constant folding check - this used to trigger a bug + reg [23:0] a; + reg [3:0] b; + + initial begin + a = 24'd0; + b = 4'b0111; + a[3*(b[2:0]+0)+:3] = 3'd7; // Check LSB expression goes to 32-bits + if (a != 24'b11100000_00000000_00000000) $stop; + + a = 24'd0; + b = 4'b0110; + a[3*(b[2:0]+0)-:3] = 3'd7; // Check MSB expression goes to 32-bits + if (a != 24'b00000111_00000000_00000000) $stop; + end endmodule diff --git a/test_regress/t/t_select_plusloop.pl b/test_regress/t/t_select_plusloop.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_plusloop.pl +++ b/test_regress/t/t_select_plusloop.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_runtime_range.pl b/test_regress/t/t_select_runtime_range.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_runtime_range.pl +++ b/test_regress/t/t_select_runtime_range.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_select_set.pl b/test_regress/t/t_select_set.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_select_set.pl +++ b/test_regress/t/t_select_set.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_slice_cond.pl b/test_regress/t/t_slice_cond.pl index d1bf185c9..552bd97db 100755 --- a/test_regress/t/t_slice_cond.pl +++ b/test_regress/t/t_slice_cond.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_slice_init.pl b/test_regress/t/t_slice_init.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_slice_init.pl +++ b/test_regress/t/t_slice_init.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_slice_struct_array_modport.pl b/test_regress/t/t_slice_struct_array_modport.pl index a4d74c0ba..13c6e2b71 100755 --- a/test_regress/t/t_slice_struct_array_modport.pl +++ b/test_regress/t/t_slice_struct_array_modport.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_split_var_0.pl b/test_regress/t/t_split_var_0.pl index b401de638..0e94ef9ad 100755 --- a/test_regress/t/t_split_var_0.pl +++ b/test_regress/t/t_split_var_0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_split_var_1_bad.out b/test_regress/t/t_split_var_1_bad.out index b51f38b0b..96b602356 100644 --- a/test_regress/t/t_split_var_1_bad.out +++ b/test_regress/t/t_split_var_1_bad.out @@ -1,65 +1,48 @@ -%Warning-SPLITVAR: t/t_split_var_1_bad.v:7:13: 'should_show_warning_global0' has split_var metacomment, but will not be split because it is not declared in a module. - 7 | logic [7:0] should_show_warning_global0 /*verilator split_var*/ ; - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ - ... Use "/* verilator lint_off SPLITVAR */" and lint_on around source to disable this message. -%Warning-SPLITVAR: t/t_split_var_1_bad.v:8:13: 'should_show_warning_global1' has split_var metacomment, but will not be split because it is not declared in a module. - 8 | logic [7:0] should_show_warning_global1 [1:0] /*verilator split_var*/ ; - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ -%Warning-SPLITVAR: t/t_split_var_1_bad.v:11:16: 'should_show_warning_ifs0' has split_var metacomment, but will not be split because it is not declared in a module. - 11 | logic [7:0] should_show_warning_ifs0 /*verilator split_var*/ ; - | ^~~~~~~~~~~~~~~~~~~~~~~~ -%Warning-SPLITVAR: t/t_split_var_1_bad.v:12:16: 'should_show_warning_ifs1' has split_var metacomment, but will not be split because it is not declared in a module. - 12 | logic [7:0] should_show_warning_ifs1 [1:0] /*verilator split_var*/ ; - | ^~~~~~~~~~~~~~~~~~~~~~~~ -%Warning-SPLITVAR: t/t_split_var_1_bad.v:38:14: 'cannot_split1' has split_var metacomment but will not be split because it is accessed from another module via a dot. - 38 | i_sub0.cannot_split1[0] = 0; - | ^~~~~~~~~~~~~ -%Warning-SELRANGE: t/t_split_var_1_bad.v:83:33: Selection index out of range: 13 outside 12:10 - : ... In instance t.i_sub3 - 83 | assign outwires[12] = inwires[13]; - | ^ -%Warning-WIDTH: t/t_split_var_1_bad.v:39:31: Operator ASSIGN expects 8 bits on the Assign RHS, but Assign RHS's FUNCREF 'bad_func' generates 32 bits. - : ... In instance t - 39 | i_sub0.cannot_split1[1] = bad_func(addr, rd_data0); - | ^ -%Error: t/t_split_var_1_bad.v:72:16: Illegal assignment of constant to unpacked array - : ... In instance t.i_sub2 - 72 | assign b = a[0]; - | ^ -%Warning-SPLITVAR: t/t_split_var_1_bad.v:51:31: 'cannot_split0' has split_var metacomment but will not be split because index cannot be determined statically. + : ... In instance t + : ... In instance t + : ... In instance t + : ... In instance t : ... In instance t.i_sub0 - 51 | rd_data = cannot_split0[addr]; - | ^~~~ -%Warning-SPLITVAR: t/t_split_var_1_bad.v:83:34: 'inwires' has split_var metacomment but will not be split because index is out of range. + : ... In instance t.i_sub1 + : ... In instance t.i_sub1 + : ... In instance t.i_sub3 : ... In instance t.i_sub3 - 83 | assign outwires[12] = inwires[13]; - | ^~ -%Warning-SPLITVAR: t/t_split_var_1_bad.v:17:9: 'should_show_warning0' has split_var metacomment but will not be split because it is not an aggregate type of bit nor logic : ... In instance t - 17 | real should_show_warning0 /*verilator split_var*/ ; - | ^~~~~~~~~~~~~~~~~~~~ -%Warning-SPLITVAR: t/t_split_var_1_bad.v:18:11: 'should_show_warning1' has split_var metacomment but will not be split because it is not an aggregate type of bit nor logic - : ... In instance t - 18 | string should_show_warning1 /*verilator split_var*/ ; - | ^~~~~~~~~~~~~~~~~~~~ -%Warning-SPLITVAR: t/t_split_var_1_bad.v:19:11: 'should_show_warning2' has split_var metacomment but will not be split because its bitwidth is 1 - : ... In instance t - 19 | wire should_show_warning2 /*verilator split_var*/ ; - | ^~~~~~~~~~~~~~~~~~~~ -%Warning-SPLITVAR: t/t_split_var_1_bad.v:30:44: 'inout_port' has split_var metacomment but will not be split because it is an inout port - : ... In instance t - 30 | function int bad_func(inout logic [3:0] inout_port /*verilator split_var*/ , + : ... In instance t + : ... In instance t.i_sub2 + ... Use "/* verilator lint_off SPLITVAR */" and lint_on around source to disable this message. | ^~~~~~~~~~ -%Warning-SPLITVAR: t/t_split_var_1_bad.v:31:42: 'ref_port' has split_var metacomment but will not be split because it is a ref argument - : ... In instance t - 31 | ref logic [7:0] ref_port /*verilator split_var*/ ); | ^~~~~~~~ -%Warning-SPLITVAR: t/t_split_var_1_bad.v:57:11: 'cannot_split_genvar' has split_var metacomment but will not be split because it is not an aggregate type of bit nor logic - : ... In instance t.i_sub1 - 57 | genvar cannot_split_genvar /*verilator split_var*/ ; - | ^~~~~~~~~~~~~~~~~~~ -%Warning-SPLITVAR: t/t_split_var_1_bad.v:60:29: 'cannot_split' has split_var metacomment but will not be split because its bit range cannot be determined statically. - : ... In instance t.i_sub1 - 60 | rd_data = cannot_split[addr]; + | ^~ + | ^ + | ^ + | ^~~~ | ^ + | ^ + | ^~~~~~~~~~~~~~~~~~~~~~~~ + | ^~~~~~~~~~~~~~~~~~~~~~~~ + | ^~~~~~~~~~~~~ + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ + | ^~~~~~~~~~~~~~~~~~~ + | ^~~~~~~~~~~~~~~~~~~~ + | ^~~~~~~~~~~~~~~~~~~~ + | ^~~~~~~~~~~~~~~~~~~~ + 7 | logic [7:0] should_show_warning_global0 /*verilator split_var*/ ; + 8 | logic [7:0] should_show_warning_global1 [1:0] /*verilator split_var*/ ; + 11 | logic [7:0] should_show_warning_ifs0 /*verilator split_var*/ ; + 12 | logic [7:0] should_show_warning_ifs1 [1:0] /*verilator split_var*/ ; + 17 | real should_show_warning0 /*verilator split_var*/ ; + 18 | string should_show_warning1 /*verilator split_var*/ ; + 19 | wire should_show_warning2 /*verilator split_var*/ ; + 30 | function int bad_func(inout logic [3:0] inout_port /*verilator split_var*/ , + 31 | ref logic [7:0] ref_port /*verilator split_var*/ ); + 38 | i_sub0.cannot_split1[0] = 0; + 39 | i_sub0.cannot_split1[1] = bad_func(addr, rd_data0); + 51 | rd_data = cannot_split0[addr]; + 57 | genvar cannot_split_genvar /*verilator split_var*/ ; + 60 | rd_data = cannot_split[addr]; + 72 | assign b = a[0]; + 83 | assign outwires[12] = inwires[13]; + 83 | assign outwires[12] = inwires[13]; %Error: Exiting due to diff --git a/test_regress/t/t_split_var_1_bad.pl b/test_regress/t/t_split_var_1_bad.pl index 16d5325a7..bbfbd2b0c 100755 --- a/test_regress/t/t_split_var_1_bad.pl +++ b/test_regress/t/t_split_var_1_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,13 +8,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, verilator_flags2 => ['--stats'], - expect_filename => $Self->{golden_filename}, + # When issue-2407 resolved, decomment and update golden file + #expect_filename => $Self->{golden_filename}, ); +# When issue-2407 resolved, remove +files_identical_sorted("$Self->{obj_dir}/vlt_compile.log", $Self->{golden_filename}, 1); + ok(1); 1; diff --git a/test_regress/t/t_split_var_2_trace.pl b/test_regress/t/t_split_var_2_trace.pl index 0d815e82b..959d96d7c 100755 --- a/test_regress/t/t_split_var_2_trace.pl +++ b/test_regress/t/t_split_var_2_trace.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_static_elab.pl b/test_regress/t/t_static_elab.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_static_elab.pl +++ b/test_regress/t/t_static_elab.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_stop_bad.pl b/test_regress/t/t_stop_bad.pl index 16bcd07b8..31a7a66ff 100755 --- a/test_regress/t/t_stop_bad.pl +++ b/test_regress/t/t_stop_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_stream.pl b/test_regress/t/t_stream.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_stream.pl +++ b/test_regress/t/t_stream.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_stream2.pl b/test_regress/t/t_stream2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_stream2.pl +++ b/test_regress/t/t_stream2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_stream3.pl b/test_regress/t/t_stream3.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_stream3.pl +++ b/test_regress/t/t_stream3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_string.pl b/test_regress/t/t_string.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_string.pl +++ b/test_regress/t/t_string.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_string.v b/test_regress/t/t_string.v index 11bf3ac16..6b8e48e07 100644 --- a/test_regress/t/t_string.v +++ b/test_regress/t/t_string.v @@ -31,6 +31,7 @@ module t (/*AUTOARG*/ initial begin $sformat(vstr, "s=%s", s); `checks(vstr, "s=a"); + `checks(string'(vstr), "s=a"); `checks(s, "a"); `checks({s,s,s}, "aaa"); `checks({4{s}}, "aaaa"); diff --git a/test_regress/t/t_string_type_methods.pl b/test_regress/t/t_string_type_methods.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_string_type_methods.pl +++ b/test_regress/t/t_string_type_methods.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_string_type_methods_bad.pl b/test_regress/t/t_string_type_methods_bad.pl index dba098eb6..a60503a1f 100755 --- a/test_regress/t/t_string_type_methods_bad.pl +++ b/test_regress/t/t_string_type_methods_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_struct_anon.pl b/test_regress/t/t_struct_anon.pl index a4d74c0ba..13c6e2b71 100755 --- a/test_regress/t/t_struct_anon.pl +++ b/test_regress/t/t_struct_anon.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_array.pl b/test_regress/t/t_struct_array.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_struct_array.pl +++ b/test_regress/t/t_struct_array.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_genfor.pl b/test_regress/t/t_struct_genfor.pl index a4d74c0ba..13c6e2b71 100755 --- a/test_regress/t/t_struct_genfor.pl +++ b/test_regress/t/t_struct_genfor.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_init.pl b/test_regress/t/t_struct_init.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_struct_init.pl +++ b/test_regress/t/t_struct_init.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_init_bad.pl b/test_regress/t/t_struct_init_bad.pl index 682abbc5e..c7da11338 100755 --- a/test_regress/t/t_struct_init_bad.pl +++ b/test_regress/t/t_struct_init_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,11 +8,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); top_filename("t/t_struct_init.v"); -compile( +lint( v_flags2 => ['+define+T_STRUCT_INIT_BAD'], fails => 1, expect_filename => $Self->{golden_filename}, diff --git a/test_regress/t/t_struct_init_trace.pl b/test_regress/t/t_struct_init_trace.pl index 6ff009330..0b6e5073d 100755 --- a/test_regress/t/t_struct_init_trace.pl +++ b/test_regress/t/t_struct_init_trace.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_nest.pl b/test_regress/t/t_struct_nest.pl index a4d74c0ba..13c6e2b71 100755 --- a/test_regress/t/t_struct_nest.pl +++ b/test_regress/t/t_struct_nest.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_notfound_bad.pl b/test_regress/t/t_struct_notfound_bad.pl index dba098eb6..a60503a1f 100755 --- a/test_regress/t/t_struct_notfound_bad.pl +++ b/test_regress/t/t_struct_notfound_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_struct_packed_sysfunct.pl b/test_regress/t/t_struct_packed_sysfunct.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_struct_packed_sysfunct.pl +++ b/test_regress/t/t_struct_packed_sysfunct.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_packed_value_list.pl b/test_regress/t/t_struct_packed_value_list.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_struct_packed_value_list.pl +++ b/test_regress/t/t_struct_packed_value_list.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_packed_write_read.pl b/test_regress/t/t_struct_packed_write_read.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_struct_packed_write_read.pl +++ b/test_regress/t/t_struct_packed_write_read.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_param.pl b/test_regress/t/t_struct_param.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_struct_param.pl +++ b/test_regress/t/t_struct_param.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_pat_width.pl b/test_regress/t/t_struct_pat_width.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_struct_pat_width.pl +++ b/test_regress/t/t_struct_pat_width.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_port.pl b/test_regress/t/t_struct_port.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_struct_port.pl +++ b/test_regress/t/t_struct_port.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_portsel.pl b/test_regress/t/t_struct_portsel.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_struct_portsel.pl +++ b/test_regress/t/t_struct_portsel.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_unaligned.pl b/test_regress/t/t_struct_unaligned.pl index eda64373b..624f04e28 100755 --- a/test_regress/t/t_struct_unaligned.pl +++ b/test_regress/t/t_struct_unaligned.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_unpacked.pl b/test_regress/t/t_struct_unpacked.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_struct_unpacked.pl +++ b/test_regress/t/t_struct_unpacked.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_struct_unpacked2.out b/test_regress/t/t_struct_unpacked2.out new file mode 100644 index 000000000..3d938df82 --- /dev/null +++ b/test_regress/t/t_struct_unpacked2.out @@ -0,0 +1,8 @@ +%Warning-UNPACKED: t/t_struct_unpacked2.v:10:13: Unsupported: Unpacked array in packed struct/union (struct/union converted to unpacked) + 10 | int b [2]; + | ^ + ... Use "/* verilator lint_off UNPACKED */" and lint_on around source to disable this message. +%Warning-UNPACKED: t/t_struct_unpacked2.v:9:12: Unsupported: Unpacked struct/union + 9 | typedef struct { + | ^~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_struct_unpacked2.pl b/test_regress/t/t_struct_unpacked2.pl new file mode 100755 index 000000000..59ba0d6c6 --- /dev/null +++ b/test_regress/t/t_struct_unpacked2.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(linter => 1); + +lint( + fails => $Self->{vlt_all}, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_struct_unpacked2.v b/test_regress/t/t_struct_unpacked2.v new file mode 100644 index 000000000..e7c6ff9ff --- /dev/null +++ b/test_regress/t/t_struct_unpacked2.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2009 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module x; + + typedef struct { + int b [2]; + } notpacked_t; + + notpacked_t n; + + initial begin + n.b[0] = 1; + if (n.b[0] != 1) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_struct_unpacked_bad.pl b/test_regress/t/t_struct_unpacked_bad.pl index c1dba4c49..59ba0d6c6 100755 --- a/test_regress/t/t_struct_unpacked_bad.pl +++ b/test_regress/t/t_struct_unpacked_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => $Self->{vlt_all}, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_sv_bus_mux_demux.pl b/test_regress/t/t_sv_bus_mux_demux.pl index db4e357ac..c31dd4c0c 100755 --- a/test_regress/t/t_sv_bus_mux_demux.pl +++ b/test_regress/t/t_sv_bus_mux_demux.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sv_conditional.pl b/test_regress/t/t_sv_conditional.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_sv_conditional.pl +++ b/test_regress/t/t_sv_conditional.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sv_cpu.pl b/test_regress/t/t_sv_cpu.pl index a9984d5a8..6cc81f85a 100755 --- a/test_regress/t/t_sv_cpu.pl +++ b/test_regress/t/t_sv_cpu.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_file_autoflush.pl b/test_regress/t/t_sys_file_autoflush.pl index 70f8f6f68..058d7b858 100755 --- a/test_regress/t/t_sys_file_autoflush.pl +++ b/test_regress/t/t_sys_file_autoflush.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_file_basic.pl b/test_regress/t/t_sys_file_basic.pl index 1e25a84c4..7b4870947 100755 --- a/test_regress/t/t_sys_file_basic.pl +++ b/test_regress/t/t_sys_file_basic.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_file_basic.v b/test_regress/t/t_sys_file_basic.v index fe075a6be..272574d0d 100644 --- a/test_regress/t/t_sys_file_basic.v +++ b/test_regress/t/t_sys_file_basic.v @@ -139,8 +139,8 @@ module t; if (chars != 1) $stop; if (letterq != "ijklmnop") $stop; - chars = $sscanf("xa=1f xb=12898971238912389712783490823_abcdef689_02348923", - "xa=%x xb=%x", letterq, letterw); + chars = $sscanf("xa=1f ign=22 xb=12898971238912389712783490823_abcdef689_02348923", + "xa=%x ign=%*d xb=%x", letterq, letterw); if (`verbose) $write("c=%0d xa=%x xb=%x\n", chars, letterq, letterw); if (chars != 2) $stop; if (letterq != 64'h1f) $stop; @@ -154,8 +154,8 @@ module t; if (letterw != 128'hd2a55) $stop; if (letterz != {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0","2"}) $stop; - chars = $sscanf("oa=23 ob=125634123615234123681236", - "oa=%o ob=%o", letterq, letterw); + chars = $sscanf("oa=23 oi=11 ob=125634123615234123681236", + "oa=%o oi=%*o ob=%o", letterq, letterw); if (`verbose) $write("c=%0d oa=%x ob=%x\n", chars, letterq, letterw); if (chars != 2) $stop; if (letterq != 64'h13) $stop; diff --git a/test_regress/t/t_sys_file_basic_mcd.out b/test_regress/t/t_sys_file_basic_mcd.out new file mode 100644 index 000000000..bac06f7e9 --- /dev/null +++ b/test_regress/t/t_sys_file_basic_mcd.out @@ -0,0 +1,2 @@ +Sean Connery was the best Bond. +*-* All Finished *-* diff --git a/test_regress/t/t_sys_file_basic_mcd.pl b/test_regress/t/t_sys_file_basic_mcd.pl new file mode 100755 index 000000000..106810fa0 --- /dev/null +++ b/test_regress/t/t_sys_file_basic_mcd.pl @@ -0,0 +1,29 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(simulator => 1); + +unlink("$Self->{obj_dir}/t_sys_file_basic_mcd.log"); + +compile(); +execute( + check_finished => 1, + expect_filename => $Self->{golden_filename}, + ); + +files_identical("$Self->{obj_dir}/t_sys_file_basic_mcd_test2_0.dat", + "$Self->{t_dir}/t_sys_file_basic_mcd_test2_0.dat"); +files_identical("$Self->{obj_dir}/t_sys_file_basic_mcd_test2_1.dat", + "$Self->{t_dir}/t_sys_file_basic_mcd_test2_1.dat"); +files_identical("$Self->{obj_dir}/t_sys_file_basic_mcd_test2_2.dat", + "$Self->{t_dir}/t_sys_file_basic_mcd_test2_2.dat"); + +ok(1); +1; diff --git a/test_regress/t/t_sys_file_basic_mcd.v b/test_regress/t/t_sys_file_basic_mcd.v new file mode 100644 index 000000000..16742829a --- /dev/null +++ b/test_regress/t/t_sys_file_basic_mcd.v @@ -0,0 +1,105 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + + +module t; +`define STR(__s) `"__s`" + + task automatic fail(string s); begin + $display({"FAIL! Reason: ", s}); + $stop; + end endtask + + task automatic test1; begin + int fd[30], fd_fail, fd_success, fd_close, tmp; + for (int i = 0; i < 30; i++) begin + // Attempt to allocate 30 MCD descriptors; returned descriptors + // should fall within correct range: [1, 30]. + tmp = $fopen($sformatf("%s/some_file%0d.dat", `STR(`TEST_OBJ_DIR), i)); + fd[i] = tmp; + if ((fd[i] == 0) || !$onehot(fd[i])) + fail($sformatf("MCD descriptor out of range %d", fd[i])); + end + // Attempt to allocate another MCD descriptor when all should + // be used. We expect this operation to fail and return the + // invalid descriptor (0). + fd_fail = $fopen($sformatf("%s/another_file.dat", `STR(`TEST_OBJ_DIR))); + if (fd_fail != 0) + fail("Able to allocate MCD descriptor when fully utilized."); + // Return descriptor back to pool + fd_close = fd[0]; + $fclose(fd_close); + // Re-attempt MCD allocation; should pass at this point. + fd_success = $fopen($sformatf("%s/yet_another_file.dat", `STR(`TEST_OBJ_DIR))); + if (fd_success == 0) + fail("Expect to have free descriptors at this point."); + // Returned descriptor should have a value matching that which + // had previously just been returned back to the pool. + if (fd_success != fd[0]) + fail("Descriptor has incorrect value."); + // Return all descriptors back to the pool. + for (int i = 1; i < 30; i++) begin + fd_close = fd[i]; + $fclose(fd_close); + end + end endtask + + task automatic test2; begin + // Validate basic MCD functionality. + + integer fd[3], fd_all, tmp; + for (int i = 0; i < 3; i++) begin + + tmp = $fopen($sformatf("%s/t_sys_file_basic_mcd_test2_%0d.dat", `STR(`TEST_OBJ_DIR), i)); + fd[i] = tmp; + end + + fd_all = 0; + for (int i = 0; i < 3; i++) + fd_all |= fd[i]; + + $fwrite(fd_all, "Scotland is the greatest country.\n"); + $fwrite(fd_all, "All other countries are inferior.\n"); + $fwrite(fd_all, "Woe betide those to stand against the mighty Scottish nation.\n"); + $fclose(fd_all); + end endtask + + task automatic test3; begin + // Write some things to standard output. + $fwrite(32'h8000_0001, "Sean Connery was the best Bond.\n"); + end endtask + + task automatic test4; begin + int fd; + // Wide filename + fd = $fopen({`STR(`TEST_OBJ_DIR), + "some_very_large_filename_that_no_one_would_ever_use_", + "except_to_purposefully_break_my_beautiful_code.dat"}); + if (fd == 0) fail("Long filename could not be opened."); + $fclose(fd); + end endtask + + initial begin + + // Test1: Validate file descriptor region. + test1; + + // Test2: Validate basic MCD functionality. + test2; + + // Test3: Validate explicit descriptor ID + test3; + + // Test4: Validate filename lengths + test4; + + $write("*-* All Finished *-*\n"); + $finish(0); // Test arguments to finish + + end // initial begin + +`undef STR +endmodule // t diff --git a/test_regress/t/t_sys_file_basic_mcd_test2_0.dat b/test_regress/t/t_sys_file_basic_mcd_test2_0.dat new file mode 100644 index 000000000..d31f40f60 --- /dev/null +++ b/test_regress/t/t_sys_file_basic_mcd_test2_0.dat @@ -0,0 +1,3 @@ +Scotland is the greatest country. +All other countries are inferior. +Woe betide those to stand against the mighty Scottish nation. diff --git a/test_regress/t/t_sys_file_basic_mcd_test2_1.dat b/test_regress/t/t_sys_file_basic_mcd_test2_1.dat new file mode 100644 index 000000000..d31f40f60 --- /dev/null +++ b/test_regress/t/t_sys_file_basic_mcd_test2_1.dat @@ -0,0 +1,3 @@ +Scotland is the greatest country. +All other countries are inferior. +Woe betide those to stand against the mighty Scottish nation. diff --git a/test_regress/t/t_sys_file_basic_mcd_test2_2.dat b/test_regress/t/t_sys_file_basic_mcd_test2_2.dat new file mode 100644 index 000000000..d31f40f60 --- /dev/null +++ b/test_regress/t/t_sys_file_basic_mcd_test2_2.dat @@ -0,0 +1,3 @@ +Scotland is the greatest country. +All other countries are inferior. +Woe betide those to stand against the mighty Scottish nation. diff --git a/test_regress/t/t_sys_file_basic_uz.dat b/test_regress/t/t_sys_file_basic_uz.dat new file mode 100644 index 000000000..03a38c52b Binary files /dev/null and b/test_regress/t/t_sys_file_basic_uz.dat differ diff --git a/test_regress/t/t_sys_file_basic_uz.out b/test_regress/t/t_sys_file_basic_uz.out new file mode 100644 index 000000000..6cd8f845b --- /dev/null +++ b/test_regress/t/t_sys_file_basic_uz.out @@ -0,0 +1,2048 @@ +00 +01 +02 +03 +04 +05 +06 +07 +08 +09 +0a +0b +0c +0d +0e +0f +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +1a +1b +1c +1d +1e +1f +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +2a +2b +2c +2d +2e +2f +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +3a +3b +3c +3d +3e +3f +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +4a +4b +4c +4d +4e +4f +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +5a +5b +5c +5d +5e +5f +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +6a +6b +6c +6d +6e +6f +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +7a +7b +7c +7d +7e +7f +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +8a +8b +8c +8d +8e +8f +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +9a +9b +9c +9d +9e +9f +a0 +a1 +a2 +a3 +a4 +a5 +a6 +a7 +a8 +a9 +aa +ab +ac +ad +ae +af +b0 +b1 +b2 +b3 +b4 +b5 +b6 +b7 +b8 +b9 +ba +bb +bc +bd +be +bf +c0 +c1 +c2 +c3 +c4 +c5 +c6 +c7 +c8 +c9 +ca +cb +cc +cd +ce +cf +d0 +d1 +d2 +d3 +d4 +d5 +d6 +d7 +d8 +d9 +da +db +dc +dd +de +df +e0 +e1 +e2 +e3 +e4 +e5 +e6 +e7 +e8 +e9 +ea +eb +ec +ed +ee +ef +f0 +f1 +f2 +f3 +f4 +f5 +f6 +f7 +f8 +f9 +fa +fb +fc +fd +fe +ff +0100 +0201 +0302 +0403 +0504 +0605 +0706 +0807 +0908 +0a09 +0b0a +0c0b +0d0c +0e0d +0f0e +100f +1110 +1211 +1312 +1413 +1514 +1615 +1716 +1817 +1918 +1a19 +1b1a +1c1b +1d1c +1e1d +1f1e +201f +2120 +2221 +2322 +2423 +2524 +2625 +2726 +2827 +2928 +2a29 +2b2a +2c2b +2d2c +2e2d +2f2e +302f +3130 +3231 +3332 +3433 +3534 +3635 +3736 +3837 +3938 +3a39 +3b3a +3c3b +3d3c +3e3d +3f3e +403f +4140 +4241 +4342 +4443 +4544 +4645 +4746 +4847 +4948 +4a49 +4b4a +4c4b +4d4c +4e4d +4f4e +504f +5150 +5251 +5352 +5453 +5554 +5655 +5756 +5857 +5958 +5a59 +5b5a +5c5b +5d5c +5e5d +5f5e +605f +6160 +6261 +6362 +6463 +6564 +6665 +6766 +6867 +6968 +6a69 +6b6a +6c6b +6d6c +6e6d +6f6e +706f +7170 +7271 +7372 +7473 +7574 +7675 +7776 +7877 +7978 +7a79 +7b7a +7c7b +7d7c +7e7d +7f7e +807f +8180 +8281 +8382 +8483 +8584 +8685 +8786 +8887 +8988 +8a89 +8b8a +8c8b +8d8c +8e8d +8f8e +908f +9190 +9291 +9392 +9493 +9594 +9695 +9796 +9897 +9998 +9a99 +9b9a +9c9b +9d9c +9e9d +9f9e +a09f +a1a0 +a2a1 +a3a2 +a4a3 +a5a4 +a6a5 +a7a6 +a8a7 +a9a8 +aaa9 +abaa +acab +adac +aead +afae +b0af +b1b0 +b2b1 +b3b2 +b4b3 +b5b4 +b6b5 +b7b6 +b8b7 +b9b8 +bab9 +bbba +bcbb +bdbc +bebd +bfbe +c0bf +c1c0 +c2c1 +c3c2 +c4c3 +c5c4 +c6c5 +c7c6 +c8c7 +c9c8 +cac9 +cbca +cccb +cdcc +cecd +cfce +d0cf +d1d0 +d2d1 +d3d2 +d4d3 +d5d4 +d6d5 +d7d6 +d8d7 +d9d8 +dad9 +dbda +dcdb +dddc +dedd +dfde +e0df +e1e0 +e2e1 +e3e2 +e4e3 +e5e4 +e6e5 +e7e6 +e8e7 +e9e8 +eae9 +ebea +eceb +edec +eeed +efee +f0ef +f1f0 +f2f1 +f3f2 +f4f3 +f5f4 +f6f5 +f7f6 +f8f7 +f9f8 +faf9 +fbfa +fcfb +fdfc +fefd +fffe +00ff +03020100 +04030201 +05040302 +06050403 +07060504 +08070605 +09080706 +0a090807 +0b0a0908 +0c0b0a09 +0d0c0b0a +0e0d0c0b +0f0e0d0c +100f0e0d +11100f0e +1211100f +13121110 +14131211 +15141312 +16151413 +17161514 +18171615 +19181716 +1a191817 +1b1a1918 +1c1b1a19 +1d1c1b1a +1e1d1c1b +1f1e1d1c +201f1e1d +21201f1e +2221201f +23222120 +24232221 +25242322 +26252423 +27262524 +28272625 +29282726 +2a292827 +2b2a2928 +2c2b2a29 +2d2c2b2a +2e2d2c2b +2f2e2d2c +302f2e2d +31302f2e +3231302f +33323130 +34333231 +35343332 +36353433 +37363534 +38373635 +39383736 +3a393837 +3b3a3938 +3c3b3a39 +3d3c3b3a +3e3d3c3b +3f3e3d3c +403f3e3d +41403f3e +4241403f +43424140 +44434241 +45444342 +46454443 +47464544 +48474645 +49484746 +4a494847 +4b4a4948 +4c4b4a49 +4d4c4b4a +4e4d4c4b +4f4e4d4c +504f4e4d +51504f4e +5251504f +53525150 +54535251 +55545352 +56555453 +57565554 +58575655 +59585756 +5a595857 +5b5a5958 +5c5b5a59 +5d5c5b5a +5e5d5c5b +5f5e5d5c +605f5e5d +61605f5e +6261605f +63626160 +64636261 +65646362 +66656463 +67666564 +68676665 +69686766 +6a696867 +6b6a6968 +6c6b6a69 +6d6c6b6a +6e6d6c6b +6f6e6d6c +706f6e6d +71706f6e +7271706f +73727170 +74737271 +75747372 +76757473 +77767574 +78777675 +79787776 +7a797877 +7b7a7978 +7c7b7a79 +7d7c7b7a +7e7d7c7b +7f7e7d7c +807f7e7d +81807f7e +8281807f +83828180 +84838281 +85848382 +86858483 +87868584 +88878685 +89888786 +8a898887 +8b8a8988 +8c8b8a89 +8d8c8b8a +8e8d8c8b +8f8e8d8c +908f8e8d +91908f8e +9291908f +93929190 +94939291 +95949392 +96959493 +97969594 +98979695 +99989796 +9a999897 +9b9a9998 +9c9b9a99 +9d9c9b9a +9e9d9c9b +9f9e9d9c +a09f9e9d +a1a09f9e +a2a1a09f +a3a2a1a0 +a4a3a2a1 +a5a4a3a2 +a6a5a4a3 +a7a6a5a4 +a8a7a6a5 +a9a8a7a6 +aaa9a8a7 +abaaa9a8 +acabaaa9 +adacabaa +aeadacab +afaeadac +b0afaead +b1b0afae +b2b1b0af +b3b2b1b0 +b4b3b2b1 +b5b4b3b2 +b6b5b4b3 +b7b6b5b4 +b8b7b6b5 +b9b8b7b6 +bab9b8b7 +bbbab9b8 +bcbbbab9 +bdbcbbba +bebdbcbb +bfbebdbc +c0bfbebd +c1c0bfbe +c2c1c0bf +c3c2c1c0 +c4c3c2c1 +c5c4c3c2 +c6c5c4c3 +c7c6c5c4 +c8c7c6c5 +c9c8c7c6 +cac9c8c7 +cbcac9c8 +cccbcac9 +cdcccbca +cecdcccb +cfcecdcc +d0cfcecd +d1d0cfce +d2d1d0cf +d3d2d1d0 +d4d3d2d1 +d5d4d3d2 +d6d5d4d3 +d7d6d5d4 +d8d7d6d5 +d9d8d7d6 +dad9d8d7 +dbdad9d8 +dcdbdad9 +dddcdbda +dedddcdb +dfdedddc +e0dfdedd +e1e0dfde +e2e1e0df +e3e2e1e0 +e4e3e2e1 +e5e4e3e2 +e6e5e4e3 +e7e6e5e4 +e8e7e6e5 +e9e8e7e6 +eae9e8e7 +ebeae9e8 +ecebeae9 +edecebea +eeedeceb +efeeedec +f0efeeed +f1f0efee +f2f1f0ef +f3f2f1f0 +f4f3f2f1 +f5f4f3f2 +f6f5f4f3 +f7f6f5f4 +f8f7f6f5 +f9f8f7f6 +faf9f8f7 +fbfaf9f8 +fcfbfaf9 +fdfcfbfa +fefdfcfb +fffefdfc +00fffefd +0100fffe +020100ff +0706050403020100 +0807060504030201 +0908070605040302 +0a09080706050403 +0b0a090807060504 +0c0b0a0908070605 +0d0c0b0a09080706 +0e0d0c0b0a090807 +0f0e0d0c0b0a0908 +100f0e0d0c0b0a09 +11100f0e0d0c0b0a +1211100f0e0d0c0b +131211100f0e0d0c +14131211100f0e0d +1514131211100f0e +161514131211100f +1716151413121110 +1817161514131211 +1918171615141312 +1a19181716151413 +1b1a191817161514 +1c1b1a1918171615 +1d1c1b1a19181716 +1e1d1c1b1a191817 +1f1e1d1c1b1a1918 +201f1e1d1c1b1a19 +21201f1e1d1c1b1a +2221201f1e1d1c1b +232221201f1e1d1c +24232221201f1e1d +2524232221201f1e +262524232221201f +2726252423222120 +2827262524232221 +2928272625242322 +2a29282726252423 +2b2a292827262524 +2c2b2a2928272625 +2d2c2b2a29282726 +2e2d2c2b2a292827 +2f2e2d2c2b2a2928 +302f2e2d2c2b2a29 +31302f2e2d2c2b2a +3231302f2e2d2c2b +333231302f2e2d2c +34333231302f2e2d +3534333231302f2e +363534333231302f +3736353433323130 +3837363534333231 +3938373635343332 +3a39383736353433 +3b3a393837363534 +3c3b3a3938373635 +3d3c3b3a39383736 +3e3d3c3b3a393837 +3f3e3d3c3b3a3938 +403f3e3d3c3b3a39 +41403f3e3d3c3b3a +4241403f3e3d3c3b +434241403f3e3d3c +44434241403f3e3d +4544434241403f3e +464544434241403f +4746454443424140 +4847464544434241 +4948474645444342 +4a49484746454443 +4b4a494847464544 +4c4b4a4948474645 +4d4c4b4a49484746 +4e4d4c4b4a494847 +4f4e4d4c4b4a4948 +504f4e4d4c4b4a49 +51504f4e4d4c4b4a +5251504f4e4d4c4b +535251504f4e4d4c +54535251504f4e4d +5554535251504f4e +565554535251504f +5756555453525150 +5857565554535251 +5958575655545352 +5a59585756555453 +5b5a595857565554 +5c5b5a5958575655 +5d5c5b5a59585756 +5e5d5c5b5a595857 +5f5e5d5c5b5a5958 +605f5e5d5c5b5a59 +61605f5e5d5c5b5a +6261605f5e5d5c5b +636261605f5e5d5c +64636261605f5e5d +6564636261605f5e +666564636261605f +6766656463626160 +6867666564636261 +6968676665646362 +6a69686766656463 +6b6a696867666564 +6c6b6a6968676665 +6d6c6b6a69686766 +6e6d6c6b6a696867 +6f6e6d6c6b6a6968 +706f6e6d6c6b6a69 +71706f6e6d6c6b6a +7271706f6e6d6c6b +737271706f6e6d6c +74737271706f6e6d +7574737271706f6e +767574737271706f +7776757473727170 +7877767574737271 +7978777675747372 +7a79787776757473 +7b7a797877767574 +7c7b7a7978777675 +7d7c7b7a79787776 +7e7d7c7b7a797877 +7f7e7d7c7b7a7978 +807f7e7d7c7b7a79 +81807f7e7d7c7b7a +8281807f7e7d7c7b +838281807f7e7d7c +84838281807f7e7d +8584838281807f7e +868584838281807f +8786858483828180 +8887868584838281 +8988878685848382 +8a89888786858483 +8b8a898887868584 +8c8b8a8988878685 +8d8c8b8a89888786 +8e8d8c8b8a898887 +8f8e8d8c8b8a8988 +908f8e8d8c8b8a89 +91908f8e8d8c8b8a +9291908f8e8d8c8b +939291908f8e8d8c +94939291908f8e8d +9594939291908f8e +969594939291908f +9796959493929190 +9897969594939291 +9998979695949392 +9a99989796959493 +9b9a999897969594 +9c9b9a9998979695 +9d9c9b9a99989796 +9e9d9c9b9a999897 +9f9e9d9c9b9a9998 +a09f9e9d9c9b9a99 +a1a09f9e9d9c9b9a +a2a1a09f9e9d9c9b +a3a2a1a09f9e9d9c +a4a3a2a1a09f9e9d +a5a4a3a2a1a09f9e +a6a5a4a3a2a1a09f +a7a6a5a4a3a2a1a0 +a8a7a6a5a4a3a2a1 +a9a8a7a6a5a4a3a2 +aaa9a8a7a6a5a4a3 +abaaa9a8a7a6a5a4 +acabaaa9a8a7a6a5 +adacabaaa9a8a7a6 +aeadacabaaa9a8a7 +afaeadacabaaa9a8 +b0afaeadacabaaa9 +b1b0afaeadacabaa +b2b1b0afaeadacab +b3b2b1b0afaeadac +b4b3b2b1b0afaead +b5b4b3b2b1b0afae +b6b5b4b3b2b1b0af +b7b6b5b4b3b2b1b0 +b8b7b6b5b4b3b2b1 +b9b8b7b6b5b4b3b2 +bab9b8b7b6b5b4b3 +bbbab9b8b7b6b5b4 +bcbbbab9b8b7b6b5 +bdbcbbbab9b8b7b6 +bebdbcbbbab9b8b7 +bfbebdbcbbbab9b8 +c0bfbebdbcbbbab9 +c1c0bfbebdbcbbba +c2c1c0bfbebdbcbb +c3c2c1c0bfbebdbc +c4c3c2c1c0bfbebd +c5c4c3c2c1c0bfbe +c6c5c4c3c2c1c0bf +c7c6c5c4c3c2c1c0 +c8c7c6c5c4c3c2c1 +c9c8c7c6c5c4c3c2 +cac9c8c7c6c5c4c3 +cbcac9c8c7c6c5c4 +cccbcac9c8c7c6c5 +cdcccbcac9c8c7c6 +cecdcccbcac9c8c7 +cfcecdcccbcac9c8 +d0cfcecdcccbcac9 +d1d0cfcecdcccbca +d2d1d0cfcecdcccb +d3d2d1d0cfcecdcc +d4d3d2d1d0cfcecd +d5d4d3d2d1d0cfce +d6d5d4d3d2d1d0cf +d7d6d5d4d3d2d1d0 +d8d7d6d5d4d3d2d1 +d9d8d7d6d5d4d3d2 +dad9d8d7d6d5d4d3 +dbdad9d8d7d6d5d4 +dcdbdad9d8d7d6d5 +dddcdbdad9d8d7d6 +dedddcdbdad9d8d7 +dfdedddcdbdad9d8 +e0dfdedddcdbdad9 +e1e0dfdedddcdbda +e2e1e0dfdedddcdb +e3e2e1e0dfdedddc +e4e3e2e1e0dfdedd +e5e4e3e2e1e0dfde +e6e5e4e3e2e1e0df +e7e6e5e4e3e2e1e0 +e8e7e6e5e4e3e2e1 +e9e8e7e6e5e4e3e2 +eae9e8e7e6e5e4e3 +ebeae9e8e7e6e5e4 +ecebeae9e8e7e6e5 +edecebeae9e8e7e6 +eeedecebeae9e8e7 +efeeedecebeae9e8 +f0efeeedecebeae9 +f1f0efeeedecebea +f2f1f0efeeedeceb +f3f2f1f0efeeedec +f4f3f2f1f0efeeed +f5f4f3f2f1f0efee +f6f5f4f3f2f1f0ef +f7f6f5f4f3f2f1f0 +f8f7f6f5f4f3f2f1 +f9f8f7f6f5f4f3f2 +faf9f8f7f6f5f4f3 +fbfaf9f8f7f6f5f4 +fcfbfaf9f8f7f6f5 +fdfcfbfaf9f8f7f6 +fefdfcfbfaf9f8f7 +fffefdfcfbfaf9f8 +00fffefdfcfbfaf9 +0100fffefdfcfbfa +020100fffefdfcfb +03020100fffefdfc +0403020100fffefd +050403020100fffe +06050403020100ff +00 +01 +02 +03 +04 +05 +06 +07 +08 +09 +0a +0b +0c +0d +0e +0f +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +1a +1b +1c +1d +1e +1f +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +2a +2b +2c +2d +2e +2f +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +3a +3b +3c +3d +3e +3f +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +4a +4b +4c +4d +4e +4f +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +5a +5b +5c +5d +5e +5f +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +6a +6b +6c +6d +6e +6f +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +7a +7b +7c +7d +7e +7f +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +8a +8b +8c +8d +8e +8f +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +9a +9b +9c +9d +9e +9f +a0 +a1 +a2 +a3 +a4 +a5 +a6 +a7 +a8 +a9 +aa +ab +ac +ad +ae +af +b0 +b1 +b2 +b3 +b4 +b5 +b6 +b7 +b8 +b9 +ba +bb +bc +bd +be +bf +c0 +c1 +c2 +c3 +c4 +c5 +c6 +c7 +c8 +c9 +ca +cb +cc +cd +ce +cf +d0 +d1 +d2 +d3 +d4 +d5 +d6 +d7 +d8 +d9 +da +db +dc +dd +de +df +e0 +e1 +e2 +e3 +e4 +e5 +e6 +e7 +e8 +e9 +ea +eb +ec +ed +ee +ef +f0 +f1 +f2 +f3 +f4 +f5 +f6 +f7 +f8 +f9 +fa +fb +fc +fd +fe +ff +0100 +0201 +0302 +0403 +0504 +0605 +0706 +0807 +0908 +0a09 +0b0a +0c0b +0d0c +0e0d +0f0e +100f +1110 +1211 +1312 +1413 +1514 +1615 +1716 +1817 +1918 +1a19 +1b1a +1c1b +1d1c +1e1d +1f1e +201f +2120 +2221 +2322 +2423 +2524 +2625 +2726 +2827 +2928 +2a29 +2b2a +2c2b +2d2c +2e2d +2f2e +302f +3130 +3231 +3332 +3433 +3534 +3635 +3736 +3837 +3938 +3a39 +3b3a +3c3b +3d3c +3e3d +3f3e +403f +4140 +4241 +4342 +4443 +4544 +4645 +4746 +4847 +4948 +4a49 +4b4a +4c4b +4d4c +4e4d +4f4e +504f +5150 +5251 +5352 +5453 +5554 +5655 +5756 +5857 +5958 +5a59 +5b5a +5c5b +5d5c +5e5d +5f5e +605f +6160 +6261 +6362 +6463 +6564 +6665 +6766 +6867 +6968 +6a69 +6b6a +6c6b +6d6c +6e6d +6f6e +706f +7170 +7271 +7372 +7473 +7574 +7675 +7776 +7877 +7978 +7a79 +7b7a +7c7b +7d7c +7e7d +7f7e +807f +8180 +8281 +8382 +8483 +8584 +8685 +8786 +8887 +8988 +8a89 +8b8a +8c8b +8d8c +8e8d +8f8e +908f +9190 +9291 +9392 +9493 +9594 +9695 +9796 +9897 +9998 +9a99 +9b9a +9c9b +9d9c +9e9d +9f9e +a09f +a1a0 +a2a1 +a3a2 +a4a3 +a5a4 +a6a5 +a7a6 +a8a7 +a9a8 +aaa9 +abaa +acab +adac +aead +afae +b0af +b1b0 +b2b1 +b3b2 +b4b3 +b5b4 +b6b5 +b7b6 +b8b7 +b9b8 +bab9 +bbba +bcbb +bdbc +bebd +bfbe +c0bf +c1c0 +c2c1 +c3c2 +c4c3 +c5c4 +c6c5 +c7c6 +c8c7 +c9c8 +cac9 +cbca +cccb +cdcc +cecd +cfce +d0cf +d1d0 +d2d1 +d3d2 +d4d3 +d5d4 +d6d5 +d7d6 +d8d7 +d9d8 +dad9 +dbda +dcdb +dddc +dedd +dfde +e0df +e1e0 +e2e1 +e3e2 +e4e3 +e5e4 +e6e5 +e7e6 +e8e7 +e9e8 +eae9 +ebea +eceb +edec +eeed +efee +f0ef +f1f0 +f2f1 +f3f2 +f4f3 +f5f4 +f6f5 +f7f6 +f8f7 +f9f8 +faf9 +fbfa +fcfb +fdfc +fefd +fffe +00ff +03020100 +04030201 +05040302 +06050403 +07060504 +08070605 +09080706 +0a090807 +0b0a0908 +0c0b0a09 +0d0c0b0a +0e0d0c0b +0f0e0d0c +100f0e0d +11100f0e +1211100f +13121110 +14131211 +15141312 +16151413 +17161514 +18171615 +19181716 +1a191817 +1b1a1918 +1c1b1a19 +1d1c1b1a +1e1d1c1b +1f1e1d1c +201f1e1d +21201f1e +2221201f +23222120 +24232221 +25242322 +26252423 +27262524 +28272625 +29282726 +2a292827 +2b2a2928 +2c2b2a29 +2d2c2b2a +2e2d2c2b +2f2e2d2c +302f2e2d +31302f2e +3231302f +33323130 +34333231 +35343332 +36353433 +37363534 +38373635 +39383736 +3a393837 +3b3a3938 +3c3b3a39 +3d3c3b3a +3e3d3c3b +3f3e3d3c +403f3e3d +41403f3e +4241403f +43424140 +44434241 +45444342 +46454443 +47464544 +48474645 +49484746 +4a494847 +4b4a4948 +4c4b4a49 +4d4c4b4a +4e4d4c4b +4f4e4d4c +504f4e4d +51504f4e +5251504f +53525150 +54535251 +55545352 +56555453 +57565554 +58575655 +59585756 +5a595857 +5b5a5958 +5c5b5a59 +5d5c5b5a +5e5d5c5b +5f5e5d5c +605f5e5d +61605f5e +6261605f +63626160 +64636261 +65646362 +66656463 +67666564 +68676665 +69686766 +6a696867 +6b6a6968 +6c6b6a69 +6d6c6b6a +6e6d6c6b +6f6e6d6c +706f6e6d +71706f6e +7271706f +73727170 +74737271 +75747372 +76757473 +77767574 +78777675 +79787776 +7a797877 +7b7a7978 +7c7b7a79 +7d7c7b7a +7e7d7c7b +7f7e7d7c +807f7e7d +81807f7e +8281807f +83828180 +84838281 +85848382 +86858483 +87868584 +88878685 +89888786 +8a898887 +8b8a8988 +8c8b8a89 +8d8c8b8a +8e8d8c8b +8f8e8d8c +908f8e8d +91908f8e +9291908f +93929190 +94939291 +95949392 +96959493 +97969594 +98979695 +99989796 +9a999897 +9b9a9998 +9c9b9a99 +9d9c9b9a +9e9d9c9b +9f9e9d9c +a09f9e9d +a1a09f9e +a2a1a09f +a3a2a1a0 +a4a3a2a1 +a5a4a3a2 +a6a5a4a3 +a7a6a5a4 +a8a7a6a5 +a9a8a7a6 +aaa9a8a7 +abaaa9a8 +acabaaa9 +adacabaa +aeadacab +afaeadac +b0afaead +b1b0afae +b2b1b0af +b3b2b1b0 +b4b3b2b1 +b5b4b3b2 +b6b5b4b3 +b7b6b5b4 +b8b7b6b5 +b9b8b7b6 +bab9b8b7 +bbbab9b8 +bcbbbab9 +bdbcbbba +bebdbcbb +bfbebdbc +c0bfbebd +c1c0bfbe +c2c1c0bf +c3c2c1c0 +c4c3c2c1 +c5c4c3c2 +c6c5c4c3 +c7c6c5c4 +c8c7c6c5 +c9c8c7c6 +cac9c8c7 +cbcac9c8 +cccbcac9 +cdcccbca +cecdcccb +cfcecdcc +d0cfcecd +d1d0cfce +d2d1d0cf +d3d2d1d0 +d4d3d2d1 +d5d4d3d2 +d6d5d4d3 +d7d6d5d4 +d8d7d6d5 +d9d8d7d6 +dad9d8d7 +dbdad9d8 +dcdbdad9 +dddcdbda +dedddcdb +dfdedddc +e0dfdedd +e1e0dfde +e2e1e0df +e3e2e1e0 +e4e3e2e1 +e5e4e3e2 +e6e5e4e3 +e7e6e5e4 +e8e7e6e5 +e9e8e7e6 +eae9e8e7 +ebeae9e8 +ecebeae9 +edecebea +eeedeceb +efeeedec +f0efeeed +f1f0efee +f2f1f0ef +f3f2f1f0 +f4f3f2f1 +f5f4f3f2 +f6f5f4f3 +f7f6f5f4 +f8f7f6f5 +f9f8f7f6 +faf9f8f7 +fbfaf9f8 +fcfbfaf9 +fdfcfbfa +fefdfcfb +fffefdfc +00fffefd +0100fffe +020100ff +0706050403020100 +0807060504030201 +0908070605040302 +0a09080706050403 +0b0a090807060504 +0c0b0a0908070605 +0d0c0b0a09080706 +0e0d0c0b0a090807 +0f0e0d0c0b0a0908 +100f0e0d0c0b0a09 +11100f0e0d0c0b0a +1211100f0e0d0c0b +131211100f0e0d0c +14131211100f0e0d +1514131211100f0e +161514131211100f +1716151413121110 +1817161514131211 +1918171615141312 +1a19181716151413 +1b1a191817161514 +1c1b1a1918171615 +1d1c1b1a19181716 +1e1d1c1b1a191817 +1f1e1d1c1b1a1918 +201f1e1d1c1b1a19 +21201f1e1d1c1b1a +2221201f1e1d1c1b +232221201f1e1d1c +24232221201f1e1d +2524232221201f1e +262524232221201f +2726252423222120 +2827262524232221 +2928272625242322 +2a29282726252423 +2b2a292827262524 +2c2b2a2928272625 +2d2c2b2a29282726 +2e2d2c2b2a292827 +2f2e2d2c2b2a2928 +302f2e2d2c2b2a29 +31302f2e2d2c2b2a +3231302f2e2d2c2b +333231302f2e2d2c +34333231302f2e2d +3534333231302f2e +363534333231302f +3736353433323130 +3837363534333231 +3938373635343332 +3a39383736353433 +3b3a393837363534 +3c3b3a3938373635 +3d3c3b3a39383736 +3e3d3c3b3a393837 +3f3e3d3c3b3a3938 +403f3e3d3c3b3a39 +41403f3e3d3c3b3a +4241403f3e3d3c3b +434241403f3e3d3c +44434241403f3e3d +4544434241403f3e +464544434241403f +4746454443424140 +4847464544434241 +4948474645444342 +4a49484746454443 +4b4a494847464544 +4c4b4a4948474645 +4d4c4b4a49484746 +4e4d4c4b4a494847 +4f4e4d4c4b4a4948 +504f4e4d4c4b4a49 +51504f4e4d4c4b4a +5251504f4e4d4c4b +535251504f4e4d4c +54535251504f4e4d +5554535251504f4e +565554535251504f +5756555453525150 +5857565554535251 +5958575655545352 +5a59585756555453 +5b5a595857565554 +5c5b5a5958575655 +5d5c5b5a59585756 +5e5d5c5b5a595857 +5f5e5d5c5b5a5958 +605f5e5d5c5b5a59 +61605f5e5d5c5b5a +6261605f5e5d5c5b +636261605f5e5d5c +64636261605f5e5d +6564636261605f5e +666564636261605f +6766656463626160 +6867666564636261 +6968676665646362 +6a69686766656463 +6b6a696867666564 +6c6b6a6968676665 +6d6c6b6a69686766 +6e6d6c6b6a696867 +6f6e6d6c6b6a6968 +706f6e6d6c6b6a69 +71706f6e6d6c6b6a +7271706f6e6d6c6b +737271706f6e6d6c +74737271706f6e6d +7574737271706f6e +767574737271706f +7776757473727170 +7877767574737271 +7978777675747372 +7a79787776757473 +7b7a797877767574 +7c7b7a7978777675 +7d7c7b7a79787776 +7e7d7c7b7a797877 +7f7e7d7c7b7a7978 +807f7e7d7c7b7a79 +81807f7e7d7c7b7a +8281807f7e7d7c7b +838281807f7e7d7c +84838281807f7e7d +8584838281807f7e +868584838281807f +8786858483828180 +8887868584838281 +8988878685848382 +8a89888786858483 +8b8a898887868584 +8c8b8a8988878685 +8d8c8b8a89888786 +8e8d8c8b8a898887 +8f8e8d8c8b8a8988 +908f8e8d8c8b8a89 +91908f8e8d8c8b8a +9291908f8e8d8c8b +939291908f8e8d8c +94939291908f8e8d +9594939291908f8e +969594939291908f +9796959493929190 +9897969594939291 +9998979695949392 +9a99989796959493 +9b9a999897969594 +9c9b9a9998979695 +9d9c9b9a99989796 +9e9d9c9b9a999897 +9f9e9d9c9b9a9998 +a09f9e9d9c9b9a99 +a1a09f9e9d9c9b9a +a2a1a09f9e9d9c9b +a3a2a1a09f9e9d9c +a4a3a2a1a09f9e9d +a5a4a3a2a1a09f9e +a6a5a4a3a2a1a09f +a7a6a5a4a3a2a1a0 +a8a7a6a5a4a3a2a1 +a9a8a7a6a5a4a3a2 +aaa9a8a7a6a5a4a3 +abaaa9a8a7a6a5a4 +acabaaa9a8a7a6a5 +adacabaaa9a8a7a6 +aeadacabaaa9a8a7 +afaeadacabaaa9a8 +b0afaeadacabaaa9 +b1b0afaeadacabaa +b2b1b0afaeadacab +b3b2b1b0afaeadac +b4b3b2b1b0afaead +b5b4b3b2b1b0afae +b6b5b4b3b2b1b0af +b7b6b5b4b3b2b1b0 +b8b7b6b5b4b3b2b1 +b9b8b7b6b5b4b3b2 +bab9b8b7b6b5b4b3 +bbbab9b8b7b6b5b4 +bcbbbab9b8b7b6b5 +bdbcbbbab9b8b7b6 +bebdbcbbbab9b8b7 +bfbebdbcbbbab9b8 +c0bfbebdbcbbbab9 +c1c0bfbebdbcbbba +c2c1c0bfbebdbcbb +c3c2c1c0bfbebdbc +c4c3c2c1c0bfbebd +c5c4c3c2c1c0bfbe +c6c5c4c3c2c1c0bf +c7c6c5c4c3c2c1c0 +c8c7c6c5c4c3c2c1 +c9c8c7c6c5c4c3c2 +cac9c8c7c6c5c4c3 +cbcac9c8c7c6c5c4 +cccbcac9c8c7c6c5 +cdcccbcac9c8c7c6 +cecdcccbcac9c8c7 +cfcecdcccbcac9c8 +d0cfcecdcccbcac9 +d1d0cfcecdcccbca +d2d1d0cfcecdcccb +d3d2d1d0cfcecdcc +d4d3d2d1d0cfcecd +d5d4d3d2d1d0cfce +d6d5d4d3d2d1d0cf +d7d6d5d4d3d2d1d0 +d8d7d6d5d4d3d2d1 +d9d8d7d6d5d4d3d2 +dad9d8d7d6d5d4d3 +dbdad9d8d7d6d5d4 +dcdbdad9d8d7d6d5 +dddcdbdad9d8d7d6 +dedddcdbdad9d8d7 +dfdedddcdbdad9d8 +e0dfdedddcdbdad9 +e1e0dfdedddcdbda +e2e1e0dfdedddcdb +e3e2e1e0dfdedddc +e4e3e2e1e0dfdedd +e5e4e3e2e1e0dfde +e6e5e4e3e2e1e0df +e7e6e5e4e3e2e1e0 +e8e7e6e5e4e3e2e1 +e9e8e7e6e5e4e3e2 +eae9e8e7e6e5e4e3 +ebeae9e8e7e6e5e4 +ecebeae9e8e7e6e5 +edecebeae9e8e7e6 +eeedecebeae9e8e7 +efeeedecebeae9e8 +f0efeeedecebeae9 +f1f0efeeedecebea +f2f1f0efeeedeceb +f3f2f1f0efeeedec +f4f3f2f1f0efeeed +f5f4f3f2f1f0efee +f6f5f4f3f2f1f0ef +f7f6f5f4f3f2f1f0 +f8f7f6f5f4f3f2f1 +f9f8f7f6f5f4f3f2 +faf9f8f7f6f5f4f3 +fbfaf9f8f7f6f5f4 +fcfbfaf9f8f7f6f5 +fdfcfbfaf9f8f7f6 +fefdfcfbfaf9f8f7 +fffefdfcfbfaf9f8 +00fffefdfcfbfaf9 +0100fffefdfcfbfa +020100fffefdfcfb +03020100fffefdfc +0403020100fffefd +050403020100fffe +06050403020100ff diff --git a/test_regress/t/t_sys_file_basic_uz.pl b/test_regress/t/t_sys_file_basic_uz.pl new file mode 100755 index 000000000..e2be86bfc --- /dev/null +++ b/test_regress/t/t_sys_file_basic_uz.pl @@ -0,0 +1,27 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(simulator => 1); + +unlink("$Self->{obj_dir}/t_sys_file_basic_uz_test.log"); + +compile(); + +execute( + check_finished => 1, + ); + +files_identical("$Self->{obj_dir}/t_sys_file_basic_uz_test.log", $Self->{golden_filename}); + +files_identical("$Self->{obj_dir}/t_sys_file_basic_uz_test.bin", + "$Self->{t_dir}/t_sys_file_basic_uz.dat"); + +ok(1); +1; diff --git a/test_regress/t/t_sys_file_basic_uz.v b/test_regress/t/t_sys_file_basic_uz.v new file mode 100644 index 000000000..a407299f1 --- /dev/null +++ b/test_regress/t/t_sys_file_basic_uz.v @@ -0,0 +1,137 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2030 by Stephen Henry. +// SPDX-License-Identifier: CC0-1.0 + +module t; + + int fdin_bin, fdout_txt, fdout_bin; +`define STRINGIFY(x) `"x`" + +`define checkh(gotv,expv) \ + do if ((gotv) !== (expv)) begin\ + $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv));\ + end while(0) + + // + // + task automatic test1; begin + for (int i = 0; i < 256; i++) begin + byte actual, expected; + expected = i[7:0]; + $fscanf(fdin_bin, "%u", actual); + `checkh(actual, expected); + $fdisplay(fdout_txt, "%h", actual); + $fwrite(fdout_bin, "%u", actual); + end + + for (int i = 0; i < 256; i++) begin + shortint actual, expected; + for (int j = 0; j < 2; j++) + expected[(8 * j)+:8] = i[7:0] + j[7:0]; + $fscanf(fdin_bin, "%u", actual); + `checkh(actual, expected); + $fdisplay(fdout_txt, "%h", actual); + $fwrite(fdout_bin, "%u", actual); + end + + for (int i = 0; i < 256; i++) begin + int actual, expected; + for (int j = 0; j < 4; j++) + expected[(8 * j)+:8] = i[7:0] + j[7:0]; + $fscanf(fdin_bin, "%u", actual); + `checkh(actual, expected); + $fdisplay(fdout_txt, "%h", actual); + $fwrite(fdout_bin, "%u", actual); + end + + for (int i = 0; i < 256; i++) begin + longint actual, expected; + for (int j = 0; j < 8; j++) + expected[(8 * j)+:8] = i[7:0] + j[7:0]; + $fscanf(fdin_bin, "%u", actual); + `checkh(actual, expected); + $fdisplay(fdout_txt, "%h", actual); + $fwrite(fdout_bin, "%u", actual); + end + end endtask + + // + // + task automatic test2; begin + for (int i = 0; i < 256; i++) begin + byte actual, expected; + expected = i[7:0]; + $fscanf(fdin_bin, "%z", actual); + `checkh(actual, expected); + $fdisplay(fdout_txt, "%h", actual); + $fwrite(fdout_bin, "%z", actual); + end + + for (int i = 0; i < 256; i++) begin + shortint actual, expected; + for (int j = 0; j < 2; j++) + expected[(8 * j)+:8] = i[7:0] + j[7:0]; + $fscanf(fdin_bin, "%z", actual); + `checkh(actual, expected); + $fdisplay(fdout_txt, "%h", actual); + $fwrite(fdout_bin, "%z", actual); + end + + for (int i = 0; i < 256; i++) begin + int actual, expected; + for (int j = 0; j < 4; j++) + expected[(8 * j)+:8] = i[7:0] + j[7:0]; + $fscanf(fdin_bin, "%z", actual); + `checkh(actual, expected); + $fdisplay(fdout_txt, "%h", actual); + $fwrite(fdout_bin, "%z", actual); + end + + for (int i = 0; i < 256; i++) begin + longint actual, expected; + for (int j = 0; j < 8; j++) + expected[(8 * j)+:8] = i[7:0] + j[7:0]; + $fscanf(fdin_bin, "%z", actual); + `checkh(actual, expected); + $fdisplay(fdout_txt, "%h", actual); + $fwrite(fdout_bin, "%z", actual); + end + end endtask + + initial begin : main_PROC + + string filename; + + filename = "t/t_sys_file_basic_uz.dat"; + fdin_bin = $fopen(filename, "rb"); + +`ifdef IVERILOG + filename = $sformatf("%s/t_sys_file_basic_uz_test.log","obj_iv/t_sys_file_basic_uz"); +`else + filename = $sformatf("%s/t_sys_file_basic_uz_test.log",`STRINGIFY(`TEST_OBJ_DIR)); +`endif + fdout_txt = $fopen(filename, "w"); + +`ifdef IVERILOG + filename = $sformatf("%s/t_sys_file_basic_uz_test.bin","obj_iv/t_sys_file_basic_uz"); +`else + filename = $sformatf("%s/t_sys_file_basic_uz_test.bin",`STRINGIFY(`TEST_OBJ_DIR)); +`endif + $display(filename); + fdout_bin = $fopen(filename, "wb"); + + test1; + test2; + + $fclose(fdin_bin); + $fclose(fdout_txt); + + $write("*-* All Finished *-*\n"); + $finish(0); // Test arguments to finish + + end // block: main_PROC + +`undef STRINGIFY +endmodule // t diff --git a/test_regress/t/t_sys_file_scan.pl b/test_regress/t/t_sys_file_scan.pl index f9d78641c..7169fcdde 100755 --- a/test_regress/t/t_sys_file_scan.pl +++ b/test_regress/t/t_sys_file_scan.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_fread.pl b/test_regress/t/t_sys_fread.pl index 144b8e678..d4594dc84 100755 --- a/test_regress/t/t_sys_fread.pl +++ b/test_regress/t/t_sys_fread.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_plusargs.pl b/test_regress/t/t_sys_plusargs.pl index 56ca5c0f3..05eeca761 100755 --- a/test_regress/t/t_sys_plusargs.pl +++ b/test_regress/t/t_sys_plusargs.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_plusargs_bad.pl b/test_regress/t/t_sys_plusargs_bad.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_sys_plusargs_bad.pl +++ b/test_regress/t/t_sys_plusargs_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_rand.pl b/test_regress/t/t_sys_rand.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_sys_rand.pl +++ b/test_regress/t/t_sys_rand.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_rand_seed.out b/test_regress/t/t_sys_rand_seed.out new file mode 100644 index 000000000..26738d308 --- /dev/null +++ b/test_regress/t/t_sys_rand_seed.out @@ -0,0 +1,7 @@ +%Error: t/t_sys_rand_seed.v:13:16: Unsupported: Seed on $random. Suggest use +verilator+seed+ runtime flag + 13 | valuea = $random(10); + | ^~~~~~~ +%Error: t/t_sys_rand_seed.v:14:16: Unsupported: Seed on $random. Suggest use +verilator+seed+ runtime flag + 14 | valueb = $random(10); + | ^~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_sys_rand_seed.pl b/test_regress/t/t_sys_rand_seed.pl new file mode 100755 index 000000000..391ec23fd --- /dev/null +++ b/test_regress/t/t_sys_rand_seed.pl @@ -0,0 +1,22 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(simulator => 1); + +compile( + fails => $Self->{vlt_all}, + expect_filename => $Self->{golden_filename}, + ); + +execute( + ) if !$Self->{vlt_all}; + +ok(1); +1; diff --git a/test_regress/t/t_sys_rand_seed.v b/test_regress/t/t_sys_rand_seed.v new file mode 100644 index 000000000..2780345a3 --- /dev/null +++ b/test_regress/t/t_sys_rand_seed.v @@ -0,0 +1,19 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t; + + int valuea; + int valueb; + + initial begin + valuea = $random(10); + valueb = $random(10); + if (valuea !== valueb) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_sys_readmem.pl b/test_regress/t/t_sys_readmem.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_sys_readmem.pl +++ b/test_regress/t/t_sys_readmem.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_readmem_assoc.pl b/test_regress/t/t_sys_readmem_assoc.pl index f797f73ce..493cedf7e 100755 --- a/test_regress/t/t_sys_readmem_assoc.pl +++ b/test_regress/t/t_sys_readmem_assoc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_readmem_assoc_bad.pl b/test_regress/t/t_sys_readmem_assoc_bad.pl index c1dba4c49..59ba0d6c6 100755 --- a/test_regress/t/t_sys_readmem_assoc_bad.pl +++ b/test_regress/t/t_sys_readmem_assoc_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => $Self->{vlt_all}, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_sys_readmem_bad_addr.pl b/test_regress/t/t_sys_readmem_bad_addr.pl index 1d965ffec..d89f1290d 100755 --- a/test_regress/t/t_sys_readmem_bad_addr.pl +++ b/test_regress/t/t_sys_readmem_bad_addr.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_readmem_bad_digit.pl b/test_regress/t/t_sys_readmem_bad_digit.pl index 1d965ffec..d89f1290d 100755 --- a/test_regress/t/t_sys_readmem_bad_digit.pl +++ b/test_regress/t/t_sys_readmem_bad_digit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_readmem_bad_end.pl b/test_regress/t/t_sys_readmem_bad_end.pl index 1d965ffec..d89f1290d 100755 --- a/test_regress/t/t_sys_readmem_bad_end.pl +++ b/test_regress/t/t_sys_readmem_bad_end.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_readmem_bad_notfound.pl b/test_regress/t/t_sys_readmem_bad_notfound.pl index 1d965ffec..d89f1290d 100755 --- a/test_regress/t/t_sys_readmem_bad_notfound.pl +++ b/test_regress/t/t_sys_readmem_bad_notfound.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_sformat.pl b/test_regress/t/t_sys_sformat.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_sys_sformat.pl +++ b/test_regress/t/t_sys_sformat.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_sformat_noopt.pl b/test_regress/t/t_sys_sformat_noopt.pl index 5a82f0df1..c27062f54 100755 --- a/test_regress/t/t_sys_sformat_noopt.pl +++ b/test_regress/t/t_sys_sformat_noopt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_system.pl b/test_regress/t/t_sys_system.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_sys_system.pl +++ b/test_regress/t/t_sys_system.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_time.pl b/test_regress/t/t_sys_time.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_sys_time.pl +++ b/test_regress/t/t_sys_time.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_sys_writemem.pl b/test_regress/t/t_sys_writemem.pl index 93c8b1672..431a02b0e 100755 --- a/test_regress/t/t_sys_writemem.pl +++ b/test_regress/t/t_sys_writemem.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_table_fsm.pl b/test_regress/t/t_table_fsm.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_table_fsm.pl +++ b/test_regress/t/t_table_fsm.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_threads_counter_0.pl b/test_regress/t/t_threads_counter_0.pl index 189abd405..8ba463b4e 100755 --- a/test_regress/t/t_threads_counter_0.pl +++ b/test_regress/t/t_threads_counter_0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_threads_counter_1.pl b/test_regress/t/t_threads_counter_1.pl index 0c3a06a5d..f1b1cf7b0 100755 --- a/test_regress/t/t_threads_counter_1.pl +++ b/test_regress/t/t_threads_counter_1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_threads_counter_2.pl b/test_regress/t/t_threads_counter_2.pl index 76c97a8b7..460c79651 100755 --- a/test_regress/t/t_threads_counter_2.pl +++ b/test_regress/t/t_threads_counter_2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_threads_counter_4.pl b/test_regress/t/t_threads_counter_4.pl index 856750e0f..97ac33b97 100755 --- a/test_regress/t/t_threads_counter_4.pl +++ b/test_regress/t/t_threads_counter_4.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_threads_nondeterminism.pl b/test_regress/t/t_threads_nondeterminism.pl index 0d4850945..418a03fc6 100755 --- a/test_regress/t/t_threads_nondeterminism.pl +++ b/test_regress/t/t_threads_nondeterminism.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_literals.pl b/test_regress/t/t_time_literals.pl index 48c6bfa36..1c5145af7 100755 --- a/test_regress/t/t_time_literals.pl +++ b/test_regress/t/t_time_literals.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_passed.pl b/test_regress/t/t_time_passed.pl index 2934909ea..88b7809fc 100755 --- a/test_regress/t/t_time_passed.pl +++ b/test_regress/t/t_time_passed.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_print.pl b/test_regress/t/t_time_print.pl index 2934909ea..88b7809fc 100755 --- a/test_regress/t/t_time_print.pl +++ b/test_regress/t/t_time_print.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_sc_bad.out b/test_regress/t/t_time_sc_bad.out index fb65dcdf0..86603162d 100644 --- a/test_regress/t/t_time_sc_bad.out +++ b/test_regress/t/t_time_sc_bad.out @@ -1,2 +1,2 @@ -%Error: SystemC's sc_set_time_resolution is 10^-9, which does not match Verilog timeprecision 10^-12. Suggest use 'sc_set_time_resolution(1ps)', or Verilator '--timescale-override 1ns/1ns' +%Error: SystemC's sc_set_time_resolution is 10^-9, which does not match Verilog timeprecision 10^-12. Suggest use 'sc_set_time_resolution(1s)', or Verilator '--timescale-override 1s/1s' Aborting... diff --git a/test_regress/t/t_time_sc_bad.pl b/test_regress/t/t_time_sc_bad.pl index 3a854f25d..1c293ef05 100755 --- a/test_regress/t/t_time_sc_bad.pl +++ b/test_regress/t/t_time_sc_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_sc_fs.pl b/test_regress/t/t_time_sc_fs.pl index 7bb640bfe..f3f22f608 100755 --- a/test_regress/t/t_time_sc_fs.pl +++ b/test_regress/t/t_time_sc_fs.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_sc_ms.pl b/test_regress/t/t_time_sc_ms.pl index 12e800db8..3e90c0c36 100755 --- a/test_regress/t/t_time_sc_ms.pl +++ b/test_regress/t/t_time_sc_ms.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_sc_ns.pl b/test_regress/t/t_time_sc_ns.pl index a9822649a..76073b3f8 100755 --- a/test_regress/t/t_time_sc_ns.pl +++ b/test_regress/t/t_time_sc_ns.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_sc_sec.pl b/test_regress/t/t_time_sc_sec.pl index bc1136ae2..8bc81ac97 100755 --- a/test_regress/t/t_time_sc_sec.pl +++ b/test_regress/t/t_time_sc_sec.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_sc_us.pl b/test_regress/t/t_time_sc_us.pl index 7c3769370..e5533c631 100755 --- a/test_regress/t/t_time_sc_us.pl +++ b/test_regress/t/t_time_sc_us.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_stamp64.pl b/test_regress/t/t_time_stamp64.pl index 27bf74bb1..a3a332be9 100755 --- a/test_regress/t/t_time_stamp64.pl +++ b/test_regress/t/t_time_stamp64.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_stamp_double.pl b/test_regress/t/t_time_stamp_double.pl index d86b6b3af..2b7dbde51 100755 --- a/test_regress/t/t_time_stamp_double.pl +++ b/test_regress/t/t_time_stamp_double.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_vpi_100s10ms.out b/test_regress/t/t_time_vpi_100s10ms.out new file mode 100644 index 000000000..73db352ca --- /dev/null +++ b/test_regress/t/t_time_vpi_100s10ms.out @@ -0,0 +1,15 @@ +:: In top.t +Time scale of t is 100s / 10ms +[100000000] time%0d=10000 123%0t=1230000 + dig%0t=0 dig%0d=0 + rdig%0t=543 rdig%0f=0.054321 +[0.000000ns] time%0d=10000 123%0t=12300000000000.000000ns + dig%0t=0.000000ns dig%0d=0 + rdig%0t=5432109876.543210ns rdig%0f=0.054321 +[0.000000ns] stime%0t=0.000000ns stime%0d=10000 stime%0f=10000.000000 +[0.000000ns] rtime%0t=0.000000ns rtime%0d=10000 rtime%0f=10000.000000 +global vpiSimTime = 0,100000000 vpiScaledRealTime = 1e+08 +global vpiTimeUnit = -2 vpiTimePrecision = -2 +top.t vpiSimTime = 0,100000000 vpiScaledRealTime = 10000 +top.t vpiTimeUnit = 2 vpiTimePrecision = -2 +*-* All Finished *-* diff --git a/test_regress/t/t_time_vpi_100s10ms.pl b/test_regress/t/t_time_vpi_100s10ms.pl new file mode 100755 index 000000000..34e5ba90e --- /dev/null +++ b/test_regress/t/t_time_vpi_100s10ms.pl @@ -0,0 +1,30 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(simulator_st => 1); + +top_filename("t/t_time_vpi.v"); + +$Self->{main_time_multiplier} = 100e0 / 10e-6; + +compile( + v_flags2 => ['+define+time_scale_units=100s +define+time_scale_prec=10ms', + 't/t_time_vpi_c.cpp'], + verilator_flags2 => ['--vpi'], + ); + +execute( + check_finished => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); + +1; diff --git a/test_regress/t/t_time_vpi_10ms10ns.pl b/test_regress/t/t_time_vpi_10ms10ns.pl index 6a32278b3..e6bf379c2 100755 --- a/test_regress/t/t_time_vpi_10ms10ns.pl +++ b/test_regress/t/t_time_vpi_10ms10ns.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_vpi_1fs1fs.pl b/test_regress/t/t_time_vpi_1fs1fs.pl index 7b8e47860..84b0c95c1 100755 --- a/test_regress/t/t_time_vpi_1fs1fs.pl +++ b/test_regress/t/t_time_vpi_1fs1fs.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_vpi_1ms10ns.pl b/test_regress/t/t_time_vpi_1ms10ns.pl index 05fc59263..713f547c2 100755 --- a/test_regress/t/t_time_vpi_1ms10ns.pl +++ b/test_regress/t/t_time_vpi_1ms10ns.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_vpi_1ns1ns.pl b/test_regress/t/t_time_vpi_1ns1ns.pl index 215358c27..32e10e69e 100755 --- a/test_regress/t/t_time_vpi_1ns1ns.pl +++ b/test_regress/t/t_time_vpi_1ns1ns.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_vpi_1ps1fs.pl b/test_regress/t/t_time_vpi_1ps1fs.pl index 4d172aefe..eb619bf9d 100755 --- a/test_regress/t/t_time_vpi_1ps1fs.pl +++ b/test_regress/t/t_time_vpi_1ps1fs.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_vpi_1s10ns.pl b/test_regress/t/t_time_vpi_1s10ns.pl index f98926d02..88d513a8a 100755 --- a/test_regress/t/t_time_vpi_1s10ns.pl +++ b/test_regress/t/t_time_vpi_1s10ns.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_time_vpi_1us1ns.pl b/test_regress/t/t_time_vpi_1us1ns.pl index 6a5205e42..e4b9adc38 100755 --- a/test_regress/t/t_time_vpi_1us1ns.pl +++ b/test_regress/t/t_time_vpi_1us1ns.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_timescale.pl b/test_regress/t/t_timescale.pl index 7cd01c28d..1bab927e5 100755 --- a/test_regress/t/t_timescale.pl +++ b/test_regress/t/t_timescale.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_timescale_default.pl b/test_regress/t/t_timescale_default.pl index 2934909ea..88b7809fc 100755 --- a/test_regress/t/t_timescale_default.pl +++ b/test_regress/t/t_timescale_default.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_timescale_lint_bad.pl b/test_regress/t/t_timescale_lint_bad.pl index 6c66d6a67..54c63c732 100755 --- a/test_regress/t/t_timescale_lint_bad.pl +++ b/test_regress/t/t_timescale_lint_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_timescale_parse.pl b/test_regress/t/t_timescale_parse.pl index 7b012fe8b..334cd0451 100755 --- a/test_regress/t/t_timescale_parse.pl +++ b/test_regress/t/t_timescale_parse.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_timescale_parse.v b/test_regress/t/t_timescale_parse.v index 63e5fbb1e..e58bb0741 100644 --- a/test_regress/t/t_timescale_parse.v +++ b/test_regress/t/t_timescale_parse.v @@ -12,38 +12,42 @@ module modname; \ task check; t = 1ns; $write("%m %0t\n", t); endtask \ endmodule +`timescale 100s/1fs +`testmod(sp2) +`timescale 10s/1fs +`testmod(sp1) `timescale 1s/1fs -`testmod(s0) +`testmod(sp0) `timescale 100ms/1fs -`testmod(s1) +`testmod(sm1) `timescale 10ms/1fs -`testmod(s2) +`testmod(sm2) `timescale 1ms/1fs -`testmod(s3) +`testmod(sm3) `timescale 100us/1fs -`testmod(s4) +`testmod(sm4) `timescale 10us/1fs -`testmod(s5) +`testmod(sm5) `timescale 1us/1fs -`testmod(s6) +`testmod(sm6) `timescale 100ns/1fs -`testmod(s7) +`testmod(sm7) `timescale 10ns/1fs -`testmod(s8) +`testmod(sm8) `timescale 1ns/1fs -`testmod(s9) +`testmod(sm9) `timescale 100ps/1fs -`testmod(s10) +`testmod(sm10) `timescale 10ps/1fs -`testmod(s11) +`testmod(sm11) `timescale 1ps/1fs -`testmod(s12) +`testmod(sm12) `timescale 100 fs/1fs -`testmod(s13) +`testmod(sm13) `timescale 10fs/1 fs -`testmod(s14) +`testmod(sm14) `timescale 1 fs / 1 fs // Comment -`testmod(s15) +`testmod(sm15) module r0; @@ -58,43 +62,47 @@ module r1; endmodule module t; - s0 s0(); - s1 s1(); - s2 s2(); - s3 s3(); - s4 s4(); - s5 s5(); - s6 s6(); - s7 s7(); - s8 s8(); - s9 s9(); - s10 s10(); - s11 s11(); - s12 s12(); - s13 s13(); - s14 s14(); - s15 s15(); + sp2 sp2(); + sp1 sp1(); + sp0 sp0(); + sm1 sm1(); + sm2 sm2(); + sm3 sm3(); + sm4 sm4(); + sm5 sm5(); + sm6 sm6(); + sm7 sm7(); + sm8 sm8(); + sm9 sm9(); + sm10 sm10(); + sm11 sm11(); + sm12 sm12(); + sm13 sm13(); + sm14 sm14(); + sm15 sm15(); r0 r0(); r1 r1(); final begin - s0.check(); - s1.check(); - s2.check(); - s3.check(); - s4.check(); - s5.check(); - s6.check(); - s7.check(); - s8.check(); - s9.check(); - s10.check(); - s11.check(); - s12.check(); - s13.check(); - s14.check(); - s15.check(); + sp2.check(); + sp1.check(); + sp0.check(); + sm1.check(); + sm2.check(); + sm3.check(); + sm4.check(); + sm5.check(); + sm6.check(); + sm7.check(); + sm8.check(); + sm9.check(); + sm10.check(); + sm11.check(); + sm12.check(); + sm13.check(); + sm14.check(); + sm15.check(); r0.check(); r1.check(); $write("*-* All Finished *-*\n"); diff --git a/test_regress/t/t_timescale_parse_bad.pl b/test_regress/t/t_timescale_parse_bad.pl index c1dba4c49..59ba0d6c6 100755 --- a/test_regress/t/t_timescale_parse_bad.pl +++ b/test_regress/t/t_timescale_parse_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => $Self->{vlt_all}, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_trace_array.pl b/test_regress/t/t_trace_array.pl index fd2cd5027..63bf5c2b6 100755 --- a/test_regress/t/t_trace_array.pl +++ b/test_regress/t/t_trace_array.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_array_fst.pl b/test_regress/t/t_trace_array_fst.pl index f3b30bbf0..f09bea826 100755 --- a/test_regress/t/t_trace_array_fst.pl +++ b/test_regress/t/t_trace_array_fst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_array_fst_portable.pl b/test_regress/t/t_trace_array_fst_portable.pl index 0b15dea3c..f182ef1b7 100755 --- a/test_regress/t/t_trace_array_fst_portable.pl +++ b/test_regress/t/t_trace_array_fst_portable.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_array_fst_threads_1.pl b/test_regress/t/t_trace_array_fst_threads_1.pl index 487c4b474..0be5ffbc2 100755 --- a/test_regress/t/t_trace_array_fst_threads_1.pl +++ b/test_regress/t/t_trace_array_fst_threads_1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_array_fst_threads_2.pl b/test_regress/t/t_trace_array_fst_threads_2.pl index 170baffe6..e20a9056b 100755 --- a/test_regress/t/t_trace_array_fst_threads_2.pl +++ b/test_regress/t/t_trace_array_fst_threads_2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_array_threads_1.pl b/test_regress/t/t_trace_array_threads_1.pl index 00d9d4789..618053e42 100755 --- a/test_regress/t/t_trace_array_threads_1.pl +++ b/test_regress/t/t_trace_array_threads_1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_c_api.cpp b/test_regress/t/t_trace_c_api.cpp new file mode 100644 index 000000000..5b8e5dbc7 --- /dev/null +++ b/test_regress/t/t_trace_c_api.cpp @@ -0,0 +1,22 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +// +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2008 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +#include +#include + +#include VM_PREFIX_INCLUDE + +extern void vcdTestMain(const char* filenamep); + +int main(int argc, char** argv, char** env) { + const char* filenamep = VL_STRINGIFY(TEST_OBJ_DIR) "/simx.vcd"; + printf("Writing %s\n", filenamep); + vcdTestMain(filenamep); + printf("*-* All Finished *-*\n"); + return 0; +} diff --git a/test_regress/t/t_trace_c_api.pl b/test_regress/t/t_trace_c_api.pl new file mode 100755 index 000000000..541970008 --- /dev/null +++ b/test_regress/t/t_trace_c_api.pl @@ -0,0 +1,30 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003-2013 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 + +scenarios(vlt => 1); + +compile( + make_top_shell => 0, + make_main => 0, + v_flags2 => ["--trace --exe $Self->{t_dir}/t_trace_c_api.cpp", + "-CFLAGS -DVERILATED_VCD_TEST", + "-CFLAGS -DVL_TRACE_VCD_OLD_API"], + ); + +execute( + check_finished => 1, + ); + +# vcddiff bug crashes +#vcd_identical("$Self->{obj_dir}/simx.vcd", +# $Self->{golden_filename}); + +ok(1); +1; diff --git a/test_regress/t/t_trace_c_api.v b/test_regress/t/t_trace_c_api.v new file mode 100644 index 000000000..7b440cb91 --- /dev/null +++ b/test_regress/t/t_trace_c_api.v @@ -0,0 +1,8 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2013 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t; +endmodule diff --git a/test_regress/t/t_trace_cat.pl b/test_regress/t/t_trace_cat.pl index 958db5f1c..78832a416 100755 --- a/test_regress/t/t_trace_cat.pl +++ b/test_regress/t/t_trace_cat.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_cat_renew.pl b/test_regress/t/t_trace_cat_renew.pl index 45b0aabb0..8ea59e856 100755 --- a/test_regress/t/t_trace_cat_renew.pl +++ b/test_regress/t/t_trace_cat_renew.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_cat_reopen.pl b/test_regress/t/t_trace_cat_reopen.pl index 45b0aabb0..8ea59e856 100755 --- a/test_regress/t/t_trace_cat_reopen.pl +++ b/test_regress/t/t_trace_cat_reopen.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_complex.pl b/test_regress/t/t_trace_complex.pl index 5fde2b79c..49c306eb5 100755 --- a/test_regress/t/t_trace_complex.pl +++ b/test_regress/t/t_trace_complex.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_complex_fst.pl b/test_regress/t/t_trace_complex_fst.pl index 9b76e1c36..6ec35cae7 100755 --- a/test_regress/t/t_trace_complex_fst.pl +++ b/test_regress/t/t_trace_complex_fst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_complex_fst_threads_1.pl b/test_regress/t/t_trace_complex_fst_threads_1.pl index 5e9707bf6..e38cce31c 100755 --- a/test_regress/t/t_trace_complex_fst_threads_1.pl +++ b/test_regress/t/t_trace_complex_fst_threads_1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_complex_fst_threads_2.pl b/test_regress/t/t_trace_complex_fst_threads_2.pl index 7cbdebcbb..72d74d432 100755 --- a/test_regress/t/t_trace_complex_fst_threads_2.pl +++ b/test_regress/t/t_trace_complex_fst_threads_2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_complex_old_api.pl b/test_regress/t/t_trace_complex_old_api.pl index 730aa1e76..f1b4027b6 100755 --- a/test_regress/t/t_trace_complex_old_api.pl +++ b/test_regress/t/t_trace_complex_old_api.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_complex_params.pl b/test_regress/t/t_trace_complex_params.pl index 0c896905a..04c792441 100755 --- a/test_regress/t/t_trace_complex_params.pl +++ b/test_regress/t/t_trace_complex_params.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_complex_params_fst.pl b/test_regress/t/t_trace_complex_params_fst.pl index ecb5daf90..aba062c24 100755 --- a/test_regress/t/t_trace_complex_params_fst.pl +++ b/test_regress/t/t_trace_complex_params_fst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_complex_portable.pl b/test_regress/t/t_trace_complex_portable.pl index b168579a4..5ddd2e3a4 100755 --- a/test_regress/t/t_trace_complex_portable.pl +++ b/test_regress/t/t_trace_complex_portable.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_complex_structs.pl b/test_regress/t/t_trace_complex_structs.pl index c02c2edba..6234bcdde 100755 --- a/test_regress/t/t_trace_complex_structs.pl +++ b/test_regress/t/t_trace_complex_structs.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_complex_structs_fst.pl b/test_regress/t/t_trace_complex_structs_fst.pl index 08626b897..def4c9f46 100755 --- a/test_regress/t/t_trace_complex_structs_fst.pl +++ b/test_regress/t/t_trace_complex_structs_fst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_complex_threads_1.pl b/test_regress/t/t_trace_complex_threads_1.pl index 0999ed679..483faf3ab 100755 --- a/test_regress/t/t_trace_complex_threads_1.pl +++ b/test_regress/t/t_trace_complex_threads_1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_decoration.pl b/test_regress/t/t_trace_decoration.pl index 1e56e3468..fd2355ca5 100755 --- a/test_regress/t/t_trace_decoration.pl +++ b/test_regress/t/t_trace_decoration.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_dumporder_bad.pl b/test_regress/t/t_trace_dumporder_bad.pl index f631d6efd..df6f46881 100755 --- a/test_regress/t/t_trace_dumporder_bad.pl +++ b/test_regress/t/t_trace_dumporder_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_ena_cc.out b/test_regress/t/t_trace_ena_cc.out index 32c437d8a..15693b267 100644 --- a/test_regress/t/t_trace_ena_cc.out +++ b/test_regress/t/t_trace_ena_cc.out @@ -83,7 +83,7 @@ r0.8999999999999999 % #95 0' #100 +1' b00000000000000000000000000001011 # b00000000000000000000000000001001 $ r0.9999999999999999 % -1' diff --git a/test_regress/t/t_trace_ena_cc.pl b/test_regress/t/t_trace_ena_cc.pl index c21a28eac..ff3debaf3 100755 --- a/test_regress/t/t_trace_ena_cc.pl +++ b/test_regress/t/t_trace_ena_cc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_ena_sc.pl b/test_regress/t/t_trace_ena_sc.pl index 1b3f63236..6a493841e 100755 --- a/test_regress/t/t_trace_ena_sc.pl +++ b/test_regress/t/t_trace_ena_sc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_flag_off.pl b/test_regress/t/t_trace_flag_off.pl index 08f94898c..32a214e08 100755 --- a/test_regress/t/t_trace_flag_off.pl +++ b/test_regress/t/t_trace_flag_off.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -16,7 +16,6 @@ compile( execute( expect_filename => $Self->{golden_filename}, - fails => 0, ); ok(1); diff --git a/test_regress/t/t_trace_fst.pl b/test_regress/t/t_trace_fst.pl index f03d12134..42029ba72 100755 --- a/test_regress/t/t_trace_fst.pl +++ b/test_regress/t/t_trace_fst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_litendian.out b/test_regress/t/t_trace_litendian.out new file mode 100644 index 000000000..c51c5e99e --- /dev/null +++ b/test_regress/t/t_trace_litendian.out @@ -0,0 +1,144 @@ +$version Generated by VerilatedVcd $end +$date Sun May 3 21:38:46 2020 + $end +$timescale 1ps $end + + $scope module top $end + $var wire 1 } clk $end + $scope module t $end + $var wire 8 ~ P [0:7] $end + $var wire 8 !! Q [0:7] $end + $var wire 1 } clk $end + $var wire 32 # cyc [31:0] $end + $var wire 1 $ v_a [0:0] $end + $var wire 2 % v_b [0:1] $end + $var wire 8 & v_c [0:7] $end + $var wire 9 ' v_d [0:8] $end + $var wire 16 ( v_e [0:15] $end + $var wire 17 ) v_f [0:16] $end + $var wire 32 * v_g [0:31] $end + $var wire 33 + v_h [0:32] $end + $var wire 64 - v_i [0:63] $end + $var wire 65 / v_j [0:64] $end + $var wire 128 2 v_k [0:127] $end + $var wire 129 6 v_l [0:128] $end + $var wire 256 ; v_m [0:255] $end + $var wire 257 C v_n [0:256] $end + $var wire 512 L v_o [0:511] $end + $var wire 3 \ v_p [-1:1] $end + $var wire 15 ] v_q [-7:7] $end + $var wire 31 ^ v_r [-15:15] $end + $var wire 63 _ v_s [-31:31] $end + $var wire 127 a v_t [-63:63] $end + $var wire 255 e v_u [-127:127] $end + $var wire 511 m v_v [-255:255] $end + $upscope $end + $upscope $end +$enddefinitions $end + + +#0 +b00000000000000000000000000000000 # +0$ +b00 % +b00000000 & +b000000000 ' +b0000000000000000 ( +b00000000000000000 ) +b00000000000000000000000000000000 * +b000000000000000000000000000000000 + +b0000000000000000000000000000000000000000000000000000000000000000 - +b00000000000000000000000000000000000000000000000000000000000000000 / +b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 2 +b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 6 +b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ; +b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 C +b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 L +b000 \ +b000000000000000 ] +b0000000000000000000000000000000 ^ +b000000000000000000000000000000000000000000000000000000000000000 _ +b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 a +b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 e +b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 m +0} +b00001010 ~ +b00010100 !! +#10 +b00000000000000000000000000000001 # +1$ +b11 % +b11111111 & +b111111111 ' +b1111111111111111 ( +b11111111111111111 ) +b11111111111111111111111111111111 * +b111111111111111111111111111111111 + +b1111111111111111111111111111111111111111111111111111111111111111 - +b11111111111111111111111111111111111111111111111111111111111111111 / +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 2 +b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 6 +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 ; +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 C +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 L +b111 \ +b111111111111111 ] +b1111111111111111111111111111111 ^ +b111111111111111111111111111111111111111111111111111111111111111 _ +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 a +b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 e +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 m +1} +#15 +0} +#20 +b00000000000000000000000000000010 # +0$ +b10 % +b11111110 & +b111111110 ' +b1111111111111110 ( +b11111111111111110 ) +b11111111111111111111111111111110 * +b111111111111111111111111111111110 + +b1111111111111111111111111111111111111111111111111111111111111110 - +b11111111111111111111111111111111111111111111111111111111111111110 / +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 2 +b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 6 +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 ; +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 C +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 L +b110 \ +b111111111111110 ] +b1111111111111111111111111111110 ^ +b111111111111111111111111111111111111111111111111111111111111110 _ +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 a +b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 e +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 m +1} +#25 +0} +#30 +b00000000000000000000000000000011 # +b00 % +b11111100 & +b111111100 ' +b1111111111111100 ( +b11111111111111100 ) +b11111111111111111111111111111100 * +b111111111111111111111111111111100 + +b1111111111111111111111111111111111111111111111111111111111111100 - +b11111111111111111111111111111111111111111111111111111111111111100 / +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 2 +b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 6 +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 ; +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 C +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 L +b100 \ +b111111111111100 ] +b1111111111111111111111111111100 ^ +b111111111111111111111111111111111111111111111111111111111111100 _ +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 a +b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 e +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 m +1} diff --git a/test_regress/t/t_trace_litendian.pl b/test_regress/t/t_trace_litendian.pl new file mode 100755 index 000000000..6ed5efd1c --- /dev/null +++ b/test_regress/t/t_trace_litendian.pl @@ -0,0 +1,28 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Geza Lore. 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 + +scenarios(simulator => 1); + +# Travis environment offers 2 VCPUs, 2 thread setting causes the following warning. +# %Warning-UNOPTTHREADS: Thread scheduler is unable to provide requested parallelism; consider asking for fewer threads. +# Strangely, asking for more threads makes it go away. +compile( + verilator_flags2 => ['--cc --trace --trace-params -Wno-LITENDIAN', + ($Self->{vltmt} ? '--threads 6' : '')], + ); + +execute( + check_finished => 1, + ); + +vcd_identical("$Self->{obj_dir}/simx.vcd", $Self->{golden_filename}); + +ok(1); +1; diff --git a/test_regress/t/t_trace_litendian.v b/test_regress/t/t_trace_litendian.v new file mode 100644 index 000000000..348b80ea6 --- /dev/null +++ b/test_regress/t/t_trace_litendian.v @@ -0,0 +1,97 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Geza Lore. +// SPDX-License-Identifier: CC0-1.0 + +module t #( + parameter [0:7] P = 8'd10 + )(/*AUTOARG*/ + // Inputs + clk + ); + input clk; + int cyc = 0; + + localparam [0:7] Q = 8'd20; + + logic [ 0: 0] v_a = '0; + logic [ 0: 1] v_b = '0; + logic [ 0: 7] v_c = '0; + logic [ 0: 8] v_d = '0; + logic [ 0: 15] v_e = '0; + logic [ 0: 16] v_f = '0; + logic [ 0: 31] v_g = '0; + logic [ 0: 32] v_h = '0; + logic [ 0: 63] v_i = '0; + logic [ 0: 64] v_j = '0; + logic [ 0:127] v_k = '0; + logic [ 0:128] v_l = '0; + logic [ 0:255] v_m = '0; + logic [ 0:256] v_n = '0; + logic [ 0:511] v_o = '0; + logic [ -1: 1] v_p = '0; + logic [ -7: 7] v_q = '0; + logic [ -15: 15] v_r = '0; + logic [ -31: 31] v_s = '0; + logic [ -63: 63] v_t = '0; + logic [-127:127] v_u = '0; + logic [-255:255] v_v = '0; + + always @(posedge clk) begin + if (cyc == 0) begin + v_a <= '1; + v_b <= '1; + v_c <= '1; + v_d <= '1; + v_e <= '1; + v_f <= '1; + v_g <= '1; + v_h <= '1; + v_i <= '1; + v_j <= '1; + v_k <= '1; + v_l <= '1; + v_m <= '1; + v_n <= '1; + v_o <= '1; + v_p <= '1; + v_q <= '1; + v_r <= '1; + v_s <= '1; + v_t <= '1; + v_u <= '1; + v_v <= '1; + end else begin + v_a <= v_a << 1; + v_b <= v_b << 1; + v_c <= v_c << 1; + v_d <= v_d << 1; + v_e <= v_e << 1; + v_f <= v_f << 1; + v_g <= v_g << 1; + v_h <= v_h << 1; + v_i <= v_i << 1; + v_j <= v_j << 1; + v_k <= v_k << 1; + v_l <= v_l << 1; + v_m <= v_m << 1; + v_n <= v_n << 1; + v_o <= v_o << 1; + v_p <= v_p << 1; + v_q <= v_q << 1; + v_r <= v_r << 1; + v_s <= v_s << 1; + v_t <= v_t << 1; + v_u <= v_u << 1; + v_v <= v_v << 1; + end + + cyc <= cyc + 1; + if (cyc == 2) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + +endmodule diff --git a/test_regress/t/t_trace_litendian_fst.out b/test_regress/t/t_trace_litendian_fst.out new file mode 100644 index 000000000..fca4ff32e --- /dev/null +++ b/test_regress/t/t_trace_litendian_fst.out @@ -0,0 +1,149 @@ +$date + Sun May 3 21:53:46 2020 + +$end +$version + fstWriter +$end +$timescale + 1ps +$end +$scope module top $end +$var wire 1 ! clk $end +$scope module t $end +$var parameter 8 " P $end +$var wire 1 ! clk $end +$var int 32 # cyc $end +$var parameter 8 $ Q $end +$var logic 1 % v_a $end +$var logic 2 & v_b $end +$var logic 8 ' v_c $end +$var logic 9 ( v_d $end +$var logic 16 ) v_e $end +$var logic 17 * v_f $end +$var logic 32 + v_g $end +$var logic 33 , v_h $end +$var logic 64 - v_i $end +$var logic 65 . v_j $end +$var logic 128 / v_k $end +$var logic 129 0 v_l $end +$var logic 256 1 v_m $end +$var logic 257 2 v_n $end +$var logic 512 3 v_o $end +$var logic 3 4 v_p $end +$var logic 15 5 v_q $end +$var logic 31 6 v_r $end +$var logic 63 7 v_s $end +$var logic 127 8 v_t $end +$var logic 255 9 v_u $end +$var logic 511 : v_v $end +$upscope $end +$upscope $end +$enddefinitions $end +#0 +$dumpvars +b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 : +b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 9 +b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 8 +b000000000000000000000000000000000000000000000000000000000000000 7 +b0000000000000000000000000000000 6 +b000000000000000 5 +b000 4 +b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 3 +b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 2 +b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1 +b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0 +b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 / +b00000000000000000000000000000000000000000000000000000000000000000 . +b0000000000000000000000000000000000000000000000000000000000000000 - +b000000000000000000000000000000000 , +b00000000000000000000000000000000 + +b00000000000000000 * +b0000000000000000 ) +b000000000 ( +b00000000 ' +b00 & +0% +b00010100 $ +b00000000000000000000000000000000 # +b00001010 " +0! +$end +#10 +1! +b00000000000000000000000000000001 # +1% +b11 & +b11111111 ' +b111111111 ( +b1111111111111111 ) +b11111111111111111 * +b11111111111111111111111111111111 + +b111111111111111111111111111111111 , +b1111111111111111111111111111111111111111111111111111111111111111 - +b11111111111111111111111111111111111111111111111111111111111111111 . +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 / +b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 0 +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 1 +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 2 +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 3 +b111 4 +b111111111111111 5 +b1111111111111111111111111111111 6 +b111111111111111111111111111111111111111111111111111111111111111 7 +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 8 +b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 9 +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 : +#15 +0! +#20 +1! +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 : +b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 9 +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 8 +b111111111111111111111111111111111111111111111111111111111111110 7 +b1111111111111111111111111111110 6 +b111111111111110 5 +b110 4 +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 3 +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 2 +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 1 +b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 0 +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110 / +b11111111111111111111111111111111111111111111111111111111111111110 . +b1111111111111111111111111111111111111111111111111111111111111110 - +b111111111111111111111111111111110 , +b11111111111111111111111111111110 + +b11111111111111110 * +b1111111111111110 ) +b111111110 ( +b11111110 ' +b10 & +0% +b00000000000000000000000000000010 # +#25 +0! +#30 +1! +b00000000000000000000000000000011 # +b00 & +b11111100 ' +b111111100 ( +b1111111111111100 ) +b11111111111111100 * +b11111111111111111111111111111100 + +b111111111111111111111111111111100 , +b1111111111111111111111111111111111111111111111111111111111111100 - +b11111111111111111111111111111111111111111111111111111111111111100 . +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 / +b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 0 +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 1 +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 2 +b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 3 +b100 4 +b111111111111100 5 +b1111111111111111111111111111100 6 +b111111111111111111111111111111111111111111111111111111111111100 7 +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 8 +b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 9 +b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100 : diff --git a/test_regress/t/t_trace_litendian_fst.pl b/test_regress/t/t_trace_litendian_fst.pl new file mode 100755 index 000000000..f13aa0c0d --- /dev/null +++ b/test_regress/t/t_trace_litendian_fst.pl @@ -0,0 +1,30 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Geza Lore. 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 + +scenarios(simulator => 1); + +top_filename("t/t_trace_litendian.v"); + +# Travis environment offers 2 VCPUs, 2 thread setting causes the following warning. +# %Warning-UNOPTTHREADS: Thread scheduler is unable to provide requested parallelism; consider asking for fewer threads. +# Strangely, asking for more threads makes it go away. +compile( + verilator_flags2 => ['--cc --trace-fst --trace-params -Wno-LITENDIAN', + ($Self->{vltmt} ? '--threads 6' : '')], + ); + +execute( + check_finished => 1, + ); + +fst_identical("$Self->{obj_dir}/simx.fst", $Self->{golden_filename}); + +ok(1); +1; diff --git a/test_regress/t/t_trace_off_cc.pl b/test_regress/t/t_trace_off_cc.pl index e339997bf..0aa901413 100755 --- a/test_regress/t/t_trace_off_cc.pl +++ b/test_regress/t/t_trace_off_cc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_off_sc.pl b/test_regress/t/t_trace_off_sc.pl index 3a5f13f69..fb6a3392e 100755 --- a/test_regress/t/t_trace_off_sc.pl +++ b/test_regress/t/t_trace_off_sc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_packed_struct.pl b/test_regress/t/t_trace_packed_struct.pl index d41b7c1ba..795f3673b 100755 --- a/test_regress/t/t_trace_packed_struct.pl +++ b/test_regress/t/t_trace_packed_struct.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_packed_struct_fst.pl b/test_regress/t/t_trace_packed_struct_fst.pl index a84d85f7d..394fb3efd 100755 --- a/test_regress/t/t_trace_packed_struct_fst.pl +++ b/test_regress/t/t_trace_packed_struct_fst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_param.pl b/test_regress/t/t_trace_param.pl index d9fbe89cc..71022a7d7 100755 --- a/test_regress/t/t_trace_param.pl +++ b/test_regress/t/t_trace_param.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_param_fst.pl b/test_regress/t/t_trace_param_fst.pl index 87446f8d1..38e46c0b8 100755 --- a/test_regress/t/t_trace_param_fst.pl +++ b/test_regress/t/t_trace_param_fst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_primitive.pl b/test_regress/t/t_trace_primitive.pl index 515d10698..dc8c69b4c 100755 --- a/test_regress/t/t_trace_primitive.pl +++ b/test_regress/t/t_trace_primitive.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_primitive_fst.pl b/test_regress/t/t_trace_primitive_fst.pl index f2b56c2bd..2c52884c2 100755 --- a/test_regress/t/t_trace_primitive_fst.pl +++ b/test_regress/t/t_trace_primitive_fst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_public_func.pl b/test_regress/t/t_trace_public_func.pl index 672d8ce55..e17f41601 100755 --- a/test_regress/t/t_trace_public_func.pl +++ b/test_regress/t/t_trace_public_func.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_public_func_vlt.pl b/test_regress/t/t_trace_public_func_vlt.pl index 29380e643..3c627949a 100755 --- a/test_regress/t/t_trace_public_func_vlt.pl +++ b/test_regress/t/t_trace_public_func_vlt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_public_sig.pl b/test_regress/t/t_trace_public_sig.pl index c882e2679..0a577a343 100755 --- a/test_regress/t/t_trace_public_sig.pl +++ b/test_regress/t/t_trace_public_sig.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_public_sig_vlt.pl b/test_regress/t/t_trace_public_sig_vlt.pl index 7ecac0618..2f20c9ff2 100755 --- a/test_regress/t/t_trace_public_sig_vlt.pl +++ b/test_regress/t/t_trace_public_sig_vlt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_scstruct.pl b/test_regress/t/t_trace_scstruct.pl index 77cb15478..fb375c474 100755 --- a/test_regress/t/t_trace_scstruct.pl +++ b/test_regress/t/t_trace_scstruct.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_string.pl b/test_regress/t/t_trace_string.pl index d3096503a..544c5a7a4 100755 --- a/test_regress/t/t_trace_string.pl +++ b/test_regress/t/t_trace_string.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_string_fst.pl b/test_regress/t/t_trace_string_fst.pl index 01a7456be..cfd82a08d 100755 --- a/test_regress/t/t_trace_string_fst.pl +++ b/test_regress/t/t_trace_string_fst.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_timescale.out b/test_regress/t/t_trace_timescale.out index 208185cca..34791f485 100644 --- a/test_regress/t/t_trace_timescale.out +++ b/test_regress/t/t_trace_timescale.out @@ -67,5 +67,5 @@ b00000000000000000000000000001010 # #105 0+ #110 -b00000000000000000000000000001011 # 1+ +b00000000000000000000000000001011 # diff --git a/test_regress/t/t_trace_timescale.pl b/test_regress/t/t_trace_timescale.pl index 548304134..ed4a3b3e4 100755 --- a/test_regress/t/t_trace_timescale.pl +++ b/test_regress/t/t_trace_timescale.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_two_cc.cpp b/test_regress/t/t_trace_two_cc.cpp index 5cd87cbeb..e339c6a24 100644 --- a/test_regress/t/t_trace_two_cc.cpp +++ b/test_regress/t/t_trace_two_cc.cpp @@ -20,6 +20,7 @@ // Compile in place #include "Vt_trace_two_b.cpp" +#include "Vt_trace_two_b__Slow.cpp" #include "Vt_trace_two_b__Syms.cpp" #include "Vt_trace_two_b__Trace.cpp" #include "Vt_trace_two_b__Trace__Slow.cpp" diff --git a/test_regress/t/t_trace_two_dump_cc.out b/test_regress/t/t_trace_two_dump_cc.out index c452d0e3f..46be29d26 100644 --- a/test_regress/t/t_trace_two_dump_cc.out +++ b/test_regress/t/t_trace_two_dump_cc.out @@ -100,6 +100,6 @@ b00000000000000000000000000001011 + 03 #110 #110 +13 b00000000000000000000000000001011 # b00000000000000000000000000001100 + -13 diff --git a/test_regress/t/t_trace_two_dump_cc.pl b/test_regress/t/t_trace_two_dump_cc.pl index e76663909..0b20803a9 100755 --- a/test_regress/t/t_trace_two_dump_cc.pl +++ b/test_regress/t/t_trace_two_dump_cc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_two_dump_sc.pl b/test_regress/t/t_trace_two_dump_sc.pl index 68b7e66fa..311848fe7 100755 --- a/test_regress/t/t_trace_two_dump_sc.pl +++ b/test_regress/t/t_trace_two_dump_sc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_two_dumpfst_cc.pl b/test_regress/t/t_trace_two_dumpfst_cc.pl index 6a1fae915..37f00db1c 100755 --- a/test_regress/t/t_trace_two_dumpfst_cc.pl +++ b/test_regress/t/t_trace_two_dumpfst_cc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_two_hdr_cc.pl b/test_regress/t/t_trace_two_hdr_cc.pl index a9c610767..352e12450 100755 --- a/test_regress/t/t_trace_two_hdr_cc.pl +++ b/test_regress/t/t_trace_two_hdr_cc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_two_hdr_sc.out b/test_regress/t/t_trace_two_hdr_sc.out index 8f680510d..46befffe5 100644 --- a/test_regress/t/t_trace_two_hdr_sc.out +++ b/test_regress/t/t_trace_two_hdr_sc.out @@ -120,7 +120,7 @@ r0.8999999999999999 F 0> #100000 1# +1> b00000000000000000000000000001011 + b00000000000000000000000000001100 3 -1> r0.9999999999999999 F diff --git a/test_regress/t/t_trace_two_hdr_sc.pl b/test_regress/t/t_trace_two_hdr_sc.pl index 922edf3cd..b62a58aef 100755 --- a/test_regress/t/t_trace_two_hdr_sc.pl +++ b/test_regress/t/t_trace_two_hdr_sc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_two_hdrfst_cc.pl b/test_regress/t/t_trace_two_hdrfst_cc.pl index 653776ccc..cbdae9a87 100755 --- a/test_regress/t/t_trace_two_hdrfst_cc.pl +++ b/test_regress/t/t_trace_two_hdrfst_cc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_two_port_cc.out b/test_regress/t/t_trace_two_port_cc.out index 4764562aa..9858cf941 100644 --- a/test_regress/t/t_trace_two_port_cc.out +++ b/test_regress/t/t_trace_two_port_cc.out @@ -100,6 +100,6 @@ b00000000000000000000000000001011 + 03 #110 #110 +13 b00000000000000000000000000001011 # b00000000000000000000000000001100 + -13 diff --git a/test_regress/t/t_trace_two_port_cc.pl b/test_regress/t/t_trace_two_port_cc.pl index e12876ece..c35b91acb 100755 --- a/test_regress/t/t_trace_two_port_cc.pl +++ b/test_regress/t/t_trace_two_port_cc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_two_port_sc.pl b/test_regress/t/t_trace_two_port_sc.pl index ce581bf42..84676c3a8 100755 --- a/test_regress/t/t_trace_two_port_sc.pl +++ b/test_regress/t/t_trace_two_port_sc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_two_portfst_cc.pl b/test_regress/t/t_trace_two_portfst_cc.pl index 299b3cefb..689296b42 100755 --- a/test_regress/t/t_trace_two_portfst_cc.pl +++ b/test_regress/t/t_trace_two_portfst_cc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_trace_two_sc.cpp b/test_regress/t/t_trace_two_sc.cpp index 1f313d7d7..21a7a954b 100644 --- a/test_regress/t/t_trace_two_sc.cpp +++ b/test_regress/t/t_trace_two_sc.cpp @@ -16,6 +16,7 @@ // Compile in place #include "Vt_trace_two_b.cpp" +#include "Vt_trace_two_b__Slow.cpp" #include "Vt_trace_two_b__Syms.cpp" #include "Vt_trace_two_b__Trace.cpp" #include "Vt_trace_two_b__Trace__Slow.cpp" diff --git a/test_regress/t/t_tri_array.pl b/test_regress/t/t_tri_array.pl index 638ba1876..afd57d2de 100755 --- a/test_regress/t/t_tri_array.pl +++ b/test_regress/t/t_tri_array.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_array_bufif.pl b/test_regress/t/t_tri_array_bufif.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_tri_array_bufif.pl +++ b/test_regress/t/t_tri_array_bufif.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_array_pull.pl b/test_regress/t/t_tri_array_pull.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_tri_array_pull.pl +++ b/test_regress/t/t_tri_array_pull.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_compass_bad.pl b/test_regress/t/t_tri_compass_bad.pl index a0cbbba4d..da8086e04 100755 --- a/test_regress/t/t_tri_compass_bad.pl +++ b/test_regress/t/t_tri_compass_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(vlt => 1); -compile( +lint( expect_filename => $Self->{golden_filename}, fails => 1, ); diff --git a/test_regress/t/t_tri_dangle.pl b/test_regress/t/t_tri_dangle.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_tri_dangle.pl +++ b/test_regress/t/t_tri_dangle.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_eqcase.pl b/test_regress/t/t_tri_eqcase.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_tri_eqcase.pl +++ b/test_regress/t/t_tri_eqcase.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_gate_bufif0.pl b/test_regress/t/t_tri_gate_bufif0.pl index 839f4bd91..fe60c4a2d 100755 --- a/test_regress/t/t_tri_gate_bufif0.pl +++ b/test_regress/t/t_tri_gate_bufif0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_gate_bufif1.pl b/test_regress/t/t_tri_gate_bufif1.pl index 75b89c4a0..2d48b6683 100755 --- a/test_regress/t/t_tri_gate_bufif1.pl +++ b/test_regress/t/t_tri_gate_bufif1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # DESCRIPTION: Verilator: Verilog Test driver/expect definition # # Copyright 2003-2009 by Wilson Snyder. This program is free software; you diff --git a/test_regress/t/t_tri_gate_cond.pl b/test_regress/t/t_tri_gate_cond.pl index d59a475b1..9dd84b300 100755 --- a/test_regress/t/t_tri_gate_cond.pl +++ b/test_regress/t/t_tri_gate_cond.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_gate_nmos.pl b/test_regress/t/t_tri_gate_nmos.pl index d6bd9b4db..f5398c4e2 100755 --- a/test_regress/t/t_tri_gate_nmos.pl +++ b/test_regress/t/t_tri_gate_nmos.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_gate_notif0.pl b/test_regress/t/t_tri_gate_notif0.pl index a2d66b275..500b4c300 100755 --- a/test_regress/t/t_tri_gate_notif0.pl +++ b/test_regress/t/t_tri_gate_notif0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_gate_notif1.pl b/test_regress/t/t_tri_gate_notif1.pl index b7f8fb168..3d319380c 100755 --- a/test_regress/t/t_tri_gate_notif1.pl +++ b/test_regress/t/t_tri_gate_notif1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_gate_pmos.pl b/test_regress/t/t_tri_gate_pmos.pl index 02b626999..2d3352e29 100755 --- a/test_regress/t/t_tri_gate_pmos.pl +++ b/test_regress/t/t_tri_gate_pmos.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_gen.pl b/test_regress/t/t_tri_gen.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_tri_gen.pl +++ b/test_regress/t/t_tri_gen.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_graph.pl b/test_regress/t/t_tri_graph.pl index c8c83176b..079bb20a8 100755 --- a/test_regress/t/t_tri_graph.pl +++ b/test_regress/t/t_tri_graph.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_graph.v b/test_regress/t/t_tri_graph.v index 1a50d6e52..868d14c62 100644 --- a/test_regress/t/t_tri_graph.v +++ b/test_regress/t/t_tri_graph.v @@ -1,4 +1,4 @@ -// DESCRIPTION: Verilator: Unsupported tristate constructur error +// DESCRIPTION: Verilator: Unsupported tristate construct error // // This is a compile only regression test of tristate handling for bug514 // diff --git a/test_regress/t/t_tri_ifbegin.pl b/test_regress/t/t_tri_ifbegin.pl index b4e63dfda..980a2d197 100755 --- a/test_regress/t/t_tri_ifbegin.pl +++ b/test_regress/t/t_tri_ifbegin.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_inout.pl b/test_regress/t/t_tri_inout.pl index 4d136dc52..ce5a6dd80 100755 --- a/test_regress/t/t_tri_inout.pl +++ b/test_regress/t/t_tri_inout.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_inout2.pl b/test_regress/t/t_tri_inout2.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_tri_inout2.pl +++ b/test_regress/t/t_tri_inout2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_inz.pl b/test_regress/t/t_tri_inz.pl index 0f7f6d060..544de0c93 100755 --- a/test_regress/t/t_tri_inz.pl +++ b/test_regress/t/t_tri_inz.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_public.pl b/test_regress/t/t_tri_public.pl index c8c83176b..079bb20a8 100755 --- a/test_regress/t/t_tri_public.pl +++ b/test_regress/t/t_tri_public.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_public.v b/test_regress/t/t_tri_public.v index 1ab31be63..07d96be1e 100644 --- a/test_regress/t/t_tri_public.v +++ b/test_regress/t/t_tri_public.v @@ -1,4 +1,4 @@ -// DESCRIPTION: Verilator: Unsupported tristate constructur error +// DESCRIPTION: Verilator: Unsupported tristate construct error // // This is a compile only regression test of tristate handling for bug514 // diff --git a/test_regress/t/t_tri_pull01.pl b/test_regress/t/t_tri_pull01.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_tri_pull01.pl +++ b/test_regress/t/t_tri_pull01.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_pull2_bad.pl b/test_regress/t/t_tri_pull2_bad.pl index c1dba4c49..c213189c1 100755 --- a/test_regress/t/t_tri_pull2_bad.pl +++ b/test_regress/t/t_tri_pull2_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(simulator => 1); -compile( +lint( fails => $Self->{vlt_all}, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_tri_pull_bad.pl b/test_regress/t/t_tri_pull_bad.pl index c1dba4c49..c213189c1 100755 --- a/test_regress/t/t_tri_pull_bad.pl +++ b/test_regress/t/t_tri_pull_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(simulator => 1); -compile( +lint( fails => $Self->{vlt_all}, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_tri_pullup.pl b/test_regress/t/t_tri_pullup.pl index 4d136dc52..ce5a6dd80 100755 --- a/test_regress/t/t_tri_pullup.pl +++ b/test_regress/t/t_tri_pullup.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_pullvec_bad.pl b/test_regress/t/t_tri_pullvec_bad.pl index 2e7d95bc6..48bf31461 100755 --- a/test_regress/t/t_tri_pullvec_bad.pl +++ b/test_regress/t/t_tri_pullvec_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_select.pl b/test_regress/t/t_tri_select.pl index 4d136dc52..ce5a6dd80 100755 --- a/test_regress/t/t_tri_select.pl +++ b/test_regress/t/t_tri_select.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_select_unsized.pl b/test_regress/t/t_tri_select_unsized.pl index 6b3816add..11a648d2d 100755 --- a/test_regress/t/t_tri_select_unsized.pl +++ b/test_regress/t/t_tri_select_unsized.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_unconn.pl b/test_regress/t/t_tri_unconn.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_tri_unconn.pl +++ b/test_regress/t/t_tri_unconn.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_tri_various.pl b/test_regress/t/t_tri_various.pl index 6e82e9cdb..f60fd309f 100755 --- a/test_regress/t/t_tri_various.pl +++ b/test_regress/t/t_tri_various.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_type.pl b/test_regress/t/t_type.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_type.pl +++ b/test_regress/t/t_type.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_type_param.pl b/test_regress/t/t_type_param.pl index f4ca8a9d8..ec4c9a6e4 100755 --- a/test_regress/t/t_type_param.pl +++ b/test_regress/t/t_type_param.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_type_param_collision.pl b/test_regress/t/t_type_param_collision.pl index 28b538faf..247c1e80b 100755 --- a/test_regress/t/t_type_param_collision.pl +++ b/test_regress/t/t_type_param_collision.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_typedef.pl b/test_regress/t/t_typedef.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_typedef.pl +++ b/test_regress/t/t_typedef.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_typedef.v b/test_regress/t/t_typedef.v index 78f966825..8b135cc9b 100644 --- a/test_regress/t/t_typedef.v +++ b/test_regress/t/t_typedef.v @@ -8,16 +8,17 @@ program t; parameter SIZE = 5; typedef vec_t; // Forward + //UNSUP typedef vec_t; // Multi-forward is ok - typedef reg [SIZE-1:0] vec_t ; + typedef reg [SIZE-1:0] vec_t; vec_t a; initial a =0; - typedef bit [SIZE-1:0] vec_bit_t ; + typedef bit [SIZE-1:0] vec_bit_t; vec_bit_t b; initial b =0; - typedef int array [3]; - typedef array array2 [2]; - array2 ar [1]; + typedef int array_t [3]; + typedef array_t array2_t [2]; + array2_t ar [1]; // Define before use // Not sure how well supported this is elsewhere diff --git a/test_regress/t/t_typedef_array.pl b/test_regress/t/t_typedef_array.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_typedef_array.pl +++ b/test_regress/t/t_typedef_array.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_typedef_circ_bad.pl b/test_regress/t/t_typedef_circ_bad.pl index 056b9974f..59ba0d6c6 100755 --- a/test_regress/t/t_typedef_circ_bad.pl +++ b/test_regress/t/t_typedef_circ_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_typedef_package.pl b/test_regress/t/t_typedef_package.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_typedef_package.pl +++ b/test_regress/t/t_typedef_package.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_typedef_param.pl b/test_regress/t/t_typedef_param.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_typedef_param.pl +++ b/test_regress/t/t_typedef_param.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_typedef_port.pl b/test_regress/t/t_typedef_port.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_typedef_port.pl +++ b/test_regress/t/t_typedef_port.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_typedef_signed.pl b/test_regress/t/t_typedef_signed.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_typedef_signed.pl +++ b/test_regress/t/t_typedef_signed.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_typedef_unused_bad.pl b/test_regress/t/t_typedef_unused_bad.pl index 7c259dcfb..eb5a450f9 100755 --- a/test_regress/t/t_typedef_unused_bad.pl +++ b/test_regress/t/t_typedef_unused_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_typename.pl b/test_regress/t/t_typename.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_typename.pl +++ b/test_regress/t/t_typename.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_udp.out b/test_regress/t/t_udp.out new file mode 100644 index 000000000..ff1599baa --- /dev/null +++ b/test_regress/t/t_udp.out @@ -0,0 +1,4 @@ +%Error: t/t_udp.v:104:4: Unsupported: Verilog 1995 UDP Tables. Use --bbox-unsup to ignore tables. + 104 | table + | ^~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_udp.pl b/test_regress/t/t_udp.pl new file mode 100755 index 000000000..4f8c004cf --- /dev/null +++ b/test_regress/t/t_udp.pl @@ -0,0 +1,24 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(simulator => 1); + +top_filename("t/t_udp.v"); + +compile( + fails => $Self->{vlt_all}, + expect_filename => $Self->{golden_filename}, + ); + +execute( + ) if !$Self->{vlt_all}; + +ok(1); +1; diff --git a/test_regress/t/t_udp_bad.out b/test_regress/t/t_udp_bad.out index ff1599baa..f689ded39 100644 --- a/test_regress/t/t_udp_bad.out +++ b/test_regress/t/t_udp_bad.out @@ -1,4 +1,17 @@ -%Error: t/t_udp.v:104:4: Unsupported: Verilog 1995 UDP Tables. Use --bbox-unsup to ignore tables. - 104 | table - | ^~~~~ +%Warning-PINMISSING: t/t_udp_bad.v:10:10: Cell has missing pin: 'c_bad' + 10 | udp_x x (a, b); + | ^ + ... Use "/* verilator lint_off PINMISSING */" and lint_on around source to disable this message. +%Error: t/t_udp_bad.v:14:18: Pin is not an in/out/inout/interface: 'a_bad' + 14 | primitive udp_x (a_bad, b, c_bad); + | ^~~~~ +%Error: t/t_udp_bad.v:10:13: Pin not found: '__pinNumber1' + 10 | udp_x x (a, b); + | ^ +%Error: t/t_udp_bad.v:15:9: Only inputs and outputs are allowed in udp modules + 15 | tri a_bad; + | ^~~~~ +%Error: t/t_udp_bad.v:17:11: Multiple outputs not allowed in udp modules + 17 | output c_bad; + | ^~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_udp_bad.pl b/test_regress/t/t_udp_bad.pl index 90bbf23a2..fc220ea47 100755 --- a/test_regress/t/t_udp_bad.pl +++ b/test_regress/t/t_udp_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,17 +8,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -top_filename("t/t_udp.v"); - -compile( +lint( + verilator_flags2 => ["--lint-only --bbox-unsup"], fails => $Self->{vlt_all}, expect_filename => $Self->{golden_filename}, ); -execute( - ) if !$Self->{vlt_all}; - ok(1); 1; diff --git a/test_regress/t/t_udp_bad.v b/test_regress/t/t_udp_bad.v new file mode 100644 index 000000000..a17fa461d --- /dev/null +++ b/test_regress/t/t_udp_bad.v @@ -0,0 +1,23 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2009 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/); + + wire a, b; + udp_x x (a, b); + +endmodule + +primitive udp_x (a_bad, b, c_bad); + tri a_bad; + output b; + output c_bad; + table + //a b + 0 : 1; + 1 : 0; + endtable +endprimitive diff --git a/test_regress/t/t_udp_lint.pl b/test_regress/t/t_udp_lint.pl index a49bf45aa..bce98ae52 100755 --- a/test_regress/t/t_udp_lint.pl +++ b/test_regress/t/t_udp_lint.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_udp_noname.pl b/test_regress/t/t_udp_noname.pl index 1de24403a..b4e56a7d2 100755 --- a/test_regress/t/t_udp_noname.pl +++ b/test_regress/t/t_udp_noname.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unbounded.pl b/test_regress/t/t_unbounded.pl new file mode 100755 index 000000000..f60fd309f --- /dev/null +++ b/test_regress/t/t_unbounded.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003-2009 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 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_unbounded.v b/test_regress/t/t_unbounded.v new file mode 100644 index 000000000..a8b6d3bba --- /dev/null +++ b/test_regress/t/t_unbounded.v @@ -0,0 +1,23 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2014 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t(); + + localparam UNB = $; + localparam int UNB2 = $; + localparam SIX = 6; + + initial begin + if ($bits($isunbounded(0)) !== 1) $stop; + if ($isunbounded(0) !== 1'b0) $stop; + if ($isunbounded(SIX) !== 0) $stop; + if ($isunbounded($) !== 1) $stop; + if ($isunbounded(UNB) !== 1) $stop; + if ($isunbounded(UNB2) !== 1) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_unconnected.pl b/test_regress/t/t_unconnected.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_unconnected.pl +++ b/test_regress/t/t_unconnected.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unconnected_bad.pl b/test_regress/t/t_unconnected_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_unconnected_bad.pl +++ b/test_regress/t/t_unconnected_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unicode.pl b/test_regress/t/t_unicode.pl index 0dfe66ecb..5d143bbdc 100755 --- a/test_regress/t/t_unicode.pl +++ b/test_regress/t/t_unicode.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_uniqueif.pl b/test_regress/t/t_uniqueif.pl index 4c0a46a1c..59aeed76c 100755 --- a/test_regress/t/t_uniqueif.pl +++ b/test_regress/t/t_uniqueif.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_uniqueif_fail1.pl b/test_regress/t/t_uniqueif_fail1.pl index dd4176156..0b8089a46 100755 --- a/test_regress/t/t_uniqueif_fail1.pl +++ b/test_regress/t/t_uniqueif_fail1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_uniqueif_fail2.pl b/test_regress/t/t_uniqueif_fail2.pl index 7e98ebff7..0f3406ade 100755 --- a/test_regress/t/t_uniqueif_fail2.pl +++ b/test_regress/t/t_uniqueif_fail2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_uniqueif_fail3.pl b/test_regress/t/t_uniqueif_fail3.pl index 2c56473fb..eb8c557ae 100755 --- a/test_regress/t/t_uniqueif_fail3.pl +++ b/test_regress/t/t_uniqueif_fail3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_uniqueif_fail4.pl b/test_regress/t/t_uniqueif_fail4.pl index 1c5269864..6f236b834 100755 --- a/test_regress/t/t_uniqueif_fail4.pl +++ b/test_regress/t/t_uniqueif_fail4.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unopt_array.pl b/test_regress/t/t_unopt_array.pl index 703ea7959..6361d5df0 100755 --- a/test_regress/t/t_unopt_array.pl +++ b/test_regress/t/t_unopt_array.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unopt_array_csplit.pl b/test_regress/t/t_unopt_array_csplit.pl index 3022bb2d4..eae29afb9 100755 --- a/test_regress/t/t_unopt_array_csplit.pl +++ b/test_regress/t/t_unopt_array_csplit.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unopt_bound.pl b/test_regress/t/t_unopt_bound.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_unopt_bound.pl +++ b/test_regress/t/t_unopt_bound.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unopt_combo.pl b/test_regress/t/t_unopt_combo.pl index 8dff1bf03..16e6f0588 100755 --- a/test_regress/t/t_unopt_combo.pl +++ b/test_regress/t/t_unopt_combo.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unopt_combo.vlt b/test_regress/t/t_unopt_combo.vlt new file mode 100644 index 000000000..f07f4d9f5 --- /dev/null +++ b/test_regress/t/t_unopt_combo.vlt @@ -0,0 +1,3 @@ +`verilator_config + +lint_off -rule UNOPTFLAT -file "*t_unopt_combo.v" -match "Signal unoptimizable: Feedback to clock or circular logic: 't.c'" diff --git a/test_regress/t/t_unopt_combo_bad.pl b/test_regress/t/t_unopt_combo_bad.pl index c89d32b25..5590ecd32 100755 --- a/test_regress/t/t_unopt_combo_bad.pl +++ b/test_regress/t/t_unopt_combo_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unopt_combo_isolate.pl b/test_regress/t/t_unopt_combo_isolate.pl index 1791984a2..1fd8571d3 100755 --- a/test_regress/t/t_unopt_combo_isolate.pl +++ b/test_regress/t/t_unopt_combo_isolate.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unopt_combo_isolate_vlt.pl b/test_regress/t/t_unopt_combo_isolate_vlt.pl index e89062929..8010fe402 100755 --- a/test_regress/t/t_unopt_combo_isolate_vlt.pl +++ b/test_regress/t/t_unopt_combo_isolate_vlt.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unopt_combo_waive.out b/test_regress/t/t_unopt_combo_waive.out new file mode 100644 index 000000000..e69de29bb diff --git a/test_regress/t/t_unopt_combo_waive.pl b/test_regress/t/t_unopt_combo_waive.pl new file mode 100755 index 000000000..e9505bfa5 --- /dev/null +++ b/test_regress/t/t_unopt_combo_waive.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(vlt_all => 1); + +top_filename("t/t_unopt_combo.v"); + +compile( + v_flags2 => ['+define+ATTRIBUTES', "t/t_unopt_combo.vlt"], + expect_filename => $Self->{golden_filename}, # Expect no output, as we waived + ); + +ok(1); +1; diff --git a/test_regress/t/t_unopt_converge_initial_run_bad.pl b/test_regress/t/t_unopt_converge_initial_run_bad.pl index 388e31558..8825ddf1e 100755 --- a/test_regress/t/t_unopt_converge_initial_run_bad.pl +++ b/test_regress/t/t_unopt_converge_initial_run_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -13,7 +13,7 @@ scenarios(simulator => 1); top_filename("t/t_unopt_converge_initial.v"); compile( - v_flags2 => ['+define+ALLOW_UNOPT'], + v_flags2 => ['+define+ALLOW_UNOPT --output-split 0'], ); execute( diff --git a/test_regress/t/t_unopt_converge_ndbg_bad.pl b/test_regress/t/t_unopt_converge_ndbg_bad.pl index a1444cabe..929013cbc 100755 --- a/test_regress/t/t_unopt_converge_ndbg_bad.pl +++ b/test_regress/t/t_unopt_converge_ndbg_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unopt_converge_print_bad.pl b/test_regress/t/t_unopt_converge_print_bad.pl index 69982d4b5..c20b4c98f 100755 --- a/test_regress/t/t_unopt_converge_print_bad.pl +++ b/test_regress/t/t_unopt_converge_print_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -14,7 +14,7 @@ top_filename("t/t_unopt_converge.v"); #$Self->{verilated_debug} = 1; compile( - v_flags2 => ['+define+ALLOW_UNOPT'], + v_flags2 => ['+define+ALLOW_UNOPT --output-split 0'], make_flags => 'CPPFLAGS_ADD=-DVL_DEBUG', ); diff --git a/test_regress/t/t_unopt_converge_run_bad.pl b/test_regress/t/t_unopt_converge_run_bad.pl index 48b386937..ce55a1d72 100755 --- a/test_regress/t/t_unopt_converge_run_bad.pl +++ b/test_regress/t/t_unopt_converge_run_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -13,7 +13,7 @@ scenarios(simulator => 1); top_filename("t/t_unopt_converge.v"); compile( - v_flags2 => ['+define+ALLOW_UNOPT'], + v_flags2 => ['+define+ALLOW_UNOPT --output-split 0'], ); execute( diff --git a/test_regress/t/t_unopt_converge_unopt_bad.pl b/test_regress/t/t_unopt_converge_unopt_bad.pl index 7d8530609..cd6d7d7c5 100755 --- a/test_regress/t/t_unopt_converge_unopt_bad.pl +++ b/test_regress/t/t_unopt_converge_unopt_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unoptflat_simple_2_bad.pl b/test_regress/t/t_unoptflat_simple_2_bad.pl index 740fdb35c..285d1dffd 100755 --- a/test_regress/t/t_unoptflat_simple_2_bad.pl +++ b/test_regress/t/t_unoptflat_simple_2_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unoptflat_simple_3_bad.pl b/test_regress/t/t_unoptflat_simple_3_bad.pl index 69b727070..b838ad45f 100755 --- a/test_regress/t/t_unoptflat_simple_3_bad.pl +++ b/test_regress/t/t_unoptflat_simple_3_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unoptflat_simple_bad.pl b/test_regress/t/t_unoptflat_simple_bad.pl index d12e45fe3..2a9c4d934 100755 --- a/test_regress/t/t_unoptflat_simple_bad.pl +++ b/test_regress/t/t_unoptflat_simple_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unpacked_array_order.pl b/test_regress/t/t_unpacked_array_order.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_unpacked_array_order.pl +++ b/test_regress/t/t_unpacked_array_order.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unpacked_concat_bad.pl b/test_regress/t/t_unpacked_concat_bad.pl index 2365c113e..63947fd00 100755 --- a/test_regress/t/t_unpacked_concat_bad.pl +++ b/test_regress/t/t_unpacked_concat_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unpacked_slice.pl b/test_regress/t/t_unpacked_slice.pl new file mode 100755 index 000000000..b46d46042 --- /dev/null +++ b/test_regress/t/t_unpacked_slice.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_unpacked_slice.v b/test_regress/t/t_unpacked_slice.v new file mode 100644 index 000000000..ea76566d9 --- /dev/null +++ b/test_regress/t/t_unpacked_slice.v @@ -0,0 +1,57 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2020 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) + +module t (/*AUTOARG*/); + + parameter int sliceddn[7:0] = '{'h100, 'h101, 'h102, 'h103, 'h104, 'h105, 'h106, 'h107}; + parameter int slicedup[0:7] = '{'h100, 'h101, 'h102, 'h103, 'h104, 'h105, 'h106, 'h107}; + int alldn[7:0]; + int allup[0:7]; + int twodn[1:0]; + int twoup[0:1]; + + initial begin + `checkh(sliceddn[7], 'h100); + alldn[7:0] = sliceddn[7:0]; + `checkh(alldn[7], 'h100); + alldn[7:0] = sliceddn[0 +: 8]; // down: lsb/lo +: width + `checkh(alldn[7], 'h100); + alldn[7:0] = sliceddn[7 -: 8]; // down: msb/hi -: width + `checkh(alldn[7], 'h100); + twodn[1:0] = sliceddn[6:5]; + `checkh(twodn[1], 'h101); + `checkh(twodn[0], 'h102); + twodn[1:0] = sliceddn[4 +: 2]; + `checkh(twodn[1], 'h102); + `checkh(twodn[0], 'h103); + twodn[1:0] = sliceddn[4 -: 2]; + `checkh(twodn[1], 'h103); + `checkh(twodn[0], 'h104); + + `checkh(slicedup[7], 'h107); + allup[0:7] = slicedup[0:7]; + `checkh(alldn[7], 'h100); + allup[0:7] = slicedup[0 +: 8]; // up: msb/lo +: width + `checkh(alldn[7], 'h100); + allup[0:7] = slicedup[7 -: 8]; // up: lsb/hi -: width + `checkh(alldn[7], 'h100); + twoup[0:1] = slicedup[5:6]; + `checkh(twoup[1], 'h106); + `checkh(twoup[0], 'h105); + twoup[0:1] = slicedup[4 +: 2]; + `checkh(twoup[1], 'h105); + `checkh(twoup[0], 'h104); + twoup[0:1] = slicedup[4 -: 2]; + `checkh(twoup[1], 'h104); + `checkh(twoup[0], 'h103); + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_unroll_complexcond.pl b/test_regress/t/t_unroll_complexcond.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_unroll_complexcond.pl +++ b/test_regress/t/t_unroll_complexcond.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unroll_forfor.pl b/test_regress/t/t_unroll_forfor.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_unroll_forfor.pl +++ b/test_regress/t/t_unroll_forfor.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unroll_forfor.v b/test_regress/t/t_unroll_forfor.v index b43f64ecf..a37ad75eb 100644 --- a/test_regress/t/t_unroll_forfor.v +++ b/test_regress/t/t_unroll_forfor.v @@ -24,12 +24,11 @@ module t (/*AUTOARG*/ byte i, j; // bug1044 for ( i = 0; i < 9; i = i + 1 ) - for ( j=0; j<(TEST_PARAM[i*8+:8]); j=j+1 ) - begin - // verilator lint_off WIDTH - in_tmp[TEST_PARAM[i*8+:8]+j] = in[TEST_PARAM[i*8+:8]+j]; - // verilator lint_on WIDTH - end + // verilator lint_off WIDTH + for ( j=0; j<(TEST_PARAM[i*8+:8]); j=j+1) begin + in_tmp[TEST_PARAM[i*8+:8]+j] = in[TEST_PARAM[i*8+:8]+j]; + end + // verilator lint_on WIDTH $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_unroll_genf.pl b/test_regress/t/t_unroll_genf.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_unroll_genf.pl +++ b/test_regress/t/t_unroll_genf.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_unroll_signed.pl b/test_regress/t/t_unroll_signed.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_unroll_signed.pl +++ b/test_regress/t/t_unroll_signed.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vams_basic.pl b/test_regress/t/t_vams_basic.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_vams_basic.pl +++ b/test_regress/t/t_vams_basic.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vams_kwd_bad.out b/test_regress/t/t_vams_kwd_bad.out new file mode 100644 index 000000000..739550c49 --- /dev/null +++ b/test_regress/t/t_vams_kwd_bad.out @@ -0,0 +1,199 @@ +%Error: t/t_vams_kwd_bad.v:12:8: Unsupported: AMS reserved word not implemented: 'above' + 12 | int above; + | ^~~~~ +%Error: t/t_vams_kwd_bad.v:12:13: syntax error, unexpected ';', expecting IDENTIFIER + 12 | int above; + | ^ +%Error: t/t_vams_kwd_bad.v:13:8: Unsupported: AMS reserved word not implemented: 'abs' + 13 | int abs; + | ^~~ +%Error: t/t_vams_kwd_bad.v:14:8: Unsupported: AMS reserved word not implemented: 'absdelay' + 14 | int absdelay; + | ^~~~~~~~ +%Error: t/t_vams_kwd_bad.v:15:8: Unsupported: AMS reserved word not implemented: 'abstol' + 15 | int abstol; + | ^~~~~~ +%Error: t/t_vams_kwd_bad.v:16:8: Unsupported: AMS reserved word not implemented: 'ac_stim' + 16 | int ac_stim; + | ^~~~~~~ +%Error: t/t_vams_kwd_bad.v:17:8: Unsupported: AMS reserved word not implemented: 'access' + 17 | int access; + | ^~~~~~ +%Error: t/t_vams_kwd_bad.v:18:8: Unsupported: AMS reserved word not implemented: 'acos' + 18 | int acos; + | ^~~~ +%Error: t/t_vams_kwd_bad.v:19:8: Unsupported: AMS reserved word not implemented: 'acosh' + 19 | int acosh; + | ^~~~~ +%Error: t/t_vams_kwd_bad.v:20:8: Unsupported: AMS reserved word not implemented: 'aliasparam' + 20 | int aliasparam; + | ^~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:21:8: Unsupported: AMS reserved word not implemented: 'analog' + 21 | int analog; + | ^~~~~~ +%Error: t/t_vams_kwd_bad.v:22:8: Unsupported: AMS reserved word not implemented: 'analysis' + 22 | int analysis; + | ^~~~~~~~ +%Error: t/t_vams_kwd_bad.v:23:8: Unsupported: AMS reserved word not implemented: 'assert' + 23 | int assert; + | ^~~~~~ +%Error: t/t_vams_kwd_bad.v:24:8: Unsupported: AMS reserved word not implemented: 'branch' + 24 | int branch; + | ^~~~~~ +%Error: t/t_vams_kwd_bad.v:25:8: Unsupported: AMS reserved word not implemented: 'connect' + 25 | int connect; + | ^~~~~~~ +%Error: t/t_vams_kwd_bad.v:26:8: Unsupported: AMS reserved word not implemented: 'connectmodule' + 26 | int connectmodule; + | ^~~~~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:27:8: Unsupported: AMS reserved word not implemented: 'connectrules' + 27 | int connectrules; + | ^~~~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:28:8: Unsupported: AMS reserved word not implemented: 'continuous' + 28 | int continuous; + | ^~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:29:8: Unsupported: AMS reserved word not implemented: 'cross' + 29 | int cross; + | ^~~~~ +%Error: t/t_vams_kwd_bad.v:30:8: Unsupported: AMS reserved word not implemented: 'ddt' + 30 | int ddt; + | ^~~ +%Error: t/t_vams_kwd_bad.v:31:8: Unsupported: AMS reserved word not implemented: 'ddt_nature' + 31 | int ddt_nature; + | ^~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:32:8: Unsupported: AMS reserved word not implemented: 'ddx' + 32 | int ddx; + | ^~~ +%Error: t/t_vams_kwd_bad.v:33:8: Unsupported: AMS reserved word not implemented: 'discipline' + 33 | int discipline; + | ^~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:34:8: Unsupported: AMS reserved word not implemented: 'discrete' + 34 | int discrete; + | ^~~~~~~~ +%Error: t/t_vams_kwd_bad.v:35:8: Unsupported: AMS reserved word not implemented: 'domain' + 35 | int domain; + | ^~~~~~ +%Error: t/t_vams_kwd_bad.v:36:8: Unsupported: AMS reserved word not implemented: 'driver_update' + 36 | int driver_update; + | ^~~~~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:37:8: Unsupported: AMS reserved word not implemented: 'endconnectrules' + 37 | int endconnectrules; + | ^~~~~~~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:38:8: Unsupported: AMS reserved word not implemented: 'enddiscipline' + 38 | int enddiscipline; + | ^~~~~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:39:8: Unsupported: AMS reserved word not implemented: 'endnature' + 39 | int endnature; + | ^~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:40:8: Unsupported: AMS reserved word not implemented: 'endparamset' + 40 | int endparamset; + | ^~~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:41:8: Unsupported: AMS reserved word not implemented: 'exclude' + 41 | int exclude; + | ^~~~~~~ +%Error: t/t_vams_kwd_bad.v:42:8: Unsupported: AMS reserved word not implemented: 'final_step' + 42 | int final_step; + | ^~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:43:8: Unsupported: AMS reserved word not implemented: 'flicker_noise' + 43 | int flicker_noise; + | ^~~~~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:44:8: Unsupported: AMS reserved word not implemented: 'flow' + 44 | int flow; + | ^~~~ +%Error: t/t_vams_kwd_bad.v:45:8: Unsupported: AMS reserved word not implemented: 'from' + 45 | int from; + | ^~~~ +%Error: t/t_vams_kwd_bad.v:46:8: Unsupported: AMS reserved word not implemented: 'ground' + 46 | int ground; + | ^~~~~~ +%Error: t/t_vams_kwd_bad.v:47:8: Unsupported: AMS reserved word not implemented: 'idt' + 47 | int idt; + | ^~~ +%Error: t/t_vams_kwd_bad.v:48:8: Unsupported: AMS reserved word not implemented: 'idt_nature' + 48 | int idt_nature; + | ^~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:49:8: Unsupported: AMS reserved word not implemented: 'idtmod' + 49 | int idtmod; + | ^~~~~~ +%Error: t/t_vams_kwd_bad.v:50:8: Unsupported: AMS reserved word not implemented: 'inf' + 50 | int inf; + | ^~~ +%Error: t/t_vams_kwd_bad.v:51:8: Unsupported: AMS reserved word not implemented: 'initial_step' + 51 | int initial_step; + | ^~~~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:52:8: Unsupported: AMS reserved word not implemented: 'laplace_nd' + 52 | int laplace_nd; + | ^~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:53:8: Unsupported: AMS reserved word not implemented: 'laplace_np' + 53 | int laplace_np; + | ^~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:54:8: Unsupported: AMS reserved word not implemented: 'laplace_zd' + 54 | int laplace_zd; + | ^~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:55:8: Unsupported: AMS reserved word not implemented: 'laplace_zp' + 55 | int laplace_zp; + | ^~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:56:8: Unsupported: AMS reserved word not implemented: 'last_crossing' + 56 | int last_crossing; + | ^~~~~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:57:8: Unsupported: AMS reserved word not implemented: 'limexp' + 57 | int limexp; + | ^~~~~~ +%Error: t/t_vams_kwd_bad.v:58:8: Unsupported: AMS reserved word not implemented: 'max' + 58 | int max; + | ^~~ +%Error: t/t_vams_kwd_bad.v:59:8: Unsupported: AMS reserved word not implemented: 'merged' + 59 | int merged; + | ^~~~~~ +%Error: t/t_vams_kwd_bad.v:60:8: Unsupported: AMS reserved word not implemented: 'min' + 60 | int min; + | ^~~ +%Error: t/t_vams_kwd_bad.v:61:8: Unsupported: AMS reserved word not implemented: 'nature' + 61 | int nature; + | ^~~~~~ +%Error: t/t_vams_kwd_bad.v:62:8: Unsupported: AMS reserved word not implemented: 'net_resolution' + 62 | int net_resolution; + | ^~~~~~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:63:8: Unsupported: AMS reserved word not implemented: 'noise_table' + 63 | int noise_table; + | ^~~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:64:8: Unsupported: AMS reserved word not implemented: 'paramset' + 64 | int paramset; + | ^~~~~~~~ +%Error: t/t_vams_kwd_bad.v:65:8: Unsupported: AMS reserved word not implemented: 'potential' + 65 | int potential; + | ^~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:66:8: Unsupported: AMS reserved word not implemented: 'resolveto' + 66 | int resolveto; + | ^~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:67:8: Unsupported: AMS reserved word not implemented: 'slew' + 67 | int slew; + | ^~~~ +%Error: t/t_vams_kwd_bad.v:68:8: Unsupported: AMS reserved word not implemented: 'split' + 68 | int split; + | ^~~~~ +%Error: t/t_vams_kwd_bad.v:69:8: Unsupported: AMS reserved word not implemented: 'timer' + 69 | int timer; + | ^~~~~ +%Error: t/t_vams_kwd_bad.v:70:8: Unsupported: AMS reserved word not implemented: 'transition' + 70 | int transition; + | ^~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:71:8: Unsupported: AMS reserved word not implemented: 'units' + 71 | int units; + | ^~~~~ +%Error: t/t_vams_kwd_bad.v:72:8: Unsupported: AMS reserved word not implemented: 'white_noise' + 72 | int white_noise; + | ^~~~~~~~~~~ +%Error: t/t_vams_kwd_bad.v:73:8: Unsupported: AMS reserved word not implemented: 'zi_nd' + 73 | int zi_nd; + | ^~~~~ +%Error: t/t_vams_kwd_bad.v:74:8: Unsupported: AMS reserved word not implemented: 'zi_np' + 74 | int zi_np; + | ^~~~~ +%Error: t/t_vams_kwd_bad.v:75:8: Unsupported: AMS reserved word not implemented: 'zi_zd' + 75 | int zi_zd; + | ^~~~~ +%Error: t/t_vams_kwd_bad.v:76:8: Unsupported: AMS reserved word not implemented: 'zi_zp' + 76 | int zi_zp; + | ^~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_vams_kwd_bad.pl b/test_regress/t/t_vams_kwd_bad.pl new file mode 100755 index 000000000..623dba016 --- /dev/null +++ b/test_regress/t/t_vams_kwd_bad.pl @@ -0,0 +1,20 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 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 + +scenarios(vlt => 1); + +lint( + fails => 1, + verilator_flags2 => ["--error-limit 1000"], + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_vams_kwd_bad.v b/test_regress/t/t_vams_kwd_bad.v new file mode 100644 index 000000000..822d68bd8 --- /dev/null +++ b/test_regress/t/t_vams_kwd_bad.v @@ -0,0 +1,78 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2019 by Driss Hafdi. +// SPDX-License-Identifier: CC0-1.0 + +`begin_keywords "VAMS-2.3" + +module t (/*AUTOARG*/); + + // Just get errors on bad keywords (for code coverage) + int above; + int abs; + int absdelay; + int abstol; + int ac_stim; + int access; + int acos; + int acosh; + int aliasparam; + int analog; + int analysis; + int assert; + int branch; + int connect; + int connectmodule; + int connectrules; + int continuous; + int cross; + int ddt; + int ddt_nature; + int ddx; + int discipline; + int discrete; + int domain; + int driver_update; + int endconnectrules; + int enddiscipline; + int endnature; + int endparamset; + int exclude; + int final_step; + int flicker_noise; + int flow; + int from; + int ground; + int idt; + int idt_nature; + int idtmod; + int inf; + int initial_step; + int laplace_nd; + int laplace_np; + int laplace_zd; + int laplace_zp; + int last_crossing; + int limexp; + int max; + int merged; + int min; + int nature; + int net_resolution; + int noise_table; + int paramset; + int potential; + int resolveto; + int slew; + int split; + int timer; + int transition; + int units; + int white_noise; + int zi_nd; + int zi_np; + int zi_zd; + int zi_zp; + +endmodule diff --git a/test_regress/t/t_vams_wreal.pl b/test_regress/t/t_vams_wreal.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_vams_wreal.pl +++ b/test_regress/t/t_vams_wreal.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_assign_landr.pl b/test_regress/t/t_var_assign_landr.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_var_assign_landr.pl +++ b/test_regress/t/t_var_assign_landr.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_bad_hide.pl b/test_regress/t/t_var_bad_hide.pl index b76ca20f1..f1eef1686 100755 --- a/test_regress/t/t_var_bad_hide.pl +++ b/test_regress/t/t_var_bad_hide.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_bad_hide2.pl b/test_regress/t/t_var_bad_hide2.pl index 58d9f8138..fc5822886 100755 --- a/test_regress/t/t_var_bad_hide2.pl +++ b/test_regress/t/t_var_bad_hide2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_bad_sameas.pl b/test_regress/t/t_var_bad_sameas.pl index dba098eb6..a60503a1f 100755 --- a/test_regress/t/t_var_bad_sameas.pl +++ b/test_regress/t/t_var_bad_sameas.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_var_bad_sv.pl b/test_regress/t/t_var_bad_sv.pl index 056b9974f..59ba0d6c6 100755 --- a/test_regress/t/t_var_bad_sv.pl +++ b/test_regress/t/t_var_bad_sv.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_const.pl b/test_regress/t/t_var_const.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_var_const.pl +++ b/test_regress/t/t_var_const.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_const_bad.pl b/test_regress/t/t_var_const_bad.pl index fb61de158..5e419b352 100755 --- a/test_regress/t/t_var_const_bad.pl +++ b/test_regress/t/t_var_const_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_dotted1_inl0.pl b/test_regress/t/t_var_dotted1_inl0.pl index 392cbc8fd..d56ca9496 100755 --- a/test_regress/t/t_var_dotted1_inl0.pl +++ b/test_regress/t/t_var_dotted1_inl0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_dotted1_inl1.pl b/test_regress/t/t_var_dotted1_inl1.pl index a9f4d1ec1..f5992fa03 100755 --- a/test_regress/t/t_var_dotted1_inl1.pl +++ b/test_regress/t/t_var_dotted1_inl1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_dotted1_inl2.pl b/test_regress/t/t_var_dotted1_inl2.pl index 37b5ee565..7fad5e056 100755 --- a/test_regress/t/t_var_dotted1_inl2.pl +++ b/test_regress/t/t_var_dotted1_inl2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_dotted2_inl0.pl b/test_regress/t/t_var_dotted2_inl0.pl index 269dead50..dce5f07b8 100755 --- a/test_regress/t/t_var_dotted2_inl0.pl +++ b/test_regress/t/t_var_dotted2_inl0.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_dotted2_inl1.pl b/test_regress/t/t_var_dotted2_inl1.pl index be6eb9e43..b4f57957e 100755 --- a/test_regress/t/t_var_dotted2_inl1.pl +++ b/test_regress/t/t_var_dotted2_inl1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_dotted_dup_bad.pl b/test_regress/t/t_var_dotted_dup_bad.pl index 6db424386..f25e38708 100755 --- a/test_regress/t/t_var_dotted_dup_bad.pl +++ b/test_regress/t/t_var_dotted_dup_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_dup2.pl b/test_regress/t/t_var_dup2.pl index 857f82607..09b2ce4eb 100755 --- a/test_regress/t/t_var_dup2.pl +++ b/test_regress/t/t_var_dup2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_dup2_bad.pl b/test_regress/t/t_var_dup2_bad.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_var_dup2_bad.pl +++ b/test_regress/t/t_var_dup2_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_dup3.pl b/test_regress/t/t_var_dup3.pl index 857f82607..09b2ce4eb 100755 --- a/test_regress/t/t_var_dup3.pl +++ b/test_regress/t/t_var_dup3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_dup_bad.pl b/test_regress/t/t_var_dup_bad.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_var_dup_bad.pl +++ b/test_regress/t/t_var_dup_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_escape.pl b/test_regress/t/t_var_escape.pl index 8636c72ab..e8c85b61e 100755 --- a/test_regress/t/t_var_escape.pl +++ b/test_regress/t/t_var_escape.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_in_assign.pl b/test_regress/t/t_var_in_assign.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_var_in_assign.pl +++ b/test_regress/t/t_var_in_assign.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_in_assign_bad.pl b/test_regress/t/t_var_in_assign_bad.pl index 6fd21d17b..4fa14760f 100755 --- a/test_regress/t/t_var_in_assign_bad.pl +++ b/test_regress/t/t_var_in_assign_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_init.pl b/test_regress/t/t_var_init.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_var_init.pl +++ b/test_regress/t/t_var_init.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_life.pl b/test_regress/t/t_var_life.pl index 7523d760b..1c174883c 100755 --- a/test_regress/t/t_var_life.pl +++ b/test_regress/t/t_var_life.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_local.pl b/test_regress/t/t_var_local.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_var_local.pl +++ b/test_regress/t/t_var_local.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_nonamebegin.pl b/test_regress/t/t_var_nonamebegin.pl index 055e01a1a..9082e34d3 100755 --- a/test_regress/t/t_var_nonamebegin.pl +++ b/test_regress/t/t_var_nonamebegin.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_notfound_bad.pl b/test_regress/t/t_var_notfound_bad.pl index dba098eb6..a60503a1f 100755 --- a/test_regress/t/t_var_notfound_bad.pl +++ b/test_regress/t/t_var_notfound_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_var_outoforder.pl b/test_regress/t/t_var_outoforder.pl index d89c3301f..a17622844 100755 --- a/test_regress/t/t_var_outoforder.pl +++ b/test_regress/t/t_var_outoforder.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_overcmp.pl b/test_regress/t/t_var_overcmp.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_var_overcmp.pl +++ b/test_regress/t/t_var_overcmp.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_overwidth_bad.pl b/test_regress/t/t_var_overwidth_bad.pl index e51f3030a..cecc640a5 100755 --- a/test_regress/t/t_var_overwidth_bad.pl +++ b/test_regress/t/t_var_overwidth_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_overzero.pl b/test_regress/t/t_var_overzero.pl index baeeef11c..657dda6f3 100755 --- a/test_regress/t/t_var_overzero.pl +++ b/test_regress/t/t_var_overzero.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_pins_cc.pl b/test_regress/t/t_var_pins_cc.pl index 3f712d899..cdbb061e8 100755 --- a/test_regress/t/t_var_pins_cc.pl +++ b/test_regress/t/t_var_pins_cc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_pins_sc1.pl b/test_regress/t/t_var_pins_sc1.pl index 53dcc30a8..920eb8807 100755 --- a/test_regress/t/t_var_pins_sc1.pl +++ b/test_regress/t/t_var_pins_sc1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_pins_sc2.pl b/test_regress/t/t_var_pins_sc2.pl index 7bdb70b64..c37403933 100755 --- a/test_regress/t/t_var_pins_sc2.pl +++ b/test_regress/t/t_var_pins_sc2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_pins_sc32.pl b/test_regress/t/t_var_pins_sc32.pl index 7a9318e1d..ed6db0cb3 100755 --- a/test_regress/t/t_var_pins_sc32.pl +++ b/test_regress/t/t_var_pins_sc32.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_pins_sc64.pl b/test_regress/t/t_var_pins_sc64.pl index 9cc52b1ca..cedf0208e 100755 --- a/test_regress/t/t_var_pins_sc64.pl +++ b/test_regress/t/t_var_pins_sc64.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_pins_sc_biguint.pl b/test_regress/t/t_var_pins_sc_biguint.pl index 2ad896891..42b06c465 100755 --- a/test_regress/t/t_var_pins_sc_biguint.pl +++ b/test_regress/t/t_var_pins_sc_biguint.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_pins_sc_uint.pl b/test_regress/t/t_var_pins_sc_uint.pl index 318a15105..28a2513b5 100755 --- a/test_regress/t/t_var_pins_sc_uint.pl +++ b/test_regress/t/t_var_pins_sc_uint.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_pins_sc_uint_biguint.pl b/test_regress/t/t_var_pins_sc_uint_biguint.pl index ca2ee804c..363ec234c 100755 --- a/test_regress/t/t_var_pins_sc_uint_biguint.pl +++ b/test_regress/t/t_var_pins_sc_uint_biguint.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_pins_scui.pl b/test_regress/t/t_var_pins_scui.pl index ddc57d2d8..eac0b5e90 100755 --- a/test_regress/t/t_var_pins_scui.pl +++ b/test_regress/t/t_var_pins_scui.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_port2_bad.pl b/test_regress/t/t_var_port2_bad.pl index 9112f3486..a60503a1f 100755 --- a/test_regress/t/t_var_port2_bad.pl +++ b/test_regress/t/t_var_port2_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_var_port_bad.pl b/test_regress/t/t_var_port_bad.pl index 9112f3486..a60503a1f 100755 --- a/test_regress/t/t_var_port_bad.pl +++ b/test_regress/t/t_var_port_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(linter => 1); -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_var_ref.pl b/test_regress/t/t_var_ref.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_var_ref.pl +++ b/test_regress/t/t_var_ref.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_ref_bad1.pl b/test_regress/t/t_var_ref_bad1.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_var_ref_bad1.pl +++ b/test_regress/t/t_var_ref_bad1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_ref_bad2.pl b/test_regress/t/t_var_ref_bad2.pl index 67a7abcb0..a60503a1f 100755 --- a/test_regress/t/t_var_ref_bad2.pl +++ b/test_regress/t/t_var_ref_bad2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_ref_bad3.pl b/test_regress/t/t_var_ref_bad3.pl index ac387c7d9..a5846c699 100755 --- a/test_regress/t/t_var_ref_bad3.pl +++ b/test_regress/t/t_var_ref_bad3.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_ref_noinline.pl b/test_regress/t/t_var_ref_noinline.pl index 06315e8c9..9ba333659 100755 --- a/test_regress/t/t_var_ref_noinline.pl +++ b/test_regress/t/t_var_ref_noinline.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_rsvd.pl b/test_regress/t/t_var_rsvd.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_var_rsvd.pl +++ b/test_regress/t/t_var_rsvd.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_rsvd_bad.pl b/test_regress/t/t_var_rsvd_bad.pl index 0e4c147b8..a034e8fa8 100755 --- a/test_regress/t/t_var_rsvd_bad.pl +++ b/test_regress/t/t_var_rsvd_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,11 +8,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); top_filename("t/t_var_rsvd_port.v"); -compile( +lint( fails => $Self->{vlt_all}, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_var_rsvd_port.pl b/test_regress/t/t_var_rsvd_port.pl index ff17d510c..de2083cc5 100755 --- a/test_regress/t/t_var_rsvd_port.pl +++ b/test_regress/t/t_var_rsvd_port.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_set_link.pl b/test_regress/t/t_var_set_link.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_var_set_link.pl +++ b/test_regress/t/t_var_set_link.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_static.pl b/test_regress/t/t_var_static.pl index 1676c3883..1befb2521 100755 --- a/test_regress/t/t_var_static.pl +++ b/test_regress/t/t_var_static.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_suggest_bad.pl b/test_regress/t/t_var_suggest_bad.pl index 056b9974f..59ba0d6c6 100755 --- a/test_regress/t/t_var_suggest_bad.pl +++ b/test_regress/t/t_var_suggest_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_tieout.pl b/test_regress/t/t_var_tieout.pl index 1d046ed3f..b46d46042 100755 --- a/test_regress/t/t_var_tieout.pl +++ b/test_regress/t/t_var_tieout.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_types.pl b/test_regress/t/t_var_types.pl index 3a8a4d160..174d78f53 100755 --- a/test_regress/t/t_var_types.pl +++ b/test_regress/t/t_var_types.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_types_bad.pl b/test_regress/t/t_var_types_bad.pl index ef023b9fc..d2715e7c7 100755 --- a/test_regress/t/t_var_types_bad.pl +++ b/test_regress/t/t_var_types_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,11 +8,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(linter => 1); $Self->{verilated_randReset} = 1; # allow checking if we initialize vars to zero only when needed -compile( +lint( fails => 1, expect_filename => $Self->{golden_filename}, ); diff --git a/test_regress/t/t_var_vec_sel.pl b/test_regress/t/t_var_vec_sel.pl index a4d74c0ba..13c6e2b71 100755 --- a/test_regress/t/t_var_vec_sel.pl +++ b/test_regress/t/t_var_vec_sel.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_var_xref_gen.pl b/test_regress/t/t_var_xref_gen.pl index f126bab59..873cde7f6 100755 --- a/test_regress/t/t_var_xref_gen.pl +++ b/test_regress/t/t_var_xref_gen.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_verilated_all.pl b/test_regress/t/t_verilated_all.pl index 0bd51a322..1d8370346 100755 --- a/test_regress/t/t_verilated_all.pl +++ b/test_regress/t/t_verilated_all.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_verilated_all_newest.pl b/test_regress/t/t_verilated_all_newest.pl index 702f6cf07..1df755ae6 100755 --- a/test_regress/t/t_verilated_all_newest.pl +++ b/test_regress/t/t_verilated_all_newest.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_verilated_all_oldest.pl b/test_regress/t/t_verilated_all_oldest.pl index 11fa3349c..db800f7b0 100755 --- a/test_regress/t/t_verilated_all_oldest.pl +++ b/test_regress/t/t_verilated_all_oldest.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_verilated_debug.out b/test_regress/t/t_verilated_debug.out index f1bcca561..f4bc23936 100644 --- a/test_regress/t/t_verilated_debug.out +++ b/test_regress/t/t_verilated_debug.out @@ -11,9 +11,11 @@ internalsDump: -V{t#,#}+ Vt_verilated_debug::_eval_settle -V{t#,#}+ Vt_verilated_debug::_eval -V{t#,#}+ Vt_verilated_debug::_change_request +-V{t#,#}+ Vt_verilated_debug::_change_request_1 -V{t#,#}+ Clock loop -V{t#,#}+ Vt_verilated_debug::_eval -V{t#,#}+ Vt_verilated_debug::_change_request +-V{t#,#}+ Vt_verilated_debug::_change_request_1 -V{t#,#}+++++TOP Evaluate Vt_verilated_debug::eval -V{t#,#}+ Vt_verilated_debug::_eval_debug_assertions -V{t#,#}+ Clock loop @@ -21,4 +23,5 @@ internalsDump: -V{t#,#}+ Vt_verilated_debug::_sequent__TOP__1 *-* All Finished *-* -V{t#,#}+ Vt_verilated_debug::_change_request +-V{t#,#}+ Vt_verilated_debug::_change_request_1 -V{t#,#}+ Vt_verilated_debug::final diff --git a/test_regress/t/t_verilated_debug.pl b/test_regress/t/t_verilated_debug.pl index 08d810c99..04964e29f 100755 --- a/test_regress/t/t_verilated_debug.pl +++ b/test_regress/t/t_verilated_debug.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_verilated_threaded.pl b/test_regress/t/t_verilated_threaded.pl index 5f8920700..ec8edeb50 100755 --- a/test_regress/t/t_verilated_threaded.pl +++ b/test_regress/t/t_verilated_threaded.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vgen.pl b/test_regress/t/t_vgen.pl index 8c25ac412..a488b5a3f 100755 --- a/test_regress/t/t_vgen.pl +++ b/test_regress/t/t_vgen.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vlcov_debugi.pl b/test_regress/t/t_vlcov_debugi.pl index 5517958e8..8cc5f0d57 100755 --- a/test_regress/t/t_vlcov_debugi.pl +++ b/test_regress/t/t_vlcov_debugi.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -20,6 +20,7 @@ foreach my $basename ("t_vlcov_data_a.dat", "--debugi 9", ], tee => $Self->{verbose}, + verilator_run => 1, ); } diff --git a/test_regress/t/t_vlcov_flag_invalid_bad.out b/test_regress/t/t_vlcov_flag_invalid_bad.out new file mode 100644 index 000000000..54d2f3d73 --- /dev/null +++ b/test_regress/t/t_vlcov_flag_invalid_bad.out @@ -0,0 +1 @@ +%Error: Invalid option: --invalid-dash diff --git a/test_regress/t/t_vlcov_flag_invalid_bad.pl b/test_regress/t/t_vlcov_flag_invalid_bad.pl new file mode 100755 index 000000000..c89584f1b --- /dev/null +++ b/test_regress/t/t_vlcov_flag_invalid_bad.pl @@ -0,0 +1,22 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(vlt => 1); + +run(cmd => ["../bin/verilator_coverage", '--invalid-dash'], + logfile => $Self->{run_log_filename}, + fails => 1, + expect_filename => $Self->{golden_filename}, + verilator_run => 1, + ); + +ok(1); + +1; diff --git a/test_regress/t/t_vlcov_info.out b/test_regress/t/t_vlcov_info.out new file mode 100644 index 000000000..40b3c320b --- /dev/null +++ b/test_regress/t/t_vlcov_info.out @@ -0,0 +1,4 @@ +TN:verilator_coverage +SF:file1.sp +DA:159,53 +end_of_record diff --git a/test_regress/t/t_vlcov_info.pl b/test_regress/t/t_vlcov_info.pl new file mode 100755 index 000000000..ee4467fc2 --- /dev/null +++ b/test_regress/t/t_vlcov_info.pl @@ -0,0 +1,26 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003-2009 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 + +scenarios(dist => 1); + +run(cmd => ["../bin/verilator_coverage", + "--write-info", "$Self->{obj_dir}/coverage.info", + "t/t_vlcov_data_a.dat", + "t/t_vlcov_data_b.dat", + "t/t_vlcov_data_c.dat", + "t/t_vlcov_data_d.dat", + ], + verilator_run => 1, + ); + +files_identical("$Self->{obj_dir}/coverage.info", $Self->{golden_filename}); + +ok(1); +1; diff --git a/test_regress/t/t_vlcov_merge.pl b/test_regress/t/t_vlcov_merge.pl index 3437bfdb1..cfac15b48 100755 --- a/test_regress/t/t_vlcov_merge.pl +++ b/test_regress/t/t_vlcov_merge.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -16,19 +16,13 @@ run(cmd => ["../bin/verilator_coverage", "t/t_vlcov_data_b.dat", "t/t_vlcov_data_c.dat", "t/t_vlcov_data_d.dat", - ]); + ], + verilator_run => 1, + ); # Older clib's didn't properly sort maps, but the coverage data doesn't # really care about ordering. So avoid false failures by sorting. -# Set LC_ALL as suggested in the sort manpage to avoid sort order -# changes from the locale. -$ENV{LC_ALL} = "C"; -run(cmd => ["sort", - "$Self->{obj_dir}/coverage.dat", - "> $Self->{obj_dir}/coverage-sort.dat", - ]); - -files_identical("$Self->{obj_dir}/coverage-sort.dat", $Self->{golden_filename}); +files_identical_sorted("$Self->{obj_dir}/coverage.dat", $Self->{golden_filename}); ok(1); 1; diff --git a/test_regress/t/t_vlcov_nfound_bad.pl b/test_regress/t/t_vlcov_nfound_bad.pl index 35e66208a..e38aabd39 100755 --- a/test_regress/t/t_vlcov_nfound_bad.pl +++ b/test_regress/t/t_vlcov_nfound_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -15,6 +15,7 @@ run(fails => 1, "t/t_NOT_FOUND",], logfile => $Self->{run_log_filename}, expect_filename => $Self->{golden_filename}, + verilator_run => 1, ); ok(1); diff --git a/test_regress/t/t_vlcov_rank.pl b/test_regress/t/t_vlcov_rank.pl index 2d8d806f7..ca5917c16 100755 --- a/test_regress/t/t_vlcov_rank.pl +++ b/test_regress/t/t_vlcov_rank.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -19,6 +19,7 @@ run(cmd => ["../bin/verilator_coverage", ], logfile => "$Self->{obj_dir}/vlcov.log", tee => 0, + verilator_run => 1, ); files_identical("$Self->{obj_dir}/vlcov.log", $Self->{golden_filename}); diff --git a/test_regress/t/t_vlcov_rewrite.pl b/test_regress/t/t_vlcov_rewrite.pl index 81634291e..6611d4e00 100755 --- a/test_regress/t/t_vlcov_rewrite.pl +++ b/test_regress/t/t_vlcov_rewrite.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -20,6 +20,7 @@ foreach my $basename ("t_vlcov_data_a.dat", "--write", "$Self->{obj_dir}/${basename}" ], tee => 0, + verilator_run => 1, ); files_identical("$Self->{obj_dir}/${basename}", "t/${basename}"); } diff --git a/test_regress/t/t_vlt_syntax_bad.pl b/test_regress/t/t_vlt_syntax_bad.pl index 80bf52112..5d79360fb 100755 --- a/test_regress/t/t_vlt_syntax_bad.pl +++ b/test_regress/t/t_vlt_syntax_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -8,9 +8,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(vlt_all => 1); +scenarios(vlt => 1); -compile( +lint( verilator_flags2 => ["t/t_vlt_syntax_bad.vlt"], fails => 1, expect_filename => $Self->{golden_filename}, diff --git a/test_regress/t/t_vlt_warn.pl b/test_regress/t/t_vlt_warn.pl index d1ec9e8ed..9d2a06917 100755 --- a/test_regress/t/t_vlt_warn.pl +++ b/test_regress/t/t_vlt_warn.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vlt_warn_bad.pl b/test_regress/t/t_vlt_warn_bad.pl index 2fea6cef3..43047c39e 100755 --- a/test_regress/t/t_vlt_warn_bad.pl +++ b/test_regress/t/t_vlt_warn_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vpi_finish.pl b/test_regress/t/t_vpi_finish.pl new file mode 100755 index 000000000..050052f66 --- /dev/null +++ b/test_regress/t/t_vpi_finish.pl @@ -0,0 +1,23 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(simulator => 1); + +compile( + v_flags2 => ["--vpi t/t_vpi_finish_c.cpp"], + ); + +execute( + check_finished => 1, + ); + +ok(1); + +1; diff --git a/test_regress/t/t_vpi_finish.v b/test_regress/t/t_vpi_finish.v new file mode 100644 index 000000000..4b211d63c --- /dev/null +++ b/test_regress/t/t_vpi_finish.v @@ -0,0 +1,17 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2020 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 + +module t (/*AUTOARG*/); + + import "DPI-C" function void dpii_test(); + + initial begin + $write("*-* All Finished *-*\n"); + dpii_test(); // $finish + end +endmodule diff --git a/test_regress/t/t_vpi_finish_c.cpp b/test_regress/t/t_vpi_finish_c.cpp new file mode 100644 index 000000000..14f1e056d --- /dev/null +++ b/test_regress/t/t_vpi_finish_c.cpp @@ -0,0 +1,27 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2009-2009 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 +// +//************************************************************************* + +#include +#include +#include "svdpi.h" +#include "vpi_user.h" + +//====================================================================== + +extern "C" { + extern void dpii_test(); +} + +//====================================================================== + +void dpii_test() { + vpi_control(vpiFinish); +} diff --git a/test_regress/t/t_vpi_get.pl b/test_regress/t/t_vpi_get.pl index 93f8dbb0c..dc126dc16 100755 --- a/test_regress/t/t_vpi_get.pl +++ b/test_regress/t/t_vpi_get.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vpi_get_public_rw_switch.pl b/test_regress/t/t_vpi_get_public_rw_switch.pl index 8228d7585..8c11341ac 100755 --- a/test_regress/t/t_vpi_get_public_rw_switch.pl +++ b/test_regress/t/t_vpi_get_public_rw_switch.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vpi_memory.cpp b/test_regress/t/t_vpi_memory.cpp index 5b229b78b..1f8882a4d 100644 --- a/test_regress/t/t_vpi_memory.cpp +++ b/test_regress/t/t_vpi_memory.cpp @@ -87,9 +87,6 @@ int _mon_check_range(TestVpiHandle& handle, int size, int left, int right) { // check size of object int vpisize = vpi_get(vpiSize, handle); CHECK_RESULT(vpisize, size); - // check size of range - vpisize = vpi_get(vpiSize, handle); - CHECK_RESULT(vpisize, size); // check left hand side of range left_h = vpi_handle(vpiLeftRange, handle); CHECK_RESULT_NZ(left_h); @@ -110,7 +107,7 @@ int _mon_check_range(TestVpiHandle& handle, int size, int left, int right) { int _mon_check_memory() { int cnt; - TestVpiHandle mem_h, lcl_h; + TestVpiHandle mem_h, lcl_h, side_h; vpiHandle iter_h; // Icarus does not like auto free of iterator handles s_vpi_value value = {.format = vpiIntVal, .value = {.integer = 0}}; vpi_printf((PLI_BYTE8*)"Check memory vpi ...\n"); @@ -158,6 +155,21 @@ int _mon_check_memory() { CHECK_RESULT(should_be_NULL, 0); should_be_NULL = vpi_handle(vpiScope, iter_h); CHECK_RESULT(should_be_NULL, 0); + + // check vpiRange + iter_h = vpi_iterate(vpiRange, mem_h); + CHECK_RESULT_NZ(iter_h); + lcl_h = vpi_scan(iter_h); + CHECK_RESULT_NZ(lcl_h); + side_h = vpi_handle(vpiLeftRange, lcl_h); + CHECK_RESULT_NZ(side_h); + vpi_get_value(side_h, &value); + CHECK_RESULT(value.value.integer, 16); + side_h = vpi_handle(vpiRightRange, lcl_h); + CHECK_RESULT_NZ(side_h); + vpi_get_value(side_h, &value); + CHECK_RESULT(value.value.integer, 1); + return 0; // Ok } diff --git a/test_regress/t/t_vpi_memory.pl b/test_regress/t/t_vpi_memory.pl index 1a6da9c4a..c01c0b9ed 100755 --- a/test_regress/t/t_vpi_memory.pl +++ b/test_regress/t/t_vpi_memory.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vpi_module.pl b/test_regress/t/t_vpi_module.pl index 2e99e1a83..69d086d90 100755 --- a/test_regress/t/t_vpi_module.pl +++ b/test_regress/t/t_vpi_module.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vpi_sc.pl b/test_regress/t/t_vpi_sc.pl index 730065a65..b4f453e63 100755 --- a/test_regress/t/t_vpi_sc.pl +++ b/test_regress/t/t_vpi_sc.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vpi_stop_bad.out b/test_regress/t/t_vpi_stop_bad.out new file mode 100644 index 000000000..4c93b7cd7 --- /dev/null +++ b/test_regress/t/t_vpi_stop_bad.out @@ -0,0 +1,2 @@ +%Error: Verilog $stop +Aborting... diff --git a/test_regress/t/t_vpi_stop_bad.pl b/test_regress/t/t_vpi_stop_bad.pl new file mode 100755 index 000000000..89f7e8b16 --- /dev/null +++ b/test_regress/t/t_vpi_stop_bad.pl @@ -0,0 +1,25 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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 + +scenarios(simulator => 1); + +compile( + v_flags2 => ["--vpi t/t_vpi_stop_bad_c.cpp"], + ); + +execute( + fails => 1, + check_finished => 0, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); + +1; diff --git a/test_regress/t/t_vpi_stop_bad.v b/test_regress/t/t_vpi_stop_bad.v new file mode 100644 index 000000000..655f52880 --- /dev/null +++ b/test_regress/t/t_vpi_stop_bad.v @@ -0,0 +1,19 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2020 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 + +module t (/*AUTOARG*/); + + import "DPI-C" function void dpii_test(); + + initial begin + dpii_test(); + $display("Should have stopped above"); + //$write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_vpi_stop_bad_c.cpp b/test_regress/t/t_vpi_stop_bad_c.cpp new file mode 100644 index 000000000..40f9982d6 --- /dev/null +++ b/test_regress/t/t_vpi_stop_bad_c.cpp @@ -0,0 +1,27 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2009-2009 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 +// +//************************************************************************* + +#include +#include +#include "svdpi.h" +#include "vpi_user.h" + +//====================================================================== + +extern "C" { + extern void dpii_test(); +} + +//====================================================================== + +void dpii_test() { + vpi_control(vpiStop); +} diff --git a/test_regress/t/t_vpi_time_cb.pl b/test_regress/t/t_vpi_time_cb.pl index 512dbb1b7..0f61b3e1c 100755 --- a/test_regress/t/t_vpi_time_cb.pl +++ b/test_regress/t/t_vpi_time_cb.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vpi_unimpl.cpp b/test_regress/t/t_vpi_unimpl.cpp index dd9eb9fad..63ce3f507 100644 --- a/test_regress/t/t_vpi_unimpl.cpp +++ b/test_regress/t/t_vpi_unimpl.cpp @@ -71,6 +71,7 @@ unsigned int callback_count = 0; int _mon_check_unimpl(p_cb_data cb_data) { static TestVpiHandle cb, clk_h; + vpiHandle handle; if (cb_data) { // this is the callback s_vpi_error_info info; @@ -123,6 +124,33 @@ int _mon_check_unimpl(p_cb_data cb_data) { CHECK_RESULT(callback_count, 16); vpi_handle_by_multi_index(NULL, 0, NULL); CHECK_RESULT(callback_count, 17); + vpi_control(0); + CHECK_RESULT(callback_count, 18); + + s_vpi_time time_s; + time_s.type = 0; + vpi_get_time(NULL, &time_s); + CHECK_RESULT(callback_count, 19); + + handle = vpi_put_value(NULL, NULL, NULL, 0); + CHECK_RESULT(callback_count, 20); + CHECK_RESULT(handle, 0); + + handle = vpi_handle(0, NULL); + CHECK_RESULT(callback_count, 21); + CHECK_RESULT(handle, 0); + + vpi_iterate(0, NULL); + CHECK_RESULT(callback_count, 22); + + handle = vpi_register_cb(NULL); + CHECK_RESULT(callback_count, 23); + CHECK_RESULT(handle, 0); + s_cb_data cb_data_s; + cb_data_s.reason = 0; // Bad + handle = vpi_register_cb(&cb_data_s); + CHECK_RESULT(callback_count, 24); + CHECK_RESULT(handle, 0); } return 0; // Ok } @@ -173,7 +201,9 @@ int main(int argc, char** argv, char** env) { if (tfp) tfp->dump(main_time); #endif } - CHECK_RESULT(callback_count, 17); + if (!callback_count) { + vl_fatal(FILENM, __LINE__, "main", "%Error: never got callbacks"); + } if (!Verilated::gotFinish()) { vl_fatal(FILENM, __LINE__, "main", "%Error: Timeout; never got a $finish"); } diff --git a/test_regress/t/t_vpi_unimpl.pl b/test_regress/t/t_vpi_unimpl.pl index 5160957d8..dce3e4aae 100755 --- a/test_regress/t/t_vpi_unimpl.pl +++ b/test_regress/t/t_vpi_unimpl.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index 739cfd235..d268261ae 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -273,7 +273,7 @@ int _mon_check_var() { vpi_get_value(vh10, &tmpValue); CHECK_RESULT(tmpValue.value.integer, 4); p = vpi_get_str(vpiType, vh10); - CHECK_RESULT_CSTR(p, "*undefined*"); + CHECK_RESULT_CSTR(p, "vpiConstant"); } { TestVpiHandle vh10 = vpi_handle(vpiRightRange, vh4); @@ -281,7 +281,7 @@ int _mon_check_var() { vpi_get_value(vh10, &tmpValue); CHECK_RESULT(tmpValue.value.integer, 3); p = vpi_get_str(vpiType, vh10); - CHECK_RESULT_CSTR(p, "*undefined*"); + CHECK_RESULT_CSTR(p, "vpiConstant"); } { TestVpiHandle vh10 = vpi_iterate(vpiMemoryWord, vh4); @@ -297,13 +297,13 @@ int _mon_check_var() { vpi_get_value(vh12, &tmpValue); CHECK_RESULT(tmpValue.value.integer, 2); p = vpi_get_str(vpiType, vh12); - CHECK_RESULT_CSTR(p, "*undefined*"); + CHECK_RESULT_CSTR(p, "vpiConstant"); TestVpiHandle vh13 = vpi_handle(vpiRightRange, vh11); CHECK_RESULT_NZ(vh13); vpi_get_value(vh13, &tmpValue); CHECK_RESULT(tmpValue.value.integer, 1); p = vpi_get_str(vpiType, vh13); - CHECK_RESULT_CSTR(p, "*undefined*"); + CHECK_RESULT_CSTR(p, "vpiConstant"); } return 0; diff --git a/test_regress/t/t_vpi_var.pl b/test_regress/t/t_vpi_var.pl index c21977991..57c6f6cb7 100755 --- a/test_regress/t/t_vpi_var.pl +++ b/test_regress/t/t_vpi_var.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_vpi_zero_time_cb.pl b/test_regress/t/t_vpi_zero_time_cb.pl index 717592491..767fd64a2 100755 --- a/test_regress/t/t_vpi_zero_time_cb.pl +++ b/test_regress/t/t_vpi_zero_time_cb.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_waiveroutput.out b/test_regress/t/t_waiveroutput.out new file mode 100644 index 000000000..01132a95d --- /dev/null +++ b/test_regress/t/t_waiveroutput.out @@ -0,0 +1,13 @@ +// DESCRIPTION: Verilator output: Waivers generated with --waiver-output + +`verilator_config + +// Below you find suggested waivers. You have three options: +// 1. Fix the reason for the linter warning +// 2. Keep the waiver permanently if you are sure this is okay +// 3. Keep the waiver temporarily to suppress the output + +// lint_off -rule WIDTH -file "*t/t_waiveroutput.v" -match "Operator ASSIGN expects 1 bits on the Assign RHS, but Assign RHS's CONST '2'h3' generates 2 bits." + +// lint_off -rule UNUSED -file "*t/t_waiveroutput.v" -match "Signal is not used: 'width_warn'" + diff --git a/test_regress/t/t_waiveroutput.pl b/test_regress/t/t_waiveroutput.pl new file mode 100755 index 000000000..08f77ed08 --- /dev/null +++ b/test_regress/t/t_waiveroutput.pl @@ -0,0 +1,30 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2012 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 + +scenarios(vlt => 1); + +my $out_filename = "$Self->{obj_dir}/$Self->{name}_waiver_gen.vlt"; +my $waiver_filename = "$Self->{obj_dir}/$Self->{name}_waiver.vlt"; + +compile( + v_flags2 => ['--waiver-output', $out_filename], + fails => 1, + ); + +files_identical("$out_filename", $Self->{golden_filename}); + +run(cmd=>["sed 's/\\/\\/ lint_off/lint_off/g' $out_filename > $waiver_filename"]); + +compile( + v_flags2 => [$waiver_filename], + ); + +ok(1); +1; diff --git a/test_regress/t/t_waiveroutput.v b/test_regress/t/t_waiveroutput.v new file mode 100644 index 000000000..c84e9dec4 --- /dev/null +++ b/test_regress/t/t_waiveroutput.v @@ -0,0 +1,10 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2012 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t_waiveroutput; + + reg width_warn = 2'b11; // Width warning - must be line 18 +endmodule diff --git a/test_regress/t/t_waiveroutput_allgood.out b/test_regress/t/t_waiveroutput_allgood.out new file mode 100644 index 000000000..673c0445a --- /dev/null +++ b/test_regress/t/t_waiveroutput_allgood.out @@ -0,0 +1,10 @@ +// DESCRIPTION: Verilator output: Waivers generated with --waiver-output + +`verilator_config + +// Below you find suggested waivers. You have three options: +// 1. Fix the reason for the linter warning +// 2. Keep the waiver permanently if you are sure this is okay +// 3. Keep the waiver temporarily to suppress the output + +// No waivers needed - great! diff --git a/test_regress/t/t_waiveroutput_allgood.pl b/test_regress/t/t_waiveroutput_allgood.pl new file mode 100755 index 000000000..8a1846a0d --- /dev/null +++ b/test_regress/t/t_waiveroutput_allgood.pl @@ -0,0 +1,25 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2012 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 + +scenarios(vlt => 1); + +my $out_filename = "$Self->{obj_dir}/$Self->{name}_waiver_gen.vlt"; +my $waiver_filename = "t/$Self->{name}.vlt"; + +top_filename("t/t_waiveroutput.v"); + +compile( + v_flags2 => [$waiver_filename, '--waiver-output', $out_filename], + ); + +files_identical("$out_filename", $Self->{golden_filename}); + +ok(1); +1; diff --git a/test_regress/t/t_waiveroutput_allgood.vlt b/test_regress/t/t_waiveroutput_allgood.vlt new file mode 100644 index 000000000..2f6af4e29 --- /dev/null +++ b/test_regress/t/t_waiveroutput_allgood.vlt @@ -0,0 +1,12 @@ +// DESCRIPTION: Verilator output: Waivers generated with --waiver-output + +`verilator_config + +// Below you find suggested waivers. You have three options: +// 1. Fix the reason for the linter warning +// 2. Keep the waiver permanently if you are sure this is okay +// 3. Keep the waiver temporarily to suppress the output + +lint_off -rule WIDTH -file "*t/t_waiveroutput.v" -match "Operator ASSIGN expects 1 bits on the Assign RHS, but Assign RHS's CONST '2'h3' generates 2 bits." + +lint_off -rule UNUSED -file "*t/t_waiveroutput.v" -match "Signal is not used: 'width_warn'" diff --git a/test_regress/t/t_wire_beh1364_bad.pl b/test_regress/t/t_wire_beh1364_bad.pl index 0c056a285..ee98f2262 100755 --- a/test_regress/t/t_wire_beh1364_bad.pl +++ b/test_regress/t/t_wire_beh1364_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # @@ -10,11 +10,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(vlt => 1); +my $waiver_filename = "$Self->{obj_dir}/$Self->{name}_waiver.vlt"; + lint( - verilator_flags2 => ["--lint-only --language 1364-2001"], + verilator_flags2 => ["--lint-only --language 1364-2001 --waiver-output ${waiver_filename}"], fails => 1, expect_filename => $Self->{golden_filename}, ); +if (-e $waiver_filename) { + error("Waiver file generated, not expected.."); +} + ok(1); 1; diff --git a/test_regress/t/t_wire_beh1800_bad.pl b/test_regress/t/t_wire_beh1800_bad.pl index 8bf670e39..85114ac5d 100755 --- a/test_regress/t/t_wire_beh1800_bad.pl +++ b/test_regress/t/t_wire_beh1800_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_wire_behp1364_bad.pl b/test_regress/t/t_wire_behp1364_bad.pl index 0c056a285..77f34c903 100755 --- a/test_regress/t/t_wire_behp1364_bad.pl +++ b/test_regress/t/t_wire_behp1364_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_wire_behp1800_bad.pl b/test_regress/t/t_wire_behp1800_bad.pl index 8bf670e39..85114ac5d 100755 --- a/test_regress/t/t_wire_behp1800_bad.pl +++ b/test_regress/t/t_wire_behp1800_bad.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_wire_types.pl b/test_regress/t/t_wire_types.pl index 3a8a4d160..174d78f53 100755 --- a/test_regress/t/t_wire_types.pl +++ b/test_regress/t/t_wire_types.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_xml_first.pl b/test_regress/t/t_xml_first.pl index 8a75bfd1e..cd9490294 100755 --- a/test_regress/t/t_xml_first.pl +++ b/test_regress/t/t_xml_first.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_xml_flat.pl b/test_regress/t/t_xml_flat.pl index f8062ce2d..dd19fee39 100755 --- a/test_regress/t/t_xml_flat.pl +++ b/test_regress/t/t_xml_flat.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_xml_output.pl b/test_regress/t/t_xml_output.pl index 1c0df5f82..f6126c66f 100755 --- a/test_regress/t/t_xml_output.pl +++ b/test_regress/t/t_xml_output.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/test_regress/t/t_xml_tag.pl b/test_regress/t/t_xml_tag.pl index 8a75bfd1e..cd9490294 100755 --- a/test_regress/t/t_xml_tag.pl +++ b/test_regress/t/t_xml_tag.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } # DESCRIPTION: Verilator: Verilog Test driver/expect definition # diff --git a/verilator-config.cmake.in b/verilator-config.cmake.in index 50edfdcd9..b13b32301 100644 --- a/verilator-config.cmake.in +++ b/verilator-config.cmake.in @@ -116,7 +116,7 @@ define_property(TARGET function(verilate TARGET) cmake_parse_arguments(VERILATE "COVERAGE;TRACE;TRACE_FST;SYSTEMC" "PREFIX;TOP_MODULE;THREADS;DIRECTORY" - "SOURCES;VERILATOR_ARGS;INCLUDE_DIRS;OPT_SLOW;OPT_FAST" + "SOURCES;VERILATOR_ARGS;INCLUDE_DIRS;OPT_SLOW;OPT_FAST;OPT_GLOBAL" ${ARGN}) if (NOT VERILATE_SOURCES) message(FATAL_ERROR "Need at least one source") @@ -290,6 +290,11 @@ function(verilate TARGET) set_property(SOURCE "${VFAST}" APPEND_STRING PROPERTY COMPILE_FLAGS " ${OPT_FAST}") endforeach() endforeach() + foreach(VGLOBAL ${${VERILATE_PREFIX}_GLOBAL}) + foreach(OPT_GLOBAL ${VERILATE_OPT_GLOBAL} ${${VERILATE_PREFIX}_USER_CFLAGS}) + set_property(SOURCE "${VGLOBAL}" APPEND_STRING PROPERTY COMPILE_FLAGS " ${OPT_GLOBAL}") + endforeach() + endforeach() target_include_directories(${TARGET} PUBLIC "${VERILATOR_ROOT}/include" "${VERILATOR_ROOT}/include/vltstd") diff --git a/verilator.pc.in b/verilator.pc.in index 6191d3577..ed8b58d3a 100644 --- a/verilator.pc.in +++ b/verilator.pc.in @@ -7,7 +7,7 @@ includedir=@pkgdatadir@/include Name: verilator Description: fast free Verilog simulator URL: https://verilator.org -Version: @PACKAGE_VERSION@ +Version: @PACKAGE_VERSION_NUMBER@ Requires: Libs: Cflags: -I${includedir} -I${includedir}/vltstd