mirror of
https://github.com/verilator/verilator.git
synced 2026-10-04 17:13:40 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c5314b39c | ||
|
|
e76f29e5ba | ||
|
|
5a83209b9b | ||
|
|
4655ee014b | ||
|
|
12f0017d4a | ||
|
|
ca3b5fbe99 | ||
|
|
9de6612cde | ||
|
|
2d7e8b58e4 | ||
|
|
f3a97841bd | ||
|
|
40f0378136 | ||
|
|
17b6ce1379 | ||
|
|
14ac24cacc | ||
|
|
6bf253deda | ||
|
|
aa4346a0e3 | ||
|
|
8c541a6e4d | ||
|
|
1a43afe6f7 | ||
|
|
9882c4c761 | ||
|
|
54ad04b6e9 | ||
|
|
540cd772e4 | ||
|
|
621de301c7 | ||
|
|
8769c1a92b | ||
|
|
8e1c0b0852 | ||
|
|
56d6791205 | ||
|
|
016e630ecf | ||
|
|
69b779b4a8 | ||
|
|
7a537765bc | ||
|
|
21b2e874ce | ||
|
|
55ad950609 | ||
|
|
654ab117f2 | ||
|
|
5ec9bfc47d | ||
|
|
1066f06ec1 | ||
|
|
668dbb25ab | ||
|
|
fced4d6e57 | ||
|
|
c5ba6e22fa | ||
|
|
6012ec8eb7 | ||
|
|
75a44e5aa9 | ||
|
|
a811f2e17d | ||
|
|
b65f2509a2 | ||
|
|
b60117c713 | ||
|
|
d3142736c8 | ||
|
|
1ececf1127 | ||
|
|
a09f7713ce | ||
|
|
f3bace10ae | ||
|
|
39d9bd4d47 | ||
|
|
eb2cfe1d19 | ||
|
|
ca5a7d7656 | ||
|
|
ea2084392f | ||
|
|
5d99534d54 | ||
|
|
f048cff093 | ||
|
|
f571181d36 | ||
|
|
fc9b66b078 | ||
|
|
f039a94744 | ||
|
|
b4baa7ce02 | ||
|
|
bd38c8fe3c | ||
|
|
9a0748d8ed | ||
|
|
feae9ca4aa | ||
|
|
d1ee9827a0 | ||
|
|
1fe591ae20 | ||
|
|
b820e1b587 | ||
|
|
ebfc2a4942 | ||
|
|
7167d4bdc0 | ||
|
|
a022b672a0 | ||
|
|
a7a48221d3 | ||
|
|
e5118661a7 | ||
|
|
58d9a5ebac | ||
|
|
fae7f11222 | ||
|
|
1986e62477 | ||
|
|
0ee2a0e6d7 | ||
|
|
2b28ddd0c6 | ||
|
|
b15ef49c57 | ||
|
|
ed05caec93 | ||
|
|
25ca965938 | ||
|
|
ead27db9f0 | ||
|
|
4650105d90 | ||
|
|
b8417abee5 | ||
|
|
cc982ec7fe | ||
|
|
2dba76a7c2 | ||
|
|
9fd5634778 | ||
|
|
c8063e5732 | ||
|
|
ee3ba7c761 | ||
|
|
2882737bcd | ||
|
|
47588f343b | ||
|
|
1c0af6c7bc | ||
|
|
b07ffb3c78 | ||
|
|
bea82def10 | ||
|
|
671a857560 | ||
|
|
eff2d977c1 | ||
|
|
30a0d62436 | ||
|
|
91d0f25442 | ||
|
|
4a10c9ef6f | ||
|
|
9d7f5bdc26 | ||
|
|
99dbd23f1b | ||
|
|
673f086e87 | ||
|
|
4103925835 | ||
|
|
cad2780219 | ||
|
|
4636a7f14b | ||
|
|
a64bdf50fb | ||
|
|
706534ffe1 | ||
|
|
4286af3599 | ||
|
|
9a0254a118 | ||
|
|
f3ae4b8786 | ||
|
|
6566e853cd | ||
|
|
ab06ace1f6 | ||
|
|
9a65ed4ce2 | ||
|
|
5ba7084815 | ||
|
|
dc10118d3b | ||
|
|
27102ea0fb | ||
|
|
c563175ff0 | ||
|
|
b110c55993 | ||
|
|
dc346b7ffa | ||
|
|
88fcbf5f1d | ||
|
|
eace1d9c67 | ||
|
|
d0d39c13e7 | ||
|
|
2733d43ea7 | ||
|
|
ae6ec411d0 | ||
|
|
8a77af7a6d | ||
|
|
2a57ead7e3 | ||
|
|
839315b271 | ||
|
|
67dfa37c56 | ||
|
|
590188820d | ||
|
|
a764c70b4a | ||
|
|
a27abab65f | ||
|
|
c241ec90ec | ||
|
|
f789d28277 | ||
|
|
c1c8b30a35 | ||
|
|
15046c6c59 | ||
|
|
1da15181da | ||
|
|
3c6b755352 | ||
|
|
3c144ada53 | ||
|
|
7ba6647c4f | ||
|
|
e708670f9a | ||
|
|
de4c6065dc | ||
|
|
d60f180f43 | ||
|
|
30318a6654 | ||
|
|
d8420413b7 | ||
|
|
a5951babfc | ||
|
|
2cba167634 | ||
|
|
89743aae5d | ||
|
|
e6135981a5 | ||
|
|
739521333c | ||
|
|
64af83161a | ||
|
|
98252634fc | ||
|
|
a87fb57656 | ||
|
|
34708bbba1 | ||
|
|
f91259f46d | ||
|
|
cf6e362972 | ||
|
|
95c4ade718 | ||
|
|
84125d7c92 | ||
|
|
17721aff55 | ||
|
|
d1b6224c2b | ||
|
|
1bd31742b9 | ||
|
|
165a2ef1b8 | ||
|
|
774c10396c | ||
|
|
33c5b5feb8 | ||
|
|
b83b9974ee | ||
|
|
bcbe5059a9 | ||
|
|
5bda901146 | ||
|
|
82565690c7 | ||
|
|
978d900e36 | ||
|
|
d330100542 | ||
|
|
4c0edd2efb | ||
|
|
146cdc020d | ||
|
|
52f2b9ef58 | ||
|
|
a09506a0ad | ||
|
|
10d33238b9 | ||
|
|
b78ea06829 | ||
|
|
eae942b91c | ||
|
|
1075b006b5 | ||
|
|
afaa02709c | ||
|
|
332a687aef | ||
|
|
d1c7875406 | ||
|
|
cbc2f9eb32 | ||
|
|
26e3785963 | ||
|
|
f8b7fb72b8 | ||
|
|
7b12f6a1dd | ||
|
|
c7a0613c57 | ||
|
|
83a0085c4d | ||
|
|
05bb7fa821 | ||
|
|
4cc42133b5 | ||
|
|
a773a52559 | ||
|
|
5af271cf3a | ||
|
|
0c2bab1f69 | ||
|
|
b7233d063f | ||
|
|
8720841c48 | ||
|
|
263697e491 | ||
|
|
493f1da266 | ||
|
|
8b44a54bb2 | ||
|
|
b5828a7ce9 | ||
|
|
51a18225ad | ||
|
|
28625451dd | ||
|
|
3914176bc4 | ||
|
|
13989b965d | ||
|
|
770cd24f27 | ||
|
|
431bb1ed16 | ||
|
|
3bb9c7ee92 | ||
|
|
45edcbb03e | ||
|
|
e99fd2892b | ||
|
|
99ea16d7fd | ||
|
|
bc9ff6d1bf | ||
|
|
ad3bcbb1bb | ||
|
|
25dde58297 | ||
|
|
bba3487dc4 | ||
|
|
4fdaa46328 | ||
|
|
4427f03b08 | ||
|
|
4e2c63c8cb | ||
|
|
afecde87d8 | ||
|
|
c14eae6d56 | ||
|
|
684aba0e90 | ||
|
|
46f8a659b3 | ||
|
|
3940a214d0 | ||
|
|
411f563cbe | ||
|
|
b5a6b34968 | ||
|
|
fa8eaf7355 | ||
|
|
7eb09c3445 | ||
|
|
edfd3d7206 | ||
|
|
d699caf255 | ||
|
|
bd4eede6b4 | ||
|
|
1fd8e772b0 | ||
|
|
7ce0bd1181 | ||
|
|
a4b7c39a9a | ||
|
|
a5ee8b39ef | ||
|
|
5b06c60318 | ||
|
|
b306715b4a | ||
|
|
8d99bdac25 | ||
|
|
e114dfda6d | ||
|
|
472ad90d83 | ||
|
|
622f0c047c | ||
|
|
7f38414276 | ||
|
|
1d3d59243c | ||
|
|
e2343c03e0 | ||
|
|
0e0df1fb3b | ||
|
|
800a789f50 | ||
|
|
106664b942 | ||
|
|
1c738c6b83 | ||
|
|
25fa1d7c6a | ||
|
|
45162652de | ||
|
|
537650a2cd | ||
|
|
f849073137 | ||
|
|
a3c154dcd3 | ||
|
|
1b8228b642 | ||
|
|
732d03f4e5 | ||
|
|
33787c6add | ||
|
|
44e7d2ebe6 | ||
|
|
e49ae663a6 | ||
|
|
2385ab8294 | ||
|
|
84ccb23098 | ||
|
|
ad343f8260 | ||
|
|
018d766179 | ||
|
|
a948be184c | ||
|
|
72b4a74245 | ||
|
|
36c824d973 | ||
|
|
229ce1aecf | ||
|
|
be45a9b7d5 | ||
|
|
d2c72a7f21 | ||
|
|
60e9827ffe | ||
|
|
a9256d4758 | ||
|
|
750b5be5d3 | ||
|
|
28bd7e5b19 | ||
|
|
d64c023099 | ||
|
|
429cb1f7f7 | ||
|
|
9f75068059 | ||
|
|
4636e9cffb | ||
|
|
4b2bf556d8 | ||
|
|
a16ea94836 | ||
|
|
b9ea249f81 | ||
|
|
470f480bc1 | ||
|
|
24ff3155ae | ||
|
|
47b3f464a9 | ||
|
|
cd201f8eb8 | ||
|
|
016278a759 | ||
|
|
b68f101e81 | ||
|
|
ab13548018 | ||
|
|
f507ee56b0 | ||
|
|
761adf1cf0 | ||
|
|
cd1fe64e6c |
@@ -63,6 +63,8 @@ ForEachMacros:
|
||||
SortIncludes: true
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '"V3Pch.*\.h"'
|
||||
Priority: -2 # Precompiled headers
|
||||
- Regex: '"(config_build|verilated_config|verilatedos)\.h"'
|
||||
Priority: -1 # Sepecials before main header
|
||||
- Regex: '(<|")verilated.*'
|
||||
@@ -112,6 +114,9 @@ SpacesBeforeTrailingComments: 2
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 0
|
||||
Maximum: -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "Verilator Build Environment",
|
||||
|
||||
"build": {
|
||||
"dockerfile": "../ci/docker/buildenv/Dockerfile"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,8 @@ Thanks for taking the time to report this.
|
||||
|
||||
Can you attach an example that shows the issue? (Must be openly licensed, ideally in test_regress format.)
|
||||
|
||||
What 'verilator' command line do we use to run your example?
|
||||
|
||||
What 'verilator --version' are you using? Did you try it with the git master version?
|
||||
|
||||
What OS and distribution are you using?
|
||||
|
||||
@@ -23,6 +23,10 @@ defaults:
|
||||
shell: bash
|
||||
working-directory: repo
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
@@ -33,7 +37,8 @@ jobs:
|
||||
compiler:
|
||||
- { cc: clang, cxx: clang++ }
|
||||
- { cc: gcc, cxx: g++ }
|
||||
m32: [0, 1]
|
||||
# m32 1 is deprecated, not here to speed up regressions
|
||||
m32: [0]
|
||||
exclude:
|
||||
# Build pull requests only with ubuntu-22.04 and without m32
|
||||
# - os: ${{ github.event_name == 'pull_request' && 'ubuntu-18.04' || 'do-not-exclude' }}
|
||||
@@ -58,7 +63,7 @@ jobs:
|
||||
CC: ${{ matrix.compiler.cc }}
|
||||
CXX: ${{ matrix.compiler.cxx }}
|
||||
CACHE_BASE_KEY: build-${{ matrix.os }}-${{ matrix.compiler.cc }}-m32=${{ matrix.m32 }}
|
||||
CCACHE_MAXSIZE: 250M # Per build matrix entry (2000M in total)
|
||||
CCACHE_MAXSIZE: 1000M # Per build matrix entry (* 5 = 5000M in total)
|
||||
VERILATOR_ARCHIVE: verilator-${{ github.sha }}-${{ matrix.os }}-${{ matrix.compiler.cc }}${{ matrix.m32 && '-m32' || '' }}.tar.gz
|
||||
steps:
|
||||
|
||||
@@ -103,7 +108,7 @@ jobs:
|
||||
compiler:
|
||||
- { cc: clang, cxx: clang++ }
|
||||
- { cc: gcc, cxx: g++ }
|
||||
m32: [0, 1]
|
||||
m32: [0]
|
||||
suite: [dist-vlt-0, dist-vlt-1, dist-vlt-2, vltmt-0, vltmt-1]
|
||||
exclude:
|
||||
# Build pull requests only with ubuntu-22.04 and without m32
|
||||
@@ -131,7 +136,7 @@ jobs:
|
||||
CC: ${{ matrix.compiler.cc }}
|
||||
CXX: ${{ matrix.compiler.cxx }}
|
||||
CACHE_BASE_KEY: test-${{ matrix.os }}-${{ matrix.compiler.cc }}-m32=${{ matrix.m32 }}-${{ matrix.suite }}
|
||||
CCACHE_MAXSIZE: 64M # Per build matrix entry (2160M in total)
|
||||
CCACHE_MAXSIZE: 100M # Per build per suite (* 5 * 5 = 2500M in total)
|
||||
VERILATOR_ARCHIVE: verilator-${{ github.sha }}-${{ matrix.os }}-${{ matrix.compiler.cc }}${{ matrix.m32 && '-m32' || '' }}.tar.gz
|
||||
steps:
|
||||
|
||||
@@ -162,3 +167,30 @@ jobs:
|
||||
env:
|
||||
TESTS: ${{ matrix.suite }}
|
||||
run: ./ci/ci-script.bash
|
||||
|
||||
lint-py:
|
||||
runs-on: ubuntu-22.04
|
||||
name: Lint Python
|
||||
env:
|
||||
CI_BUILD_STAGE_NAME: build
|
||||
CI_RUNS_ON: ubuntu-22.04
|
||||
CI_M32: 0
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: repo
|
||||
|
||||
- name: Install packages for build
|
||||
run: ./ci/ci-install.bash
|
||||
|
||||
# We use specific version numbers, otherwise a Python package
|
||||
# update may add a warning and break our build
|
||||
- name: Install packages for lint
|
||||
run: sudo pip3 install pylint==3.0.2 ruff==0.1.3 clang sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe ruff
|
||||
|
||||
- name: Configure
|
||||
run: autoconf && ./configure --enable-longtests --enable-ccwarn
|
||||
|
||||
- name: Lint
|
||||
run: make -k lint-py
|
||||
|
||||
@@ -22,6 +22,10 @@ defaults:
|
||||
run:
|
||||
working-directory: repo
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
windows:
|
||||
|
||||
@@ -43,3 +43,4 @@ verilator-config-version.cmake
|
||||
/.vscode/
|
||||
/.idea/
|
||||
/cmake-build-*/
|
||||
/test_regress/snapshot/
|
||||
|
||||
+24
-3
@@ -4,7 +4,7 @@
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
# Copyright 2003-2023 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2024 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.
|
||||
@@ -15,7 +15,7 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
cmake_policy(SET CMP0091 NEW) # Use MSVC_RUNTIME_LIBRARY to select the runtime
|
||||
project(Verilator
|
||||
VERSION 5.016
|
||||
VERSION 5.020
|
||||
HOMEPAGE_URL https://verilator.org
|
||||
LANGUAGES CXX
|
||||
)
|
||||
@@ -35,7 +35,7 @@ if (NOT WIN32)
|
||||
message(WARNING "CMake support on Linux/OSX is experimental.")
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
if (WIN32)
|
||||
if (DEFINED ENV{WIN_FLEX_BISON})
|
||||
set(WIN_FLEX_BISON "$ENV{WIN_FLEX_BISON}")
|
||||
endif()
|
||||
@@ -48,6 +48,27 @@ if (MSVC)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
endif()
|
||||
|
||||
set(OBJCACHE "" CACHE STRING "Path for ccache, auto-detected if empty")
|
||||
option(OBJCACHE_ENABLED "Compile Verilator with ccache" ON)
|
||||
|
||||
if (OBJCACHE_ENABLED)
|
||||
if (OBJCACHE STREQUAL "")
|
||||
find_program(OBJCACHE_PATH ccache)
|
||||
if (OBJCACHE_PATH STREQUAL "OBJCACHE_PATH-NOTFOUND")
|
||||
set(OBJCACHE_PATH "")
|
||||
endif()
|
||||
else()
|
||||
set(OBJCACHE_PATH "${OBJCACHE}")
|
||||
endif()
|
||||
if (NOT OBJCACHE_PATH STREQUAL "")
|
||||
execute_process(COMMAND "${OBJCACHE_PATH}" --version
|
||||
OUTPUT_VARIABLE objcache_version)
|
||||
string(REGEX MATCH "[^\n\r]+" objcache_version "${objcache_version}")
|
||||
message(STATUS "Found ccache: ${OBJCACHE_PATH} (\"${objcache_version}\")")
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER "${OBJCACHE_PATH}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(BISON)
|
||||
find_package(FLEX)
|
||||
|
||||
|
||||
@@ -8,6 +8,147 @@ The changes in each Verilator version are described below. The
|
||||
contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
|
||||
Verilator 5.020 2024-01-01
|
||||
==========================
|
||||
|
||||
**Major:**
|
||||
|
||||
* Support compilation with precompiled headers with Make and GCC or CLang.
|
||||
* Change include to systemc instead of systemc.h (#4622) (#4623). [Chih-Mao Chen]
|
||||
This may require that SystemC programs add 'using namespace sc_core', 'using namespace sc_dt'.
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Add devcontainer support (#4748). [Stefan Wallentowitz]
|
||||
* Support `iff` in sensitivity list (#1482) (#4626). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Support parameterized virtual interfaces (#4047) (#4743). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Support --timing triggers for virtual interfaces (#4673). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Support ccache when compiling Verilator with CMake (#4678). [Anthony Donlon]
|
||||
* Support passing constraints to --xml-only output (still otherwise unsupported) (#4683). [Shahid Ikram]
|
||||
* Support node memory usage information in --stats (#4684). [Geza Lore]
|
||||
* Support vpiConstType in vpi_get() (#4761). [Todd Strader]
|
||||
* Support vpi_iterate on packages with vpiInstance (#4726). [Todd Strader]
|
||||
* Support multiple parameters in virtual interfaces (#4745). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Support user C/C++ code in final archive, and make a lib{model}.a (#4749) (#4754). [Fan Shupei]
|
||||
* Support inside operator on unpacked arrays and queues (#4751). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Support VPI parameter iteration (#4765). [Todd Strader]
|
||||
* Support packages in vpi_handle_by_name() (#4768). [Todd Strader]
|
||||
* Support invoking interface methods on virtual interface variables (#4774) (#4775). [Jordan McConnon]
|
||||
* Remove deprecated options (#4663). [Geza Lore]
|
||||
* Remove older compiler support; require C++14 or newer (#4784) (#4786).
|
||||
* Optimize timing-delayed queue (#4584). [qrqiuren]
|
||||
* Optimize substitute optimization memory usage (#4687). [Geza Lore]
|
||||
* Optimize wide primitive operations with -Oz (#4733). [Geza Lore]
|
||||
* Optimize V3Premit performance etc. (#4736). [Geza Lore]
|
||||
* Fix VPI TOP level variable iteration (#3919) (#4618). [Marlon James]
|
||||
* Fix display with no % printing assoc array (#4376). [Alex Solomatnikov]
|
||||
* Fix scheduling of external force signals (#4577) (#4668). [Geza Lore]
|
||||
* Fix a memory leak in V3Fork (#4628). [Krzysztof Boroński]
|
||||
* Fix linking parameterized hierarchical blocks and recursive hierarchical blocks (#4654). [Anthony Donlon]
|
||||
* Fix identifiers that end with '_' on Windows (#4655). [Anthony Donlon]
|
||||
* Fix 'for' loop with outside variable reference (#4660). [David Harris]
|
||||
* Fix tracing FST enums (#4661) (#4756). [Todd Strader]
|
||||
* Fix interface parameters used in loop generate constructs (#4664) (#4665). [Anthony Donlon]
|
||||
* Fix C++20 compilation errors (#4670).
|
||||
* Fix deadlocks in error handler (#4672). [Mariusz Glebocki, Antmicro Ltd.]
|
||||
* Fix MingW compilation (#4675). [David Ledger]
|
||||
* Fix trace when using SystemC with certain configurations (#4676). [Anthony Donlon]
|
||||
* Fix range access to classes depending on parameter resolution (#4681). [Krzysztof Boroński]
|
||||
* Fix select into constant And/Or/Xor pattern (#4689). [Geza Lore]
|
||||
* Fix access type of function arguments (#4692) (#4694). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix dynamic NBAs with automatic vars (#4696). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix # 0 delays for process resumption, etc. (#4697). [Krzysztof Boroński]
|
||||
* Fix conflicted namespace for coroutines (#4701) (#4707). [Jinyan Xu]
|
||||
* Fix compilers seeing empty input due to file system races (#4708). [Flavien Solt]
|
||||
* Fix shift of > 32-bit number (#4719). [Flavien Solt]
|
||||
* Fix Windows include gates in filesystem Flush implementation. (#4720). [William D. Jones]
|
||||
* Fix power operator with wide numbers and constants (#4721) (#4763). [Flavien Solt]
|
||||
* Fix parameter passing to ports (#4723). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix block names of nested do..while loops (#4728). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix class name in error on 'new' on virtual class (#4739). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix typedefs pointing to parameterized classes (#4747). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix $finish twice to no longer exit (#4757). [Tim Hutt]
|
||||
* Fix dynamic NBA conditions (#4773). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix `V3Fork` stage to run only if `--timing` is set (#4778). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix max multiply width and add runtime assertions if too small. (#4781)
|
||||
|
||||
|
||||
Verilator 5.018 2023-10-30
|
||||
==========================
|
||||
|
||||
**Major:**
|
||||
|
||||
* Support compilation with precompiled headers with Make and GCC or CLang.
|
||||
* Change include of systemc instead of systemc.h (#4622) (#4623). [Chih-Mao Chen]
|
||||
This may require that SystemC programs add 'using namespace sc_core', 'using namespace sc_dt'.
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Add SIDEEFFECT warning on mishandled side effect cases.
|
||||
* Add trace() API even when Verilated without --trace (#4462). [phelter]
|
||||
* Add warning on interface instantiation without parens (#4094). [Gökçe Aydos]
|
||||
* Add sv_vpi_user.h from IEEE 1800-2017 Annex M (#4606). [Marlon James]
|
||||
* Support 'disable fork' (#4125) (#4569). [Aleksander Kiryk, Antmicro Ltd.]
|
||||
* Support 'wait fork' (#4586). [Aleksander Kiryk, Antmicro Ltd.]
|
||||
* Support 'randc' (#4349).
|
||||
* Support assigning events (#4403). [Krzysztof Boroński]
|
||||
* Support resizing function call inout arguments (#4467).
|
||||
* Support NBAs in non-inlined functions/tasks (#4496) (#4572). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Support converting parameters inside modules to localparams (#4511). [Anthony Donlon]
|
||||
* Support concatenation of unpacked arrays (#4558). [Yutetsu TAKATSUKASA]
|
||||
* Support Clang 16 (#4592). [Mariusz Glebocki]
|
||||
* Support VPI variables of real and string data types (#4594). [Marlon James]
|
||||
* Support making VL_LOCK_SPINS configurable (#4599). [Geza Lore]
|
||||
* Change code --stats output (#4597). [Geza Lore]
|
||||
* Change --prof-exec infrastructure and report (#4602). [Geza Lore]
|
||||
* Change lint_off to not propagate upwards to files including where the lint_off is.
|
||||
* Optimize empty expression statements (#4544).
|
||||
* Optimize trace internals (#4610) (#4612). [Geza Lore]
|
||||
* Optimize internal performance issues (#4638). [Geza Lore]
|
||||
* Fix conversion of impure logical expressions to bit expressions (#487 partial) (#4437). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix enum functions in localparams (#3999). [Andrew Nolte]
|
||||
* Fix passing arguments by reference (#3385 partial) (#4489). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix multithreading handling to separate by code units that use/never use it (#4228). [Mariusz Glebocki, Antmicro Ltd.]
|
||||
* Fix usage of annotation options (#4486) (#4504). [Michal Czyz]
|
||||
* Fix detecting local vars in nested forks (#4493) (#4506). [Kamil Rakoczy]
|
||||
* Fix handling input file path separator (#4515) (#4516). [Anthony Donlon]
|
||||
* Fix mis-support for parameterized UDPs (#4518). [Anthony Donlon]
|
||||
* Fix constant conversion of $realtobits, $bitstoreal (#4522). [Andrew Nolte]
|
||||
* Fix conversion of integers in $display '%e' (#4528). [muzafferkal]
|
||||
* Fix non-inlined interface tracing (#3984) (#4530). [Todd Strader]
|
||||
* Fix stream operations with operands of struct type (#4531) (#4532). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix 'this' in a constructor (#4533). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix stream shift operator of 32 bits (#4536). [Julien Faucher]
|
||||
* Fix object destruction after a copy constructor (#4540) (#4541). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix inlining of real functions miscasting (#4543). [Andrew Nolte]
|
||||
* Fix broken link error for enum references (#4551). [Anthony Donlon]
|
||||
* Fix logical expressions with class objects - caching in v3Const (#4552). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix using functions/tasks following class definition inside module (#4553). [Anthony Donlon]
|
||||
* Fix large constant buffer overflow (#4556). [Varun Koyyalagunta]
|
||||
* Fix instance arrays connecting to array of structs (#4557). [raphmaster]
|
||||
* Fix error message for invalid parameter overrides (#4559). [Anthony Donlon]
|
||||
* Fix shift to remove operation side effects (#4563).
|
||||
* Fix compile warning on unused member function variable (#4567).
|
||||
* Fix method narrowing conversion compiler error (#4568).
|
||||
* Fix interface comparison (#4570). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix dynamic triggers for named events (#4571). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix dictionaries with keys of class types (#4576). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix to not remap local assign intervals in forks (#4583). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix display optimization ignoring side effects (#4585).
|
||||
* Fix PLI/DPI user defined system task/function grammar (#4587) (#4588). [Quentin Corradi]
|
||||
* Fix fault on empty clocking block (#4593). [Alex Mykyta]
|
||||
* Fix creating implicit nets for inputs of gate primitives (#4603). [Geza Lore]
|
||||
* Fix try_put method of unbounded mailbox (#4608). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix stable name generation in V3Fork (#4615) (#4624). [Krzysztof Boroński]
|
||||
* Fix virtual methods (#4616). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix insertion at queue end (#4619). [Krzysztof Boroński]
|
||||
* Fix rand fields of reference types (#4627). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix dynamic casts of null values (#4631). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix signals read via virtual interfaces being misoptimized (#4645). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix handling of static keyword in methods (#4649). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix preprocessor to show `line 2 on resumed file.
|
||||
|
||||
|
||||
Verilator 5.016 2023-09-16
|
||||
==========================
|
||||
|
||||
@@ -434,7 +575,7 @@ Verilator 5.002 2022-10-29
|
||||
* Fix null access on optimized-out fork statements (#3658). [Krzysztof Bieganski, Antmicro Ltd]
|
||||
* Fix VPI inline module naming mismatch (#3690) (#3694). [Jiuyang Liu]
|
||||
* Fix deadlock in timeprecision when using SystemC (#3707). [Kamil Rakoczy, Antmicro Ltd]
|
||||
* Fix width mismatch on inside operator (#3714). [Alex Torregrosa]
|
||||
* Fix width mismatch on inside operator (#3714). [Àlex Torregrosa]
|
||||
|
||||
|
||||
Verilator 4.228 2022-10-01
|
||||
@@ -664,7 +805,7 @@ Verilator 4.214 2021-10-17
|
||||
* Fix removing if statement with side effect in condition (#3131). [Alexander Grobman]
|
||||
* Fix --waiver-output for multiline warnings (#2429) (#3141). [Keith Colbert]
|
||||
* Fix internal error on bad widths (#3140) (#3145). [Zhanglei Wang]
|
||||
* Fix crash on clang 12/13 (#3148). [Kouping Hsu]
|
||||
* Fix crash on clang 12/13 (#3148). [Kuoping Hsu]
|
||||
* Fix cygwin compile error due to missing -std=gnu++14 (#3149). [Sun Kim]
|
||||
* Fix $urandom_range when the range is 0 ... UINT_MAX (#3161). [Iru Cai]
|
||||
* Fix constructor-parameter argument comma-separation in C++ (#3162). [Matthew Ballance]
|
||||
@@ -779,12 +920,12 @@ Verilator 4.202 2021-04-24
|
||||
* Mark --no-relative-cfuncs as scheduled for deprecation.
|
||||
* Add --coverage-max-width (#2853). [xuejiazidi]
|
||||
* Add VerilatedCovContext::forcePerInstance (#2793). [Kevin Laeufer]
|
||||
* Add FST SystemC tracing (#2806). [Alex Torregrosa]
|
||||
* Add FST SystemC tracing (#2806). [Àlex Torregrosa]
|
||||
* Add PINNOTFOUND warning in place of error (#2868). [Udi Finkelstein]
|
||||
* Support overlaps in priority case statements (#2864). [Rupert Swarbrick]
|
||||
* Support for null ports (#2875). [Udi Finkelstein]
|
||||
* Fix class unpacked-array compile error (#2774). [Iru Cai]
|
||||
* Fix scope types in FST and VCD traces (#2805). [Alex Torregrosa]
|
||||
* Fix scope types in FST and VCD traces (#2805). [Àlex Torregrosa]
|
||||
* Fix exceeding command-line ar limit (#2834). [Yinan Xu]
|
||||
* Fix false $dumpfile warning on model save (#2834). [Yinan Xu]
|
||||
* Fix --timescale-override not suppressing TIMESCALEMOD (#2838). [Kaleb Barrett]
|
||||
@@ -841,7 +982,7 @@ Verilator 4.110 2021-02-25
|
||||
**Minor:**
|
||||
|
||||
* Support concat selection (#2721).
|
||||
* Support struct scopes when dumping structs to VCD (#2776) [Alex Torregrosa]
|
||||
* Support struct scopes when dumping structs to VCD (#2776) [Àlex Torregrosa]
|
||||
* Generate SELRANGE for potentially unreachable code (#2625) (#2754) [Pierre-Henri Horrein]
|
||||
* For --flatten, override inlining of public and no_inline modules (#2761) [James Hanlon]
|
||||
* Fix little endian interface pin swizzling (#2475). [Don Owen]
|
||||
@@ -852,7 +993,7 @@ Verilator 4.110 2021-02-25
|
||||
* Fix class extends with VM_PARALLEL_BUILDS (#2775). [Iru Cai]
|
||||
* Fix shifts by > 32 bit values (#2785). [qrq992]
|
||||
* Fix examples not flushing vcd (#2787). [Richard E George]
|
||||
* Fix little endian packed array pattern assignment (#2795). [Alex Torregrosa]
|
||||
* Fix little endian packed array pattern assignment (#2795). [Àlex Torregrosa]
|
||||
|
||||
|
||||
Verilator 4.108 2021-01-10
|
||||
@@ -1328,7 +1469,7 @@ Verilator 4.014 2019-05-08
|
||||
**Minor:**
|
||||
|
||||
* Add --trace-fst-thread.
|
||||
* Support '#' comments in $readmem. (#1411) [Frederick Requin]
|
||||
* Support '#' comments in $readmem. (#1411) [Frédéric Requin]
|
||||
* Support "'dx" constants. (#1423) [Udi Finkelstein]
|
||||
* For FST tracing use LZ4 compression. [Tony Bybell]
|
||||
* Add error when use parameters without value. (#1424) [Peter Gerst]
|
||||
@@ -1598,19 +1739,19 @@ Verilator 3.912 2017-09-23
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Support or/and/xor array intrinsic methods. (#1210) [Mike Popoloski]
|
||||
* Support or/and/xor array intrinsic methods. (#1210) [Michael Popoloski]
|
||||
* Support package export. (#1217) [Usuario Eda]
|
||||
* Support module port parameters without defaults. (#1213) [Mike Popoloski]
|
||||
* Support module port parameters without defaults. (#1213) [Michael Popoloski]
|
||||
* Add performance information to --stats file.
|
||||
* Simplify VL_CONST_W macro generation for faster compiles.
|
||||
* Optimize improvements for Shift-And, and replication constructs.
|
||||
* Fix ordering of arrayed cell wide connections. (#1202 partial) [Mike Popoloski]
|
||||
* Fix LITENDIAN warning on arrayed cells. (#1202) [Mike Popoloski]
|
||||
* Fix enum ranges without colons. (#1204) [Mike Popoloski]
|
||||
* Fix GCC noreturn compile error. (#1209) [Mike Popoloski]
|
||||
* Fix constant function default parameters. (#1211) [Mike Popoloski]
|
||||
* Fix non-colon array of interface modports. (#1212) [Mike Popoloski]
|
||||
* Fix .name connections on interfaces. (#1214) [Mike Popoloski]
|
||||
* Fix ordering of arrayed cell wide connections. (#1202 partial) [Michael Popoloski]
|
||||
* Fix LITENDIAN warning on arrayed cells. (#1202) [Michael Popoloski]
|
||||
* Fix enum ranges without colons. (#1204) [Michael Popoloski]
|
||||
* Fix GCC noreturn compile error. (#1209) [Michael Popoloski]
|
||||
* Fix constant function default parameters. (#1211) [Michael Popoloski]
|
||||
* Fix non-colon array of interface modports. (#1212) [Michael Popoloski]
|
||||
* Fix .name connections on interfaces. (#1214) [Michael Popoloski]
|
||||
* Fix wide array indices causing compile error.
|
||||
|
||||
|
||||
@@ -1732,8 +1873,8 @@ Verilator 3.888 2016-10-14
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Add --no-decoration to remove output comments, msg2015. [Frederic Requin]
|
||||
* If VM_PARALLEL_BUILDS=1, use OPT_FAST and OPT_SLOW. [Frederic Requin]
|
||||
* Add --no-decoration to remove output comments, msg2015. [Frédéric Requin]
|
||||
* If VM_PARALLEL_BUILDS=1, use OPT_FAST and OPT_SLOW. [Frédéric Requin]
|
||||
Set VM_DEFAULT_RULES=0 for old behavior.
|
||||
* Add error on DPI functions > 32 bits. (#1898) [Elliot Mednick]
|
||||
* Improve Verilation performance on internal strings. (#1896) [Johan Bjork]
|
||||
@@ -1769,7 +1910,7 @@ Verilator 3.884 2016-05-18
|
||||
* Fix --output-split of constructors. (#1035) [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 $value$plusargs to string. (#1880) [Frederic Requin]
|
||||
* Fix $value$plusargs to string. (#1880) [Frédéric Requin]
|
||||
|
||||
|
||||
Verilator 3.882 2016-03-01
|
||||
@@ -1848,13 +1989,13 @@ Verilator 3.876 2015-08-12
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Add tracing_on, etc to vlt files. (#932) [Frederic Requin]
|
||||
* Add tracing_on, etc to vlt files. (#932) [Frédéric Requin]
|
||||
* Support extraction of enum bits. (#951) [Jonathon Donaldson]
|
||||
* Fix MinGW compiler error. (#927) (#929) [Hans Tichelaar]
|
||||
* Fix .c files to be treated as .cpp. (#930) [Jonathon Donaldson]
|
||||
* 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) [Frédéric Requin]
|
||||
* Fix $fopen with SV string. (#947) [Sven Stucki]
|
||||
* Fix hashed error with typedef inside block. (#948) [Sven Stucki]
|
||||
* Fix makefile with --coverage. (#953) [Eivind Liland]
|
||||
@@ -2094,7 +2235,7 @@ Verilator 3.852 2013-09-29
|
||||
|
||||
* Support named function and task arguments. [Chris Randall]
|
||||
* Report SELRANGE warning for non-generate if. (#675) [Roland Kruse]
|
||||
* Fix ordering of $fgetc. (#1808) [Frederic Requin]
|
||||
* Fix ordering of $fgetc. (#1808) [Frédéric Requin]
|
||||
* Fix --output-split-cfunc to count internal functions. [Chris Randall]
|
||||
* Fix crash on 32-bit Ubuntu. (#670) [Mark Jackson Pulver]
|
||||
|
||||
@@ -2162,7 +2303,7 @@ Verilator 3.846 2013-03-09
|
||||
* Fix DETECTARRAY on packed structures. (#610) [Jeremy Bennett]
|
||||
* Fix LITENDIAN on unpacked structures. (#614) [Wai Sum Mong]
|
||||
* 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) [Frédéric Requin]
|
||||
* Fix UNOPTFLAT circular array bounds crossing. (#630) [Jie Xu]
|
||||
|
||||
|
||||
@@ -3474,7 +3615,7 @@ Verilator 3.460 2005-07-27 Beta
|
||||
* Fix false warning when a clock is constant.
|
||||
* Fix X/Z in decimal numbers. [Wim Michiels]
|
||||
* Fix genvar statements in non-named generate blocks.
|
||||
* Fix core dump when missing newline in `define. [David van der bokke]
|
||||
* Fix core dump when missing newline in `define. [David van der Bokke]
|
||||
|
||||
|
||||
Verilator 3.450 2005-07-12
|
||||
@@ -4370,7 +4511,7 @@ Verilator 0.0 1994-07-08
|
||||
Copyright
|
||||
=========
|
||||
|
||||
Copyright 2001-2023 by Wilson Snyder. This program is free software; you
|
||||
Copyright 2001-2024 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.
|
||||
|
||||
+13
-3
@@ -7,7 +7,7 @@
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
# Copyright 2003-2023 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2024 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.
|
||||
@@ -173,6 +173,10 @@ smoke-test: all_nomsg
|
||||
test_regress: all_nomsg
|
||||
$(MAKE) -C test_regress
|
||||
|
||||
.PHONY: test-snap test-diff
|
||||
test-snap test-diff:
|
||||
$(MAKE) -C test_regress $@
|
||||
|
||||
examples: all_nomsg
|
||||
for p in $(EXAMPLES) ; do \
|
||||
$(MAKE) -C $$p VERILATOR_ROOT=`pwd` || exit 10; \
|
||||
@@ -430,9 +434,15 @@ PYLINT_FLAGS = --score=n --disable=R0801
|
||||
RUFF = ruff
|
||||
RUFF_FLAGS = check --ignore=E402,E501,E701
|
||||
|
||||
# "make -k" so can see all tool result errors
|
||||
lint-py:
|
||||
-$(PYLINT) $(PYLINT_FLAGS) $(PY_PROGRAMS)
|
||||
-$(RUFF) $(RUFF_FLAGS) $(PY_PROGRAMS)
|
||||
$(MAKE) -k lint-py-pylint lint-py-ruff
|
||||
|
||||
lint-py-pylint:
|
||||
$(PYLINT) $(PYLINT_FLAGS) $(PY_PROGRAMS)
|
||||
|
||||
lint-py-ruff:
|
||||
$(RUFF) $(RUFF_FLAGS) $(PY_PROGRAMS)
|
||||
|
||||
format-pl-exec:
|
||||
-chmod a+x test_regress/t/*.pl
|
||||
|
||||
+2
-2
@@ -142,7 +142,7 @@ Related Projects
|
||||
Open License
|
||||
============
|
||||
|
||||
Verilator is Copyright 2003-2023 by Wilson Snyder. (Report bugs to
|
||||
Verilator is Copyright 2003-2024 by Wilson Snyder. (Report bugs to
|
||||
`Verilator Issues <https://verilator.org/issues>`_.)
|
||||
|
||||
Verilator is free software; you can redistribute it and/or modify it under
|
||||
@@ -150,7 +150,7 @@ the terms of either the GNU Lesser General Public License Version 3 or the
|
||||
Perl Artistic License Version 2.0. See the documentation for more details.
|
||||
|
||||
.. _CHIPS Alliance: https://chipsalliance.org
|
||||
.. _Icarus Verilog: http://iverilog.icarus.com
|
||||
.. _Icarus Verilog: https://steveicarus.github.io/iverilog
|
||||
.. _Linux Foundation: https://www.linuxfoundation.org
|
||||
.. |Logo| image:: https://www.veripool.org/img/verilator_256_200_min.png
|
||||
.. |verilator multithreaded performance| image:: https://www.veripool.org/img/verilator_multithreaded_performance_bg-min.png
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env perl
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2003-2023 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2024 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.
|
||||
@@ -501,7 +501,7 @@ description of these arguments.
|
||||
|
||||
The latest version is available from L<https://verilator.org>.
|
||||
|
||||
Copyright 2003-2023 by Wilson Snyder. This program is free software; you can
|
||||
Copyright 2003-2024 by Wilson Snyder. This program is free software; you can
|
||||
redistribute it and/or modify the Verilator internals under the terms of
|
||||
either the GNU Lesser General Public License Version 3 or the Perl Artistic
|
||||
License Version 2.0.
|
||||
|
||||
@@ -17,7 +17,7 @@ parser = argparse.ArgumentParser(
|
||||
For documentation see
|
||||
https://verilator.org/guide/latest/exe_verilator_ccache_report.html""",
|
||||
epilog=
|
||||
"""Copyright 2002-2023 by Wilson Snyder. This program is free software; you
|
||||
"""Copyright 2002-2024 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.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env perl
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2003-2023 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2024 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.
|
||||
@@ -188,7 +188,7 @@ L<https://verilator.org/guide/latest/exe_verilator_coverage.html>.
|
||||
|
||||
The latest version is available from L<https://verilator.org>.
|
||||
|
||||
Copyright 2003-2023 by Wilson Snyder. This program is free software; you
|
||||
Copyright 2003-2024 by Wilson Snyder. This program is free software; you
|
||||
can redistribute it and/or modify the Verilator internals under the terms
|
||||
of either the GNU Lesser General Public License Version 3 or the Perl
|
||||
Artistic License Version 2.0.
|
||||
|
||||
@@ -110,7 +110,7 @@ Verilator_difftree is used for debugging Verilator tree output files.
|
||||
It performs a diff between two files, or all files common between two
|
||||
directories, ignoring irrelevant pointer differences.""",
|
||||
epilog=
|
||||
"""Copyright 2005-2023 by Wilson Snyder. This program is free software; you
|
||||
"""Copyright 2005-2024 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.
|
||||
|
||||
+340
-277
@@ -1,33 +1,32 @@
|
||||
#!/usr/bin/env python3
|
||||
# pylint: disable=C0103,C0114,C0116,C0209,C0301,R0914,R0912,R0915,W0511,eval-used
|
||||
# pylint: disable=C0103,C0114,C0116,C0209,C0301,R0914,R0912,R0915,W0511,W0603,eval-used
|
||||
######################################################################
|
||||
|
||||
import argparse
|
||||
import bisect
|
||||
import collections
|
||||
import math
|
||||
import re
|
||||
import statistics
|
||||
# from pprint import pprint
|
||||
|
||||
Threads = collections.defaultdict(lambda: collections.defaultdict(lambda: {}))
|
||||
Mtasks = collections.defaultdict(lambda: {})
|
||||
Evals = collections.defaultdict(lambda: {})
|
||||
EvalLoops = collections.defaultdict(lambda: {})
|
||||
Sections = []
|
||||
LongestVcdStrValueLength = 0
|
||||
Threads = collections.defaultdict(lambda: []) # List of records per thread id
|
||||
Mtasks = collections.defaultdict(lambda: {'elapsed': 0, 'end': 0})
|
||||
Cpus = collections.defaultdict(lambda: {'mtask_time': 0})
|
||||
Global = {
|
||||
'args': {},
|
||||
'cpuinfo': collections.defaultdict(lambda: {}),
|
||||
'rdtsc_cycle_time': 0,
|
||||
'stats': {}
|
||||
}
|
||||
ElapsedTime = None # total elapsed time
|
||||
ExecGraphTime = 0 # total elapsed time excuting an exec graph
|
||||
ExecGraphIntervals = [] # list of (start, end) pairs
|
||||
|
||||
######################################################################
|
||||
|
||||
|
||||
def process(filename):
|
||||
read_data(filename)
|
||||
report()
|
||||
|
||||
|
||||
def read_data(filename):
|
||||
with open(filename, "r", encoding="utf8") as fh:
|
||||
re_thread = re.compile(r'^VLPROFTHREAD (\d+)$')
|
||||
@@ -39,14 +38,17 @@ def read_data(filename):
|
||||
re_arg1 = re.compile(r'VLPROF arg\s+(\S+)\+([0-9.]*)\s*')
|
||||
re_arg2 = re.compile(r'VLPROF arg\s+(\S+)\s+([0-9.]*)\s*$')
|
||||
re_stat = re.compile(r'VLPROF stat\s+(\S+)\s+([0-9.]+)')
|
||||
re_time = re.compile(r'rdtsc time = (\d+) ticks')
|
||||
re_proc_cpu = re.compile(r'VLPROFPROC processor\s*:\s*(\d+)\s*$')
|
||||
re_proc_dat = re.compile(r'VLPROFPROC ([a-z_ ]+)\s*:\s*(.*)$')
|
||||
cpu = None
|
||||
thread = None
|
||||
execGraphStart = None
|
||||
|
||||
lastEvalBeginTick = None
|
||||
lastEvalLoopBeginTick = None
|
||||
global LongestVcdStrValueLength
|
||||
global ExecGraphTime
|
||||
|
||||
SectionStack = []
|
||||
mTaskThread = {}
|
||||
|
||||
for line in fh:
|
||||
recordMatch = re_record.match(line)
|
||||
@@ -54,29 +56,31 @@ def read_data(filename):
|
||||
kind, tick, payload = recordMatch.groups()
|
||||
tick = int(tick)
|
||||
payload = payload.strip()
|
||||
if kind == "EVAL_BEGIN":
|
||||
Evals[tick]['start'] = tick
|
||||
lastEvalBeginTick = tick
|
||||
elif kind == "EVAL_END":
|
||||
Evals[lastEvalBeginTick]['end'] = tick
|
||||
lastEvalBeginTick = None
|
||||
elif kind == "EVAL_LOOP_BEGIN":
|
||||
EvalLoops[tick]['start'] = tick
|
||||
lastEvalLoopBeginTick = tick
|
||||
elif kind == "EVAL_LOOP_END":
|
||||
EvalLoops[lastEvalLoopBeginTick]['end'] = tick
|
||||
lastEvalLoopBeginTick = None
|
||||
if kind == "SECTION_PUSH":
|
||||
LongestVcdStrValueLength = max(LongestVcdStrValueLength,
|
||||
len(payload))
|
||||
SectionStack.append(payload)
|
||||
Sections.append((tick, tuple(SectionStack)))
|
||||
elif kind == "SECTION_POP":
|
||||
assert SectionStack, "SECTION_POP without SECTION_PUSH"
|
||||
SectionStack.pop()
|
||||
Sections.append((tick, tuple(SectionStack)))
|
||||
elif kind == "MTASK_BEGIN":
|
||||
mtask, predict_start, ecpu = re_payload_mtaskBegin.match(
|
||||
payload).groups()
|
||||
mtask = int(mtask)
|
||||
predict_start = int(predict_start)
|
||||
ecpu = int(ecpu)
|
||||
Threads[thread][tick]['mtask'] = mtask
|
||||
Threads[thread][tick]['predict_start'] = predict_start
|
||||
Threads[thread][tick]['cpu'] = ecpu
|
||||
if 'elapsed' not in Mtasks[mtask]:
|
||||
Mtasks[mtask] = {'end': 0, 'elapsed': 0}
|
||||
mTaskThread[mtask] = thread
|
||||
records = Threads[thread]
|
||||
assert not records or records[-1]['start'] <= records[-1][
|
||||
'end'] <= tick
|
||||
records.append({
|
||||
'start': tick,
|
||||
'mtask': mtask,
|
||||
'predict_start': predict_start,
|
||||
'cpu': ecpu
|
||||
})
|
||||
Mtasks[mtask]['begin'] = tick
|
||||
Mtasks[mtask]['thread'] = thread
|
||||
Mtasks[mtask]['predict_start'] = predict_start
|
||||
@@ -86,11 +90,18 @@ def read_data(filename):
|
||||
mtask = int(mtask)
|
||||
predict_cost = int(predict_cost)
|
||||
begin = Mtasks[mtask]['begin']
|
||||
Threads[thread][begin]['end'] = tick
|
||||
Threads[thread][begin]['predict_cost'] = predict_cost
|
||||
record = Threads[mTaskThread[mtask]][-1]
|
||||
record['end'] = tick
|
||||
record['predict_cost'] = predict_cost
|
||||
Mtasks[mtask]['elapsed'] += tick - begin
|
||||
Mtasks[mtask]['predict_cost'] = predict_cost
|
||||
Mtasks[mtask]['end'] = max(Mtasks[mtask]['end'], tick)
|
||||
elif kind == "EXEC_GRAPH_BEGIN":
|
||||
execGraphStart = tick
|
||||
elif kind == "EXEC_GRAPH_END":
|
||||
ExecGraphTime += tick - execGraphStart
|
||||
ExecGraphIntervals.append((execGraphStart, tick))
|
||||
execGraphStart = None
|
||||
elif Args.debug:
|
||||
print("-Unknown execution trace record: %s" % line)
|
||||
elif re_thread.match(line):
|
||||
@@ -109,7 +120,7 @@ def read_data(filename):
|
||||
elif re_proc_cpu.match(line):
|
||||
match = re_proc_cpu.match(line)
|
||||
cpu = int(match.group(1))
|
||||
elif cpu and re_proc_dat.match(line):
|
||||
elif cpu is not None and re_proc_dat.match(line):
|
||||
match = re_proc_dat.match(line)
|
||||
term = match.group(1)
|
||||
value = match.group(2)
|
||||
@@ -121,11 +132,6 @@ def read_data(filename):
|
||||
pass
|
||||
elif Args.debug:
|
||||
print("-Unk: %s" % line)
|
||||
# TODO -- this is parsing text printed by a client.
|
||||
# Really, verilator proper should generate this
|
||||
# if it's useful...
|
||||
if re_time.match(line):
|
||||
Global['rdtsc_cycle_time'] = re_time.group(1)
|
||||
|
||||
|
||||
def re_match_result(regexp, line, result_to):
|
||||
@@ -144,125 +150,33 @@ def report():
|
||||
plus = "+" if re.match(r'^\+', arg) else " "
|
||||
print(" %s%s%s" % (arg, plus, Global['args'][arg]))
|
||||
|
||||
for records in Threads.values():
|
||||
for record in records:
|
||||
cpu = record['cpu']
|
||||
elapsed = record['end'] - record['start']
|
||||
Cpus[cpu]['mtask_time'] += elapsed
|
||||
|
||||
global ElapsedTime
|
||||
ElapsedTime = int(Global['stats']['ticks'])
|
||||
nthreads = int(Global['stats']['threads'])
|
||||
Global['cpus'] = {}
|
||||
for thread in Threads:
|
||||
# Make potentially multiple characters per column
|
||||
for start in Threads[thread]:
|
||||
if not Threads[thread][start]:
|
||||
continue
|
||||
cpu = Threads[thread][start]['cpu']
|
||||
elapsed = Threads[thread][start]['end'] - start
|
||||
if cpu not in Global['cpus']:
|
||||
Global['cpus'][cpu] = {'cpu_time': 0}
|
||||
Global['cpus'][cpu]['cpu_time'] += elapsed
|
||||
ncpus = max(len(Cpus), 1)
|
||||
|
||||
measured_mt_mtask_time = 0
|
||||
predict_mt_mtask_time = 0
|
||||
long_mtask_time = 0
|
||||
measured_last_end = 0
|
||||
predict_last_end = 0
|
||||
for mtask in Mtasks:
|
||||
measured_mt_mtask_time += Mtasks[mtask]['elapsed']
|
||||
predict_mt_mtask_time += Mtasks[mtask]['predict_cost']
|
||||
measured_last_end = max(measured_last_end, Mtasks[mtask]['end'])
|
||||
predict_last_end = max(
|
||||
predict_last_end,
|
||||
Mtasks[mtask]['predict_start'] + Mtasks[mtask]['predict_cost'])
|
||||
long_mtask_time = max(long_mtask_time, Mtasks[mtask]['elapsed'])
|
||||
Global['measured_last_end'] = measured_last_end
|
||||
Global['predict_last_end'] = predict_last_end
|
||||
|
||||
# If we know cycle time in the same (rdtsc) units,
|
||||
# this will give us an actual utilization number,
|
||||
# (how effectively we keep the cores busy.)
|
||||
#
|
||||
# It also gives us a number we can compare against
|
||||
# serial mode, to estimate the overhead of data sharing,
|
||||
# which will show up in the total elapsed time. (Overhead
|
||||
# of synchronization and scheduling should not.)
|
||||
print("\nAnalysis:")
|
||||
print(" Total threads = %d" % nthreads)
|
||||
print(" Total mtasks = %d" % len(Mtasks))
|
||||
ncpus = max(len(Global['cpus']), 1)
|
||||
print(" Total cpus used = %d" % ncpus)
|
||||
print(" Total yields = %d" %
|
||||
int(Global['stats'].get('yields', 0)))
|
||||
print(" Total evals = %d" % len(Evals))
|
||||
print(" Total eval loops = %d" % len(EvalLoops))
|
||||
if Mtasks:
|
||||
print(" Total eval time = %d rdtsc ticks" %
|
||||
Global['measured_last_end'])
|
||||
print(" Longest mtask time = %d rdtsc ticks" % long_mtask_time)
|
||||
print(" All-thread mtask time = %d rdtsc ticks" %
|
||||
measured_mt_mtask_time)
|
||||
long_efficiency = long_mtask_time / (Global.get(
|
||||
'measured_last_end', 1) or 1)
|
||||
print(" Longest-thread efficiency = %0.1f%%" %
|
||||
(long_efficiency * 100.0))
|
||||
mt_efficiency = measured_mt_mtask_time / (
|
||||
Global.get('measured_last_end', 1) * nthreads or 1)
|
||||
print(" All-thread efficiency = %0.1f%%" %
|
||||
(mt_efficiency * 100.0))
|
||||
print(" All-thread speedup = %0.1f" %
|
||||
(mt_efficiency * nthreads))
|
||||
if Global['rdtsc_cycle_time'] > 0:
|
||||
ut = measured_mt_mtask_time / Global['rdtsc_cycle_time']
|
||||
print("tot_mtask_cpu=" + measured_mt_mtask_time + " cyc=" +
|
||||
Global['rdtsc_cycle_time'] + " ut=" + ut)
|
||||
|
||||
predict_mt_efficiency = predict_mt_mtask_time / (
|
||||
Global.get('predict_last_end', 1) * nthreads or 1)
|
||||
print("\nPrediction (what Verilator used for scheduling):")
|
||||
print(" All-thread efficiency = %0.1f%%" %
|
||||
(predict_mt_efficiency * 100.0))
|
||||
print(" All-thread speedup = %0.1f" %
|
||||
(predict_mt_efficiency * nthreads))
|
||||
|
||||
p2e_ratios = []
|
||||
min_p2e = 1000000
|
||||
min_mtask = None
|
||||
max_p2e = -1000000
|
||||
max_mtask = None
|
||||
|
||||
for mtask in sorted(Mtasks.keys()):
|
||||
if Mtasks[mtask]['elapsed'] > 0:
|
||||
if Mtasks[mtask]['predict_cost'] == 0:
|
||||
Mtasks[mtask]['predict_cost'] = 1 # don't log(0) below
|
||||
p2e_ratio = math.log(Mtasks[mtask]['predict_cost'] /
|
||||
Mtasks[mtask]['elapsed'])
|
||||
p2e_ratios.append(p2e_ratio)
|
||||
|
||||
if p2e_ratio > max_p2e:
|
||||
max_p2e = p2e_ratio
|
||||
max_mtask = mtask
|
||||
if p2e_ratio < min_p2e:
|
||||
min_p2e = p2e_ratio
|
||||
min_mtask = mtask
|
||||
|
||||
print("\nMTask statistics:")
|
||||
print(" min log(p2e) = %0.3f" % min_p2e, end="")
|
||||
print(" from mtask %d (predict %d," %
|
||||
(min_mtask, Mtasks[min_mtask]['predict_cost']),
|
||||
end="")
|
||||
print(" elapsed %d)" % Mtasks[min_mtask]['elapsed'])
|
||||
print(" max log(p2e) = %0.3f" % max_p2e, end="")
|
||||
print(" from mtask %d (predict %d," %
|
||||
(max_mtask, Mtasks[max_mtask]['predict_cost']),
|
||||
end="")
|
||||
print(" elapsed %d)" % Mtasks[max_mtask]['elapsed'])
|
||||
|
||||
stddev = statistics.pstdev(p2e_ratios)
|
||||
mean = statistics.mean(p2e_ratios)
|
||||
print(" mean = %0.3f" % mean)
|
||||
print(" stddev = %0.3f" % stddev)
|
||||
print(" e ^ stddev = %0.3f" % math.exp(stddev))
|
||||
print("\nSummary:")
|
||||
print(" Total elapsed time = {} rdtsc ticks".format(ElapsedTime))
|
||||
print(" Parallelized code = {:.2%} of elapsed time".format(
|
||||
ExecGraphTime / ElapsedTime))
|
||||
print(" Total threads = %d" % nthreads)
|
||||
print(" Total CPUs used = %d" % ncpus)
|
||||
print(" Total mtasks = %d" % len(Mtasks))
|
||||
print(" Total yields = %d" % int(Global['stats'].get('yields', 0)))
|
||||
|
||||
report_mtasks()
|
||||
report_cpus()
|
||||
report_sections()
|
||||
|
||||
if nthreads > ncpus:
|
||||
print()
|
||||
print("%%Warning: There were fewer CPUs (%d) then threads (%d)." %
|
||||
print("%%Warning: There were fewer CPUs (%d) than threads (%d)." %
|
||||
(ncpus, nthreads))
|
||||
print(" : See docs on use of numactl.")
|
||||
else:
|
||||
@@ -279,32 +193,130 @@ def report():
|
||||
print()
|
||||
|
||||
|
||||
def report_mtasks():
|
||||
if not Mtasks:
|
||||
return
|
||||
|
||||
nthreads = int(Global['stats']['threads'])
|
||||
|
||||
# If we know cycle time in the same (rdtsc) units,
|
||||
# this will give us an actual utilization number,
|
||||
# (how effectively we keep the cores busy.)
|
||||
#
|
||||
# It also gives us a number we can compare against
|
||||
# serial mode, to estimate the overhead of data sharing,
|
||||
# which will show up in the total elapsed time. (Overhead
|
||||
# of synchronization and scheduling should not.)
|
||||
total_mtask_time = 0
|
||||
thread_mtask_time = collections.defaultdict(lambda: 0)
|
||||
long_mtask_time = 0
|
||||
long_mtask = None
|
||||
predict_mtask_time = 0
|
||||
predict_elapsed = 0
|
||||
for mtaskId in Mtasks:
|
||||
record = Mtasks[mtaskId]
|
||||
predict_mtask_time += record['predict_cost']
|
||||
total_mtask_time += record['elapsed']
|
||||
thread_mtask_time[record['thread']] += record['elapsed']
|
||||
predict_end = record['predict_start'] + record['predict_cost']
|
||||
predict_elapsed = max(predict_elapsed, predict_end)
|
||||
if record['elapsed'] > long_mtask_time:
|
||||
long_mtask_time = record['elapsed']
|
||||
long_mtask = mtaskId
|
||||
Global['predict_last_end'] = predict_elapsed
|
||||
|
||||
serialTime = ElapsedTime - ExecGraphTime
|
||||
|
||||
def subReport(elapsed, work):
|
||||
print(" Thread utilization = {:7.2%}".format(work /
|
||||
(elapsed * nthreads)))
|
||||
print(" Speedup = {:6.3}x".format(work / elapsed))
|
||||
|
||||
print("\nParallelized code, measured:")
|
||||
subReport(ExecGraphTime, total_mtask_time)
|
||||
|
||||
print("\nParallelized code, predicted during static scheduling:")
|
||||
subReport(predict_elapsed, predict_mtask_time)
|
||||
|
||||
print("\nAll code, measured:")
|
||||
subReport(ElapsedTime, serialTime + total_mtask_time)
|
||||
|
||||
print("\nAll code, measured, scaled by predicted speedup:")
|
||||
expectedParallelSpeedup = predict_mtask_time / predict_elapsed
|
||||
scaledElapsed = serialTime + total_mtask_time / expectedParallelSpeedup
|
||||
subReport(scaledElapsed, serialTime + total_mtask_time)
|
||||
|
||||
p2e_ratios = []
|
||||
min_p2e = 1000000
|
||||
min_mtask = None
|
||||
max_p2e = -1000000
|
||||
max_mtask = None
|
||||
|
||||
for mtask in sorted(Mtasks.keys()):
|
||||
if Mtasks[mtask]['elapsed'] > 0:
|
||||
if Mtasks[mtask]['predict_cost'] == 0:
|
||||
Mtasks[mtask]['predict_cost'] = 1 # don't log(0) below
|
||||
p2e_ratio = math.log(Mtasks[mtask]['predict_cost'] /
|
||||
Mtasks[mtask]['elapsed'])
|
||||
p2e_ratios.append(p2e_ratio)
|
||||
|
||||
if p2e_ratio > max_p2e:
|
||||
max_p2e = p2e_ratio
|
||||
max_mtask = mtask
|
||||
if p2e_ratio < min_p2e:
|
||||
min_p2e = p2e_ratio
|
||||
min_mtask = mtask
|
||||
|
||||
print("\nMTask statistics:")
|
||||
print(" Longest mtask id = {}".format(long_mtask))
|
||||
print(" Longest mtask time = {:.2%} of time elapsed in parallelized code".
|
||||
format(long_mtask_time / ExecGraphTime))
|
||||
print(" min log(p2e) = %0.3f" % min_p2e, end="")
|
||||
|
||||
print(" from mtask %d (predict %d," %
|
||||
(min_mtask, Mtasks[min_mtask]['predict_cost']),
|
||||
end="")
|
||||
print(" elapsed %d)" % Mtasks[min_mtask]['elapsed'])
|
||||
print(" max log(p2e) = %0.3f" % max_p2e, end="")
|
||||
print(" from mtask %d (predict %d," %
|
||||
(max_mtask, Mtasks[max_mtask]['predict_cost']),
|
||||
end="")
|
||||
print(" elapsed %d)" % Mtasks[max_mtask]['elapsed'])
|
||||
|
||||
stddev = statistics.pstdev(p2e_ratios)
|
||||
mean = statistics.mean(p2e_ratios)
|
||||
print(" mean = %0.3f" % mean)
|
||||
print(" stddev = %0.3f" % stddev)
|
||||
print(" e ^ stddev = %0.3f" % math.exp(stddev))
|
||||
|
||||
|
||||
def report_cpus():
|
||||
print("\nCPUs:")
|
||||
print("\nCPU info:")
|
||||
|
||||
Global['cpu_sockets'] = collections.defaultdict(lambda: 0)
|
||||
Global['cpu_socket_cores'] = collections.defaultdict(lambda: 0)
|
||||
|
||||
for cpu in sorted(Global['cpus'].keys()):
|
||||
print(" cpu %d: " % cpu, end='')
|
||||
print("cpu_time=%d" % Global['cpus'][cpu]['cpu_time'], end='')
|
||||
|
||||
socket = None
|
||||
print(" Id | Time spent executing MTask | Socket | Core | Model")
|
||||
print(" | % of elapsed ticks / ticks | | |")
|
||||
print(" ====|============================|========|======|======")
|
||||
for cpu in sorted(Cpus):
|
||||
socket = ""
|
||||
core = ""
|
||||
model = ""
|
||||
if cpu in Global['cpuinfo']:
|
||||
cpuinfo = Global['cpuinfo'][cpu]
|
||||
if 'physical_id' in cpuinfo and 'core_id' in cpuinfo:
|
||||
socket = int(cpuinfo['physical_id'])
|
||||
socket = cpuinfo['physical_id']
|
||||
Global['cpu_sockets'][socket] += 1
|
||||
print(" socket=%d" % socket, end='')
|
||||
|
||||
core = int(cpuinfo['core_id'])
|
||||
Global['cpu_socket_cores'][str(socket) + "__" + str(core)] += 1
|
||||
print(" core=%d" % core, end='')
|
||||
core = cpuinfo['core_id']
|
||||
Global['cpu_socket_cores'][socket + "__" + core] += 1
|
||||
|
||||
if 'model_name' in cpuinfo:
|
||||
model = cpuinfo['model_name']
|
||||
print(" %s" % model, end='')
|
||||
print()
|
||||
|
||||
print(" {:3d} | {:7.2%} / {:16d} | {:>6s} | {:>4s} | {}".format(
|
||||
cpu, Cpus[cpu]['mtask_time'] / ElapsedTime,
|
||||
Cpus[cpu]['mtask_time'], socket, core, model))
|
||||
|
||||
if len(Global['cpu_sockets']) > 1:
|
||||
Global['cpu_sockets_warning'] = True
|
||||
@@ -313,25 +325,68 @@ def report_cpus():
|
||||
Global['cpu_socket_cores_warning'] = True
|
||||
|
||||
|
||||
def report_sections():
|
||||
if not Sections:
|
||||
return
|
||||
print("\nSection profile:")
|
||||
|
||||
totalTime = collections.defaultdict(lambda: 0)
|
||||
selfTime = collections.defaultdict(lambda: 0)
|
||||
|
||||
sectionTree = [0, {}, 1] # [selfTime, childTrees, numberOfTimesEntered]
|
||||
prevTime = 0
|
||||
prevStack = ()
|
||||
for time, stack in Sections:
|
||||
if len(stack) > len(prevStack):
|
||||
scope = sectionTree
|
||||
for item in stack:
|
||||
scope = scope[1].setdefault(item, [0, {}, 0])
|
||||
scope[2] += 1
|
||||
dt = time - prevTime
|
||||
scope = sectionTree
|
||||
for item in prevStack:
|
||||
scope = scope[1].setdefault(item, [0, {}, 0])
|
||||
scope[0] += dt
|
||||
|
||||
if prevStack:
|
||||
for name in prevStack:
|
||||
totalTime[name] += dt
|
||||
selfTime[prevStack[-1]] += dt
|
||||
prevTime = time
|
||||
prevStack = stack
|
||||
|
||||
def treeSum(tree):
|
||||
n = tree[0]
|
||||
for subTree in tree[1].values():
|
||||
n += treeSum(subTree)
|
||||
return n
|
||||
|
||||
# Make sure the tree sums to the elapsed time
|
||||
sectionTree[0] += ElapsedTime - treeSum(sectionTree)
|
||||
|
||||
def printTree(prefix, name, entries, tree):
|
||||
print(" {:7.2%} | {:7.2%} | {:8} | {:10.2f} | {}".format(
|
||||
treeSum(tree) / ElapsedTime, tree[0] / ElapsedTime, tree[2],
|
||||
tree[2] / entries, prefix + name))
|
||||
for k in sorted(tree[1], key=lambda _: -treeSum(tree[1][_])):
|
||||
printTree(prefix + " ", k, tree[2], tree[1][k])
|
||||
|
||||
print(" Total | Self | Total | Relative | Section")
|
||||
print(" time | time | entries | entries | name ")
|
||||
print("==========|=========|==========|============|========")
|
||||
printTree("", "*TOTAL*", 1, sectionTree)
|
||||
|
||||
|
||||
######################################################################
|
||||
|
||||
|
||||
def write_vcd(filename):
|
||||
print("Writing %s" % filename)
|
||||
with open(filename, "w", encoding="utf8") as fh:
|
||||
vcd = {
|
||||
'values':
|
||||
collections.defaultdict(lambda: {}), # {<time>}{<code>} = value
|
||||
'sigs': {
|
||||
'predicted_threads': {},
|
||||
'measured_threads': {},
|
||||
'cpus': {},
|
||||
'evals': {},
|
||||
'mtasks': {},
|
||||
'Stats': {}
|
||||
} # {<module>}{<sig}} = code
|
||||
}
|
||||
code = 0
|
||||
# dict of dicts of hierarchy elements/signal name -> (code, width)
|
||||
scopeSigs = {}
|
||||
# map from time -> code -> value
|
||||
values = collections.defaultdict(lambda: {})
|
||||
|
||||
parallelism = {
|
||||
'measured': collections.defaultdict(lambda: 0),
|
||||
@@ -340,132 +395,139 @@ def write_vcd(filename):
|
||||
parallelism['measured'][0] = 0
|
||||
parallelism['predicted'][0] = 0
|
||||
|
||||
# Measured graph
|
||||
for thread in sorted(Threads.keys()):
|
||||
sig = "thread%d_mtask" % thread
|
||||
if sig not in vcd['sigs']['measured_threads']:
|
||||
vcd['sigs']['measured_threads'][sig] = code
|
||||
code += 1
|
||||
mcode = vcd['sigs']['measured_threads'][sig]
|
||||
nextFreeCode = 0
|
||||
|
||||
for start in sorted(Threads[thread]):
|
||||
mtask = Threads[thread][start]['mtask']
|
||||
end = Threads[thread][start]['end']
|
||||
cpu = Threads[thread][start]['cpu']
|
||||
vcd['values'][start][mcode] = mtask
|
||||
vcd['values'][end][mcode] = None
|
||||
def getCode(width, *names):
|
||||
nonlocal nextFreeCode
|
||||
scope = scopeSigs
|
||||
*path, name = names
|
||||
for item in path:
|
||||
scope = scope.setdefault(item, {})
|
||||
code, oldWidth = scope.setdefault(name, (nextFreeCode, width))
|
||||
assert oldWidth == width
|
||||
if code == nextFreeCode:
|
||||
nextFreeCode += 1
|
||||
return code
|
||||
|
||||
def addValue(code, time, val):
|
||||
if isinstance(val, str):
|
||||
buf = ""
|
||||
for c in val:
|
||||
buf += bin(ord(c))[2:].rjust(8, "0")
|
||||
val = buf.ljust(LongestVcdStrValueLength * 8, "0")
|
||||
values[time][code] = val
|
||||
|
||||
# Measured graph
|
||||
for thread in sorted(Threads):
|
||||
mcode = getCode(32, 'measured', 't%d_mtask' % thread)
|
||||
for record in Threads[thread]:
|
||||
start = record['start']
|
||||
mtask = record['mtask']
|
||||
end = record['end']
|
||||
cpu = record['cpu']
|
||||
addValue(mcode, start, mtask)
|
||||
addValue(mcode, end, None)
|
||||
parallelism['measured'][start] += 1
|
||||
parallelism['measured'][end] -= 1
|
||||
|
||||
sig = "cpu%d_thread" % cpu
|
||||
if sig not in vcd['sigs']['cpus']:
|
||||
vcd['sigs']['cpus'][sig] = code
|
||||
code += 1
|
||||
ccode = vcd['sigs']['cpus'][sig]
|
||||
vcd['values'][start][ccode] = thread
|
||||
vcd['values'][end][ccode] = None
|
||||
code = getCode(32, 'measured', 'cpu%d_thread' % cpu)
|
||||
addValue(code, start, thread)
|
||||
addValue(code, end, None)
|
||||
|
||||
sig = "mtask%d_cpu" % mtask
|
||||
if sig not in vcd['sigs']['mtasks']:
|
||||
vcd['sigs']['mtasks'][sig] = code
|
||||
code += 1
|
||||
ccode = vcd['sigs']['mtasks'][sig]
|
||||
vcd['values'][start][ccode] = cpu
|
||||
vcd['values'][end][ccode] = None
|
||||
code = getCode(32, 'measured', 'cpu%d_mtask' % cpu)
|
||||
addValue(code, start, mtask)
|
||||
addValue(code, end, None)
|
||||
|
||||
# Eval graph
|
||||
vcd['sigs']['evals']["eval"] = code
|
||||
elcode = code
|
||||
code += 1
|
||||
n = 0
|
||||
for eval_start in Evals:
|
||||
eval_end = Evals[eval_start]['end']
|
||||
n += 1
|
||||
vcd['values'][eval_start][elcode] = n
|
||||
vcd['values'][eval_end][elcode] = None
|
||||
tStart = sorted(_['start'] for records in Threads.values()
|
||||
for _ in records)
|
||||
tEnd = sorted(_['end'] for records in Threads.values()
|
||||
for _ in records)
|
||||
|
||||
# Eval_loop graph
|
||||
vcd['sigs']['evals']["eval_loop"] = code
|
||||
elcode = code
|
||||
code += 1
|
||||
n = 0
|
||||
for eval_start in EvalLoops:
|
||||
eval_end = EvalLoops[eval_start]['end']
|
||||
n += 1
|
||||
vcd['values'][eval_start][elcode] = n
|
||||
vcd['values'][eval_end][elcode] = None
|
||||
# Predicted graph
|
||||
for start, end in ExecGraphIntervals:
|
||||
# Find the earliest MTask start after the start point, and the
|
||||
# latest MTask end before the end point, so we can scale to the
|
||||
# same range
|
||||
start = tStart[bisect.bisect_left(tStart, start)]
|
||||
end = tEnd[bisect.bisect_right(tEnd, end) - 1]
|
||||
# Compute scale so predicted graph is of same width as interval
|
||||
measured_scaling = (end - start) / Global['predict_last_end']
|
||||
# Predict mtasks that fill the time the execution occupied
|
||||
for mtask in Mtasks:
|
||||
thread = Mtasks[mtask]['thread']
|
||||
pred_scaled_start = start + int(
|
||||
Mtasks[mtask]['predict_start'] * measured_scaling)
|
||||
pred_scaled_end = start + int(
|
||||
(Mtasks[mtask]['predict_start'] +
|
||||
Mtasks[mtask]['predict_cost']) * measured_scaling)
|
||||
if pred_scaled_start == pred_scaled_end:
|
||||
continue
|
||||
|
||||
if Mtasks:
|
||||
# Predicted graph
|
||||
for eval_start in EvalLoops:
|
||||
eval_end = EvalLoops[eval_start]['end']
|
||||
# Compute scale so predicted graph is of same width as eval
|
||||
measured_scaling = (eval_end -
|
||||
eval_start) / Global['predict_last_end']
|
||||
# Predict mtasks that fill the time the eval occupied
|
||||
for mtask in Mtasks:
|
||||
thread = Mtasks[mtask]['thread']
|
||||
pred_scaled_start = eval_start + int(
|
||||
Mtasks[mtask]['predict_start'] * measured_scaling)
|
||||
pred_scaled_end = eval_start + int(
|
||||
(Mtasks[mtask]['predict_start'] +
|
||||
Mtasks[mtask]['predict_cost']) * measured_scaling)
|
||||
if pred_scaled_start == pred_scaled_end:
|
||||
continue
|
||||
mcode = getCode(32, 'predicted', 't%d_mtask' % thread)
|
||||
addValue(mcode, pred_scaled_start, mtask)
|
||||
addValue(mcode, pred_scaled_end, None)
|
||||
|
||||
sig = "predicted_thread%d_mtask" % thread
|
||||
if sig not in vcd['sigs']['predicted_threads']:
|
||||
vcd['sigs']['predicted_threads'][sig] = code
|
||||
code += 1
|
||||
mcode = vcd['sigs']['predicted_threads'][sig]
|
||||
parallelism['predicted'][pred_scaled_start] += 1
|
||||
parallelism['predicted'][pred_scaled_end] -= 1
|
||||
|
||||
vcd['values'][pred_scaled_start][mcode] = mtask
|
||||
vcd['values'][pred_scaled_end][mcode] = None
|
||||
# Parallelism graph
|
||||
for measpred in ('measured', 'predicted'):
|
||||
pcode = getCode(32, 'stats', '%s_parallelism' % measpred)
|
||||
value = 0
|
||||
for time in sorted(parallelism[measpred].keys()):
|
||||
value += parallelism[measpred][time]
|
||||
addValue(pcode, time, value)
|
||||
|
||||
parallelism['predicted'][pred_scaled_start] += 1
|
||||
parallelism['predicted'][pred_scaled_end] -= 1
|
||||
|
||||
# Parallelism graph
|
||||
for measpred in ('measured', 'predicted'):
|
||||
vcd['sigs']['Stats']["%s_parallelism" % measpred] = code
|
||||
pcode = code
|
||||
code += 1
|
||||
value = 0
|
||||
for time in sorted(parallelism[measpred].keys()):
|
||||
value += parallelism[measpred][time]
|
||||
vcd['values'][time][pcode] = value
|
||||
# Section graph
|
||||
if Sections:
|
||||
scode = getCode(LongestVcdStrValueLength * 8, "section", "trace")
|
||||
dcode = getCode(32, "section", "depth")
|
||||
for time, stack in Sections:
|
||||
addValue(scode, time, stack[-1] if stack else None)
|
||||
addValue(dcode, time, len(stack))
|
||||
|
||||
# Create output file
|
||||
fh.write("$version Generated by verilator_gantt $end\n")
|
||||
fh.write("$timescale 1ns $end\n")
|
||||
fh.write("\n")
|
||||
|
||||
all_codes = {}
|
||||
all_codes = set()
|
||||
|
||||
def writeScope(scope):
|
||||
assert isinstance(scope, dict)
|
||||
for key in sorted(scope):
|
||||
val = scope[key]
|
||||
if isinstance(val, dict):
|
||||
fh.write(" $scope module %s $end\n" % key)
|
||||
writeScope(val)
|
||||
fh.write(" $upscope $end\n")
|
||||
else:
|
||||
(code, width) = val
|
||||
all_codes.add(code)
|
||||
fh.write(" $var wire %d v%x %s [%d:0] $end\n" %
|
||||
(width, code, key, width - 1))
|
||||
|
||||
fh.write(" $scope module gantt $end\n")
|
||||
for module in sorted(vcd['sigs'].keys()):
|
||||
fh.write(" $scope module %s $end\n" % module)
|
||||
for sig in sorted(vcd['sigs'][module].keys()):
|
||||
code = vcd['sigs'][module][sig]
|
||||
fh.write(" $var wire 32 v%x %s [31:0] $end\n" % (code, sig))
|
||||
all_codes[code] = 1
|
||||
fh.write(" $upscope $end\n")
|
||||
writeScope(scopeSigs)
|
||||
fh.write(" $upscope $end\n")
|
||||
fh.write("$enddefinitions $end\n")
|
||||
fh.write("\n")
|
||||
|
||||
first = True
|
||||
for time in sorted(vcd['values']):
|
||||
for time in sorted(values):
|
||||
if first:
|
||||
first = False
|
||||
# Start with Z for any signals without time zero data
|
||||
for code in sorted(all_codes.keys()):
|
||||
if code not in vcd['values'][time]:
|
||||
vcd['values'][time][code] = None
|
||||
for code in sorted(all_codes):
|
||||
if code not in values[time]:
|
||||
addValue(code, time, None)
|
||||
fh.write("#%d\n" % time)
|
||||
for code in sorted(vcd['values'][time].keys()):
|
||||
value = vcd['values'][time][code]
|
||||
for code in sorted(values[time]):
|
||||
value = values[time][code]
|
||||
if value is None:
|
||||
fh.write("bz v%x\n" % code)
|
||||
elif isinstance(value, str):
|
||||
fh.write("b%s v%x\n" % (value, code))
|
||||
else:
|
||||
fh.write("b%s v%x\n" % (format(value, 'b'), code))
|
||||
|
||||
@@ -484,7 +546,7 @@ Verilator_gantt creates a visual representation to help analyze Verilator
|
||||
For documentation see
|
||||
https://verilator.org/guide/latest/exe_verilator_gantt.html""",
|
||||
epilog=
|
||||
"""Copyright 2018-2023 by Wilson Snyder. This program is free software; you
|
||||
"""Copyright 2018-2024 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.
|
||||
@@ -504,7 +566,8 @@ parser.add_argument('filename',
|
||||
|
||||
Args = parser.parse_args()
|
||||
|
||||
process(Args.filename)
|
||||
read_data(Args.filename)
|
||||
report()
|
||||
if not Args.no_vcd:
|
||||
write_vcd(Args.vcd)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
# pylint: disable=C0114,C0209
|
||||
#
|
||||
# Copyright 2003-2023 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2024 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify the Verilator internals under the terms
|
||||
# of either the GNU Lesser General Public License Version 3 or the Perl
|
||||
# Artistic License Version 2.0.
|
||||
|
||||
@@ -181,7 +181,7 @@ in each Verilog block.
|
||||
For documentation see
|
||||
https://verilator.org/guide/latest/exe_verilator_profcfunc.html""",
|
||||
epilog=
|
||||
"""Copyright 2002-2023 by Wilson Snyder. This program is free software; you
|
||||
"""Copyright 2002-2024 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.
|
||||
|
||||
@@ -26,4 +26,5 @@ if git log --format=%B -n 1 "$COMMIT" | grep -q -i '\[CI\s\+ccache\s\+clear\]';
|
||||
fi
|
||||
|
||||
# Dump stats, then zero stats
|
||||
# 22.04: ccache -s -v -z
|
||||
ccache -s -z
|
||||
|
||||
+4
-2
@@ -49,6 +49,7 @@ if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
|
||||
./configure --enable-longtests --enable-ccwarn ${CI_M32:+--enable-m32}
|
||||
ccache -z
|
||||
"$MAKE" -j "$NPROC" -k
|
||||
# 22.04: ccache -s -v
|
||||
ccache -s
|
||||
if [ "$CI_OS_NAME" = "osx" ]; then
|
||||
file bin/verilator_bin
|
||||
@@ -89,8 +90,8 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
|
||||
export VERILATOR_TEST_NO_GPROF=1 # gprof is a bit different on FreeBSD, disable
|
||||
fi
|
||||
|
||||
# Run sanitize on Ubuntu 20.04 only
|
||||
[ "$CI_RUNS_ON" = 'ubuntu-20.04' ] && [ "$CI_M32" = "" ] && sanitize='--sanitize' || sanitize=''
|
||||
# Run sanitize on Ubuntu 22.04 only
|
||||
[ "$CI_RUNS_ON" = 'ubuntu-22.04' ] && [ "$CI_M32" = "" ] && sanitize='--sanitize' || sanitize=''
|
||||
|
||||
# Run the specified test
|
||||
ccache -z
|
||||
@@ -180,6 +181,7 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
|
||||
fatal "Unknown test: $TESTS"
|
||||
;;
|
||||
esac
|
||||
# 22.04: ccache -s -v
|
||||
ccache -s
|
||||
|
||||
# Upload coverage data
|
||||
|
||||
@@ -8,6 +8,16 @@
|
||||
|
||||
FROM ubuntu:22.04
|
||||
|
||||
# Create the user
|
||||
RUN groupadd verilator \
|
||||
&& useradd -g verilator -m verilator -s /bin/bash \
|
||||
&& apt-get update \
|
||||
&& apt-get install --no-install-recommends -y sudo \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& echo verilator ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/verilator \
|
||||
&& chmod 0440 /etc/sudoers.d/verilator
|
||||
|
||||
RUN apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive \
|
||||
apt-get install --no-install-recommends -y \
|
||||
@@ -33,7 +43,6 @@ RUN apt-get update \
|
||||
perl \
|
||||
python3 \
|
||||
wget \
|
||||
zlibc \
|
||||
zlib1g \
|
||||
zlib1g-dev \
|
||||
&& apt-get clean \
|
||||
@@ -52,6 +61,8 @@ COPY build.sh /tmp/build.sh
|
||||
|
||||
ENV VERILATOR_AUTHOR_SITE=1
|
||||
|
||||
USER verilator
|
||||
|
||||
WORKDIR /work
|
||||
|
||||
ENTRYPOINT [ "/tmp/build.sh" ]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
Verilator Build Docker Container
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
Verilator Executable Docker Container
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# DESCRIPTION: codecov.io config
|
||||
#
|
||||
# Copyright 2020-2023 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2020-2024 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.
|
||||
|
||||
+42
-21
@@ -1,6 +1,6 @@
|
||||
# DESCRIPTION: Process this file with autoconf to produce a configure script.
|
||||
#
|
||||
# Copyright 2003-2023 by Wilson Snyder. Verilator is free software; you
|
||||
# Copyright 2003-2024 by Wilson Snyder. Verilator 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
|
||||
@@ -10,7 +10,7 @@
|
||||
# Then 'make maintainer-dist'
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[5.016 2023-09-16],
|
||||
AC_INIT([Verilator],[5.020 2024-01-01],
|
||||
[https://verilator.org],
|
||||
[verilator],[https://verilator.org])
|
||||
|
||||
@@ -24,6 +24,10 @@ AC_SUBST(PACKAGE_VERSION_NUMBER)
|
||||
AC_DEFINE_UNQUOTED([PACKAGE_VERSION_NUMBER_STRING],["$PACKAGE_VERSION_NUMBER"],[Package version as a number])
|
||||
VERILATOR_VERSION_INTEGER=`AS_ECHO("$PACKAGE_VERSION") | [sed 's/\([0-9]\)\.\([0-9][0-9][0-9]\) .*/\1\2000/g']`
|
||||
AC_SUBST(VERILATOR_VERSION_INTEGER)
|
||||
AC_DEFINE_UNQUOTED([PACKAGE_VERSION_STRING_CHAR],
|
||||
[static const char* const PACKAGE_STRING_UNUSED = "$PACKAGE_STRING";],
|
||||
[Package version as a number])
|
||||
AC_SUBST(PACKAGE_VERSION_STRING_CHAR)
|
||||
|
||||
# Ignore automake flags passed by Ubuntu builds
|
||||
AC_ARG_ENABLE([dependency-tracking],
|
||||
@@ -350,7 +354,7 @@ AC_SUBST(CFG_CXXFLAGS_PROFILE)
|
||||
# Macros work such that first option that passes is the one we take
|
||||
# Currently enable c++17/c++14 due to packaged SystemC dependency
|
||||
# c++17 is the newest that Verilator is regularly tested to support
|
||||
# c++11 is the oldest that Verilator supports
|
||||
# c++14 is the oldest that Verilator supports
|
||||
# gnu is required for Cygwin to compile verilated.h successfully
|
||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++20)
|
||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++20)
|
||||
@@ -358,8 +362,6 @@ _MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++17)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++17)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++14)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++14)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++11)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++11)
|
||||
AC_SUBST(CFG_CXXFLAGS_STD_NEWEST)
|
||||
|
||||
# Flags for compiling Verilator internals including parser, and Verilated files
|
||||
@@ -371,10 +373,9 @@ _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wthread-safety)
|
||||
AC_SUBST(CFG_CXXFLAGS_WEXTRA)
|
||||
|
||||
# Flags for coroutine support for dynamic scheduling
|
||||
_MY_CXX_CHECK_IFELSE(
|
||||
-fcoroutines-ts,
|
||||
[CFG_CXXFLAGS_COROUTINES="-fcoroutines-ts"],
|
||||
[CFG_CXXFLAGS_COROUTINES="-fcoroutines"])
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines-ts)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines-ts -Wno-deprecated-experimental-coroutine)
|
||||
AC_SUBST(CFG_CXXFLAGS_COROUTINES)
|
||||
|
||||
# HAVE_COROUTINES
|
||||
@@ -442,14 +443,19 @@ m4_foreach([cflag],[
|
||||
[-mno-cet],
|
||||
[-Qunused-arguments],
|
||||
[-Wno-bool-operation],
|
||||
[-Wno-tautological-bitwise-compare],
|
||||
[-Wno-c++11-narrowing],
|
||||
[-Wno-constant-logical-operand],
|
||||
[-Wno-non-pod-varargs],
|
||||
[-Wno-overloaded-virtual],
|
||||
[-Wno-parentheses-equality],
|
||||
[-Wno-shadow],
|
||||
[-Wno-sign-compare],
|
||||
[-Wno-tautological-bitwise-compare],
|
||||
[-Wno-uninitialized],
|
||||
[-Wno-unused-but-set-parameter],
|
||||
[-Wno-unused-but-set-variable],
|
||||
[-Wno-unused-parameter],
|
||||
[-Wno-unused-variable],
|
||||
[-Wno-shadow]],[
|
||||
[-Wno-unused-variable]],[
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,cflag)
|
||||
# CMake will test what flags work itself, so pass all flags through to it
|
||||
CFG_CXX_FLAGS_CMAKE="$CFG_CXX_FLAGS_CMAKE cflag"
|
||||
@@ -513,14 +519,14 @@ _MY_LDLIBS_CHECK_IFELSE(
|
||||
fi])
|
||||
AC_SUBST(CFG_LIBS)
|
||||
|
||||
# Need C++11 at least
|
||||
#Alternative: AX_CXX_COMPILE_STDCXX([11])
|
||||
# Need C++14 at least
|
||||
#Alternative: AX_CXX_COMPILE_STDCXX([14])
|
||||
AC_DEFUN([_MY_CXX_CHECK_CXX_VER],
|
||||
[# _MY_CXX_CHECK_CXX_VER(flag) -- Check if compiler runs C++11
|
||||
[# _MY_CXX_CHECK_CXX_VER(flag) -- Check if compiler runs C++14
|
||||
# Set $_my_result
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([#include <thread>
|
||||
#if (__cplusplus < 201103L)
|
||||
#if (__cplusplus < 201402L)
|
||||
# error "Too old"
|
||||
#endif
|
||||
], [[ ]])],
|
||||
@@ -536,13 +542,13 @@ AC_DEFUN([_MY_CXX_CHECK_CXX_VER],
|
||||
# Add $CFG_CXXFLAGS_STD only if can't compile correctly otherwise,
|
||||
# as adding std= when not needed can cause errors with the C++ std library.
|
||||
CFG_CXXFLAGS_STD=$CFG_CXXFLAGS_STD_NEWEST
|
||||
AC_MSG_CHECKING(whether $CXX supports C++11)
|
||||
AC_MSG_CHECKING(whether $CXX supports C++14)
|
||||
_MY_CXX_CHECK_CXX_VER()
|
||||
AC_MSG_RESULT($_my_result)
|
||||
if test "$_my_result" = "no" ; then
|
||||
CXXFLAGS="$CXXFLAGS $CFG_CXXFLAGS_STD"
|
||||
CFG_CXX_FLAGS_CMAKE="$CFG_CXX_FLAGS_CMAKE $CFG_CXXFLAGS_STD"
|
||||
AC_MSG_CHECKING(whether $CXX supports C++11 with $CFG_CXXFLAGS_STD)
|
||||
AC_MSG_CHECKING(whether $CXX supports C++14 with $CFG_CXXFLAGS_STD)
|
||||
_MY_CXX_CHECK_CXX_VER()
|
||||
AC_MSG_RESULT($_my_result)
|
||||
else
|
||||
@@ -552,13 +558,28 @@ else
|
||||
fi
|
||||
if test "$_my_result" = "no" ; then
|
||||
AC_MSG_NOTICE([[]])
|
||||
AC_MSG_ERROR([[the $CXX compiler appears to not support C++11.
|
||||
AC_MSG_ERROR([[the $CXX compiler appears to not support C++14.
|
||||
|
||||
Verilator requires a C++11 or newer compiler.]])
|
||||
Verilator requires a C++14 or newer compiler.]])
|
||||
|
||||
fi
|
||||
AC_SUBST(CFG_CXXFLAGS_STD)
|
||||
|
||||
# Compiler precompiled header options (assumes either gcc or clang++)
|
||||
AC_MSG_CHECKING([for $CXX precompile header include option])
|
||||
if $CXX --help | grep include-pch >/dev/null 2>/dev/null ; then
|
||||
# clang
|
||||
CFG_CXXFLAGS_PCH_I=-include-pch
|
||||
CFG_GCH_IF_CLANG=.gch
|
||||
else
|
||||
# GCC
|
||||
CFG_CXXFLAGS_PCH_I=-include
|
||||
CFG_GCH_IF_CLANG=
|
||||
fi
|
||||
AC_MSG_RESULT($CFG_CXXFLAGS_PCH_I)
|
||||
AC_SUBST(CFG_CXXFLAGS_PCH_I)
|
||||
AC_SUBST(CFG_GCH_IF_CLANG)
|
||||
|
||||
# Checks for library functions.
|
||||
AC_CHECK_MEMBER([struct stat.st_mtim.tv_nsec],
|
||||
[AC_DEFINE([HAVE_STAT_NSEC],[1],[Defined if struct stat has st_mtim.tv_nsec])],
|
||||
@@ -573,7 +594,7 @@ ACO_SAVE_LIBS="$LIBS"
|
||||
LIBS="$LIBS -lsystemc"
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <systemc.h>
|
||||
extern "C" int sc_main(int argc, char* argv[]) {}
|
||||
extern "C" int sc_main(int argc, char* argv[]) { return 0; }
|
||||
]],[[sc_version()]])],
|
||||
[_my_result=yes
|
||||
AC_DEFINE([HAVE_SYSTEMC],[1],[Defined if have SystemC library])],
|
||||
|
||||
@@ -19,12 +19,14 @@ Anthony Donlon
|
||||
Arkadiusz Kozdra
|
||||
Aylon Chaim Porat
|
||||
Cameron Kirk
|
||||
Chih-Mao Chen
|
||||
Chris Randall
|
||||
Chuxuan Wang
|
||||
Conor McCullough
|
||||
Dan Petrisko
|
||||
Daniel Bates
|
||||
David Horton
|
||||
David Ledger
|
||||
David Metz
|
||||
David Stanford
|
||||
David Turner
|
||||
@@ -49,6 +51,7 @@ Glen Gibb
|
||||
Gökçe Aydos
|
||||
Graham Rushton
|
||||
Guokai Chen
|
||||
Gus Smith
|
||||
Gustav Svensk
|
||||
Harald Heckmann
|
||||
Hennadii Chernyshchyk
|
||||
@@ -57,6 +60,7 @@ Huang Rui
|
||||
Huanghuang Zhou
|
||||
HungMingWu
|
||||
HyungKi Jeong
|
||||
Ícaro Lima
|
||||
Ilya Barkov
|
||||
Iru Cai
|
||||
Ivan Vnučec
|
||||
@@ -75,12 +79,14 @@ Jesse Taube
|
||||
Jevin Sweval
|
||||
Jiacheng Qian
|
||||
Jiamin Zhu
|
||||
Jinyan Xu
|
||||
Jiuyang Liu
|
||||
Joey Liu
|
||||
John Coiner
|
||||
John Demme
|
||||
John Wehle
|
||||
Jonathan Drolet
|
||||
Jordan McConnon
|
||||
Jose Loyola
|
||||
Josep Sans
|
||||
Joseph Nwabueze
|
||||
@@ -88,6 +94,7 @@ Josh Redford
|
||||
Julian Daube
|
||||
Julie Schwartz
|
||||
Julien Margetts
|
||||
Justin Thiel
|
||||
Kaleb Barrett
|
||||
Kamil Rakoczy
|
||||
Kanad Kanhere
|
||||
@@ -114,6 +121,7 @@ Martin Stadler
|
||||
Matthew Ballance
|
||||
Michael Killough
|
||||
Michaël Lefebvre
|
||||
Michal Czyz
|
||||
Mike Popoloski
|
||||
Miodrag Milanović
|
||||
Mladen Slijepcevic
|
||||
@@ -134,7 +142,9 @@ Pierre-Henri Horrein
|
||||
Pieter Kapsenberg
|
||||
Piotr Binkowski
|
||||
Qingyao Sun
|
||||
Quentin Corradi
|
||||
Rafal Kapuscik
|
||||
Rasfunk
|
||||
Raynard Qiao
|
||||
Richard Myers
|
||||
Risto Pejašinović
|
||||
@@ -179,5 +189,6 @@ Yuri Victorovich
|
||||
Yutetsu TAKATSUKASA
|
||||
Yves Mathieu
|
||||
Zhanglei Wang
|
||||
Zhou Shen
|
||||
Zixi Li
|
||||
أحمد المحمودي
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Code available from: https://verilator.org
|
||||
#
|
||||
# Copyright 2003-2023 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2024 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.
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
Verilator Documentation
|
||||
=======================
|
||||
|
||||
This folder contains sources for Verilator documentation.
|
||||
|
||||
For formatted documentation see:
|
||||
|
||||
- `Verilator README <https://github.com/verilator/verilator>`_
|
||||
|
||||
- `Verilator installation and package directory structure
|
||||
<https://verilator.org/install>`_
|
||||
|
||||
- `Verilator manual (HTML) <https://verilator.org/verilator_doc.html>`_,
|
||||
or `Verilator manual (PDF) <https://verilator.org/verilator_doc.pdf>`_
|
||||
|
||||
- `Subscribe to Verilator announcements
|
||||
<https://github.com/verilator/verilator-announce>`_
|
||||
|
||||
- `Verilator forum <https://verilator.org/forum>`_
|
||||
|
||||
- `Verilator issues <https://verilator.org/issues>`_
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# pylint: disable=C0112,C0114,C0115,C0116,C0209,C0301,R0201,R0903
|
||||
# pylint: disable=C0112,C0114,C0115,C0116,C0209,C0301,R0903
|
||||
# -*- Python -*- See copyright, etc below
|
||||
######################################################################
|
||||
|
||||
@@ -40,7 +40,7 @@ parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""Read a file and extract documentation data.""",
|
||||
epilog=
|
||||
""" Copyright 2021-2023 by Wilson Snyder. This package is free software;
|
||||
""" Copyright 2021-2024 by Wilson Snyder. This package 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.
|
||||
|
||||
@@ -55,7 +55,7 @@ parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""Post-process Sphinx HTML.""",
|
||||
epilog=
|
||||
""" Copyright 2021-2023 by Wilson Snyder. This package is free software;
|
||||
""" Copyright 2021-2024 by Wilson Snyder. This package 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.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
****************
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
# pylint: disable=C0103,C0114,C0116,C0301,E0402,W0622
|
||||
#
|
||||
# Configuration file for Verilator's Sphinx documentation builder.
|
||||
# Copyright 2003-2023 by Wilson Snyder.
|
||||
# Copyright 2003-2024 by Wilson Snyder.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
#
|
||||
# This file only contains overridden options. For a full list:
|
||||
@@ -230,4 +230,4 @@ spelling_ignore_contributor_names = True
|
||||
|
||||
breathe_projects = {"verilated": "_build/doxygen/verilated/xml/"}
|
||||
breathe_default_project = "verilated"
|
||||
breathe_default_members = ('members')
|
||||
breathe_default_members = 'members'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Connecting:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
*******************************
|
||||
|
||||
+122
-92
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
************************
|
||||
@@ -27,107 +27,137 @@ Alliance <https://chipsalliance.org>`_, `Antmicro Ltd
|
||||
<https://antmicro.com>`_ and `Shunyao CAD <https://shunyaocad.com>`_.
|
||||
|
||||
Previous major corporate sponsors of Verilator, by providing significant
|
||||
contributions of time or funds 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.,
|
||||
SiCortex Inc, and Shunyao CAD.
|
||||
contributions of time or funds include: Antmicro Ltd., Atmel Corporation,
|
||||
Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd., Hicamp
|
||||
Systems, Intel Corporation, Marvell Inc., Mindspeed Technologies Inc.,
|
||||
MicroTune Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus
|
||||
Networks Inc., SiCortex Inc, Shunyao CAD, and Western Digital Inc.
|
||||
|
||||
The contributors of major functionality are: Krzysztof
|
||||
Bieganski, Byron Bradley, 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.
|
||||
The contributors of major functionality are: Jeremy Bennett, Krzysztof
|
||||
Bieganski, Byron Bradley, Lane Brooks, John Coiner, Duane Galbi, Geza Lore,
|
||||
Todd Strader, Yutetsu Takatsukasa, Stefan Wallentowitz, Paul Wasson, Jie
|
||||
Xu, and Wilson Snyder.
|
||||
|
||||
Some of the people who have provided ideas, and feedback for Verilator
|
||||
include:
|
||||
|
||||
David Addison, Tariq B. Ahmad, Nikana Anastasiadis, Vasu Arasanipalai, Jens
|
||||
Arm, Sharad Bagri, Matthew Ballance, Andrew Bardsley, Matthew Barr, Geoff
|
||||
Barrett, Kaleb Barrett, Julius Baxter, Jeremy Bennett, Michael Berman, Jean
|
||||
Berniolles, Victor Besyakov, Moinak Bhattacharyya, Krzysztof Bieganski,
|
||||
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, Iru
|
||||
Cai, Ted Campbell, Chris Candler, Lauren Carlson, Donal Casey, Alex
|
||||
Chadwick, Marcel Chang, Aliaksei Chapyzhenka, Guokai Chen, Terry Chen,
|
||||
Yi-Chung Chen, Enzo Chi, Robert A. Clark, Ryan Clarke, Allan Cochrane, John
|
||||
Coiner, Keith Colbert, Gianfranco Costamagna, Sean Cross, George Cuan, Joe
|
||||
DErrico, Lukasz Dalek, 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, Larry
|
||||
Doolittle, Sebastian Dressler, Jonathan Drolet, 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, Bill Flynn,
|
||||
Andrea Foletto, Bob Fredieu, Duane Galbi, Mostafa Gamal, Benjamin Gartner,
|
||||
Christian Gelinek, Richard E George, Peter Gerst, Glen Gibb, Michael
|
||||
Gielda, Barbara Gigerl, Shankar Giri, Dan Gisselquist, Petr Gladkikh, Sam
|
||||
Gladstone, Mariusz Glebocki, Andrew Goessling, Amir Gonnen, Chitlesh
|
||||
Goorah, Tomasz Gorochowik, Kai Gossner, Sergi Granell, Al Grant, Nathan
|
||||
Graybeal, Alexander Grobman, Graham Rushton, Xuan Guo, Driss Hafdi, Neil
|
||||
Hamilton, James Hanlon, Oyvind Harboe, Jannis Harder, Junji Hashimoto,
|
||||
Thomas Hawkins, Mitch Hayenga, Harald Heckmann, Robert Henry, Stephen
|
||||
Henry, David Hewson, Jamey Hicks, Joel Holdsworth, Andrew Holme, Hiroki
|
||||
Honda, Alex Hornung, Pierre-Henri Horrein, David Horton, Peter Horvath, Jae
|
||||
Hossell, Kuoping Hsu, Teng Huang, Steven Hugg, Alan Hunter, James
|
||||
Hutchinson, Ehab Ibrahim, Edgar E. Iglesias, Jamie Iles, Vighnesh Iyer, Ben
|
||||
Jackson, Shareef Jalloq, Marlon James, Krzysztof Jankowski, HyungKi Jeong,
|
||||
Iztok Jeras, Alexandre Joannou, James Johnson, Christophe Joly, Franck
|
||||
Jullien, James Jung, Mike Kagen, Arthur Kahlich, Kaalia Kahn, Guy-Armand
|
||||
David Addison, Tariq B. Ahmad, Nikana Anastasiadis, John David Anglin,
|
||||
Frederic Antonin, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, Rohan
|
||||
Arshid, Gökçe Aydos, Adam Bagley, Sharad Bagri, Robert Balas, Marco
|
||||
Balboni, Matthew Ballance, Andrew Bardsley, Ilya Barkov, Matthew Barr,
|
||||
Geoff Barrett, Kaleb Barrett, Daniel Bates, Julius Baxter, Michael Berman,
|
||||
Jean Berniolles, Victor Besyakov, Narayan Bhagavatula, Moinak
|
||||
Bhattacharyya, Kritik Bhimani, David Biancolin, David Binderman, Piotr
|
||||
Binkowski, Johan Björk, David Black, Tymoteusz Blazejczyk, Scott Bleiweiss,
|
||||
David van der Bokke, Daniel Bone, Guy Bonneau, Krzysztof Boroński, Gregg
|
||||
Bouchard, Christopher Boumenot, Nick Bowler, Bryan Brady, Maarten De
|
||||
Braekeleer, Charlie Brej, J Briquet, John Brownlee, KC Buckenmaier, Jeff
|
||||
Bush, Lawrence Butcher, Tony Bybell, Iru Cai, Ted Campbell, Anthony Campos,
|
||||
Chris Candler, Lauren Carlson, Gregory Carver, Donal Casey, Sebastien Van
|
||||
Cauwenberghe, Alex Chadwick, Greg Chadwick, Marcel Chang, Aliaksei
|
||||
Chapyzhenka, Chih-Mao Chen, Guokai Chen, Terry Chen, Yi-Chung Chen, Yurii
|
||||
Cherkasov, Hennadii Chernyshchyk, Enzo Chi, Robert A. Clark, Ryan Clarke,
|
||||
Allan Cochrane, Keith Colbert, Quentin Corradi, Nassim Corteggiani,
|
||||
Gianfranco Costamagna, February Cozzocrea, Sean Cross, George Cuan, Michal
|
||||
Czyz, Joe DErrico, Jim Dai, Lukasz Dalek, Laurens van Dam, Gunter
|
||||
Dannoritzer, Ashutosh Das, Julian Daube, Bernard Deadman, Peter Debacker,
|
||||
John Demme, Mike Denio, John Deroo, Philip Derrick, Aadi Desai, John
|
||||
Dickol, Ruben Diez, Danny Ding, Jacko Dirks, Ivan Djordjevic, Brad Dobbie,
|
||||
Paul Donahue, Jonathon Donaldson, Anthony Donlon, Caleb Donovick, Larry
|
||||
Doolittle, Leendert van Doorn, Sebastian Dressler, Jonathan Drolet, Maciej
|
||||
Dudek, Alex Duller, Jeff Dutton, Tomas Dzetkulic, Usuario Eda, Charles
|
||||
Eddleston, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Trevor Elbourne,
|
||||
Mats Engstrom, Robert Farrell, Julien Faucher, Olivier Faure, Eugen Fekete,
|
||||
Fabrizio Ferrandi, Udi Finkelstein, Brian Flachs, Bill Flynn, Andrea
|
||||
Foletto, Alex Forencich, Aurelien Francillon, Bob Fredieu, Manuel
|
||||
Freiberger, Mostafa Gamal, Vito Gamberini, Mostafa Garnal, Benjamin
|
||||
Gartner, Christian Gelinek, Richard E George, Peter Gerst, Glen Gibb,
|
||||
Michael Gielda, Barbara Gigerl, Nimrod Gileadi, Shankar Giri, Dan
|
||||
Gisselquist, Petr Gladkikh, Sam Gladstone, Mariusz Glebocki, Embedded Go,
|
||||
Andrew Goessling, Amir Gonnen, Chitlesh Goorah, Tomasz Gorochowik, Kai
|
||||
Gossner, Tarik Graba, Sergi Granell, Al Grant, Nathan Graybeal, Alexander
|
||||
Grobman, Qian Gu, Xuan Guo, Prabhat Gupta, Driss Hafdi, Neil Hamilton,
|
||||
James Hanlon, Tang Haojin, Øyvind Harboe, Jannis Harder, David Harris,
|
||||
Junji Hashimoto, Thomas Hawkins, Mitch Hayenga, Harald Heckmann, Robert
|
||||
Henry, Stephen Henry, Sebastian Hesselbarth, David Hewson, Jamey Hicks,
|
||||
Joel Holdsworth, Andrew Holme, Peter Holmes, Hiroki Honda, Alex Hornung,
|
||||
Pierre-Henri Horrein, David Horton, Peter Horvath, Jae Hossell, Kuoping
|
||||
Hsu, Teng Huang, Steven Hugg, Huanghuang Zhou, Alan Hunter, James
|
||||
Hutchinson, Tim Hutt, Ehab Ibrahim, Edgar E. Iglesias, Shahid Ikram, Jamie
|
||||
Iles, Vighnesh Iyer, Ben Jackson, Daniel Jacques, Shareef Jalloq, Marlon
|
||||
James, Krzysztof Jankowski, Eyck Jentzsch, HyungKi Jeong, Iztok Jeras,
|
||||
Alexandre Joannou, James Johnson, Christophe Joly, Justin Jones,
|
||||
William D. Jones, Larry Darryl Lee Jr., Franck Jullien, James Jung,
|
||||
Yoshitomo Kaneda, Mike Kagen, Arthur Kahlich, Kaalia Kahn, Guy-Armand
|
||||
Kamendje, Vasu Kandadi, Kanad Kanhere, Patricio Kaplan, Pieter Kapsenberg,
|
||||
Rafal Kapuscik, Ralf Karge, Per Karlsson, Dan Katz, Sol Katzman, Ian
|
||||
Kennedy, Michael Killough, Sun Kim, Jonathan Kimmitt, Olof Kindgren, Kevin
|
||||
Kiningham, Dan Kirkham, Aleksander Kiryk, Sobhan Klnv, Gernot Koch, Jack
|
||||
Koenig, Soon Koh, Nathan Kohagen, Steve Kolecki, Brett Koonce, Will
|
||||
Korteland, Wojciech Koszek, Varun Koyyalagunta, Arkadiusz Kozdra, Markus
|
||||
Krause, David Kravitz, Roland Kruse, Andreas Kuster, Sergey Kvachonok,
|
||||
Charles Eric LaForest, Ed Lander, Steve Lang, Stephane Laurent, Walter
|
||||
Lavino, Christian Leber, Larry Lee, Yoda Lee, Michaël Lefebvre, 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,
|
||||
Kennedy, Ami Keren, Michael Killough, Sun Kim, Jonathan Kimmitt, Olof
|
||||
Kindgren, Kevin Kiningham, Cameron Kirk, Dan Kirkham, Aleksander Kiryk,
|
||||
Sobhan Klnv, Gernot Koch, Jack Koenig, Soon Koh, Nathan Kohagen, Steve
|
||||
Kolecki, Brett Koonce, Will Korteland, Andrei Kostovski, Wojciech Koszek,
|
||||
Varun Koyyalagunta, Arkadiusz Kozdra, Markus Krause, David Kravitz, Adam
|
||||
Krolnik, Roland Kruse, Mahesh Kumashikar, Andreas Kuster, Sergey Kvachonok,
|
||||
Charles Eric LaForest, Kevin Laeufer, Ed Lander, Steve Lang, Pierre
|
||||
Laroche, Stephane Laurent, Walter Lavino, Christian Leber, David Ledger,
|
||||
Alex Lee, Larry Lee, Yoda Lee, Michaël Lefebvre, Dag Lem, Igor Lesik, John
|
||||
Li, Kay Li, Zixi Li, Davide Libenzi, Nandor Licker, Eivind Liland, Ícaro
|
||||
Lima, Kevin Lin, Yu-Sheng Lin, Charlie Lind, Andrew Ling, Jiuyang Liu, Joey
|
||||
Liu, Paul Liu, Derek Lockhart, Jake Longo, Arthur Low, Jose Loyola, Stefan
|
||||
Ludwig, Dan Lussier, Konstantin Lübeck, Fred Ma, Liwei Ma, Duraid Madina,
|
||||
Oleh Maksymenko, Affe Mao, Julien Margetts, Chick Markley, Alexis Marquet,
|
||||
Mark Marshall, Alfonso Martinez, Unai Martinez-Corral, Adrien Le Masle,
|
||||
Yves Mathieu, Patrick Maupin, Conor McCullough, Jason McMullan, Elliot
|
||||
Mednick, David Metz, Wim Michiels, Miodrag Milanovic, Kevin Millis, Wai Sum
|
||||
Mong, Peter Monsson, Sean Moore, Dennis Muhlestein, John Murphy, Matt
|
||||
Myers, Nathan Myers, Richard Myers, Dimitris Nalbantis, Peter Nelson, Bob
|
||||
Newgard, Rachit Nigam, Paul Nitza, Yossi Nivin, Pete Nixon, Lisa Noack,
|
||||
Mark Nodine, Kuba Ober, Andreas Olofsson, Baltazar Ortiz, Aleksander Osman,
|
||||
Don Owen, James Pallister, Vassilis Papaefstathiou, Brad Parker, Morten
|
||||
Borup Petersen, Dan Petrisko, Maciej Piechotka, David Pierce, Cody
|
||||
Piersall, Michael Platzer, Dominic Plunkett, David Poole, Mike Popoloski,
|
||||
Roman Popov, Rich Porter, Stefan Post, Niranjan Prabhu, Damien Pretet, Usha
|
||||
Priyadharshini, Mark Jackson Pulver, Prateek Puri, Marshal Qiao, Nandu Raj,
|
||||
Kamil Rakoczy, Danilo Ramos, Drew Ranck, Chris Randall, Anton Rapp, Josh
|
||||
Redford, Odd Magne Reitan, Frederic Requin, Dustin Richmond, Samuel Riedel,
|
||||
Alberto Del Rio, Eric Rippey, Oleg Rodionov, Ludwig Rogiers, Paul Rolfe,
|
||||
Arjen Roodselaar, Tobias Rosenkranz, Ryszard Rozak, Huang Rui, Graham
|
||||
Rushton, Jan Egil Ruud, Denis Rystsov, John Sanguinetti, Martin Schmidt,
|
||||
Julie Schwartz, Galen Seitz, Joseph Shaker, Salman Sheikh, Hao Shi, Mike
|
||||
Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Fan Shupei, Anderson Ignacio
|
||||
da Silva, Rodney Sinclair, Ameya Vikram Singh, Steven Slatter, Mladen
|
||||
Slijepcevic, Brian Small, Garrett Smith, Tim Snyder, Wilson Snyder, Maciej
|
||||
Yves Mathieu, Vladimir Matveyenko, Patrick Maupin, Stan Mayer, Conor
|
||||
McCullough, Jason McMullan, Elliot Mednick, Yuan Mei, Andy Meier,
|
||||
Rodrigo A. Melo, Benjamin Menküc, Jake Merdich, David Metz, Wim Michiels,
|
||||
Miodrag Milanović, Darryl Miles, Kevin Millis, Andrew Miloradovsky, Wai Sum
|
||||
Mong, Peter Monsson, Sean Moore, Stuart Morris, Dennis Muhlestein, John
|
||||
Murphy, Matt Myers, Nathan Myers, Richard Myers, Alex Mykyta, Dimitris
|
||||
Nalbantis, Peter Nelson, Felix Neumärker, Bob Newgard, Cong Van Nguyen,
|
||||
Rachit Nigam, Toru Niina, Paul Nitza, Yossi Nivin, Pete Nixon, Lisa Noack,
|
||||
Mark Nodine, Michael Nolan, Andrew Nolte, Joseph Nwabueze, Kuba Ober,
|
||||
Andreas Olofsson, Baltazar Ortiz, Aleksander Osman, Don Owen, Tim Paine,
|
||||
Deepa Palaniappan, James Pallister, Vassilis Papaefstathiou, Sanggyu Park,
|
||||
Brad Parker, Risto Pejašinović, Morten Borup Petersen, Dan Petrisko, Wesley
|
||||
Piard, Maciej Piechotka, David Pierce, Cody Piersall, T. Platz, Michael
|
||||
Platzer, Dominic Plunkett, David Poole, Michael Popoloski, Roman Popov,
|
||||
Aylon Chaim Porat, Oron Port, Rich Porter, Rick Porter, Stefan Post,
|
||||
Niranjan Prabhu, Damien Pretet, Harald Pretl, Bill Pringlemeir, Usha
|
||||
Priyadharshini, Mark Jackson Pulver, Prateek Puri, Jiacheng Qian, Marshal
|
||||
Qiao, Raynard Qiao, Yujia Qiao, Jasen Qin, Frank Qiu, Nandu Raj, Kamil
|
||||
Rakoczy, Danilo Ramos, Drew Ranck, Chris Randall, Anton Rapp, Josh Redford,
|
||||
Odd Magne Reitan, Frédéric Requin, Dustin Richmond, Samuel Riedel, Alberto
|
||||
Del Rio, Eric Rippey, Oleg Rodionov, Ludwig Rogiers, Paul Rolfe, Michail
|
||||
Rontionov, Arjen Roodselaar, Tobias Rosenkranz, Yernagula Roshit, Ryszard
|
||||
Rozak, Huang Rui, Graham Rushton, Jan Egil Ruud, Denis Rystsov, Pawel
|
||||
Sagan, Robert Sammelson, John Sanguinetti, Josep Sans, Luca Sasselli,
|
||||
Martin Scharrer, Martin Schmidt, Julie Schwartz, Galen Seitz, Joseph
|
||||
Shaker, Mark Shaw, Salman Sheikh, Zhou Shen, Hao Shi, James Shi, Michael
|
||||
Shinkarovsky, Rafael Shirakawa, Jeffrey Short, S Shuba, Fan Shupei, Ethan
|
||||
Sifferman, Anderson Ignacio da Silva, Rodney Sinclair, Ameya Vikram Singh,
|
||||
Sanjay Singh, Frans Skarman, Nate Slager, Steven Slatter, Mladen
|
||||
Slijepcevic, Brian Small, Garrett Smith, Gus Smith, Tim Snyder, Maciej
|
||||
Sobkowski, Stan Sokorac, Alex Solomatnikov, Flavien Solt, Wei Song, Trefor
|
||||
Southwell, Martin Stadler, 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, Gustav Svensk, Rupert Swarbrick, Yutetsu Takatsukasa,
|
||||
Thierry Tambe, Drew Taussig, Jose Tejada, Peter Tengstrand, Wesley
|
||||
Terpstra, Rui Terra, Stefan Thiede, Gary Thomas, Ian Thompson, Kevin
|
||||
Thompson, Mike Thyer, Hans Tichelaar, Viktor Tomov, Steve Tong, Topa
|
||||
Topino, Alex Torregrosa, Michael Tresidder, David Turner, Neil Turton, Mike
|
||||
Urbach, Hans Van Antwerpen, Sebastien Van Cauwenberghe, Laurens van Dam,
|
||||
Leendert van Doorn, Cong Van Nguyen, Jan Van Winkel, Srini Vemuri, Yuri
|
||||
Victorovich, Bogdan Vukobratovic, Holger Waechtler, Philipp Wagner, Stefan
|
||||
Wallentowitz, Shawn Wang, Zhanglei Wang, Paul Wasson, Greg Waters, Thomas
|
||||
Watts, Eugene Weber, David Welch, Thomas J Whatson, Martin Whitaker, Marco
|
||||
Widmer, Leon Wildman, Daniel Wilkerson, Gerald Williams, Trevor Williams,
|
||||
Jeff Winston, Joshua Wise, Clifford Wolf, Tobias Wolfel, Johan Wouters,
|
||||
Paul Wright, Junyi Xi, Ding Xiaoliang, Jie Xu, Mandy Xu, Yinan Xu, Luke
|
||||
Yang, Amir Yazdanbakhsh, Keyi Zhang, and Xi Zhang.
|
||||
Pete Stevenson, Patrick Stewart, Rob Stoddard, Tood Strader, John Stroebel,
|
||||
Ray Strouble, Sven Stucki, Howard Su, Emerson Suguimoto, Gene Sullivan,
|
||||
Qingyao Sun, Renga Sundararajan, Kuba Sunderland-Ober, Gustav Svensk,
|
||||
Rupert Swarbrick, Jevin Sweval, Shinya T-Y, Thierry Tambe, Jesse Taube,
|
||||
Drew Taussig, Jose Tejada, Sören Tempel, Peter Tengstrand, Wesley Terpstra,
|
||||
Rui Terra, Stefan Thiede, Justin Thiel, Gary Thomas, Ian Thompson, Kevin
|
||||
Thompson, Mike Thyer, Hans Tichelaar, Tudor Timi, Viktor Tomov, Steve Tong,
|
||||
Topa Topino, Àlex Torregrosa, Topa Tota, Michael Tresidder, Lenny Truong,
|
||||
David Turner, Neil Turton, Hideto Ueno, Mike Urbach, Joel Vandergriendt,
|
||||
Srini Vemuri, Srinivasan Venkataramanan, Yuri Victorovich, Ivan Vnučec,
|
||||
Bogdan Vukobratovic, Holger Waechtler, Philipp Wagner, Johannes Walter, CY
|
||||
Wang, Chuxuan Wang, Shawn Wang, Zhanglei Wang, Greg Waters, Thomas Watts,
|
||||
Eugene Weber, John Wehle, Tianrui Wei, David Welch, Thomas J Whatson,
|
||||
Martin Whitaker, Marco Widmer, Leon Wildman, Daniel S. Wilkerson, Daniel
|
||||
Wilkerson, Gerald Williams, Trevor Williams, Don Williamson, Jan Van
|
||||
Winkel, Jeff Winston, Joshua Wise, Clifford Wolf, Johan Wouters, Paul
|
||||
Wright, Tobias Wölfel, Junyi Xi, Ding Xiaoliang, Liu Xiaoyi, Mandy Xu,
|
||||
Shanshan Xu, Yinan Xu, SU YANG, Felix Yan, Luke Yang, Amir Yazdanbakhsh,
|
||||
Chentai (Seven) Yuan, Florian Zaruba, Mat Zeno, Keyi Zhang, Xi Zhang, Yike
|
||||
Zhou, Jiamin Zhu.
|
||||
|
||||
Thanks to them, and all those we've missed mentioning above, and to those
|
||||
whom have wished to remain anonymous.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
*********
|
||||
@@ -8,7 +8,7 @@ Copyright
|
||||
The latest version of Verilator is available from `https://verilator.org
|
||||
<https://verilator.org>`_.
|
||||
|
||||
Copyright 2003-2023 by Wilson Snyder. This program is free software; you
|
||||
Copyright 2003-2024 by Wilson Snyder. This program is free software; you
|
||||
can redistribute it and/or modify the Verilator internals under the terms
|
||||
of either the GNU Lesser General Public License Version 3 or the Perl
|
||||
Artistic License Version 2.0.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
Deprecations
|
||||
@@ -8,11 +8,8 @@ The following deprecated items are scheduled for future removal:
|
||||
|
||||
C++11 compiler support
|
||||
Verilator currently requires a C++20 or newer compiler for timing, and a
|
||||
C++11 or newer compiler for no-timing.
|
||||
|
||||
Verilator will require C++14 or newer compilers for both compiling
|
||||
Verilator and compiling Verilated models with --no-timing no sooner than
|
||||
January 2023.
|
||||
C++14 or newer compiler for both compiling Verilator and compiling
|
||||
Verilated models with --no-timing.
|
||||
|
||||
Verilator will require C++20 or newer compilers for both compiling
|
||||
Verilator and compiling all Verilated models no sooner than January 2025.
|
||||
@@ -21,19 +18,3 @@ C++11 compiler support
|
||||
Verilator currently regresses both 64-bit and 32-bit pointer modes (GCC's
|
||||
`-m64` and `-m32`). Support for 32-bit `-m32` mode will be deprecated no
|
||||
sooner than January 2024.
|
||||
|
||||
Option `-O<letter>`
|
||||
The debug `-O<letter>` options have been replaced with
|
||||
`-fno-<optimization>` debug options to match GCC. The old options are
|
||||
planned for removal no sooner than June 2023.
|
||||
|
||||
Option `--prof-threads`
|
||||
The `--prof-threads` option has been superseded by the `--prof-exec` and
|
||||
`--prof-pgo` options and is planned for removal no sooner than April 2023.
|
||||
|
||||
Verilated model options `+verilator+prof+threads+*`
|
||||
The `+verilator+prof+threads+start`, `+verilator+prof+threads+window` and
|
||||
`+verilator+prof+threads+file` options have been superseded by the
|
||||
`+verilator+prof+exec+start`, `+verilator+prof+exec+window` and
|
||||
`+verilator+prof+exec+file` options respectively and are planned for removal
|
||||
no sooner than April 2023.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
Environment
|
||||
@@ -29,7 +29,7 @@ associated programs.
|
||||
.. option:: OBJCACHE
|
||||
|
||||
Optionally specifies a caching or distribution program to place in front
|
||||
of all runs of the C++ compiler. For example, "ccache". If using
|
||||
of all runs of the C++ compiler. For example, "ccache" or "sccache". If using
|
||||
:command:`distcc` or :command:`icecc`/:command:`icecream`, they would
|
||||
generally be run under :command:`ccache`; see the documentation for
|
||||
those programs. If OBJCACHE is not set, and at configure time ccache
|
||||
@@ -117,3 +117,46 @@ associated programs.
|
||||
``VERILATOR_ROOT`` to point to the new version.
|
||||
|
||||
See :ref:`Installation` for more details.
|
||||
|
||||
|
||||
Make Variables
|
||||
==============
|
||||
|
||||
This section describes the make variables used by Verilator. These may be
|
||||
set by passing them to make e.g. ``make CXX=my-gcc ...``.
|
||||
|
||||
.. option:: AR
|
||||
|
||||
Optionally overrides the default :command:`ar` (archive) binary used by
|
||||
the Verilated makefiles. If AR is not set, the version found at
|
||||
configure time is used.
|
||||
|
||||
.. option:: CXX
|
||||
|
||||
Optionally overrides the default compiler binary used by the Verilated
|
||||
makefiles. If CXX is not set, the version found at configure time is
|
||||
used. Note the default flags passed to the compiler are determined at
|
||||
configuration time, so changing the CXX compiler version using this
|
||||
variable, as opposed to passing it at configuration time, may not give
|
||||
desired results.
|
||||
|
||||
.. option:: LINK
|
||||
|
||||
Optionally overrides the default linker binary used by the Verilated
|
||||
makefiles. If LINK is not set, the version found at configure time is
|
||||
used. Note the default flags passed to the linker are determined at
|
||||
configuration time, so changing the LINK version using this variable, as
|
||||
opposed to passing it at configuration time, may not give desired
|
||||
results.
|
||||
|
||||
.. option:: PERL
|
||||
|
||||
Optionally overrides the default :command:`perl` binary used by the
|
||||
Verilated makefiles. If PERL is not set, the version found at configure
|
||||
time, and compiled into the Verilator binary, is used.
|
||||
|
||||
.. option:: PYTHON3
|
||||
|
||||
Optionally overrides the default :command:`python3` binary used by the
|
||||
Verilated makefiles. If PYTHON3 is not set, the version found at
|
||||
configure time is used.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Example Create-Binary Execution:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Example C++ Execution:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
First you need Verilator installed, see :ref:`Installation`. In brief, if
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Examples in the Distribution:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Example SystemC Execution:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Examples:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Simulation Runtime Arguments:
|
||||
@@ -64,15 +64,18 @@ Summary:
|
||||
|
||||
.. option:: +verilator+prof+threads+file+<filename>
|
||||
|
||||
Deprecated. Alias for :vlopt:`+verilator+prof+exec+file+\<filename\>`
|
||||
Removed in 5.020. Was an alias for
|
||||
:vlopt:`+verilator+prof+exec+file+\<filename\>`
|
||||
|
||||
.. option:: +verilator+prof+threads+start+<value>
|
||||
|
||||
Deprecated. Alias for :vlopt:`+verilator+prof+exec+start+\<value\>`
|
||||
Removed in 5.020. Was an alias for
|
||||
:vlopt:`+verilator+prof+exec+start+\<value\>`
|
||||
|
||||
.. option:: +verilator+prof+threads+window+<value>
|
||||
|
||||
Deprecated. Alias for :vlopt:`+verilator+prof+exec+window+\<value\>`
|
||||
Removed in 5.020. Was an alias for
|
||||
:vlopt:`+verilator+prof+exec+window+\<value\>`
|
||||
|
||||
.. option:: +verilator+prof+vlt+file+<filename>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
verilator Arguments
|
||||
@@ -1036,7 +1036,7 @@ Summary:
|
||||
|
||||
.. option:: --prof-threads
|
||||
|
||||
Deprecated. Same as --prof-exec and --prof-pgo together.
|
||||
Removed in 5.020. Was an alias for --prof-exec and --prof-pgo together.
|
||||
|
||||
.. option:: --protect-ids
|
||||
|
||||
@@ -1363,13 +1363,13 @@ Summary:
|
||||
Enable FST waveform tracing in the model. This overrides
|
||||
:vlopt:`--trace`. See also :vlopt:`--trace-threads` option.
|
||||
|
||||
.. option:: --trace-max-array *depth*
|
||||
.. option:: --trace-max-array <depth>
|
||||
|
||||
Rarely needed. Specify the maximum array depth of a signal that may be
|
||||
traced. Defaults to 32, as tracing large arrays may greatly slow traced
|
||||
simulations.
|
||||
|
||||
.. option:: --trace-max-width *width*
|
||||
.. option:: --trace-max-width <width>
|
||||
|
||||
Rarely needed. Specify the maximum bit width of a signal that may be
|
||||
traced. Defaults to 256, as tracing large vectors may greatly slow
|
||||
@@ -1386,7 +1386,7 @@ Summary:
|
||||
format constraints, this may result in significantly slower trace times
|
||||
and larger trace files.
|
||||
|
||||
.. option:: --trace-threads *threads*
|
||||
.. option:: --trace-threads <threads>
|
||||
|
||||
Enable waveform tracing using separate threads. This is typically faster
|
||||
in simulation runtime but uses more total compute. This option only
|
||||
@@ -1427,12 +1427,12 @@ Summary:
|
||||
Rarely needed. Specifies the maximum number of loop iterations that may be
|
||||
unrolled. See also :option:`BLKLOOPINIT` warning.
|
||||
|
||||
.. option:: --unroll-stmts *statements*
|
||||
.. option:: --unroll-stmts <statements>
|
||||
|
||||
Rarely needed. Specifies the maximum number of statements in a loop for
|
||||
that loop to be unrolled. See also :option:`BLKLOOPINIT` warning.
|
||||
|
||||
.. option:: --unused-regexp *regexp*
|
||||
.. option:: --unused-regexp <regexp>
|
||||
|
||||
Rarely needed. Specifies a simple regexp with \* and ? that, if a signal
|
||||
name matches, will suppress the :option:`UNUSED` warning. Defaults to
|
||||
@@ -1444,7 +1444,7 @@ Summary:
|
||||
into Verilator. (Similar to :command:`perl -V`.) See also
|
||||
:vlopt:`--getenv` option.
|
||||
|
||||
.. option:: -v *filename*
|
||||
.. option:: -v <filename>
|
||||
|
||||
Read the filename as a Verilog library. Any modules in the file may be
|
||||
used to resolve instances in the top-level module, otherwise, they are
|
||||
@@ -1481,7 +1481,7 @@ Summary:
|
||||
|
||||
Enable the use of VPI and linking against the :file:`verilated_vpi.cpp` files.
|
||||
|
||||
.. option:: --waiver-output *filename*
|
||||
.. option:: --waiver-output <filename>
|
||||
|
||||
Generate a waiver file that contains all waiver statements to suppress
|
||||
the warnings emitted during this Verilator run. This, in particular, is
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
verilator_coverage
|
||||
@@ -64,30 +64,59 @@ if there are multiple coverage points on a single line they will merge.
|
||||
The minimum coverage across all merged points will be used to report
|
||||
coverage of the line.
|
||||
|
||||
The first character of the line shows a summary of the coverage; this
|
||||
allows use of grep to filter the report. `%` indicates at least one point
|
||||
on the line was below the coverage limit. `+` indicates an
|
||||
:option:`--annotate-points` point was at or above the limit, and `-` that
|
||||
the point was below the limit.
|
||||
Coverage data is annotated at the beginning of the line and is formatted
|
||||
as a special character followed by the number of coverage hits. The special
|
||||
characters " ,%,+,-" indicate summary of the coverage, and allow use of grep
|
||||
to filter the report.
|
||||
|
||||
* " " (whitespace) indicates that all points on the line are above the coverage limit.
|
||||
* "%" indicates at least one point on the line was below the coverage limit.
|
||||
* "+" coverage point was at or above the limit. Only used with :option:`--annotate-points`.
|
||||
* "-" coverage point was below the limit. Only used with :option:`--annotate-points`.
|
||||
|
||||
.. code-block::
|
||||
|
||||
100000 input logic a; // Begins with whitespace, because
|
||||
// number of hits (100000) is above the limit.
|
||||
+100000 point: comment=a // Begins with +, because
|
||||
// number of hits (100000) is above the limit.
|
||||
%000000 input logic b; // Begins with %, because
|
||||
// number of hits (0) is below the limit.
|
||||
-000000 point: comment=b // Begins with -, because
|
||||
// number of hits (0) is below the limit.
|
||||
|
||||
.. option:: --annotate-all
|
||||
|
||||
Specifies all files should be shown. By default, only those source files
|
||||
with low coverage are written to the output directory.
|
||||
|
||||
This option should be used together with :option:`--annotate`.
|
||||
|
||||
.. option:: --annotate-min <count>
|
||||
|
||||
Specifies if the coverage point does not include the count number of
|
||||
coverage hits, then the coverage point will be considered above the
|
||||
threshold, and the coverage report will put a "%" to indicate the coverage
|
||||
is insufficient. Defaults to 10.
|
||||
Specifies the threshold (<count>) below which coverage point is considered
|
||||
sufficient. If the threshold is not exceeded, then the annotation will begin
|
||||
with a "%" symbol to indicate the coverage is insufficient.
|
||||
|
||||
The <count> threshold defaults to 10.
|
||||
|
||||
This option should be used together with :option:`--annotate`.
|
||||
|
||||
|
||||
.. option:: --annotate-points
|
||||
|
||||
Specifies all coverage points should be shown after each line of text. By
|
||||
default, only source lines are shown.
|
||||
|
||||
with low coverage are written to the output directory.
|
||||
.. code-block::
|
||||
|
||||
100000 input logic a, b, c;
|
||||
+100000 point: comment=a // These lines are only shown
|
||||
+200000 point: comment=b // with option --annotate-points
|
||||
+300000 point: comment=c // enabled.
|
||||
|
||||
|
||||
This option should be used together with :option:`--annotate`.
|
||||
|
||||
.. option:: --help
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
verilator_gantt
|
||||
@@ -30,15 +30,13 @@ Gantt Chart VCD Signals
|
||||
In waveforms, there are the following signals. In GTKWave, use "decimal"
|
||||
data format to remove the leading zeros and make the traces easier to read.
|
||||
|
||||
evals
|
||||
Increments each time when eval_step was measured to be active. This
|
||||
allow visualization of how much time eval_step was active.
|
||||
trace/section
|
||||
Shows the name of the current top of the execution section stack.
|
||||
Set GTKWave data format to "ASCII".
|
||||
|
||||
eval_loop
|
||||
Increments each time when the evaluation loop within eval_step was
|
||||
measured to be active. For best performance, there is only a single
|
||||
evaluation loop within each eval_step call; that is, the eval_loop
|
||||
waveform looks identical to the evals waveform.
|
||||
trace/depth
|
||||
Shows the depth of the execution section stack.
|
||||
Set GTKWave data format to "Analog".
|
||||
|
||||
measured_parallelism
|
||||
The number of mtasks active at this time, for best performance, this will
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
verilator_profcfunc
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
*********************************
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
*******************
|
||||
@@ -17,13 +17,21 @@ or "`ifdef`"'s may break other tools.
|
||||
|
||||
.. option:: `__LINE__
|
||||
|
||||
The :option:`\`__LINE__` define expands to the current filename as a
|
||||
string, like C++'s __LINE__. This Verilator feature added in 2006 was
|
||||
incorporated into IEEE 1800-2009.
|
||||
The :option:`\`__LINE__` define expands to the current line number like
|
||||
C++'s __LINE__. This Verilator feature added in 2006 was incorporated
|
||||
into IEEE 1800-2009.
|
||||
|
||||
.. option:: `error [string]
|
||||
|
||||
This will report an error when encountered, like C++'s #error.
|
||||
This will report an error when the preprocessor emits it, similar to
|
||||
C++'s #error.
|
||||
|
||||
.. option:: `line
|
||||
|
||||
As a special case `\`line \`__LINE__ "filename"` allows setting the
|
||||
filename, without changing the line number. This is used for some
|
||||
internal tests, so that debugging can leave the line numbers correctly
|
||||
referring to the test file's line numbers.
|
||||
|
||||
.. option:: """ [string] """
|
||||
|
||||
|
||||
+2
-8
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
******************************
|
||||
@@ -220,12 +220,6 @@ This is done for you if you are using the Verilator :vlopt:`--binary` or
|
||||
You can call :code:`->trace()` on multiple Verilated objects with the same
|
||||
trace file if you want all data to land in the same output file.
|
||||
|
||||
When using SystemC 2.3, the SystemC library must have been built with the
|
||||
experimental simulation phase callback-based tracing disabled. This is
|
||||
disabled by default when building SystemC with its configure based build
|
||||
system, but when building SystemC with CMake, you must pass
|
||||
``-DENABLE_PHASE_CALLBACKS_TRACING=OFF`` to disable this feature.
|
||||
|
||||
|
||||
How do I generate FST waveforms (traces) in C++ or SystemC?
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
@@ -401,7 +395,7 @@ How do I get faster build times?
|
||||
* 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
|
||||
ccache, sccache, distcc, or icecream packages. ccache will skip GCC runs between
|
||||
identical source builds, even across different users. If ccache was
|
||||
installed when Verilator was built, it is used, or see OBJCACHE
|
||||
environment variable to override this. Also see the
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
*****
|
||||
@@ -50,9 +50,9 @@ For --cc/--sc, it creates:
|
||||
- Make include file with class names (from --make gmake)
|
||||
* - *{prefix}*\ _hier.mk
|
||||
- Make file for hierarchy blocks (from --make gmake)
|
||||
* - *{prefix}*\ _hierMkArgs.f
|
||||
* - *{prefix}*\ __hierMkArgs.f
|
||||
- Arguments for hierarchical Verilation (from --make gmake)
|
||||
* - *{prefix}*\ _hierCMakeArgs.f
|
||||
* - *{prefix}*\ __hierCMakeArgs.f
|
||||
- Arguments for hierarchical Verilation (from --make cmake)
|
||||
* - *{prefix}*\ .h
|
||||
- Model header
|
||||
@@ -145,6 +145,10 @@ After running Make, the C++ compiler may produce the following:
|
||||
- Intermediate objects
|
||||
* - *{prefix}*\
|
||||
- Final executable (from --exe)
|
||||
* - lib\ *{prefix}*\ .a
|
||||
- Final archive (default lib mode)
|
||||
* - libverilated.a
|
||||
- Runtime for verilated model (default lib mode)
|
||||
* - *{prefix}*\ __ALL.a
|
||||
- Library of all Verilated objects
|
||||
* - *{prefix}*\ __ALL.cpp
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
######################
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _CMakeInstallation:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Installation:
|
||||
|
||||
+19
-38
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
***************
|
||||
@@ -237,11 +237,9 @@ optimizations will be disabled around the latch.
|
||||
Structures and Unions
|
||||
---------------------
|
||||
|
||||
Presently Verilator only supports packed structs and packed unions. Rand
|
||||
and randc tags on members are ignored. All structures and unions are
|
||||
represented as a single vector, which means that generating one member of a
|
||||
structure from blocking, and another from non-blocking assignments is
|
||||
unsupported.
|
||||
All structures and unions are scheduled together, which means that
|
||||
generating one member of a structure from blocking, and another from
|
||||
non-blocking assignments is unsupported.
|
||||
|
||||
|
||||
.. _Unknown States:
|
||||
@@ -320,20 +318,6 @@ there will be considered a two-state variable that is read and written
|
||||
instead of a four-state variable.
|
||||
|
||||
|
||||
Functions & Tasks
|
||||
-----------------
|
||||
|
||||
All functions and tasks will be inlined (will not become functions in C.)
|
||||
The only support provided is simple statements in tasks (which may
|
||||
affect global variables).
|
||||
|
||||
Recursive functions and tasks are not supported. All inputs and outputs
|
||||
are automatic as if they had the Verilog 2001 "automatic" keyword
|
||||
prepended. (If you don't know what this means, Verilator will do what you
|
||||
probably expect, what C does. The default behavior of Verilog is
|
||||
different.)
|
||||
|
||||
|
||||
Gate Primitives
|
||||
---------------
|
||||
|
||||
@@ -383,24 +367,6 @@ Verilator does not support SEREs yet. All assertion and coverage
|
||||
statements must be simple expressions that complete in one cycle.
|
||||
|
||||
|
||||
Force statement
|
||||
---------------
|
||||
|
||||
Verilator supports the procedural `force` (and corresponding `release`)
|
||||
statement. However, the behavior of the `force` statement does not entirely
|
||||
comply with IEEE 1800. According to the standard,
|
||||
when a procedural statement of the form `force a = b;` is executed, the
|
||||
simulation should behave as if, from that point forwards, a continuous
|
||||
assignment `assign a = b;` has been added to override the drivers of `a`.
|
||||
More specifically: the value of `a` should be updated whenever the value of
|
||||
`b` changes, until a `release a;` statement is executed.
|
||||
Verilator instead evaluates the current value of `b` when the `force`
|
||||
statement is executed, and forces `a` to that value, without updating it
|
||||
until a new `force` or `release` statement is encountered that applies to
|
||||
`a`. This non-standard behavior is nevertheless consistent with some other
|
||||
simulators.
|
||||
|
||||
|
||||
Encrypted Verilog
|
||||
-----------------
|
||||
|
||||
@@ -471,6 +437,21 @@ disable
|
||||
provide loop break and continue functionality before SystemVerilog added
|
||||
the break and continue keywords.
|
||||
|
||||
force, release
|
||||
Verilator supports the procedural `force` (and corresponding `release`)
|
||||
statement. However, the behavior of the `force` statement does not
|
||||
entirely comply with IEEE 1800. According to the standard, when a
|
||||
procedural statement of the form `force a = b;` is executed, the
|
||||
simulation should behave as if, from that point forwards, a continuous
|
||||
assignment `assign a = b;` has been added to override the drivers of `a`.
|
||||
More specifically: the value of `a` should be updated whenever the value
|
||||
of `b` changes, until a `release a;` statement is executed. Verilator
|
||||
instead evaluates the current value of `b` when the `force` statement is
|
||||
executed, and forces `a` to that value, without updating it until a new
|
||||
`force` or `release` statement is encountered that applies to `a`. This
|
||||
non-standard behavior is nevertheless consistent with some other
|
||||
simulators.
|
||||
|
||||
inside
|
||||
Inside expressions may not include unpacked array traversal or $ as an
|
||||
upper bound. Case inside and case matches are also unsupported.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
********
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Simulating:
|
||||
|
||||
+24
-13
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
**********
|
||||
@@ -7,9 +7,13 @@ Verilating
|
||||
|
||||
Verilator may be used in five major ways:
|
||||
|
||||
* With the :vlopt:`--binary` option, Verilator will translate the design
|
||||
into an executable, via generating C++ and compiling it. See
|
||||
:ref:`Binary, C++ and SystemC Generation`.
|
||||
|
||||
* With the :vlopt:`--cc` or :vlopt:`--sc` options, Verilator will translate
|
||||
the design into C++ or SystemC code, respectively. See :ref:`C++ and
|
||||
SystemC Generation`.
|
||||
the design into C++ or SystemC code, respectively. See :ref:`Binary, C++
|
||||
and SystemC Generation`.
|
||||
|
||||
* With the :vlopt:`--lint-only` option, Verilator will lint the design to
|
||||
check for warnings but will not typically create any output files.
|
||||
@@ -24,13 +28,15 @@ Verilator may be used in five major ways:
|
||||
expanded.
|
||||
|
||||
|
||||
.. _C++ and SystemC Generation:
|
||||
.. _Binary, C++ and SystemC Generation:
|
||||
|
||||
C++ and SystemC Generation
|
||||
==========================
|
||||
Binary, C++ and SystemC Generation
|
||||
==================================
|
||||
|
||||
Verilator will translate a SystemVerilog design into C++ with the
|
||||
:vlopt:`--cc` option, or into SystemC with the :vlopt:`--sc` option.
|
||||
:vlopt:`--cc` option, or into SystemC with the :vlopt:`--sc` option. It
|
||||
will translate into C++ and compile it into an executable binary with the
|
||||
:vlopt:`--binary` option.
|
||||
|
||||
When using these options:
|
||||
|
||||
@@ -45,14 +51,19 @@ When using these options:
|
||||
The prefix is set with :vlopt:`--prefix`, or defaults to the name of the
|
||||
top module.
|
||||
|
||||
#. If :vlopt:`--exe` is used, Verilator creates makefiles to generate a
|
||||
simulation executable, otherwise, it creates makefiles to generate an
|
||||
archive (.a) containing the objects.
|
||||
#. If :vlopt:`--binary` or :vlopt:`--main` is used, Verilator creates a C++
|
||||
top wrapper to read command line arguments, create the model, and
|
||||
execute the model.
|
||||
|
||||
#. If :vlopt:`--build` option was used, it calls :ref:`GNU Make` or
|
||||
:ref:`CMake` to build the model.
|
||||
#. If :vlopt:`--binary` or :vlopt:`--exe` is used, Verilator creates
|
||||
makefiles to generate a simulation executable, otherwise, it creates
|
||||
makefiles to generate an archive (.a) containing the objects.
|
||||
|
||||
Once a model is built, it is then typically run, see :ref:`Simulating`.
|
||||
#. If :vlopt:`--binary` or :vlopt:`--build` is used, it calls :ref:`GNU
|
||||
Make` or :ref:`CMake` to build the model.
|
||||
|
||||
Once a model is built, the next step is typically for the user to run it,
|
||||
see :ref:`Simulating`.
|
||||
|
||||
|
||||
.. _Hierarchical Verilation:
|
||||
|
||||
+61
-16
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2023 by Wilson Snyder.
|
||||
.. Copyright 2003-2024 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
*******************
|
||||
@@ -12,10 +12,18 @@ Disabling Warnings
|
||||
|
||||
Warnings may be disabled in multiple ways:
|
||||
|
||||
#. Disable the warning in the source code. When the warning is printed, it
|
||||
will include a warning code. Surround the offending line with a
|
||||
:code:`/*verilator&32;lint_off*/` and :code:`/*verilator&32;lint_on*/`
|
||||
metacomment pair:
|
||||
#. Disable the warning globally by invoking Verilator with the
|
||||
:code:`-Wno-{warning-code}` option.
|
||||
|
||||
Global disables should be avoided, as they removes all checking across
|
||||
the source files, and prevents other users from compiling the sources
|
||||
without knowing the magic set of disables needed to compile those
|
||||
sources successfully.
|
||||
|
||||
#. Disable the warning in the design source code. When the warning is
|
||||
printed, it will include a warning code. Surround the offending line
|
||||
with a :code:`/*verilator&32;lint_off*/` and
|
||||
:code:`/*verilator&32;lint_on*/` metacomment pair:
|
||||
|
||||
.. code-block:: sv
|
||||
|
||||
@@ -23,6 +31,12 @@ Warnings may be disabled in multiple ways:
|
||||
if (`DEF_THAT_IS_EQ_ZERO <= 3) $stop;
|
||||
// verilator lint_on UNSIGNED
|
||||
|
||||
|
||||
A lint_off in the design source code will propagate down to any child
|
||||
files (files later included by the file with the lint_off), but will not
|
||||
propagate upwards to any parent file (file that included the file with
|
||||
the lint_off).
|
||||
|
||||
#. Disable the warning using :ref:`Configuration Files` with a
|
||||
:option:`lint_off` command. This is useful when a script suppresses
|
||||
warnings, and the Verilog source should not be changed. This method also
|
||||
@@ -32,12 +46,6 @@ Warnings may be disabled in multiple ways:
|
||||
|
||||
lint_off -rule UNSIGNED -file "*/example.v" -line 1
|
||||
|
||||
#. Disable the warning globally invoking Verilator with the
|
||||
:code:`-Wno-{warning-code}` option. This should be avoided, as it
|
||||
removes all checking across the designs, and prevents other users from
|
||||
compiling your code without knowing the magic set of disables needed to
|
||||
compile your design successfully.
|
||||
|
||||
|
||||
Error And Warning Format
|
||||
========================
|
||||
@@ -1166,7 +1174,7 @@ List Of Warnings
|
||||
|
||||
Warns that a feature requires a newer standard of Verilog or SystemVerilog
|
||||
than the one specified by the :vlopt:`--language` option. For example, unsized
|
||||
unbased literals (`'0`, `'1`, `'z`, `'x`) require 1800-2005 or later.
|
||||
unbased literals (`'0`, `'1`, `'z`, `'x`) require IEEE 1800-2005 or later.
|
||||
|
||||
To avoid this warning, use a Verilog or SystemVerilog standard that
|
||||
supports the feature. Alternatively, modify your code to use a different
|
||||
@@ -1360,7 +1368,10 @@ List Of Warnings
|
||||
|
||||
.. option:: RANDC
|
||||
|
||||
Warns that the :code:`randc` keyword is unsupported and being converted
|
||||
Historical, never issued since version 5.018, when :code:`randc` became
|
||||
fully supported.
|
||||
|
||||
Warned that the :code:`randc` keyword was unsupported and was converted
|
||||
to :code:`rand`.
|
||||
|
||||
|
||||
@@ -1503,6 +1514,39 @@ List Of Warnings
|
||||
modeled values, or DPI calls.
|
||||
|
||||
|
||||
.. option:: SIDEEFFECT
|
||||
|
||||
Warns that an expression has a side effect that might not properly be
|
||||
executed by Verilator.
|
||||
|
||||
This often represents a bug in Verilator, as opposed to a bad code
|
||||
construct, however the Verilog code can typically be changed to avoid
|
||||
the warning.
|
||||
|
||||
Faulty example:
|
||||
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
:emphasize-lines: 1
|
||||
|
||||
x = y[a++];
|
||||
|
||||
This example warns because Verilator does not currently handle side
|
||||
effects inside array subscripts; the a++ may be executed multiple times.
|
||||
|
||||
Rewrite the code to avoid expression side effects, typically by using a
|
||||
temporary:
|
||||
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
|
||||
temp = a++;
|
||||
x = y[temp];
|
||||
|
||||
Ignoring this warning may make Verilator simulations differ from other
|
||||
simulators.
|
||||
|
||||
|
||||
.. option:: SPLITVAR
|
||||
|
||||
Warns that a variable with a :option:`/*verilator&32;split_var*/`
|
||||
@@ -2043,17 +2087,18 @@ List Of Warnings
|
||||
|
||||
.. include:: ../../docs/gen/ex_WIDTHEXPAND_1_fixed.rst
|
||||
|
||||
|
||||
.. option:: WIDTHTRUNC
|
||||
|
||||
A more granular WIDTH warning, for when a value is truncated
|
||||
A more granular WIDTH warning, for when a value is truncated.
|
||||
|
||||
.. option:: WIDTHEXPAND
|
||||
|
||||
A more granular WIDTH warning, for when a value is zero expanded
|
||||
A more granular WIDTH warning, for when a value is zero expanded.
|
||||
|
||||
.. option:: WIDTHXZEXPAND
|
||||
|
||||
A more granular WIDTH warning, for when a value is X/Z expanded
|
||||
A more granular WIDTH warning, for when a value is X/Z expanded.
|
||||
|
||||
.. option:: WIDTHCONCAT
|
||||
|
||||
|
||||
+22
-9
@@ -1035,11 +1035,11 @@ Coding Conventions
|
||||
==================
|
||||
|
||||
|
||||
Compiler Version and C++11
|
||||
Compiler Version and C++14
|
||||
--------------------------
|
||||
|
||||
Verilator requires C11. Verilator does not require any newer versions, but
|
||||
is maintained to build successfully with C14/C17/C20.
|
||||
Verilator requires C14. Verilator does not require any newer versions, but
|
||||
is maintained to build successfully with C17/C20.
|
||||
|
||||
|
||||
Indentation and Naming Style
|
||||
@@ -1222,9 +1222,9 @@ There are three ways data is passed between visitor functions.
|
||||
|
||||
2. User attributes. Each ``AstNode`` (**Note.** The AST node, not the
|
||||
visitor) has five user attributes, which may be accessed as an
|
||||
integer using the ``user1()`` through ``user5()`` methods, or as a
|
||||
integer using the ``user1()`` through ``user4()`` methods, or as a
|
||||
pointer (of type ``AstNUser``) using the ``user1p()`` through
|
||||
``user5p()`` methods (a common technique lifted from graph traversal
|
||||
``user4p()`` methods (a common technique lifted from graph traversal
|
||||
packages).
|
||||
|
||||
A visitor first clears the one it wants to use by calling
|
||||
@@ -1400,7 +1400,7 @@ Controlling the Test Driver
|
||||
---------------------------
|
||||
|
||||
The test driver script `driver.pl` runs tests; see the `Test Driver`
|
||||
section. The individual test drivers are written in PERL; see `Test
|
||||
section. The individual test drivers are written in Perl; see `Test
|
||||
Language`.
|
||||
|
||||
|
||||
@@ -1432,7 +1432,7 @@ Developers will also want to call ./configure with two extra flags:
|
||||
disabled by default, as SystemC installation problems would otherwise
|
||||
falsely indicate a Verilator problem.
|
||||
|
||||
When enabling the long tests, some additional PERL modules are needed,
|
||||
When enabling the long tests, some additional Perl modules are needed,
|
||||
which you can install using cpan.
|
||||
|
||||
::
|
||||
@@ -1462,6 +1462,19 @@ There are some traps to avoid when running regression tests
|
||||
system-dependent, but on Fedora Linux it would require editing the
|
||||
``/etc/security/limits.conf`` file as root.
|
||||
|
||||
Diffing generated code after changes
|
||||
------------------------------------
|
||||
|
||||
When making a change in the code generation area that should not change the
|
||||
actual emitted code, it is useful to perform a diff to make sure the emitted
|
||||
code really did not change. To do this, the top level Makefile provides the
|
||||
*test-snap* and *test-diff* targets:
|
||||
|
||||
- Run the test suite with ``make test``
|
||||
- Take a snapshot with ``make test-snap``
|
||||
- Apply your changes
|
||||
- Run the test suite again with ``make test``
|
||||
- See the changes in the output with ``make test-diff``
|
||||
|
||||
Continuous Integration
|
||||
----------------------
|
||||
@@ -1640,7 +1653,7 @@ Source file and line
|
||||
file is ``a``, the 26th is ``z``, the 27th is ``aa``, and so on.
|
||||
|
||||
User pointers
|
||||
Shows the value of the node's user1p...user5p, if non-NULL.
|
||||
Shows the value of the node's user1p...user4p, if non-NULL.
|
||||
|
||||
Data type
|
||||
Many nodes have an explicit data type. "@dt=0x..." indicates the
|
||||
@@ -2224,7 +2237,7 @@ xsim_flags / xsim_flags2 / xsim_run_flags
|
||||
Distribution
|
||||
============
|
||||
|
||||
Copyright 2008-2023 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2008-2024 by Wilson Snyder. Verilator 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.
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
ABCp
|
||||
Aadi
|
||||
Accellera
|
||||
Affe
|
||||
Aleksander
|
||||
@@ -13,21 +14,26 @@ Antonin
|
||||
Antwerpen
|
||||
Arasanipalai
|
||||
Arjen
|
||||
Arshid
|
||||
Asciidoc
|
||||
Ashutosh
|
||||
Ast
|
||||
Atmel
|
||||
Aurelien
|
||||
Bagri
|
||||
Balboni
|
||||
Baltazar
|
||||
Bardsley
|
||||
Benchmarking
|
||||
Berman
|
||||
Bhagavatula
|
||||
Bhattacharyya
|
||||
Biancolin
|
||||
Binderman
|
||||
Björk
|
||||
Bleiweiss
|
||||
Bogdan
|
||||
Bonneau
|
||||
Bouchard
|
||||
Boumenot
|
||||
Brej
|
||||
@@ -35,24 +41,31 @@ Briquet
|
||||
Brownlee
|
||||
Buckenmaier
|
||||
Bybell
|
||||
CLang
|
||||
CMake
|
||||
Cai
|
||||
Cavium
|
||||
Cfuncs
|
||||
Chandan
|
||||
Chentai
|
||||
Cherkasov
|
||||
Chih
|
||||
Chitlesh
|
||||
Christophe
|
||||
Cochrane
|
||||
Conda
|
||||
Corteggiani
|
||||
Cozzocrea
|
||||
Cuan
|
||||
Cygwin
|
||||
DErrico
|
||||
DFG
|
||||
Da
|
||||
Dai
|
||||
Danilo
|
||||
Dannoritzer
|
||||
Das
|
||||
Davide
|
||||
Dcache
|
||||
Deadman
|
||||
Debacker
|
||||
@@ -61,6 +74,7 @@ Defparams
|
||||
Denio
|
||||
Deprecations
|
||||
Deroo
|
||||
Desai
|
||||
Dickol
|
||||
Diez
|
||||
Dimitris
|
||||
@@ -69,9 +83,11 @@ Djordjevic
|
||||
Dobbie
|
||||
Dockerfile
|
||||
Donal
|
||||
Donovick
|
||||
Doorn
|
||||
Doxygen
|
||||
Dressler
|
||||
Dudek
|
||||
Duraid
|
||||
Dutton
|
||||
Dzetkulic
|
||||
@@ -89,14 +105,20 @@ Engstrom
|
||||
Enzo
|
||||
Eugen
|
||||
Fabrizio
|
||||
Faucher
|
||||
Faure
|
||||
Fekete
|
||||
Ferrandi
|
||||
Flachs
|
||||
Flavien
|
||||
Florian
|
||||
Foletto
|
||||
Forencich
|
||||
Forker
|
||||
Francillon
|
||||
Fredieu
|
||||
Freiberger
|
||||
Frédéric
|
||||
GTKWave
|
||||
Galbi
|
||||
Gantt
|
||||
@@ -116,18 +138,23 @@ Goessling
|
||||
Gonnen
|
||||
Goorah
|
||||
Gossner
|
||||
Graba
|
||||
Graphviz
|
||||
Graybeal
|
||||
Grobman
|
||||
Grulfen
|
||||
Gu
|
||||
Gunter
|
||||
Guo
|
||||
Hao
|
||||
Haojin
|
||||
Harboe
|
||||
Hashimoto
|
||||
Hayenga
|
||||
Hesselbarth
|
||||
Hewson
|
||||
Hicamp
|
||||
Hideto
|
||||
Hiroki
|
||||
Holdsworth
|
||||
Holme
|
||||
@@ -135,8 +162,10 @@ Homebrew
|
||||
Hornung
|
||||
Hossell
|
||||
Hsu
|
||||
Hutt
|
||||
Hyperthreading
|
||||
Ibrahim
|
||||
Ikram
|
||||
Iles
|
||||
Inlines
|
||||
Inout
|
||||
@@ -148,6 +177,7 @@ Jae
|
||||
Jalloq
|
||||
Jankowski
|
||||
Jannis
|
||||
Jasen
|
||||
Jens
|
||||
Jeras
|
||||
Jiuyang
|
||||
@@ -163,6 +193,7 @@ Kahn
|
||||
Kai
|
||||
Kamendje
|
||||
Kandadi
|
||||
Kaneda
|
||||
Kaplan
|
||||
Karge
|
||||
Karlsson
|
||||
@@ -178,6 +209,7 @@ Klnv
|
||||
Koenig
|
||||
Koh
|
||||
Kolecki
|
||||
Konstantin
|
||||
Koonce
|
||||
Korteland
|
||||
Koszek
|
||||
@@ -189,17 +221,23 @@ Kumashikar
|
||||
Kuoping
|
||||
Kurachi
|
||||
Laeufer
|
||||
Laroche
|
||||
Laurens
|
||||
Lavino
|
||||
Leber
|
||||
Leendert
|
||||
Lem
|
||||
Lesik
|
||||
Libenzi
|
||||
Licker
|
||||
Liland
|
||||
Liu
|
||||
Liwei
|
||||
Lockhart
|
||||
Longo
|
||||
Luca
|
||||
Lussier
|
||||
Lübeck
|
||||
MMD
|
||||
MODDUP
|
||||
MTasks
|
||||
@@ -209,10 +247,15 @@ Mahesh
|
||||
Mahmoudy
|
||||
Makefile
|
||||
Makefiles
|
||||
Maksymenko
|
||||
Markley
|
||||
Marquet
|
||||
Matveyenko
|
||||
Maupin
|
||||
Mdir
|
||||
Mednick
|
||||
Mei
|
||||
Melo
|
||||
Menküc
|
||||
Michail
|
||||
Michiels
|
||||
@@ -230,9 +273,11 @@ Mong
|
||||
Muhlestein
|
||||
Multithreaded
|
||||
Multithreading
|
||||
Mykyta
|
||||
NOUNOPTFLAT
|
||||
NaN
|
||||
Nalbantis
|
||||
Nandor
|
||||
Narayan
|
||||
Nassim
|
||||
Nauticus
|
||||
@@ -243,16 +288,20 @@ Niranjan
|
||||
Nitza
|
||||
Noack
|
||||
Nodine
|
||||
Ober
|
||||
Oleg
|
||||
Olof
|
||||
Olofsson
|
||||
Oron
|
||||
Oyvind
|
||||
PLI
|
||||
Palaniappan
|
||||
Patricio
|
||||
Petr
|
||||
Piard
|
||||
Piechotka
|
||||
Piersall
|
||||
Platz
|
||||
Platzer
|
||||
Plunkett
|
||||
Popolon
|
||||
@@ -269,6 +318,8 @@ Priyadharshini
|
||||
Pullup
|
||||
Pulver
|
||||
Puri
|
||||
Qin
|
||||
Qiu
|
||||
Questa
|
||||
Rachit
|
||||
Ralf
|
||||
@@ -278,28 +329,37 @@ Reitan
|
||||
Renga
|
||||
Requin
|
||||
Rodionov
|
||||
Rohan
|
||||
Rolfe
|
||||
Rontionov
|
||||
Roodselaar
|
||||
Roshit
|
||||
Runtime
|
||||
Ruud
|
||||
Rystsov
|
||||
STandarD
|
||||
Salman
|
||||
Sammelson
|
||||
Sanggyu
|
||||
Sanguinetti
|
||||
Sanjay
|
||||
Sasselli
|
||||
Scharrer
|
||||
Seitz
|
||||
Shahid
|
||||
Shankar
|
||||
Shanshan
|
||||
Sharad
|
||||
Shareef
|
||||
Shen
|
||||
Sheng
|
||||
Shi
|
||||
Shinkarovsky
|
||||
Shinya
|
||||
Shirakawa
|
||||
Shuba
|
||||
Shunyao
|
||||
Slager
|
||||
Slatter
|
||||
SoC
|
||||
Sobhan
|
||||
@@ -319,6 +379,7 @@ Stucki
|
||||
Su
|
||||
Suguimoto
|
||||
Sundararajan
|
||||
Sunderland
|
||||
Suse
|
||||
Syms
|
||||
Synopsys
|
||||
@@ -326,6 +387,7 @@ SystemC
|
||||
SystemVerilog
|
||||
Takatsukasa
|
||||
Tambe
|
||||
Tarik
|
||||
Tariq
|
||||
Tejada
|
||||
Tengstrand
|
||||
@@ -333,6 +395,7 @@ Terpstra
|
||||
Thiede
|
||||
Thierry
|
||||
Thyer
|
||||
Tianrui
|
||||
Tichelaar
|
||||
Timi
|
||||
Tomov
|
||||
@@ -343,9 +406,11 @@ Trefor
|
||||
Tresidder
|
||||
Tri
|
||||
Tristate
|
||||
Truong
|
||||
Turton
|
||||
UNOPTFLAT
|
||||
Ubixum
|
||||
Ueno
|
||||
Uints
|
||||
Undefines
|
||||
Unsized
|
||||
@@ -354,6 +419,7 @@ Uselib
|
||||
Usha
|
||||
Usuario
|
||||
VERILATOR
|
||||
Vandergriendt
|
||||
Vasu
|
||||
Vdeeptemp
|
||||
Vdly
|
||||
@@ -391,14 +457,20 @@ Wwarn
|
||||
XSim
|
||||
Xcelium
|
||||
Xiaoliang
|
||||
Xiaoyi
|
||||
Xuan
|
||||
Xuanqi
|
||||
Yazdanbakhsh
|
||||
Yernagula
|
||||
Yi
|
||||
Yike
|
||||
Yinan
|
||||
Yoshitomo
|
||||
Yosys
|
||||
Yu
|
||||
Yujia
|
||||
Yurii
|
||||
Zaruba
|
||||
Zhang
|
||||
abirkmanis
|
||||
accessor
|
||||
@@ -486,6 +558,7 @@ countbits
|
||||
countones
|
||||
cout
|
||||
cpp
|
||||
cppstyle
|
||||
cpu
|
||||
ctor
|
||||
ctrace
|
||||
@@ -512,6 +585,7 @@ desassign
|
||||
destructor
|
||||
detections
|
||||
dev
|
||||
devcontainer
|
||||
devel
|
||||
dir
|
||||
displayb
|
||||
@@ -520,6 +594,7 @@ doxygen
|
||||
dpiGetContext
|
||||
dpic
|
||||
dsvf
|
||||
dt
|
||||
dtor
|
||||
dumpall
|
||||
dumpfile
|
||||
@@ -669,6 +744,7 @@ libext
|
||||
libgoogle
|
||||
libsystemc
|
||||
libtcmalloc
|
||||
libverilated
|
||||
linkers
|
||||
linter
|
||||
linux
|
||||
@@ -697,6 +773,7 @@ miree
|
||||
mis
|
||||
misconnected
|
||||
misconversion
|
||||
misoptimized
|
||||
missized
|
||||
mk
|
||||
mno
|
||||
@@ -721,6 +798,7 @@ multithreading
|
||||
musl
|
||||
mutexes
|
||||
mux
|
||||
muzafferkal
|
||||
myftptoyman
|
||||
mysignal
|
||||
namespace
|
||||
@@ -759,6 +837,7 @@ pdf
|
||||
perf
|
||||
perftools
|
||||
pgo
|
||||
phelter
|
||||
picoChip
|
||||
pinIndex
|
||||
pinout
|
||||
@@ -776,6 +855,7 @@ pragma
|
||||
pragmas
|
||||
pre
|
||||
precisions
|
||||
precompiled
|
||||
predefines
|
||||
prepareClone
|
||||
prepend
|
||||
@@ -801,10 +881,12 @@ pvalue
|
||||
pwd
|
||||
py
|
||||
qrq
|
||||
qrqiuren
|
||||
radix
|
||||
randc
|
||||
randcase
|
||||
randstate
|
||||
raphmaster
|
||||
rarr
|
||||
rdtsc
|
||||
reStructuredText
|
||||
@@ -814,6 +896,7 @@ readmemb
|
||||
readmemh
|
||||
realpath
|
||||
realtime
|
||||
realtobits
|
||||
recoding
|
||||
recrem
|
||||
redeclaring
|
||||
@@ -832,6 +915,7 @@ sVerilator
|
||||
sawatzke
|
||||
sc
|
||||
scalared
|
||||
sccache
|
||||
sccanf
|
||||
seg
|
||||
setuphold
|
||||
@@ -954,7 +1038,9 @@ vlt
|
||||
vltstd
|
||||
vluint
|
||||
vpi
|
||||
vpiConstType
|
||||
vpiDefName
|
||||
vpiInstance
|
||||
vpiLeftRange
|
||||
vpiModule
|
||||
vpiSize
|
||||
@@ -984,3 +1070,5 @@ ypq
|
||||
yurivict
|
||||
zdave
|
||||
Øyvind
|
||||
Алексеевич
|
||||
Исаак
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ The XML document consists of 4 sections within the top level
|
||||
Distribution
|
||||
============
|
||||
|
||||
Copyright 2020-2023 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2020-2024 by Wilson Snyder. Verilator 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.
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "Vtop.h"
|
||||
|
||||
using namespace sc_core;
|
||||
using namespace sc_dt;
|
||||
|
||||
int sc_main(int argc, char* argv[]) {
|
||||
// This is a more complicated example, please also see the simpler examples/make_hello_c.
|
||||
@@ -52,7 +53,7 @@ int sc_main(int argc, char* argv[]) {
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
||||
// General logfile
|
||||
ios::sync_with_stdio();
|
||||
std::ios::sync_with_stdio();
|
||||
|
||||
// Define clocks
|
||||
sc_clock clk{"clk", 10, SC_NS, 0.5, 3, SC_NS, true};
|
||||
|
||||
@@ -60,8 +60,8 @@ class VlFileCopy:
|
||||
print("\t%s " % command)
|
||||
status = subprocess.call(command, shell=True)
|
||||
if status != 0:
|
||||
raise Exception("Command failed running Verilator with '" +
|
||||
command + "', stopped")
|
||||
raise RuntimeError("Command failed running Verilator with '" +
|
||||
command + "', stopped")
|
||||
|
||||
|
||||
#######################################################################
|
||||
|
||||
@@ -83,8 +83,8 @@ class VlHierGraph:
|
||||
print("\t%s " % command)
|
||||
status = subprocess.call(command, shell=True)
|
||||
if status != 0:
|
||||
raise Exception("Command failed running Verilator with '" +
|
||||
command + "', stopped")
|
||||
raise RuntimeError("Command failed running Verilator with '" +
|
||||
command + "', stopped")
|
||||
|
||||
|
||||
#######################################################################
|
||||
|
||||
+36
-36
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2024 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.
|
||||
@@ -107,16 +107,9 @@ thread_local Verilated::ThreadLocal Verilated::t_s;
|
||||
|
||||
#ifndef VL_USER_FINISH ///< Define this to override the vl_finish function
|
||||
void vl_finish(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE {
|
||||
if (false && hier) {}
|
||||
if (false && hier) {} // Unused argument
|
||||
VL_PRINTF( // Not VL_PRINTF_MT, already on main thread
|
||||
"- %s:%d: Verilog $finish\n", filename, linenum);
|
||||
if (Verilated::threadContextp()->gotFinish()) {
|
||||
VL_PRINTF( // Not VL_PRINTF_MT, already on main thread
|
||||
"- %s:%d: Second verilog $finish, exiting\n", filename, linenum);
|
||||
Verilated::runFlushCallbacks();
|
||||
Verilated::runExitCallbacks();
|
||||
std::exit(0);
|
||||
}
|
||||
Verilated::threadContextp()->gotFinish(true);
|
||||
}
|
||||
#endif
|
||||
@@ -451,6 +444,8 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
|
||||
|
||||
const int uw = VL_WORDS_I(umsbp1); // aka "m" in the algorithm
|
||||
const int vw = VL_WORDS_I(vmsbp1); // aka "n" in the algorithm
|
||||
VL_DEBUG_IFDEF(assert(uw <= VL_MULS_MAX_WORDS););
|
||||
VL_DEBUG_IFDEF(assert(vw <= VL_MULS_MAX_WORDS););
|
||||
|
||||
if (vw == 1) { // Single divisor word breaks rest of algorithm
|
||||
uint64_t k = 0;
|
||||
@@ -472,27 +467,25 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
|
||||
|
||||
// Zero for ease of debugging and to save having to zero for shifts
|
||||
// Note +1 as loop will use extra word
|
||||
for (int i = 0; i < words + 1; ++i) { un[i] = vn[i] = 0; }
|
||||
for (int i = 0; i < words + 1; ++i) un[i] = vn[i] = 0;
|
||||
|
||||
// Algorithm requires divisor MSB to be set
|
||||
// Copy and shift to normalize divisor so MSB of vn[vw-1] is set
|
||||
const int s = 31 - VL_BITBIT_I(vmsbp1 - 1); // shift amount (0...31)
|
||||
const uint32_t shift_mask = s ? 0xffffffff : 0; // otherwise >> 32 won't mask the value
|
||||
for (int i = vw - 1; i > 0; --i) {
|
||||
vn[i] = (rwp[i] << s) | (shift_mask & (rwp[i - 1] >> (32 - s)));
|
||||
}
|
||||
vn[0] = rwp[0] << s;
|
||||
|
||||
// Copy and shift dividend by same amount; may set new upper word
|
||||
if (s) {
|
||||
for (int i = vw - 1; i > 0; --i) vn[i] = (rwp[i] << s) | (rwp[i - 1] >> (32 - s));
|
||||
vn[0] = rwp[0] << s;
|
||||
un[uw] = lwp[uw - 1] >> (32 - s);
|
||||
for (int i = uw - 1; i > 0; --i) un[i] = (lwp[i] << s) | (lwp[i - 1] >> (32 - s));
|
||||
un[0] = lwp[0] << s;
|
||||
} else {
|
||||
for (int i = vw - 1; i > 0; --i) vn[i] = rwp[i];
|
||||
vn[0] = rwp[0];
|
||||
un[uw] = 0;
|
||||
for (int i = uw - 1; i > 0; --i) un[i] = lwp[i];
|
||||
un[0] = lwp[0];
|
||||
}
|
||||
for (int i = uw - 1; i > 0; --i) {
|
||||
un[i] = (lwp[i] << s) | (shift_mask & (lwp[i - 1] >> (32 - s)));
|
||||
}
|
||||
un[0] = lwp[0] << s;
|
||||
|
||||
// Main loop
|
||||
for (int j = uw - vw; j >= 0; --j) {
|
||||
@@ -536,8 +529,10 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
|
||||
|
||||
if (is_modulus) { // modulus
|
||||
// Need to reverse normalization on copy to output
|
||||
for (int i = 0; i < vw; ++i) {
|
||||
owp[i] = (un[i] >> s) | (shift_mask & (un[i + 1] << (32 - s)));
|
||||
if (s) {
|
||||
for (int i = 0; i < vw; ++i) owp[i] = (un[i] >> s) | (un[i + 1] << (32 - s));
|
||||
} else {
|
||||
for (int i = 0; i < vw; ++i) owp[i] = un[i];
|
||||
}
|
||||
for (int i = vw; i < words; ++i) owp[i] = 0;
|
||||
return owp;
|
||||
@@ -549,6 +544,8 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
|
||||
WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, const WDataInP lwp,
|
||||
const WDataInP rwp) VL_MT_SAFE {
|
||||
// obits==lbits, rbits can be different
|
||||
const int owords = VL_WORDS_I(obits);
|
||||
VL_DEBUG_IFDEF(assert(owords <= VL_MULS_MAX_WORDS););
|
||||
owp[0] = 1;
|
||||
for (int i = 1; i < VL_WORDS_I(obits); i++) owp[i] = 0;
|
||||
// cppcheck-has-bug-suppress variableScope
|
||||
@@ -560,11 +557,11 @@ WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, const WDataInP lw
|
||||
for (int bit = 0; bit < rbits; bit++) {
|
||||
if (bit > 0) { // power = power*power
|
||||
VL_ASSIGN_W(obits, lastpowstore, powstore);
|
||||
VL_MUL_W(VL_WORDS_I(obits), powstore, lastpowstore, lastpowstore);
|
||||
VL_MUL_W(owords, powstore, lastpowstore, lastpowstore);
|
||||
}
|
||||
if (VL_BITISSET_W(rwp, bit)) { // out *= power
|
||||
VL_ASSIGN_W(obits, lastoutstore, owp);
|
||||
VL_MUL_W(VL_WORDS_I(obits), owp, lastoutstore, powstore);
|
||||
VL_MUL_W(owords, owp, lastoutstore, powstore);
|
||||
}
|
||||
}
|
||||
return owp;
|
||||
@@ -576,7 +573,10 @@ WDataOutP VL_POW_WWQ(int obits, int lbits, int rbits, WDataOutP owp, const WData
|
||||
return VL_POW_WWW(obits, lbits, rbits, owp, lwp, rhsw);
|
||||
}
|
||||
QData VL_POW_QQW(int, int, int rbits, QData lhs, const WDataInP rwp) VL_MT_SAFE {
|
||||
// Skip check for rhs == 0, as short-circuit doesn't save time
|
||||
const int rwords = VL_WORDS_I(rbits);
|
||||
EData rnz = rwp[0];
|
||||
for (int w = 1; w < rwords; ++w) rnz |= rwp[w];
|
||||
if (!rnz) return 1; // rwp == 0
|
||||
if (VL_UNLIKELY(lhs == 0)) return 0;
|
||||
QData power = lhs;
|
||||
QData result = 1ULL;
|
||||
@@ -657,8 +657,10 @@ double VL_ITOR_D_W(int lbits, const WDataInP lwp) VL_PURE {
|
||||
}
|
||||
double VL_ISTOR_D_W(int lbits, const WDataInP lwp) VL_MT_SAFE {
|
||||
if (!VL_SIGN_W(lbits, lwp)) return VL_ITOR_D_W(lbits, lwp);
|
||||
const int words = VL_WORDS_I(lbits);
|
||||
VL_DEBUG_IFDEF(assert(words <= VL_MULS_MAX_WORDS););
|
||||
uint32_t pos[VL_MULS_MAX_WORDS + 1]; // Fixed size, as MSVC++ doesn't allow [words] here
|
||||
VL_NEGATE_W(VL_WORDS_I(lbits), pos, lwp);
|
||||
VL_NEGATE_W(words, pos, lwp);
|
||||
_vl_clean_inplace_w(lbits, pos);
|
||||
return -VL_ITOR_D_W(lbits, pos);
|
||||
}
|
||||
@@ -2094,7 +2096,7 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) {
|
||||
|
||||
if (VL_UNLIKELY(m_end != ~0ULL && m_addr <= m_end && !m_anyAddr)) {
|
||||
VL_WARN_MT(m_filename.c_str(), m_linenum, "",
|
||||
"$readmem file ended before specified final address (IEEE 2017 21.4)");
|
||||
"$readmem file ended before specified final address (IEEE 1800-2017 21.4)");
|
||||
}
|
||||
|
||||
return false; // EOF
|
||||
@@ -2710,14 +2712,11 @@ void VerilatedContextImp::commandArgVl(const std::string& arg) {
|
||||
"Exiting due to command line argument (not an error)");
|
||||
} else if (arg == "+verilator+noassert") {
|
||||
assertOn(false);
|
||||
} else if (commandArgVlUint64(arg, "+verilator+prof+exec+start+", u64)
|
||||
|| commandArgVlUint64(arg, "+verilator+prof+threads+start+", u64)) {
|
||||
} else if (commandArgVlUint64(arg, "+verilator+prof+exec+start+", u64)) {
|
||||
profExecStart(u64);
|
||||
} else if (commandArgVlUint64(arg, "+verilator+prof+exec+window+", u64, 1)
|
||||
|| commandArgVlUint64(arg, "+verilator+prof+threads+window+", u64, 1)) {
|
||||
} else if (commandArgVlUint64(arg, "+verilator+prof+exec+window+", u64, 1)) {
|
||||
profExecWindow(u64);
|
||||
} else if (commandArgVlString(arg, "+verilator+prof+exec+file+", str)
|
||||
|| commandArgVlString(arg, "+verilator+prof+threads+file+", str)) {
|
||||
} else if (commandArgVlString(arg, "+verilator+prof+exec+file+", str)) {
|
||||
profExecFilename(str);
|
||||
} else if (commandArgVlString(arg, "+verilator+prof+vlt+file+", str)) {
|
||||
profVltFilename(str);
|
||||
@@ -3024,6 +3023,7 @@ void Verilated::endOfEval(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
|
||||
// It should be ok to call into endOfEvalGuts, it returns immediately
|
||||
// if there are no transactions.
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("End-of-eval cleanup\n"););
|
||||
VerilatedThreadMsgQueue::flush(evalMsgQp);
|
||||
evalMsgQp->process();
|
||||
}
|
||||
|
||||
@@ -3248,11 +3248,11 @@ void VlDeleter::deleteAll() VL_EXCLUDES(m_mutex) VL_EXCLUDES(m_deleteMutex) VL_M
|
||||
VerilatedLockGuard lock{m_mutex};
|
||||
if (m_newGarbage.empty()) break;
|
||||
m_deleteMutex.lock();
|
||||
std::swap(m_newGarbage, m_toDelete);
|
||||
std::swap(m_newGarbage, m_deleteNow);
|
||||
// m_mutex is unlocked here, so destructors can enqueue new objects
|
||||
}
|
||||
for (VlDeletable* const objp : m_toDelete) delete objp;
|
||||
m_toDelete.clear();
|
||||
for (VlDeletable* const objp : m_deleteNow) delete objp;
|
||||
m_deleteNow.clear();
|
||||
m_deleteMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
+9
-4
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2024 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.
|
||||
@@ -133,7 +133,8 @@ enum VerilatedVarType : uint8_t {
|
||||
VLVT_UINT32, // AKA IData
|
||||
VLVT_UINT64, // AKA QData
|
||||
VLVT_WDATA, // AKA WData
|
||||
VLVT_STRING // C++ string
|
||||
VLVT_STRING, // C++ string
|
||||
VLVT_REAL // AKA double
|
||||
};
|
||||
|
||||
enum VerilatedVarFlags {
|
||||
@@ -164,7 +165,9 @@ inline constexpr size_t roundUpToMultipleOf(size_t value) {
|
||||
// Return current thread ID (or 0), not super fast, cache if needed
|
||||
extern uint32_t VL_THREAD_ID() VL_MT_SAFE;
|
||||
|
||||
#ifndef VL_LOCK_SPINS
|
||||
#define VL_LOCK_SPINS 50000 /// Number of times to spin for a mutex before yielding
|
||||
#endif
|
||||
|
||||
/// Mutex, wrapped to allow -fthread_safety checks
|
||||
class VL_CAPABILITY("mutex") VerilatedMutex final {
|
||||
@@ -624,8 +627,9 @@ class VerilatedScope final {
|
||||
public:
|
||||
enum Type : uint8_t {
|
||||
SCOPE_MODULE,
|
||||
SCOPE_OTHER
|
||||
}; // Type of a scope, currently module is only interesting
|
||||
SCOPE_OTHER,
|
||||
SCOPE_PACKAGE
|
||||
}; // Type of a scope, currently only module and package are interesting
|
||||
private:
|
||||
// Fastpath:
|
||||
VerilatedSyms* m_symsp = nullptr; // Symbol table
|
||||
@@ -919,6 +923,7 @@ public:
|
||||
|
||||
// Internal: Called at end of each thread mtask, before finishing eval
|
||||
static void endOfThreadMTask(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
|
||||
mtaskId(0);
|
||||
if (VL_UNLIKELY(t_s.t_endOfEvalReqd)) endOfThreadMTaskGuts(evalMsgQp);
|
||||
}
|
||||
// Internal: Called at end of eval loop
|
||||
|
||||
+54
-16
@@ -2,13 +2,16 @@
|
||||
######################################################################
|
||||
# DESCRIPTION: Makefile commands for all verilated target files
|
||||
#
|
||||
# Copyright 2003-2023 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2024 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
|
||||
######################################################################
|
||||
|
||||
# Tool names.
|
||||
# These are computed at configuration time, and most are not ?=
|
||||
# to avoid picking up potentially incorrect Make implicit variables
|
||||
AR = @AR@
|
||||
CXX = @CXX@
|
||||
LINK = @CXX@
|
||||
@@ -16,6 +19,7 @@ OBJCACHE ?= @OBJCACHE@
|
||||
PERL = @PERL@
|
||||
PYTHON3 = @PYTHON3@
|
||||
|
||||
# Configuration time options
|
||||
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
|
||||
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
|
||||
|
||||
@@ -31,6 +35,12 @@ CFG_CXXFLAGS_NO_UNUSED = @CFG_CXXFLAGS_NO_UNUSED@
|
||||
CFG_CXXFLAGS_WEXTRA = @CFG_CXXFLAGS_WEXTRA@
|
||||
# Compiler flags that enable coroutine support
|
||||
CFG_CXXFLAGS_COROUTINES = @CFG_CXXFLAGS_COROUTINES@
|
||||
# Compiler flags when creating a precompiled header
|
||||
CFG_CXXFLAGS_PCH = -x c++-header
|
||||
# Compiler option to put in front of filename to read precompiled header
|
||||
CFG_CXXFLAGS_PCH_I = @CFG_CXXFLAGS_PCH_I@
|
||||
# Compiler's filename prefix for precompiled headers, .gch if clang, empty if GCC
|
||||
CFG_GCH_IF_CLANG = @CFG_GCH_IF_CLANG@
|
||||
# Linker flags
|
||||
CFG_LDFLAGS_VERILATED = @CFG_LDFLAGS_VERILATED@
|
||||
# Linker libraries for multithreading
|
||||
@@ -43,6 +53,12 @@ VERILATOR_COVERAGE = $(PERL) $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||
VERILATOR_INCLUDER = $(PYTHON3) $(VERILATOR_ROOT)/bin/verilator_includer
|
||||
VERILATOR_CCACHE_REPORT = $(PYTHON3) $(VERILATOR_ROOT)/bin/verilator_ccache_report
|
||||
|
||||
######################################################################
|
||||
# CCACHE flags (via environment as no command line option available)
|
||||
|
||||
CCACHE_SLOPPINESS ?= pch_defines,time_macros
|
||||
export CCACHE_SLOPPINESS
|
||||
|
||||
######################################################################
|
||||
# Make checks
|
||||
|
||||
@@ -138,7 +154,7 @@ ifeq ($(VM_SC),1)
|
||||
LDFLAGS += $(SYSTEMC_CXX_FLAGS) $(addprefix -L, $(SYSTEMC_LIBDIR))
|
||||
SC_LIBS = -lsystemc
|
||||
ifneq ($(wildcard $(SYSTEMC_LIBDIR)/*numeric_bit*),)
|
||||
# Systemc 1.2.1beta
|
||||
# SystemC 1.2.1beta
|
||||
SC_LIBS += -lnumeric_bit -lqt
|
||||
endif
|
||||
endif
|
||||
@@ -162,11 +178,17 @@ endif
|
||||
VM_FAST += $(VM_CLASSES_FAST) $(VM_SUPPORT_FAST)
|
||||
VM_SLOW += $(VM_CLASSES_SLOW) $(VM_SUPPORT_SLOW)
|
||||
|
||||
# Precompiled header filename
|
||||
VK_PCH_H = $(VM_PREFIX)__pch.h
|
||||
# Compiler read-a-precompiled-header option for precompiled header filename
|
||||
VK_PCH_I_FAST = $(CFG_CXXFLAGS_PCH_I) $(VM_PREFIX)__pch.h.fast$(CFG_GCH_IF_CLANG)
|
||||
VK_PCH_I_SLOW = $(CFG_CXXFLAGS_PCH_I) $(VM_PREFIX)__pch.h.slow$(CFG_GCH_IF_CLANG)
|
||||
|
||||
#######################################################################
|
||||
### Overall Objects Linking
|
||||
|
||||
VK_FAST_OBJS = $(addsuffix .o, $(VM_FAST))
|
||||
VK_SLOW_OBJS = $(addsuffix .o, $(VM_SLOW))
|
||||
VK_OBJS_FAST = $(addsuffix .o, $(VM_FAST))
|
||||
VK_OBJS_SLOW = $(addsuffix .o, $(VM_SLOW))
|
||||
|
||||
VK_USER_OBJS = $(addsuffix .o, $(VM_USER_CLASSES))
|
||||
|
||||
@@ -193,7 +215,7 @@ else
|
||||
# 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)
|
||||
VK_OBJS += $(VK_OBJS_FAST) $(VK_OBJS_SLOW)
|
||||
endif
|
||||
|
||||
# When archiving just objects (.o), use single $(AR) run
|
||||
@@ -237,18 +259,32 @@ $(VM_PREFIX)__ALL.a: $(VK_OBJS) $(VM_HIER_LIBS)
|
||||
### Compile rules
|
||||
|
||||
ifneq ($(VM_DEFAULT_RULES),0)
|
||||
# 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.
|
||||
# We put OPT_FAST/OPT_SLOW/OPT_GLOBAL before the other flags to
|
||||
# Compilation rule for anything not in $(VK_OBJS_FAST), $(VK_OBJS_SLOW), or
|
||||
# $(VK_GLOBAL_OBJS) including verilated.o. This typically means user files
|
||||
# passed on the Verilator command line.
|
||||
#
|
||||
# These rules put OPT_FAST/OPT_SLOW/OPT_GLOBAL before the other flags to
|
||||
# allow USER_CPPFLAGS to override them
|
||||
%.o: %.cpp
|
||||
$(OBJCACHE) $(CXX) $(OPT_FAST) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
|
||||
$(VK_SLOW_OBJS): %.o: %.cpp
|
||||
$(OBJCACHE) $(CXX) $(OPT_SLOW) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
$(VK_OBJS_FAST): %.o: %.cpp $(VK_PCH_H).fast.gch
|
||||
$(OBJCACHE) $(CXX) $(OPT_FAST) $(CXXFLAGS) $(CPPFLAGS) $(VK_PCH_I_FAST) -c -o $@ $<
|
||||
|
||||
$(VK_OBJS_SLOW): %.o: %.cpp $(VK_PCH_H).slow.gch
|
||||
$(OBJCACHE) $(CXX) $(OPT_SLOW) $(CXXFLAGS) $(CPPFLAGS) $(VK_PCH_I_SLOW) -c -o $@ $<
|
||||
|
||||
$(VK_GLOBAL_OBJS): %.o: %.cpp
|
||||
$(OBJCACHE) $(CXX) $(OPT_GLOBAL) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
|
||||
# Precompile a header file
|
||||
# PCH's compiler flags must match exactly the rules' above FAST/SLOW
|
||||
# arguments used for the .cpp files, or the PCH file won't be used.
|
||||
%.fast.gch: %
|
||||
$(OBJCACHE) $(CXX) $(OPT_FAST) $(CXXFLAGS) $(CPPFLAGS) $(CFG_CXXFLAGS_PCH) $< -o $@
|
||||
%.slow.gch: %
|
||||
$(OBJCACHE) $(CXX) $(OPT_SLOW) $(CXXFLAGS) $(CPPFLAGS) $(CFG_CXXFLAGS_PCH) $< -o $@
|
||||
|
||||
endif
|
||||
|
||||
#Default rule embedded in make:
|
||||
@@ -296,19 +332,21 @@ endif
|
||||
|
||||
debug-make::
|
||||
@echo
|
||||
@echo CXXFLAGS: $(CXXFLAGS)
|
||||
@echo CPPFLAGS: $(CPPFLAGS)
|
||||
@echo CXXFLAGS: $(CXXFLAGS)
|
||||
@echo OPT_FAST: $(OPT_FAST)
|
||||
@echo OPT_SLOW: $(OPT_SLOW)
|
||||
@echo VM_PREFIX: $(VM_PREFIX)
|
||||
@echo VM_PARALLEL_BUILDS: $(VM_PARALLEL_BUILDS)
|
||||
@echo VK_OBJS: $(VK_OBJS)
|
||||
@echo VK_OBJS_FAST: $(VK_OBJS_FAST)
|
||||
@echo VK_OBJS_SLOW: $(VK_OBJS_SLOW)
|
||||
@echo VM_CLASSES_FAST: $(VM_CLASSES_FAST)
|
||||
@echo VM_CLASSES_SLOW: $(VM_CLASSES_SLOW)
|
||||
@echo VM_SUPPORT_FAST: $(VM_SUPPORT_FAST)
|
||||
@echo VM_SUPPORT_SLOW: $(VM_SUPPORT_SLOW)
|
||||
@echo VM_GLOBAL_FAST: $(VM_GLOBAL_FAST)
|
||||
@echo VM_GLOBAL_SLOW: $(VM_GLOBAL_SLOW)
|
||||
@echo VK_OBJS: $(VK_OBJS)
|
||||
@echo VM_PARALLEL_BUILDS: $(VM_PARALLEL_BUILDS)
|
||||
@echo VM_PREFIX: $(VM_PREFIX)
|
||||
@echo VM_SUPPORT_FAST: $(VM_SUPPORT_FAST)
|
||||
@echo VM_SUPPORT_SLOW: $(VM_SUPPORT_SLOW)
|
||||
@echo
|
||||
|
||||
######################################################################
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2024 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.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2024 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.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2023 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2024 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.
|
||||
@@ -211,7 +211,7 @@ private:
|
||||
std::string result = prefix + "*" + suffix;
|
||||
|
||||
// std::cout << "\nch pre=" << prefix << " s=" << suffix << "\nch a="
|
||||
// << old << "\nch b=" << add << "\ncho=" << result << std::endl;
|
||||
// << old << "\nch b=" << add << "\ncho=" << result << "\n";
|
||||
return result;
|
||||
}
|
||||
bool itemMatchesString(VerilatedCovImpItem* itemp, const std::string& match)
|
||||
@@ -337,7 +337,7 @@ public:
|
||||
const std::string key = keys[i];
|
||||
if (!keys[i].empty()) {
|
||||
const std::string val = valps[i];
|
||||
// std::cout << " " << __FUNCTION__ << " " << key << " = " << val << std::endl;
|
||||
// std::cout << " " << __FUNCTION__ << " " << key << " = " << val << "\n";
|
||||
m_insertp->m_keys[addKeynum] = valueIndex(key);
|
||||
m_insertp->m_vals[addKeynum] = valueIndex(val);
|
||||
++addKeynum;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2023 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2024 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.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2023 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2024 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.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2009-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2024 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.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2024 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.
|
||||
|
||||
+116
-107
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2023 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2024 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.
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
// clang-format off
|
||||
|
||||
#define __STDC_LIMIT_MACROS // UINT64_MAX
|
||||
#include "verilated.h"
|
||||
#include "verilated_fst_c.h"
|
||||
|
||||
@@ -40,6 +39,7 @@
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||
# include <io.h>
|
||||
@@ -50,33 +50,10 @@
|
||||
// clang-format on
|
||||
|
||||
//=============================================================================
|
||||
// Check that vltscope_t matches fstScopeType
|
||||
// Check that forward declared types matches the FST API types
|
||||
|
||||
static_assert(static_cast<int>(FST_ST_VCD_MODULE) == static_cast<int>(VLT_TRACE_SCOPE_MODULE),
|
||||
"VLT_TRACE_SCOPE_MODULE mismatches");
|
||||
static_assert(static_cast<int>(FST_ST_VCD_TASK) == static_cast<int>(VLT_TRACE_SCOPE_TASK),
|
||||
"VLT_TRACE_SCOPE_TASK mismatches");
|
||||
static_assert(static_cast<int>(FST_ST_VCD_FUNCTION) == static_cast<int>(VLT_TRACE_SCOPE_FUNCTION),
|
||||
"VLT_TRACE_SCOPE_FUNCTION mismatches");
|
||||
static_assert(static_cast<int>(FST_ST_VCD_BEGIN) == static_cast<int>(VLT_TRACE_SCOPE_BEGIN),
|
||||
"VLT_TRACE_SCOPE_BEGIN mismatches");
|
||||
static_assert(static_cast<int>(FST_ST_VCD_FORK) == static_cast<int>(VLT_TRACE_SCOPE_FORK),
|
||||
"VLT_TRACE_SCOPE_FORK mismatches");
|
||||
static_assert(static_cast<int>(FST_ST_VCD_GENERATE) == static_cast<int>(VLT_TRACE_SCOPE_GENERATE),
|
||||
"VLT_TRACE_SCOPE_GENERATE mismatches");
|
||||
static_assert(static_cast<int>(FST_ST_VCD_STRUCT) == static_cast<int>(VLT_TRACE_SCOPE_STRUCT),
|
||||
"VLT_TRACE_SCOPE_STRUCT mismatches");
|
||||
static_assert(static_cast<int>(FST_ST_VCD_UNION) == static_cast<int>(VLT_TRACE_SCOPE_UNION),
|
||||
"VLT_TRACE_SCOPE_UNION mismatches");
|
||||
static_assert(static_cast<int>(FST_ST_VCD_CLASS) == static_cast<int>(VLT_TRACE_SCOPE_CLASS),
|
||||
"VLT_TRACE_SCOPE_CLASS mismatches");
|
||||
static_assert(static_cast<int>(FST_ST_VCD_INTERFACE)
|
||||
== static_cast<int>(VLT_TRACE_SCOPE_INTERFACE),
|
||||
"VLT_TRACE_SCOPE_INTERFACE mismatches");
|
||||
static_assert(static_cast<int>(FST_ST_VCD_PACKAGE) == static_cast<int>(VLT_TRACE_SCOPE_PACKAGE),
|
||||
"VLT_TRACE_SCOPE_PACKAGE mismatches");
|
||||
static_assert(static_cast<int>(FST_ST_VCD_PROGRAM) == static_cast<int>(VLT_TRACE_SCOPE_PROGRAM),
|
||||
"VLT_TRACE_SCOPE_PROGRAM mismatches");
|
||||
static_assert(std::is_same<vlFstHandle, fstHandle>::value, "vlFstHandle mismatch");
|
||||
static_assert(std::is_same<vlFstEnumHandle, fstEnumHandle>::value, "vlFstHandle mismatch");
|
||||
|
||||
//=============================================================================
|
||||
// Specialization of the generics for this trace format
|
||||
@@ -104,19 +81,11 @@ void VerilatedFst::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
fstWriterSetPackType(m_fst, FST_WR_PT_LZ4);
|
||||
fstWriterSetTimescaleFromString(m_fst, timeResStr().c_str()); // lintok-begin-on-ref
|
||||
if (m_useFstWriterThread) fstWriterSetParallelMode(m_fst, 1);
|
||||
constDump(true); // First dump must contain the const signals
|
||||
fullDump(true); // First dump must be full for fst
|
||||
|
||||
m_curScope.clear();
|
||||
|
||||
Super::traceInit();
|
||||
|
||||
// Clear the scope stack
|
||||
auto it = m_curScope.begin();
|
||||
while (it != m_curScope.end()) {
|
||||
fstWriterSetUpscope(m_fst);
|
||||
it = m_curScope.erase(it);
|
||||
}
|
||||
|
||||
// convert m_code2symbol into an array for fast lookup
|
||||
if (!m_symbolp) {
|
||||
m_symbolp = new fstHandle[nextCode()]{0};
|
||||
@@ -154,102 +123,142 @@ void VerilatedFst::declDTypeEnum(int dtypenum, const char* name, uint32_t elemen
|
||||
m_local2fstdtype[dtypenum] = enumNum;
|
||||
}
|
||||
|
||||
void VerilatedFst::declare(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, bool bussed, int msb,
|
||||
int lsb) {
|
||||
// TODO: should return std::optional<fstScopeType>, but I can't have C++17
|
||||
static std::pair<bool, fstScopeType> toFstScopeType(VerilatedTracePrefixType type) {
|
||||
switch (type) {
|
||||
case VerilatedTracePrefixType::SCOPE_MODULE: return {true, FST_ST_VCD_MODULE};
|
||||
case VerilatedTracePrefixType::SCOPE_INTERFACE: return {true, FST_ST_VCD_INTERFACE};
|
||||
case VerilatedTracePrefixType::STRUCT_PACKED:
|
||||
case VerilatedTracePrefixType::STRUCT_UNPACKED: return {true, FST_ST_VCD_STRUCT};
|
||||
case VerilatedTracePrefixType::UNION_PACKED: return {true, FST_ST_VCD_UNION};
|
||||
default: return {false, /* unused so whatever, just need a value */ FST_ST_VCD_SCOPE};
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedFst::pushPrefix(const std::string& name, VerilatedTracePrefixType type) {
|
||||
const std::string newPrefix = m_prefixStack.back().first + name;
|
||||
const auto pair = toFstScopeType(type);
|
||||
const bool properScope = pair.first;
|
||||
const fstScopeType scopeType = pair.second;
|
||||
m_prefixStack.emplace_back(newPrefix + (properScope ? " " : ""), type);
|
||||
if (properScope) {
|
||||
const std::string scopeName = lastWord(newPrefix);
|
||||
fstWriterSetScope(m_fst, scopeType, scopeName.c_str(), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedFst::popPrefix() {
|
||||
const bool properScope = toFstScopeType(m_prefixStack.back().second).first;
|
||||
if (properScope) fstWriterSetUpscope(m_fst);
|
||||
m_prefixStack.pop_back();
|
||||
assert(!m_prefixStack.empty());
|
||||
}
|
||||
|
||||
void VerilatedFst::declare(uint32_t code, const char* name, int dtypenum,
|
||||
VerilatedTraceSigDirection direction, VerilatedTraceSigKind kind,
|
||||
VerilatedTraceSigType type, bool array, int arraynum, bool bussed,
|
||||
int msb, int lsb) {
|
||||
const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1;
|
||||
|
||||
const bool enabled = Super::declCode(code, name, bits, false);
|
||||
const std::string hierarchicalName = m_prefixStack.back().first + name;
|
||||
|
||||
const bool enabled = Super::declCode(code, hierarchicalName, bits);
|
||||
if (!enabled) return;
|
||||
|
||||
std::string nameasstr = namePrefix() + name;
|
||||
std::istringstream nameiss{nameasstr};
|
||||
std::istream_iterator<std::string> beg(nameiss);
|
||||
std::istream_iterator<std::string> end;
|
||||
std::list<std::string> tokens(beg, end); // Split name
|
||||
std::string symbol_name{tokens.back()};
|
||||
tokens.pop_back(); // Remove symbol name from hierarchy
|
||||
std::string tmpModName;
|
||||
|
||||
// Find point where current and new scope diverge
|
||||
auto cur_it = m_curScope.begin();
|
||||
auto new_it = tokens.begin();
|
||||
while (cur_it != m_curScope.end() && new_it != tokens.end()) {
|
||||
if (*cur_it != *new_it) break;
|
||||
++cur_it;
|
||||
++new_it;
|
||||
}
|
||||
|
||||
// Go back to the common point
|
||||
while (cur_it != m_curScope.end()) {
|
||||
fstWriterSetUpscope(m_fst);
|
||||
cur_it = m_curScope.erase(cur_it);
|
||||
}
|
||||
|
||||
// Follow the hierarchy of the new variable from the common scope point
|
||||
while (new_it != tokens.end()) {
|
||||
if ((new_it->back() & 0x80)) {
|
||||
tmpModName = *new_it;
|
||||
tmpModName.pop_back();
|
||||
// If the scope ends with a non-ASCII character, it will be 0x80 + fstScopeType
|
||||
fstWriterSetScope(m_fst, static_cast<fstScopeType>(new_it->back() & 0x7f),
|
||||
tmpModName.c_str(), nullptr);
|
||||
} else {
|
||||
fstWriterSetScope(m_fst, FST_ST_VCD_SCOPE, new_it->c_str(), nullptr);
|
||||
}
|
||||
m_curScope.push_back(*new_it);
|
||||
new_it = tokens.erase(new_it);
|
||||
}
|
||||
|
||||
assert(hierarchicalName.rfind(' ') != std::string::npos);
|
||||
std::stringstream name_ss;
|
||||
name_ss << symbol_name;
|
||||
name_ss << lastWord(hierarchicalName);
|
||||
if (array) name_ss << "[" << arraynum << "]";
|
||||
if (bussed) name_ss << " [" << msb << ":" << lsb << "]";
|
||||
std::string name_str = name_ss.str();
|
||||
const std::string name_str = name_ss.str();
|
||||
|
||||
if (dtypenum > 0) {
|
||||
const fstEnumHandle enumNum = m_local2fstdtype[dtypenum];
|
||||
fstWriterEmitEnumTableRef(m_fst, enumNum);
|
||||
if (dtypenum > 0) fstWriterEmitEnumTableRef(m_fst, m_local2fstdtype[dtypenum]);
|
||||
|
||||
fstVarDir varDir;
|
||||
switch (direction) {
|
||||
case VerilatedTraceSigDirection::INOUT: varDir = FST_VD_INOUT; break;
|
||||
case VerilatedTraceSigDirection::OUTPUT: varDir = FST_VD_OUTPUT; break;
|
||||
case VerilatedTraceSigDirection::INPUT: varDir = FST_VD_INPUT; break;
|
||||
case VerilatedTraceSigDirection::NONE: varDir = FST_VD_IMPLICIT; break;
|
||||
}
|
||||
|
||||
fstVarType varType;
|
||||
// Doubles have special decoding properties, so must indicate if a double
|
||||
if (type == VerilatedTraceSigType::DOUBLE) {
|
||||
if (kind == VerilatedTraceSigKind::PARAMETER) {
|
||||
varType = FST_VT_VCD_REAL_PARAMETER;
|
||||
} else {
|
||||
varType = FST_VT_VCD_REAL;
|
||||
}
|
||||
}
|
||||
// clang-format off
|
||||
else if (kind == VerilatedTraceSigKind::PARAMETER) varType = FST_VT_VCD_PARAMETER;
|
||||
else if (kind == VerilatedTraceSigKind::SUPPLY0) varType = FST_VT_VCD_SUPPLY0;
|
||||
else if (kind == VerilatedTraceSigKind::SUPPLY1) varType = FST_VT_VCD_SUPPLY1;
|
||||
else if (kind == VerilatedTraceSigKind::TRI) varType = FST_VT_VCD_TRI;
|
||||
else if (kind == VerilatedTraceSigKind::TRI0) varType = FST_VT_VCD_TRI0;
|
||||
else if (kind == VerilatedTraceSigKind::TRI1) varType = FST_VT_VCD_TRI1;
|
||||
else if (kind == VerilatedTraceSigKind::WIRE) varType = FST_VT_VCD_WIRE;
|
||||
//
|
||||
else if (type == VerilatedTraceSigType::INTEGER) varType = FST_VT_VCD_INTEGER;
|
||||
else if (type == VerilatedTraceSigType::BIT) varType = FST_VT_SV_BIT;
|
||||
else if (type == VerilatedTraceSigType::LOGIC) varType = FST_VT_SV_LOGIC;
|
||||
else if (type == VerilatedTraceSigType::INT) varType = FST_VT_SV_INT;
|
||||
else if (type == VerilatedTraceSigType::SHORTINT) varType = FST_VT_SV_SHORTINT;
|
||||
else if (type == VerilatedTraceSigType::LONGINT) varType = FST_VT_SV_LONGINT;
|
||||
else if (type == VerilatedTraceSigType::BYTE) varType = FST_VT_SV_BYTE;
|
||||
else if (type == VerilatedTraceSigType::EVENT) varType = FST_VT_VCD_EVENT;
|
||||
else if (type == VerilatedTraceSigType::TIME) varType = FST_VT_VCD_TIME;
|
||||
else { assert(0); /* Unreachable */ }
|
||||
// clang-format on
|
||||
|
||||
const auto it = vlstd::as_const(m_code2symbol).find(code);
|
||||
if (it == m_code2symbol.end()) { // New
|
||||
m_code2symbol[code]
|
||||
= fstWriterCreateVar(m_fst, vartype, vardir, bits, name_str.c_str(), 0);
|
||||
= fstWriterCreateVar(m_fst, varType, varDir, bits, name_str.c_str(), 0);
|
||||
} else { // Alias
|
||||
fstWriterCreateVar(m_fst, vartype, vardir, bits, name_str.c_str(), it->second);
|
||||
fstWriterCreateVar(m_fst, varType, varDir, bits, name_str.c_str(), it->second);
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedFst::declEvent(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, false, 0, 0);
|
||||
void VerilatedFst::declEvent(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
VerilatedTraceSigDirection direction, VerilatedTraceSigKind kind,
|
||||
VerilatedTraceSigType type, bool array, int arraynum) {
|
||||
declare(code, name, dtypenum, direction, kind, type, array, arraynum, false, 0, 0);
|
||||
}
|
||||
void VerilatedFst::declBit(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, false, 0, 0);
|
||||
void VerilatedFst::declBit(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
VerilatedTraceSigDirection direction, VerilatedTraceSigKind kind,
|
||||
VerilatedTraceSigType type, bool array, int arraynum) {
|
||||
declare(code, name, dtypenum, direction, kind, type, array, arraynum, false, 0, 0);
|
||||
}
|
||||
void VerilatedFst::declBus(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, true, msb, lsb);
|
||||
void VerilatedFst::declBus(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
VerilatedTraceSigDirection direction, VerilatedTraceSigKind kind,
|
||||
VerilatedTraceSigType type, bool array, int arraynum, int msb,
|
||||
int lsb) {
|
||||
declare(code, name, dtypenum, direction, kind, type, array, arraynum, true, msb, lsb);
|
||||
}
|
||||
void VerilatedFst::declQuad(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, true, msb, lsb);
|
||||
void VerilatedFst::declQuad(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
VerilatedTraceSigDirection direction, VerilatedTraceSigKind kind,
|
||||
VerilatedTraceSigType type, bool array, int arraynum, int msb,
|
||||
int lsb) {
|
||||
declare(code, name, dtypenum, direction, kind, type, array, arraynum, true, msb, lsb);
|
||||
}
|
||||
void VerilatedFst::declArray(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, true, msb, lsb);
|
||||
void VerilatedFst::declArray(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
VerilatedTraceSigDirection direction, VerilatedTraceSigKind kind,
|
||||
VerilatedTraceSigType type, bool array, int arraynum, int msb,
|
||||
int lsb) {
|
||||
declare(code, name, dtypenum, direction, kind, type, array, arraynum, true, msb, lsb);
|
||||
}
|
||||
void VerilatedFst::declDouble(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, false, 63, 0);
|
||||
void VerilatedFst::declDouble(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
VerilatedTraceSigDirection direction, VerilatedTraceSigKind kind,
|
||||
VerilatedTraceSigType type, bool array, int arraynum) {
|
||||
declare(code, name, dtypenum, direction, kind, type, array, arraynum, false, 63, 0);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Get/commit trace buffer
|
||||
|
||||
VerilatedFst::Buffer* VerilatedFst::getTraceBuffer() {
|
||||
VerilatedFst::Buffer* VerilatedFst::getTraceBuffer(uint32_t fidx) {
|
||||
if (offload()) return new OffloadBuffer{*this};
|
||||
return new Buffer{*this};
|
||||
}
|
||||
@@ -284,7 +293,7 @@ void VerilatedFst::configure(const VerilatedTraceConfig& config) {
|
||||
// so always inline them.
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedFstBuffer::emitEvent(uint32_t code, VlEvent newval) {
|
||||
void VerilatedFstBuffer::emitEvent(uint32_t code, const VlEventBase* newval) {
|
||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
|
||||
fstWriterEmitValueChange(m_fst, m_symbolp[code], "1");
|
||||
}
|
||||
|
||||
+41
-27
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2023 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2024 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.
|
||||
@@ -24,13 +24,14 @@
|
||||
#include "verilated.h"
|
||||
#include "verilated_trace.h"
|
||||
|
||||
#include "gtkwave/fstapi.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
typedef uint32_t vlFstHandle;
|
||||
typedef uint32_t vlFstEnumHandle;
|
||||
|
||||
class VerilatedFstBuffer;
|
||||
|
||||
//=============================================================================
|
||||
@@ -49,18 +50,22 @@ private:
|
||||
// FST specific internals
|
||||
|
||||
void* m_fst = nullptr;
|
||||
std::map<uint32_t, fstHandle> m_code2symbol;
|
||||
std::map<int, fstEnumHandle> m_local2fstdtype;
|
||||
std::list<std::string> m_curScope;
|
||||
fstHandle* m_symbolp = nullptr; // same as m_code2symbol, but as an array
|
||||
std::map<uint32_t, vlFstHandle> m_code2symbol;
|
||||
std::map<int, vlFstEnumHandle> m_local2fstdtype;
|
||||
vlFstHandle* m_symbolp = nullptr; // same as m_code2symbol, but as an array
|
||||
char* m_strbufp = nullptr; // String buffer long enough to hold maxBits() chars
|
||||
|
||||
bool m_useFstWriterThread = false; // Whether to use the separate FST writer thread
|
||||
|
||||
// Prefixes to add to signal names/scope types
|
||||
std::vector<std::pair<std::string, VerilatedTracePrefixType>> m_prefixStack{
|
||||
{"", VerilatedTracePrefixType::SCOPE_MODULE}};
|
||||
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedFst);
|
||||
void declare(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, bool bussed, int msb, int lsb);
|
||||
void declare(uint32_t code, const char* name, int dtypenum, VerilatedTraceSigDirection,
|
||||
VerilatedTraceSigKind, VerilatedTraceSigType, bool array, int arraynum,
|
||||
bool bussed, int msb, int lsb);
|
||||
|
||||
protected:
|
||||
//=========================================================================
|
||||
@@ -74,7 +79,7 @@ protected:
|
||||
bool preChangeDump() override { return isOpen(); }
|
||||
|
||||
// Trace buffer management
|
||||
Buffer* getTraceBuffer() override;
|
||||
Buffer* getTraceBuffer(uint32_t fidx) override;
|
||||
void commitTraceBuffer(Buffer*) override;
|
||||
|
||||
// Configure sub-class
|
||||
@@ -101,18 +106,27 @@ public:
|
||||
//=========================================================================
|
||||
// Internal interface to Verilator generated code
|
||||
|
||||
void declEvent(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum);
|
||||
void declBit(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum);
|
||||
void declBus(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
||||
void declQuad(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
||||
void declArray(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
||||
void declDouble(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum);
|
||||
void pushPrefix(const std::string&, VerilatedTracePrefixType);
|
||||
void popPrefix();
|
||||
|
||||
void declEvent(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
VerilatedTraceSigDirection, VerilatedTraceSigKind, VerilatedTraceSigType,
|
||||
bool array, int arraynum);
|
||||
void declBit(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
VerilatedTraceSigDirection, VerilatedTraceSigKind, VerilatedTraceSigType,
|
||||
bool array, int arraynum);
|
||||
void declBus(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
VerilatedTraceSigDirection, VerilatedTraceSigKind, VerilatedTraceSigType,
|
||||
bool array, int arraynum, int msb, int lsb);
|
||||
void declQuad(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
VerilatedTraceSigDirection, VerilatedTraceSigKind, VerilatedTraceSigType,
|
||||
bool array, int arraynum, int msb, int lsb);
|
||||
void declArray(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
VerilatedTraceSigDirection, VerilatedTraceSigKind, VerilatedTraceSigType,
|
||||
bool array, int arraynum, int msb, int lsb);
|
||||
void declDouble(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
VerilatedTraceSigDirection, VerilatedTraceSigKind, VerilatedTraceSigType,
|
||||
bool array, int arraynum);
|
||||
|
||||
void declDTypeEnum(int dtypenum, const char* name, uint32_t elements, unsigned int minValbits,
|
||||
const char** itemNamesp, const char** itemValuesp);
|
||||
@@ -149,7 +163,7 @@ class VerilatedFstBuffer VL_NOT_FINAL {
|
||||
// The FST file handle
|
||||
void* const m_fst = m_owner.m_fst;
|
||||
// code to fstHande map, as an array
|
||||
const fstHandle* const m_symbolp = m_owner.m_symbolp;
|
||||
const vlFstHandle* const m_symbolp = m_owner.m_symbolp;
|
||||
// String buffer long enough to hold maxBits() chars
|
||||
char* const m_strbufp = m_owner.m_strbufp;
|
||||
|
||||
@@ -163,7 +177,7 @@ class VerilatedFstBuffer VL_NOT_FINAL {
|
||||
|
||||
// Implementations of duck-typed methods for VerilatedTraceBuffer. These are
|
||||
// called from only one place (the full* methods), so always inline them.
|
||||
VL_ATTR_ALWINLINE void emitEvent(uint32_t code, VlEvent newval);
|
||||
VL_ATTR_ALWINLINE void emitEvent(uint32_t code, const VlEventBase* newval);
|
||||
VL_ATTR_ALWINLINE void emitBit(uint32_t code, CData newval);
|
||||
VL_ATTR_ALWINLINE void emitCData(uint32_t code, CData newval, int bits);
|
||||
VL_ATTR_ALWINLINE void emitSData(uint32_t code, SData newval, int bits);
|
||||
@@ -196,7 +210,7 @@ public:
|
||||
/// Return if file is open
|
||||
bool isOpen() const VL_MT_SAFE { return m_sptrace.isOpen(); }
|
||||
/// Open a new FST file
|
||||
void open(const char* filename) VL_MT_SAFE { m_sptrace.open(filename); }
|
||||
virtual void open(const char* filename) VL_MT_SAFE { m_sptrace.open(filename); }
|
||||
/// Close dump
|
||||
void close() VL_MT_SAFE { m_sptrace.close(); }
|
||||
/// Flush dump
|
||||
@@ -216,12 +230,12 @@ public:
|
||||
|
||||
// Set time units (s/ms, defaults to ns)
|
||||
// Users should not need to call this, as for Verilated models, these
|
||||
// propage from the Verilated default timeunit
|
||||
// propagate from the Verilated default timeunit
|
||||
void set_time_unit(const char* unitp) VL_MT_SAFE { m_sptrace.set_time_unit(unitp); }
|
||||
void set_time_unit(const std::string& unit) VL_MT_SAFE { m_sptrace.set_time_unit(unit); }
|
||||
// Set time resolution (s/ms, defaults to ns)
|
||||
// Users should not need to call this, as for Verilated models, these
|
||||
// propage from the Verilated default timeprecision
|
||||
// propagate from the Verilated default timeprecision
|
||||
void set_time_resolution(const char* unitp) VL_MT_SAFE {
|
||||
m_sptrace.set_time_resolution(unitp);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2023 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2024 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.
|
||||
|
||||
+14
-97
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// Copyright 2001-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2001-2024 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.
|
||||
@@ -12,8 +12,7 @@
|
||||
/// \file
|
||||
/// \brief Verilated tracing in FST format for SystemC header
|
||||
///
|
||||
/// User wrapper code should use this header when creating FST SystemC
|
||||
/// traces.
|
||||
/// User wrapper code should use this header when creating FST SystemC traces.
|
||||
///
|
||||
/// This class is not threadsafe, as the SystemC kernel is not threadsafe.
|
||||
///
|
||||
@@ -25,115 +24,33 @@
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include "verilated_fst_c.h"
|
||||
#include "verilated_sc.h"
|
||||
|
||||
#include <string>
|
||||
#include "verilated_sc_trace.h"
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFstSc
|
||||
///
|
||||
/// Class representing a Verilator-friendly FST trace format registered
|
||||
/// with the SystemC simulation kernel, just like a SystemC-documented
|
||||
/// trace format.
|
||||
/// Trace file used to create FST dump for SystemC version of Verilated models. It's very similar
|
||||
/// to its C version (see the class VerilatedFstC)
|
||||
|
||||
class VerilatedFstSc final : sc_core::sc_trace_file, public VerilatedFstC {
|
||||
class VerilatedFstSc final : VerilatedScTraceBase, public VerilatedFstC {
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedFstSc);
|
||||
|
||||
public:
|
||||
/// Construct a SC trace object, and register with the SystemC kernel
|
||||
VerilatedFstSc() {
|
||||
sc_core::sc_get_curr_simcontext()->add_trace_file(this);
|
||||
// We want to avoid a depreciated warning, but still be back compatible.
|
||||
// Turning off the message just for this still results in an
|
||||
// annoying "to turn off" message.
|
||||
const sc_core::sc_time t1sec{1, sc_core::SC_SEC};
|
||||
if (t1sec.to_default_time_units() != 0) {
|
||||
const sc_core::sc_time tunits{1.0 / t1sec.to_default_time_units(), sc_core::SC_SEC};
|
||||
spTrace()->set_time_unit(tunits.to_string());
|
||||
}
|
||||
spTrace()->set_time_resolution(sc_core::sc_get_time_resolution().to_string());
|
||||
}
|
||||
/// Destruct, flush, and close the dump
|
||||
~VerilatedFstSc() override { close(); }
|
||||
|
||||
// METHODS - for SC kernel
|
||||
// Called by SystemC simulate()
|
||||
void cycle(bool delta_cycle) override {
|
||||
if (!delta_cycle) this->dump(sc_core::sc_time_stamp().to_double());
|
||||
spTrace()->set_time_unit(VerilatedScTraceBase::getScTimeUnit());
|
||||
spTrace()->set_time_resolution(VerilatedScTraceBase::getScTimeResolution());
|
||||
}
|
||||
|
||||
// METHODS
|
||||
// Override VerilatedFstC. Must be called after starting simulation.
|
||||
// Note: this is not a virtual function in the base class, so no 'override'
|
||||
virtual void open(const char* filename) VL_MT_SAFE {
|
||||
if (VL_UNLIKELY(!sc_core::sc_get_curr_simcontext()->elaboration_done())) {
|
||||
Verilated::scTraceBeforeElaborationError();
|
||||
}
|
||||
void open(const char* filename) override VL_MT_SAFE {
|
||||
VerilatedScTraceBase::checkScElaborationDone();
|
||||
VerilatedFstC::open(filename);
|
||||
}
|
||||
|
||||
private:
|
||||
// METHODS - Fake outs for linker
|
||||
|
||||
#ifdef NC_SYSTEMC
|
||||
// Cadence Incisive has these as abstract functions so we must create them
|
||||
void set_time_unit(int exponent10_seconds) override {} // deprecated
|
||||
#endif
|
||||
void set_time_unit(double v, sc_core::sc_time_unit tu) override {} // LCOV_EXCL_LINE
|
||||
|
||||
//--------------------------------------------------
|
||||
// SystemC 2.1.v1
|
||||
|
||||
void write_comment(const std::string&) override {}
|
||||
void trace(const unsigned int&, const std::string&, const char**) override {}
|
||||
|
||||
#define DECL_TRACE_METHOD_A(tp) \
|
||||
void trace(const tp& object, const std::string& name) override {}
|
||||
#define DECL_TRACE_METHOD_B(tp) \
|
||||
void trace(const tp& object, const std::string& name, int width) override {}
|
||||
|
||||
// clang-format off
|
||||
// Formatting matches that of sc_trace.h
|
||||
// LCOV_EXCL_START
|
||||
#if (SYSTEMC_VERSION >= 20171012)
|
||||
DECL_TRACE_METHOD_A( sc_core::sc_event )
|
||||
DECL_TRACE_METHOD_A( sc_core::sc_time )
|
||||
#endif
|
||||
|
||||
DECL_TRACE_METHOD_A( bool )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_bit )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_logic )
|
||||
|
||||
DECL_TRACE_METHOD_B( unsigned char )
|
||||
DECL_TRACE_METHOD_B( unsigned short )
|
||||
DECL_TRACE_METHOD_B( unsigned int )
|
||||
DECL_TRACE_METHOD_B( unsigned long )
|
||||
DECL_TRACE_METHOD_B( char )
|
||||
DECL_TRACE_METHOD_B( short )
|
||||
DECL_TRACE_METHOD_B( int )
|
||||
DECL_TRACE_METHOD_B( long )
|
||||
DECL_TRACE_METHOD_B( sc_dt::int64 )
|
||||
DECL_TRACE_METHOD_B( sc_dt::uint64 )
|
||||
|
||||
DECL_TRACE_METHOD_A( float )
|
||||
DECL_TRACE_METHOD_A( double )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_int_base )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_uint_base )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_signed )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_unsigned )
|
||||
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxval )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxval_fast )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxnum )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxnum_fast )
|
||||
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_bv_base )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_lv_base )
|
||||
// LCOV_EXCL_STOP
|
||||
// clang-format on
|
||||
|
||||
#undef DECL_TRACE_METHOD_A
|
||||
#undef DECL_TRACE_METHOD_B
|
||||
// METHODS - for SC kernel
|
||||
// Called from SystemC kernel
|
||||
void cycle() override { VerilatedFstC::dump(sc_core::sc_time_stamp().to_double()); }
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
||||
+166
-140
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2024 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.
|
||||
@@ -284,6 +284,8 @@ inline uint64_t vl_time_stamp64() VL_MT_SAFE {
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// clang-format on
|
||||
|
||||
uint64_t VerilatedContext::time() const VL_MT_SAFE {
|
||||
// When using non-default context, fastest path is return time
|
||||
if (VL_LIKELY(m_s.m_time)) return m_s.m_time;
|
||||
@@ -311,25 +313,6 @@ double vl_time_multiplier(int scale) VL_PURE;
|
||||
// Return power of 10. e.g. returns 100 if n==2
|
||||
uint64_t vl_time_pow10(int n) VL_PURE;
|
||||
|
||||
#ifdef VL_DEBUG
|
||||
/// Evaluate statement if VL_DEBUG defined
|
||||
# define VL_DEBUG_IFDEF(stmt) \
|
||||
do { \
|
||||
stmt \
|
||||
} while (false)
|
||||
/// Evaluate statement if VL_DEBUG defined and Verilated::debug() enabled
|
||||
# define VL_DEBUG_IF(stmt) \
|
||||
do { \
|
||||
if (VL_UNLIKELY(Verilated::debug())) {stmt} \
|
||||
} while (false)
|
||||
#else
|
||||
// We intentionally do not compile the stmt to improve compile speed
|
||||
# define VL_DEBUG_IFDEF(stmt) do {} while (false)
|
||||
# define VL_DEBUG_IF(stmt) do {} while (false)
|
||||
#endif
|
||||
|
||||
// clang-format on
|
||||
|
||||
//=========================================================================
|
||||
// Functional macros/routines
|
||||
// These all take the form
|
||||
@@ -342,10 +325,23 @@ uint64_t vl_time_pow10(int n) VL_PURE;
|
||||
//===================================================================
|
||||
// SETTING OPERATORS
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
static WDataOutP VL_MEMSET_ZERO_W(WDataOutP owp, int words) VL_MT_SAFE {
|
||||
return static_cast<WDataOutP>(std::memset(owp, 0, words * sizeof(EData)));
|
||||
}
|
||||
VL_ATTR_ALWINLINE
|
||||
static WDataOutP VL_MEMSET_ONES_W(WDataOutP owp, int words) VL_MT_SAFE {
|
||||
return static_cast<WDataOutP>(std::memset(owp, 0xff, words * sizeof(EData)));
|
||||
}
|
||||
VL_ATTR_ALWINLINE
|
||||
static WDataOutP VL_MEMCPY_W(WDataOutP owp, WDataInP const iwp, int words) VL_MT_SAFE {
|
||||
return static_cast<WDataOutP>(std::memcpy(owp, iwp, words * sizeof(EData)));
|
||||
}
|
||||
|
||||
// Output clean
|
||||
// EMIT_RULE: VL_CLEAN: oclean=clean; obits=lbits;
|
||||
#define VL_CLEAN_II(obits, lbits, lhs) ((lhs)&VL_MASK_I(obits))
|
||||
#define VL_CLEAN_QQ(obits, lbits, lhs) ((lhs)&VL_MASK_Q(obits))
|
||||
#define VL_CLEAN_II(obits, lbits, lhs) ((lhs) & (VL_MASK_I(obits)))
|
||||
#define VL_CLEAN_QQ(obits, lbits, lhs) ((lhs) & (VL_MASK_Q(obits)))
|
||||
|
||||
// EMIT_RULE: VL_ASSIGNCLEAN: oclean=clean; obits==lbits;
|
||||
#define VL_ASSIGNCLEAN_W(obits, owp, lwp) VL_CLEAN_WW((obits), (owp), (lwp))
|
||||
@@ -356,18 +352,16 @@ static inline WDataOutP _vl_clean_inplace_w(int obits, WDataOutP owp) VL_MT_SAFE
|
||||
}
|
||||
static inline WDataOutP VL_CLEAN_WW(int obits, WDataOutP owp, WDataInP const lwp) VL_MT_SAFE {
|
||||
const int words = VL_WORDS_I(obits);
|
||||
for (int i = 0; (i < (words - 1)); ++i) owp[i] = lwp[i];
|
||||
VL_MEMCPY_W(owp, lwp, words - 1);
|
||||
owp[words - 1] = lwp[words - 1] & VL_MASK_E(obits);
|
||||
return owp;
|
||||
}
|
||||
static inline WDataOutP VL_ZERO_W(int obits, WDataOutP owp) VL_MT_SAFE {
|
||||
const int words = VL_WORDS_I(obits);
|
||||
for (int i = 0; i < words; ++i) owp[i] = 0;
|
||||
return owp;
|
||||
return VL_MEMSET_ZERO_W(owp, VL_WORDS_I(obits));
|
||||
}
|
||||
static inline WDataOutP VL_ALLONES_W(int obits, WDataOutP owp) VL_MT_SAFE {
|
||||
const int words = VL_WORDS_I(obits);
|
||||
for (int i = 0; i < (words - 1); ++i) owp[i] = ~VL_EUL(0);
|
||||
VL_MEMSET_ONES_W(owp, words - 1);
|
||||
owp[words - 1] = VL_MASK_E(obits);
|
||||
return owp;
|
||||
}
|
||||
@@ -376,9 +370,7 @@ static inline WDataOutP VL_ALLONES_W(int obits, WDataOutP owp) VL_MT_SAFE {
|
||||
// For now, we always have a clean rhs.
|
||||
// Note: If a ASSIGN isn't clean, use VL_ASSIGNCLEAN instead to do the same thing.
|
||||
static inline WDataOutP VL_ASSIGN_W(int obits, WDataOutP owp, WDataInP const lwp) VL_MT_SAFE {
|
||||
const int words = VL_WORDS_I(obits);
|
||||
for (int i = 0; i < words; ++i) owp[i] = lwp[i];
|
||||
return owp;
|
||||
return VL_MEMCPY_W(owp, lwp, VL_WORDS_I(obits));
|
||||
}
|
||||
|
||||
// EMIT_RULE: VL_ASSIGNBIT: rclean=clean;
|
||||
@@ -449,7 +441,7 @@ static inline void VL_ASSIGNBIT_WO(int bit, WDataOutP owp) VL_MT_SAFE {
|
||||
#define VL_ASSIGN_WSB(obits, owp, svar) \
|
||||
{ \
|
||||
const int words = VL_WORDS_I(obits); \
|
||||
sc_biguint<(obits)> _butemp = (svar).read(); \
|
||||
sc_dt::sc_biguint<(obits)> _butemp = (svar).read(); \
|
||||
uint32_t* chunkp = _butemp.get_raw(); \
|
||||
int32_t lsb = 0; \
|
||||
while (lsb < obits - BITS_PER_DIGIT) { \
|
||||
@@ -475,20 +467,20 @@ static inline void VL_ASSIGNBIT_WO(int bit, WDataOutP owp) VL_MT_SAFE {
|
||||
|
||||
#define VL_ASSIGN_SWI(obits, svar, rd) \
|
||||
{ \
|
||||
sc_bv<(obits)> _bvtemp; \
|
||||
sc_dt::sc_bv<(obits)> _bvtemp; \
|
||||
_bvtemp.set_word(0, (rd)); \
|
||||
(svar).write(_bvtemp); \
|
||||
}
|
||||
#define VL_ASSIGN_SWQ(obits, svar, rd) \
|
||||
{ \
|
||||
sc_bv<(obits)> _bvtemp; \
|
||||
sc_dt::sc_bv<(obits)> _bvtemp; \
|
||||
_bvtemp.set_word(0, static_cast<IData>(rd)); \
|
||||
_bvtemp.set_word(1, static_cast<IData>((rd) >> VL_IDATASIZE)); \
|
||||
(svar).write(_bvtemp); \
|
||||
}
|
||||
#define VL_ASSIGN_SWW(obits, svar, rwp) \
|
||||
{ \
|
||||
sc_bv<(obits)> _bvtemp; \
|
||||
sc_dt::sc_bv<(obits)> _bvtemp; \
|
||||
for (int i = 0; i < VL_WORDS_I(obits); ++i) _bvtemp.set_word(i, (rwp)[i]); \
|
||||
(svar).write(_bvtemp); \
|
||||
}
|
||||
@@ -504,7 +496,7 @@ static inline void VL_ASSIGNBIT_WO(int bit, WDataOutP owp) VL_MT_SAFE {
|
||||
#define VL_SC_BITS_PER_DIGIT 30 // This comes from sc_nbdefs.h BITS_PER_DIGIT
|
||||
#define VL_ASSIGN_SBW(obits, svar, rwp) \
|
||||
{ \
|
||||
sc_biguint<(obits)> _butemp; \
|
||||
sc_dt::sc_biguint<(obits)> _butemp; \
|
||||
int32_t lsb = 0; \
|
||||
uint32_t* chunkp = _butemp.get_raw(); \
|
||||
while (lsb + VL_SC_BITS_PER_DIGIT < (obits)) { \
|
||||
@@ -536,19 +528,20 @@ static inline void VL_ASSIGNBIT_WO(int bit, WDataOutP owp) VL_MT_SAFE {
|
||||
static inline WDataOutP VL_EXTEND_WI(int obits, int, WDataOutP owp, IData ld) VL_MT_SAFE {
|
||||
// Note for extracts that obits != lbits
|
||||
owp[0] = ld;
|
||||
for (int i = 1; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
return owp;
|
||||
}
|
||||
static inline WDataOutP VL_EXTEND_WQ(int obits, int, WDataOutP owp, QData ld) VL_MT_SAFE {
|
||||
VL_SET_WQ(owp, ld);
|
||||
for (int i = VL_WQ_WORDS_E; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
|
||||
VL_MEMSET_ZERO_W(owp + VL_WQ_WORDS_E, VL_WORDS_I(obits) - VL_WQ_WORDS_E);
|
||||
return owp;
|
||||
}
|
||||
static inline WDataOutP VL_EXTEND_WW(int obits, int lbits, WDataOutP owp,
|
||||
WDataInP const lwp) VL_MT_SAFE {
|
||||
for (int i = 0; i < VL_WORDS_I(lbits); ++i) owp[i] = lwp[i];
|
||||
for (int i = VL_WORDS_I(lbits); i < VL_WORDS_I(obits); ++i) owp[i] = 0;
|
||||
return owp;
|
||||
const int lwords = VL_WORDS_I(lbits);
|
||||
VL_PREFETCH_RD(lwp);
|
||||
VL_MEMSET_ZERO_W(owp + lwords, VL_WORDS_I(obits) - lwords);
|
||||
return VL_MEMCPY_W(owp, lwp, lwords);
|
||||
}
|
||||
|
||||
// EMIT_RULE: VL_EXTENDS: oclean=*dirty*; obits=lbits;
|
||||
@@ -564,26 +557,37 @@ static inline QData VL_EXTENDS_QQ(int, int lbits, QData lhs) VL_PURE {
|
||||
}
|
||||
|
||||
static inline WDataOutP VL_EXTENDS_WI(int obits, int lbits, WDataOutP owp, IData ld) VL_MT_SAFE {
|
||||
const EData sign = VL_SIGNONES_E(lbits, static_cast<EData>(ld));
|
||||
owp[0] = ld | (sign & ~VL_MASK_E(lbits));
|
||||
for (int i = 1; i < VL_WORDS_I(obits); ++i) owp[i] = sign;
|
||||
owp[0] = ld;
|
||||
if (VL_SIGN_E(lbits, owp[0])) {
|
||||
owp[0] |= ~VL_MASK_E(lbits);
|
||||
VL_MEMSET_ONES_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
} else {
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
}
|
||||
return owp;
|
||||
}
|
||||
static inline WDataOutP VL_EXTENDS_WQ(int obits, int lbits, WDataOutP owp, QData ld) VL_MT_SAFE {
|
||||
VL_SET_WQ(owp, ld);
|
||||
const EData sign = VL_SIGNONES_E(lbits, owp[1]);
|
||||
owp[1] |= sign & ~VL_MASK_E(lbits);
|
||||
for (int i = VL_WQ_WORDS_E; i < VL_WORDS_I(obits); ++i) owp[i] = sign;
|
||||
if (VL_SIGN_E(lbits, owp[1])) {
|
||||
owp[1] |= ~VL_MASK_E(lbits);
|
||||
VL_MEMSET_ONES_W(owp + VL_WQ_WORDS_E, VL_WORDS_I(obits) - VL_WQ_WORDS_E);
|
||||
} else {
|
||||
VL_MEMSET_ZERO_W(owp + VL_WQ_WORDS_E, VL_WORDS_I(obits) - VL_WQ_WORDS_E);
|
||||
}
|
||||
return owp;
|
||||
}
|
||||
static inline WDataOutP VL_EXTENDS_WW(int obits, int lbits, WDataOutP owp,
|
||||
WDataInP const lwp) VL_MT_SAFE {
|
||||
for (int i = 0; i < VL_WORDS_I(lbits) - 1; ++i) owp[i] = lwp[i];
|
||||
const int lmsw = VL_WORDS_I(lbits) - 1;
|
||||
const EData sign = VL_SIGNONES_E(lbits, lwp[lmsw]);
|
||||
owp[lmsw] = lwp[lmsw] | (sign & ~VL_MASK_E(lbits));
|
||||
for (int i = VL_WORDS_I(lbits); i < VL_WORDS_I(obits); ++i) owp[i] = sign;
|
||||
return owp;
|
||||
const int lwords = VL_WORDS_I(lbits);
|
||||
VL_PREFETCH_RD(lwp);
|
||||
owp[lwords - 1] = lwp[lwords - 1];
|
||||
if (VL_SIGN_E(lbits, lwp[lwords - 1])) {
|
||||
owp[lwords - 1] |= ~VL_MASK_E(lbits);
|
||||
VL_MEMSET_ONES_W(owp + lwords, VL_WORDS_I(obits) - lwords);
|
||||
} else {
|
||||
VL_MEMSET_ZERO_W(owp + lwords, VL_WORDS_I(obits) - lwords);
|
||||
}
|
||||
return VL_MEMCPY_W(owp, lwp, lwords - 1);
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
@@ -1028,6 +1032,7 @@ static inline QData VL_MULS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
||||
static inline WDataOutP VL_MULS_WWW(int lbits, WDataOutP owp, WDataInP const lwp,
|
||||
WDataInP const rwp) VL_MT_SAFE {
|
||||
const int words = VL_WORDS_I(lbits);
|
||||
VL_DEBUG_IFDEF(assert(words <= VL_MULS_MAX_WORDS););
|
||||
// cppcheck-suppress variableScope
|
||||
WData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
|
||||
// cppcheck-suppress variableScope
|
||||
@@ -1098,21 +1103,22 @@ static inline QData VL_MODDIVS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
||||
|
||||
static inline WDataOutP VL_DIVS_WWW(int lbits, WDataOutP owp, WDataInP const lwp,
|
||||
WDataInP const rwp) VL_MT_SAFE {
|
||||
const int words = VL_WORDS_I(lbits);
|
||||
const EData lsign = VL_SIGN_E(lbits, lwp[words - 1]);
|
||||
const EData rsign = VL_SIGN_E(lbits, rwp[words - 1]);
|
||||
const int lwords = VL_WORDS_I(lbits);
|
||||
const EData lsign = VL_SIGN_E(lbits, lwp[lwords - 1]);
|
||||
const EData rsign = VL_SIGN_E(lbits, rwp[lwords - 1]);
|
||||
VL_DEBUG_IFDEF(assert(lwords <= VL_MULS_MAX_WORDS););
|
||||
// cppcheck-suppress variableScope
|
||||
WData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
|
||||
// cppcheck-suppress variableScope
|
||||
WData rwstore[VL_MULS_MAX_WORDS];
|
||||
WDataInP ltup = lwp;
|
||||
WDataInP rtup = rwp;
|
||||
if (lsign) ltup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), lwstore, lwp));
|
||||
if (rsign) rtup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), rwstore, rwp));
|
||||
if (lsign) ltup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, lwstore, lwp));
|
||||
if (rsign) rtup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, rwstore, rwp));
|
||||
if ((lsign && !rsign) || (!lsign && rsign)) {
|
||||
WData qNoSign[VL_MULS_MAX_WORDS];
|
||||
VL_DIV_WWW(lbits, qNoSign, ltup, rtup);
|
||||
_vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), owp, qNoSign));
|
||||
_vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, owp, qNoSign));
|
||||
return owp;
|
||||
} else {
|
||||
return VL_DIV_WWW(lbits, owp, ltup, rtup);
|
||||
@@ -1120,21 +1126,22 @@ static inline WDataOutP VL_DIVS_WWW(int lbits, WDataOutP owp, WDataInP const lwp
|
||||
}
|
||||
static inline WDataOutP VL_MODDIVS_WWW(int lbits, WDataOutP owp, WDataInP const lwp,
|
||||
WDataInP const rwp) VL_MT_SAFE {
|
||||
const int words = VL_WORDS_I(lbits);
|
||||
const EData lsign = VL_SIGN_E(lbits, lwp[words - 1]);
|
||||
const EData rsign = VL_SIGN_E(lbits, rwp[words - 1]);
|
||||
const int lwords = VL_WORDS_I(lbits);
|
||||
const EData lsign = VL_SIGN_E(lbits, lwp[lwords - 1]);
|
||||
const EData rsign = VL_SIGN_E(lbits, rwp[lwords - 1]);
|
||||
VL_DEBUG_IFDEF(assert(lwords <= VL_MULS_MAX_WORDS););
|
||||
// cppcheck-suppress variableScope
|
||||
WData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
|
||||
// cppcheck-suppress variableScope
|
||||
WData rwstore[VL_MULS_MAX_WORDS];
|
||||
WDataInP ltup = lwp;
|
||||
WDataInP rtup = rwp;
|
||||
if (lsign) ltup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), lwstore, lwp));
|
||||
if (rsign) rtup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), rwstore, rwp));
|
||||
if (lsign) ltup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, lwstore, lwp));
|
||||
if (rsign) rtup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, rwstore, rwp));
|
||||
if (lsign) { // Only dividend sign matters for modulus
|
||||
WData qNoSign[VL_MULS_MAX_WORDS];
|
||||
VL_MODDIV_WWW(lbits, qNoSign, ltup, rtup);
|
||||
_vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), owp, qNoSign));
|
||||
_vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, owp, qNoSign));
|
||||
return owp;
|
||||
} else {
|
||||
return VL_MODDIV_WWW(lbits, owp, ltup, rtup);
|
||||
@@ -1437,7 +1444,7 @@ static inline IData VL_STREAML_FAST_III(int lbits, IData ld, IData rd_log2) VL_P
|
||||
if (rd_log2) {
|
||||
const uint32_t lbitsFloor = lbits & ~VL_MASK_I(rd_log2); // max multiple of rd <= lbits
|
||||
const uint32_t lbitsRem = lbits - lbitsFloor; // number of bits in most-sig slice (MSS)
|
||||
const IData msbMask = VL_MASK_I(lbitsRem) << lbitsFloor; // mask to sel only bits in MSS
|
||||
const IData msbMask = lbitsFloor == 32 ? 0UL : VL_MASK_I(lbitsRem) << lbitsFloor;
|
||||
ret = (ret & ~msbMask) | ((ret & msbMask) << ((VL_UL(1) << rd_log2) - lbitsRem));
|
||||
}
|
||||
switch (rd_log2) {
|
||||
@@ -1566,63 +1573,66 @@ static inline QData VL_DYN_TO_Q(const VlQueue<T>& q, int elem_size) {
|
||||
static inline WDataOutP VL_CONCAT_WII(int obits, int lbits, int rbits, WDataOutP owp, IData ld,
|
||||
IData rd) VL_MT_SAFE {
|
||||
owp[0] = rd;
|
||||
for (int i = 1; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
_vl_insert_WI(owp, ld, rbits + lbits - 1, rbits);
|
||||
return owp;
|
||||
}
|
||||
static inline WDataOutP VL_CONCAT_WWI(int obits, int lbits, int rbits, WDataOutP owp,
|
||||
WDataInP const lwp, IData rd) VL_MT_SAFE {
|
||||
owp[0] = rd;
|
||||
for (int i = 1; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
_vl_insert_WW(owp, lwp, rbits + lbits - 1, rbits);
|
||||
return owp;
|
||||
}
|
||||
static inline WDataOutP VL_CONCAT_WIW(int obits, int lbits, int rbits, WDataOutP owp, IData ld,
|
||||
WDataInP const rwp) VL_MT_SAFE {
|
||||
for (int i = 0; i < VL_WORDS_I(rbits); ++i) owp[i] = rwp[i];
|
||||
for (int i = VL_WORDS_I(rbits); i < VL_WORDS_I(obits); ++i) owp[i] = 0;
|
||||
const int rwords = VL_WORDS_I(rbits);
|
||||
VL_MEMCPY_W(owp, rwp, rwords);
|
||||
VL_MEMSET_ZERO_W(owp + rwords, VL_WORDS_I(obits) - rwords);
|
||||
_vl_insert_WI(owp, ld, rbits + lbits - 1, rbits);
|
||||
return owp;
|
||||
}
|
||||
static inline WDataOutP VL_CONCAT_WIQ(int obits, int lbits, int rbits, WDataOutP owp, IData ld,
|
||||
QData rd) VL_MT_SAFE {
|
||||
VL_SET_WQ(owp, rd);
|
||||
for (int i = VL_WQ_WORDS_E; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
|
||||
VL_MEMSET_ZERO_W(owp + VL_WQ_WORDS_E, VL_WORDS_I(obits) - VL_WQ_WORDS_E);
|
||||
_vl_insert_WI(owp, ld, rbits + lbits - 1, rbits);
|
||||
return owp;
|
||||
}
|
||||
static inline WDataOutP VL_CONCAT_WQI(int obits, int lbits, int rbits, WDataOutP owp, QData ld,
|
||||
IData rd) VL_MT_SAFE {
|
||||
owp[0] = rd;
|
||||
for (int i = 1; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
_vl_insert_WQ(owp, ld, rbits + lbits - 1, rbits);
|
||||
return owp;
|
||||
}
|
||||
static inline WDataOutP VL_CONCAT_WQQ(int obits, int lbits, int rbits, WDataOutP owp, QData ld,
|
||||
QData rd) VL_MT_SAFE {
|
||||
VL_SET_WQ(owp, rd);
|
||||
for (int i = VL_WQ_WORDS_E; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
|
||||
VL_MEMSET_ZERO_W(owp + VL_WQ_WORDS_E, VL_WORDS_I(obits) - VL_WQ_WORDS_E);
|
||||
_vl_insert_WQ(owp, ld, rbits + lbits - 1, rbits);
|
||||
return owp;
|
||||
}
|
||||
static inline WDataOutP VL_CONCAT_WWQ(int obits, int lbits, int rbits, WDataOutP owp,
|
||||
WDataInP const lwp, QData rd) VL_MT_SAFE {
|
||||
VL_SET_WQ(owp, rd);
|
||||
for (int i = VL_WQ_WORDS_E; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
|
||||
VL_MEMSET_ZERO_W(owp + VL_WQ_WORDS_E, VL_WORDS_I(obits) - VL_WQ_WORDS_E);
|
||||
_vl_insert_WW(owp, lwp, rbits + lbits - 1, rbits);
|
||||
return owp;
|
||||
}
|
||||
static inline WDataOutP VL_CONCAT_WQW(int obits, int lbits, int rbits, WDataOutP owp, QData ld,
|
||||
WDataInP const rwp) VL_MT_SAFE {
|
||||
for (int i = 0; i < VL_WORDS_I(rbits); ++i) owp[i] = rwp[i];
|
||||
for (int i = VL_WORDS_I(rbits); i < VL_WORDS_I(obits); ++i) owp[i] = 0;
|
||||
const int rwords = VL_WORDS_I(rbits);
|
||||
VL_MEMCPY_W(owp, rwp, rwords);
|
||||
VL_MEMSET_ZERO_W(owp + rwords, VL_WORDS_I(obits) - rwords);
|
||||
_vl_insert_WQ(owp, ld, rbits + lbits - 1, rbits);
|
||||
return owp;
|
||||
}
|
||||
static inline WDataOutP VL_CONCAT_WWW(int obits, int lbits, int rbits, WDataOutP owp,
|
||||
WDataInP const lwp, WDataInP const rwp) VL_MT_SAFE {
|
||||
for (int i = 0; i < VL_WORDS_I(rbits); ++i) owp[i] = rwp[i];
|
||||
for (int i = VL_WORDS_I(rbits); i < VL_WORDS_I(obits); ++i) owp[i] = 0;
|
||||
const int rwords = VL_WORDS_I(rbits);
|
||||
VL_MEMCPY_W(owp, rwp, rwords);
|
||||
VL_MEMSET_ZERO_W(owp + rwords, VL_WORDS_I(obits) - rwords);
|
||||
_vl_insert_WW(owp, lwp, rbits + lbits - 1, rbits);
|
||||
return owp;
|
||||
}
|
||||
@@ -1647,6 +1657,24 @@ static inline void _vl_shiftl_inplace_w(int obits, WDataOutP iowp,
|
||||
// EMIT_RULE: VL_SHIFTL: oclean=lclean; rclean==clean;
|
||||
// Important: Unlike most other funcs, the shift might well be a computed
|
||||
// expression. Thus consider this when optimizing. (And perhaps have 2 funcs?)
|
||||
// If RHS (rd/rwp) is larger than the output, zeros (or all ones for >>>) must be returned
|
||||
// (This corresponds to AstShift*Ovr Ast nodes)
|
||||
static inline IData VL_SHIFTL_III(int obits, int, int, IData lhs, IData rhs) VL_MT_SAFE {
|
||||
if (VL_UNLIKELY(rhs >= VL_IDATASIZE)) return 0;
|
||||
return lhs << rhs; // Small is common so not clean return
|
||||
}
|
||||
static inline IData VL_SHIFTL_IIQ(int obits, int, int, IData lhs, QData rhs) VL_MT_SAFE {
|
||||
if (VL_UNLIKELY(rhs >= VL_IDATASIZE)) return 0;
|
||||
return VL_CLEAN_II(obits, obits, lhs << rhs);
|
||||
}
|
||||
static inline QData VL_SHIFTL_QQI(int obits, int, int, QData lhs, IData rhs) VL_MT_SAFE {
|
||||
if (VL_UNLIKELY(rhs >= VL_QUADSIZE)) return 0;
|
||||
return lhs << rhs; // Small is common so not clean return
|
||||
}
|
||||
static inline QData VL_SHIFTL_QQQ(int obits, int, int, QData lhs, QData rhs) VL_MT_SAFE {
|
||||
if (VL_UNLIKELY(rhs >= VL_QUADSIZE)) return 0;
|
||||
return VL_CLEAN_QQ(obits, obits, lhs << rhs);
|
||||
}
|
||||
static inline WDataOutP VL_SHIFTL_WWI(int obits, int, int, WDataOutP owp, WDataInP const lwp,
|
||||
IData rd) VL_MT_SAFE {
|
||||
const int word_shift = VL_BITWORD_E(rd);
|
||||
@@ -1684,11 +1712,7 @@ static inline IData VL_SHIFTL_IIW(int obits, int, int rbits, IData lhs,
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return VL_CLEAN_II(obits, obits, lhs << rwp[0]);
|
||||
}
|
||||
static inline IData VL_SHIFTL_IIQ(int obits, int, int, IData lhs, QData rhs) VL_MT_SAFE {
|
||||
if (VL_UNLIKELY(rhs >= VL_IDATASIZE)) return 0;
|
||||
return VL_CLEAN_II(obits, obits, lhs << rhs);
|
||||
return VL_SHIFTL_III(obits, obits, 32, lhs, rwp[0]);
|
||||
}
|
||||
static inline QData VL_SHIFTL_QQW(int obits, int, int rbits, QData lhs,
|
||||
WDataInP const rwp) VL_MT_SAFE {
|
||||
@@ -1698,16 +1722,28 @@ static inline QData VL_SHIFTL_QQW(int obits, int, int rbits, QData lhs,
|
||||
}
|
||||
}
|
||||
// Above checks rwp[1]==0 so not needed in below shift
|
||||
return VL_CLEAN_QQ(obits, obits, lhs << (static_cast<QData>(rwp[0])));
|
||||
}
|
||||
static inline QData VL_SHIFTL_QQQ(int obits, int, int, QData lhs, QData rhs) VL_MT_SAFE {
|
||||
if (VL_UNLIKELY(rhs >= VL_QUADSIZE)) return 0;
|
||||
return VL_CLEAN_QQ(obits, obits, lhs << rhs);
|
||||
return VL_SHIFTL_QQI(obits, obits, 32, lhs, rwp[0]);
|
||||
}
|
||||
|
||||
// EMIT_RULE: VL_SHIFTR: oclean=lclean; rclean==clean;
|
||||
// Important: Unlike most other funcs, the shift might well be a computed
|
||||
// expression. Thus consider this when optimizing. (And perhaps have 2 funcs?)
|
||||
static inline IData VL_SHIFTR_III(int obits, int, int, IData lhs, IData rhs) VL_PURE {
|
||||
if (VL_UNLIKELY(rhs >= VL_IDATASIZE)) return 0;
|
||||
return lhs >> rhs; // Small is common so assumed not clean
|
||||
}
|
||||
static inline IData VL_SHIFTR_IIQ(int obits, int, int, IData lhs, QData rhs) VL_PURE {
|
||||
if (VL_UNLIKELY(rhs >= VL_IDATASIZE)) return 0;
|
||||
return VL_CLEAN_QQ(obits, obits, lhs >> rhs);
|
||||
}
|
||||
static inline QData VL_SHIFTR_QQI(int obits, int, int, QData lhs, IData rhs) VL_PURE {
|
||||
if (VL_UNLIKELY(rhs >= VL_QUADSIZE)) return 0;
|
||||
return lhs >> rhs; // Small is common so assumed not clean
|
||||
}
|
||||
static inline QData VL_SHIFTR_QQQ(int obits, int, int, QData lhs, QData rhs) VL_PURE {
|
||||
if (VL_UNLIKELY(rhs >= VL_QUADSIZE)) return 0;
|
||||
return VL_CLEAN_QQ(obits, obits, lhs >> rhs);
|
||||
}
|
||||
static inline WDataOutP VL_SHIFTR_WWI(int obits, int, int, WDataOutP owp, WDataInP const lwp,
|
||||
IData rd) VL_MT_SAFE {
|
||||
const int word_shift = VL_BITWORD_E(rd); // Maybe 0
|
||||
@@ -1751,29 +1787,16 @@ static inline WDataOutP VL_SHIFTR_WWQ(int obits, int lbits, int rbits, WDataOutP
|
||||
static inline IData VL_SHIFTR_IIW(int obits, int, int rbits, IData lhs,
|
||||
WDataInP const rwp) VL_PURE {
|
||||
for (int i = 1; i < VL_WORDS_I(rbits); ++i) {
|
||||
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
|
||||
return 0;
|
||||
}
|
||||
if (VL_UNLIKELY(rwp[i])) return 0; // Huge shift 1>>32 or more
|
||||
}
|
||||
return VL_CLEAN_II(obits, obits, lhs >> rwp[0]);
|
||||
return VL_SHIFTR_III(obits, obits, 32, lhs, rwp[0]);
|
||||
}
|
||||
static inline QData VL_SHIFTR_QQW(int obits, int, int rbits, QData lhs,
|
||||
WDataInP const rwp) VL_PURE {
|
||||
for (int i = 1; i < VL_WORDS_I(rbits); ++i) {
|
||||
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
|
||||
return 0;
|
||||
}
|
||||
if (VL_UNLIKELY(rwp[i])) return 0; // Huge shift 1>>32 or more
|
||||
}
|
||||
// Above checks rwp[1]==0 so not needed in below shift
|
||||
return VL_CLEAN_QQ(obits, obits, lhs >> (static_cast<QData>(rwp[0])));
|
||||
}
|
||||
static inline IData VL_SHIFTR_IIQ(int obits, int, int, IData lhs, QData rhs) VL_PURE {
|
||||
if (VL_UNLIKELY(rhs >= VL_IDATASIZE)) return 0;
|
||||
return VL_CLEAN_QQ(obits, obits, lhs >> rhs);
|
||||
}
|
||||
static inline QData VL_SHIFTR_QQQ(int obits, int, int, QData lhs, QData rhs) VL_PURE {
|
||||
if (VL_UNLIKELY(rhs >= VL_QUADSIZE)) return 0;
|
||||
return VL_CLEAN_QQ(obits, obits, lhs >> rhs);
|
||||
return VL_SHIFTR_QQI(obits, obits, 32, lhs, rwp[0]);
|
||||
}
|
||||
|
||||
// EMIT_RULE: VL_SHIFTRS: oclean=false; lclean=clean, rclean==clean;
|
||||
@@ -1783,11 +1806,13 @@ static inline IData VL_SHIFTRS_III(int obits, int lbits, int, IData lhs, IData r
|
||||
// must use lbits for sign; lbits might != obits,
|
||||
// an EXTEND(SHIFTRS(...)) can became a SHIFTRS(...) within same 32/64 bit word length
|
||||
const IData sign = -(lhs >> (lbits - 1)); // ffff_ffff if negative
|
||||
if (VL_UNLIKELY(rhs >= VL_IDATASIZE)) return sign & VL_MASK_I(obits);
|
||||
const IData signext = ~(VL_MASK_I(lbits) >> rhs); // One with bits where we've shifted "past"
|
||||
return (lhs >> rhs) | (sign & VL_CLEAN_II(obits, obits, signext));
|
||||
}
|
||||
static inline QData VL_SHIFTRS_QQI(int obits, int lbits, int, QData lhs, IData rhs) VL_PURE {
|
||||
const QData sign = -(lhs >> (lbits - 1));
|
||||
if (VL_UNLIKELY(rhs >= VL_QUADSIZE)) return sign & VL_MASK_Q(obits);
|
||||
const QData signext = ~(VL_MASK_Q(lbits) >> rhs);
|
||||
return (lhs >> rhs) | (sign & VL_CLEAN_QQ(obits, obits, signext));
|
||||
}
|
||||
@@ -1831,10 +1856,13 @@ static inline WDataOutP VL_SHIFTRS_WWW(int obits, int lbits, int rbits, WDataOut
|
||||
EData overshift = 0; // Huge shift 1>>32 or more
|
||||
for (int i = 1; i < VL_WORDS_I(rbits); ++i) overshift |= rwp[i];
|
||||
if (VL_UNLIKELY(overshift || rwp[0] >= static_cast<IData>(obits))) {
|
||||
const int lmsw = VL_WORDS_I(obits) - 1;
|
||||
const EData sign = VL_SIGNONES_E(lbits, lwp[lmsw]);
|
||||
for (int j = 0; j <= lmsw; ++j) owp[j] = sign;
|
||||
owp[lmsw] &= VL_MASK_E(lbits);
|
||||
const int owords = VL_WORDS_I(obits);
|
||||
if (VL_SIGN_E(lbits, lwp[owords - 1])) {
|
||||
VL_MEMSET_ONES_W(owp, owords);
|
||||
owp[owords - 1] &= VL_MASK_E(lbits);
|
||||
} else {
|
||||
VL_MEMSET_ZERO_W(owp, owords);
|
||||
}
|
||||
return owp;
|
||||
}
|
||||
return VL_SHIFTRS_WWI(obits, lbits, 32, owp, lwp, rwp[0]);
|
||||
@@ -2045,9 +2073,7 @@ static inline void VL_ASSIGNSEL_WW(int rbits, int obits, int lsb, WDataOutP iowp
|
||||
|
||||
static inline WDataOutP VL_COND_WIWW(int obits, WDataOutP owp, int cond, WDataInP const w1p,
|
||||
WDataInP const w2p) VL_MT_SAFE {
|
||||
const int words = VL_WORDS_I(obits);
|
||||
for (int i = 0; i < words; ++i) owp[i] = cond ? w1p[i] : w2p[i];
|
||||
return owp;
|
||||
return VL_MEMCPY_W(owp, cond ? w1p : w2p, VL_WORDS_I(obits));
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
@@ -2060,7 +2086,7 @@ static inline WDataOutP VL_COND_WIWW(int obits, WDataOutP owp, int cond, WDataIn
|
||||
// If changing the number of functions here, also change EMITCINLINES_NUM_CONSTW
|
||||
|
||||
#define VL_C_END_(obits, wordsSet) \
|
||||
for (int i = (wordsSet); i < VL_WORDS_I(obits); ++i) o[i] = 0; \
|
||||
VL_MEMSET_ZERO_W(o + (wordsSet), VL_WORDS_I(obits) - (wordsSet)); \
|
||||
return o
|
||||
|
||||
// clang-format off
|
||||
@@ -2111,60 +2137,60 @@ static inline WDataOutP VL_CONST_W_8X(int obits, WDataOutP o,
|
||||
VL_C_END_(obits, 8);
|
||||
}
|
||||
//
|
||||
static inline WDataOutP VL_CONSTHI_W_1X(int obits, int lsb, WDataOutP obase,
|
||||
static inline WDataOutP VL_CONSTHI_W_1X(int obits, int lsb, WDataOutP o,
|
||||
EData d0) VL_MT_SAFE {
|
||||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0;
|
||||
WDataOutP ohi = o + VL_WORDS_I(lsb);
|
||||
ohi[0] = d0;
|
||||
VL_C_END_(obits, VL_WORDS_I(lsb) + 1);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_2X(int obits, int lsb, WDataOutP obase,
|
||||
static inline WDataOutP VL_CONSTHI_W_2X(int obits, int lsb, WDataOutP o,
|
||||
EData d1, EData d0) VL_MT_SAFE {
|
||||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1;
|
||||
WDataOutP ohi = o + VL_WORDS_I(lsb);
|
||||
ohi[0] = d0; ohi[1] = d1;
|
||||
VL_C_END_(obits, VL_WORDS_I(lsb) + 2);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_3X(int obits, int lsb, WDataOutP obase,
|
||||
static inline WDataOutP VL_CONSTHI_W_3X(int obits, int lsb, WDataOutP o,
|
||||
EData d2, EData d1, EData d0) VL_MT_SAFE {
|
||||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1; o[2] = d2;
|
||||
WDataOutP ohi = o + VL_WORDS_I(lsb);
|
||||
ohi[0] = d0; ohi[1] = d1; ohi[2] = d2;
|
||||
VL_C_END_(obits, VL_WORDS_I(lsb) + 3);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_4X(int obits, int lsb, WDataOutP obase,
|
||||
static inline WDataOutP VL_CONSTHI_W_4X(int obits, int lsb, WDataOutP o,
|
||||
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
||||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||
WDataOutP ohi = o + VL_WORDS_I(lsb);
|
||||
ohi[0] = d0; ohi[1] = d1; ohi[2] = d2; ohi[3] = d3;
|
||||
VL_C_END_(obits, VL_WORDS_I(lsb) + 4);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_5X(int obits, int lsb, WDataOutP obase,
|
||||
static inline WDataOutP VL_CONSTHI_W_5X(int obits, int lsb, WDataOutP o,
|
||||
EData d4,
|
||||
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
||||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||
o[4] = d4;
|
||||
WDataOutP ohi = o + VL_WORDS_I(lsb);
|
||||
ohi[0] = d0; ohi[1] = d1; ohi[2] = d2; ohi[3] = d3;
|
||||
ohi[4] = d4;
|
||||
VL_C_END_(obits, VL_WORDS_I(lsb) + 5);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_6X(int obits, int lsb, WDataOutP obase,
|
||||
static inline WDataOutP VL_CONSTHI_W_6X(int obits, int lsb, WDataOutP o,
|
||||
EData d5, EData d4,
|
||||
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
||||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||
o[4] = d4; o[5] = d5;
|
||||
WDataOutP ohi = o + VL_WORDS_I(lsb);
|
||||
ohi[0] = d0; ohi[1] = d1; ohi[2] = d2; ohi[3] = d3;
|
||||
ohi[4] = d4; ohi[5] = d5;
|
||||
VL_C_END_(obits, VL_WORDS_I(lsb) + 6);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_7X(int obits, int lsb, WDataOutP obase,
|
||||
static inline WDataOutP VL_CONSTHI_W_7X(int obits, int lsb, WDataOutP o,
|
||||
EData d6, EData d5, EData d4,
|
||||
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
||||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||
o[4] = d4; o[5] = d5; o[6] = d6;
|
||||
WDataOutP ohi = o + VL_WORDS_I(lsb);
|
||||
ohi[0] = d0; ohi[1] = d1; ohi[2] = d2; ohi[3] = d3;
|
||||
ohi[4] = d4; ohi[5] = d5; ohi[6] = d6;
|
||||
VL_C_END_(obits, VL_WORDS_I(lsb) + 7);
|
||||
}
|
||||
static inline WDataOutP VL_CONSTHI_W_8X(int obits, int lsb, WDataOutP obase,
|
||||
static inline WDataOutP VL_CONSTHI_W_8X(int obits, int lsb, WDataOutP o,
|
||||
EData d7, EData d6, EData d5, EData d4,
|
||||
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
||||
WDataOutP o = obase + VL_WORDS_I(lsb);
|
||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||
o[4] = d4; o[5] = d5; o[6] = d6; o[7] = d7;
|
||||
WDataOutP ohi = o + VL_WORDS_I(lsb);
|
||||
ohi[0] = d0; ohi[1] = d1; ohi[2] = d2; ohi[3] = d3;
|
||||
ohi[4] = d4; ohi[5] = d5; ohi[6] = d6; ohi[7] = d7;
|
||||
VL_C_END_(obits, VL_WORDS_I(lsb) + 8);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2009-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2024 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.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2024 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.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2024 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.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2012-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2012-2024 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.
|
||||
@@ -161,12 +161,18 @@ void VlExecutionProfiler::dump(const char* filenamep, uint64_t tickEnd)
|
||||
|
||||
// TODO Perhaps merge with verilated_coverage output format, so can
|
||||
// have a common merging and reporting tool, etc.
|
||||
fprintf(fp, "VLPROFVERSION 2.0 # Verilator execution profile version 2.0\n");
|
||||
fprintf(fp, "VLPROFVERSION 2.1 # Verilator execution profile version 2.1\n");
|
||||
fprintf(fp, "VLPROF arg +verilator+prof+exec+start+%" PRIu64 "\n",
|
||||
Verilated::threadContextp()->profExecStart());
|
||||
fprintf(fp, "VLPROF arg +verilator+prof+exec+window+%u\n",
|
||||
Verilated::threadContextp()->profExecWindow());
|
||||
const unsigned threads = static_cast<unsigned>(m_traceps.size());
|
||||
// Note that VerilatedContext will by default create as many threads as there are hardware
|
||||
// processors, but not all of them might be utilized. Report the actual number that has trace
|
||||
// entries to avoid over-counting.
|
||||
unsigned threads = 0;
|
||||
for (const auto& pair : m_traceps) {
|
||||
if (!pair.second->empty()) ++threads;
|
||||
}
|
||||
fprintf(fp, "VLPROF stat threads %u\n", threads);
|
||||
fprintf(fp, "VLPROF stat yields %" PRIu64 "\n", VlMTaskVertex::yields());
|
||||
|
||||
@@ -183,6 +189,7 @@ void VlExecutionProfiler::dump(const char* filenamep, uint64_t tickEnd)
|
||||
for (const auto& pair : m_traceps) {
|
||||
const uint32_t threadId = pair.first;
|
||||
ExecutionTrace* const tracep = pair.second;
|
||||
if (tracep->empty()) continue;
|
||||
fprintf(fp, "VLPROFTHREAD %" PRIu32 "\n", threadId);
|
||||
|
||||
for (const VlExecutionRecord& er : *tracep) {
|
||||
@@ -191,10 +198,9 @@ void VlExecutionProfiler::dump(const char* filenamep, uint64_t tickEnd)
|
||||
fprintf(fp, "VLPROFEXEC %s %" PRIu64, name, time);
|
||||
|
||||
switch (er.m_type) {
|
||||
case VlExecutionRecord::Type::EVAL_BEGIN:
|
||||
case VlExecutionRecord::Type::EVAL_END:
|
||||
case VlExecutionRecord::Type::EVAL_LOOP_BEGIN:
|
||||
case VlExecutionRecord::Type::EVAL_LOOP_END:
|
||||
case VlExecutionRecord::Type::SECTION_POP:
|
||||
case VlExecutionRecord::Type::EXEC_GRAPH_BEGIN:
|
||||
case VlExecutionRecord::Type::EXEC_GRAPH_END:
|
||||
// No payload
|
||||
fprintf(fp, "\n");
|
||||
break;
|
||||
@@ -209,6 +215,11 @@ void VlExecutionProfiler::dump(const char* filenamep, uint64_t tickEnd)
|
||||
fprintf(fp, " id %u predictCost %u\n", payload.m_id, payload.m_predictCost);
|
||||
break;
|
||||
}
|
||||
case VlExecutionRecord::Type::SECTION_PUSH: {
|
||||
const auto& payload = er.m_payload.sectionPush;
|
||||
fprintf(fp, " %s\n", payload.m_name);
|
||||
break;
|
||||
}
|
||||
default: abort(); // LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2012-2023 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2012-2024 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.
|
||||
@@ -58,12 +58,12 @@ VL_ATTR_ALWINLINE QData VL_CPU_TICK() {
|
||||
|
||||
// clang-format off
|
||||
#define FOREACH_VlExecutionRecord_TYPE(macro) \
|
||||
_VL_FOREACH_APPLY(macro, EVAL_BEGIN) \
|
||||
_VL_FOREACH_APPLY(macro, EVAL_END) \
|
||||
_VL_FOREACH_APPLY(macro, EVAL_LOOP_BEGIN) \
|
||||
_VL_FOREACH_APPLY(macro, EVAL_LOOP_END) \
|
||||
_VL_FOREACH_APPLY(macro, SECTION_PUSH) \
|
||||
_VL_FOREACH_APPLY(macro, SECTION_POP) \
|
||||
_VL_FOREACH_APPLY(macro, MTASK_BEGIN) \
|
||||
_VL_FOREACH_APPLY(macro, MTASK_END)
|
||||
_VL_FOREACH_APPLY(macro, MTASK_END) \
|
||||
_VL_FOREACH_APPLY(macro, EXEC_GRAPH_BEGIN) \
|
||||
_VL_FOREACH_APPLY(macro, EXEC_GRAPH_END)
|
||||
// clang-format on
|
||||
|
||||
class VlExecutionRecord final {
|
||||
@@ -83,6 +83,9 @@ class VlExecutionRecord final {
|
||||
};
|
||||
|
||||
union Payload {
|
||||
struct {
|
||||
const char* m_name; // Name of section being entered
|
||||
} sectionPush;
|
||||
struct {
|
||||
uint32_t m_id; // MTask id
|
||||
uint32_t m_predictStart; // Time scheduler predicted would start
|
||||
@@ -109,10 +112,11 @@ public:
|
||||
VlExecutionRecord() = default;
|
||||
|
||||
// METHODS
|
||||
void evalBegin() { m_type = Type::EVAL_BEGIN; }
|
||||
void evalEnd() { m_type = Type::EVAL_END; }
|
||||
void evalLoopBegin() { m_type = Type::EVAL_LOOP_BEGIN; }
|
||||
void evalLoopEnd() { m_type = Type::EVAL_LOOP_END; }
|
||||
void sectionPush(const char* name) {
|
||||
m_payload.sectionPush.m_name = name;
|
||||
m_type = Type::SECTION_PUSH;
|
||||
}
|
||||
void sectionPop() { m_type = Type::SECTION_POP; }
|
||||
void mtaskBegin(uint32_t id, uint32_t predictStart) {
|
||||
m_payload.mtaskBegin.m_id = id;
|
||||
m_payload.mtaskBegin.m_predictStart = predictStart;
|
||||
@@ -124,6 +128,8 @@ public:
|
||||
m_payload.mtaskEnd.m_predictCost = predictCost;
|
||||
m_type = Type::MTASK_END;
|
||||
}
|
||||
void execGraphBegin() { m_type = Type::EXEC_GRAPH_BEGIN; }
|
||||
void execGraphEnd() { m_type = Type::EXEC_GRAPH_END; }
|
||||
};
|
||||
|
||||
static_assert(std::is_trivially_destructible<VlExecutionRecord>::value,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2023 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2024 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.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2000-2023 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2000-2024 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.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2009-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2024 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.
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// Copyright 2001-2024 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
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilated tracing for SystemC implementation code
|
||||
///
|
||||
///
|
||||
///
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VERILATOR_VERILATED_SC_TRACE_H_
|
||||
#define VERILATOR_VERILATED_SC_TRACE_H_
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include "verilated.h"
|
||||
#include "verilated_sc.h"
|
||||
|
||||
#if SYSTEMC_VERSION < 20140417 // SystemC's simulation phase callback introduced in 2.3.1
|
||||
#define _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedScTraceBase
|
||||
// Base class for VCD/FST trace format on SystemC
|
||||
// This is an internally used class - see VerilatedVcdSc and VerilatedFstSc for what to call from
|
||||
// applications
|
||||
//
|
||||
/// This class utilizes SystemC's callbacks, which allows to dump signals inside the Verilated
|
||||
/// module automatically as time advances.
|
||||
///
|
||||
/// For SystemC prior to 2.3.1, the only approach for being notified after each update is by adding
|
||||
/// a trace file (sc_trace_file) to the simulation context. And after this version the simulation
|
||||
/// phase callback approach has been introduced (sc_trace_file also utilizes this), which is
|
||||
/// presented only if it's enabled with the `--enable-phase-callbacks` option. However, when it's
|
||||
/// enabled with `--enable-phase-callbacks=tracing`, trace files will be therefore disabled, thus
|
||||
/// failing to provide its functionality.
|
||||
///
|
||||
/// To provide a universal way for tracing, the class attempts to register a phase callback first.
|
||||
/// If it fails (proving that the feature has been disabled), it'll use the trace file approach
|
||||
/// instead.
|
||||
|
||||
class VerilatedScTraceBase VL_NOT_FINAL : private sc_core::sc_object,
|
||||
private sc_core::sc_trace_file {
|
||||
bool m_enableDeltaCycles = false;
|
||||
bool m_traceFileAdded = false;
|
||||
static void stubReportHandler(const sc_core::sc_report&, const sc_core::sc_actions&){};
|
||||
|
||||
public:
|
||||
void enableDeltaCycles(bool flag = true) {
|
||||
#ifndef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
using namespace sc_core;
|
||||
// Save old report handler before overriding it
|
||||
const auto oldHandler = sc_report_handler::get_handler();
|
||||
// Override the old handler to hide 'phase callbacks not enabled' message
|
||||
sc_report_handler::set_handler(&stubReportHandler);
|
||||
if (flag) {
|
||||
// Register simulation phase callback for delta cycles
|
||||
sc_object::register_simulation_phase_callback(SC_END_OF_UPDATE);
|
||||
} else {
|
||||
sc_object::unregister_simulation_phase_callback(SC_END_OF_UPDATE);
|
||||
}
|
||||
// Restore the old handler
|
||||
sc_report_handler::set_handler(oldHandler);
|
||||
#endif
|
||||
m_enableDeltaCycles = flag;
|
||||
}
|
||||
|
||||
protected:
|
||||
VerilatedScTraceBase()
|
||||
: sc_object(sc_core::sc_gen_unique_name("$$$$verilator_sc_trace$$$$"))
|
||||
, sc_trace_file() {
|
||||
registerTraceCallback();
|
||||
};
|
||||
~VerilatedScTraceBase() override {
|
||||
#if SYSTEMC_VERSION >= 20140417 // remove_trace_file added in 2.3.1
|
||||
// Phase callback is automatically unregistered in ~sc_object(). Only the trace file is
|
||||
// needed to be removed here
|
||||
if (m_traceFileAdded) simcontext()->remove_trace_file(this);
|
||||
#endif
|
||||
};
|
||||
void registerTraceCallback() {
|
||||
#ifndef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
using namespace sc_core;
|
||||
// Save old report handler before overriding it
|
||||
const auto oldHandler = sc_report_handler::get_handler();
|
||||
// Override the old handler to hide 'phase callbacks not enabled' message
|
||||
sc_report_handler::set_handler(&stubReportHandler);
|
||||
// Register regular simulation phase (non-delta cycle) callback
|
||||
phase_cb_mask cb_mask = sc_object::register_simulation_phase_callback(SC_BEFORE_TIMESTEP);
|
||||
if (cb_mask == SC_UNITIALIZED) {
|
||||
#endif
|
||||
// Phase callback not enabled, use trace file instead
|
||||
simcontext()->add_trace_file(this);
|
||||
m_traceFileAdded = true;
|
||||
#ifndef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
}
|
||||
// Restore the old handler
|
||||
sc_report_handler::set_handler(oldHandler);
|
||||
#endif
|
||||
}
|
||||
static std::string getScTimeUnit() {
|
||||
// We want to avoid a depreciated warning, but still be back compatible.
|
||||
// Turning off the message just for this still results in an
|
||||
// annoying "to turn off" message.
|
||||
const sc_core::sc_time t1sec{1, sc_core::SC_SEC};
|
||||
if (t1sec.to_default_time_units() == 0) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", // LCOV_EXCL_LINE
|
||||
"Cannot to get valid SystemC default time unit for trace file");
|
||||
}
|
||||
const sc_core::sc_time tunits{1.0 / t1sec.to_default_time_units(), sc_core::SC_SEC};
|
||||
return tunits.to_string();
|
||||
}
|
||||
static std::string getScTimeResolution() {
|
||||
return sc_core::sc_get_time_resolution().to_string();
|
||||
}
|
||||
static void checkScElaborationDone() {
|
||||
if (!sc_core::sc_get_curr_simcontext()->elaboration_done()) {
|
||||
Verilated::scTraceBeforeElaborationError();
|
||||
}
|
||||
}
|
||||
|
||||
// METHODS - for SC kernel
|
||||
#ifndef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
// Override sc_object. Called if using phase callback
|
||||
void simulation_phase_callback() final { cycle(); }
|
||||
#endif
|
||||
// Override sc_trace_file. Called if using trace file
|
||||
void cycle(bool delta_cycle) final {
|
||||
if (!delta_cycle || m_enableDeltaCycles) cycle();
|
||||
}
|
||||
// METHODS - callbacks
|
||||
// Subclasses should implement this callback method
|
||||
virtual void cycle() = 0;
|
||||
|
||||
private:
|
||||
// METHODS - Fake outs for linker
|
||||
// LCOV_EXCL_START
|
||||
|
||||
#ifdef NC_SYSTEMC
|
||||
// Cadence Incisive has these as abstract functions so we must create them
|
||||
void set_time_unit(int exponent10_seconds) override {} // deprecated
|
||||
#endif
|
||||
void set_time_unit(double v, sc_core::sc_time_unit tu) override {} // LCOV_EXCL_LINE
|
||||
|
||||
//--------------------------------------------------
|
||||
// SystemC 2.1.v1
|
||||
|
||||
void write_comment(const std::string&) override {}
|
||||
void trace(const unsigned int&, const std::string&, const char**) override {}
|
||||
|
||||
#define DECL_TRACE_METHOD_A(tp) \
|
||||
void trace(const tp& object, const std::string& name) override {}
|
||||
#define DECL_TRACE_METHOD_B(tp) \
|
||||
void trace(const tp& object, const std::string& name, int width) override {}
|
||||
|
||||
// clang-format off
|
||||
// Formatting matches that of sc_trace.h
|
||||
#if SYSTEMC_VERSION >= 20171012 // SystemC >= 2.3.2
|
||||
DECL_TRACE_METHOD_A( sc_core::sc_event )
|
||||
DECL_TRACE_METHOD_A( sc_core::sc_time )
|
||||
#endif
|
||||
|
||||
DECL_TRACE_METHOD_A( bool )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_bit )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_logic )
|
||||
|
||||
DECL_TRACE_METHOD_B( unsigned char )
|
||||
DECL_TRACE_METHOD_B( unsigned short )
|
||||
DECL_TRACE_METHOD_B( unsigned int )
|
||||
DECL_TRACE_METHOD_B( unsigned long )
|
||||
DECL_TRACE_METHOD_B( char )
|
||||
DECL_TRACE_METHOD_B( short )
|
||||
DECL_TRACE_METHOD_B( int )
|
||||
DECL_TRACE_METHOD_B( long )
|
||||
DECL_TRACE_METHOD_B( sc_dt::int64 )
|
||||
DECL_TRACE_METHOD_B( sc_dt::uint64 )
|
||||
|
||||
DECL_TRACE_METHOD_A( float )
|
||||
DECL_TRACE_METHOD_A( double )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_int_base )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_uint_base )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_signed )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_unsigned )
|
||||
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxval )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxval_fast )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxnum )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxnum_fast )
|
||||
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_bv_base )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_lv_base )
|
||||
// LCOV_EXCL_STOP
|
||||
// clang-format on
|
||||
|
||||
#undef DECL_TRACE_METHOD_A
|
||||
#undef DECL_TRACE_METHOD_B
|
||||
};
|
||||
|
||||
#ifdef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
#undef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
#endif
|
||||
|
||||
#endif // Guard
|
||||
@@ -4,7 +4,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2022-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2022-2024 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
|
||||
@@ -47,7 +47,7 @@ package std;
|
||||
endtask
|
||||
|
||||
function int try_put(T message);
|
||||
if (num() < m_bound) begin
|
||||
if (m_bound == 0 || num() < m_bound) begin
|
||||
m_queue.push_back(message);
|
||||
return 1;
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2024 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.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2024 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.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2012-2023 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2012-2024 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.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2012-2023 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2012-2024 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.
|
||||
|
||||
@@ -53,36 +53,37 @@ void VlCoroutineHandle::dump() const {
|
||||
//======================================================================
|
||||
// VlDelayScheduler:: Methods
|
||||
|
||||
#ifdef VL_DEBUG
|
||||
void VlDelayScheduler::VlDelayedCoroutine::dump() const {
|
||||
VL_DBG_MSGF(" Awaiting time %" PRIu64 ": ", m_timestep);
|
||||
m_handle.dump();
|
||||
}
|
||||
#endif
|
||||
|
||||
void VlDelayScheduler::resume() {
|
||||
#ifdef VL_DEBUG
|
||||
VL_DEBUG_IF(dump(); VL_DBG_MSGF(" Resuming delayed processes\n"););
|
||||
#endif
|
||||
while (awaitingCurrentTime()) {
|
||||
if (m_queue.front().m_timestep != m_context.time()) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
"%Error: Encountered process that should've been resumed at an "
|
||||
"earlier simulation time. Missed a time slot?");
|
||||
}
|
||||
// Move max element in the heap to the end
|
||||
std::pop_heap(m_queue.begin(), m_queue.end());
|
||||
VlCoroutineHandle handle = std::move(m_queue.back().m_handle);
|
||||
m_queue.pop_back();
|
||||
bool resumed = false;
|
||||
|
||||
while (!m_queue.empty() && (m_queue.begin()->first == m_context.time())) {
|
||||
VlCoroutineHandle handle = std::move(m_queue.begin()->second);
|
||||
m_queue.erase(m_queue.begin());
|
||||
handle.resume();
|
||||
resumed = true;
|
||||
}
|
||||
|
||||
if (!m_zeroDelayed.empty()) {
|
||||
for (auto&& handle : m_zeroDelayed) handle.resume();
|
||||
m_zeroDelayed.clear();
|
||||
resumed = true;
|
||||
}
|
||||
|
||||
if (!resumed) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
"%Error: Encountered process that should've been resumed at an "
|
||||
"earlier simulation time. Missed a time slot?\n");
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t VlDelayScheduler::nextTimeSlot() const {
|
||||
if (empty()) {
|
||||
if (!m_queue.empty()) return m_queue.begin()->first;
|
||||
if (m_zeroDelayed.empty())
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: There is no next time slot scheduled");
|
||||
}
|
||||
return m_queue.front().m_timestep;
|
||||
return m_context.time();
|
||||
}
|
||||
|
||||
#ifdef VL_DEBUG
|
||||
@@ -91,7 +92,16 @@ void VlDelayScheduler::dump() const {
|
||||
VL_DBG_MSGF(" No delayed processes:\n");
|
||||
} else {
|
||||
VL_DBG_MSGF(" Delayed processes:\n");
|
||||
for (const auto& susp : m_queue) susp.dump();
|
||||
for (auto& susp : m_zeroDelayed) {
|
||||
VL_DBG_MSGF(" Awaiting #0-delayed resumption, "
|
||||
"time () %" PRIu64 ": ",
|
||||
m_context.time());
|
||||
susp.dump();
|
||||
}
|
||||
for (const auto& susp : m_queue) {
|
||||
VL_DBG_MSGF(" Awaiting time %" PRIu64 ": ", susp.first);
|
||||
susp.second.dump();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -153,11 +163,12 @@ void VlTriggerScheduler::dump(const char* eventDescription) const {
|
||||
// VlDynamicTriggerScheduler:: Methods
|
||||
|
||||
bool VlDynamicTriggerScheduler::evaluate() {
|
||||
m_anyTriggered = false;
|
||||
VL_DEBUG_IF(dump(););
|
||||
std::swap(m_suspended, m_evaluated);
|
||||
for (auto& coro : m_evaluated) coro.resume();
|
||||
m_evaluated.clear();
|
||||
return !m_triggered.empty();
|
||||
return m_anyTriggered;
|
||||
}
|
||||
|
||||
void VlDynamicTriggerScheduler::doPostUpdates() {
|
||||
|
||||
+37
-23
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "verilated.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
// clang-format off
|
||||
// Some preprocessor magic to support both Clang and GCC coroutines with both libc++ and libstdc++
|
||||
#if defined _LIBCPP_VERSION // libc++
|
||||
@@ -36,15 +38,15 @@
|
||||
# endif
|
||||
# include <experimental/coroutine>
|
||||
namespace std {
|
||||
using namespace experimental; // Bring std::experimental into the std namespace
|
||||
using namespace experimental; // Bring std::experimental into the std namespace
|
||||
}
|
||||
#else
|
||||
# if defined __clang__ && defined __GLIBCXX__
|
||||
# if defined __clang__ && defined __GLIBCXX__ && !defined __cpp_impl_coroutine
|
||||
# define __cpp_impl_coroutine 1 // Clang doesn't define this, but it's needed for libstdc++
|
||||
# endif
|
||||
# include <coroutine>
|
||||
# if __clang_major__ < 14
|
||||
namespace std { // Bring coroutine library into std::experimental, as Clang < 14 expects it to be there
|
||||
namespace std { // Bring coroutine library into std::experimental, as Clang < 14 expects it to be there
|
||||
namespace experimental {
|
||||
using namespace std;
|
||||
}
|
||||
@@ -148,29 +150,21 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
enum class VlDelayPhase : bool { ACTIVE, INACTIVE };
|
||||
|
||||
//=============================================================================
|
||||
// VlDelayScheduler stores coroutines to be resumed at a certain simulation time. If the current
|
||||
// time is equal to a coroutine's resume time, the coroutine gets resumed.
|
||||
|
||||
class VlDelayScheduler final {
|
||||
// TYPES
|
||||
struct VlDelayedCoroutine {
|
||||
uint64_t m_timestep; // Simulation time when the coroutine should be resumed
|
||||
VlCoroutineHandle m_handle; // The suspended coroutine to be resumed
|
||||
|
||||
// Comparison operator for std::push_heap(), std::pop_heap()
|
||||
bool operator<(const VlDelayedCoroutine& other) const {
|
||||
return m_timestep > other.m_timestep;
|
||||
}
|
||||
#ifdef VL_DEBUG
|
||||
void dump() const;
|
||||
#endif
|
||||
};
|
||||
using VlDelayedCoroutineQueue = std::vector<VlDelayedCoroutine>;
|
||||
// Time-sorted queue of timestamps and handles
|
||||
using VlDelayedCoroutineQueue = std::multimap<uint64_t, VlCoroutineHandle>;
|
||||
|
||||
// MEMBERS
|
||||
VerilatedContext& m_context;
|
||||
VlDelayedCoroutineQueue m_queue; // Coroutines to be restored at a certain simulation time
|
||||
std::vector<VlCoroutineHandle> m_zeroDelayed; // Coroutines waiting for #0
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
@@ -183,10 +177,11 @@ public:
|
||||
// coroutines)
|
||||
uint64_t nextTimeSlot() const;
|
||||
// Are there no delayed coroutines awaiting?
|
||||
bool empty() const { return m_queue.empty(); }
|
||||
bool empty() const { return m_queue.empty() && m_zeroDelayed.empty(); }
|
||||
// Are there coroutines to resume at the current simulation time?
|
||||
bool awaitingCurrentTime() const {
|
||||
return !empty() && m_queue.front().m_timestep <= m_context.time();
|
||||
return (!m_queue.empty() && (m_queue.begin()->first <= m_context.time()))
|
||||
|| !m_zeroDelayed.empty();
|
||||
}
|
||||
#ifdef VL_DEBUG
|
||||
void dump() const;
|
||||
@@ -197,19 +192,34 @@ public:
|
||||
struct Awaitable {
|
||||
VlProcessRef process; // Data of the suspended process, null if not needed
|
||||
VlDelayedCoroutineQueue& queue;
|
||||
std::vector<VlCoroutineHandle>& queueZeroDelay;
|
||||
uint64_t delay;
|
||||
VlDelayPhase phase;
|
||||
VlFileLineDebug fileline;
|
||||
|
||||
bool await_ready() const { return false; } // Always suspend
|
||||
void await_suspend(std::coroutine_handle<> coro) {
|
||||
queue.push_back({delay, VlCoroutineHandle{coro, process, fileline}});
|
||||
// Move last element to the proper place in the max-heap
|
||||
std::push_heap(queue.begin(), queue.end());
|
||||
if (phase == VlDelayPhase::ACTIVE) {
|
||||
queue.emplace(delay, VlCoroutineHandle{coro, process, fileline});
|
||||
} else {
|
||||
queueZeroDelay.emplace_back(VlCoroutineHandle{coro, process, fileline});
|
||||
}
|
||||
}
|
||||
void await_resume() const {}
|
||||
};
|
||||
return Awaitable{process, m_queue, m_context.time() + delay,
|
||||
VlFileLineDebug{filename, lineno}};
|
||||
|
||||
VlDelayPhase phase = (delay == 0) ? VlDelayPhase::INACTIVE : VlDelayPhase::ACTIVE;
|
||||
#ifdef VL_DEBUG
|
||||
if (phase == VlDelayPhase::INACTIVE) {
|
||||
VL_WARN_MT(filename, lineno, VL_UNKNOWN,
|
||||
"Encountered #0 delay. #0 scheduling support is incomplete and the "
|
||||
"process will be resumed before combinational logic evaluation.");
|
||||
}
|
||||
#endif
|
||||
|
||||
return Awaitable{process, m_queue,
|
||||
m_zeroDelayed, m_context.time() + delay,
|
||||
phase, VlFileLineDebug{filename, lineno}};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -275,6 +285,7 @@ public:
|
||||
// co_await __VdynSched.evaluation();
|
||||
// <pre updates>;
|
||||
// __Vtrigger = <trigger eval>;
|
||||
// __VdynShed.anyTriggered(__Vtrigger);
|
||||
// [optionally] co_await __VdynSched.postUpdate();
|
||||
// <post updates>;
|
||||
// }
|
||||
@@ -288,6 +299,7 @@ class VlDynamicTriggerScheduler final {
|
||||
using VlCoroutineVec = std::vector<VlCoroutineHandle>;
|
||||
|
||||
// MEMBERS
|
||||
bool m_anyTriggered = false; // If true, at least one trigger was set
|
||||
VlCoroutineVec m_suspended; // Suspended coroutines awaiting trigger evaluation
|
||||
VlCoroutineVec m_evaluated; // Coroutines currently being evaluated (for evaluate())
|
||||
VlCoroutineVec m_triggered; // Coroutines whose triggers were set, and are awaiting resumption
|
||||
@@ -313,6 +325,8 @@ class VlDynamicTriggerScheduler final {
|
||||
public:
|
||||
// Evaluates all dynamic triggers (resumed coroutines that co_await evaluation())
|
||||
bool evaluate();
|
||||
// Called by coroutines that evaluate triggers to notify the scheduler if any triggers were set
|
||||
void anyTriggered(bool triggered) { m_anyTriggered = m_anyTriggered || triggered; }
|
||||
// Runs post updates for all dynamic triggers (resumes coroutines that co_await postUpdate())
|
||||
void doPostUpdates();
|
||||
// Resumes all coroutines whose triggers are set (those that co_await resumption())
|
||||
|
||||
+83
-29
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2023 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2024 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.
|
||||
@@ -25,7 +25,6 @@
|
||||
// clang-format off
|
||||
|
||||
#include "verilated.h"
|
||||
#include "verilated_trace_defs.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <condition_variable>
|
||||
@@ -46,6 +45,54 @@ class VerilatedTraceBuffer;
|
||||
template <class T_Buffer>
|
||||
class VerilatedTraceOffloadBuffer;
|
||||
|
||||
//=============================================================================
|
||||
// Common enumerations
|
||||
|
||||
enum class VerilatedTracePrefixType : uint32_t {
|
||||
// Note: Entries must match VTracePrefixType (by name, not necessarily by value)
|
||||
ARRAY_PACKED,
|
||||
ARRAY_UNPACKED,
|
||||
SCOPE_MODULE,
|
||||
SCOPE_INTERFACE,
|
||||
STRUCT_PACKED,
|
||||
STRUCT_UNPACKED,
|
||||
UNION_PACKED
|
||||
};
|
||||
|
||||
// Direction attribute for ports
|
||||
enum class VerilatedTraceSigDirection : uint32_t {
|
||||
NONE,
|
||||
INPUT,
|
||||
OUTPUT,
|
||||
INOUT,
|
||||
};
|
||||
|
||||
// Kind of signal. Similar to nettype but with a few more alternatives
|
||||
enum class VerilatedTraceSigKind : uint32_t {
|
||||
PARAMETER,
|
||||
SUPPLY0,
|
||||
SUPPLY1,
|
||||
TRI,
|
||||
TRI0,
|
||||
TRI1,
|
||||
WIRE,
|
||||
VAR,
|
||||
};
|
||||
|
||||
// Base data type of signal
|
||||
enum class VerilatedTraceSigType : uint32_t {
|
||||
DOUBLE,
|
||||
INTEGER,
|
||||
BIT,
|
||||
LOGIC,
|
||||
INT,
|
||||
SHORTINT,
|
||||
LONGINT,
|
||||
BYTE,
|
||||
EVENT,
|
||||
TIME,
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// Offloaded tracing
|
||||
|
||||
@@ -162,24 +209,29 @@ private:
|
||||
// (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 { // The callback
|
||||
const union { // The callback
|
||||
initCb_t m_initCb;
|
||||
dumpCb_t m_dumpCb;
|
||||
dumpOffloadCb_t m_dumpOffloadCb;
|
||||
cleanupCb_t m_cleanupCb;
|
||||
};
|
||||
void* m_userp; // The user pointer to pass to the callback (the symbol table)
|
||||
const uint32_t m_fidx; // The index of the tracing function
|
||||
void* const m_userp; // The user pointer to pass to the callback (the symbol table)
|
||||
CallbackRecord(initCb_t cb, void* userp)
|
||||
: m_initCb{cb}
|
||||
, m_fidx{0}
|
||||
, m_userp{userp} {}
|
||||
CallbackRecord(dumpCb_t cb, void* userp)
|
||||
CallbackRecord(dumpCb_t cb, uint32_t fidx, void* userp)
|
||||
: m_dumpCb{cb}
|
||||
, m_fidx{fidx}
|
||||
, m_userp{userp} {}
|
||||
CallbackRecord(dumpOffloadCb_t cb, void* userp)
|
||||
CallbackRecord(dumpOffloadCb_t cb, uint32_t fidx, void* userp)
|
||||
: m_dumpOffloadCb{cb}
|
||||
, m_fidx{fidx}
|
||||
, m_userp{userp} {}
|
||||
CallbackRecord(cleanupCb_t cb, void* userp)
|
||||
: m_cleanupCb{cb}
|
||||
, m_fidx{0}
|
||||
, m_userp{userp} {}
|
||||
};
|
||||
|
||||
@@ -212,18 +264,20 @@ protected:
|
||||
private:
|
||||
std::vector<bool> m_sigs_enabledVec; // Staging for m_sigs_enabledp
|
||||
std::vector<CallbackRecord> m_initCbs; // Routines to initialize tracing
|
||||
std::vector<CallbackRecord> m_constCbs; // Routines to perform const dump
|
||||
std::vector<CallbackRecord> m_constOffloadCbs; // Routines to perform offloaded const dump
|
||||
std::vector<CallbackRecord> m_fullCbs; // Routines to perform full dump
|
||||
std::vector<CallbackRecord> m_fullOffloadCbs; // Routines to perform offloaded full dump
|
||||
std::vector<CallbackRecord> m_chgCbs; // Routines to perform incremental dump
|
||||
std::vector<CallbackRecord> m_chgOffloadCbs; // Routines to perform offloaded incremental dump
|
||||
std::vector<CallbackRecord> m_cleanupCbs; // Routines to call at the end of dump
|
||||
bool m_constDump = true; // Whether a const dump is required on the next call to 'dump'
|
||||
bool m_fullDump = true; // Whether a full dump is required on the next call to 'dump'
|
||||
uint32_t m_nextCode = 0; // Next code number to assign
|
||||
uint32_t m_numSignals = 0; // Number of distinct signals
|
||||
uint32_t m_maxBits = 0; // Number of bits in the widest signal
|
||||
std::vector<std::string> m_namePrefixStack{""}; // Path prefixes to add to signal names
|
||||
// TODO: Should keep this as a Trie, that is how it's accessed all the time.
|
||||
std::vector<std::pair<int, std::string>> m_dumpvars; // dumpvar() entries
|
||||
char m_scopeEscape = '.';
|
||||
double m_timeRes = 1e-9; // Time resolution (ns/ms etc)
|
||||
double m_timeUnit = 1e-0; // Time units (ns/ms etc)
|
||||
uint64_t m_timeLastDump = 0; // Last time we did a dump
|
||||
@@ -289,6 +343,7 @@ protected:
|
||||
uint32_t nextCode() const { return m_nextCode; }
|
||||
uint32_t numSignals() const { return m_numSignals; }
|
||||
uint32_t maxBits() const { return m_maxBits; }
|
||||
void constDump(bool value) { m_constDump = value; }
|
||||
void fullDump(bool value) { m_fullDump = value; }
|
||||
|
||||
double timeRes() const { return m_timeRes; }
|
||||
@@ -298,14 +353,7 @@ protected:
|
||||
void traceInit() VL_MT_UNSAFE;
|
||||
|
||||
// Declare new signal and return true if enabled
|
||||
bool declCode(uint32_t code, const char* namep, uint32_t bits, bool tri);
|
||||
|
||||
// Is this an escape?
|
||||
bool isScopeEscape(char c) { return std::isspace(c) || c == m_scopeEscape; }
|
||||
// Character that splits scopes. Note whitespace are ALWAYS escapes.
|
||||
char scopeEscape() { return m_scopeEscape; }
|
||||
// Prefix to assume in signal declarations
|
||||
const std::string& namePrefix() const { return m_namePrefixStack.back(); }
|
||||
bool declCode(uint32_t code, const std::string& declName, uint32_t bits);
|
||||
|
||||
void closeBase();
|
||||
void flushBase();
|
||||
@@ -313,6 +361,13 @@ protected:
|
||||
bool offload() const { return m_offload; }
|
||||
bool parallel() const { return m_parallel; }
|
||||
|
||||
// Return last ' ' separated word. Assumes string does not end in ' '.
|
||||
static std::string lastWord(const std::string& str) {
|
||||
const size_t idx = str.rfind(' ');
|
||||
if (idx == std::string::npos) return str;
|
||||
return str.substr(idx + 1);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Virtual functions to be provided by the format specific implementation
|
||||
|
||||
@@ -325,7 +380,7 @@ protected:
|
||||
virtual bool preChangeDump() = 0;
|
||||
|
||||
// Trace buffer management
|
||||
virtual Buffer* getTraceBuffer() = 0;
|
||||
virtual Buffer* getTraceBuffer(uint32_t fidx) = 0;
|
||||
virtual void commitTraceBuffer(Buffer*) = 0;
|
||||
|
||||
// Configure sub-class
|
||||
@@ -359,16 +414,13 @@ public:
|
||||
|
||||
void addModel(VerilatedModel*) VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
void addInitCb(initCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void addFullCb(dumpCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void addFullCb(dumpOffloadCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void addChgCb(dumpCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void addChgCb(dumpOffloadCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void addConstCb(dumpCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addConstCb(dumpOffloadCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addFullCb(dumpCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addFullCb(dumpOffloadCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addChgCb(dumpCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addChgCb(dumpOffloadCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addCleanupCb(cleanupCb_t cb, void* userp) VL_MT_SAFE;
|
||||
|
||||
void scopeEscape(char flag) { m_scopeEscape = flag; }
|
||||
|
||||
void pushNamePrefix(const std::string&);
|
||||
void popNamePrefix(unsigned count = 1);
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
@@ -423,7 +475,7 @@ public:
|
||||
void fullQData(uint32_t* oldp, QData newval, int bits);
|
||||
void fullWData(uint32_t* oldp, const WData* newvalp, int bits);
|
||||
void fullDouble(uint32_t* oldp, double newval);
|
||||
void fullEvent(uint32_t* oldp, VlEvent newval);
|
||||
void fullEvent(uint32_t* oldp, const VlEventBase* newval);
|
||||
|
||||
// In non-offload mode, these are called directly by the trace callbacks,
|
||||
// and are called chg*. In offload mode, they are called by the worker
|
||||
@@ -460,7 +512,9 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
VL_ATTR_ALWINLINE void chgEvent(uint32_t* oldp, VlEvent newval) { fullEvent(oldp, newval); }
|
||||
VL_ATTR_ALWINLINE void chgEvent(uint32_t* oldp, const VlEventBase* newval) {
|
||||
fullEvent(oldp, newval);
|
||||
}
|
||||
VL_ATTR_ALWINLINE void chgDouble(uint32_t* oldp, double newval) {
|
||||
double old;
|
||||
std::memcpy(&old, oldp, sizeof(old));
|
||||
@@ -539,7 +593,7 @@ public:
|
||||
m_offloadBufferWritep += 4;
|
||||
VL_DEBUG_IF(assert(m_offloadBufferWritep <= m_offloadBufferEndp););
|
||||
}
|
||||
void chgEvent(uint32_t code, VlEvent newval) {
|
||||
void chgEvent(uint32_t code, const VlEventBase* newval) {
|
||||
m_offloadBufferWritep[0] = VerilatedTraceOffloadCommand::CHG_EVENT;
|
||||
m_offloadBufferWritep[1] = code;
|
||||
m_offloadBufferWritep += 2;
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2023 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
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilated tracing types
|
||||
///
|
||||
/// This file is not part of the Verilated public-facing API.
|
||||
/// It is only for internal use by Verilated tracing routines.
|
||||
///
|
||||
//=============================================================================
|
||||
#ifndef VERILATOR_VERILATED_TRACE_DEFS_H_
|
||||
#define VERILATOR_VERILATED_TRACE_DEFS_H_
|
||||
|
||||
// Verilator tracing scope types:
|
||||
// The values should match FST_ST_VCD_* from fstScopeType in gtkwave/fstapi.h
|
||||
// verilated_fst_c.cpp contains assertions to enforce this
|
||||
enum VltTraceScope {
|
||||
VLT_TRACE_SCOPE_MODULE = 0,
|
||||
VLT_TRACE_SCOPE_TASK = 1,
|
||||
VLT_TRACE_SCOPE_FUNCTION = 2,
|
||||
VLT_TRACE_SCOPE_BEGIN = 3,
|
||||
VLT_TRACE_SCOPE_FORK = 4,
|
||||
VLT_TRACE_SCOPE_GENERATE = 5,
|
||||
VLT_TRACE_SCOPE_STRUCT = 6,
|
||||
VLT_TRACE_SCOPE_UNION = 7,
|
||||
VLT_TRACE_SCOPE_CLASS = 8,
|
||||
VLT_TRACE_SCOPE_INTERFACE = 9,
|
||||
VLT_TRACE_SCOPE_PACKAGE = 10,
|
||||
VLT_TRACE_SCOPE_PROGRAM = 11
|
||||
};
|
||||
|
||||
#endif // guard
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2023 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2024 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.
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
#if 0
|
||||
# include <iostream>
|
||||
# define VL_TRACE_OFFLOAD_DEBUG(msg) std::cout << "TRACE OFFLOAD THREAD: " << msg << std::endl
|
||||
# define VL_TRACE_OFFLOAD_DEBUG(msg) std::cout << "TRACE OFFLOAD THREAD: " << msg << "\n"
|
||||
#else
|
||||
# define VL_TRACE_OFFLOAD_DEBUG(msg)
|
||||
#endif
|
||||
@@ -64,9 +64,9 @@ static std::string doubleToTimescale(double value) VL_PURE {
|
||||
const char* suffixp = "s";
|
||||
// clang-format off
|
||||
if (value >= 1e0) { suffixp = "s"; value *= 1e0; }
|
||||
else if (value >= 1e-3 ) { suffixp = "ms"; value *= 1e3; }
|
||||
else if (value >= 1e-6 ) { suffixp = "us"; value *= 1e6; }
|
||||
else if (value >= 1e-9 ) { suffixp = "ns"; value *= 1e9; }
|
||||
else if (value >= 1e-3) { suffixp = "ms"; value *= 1e3; }
|
||||
else if (value >= 1e-6) { suffixp = "us"; value *= 1e6; }
|
||||
else if (value >= 1e-9) { suffixp = "ns"; value *= 1e9; }
|
||||
else if (value >= 1e-12) { suffixp = "ps"; value *= 1e12; }
|
||||
else if (value >= 1e-15) { suffixp = "fs"; value *= 1e15; }
|
||||
else if (value >= 1e-18) { suffixp = "as"; value *= 1e18; }
|
||||
@@ -185,7 +185,7 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::offloadWorkerThreadMain() {
|
||||
continue;
|
||||
case VerilatedTraceOffloadCommand::CHG_EVENT:
|
||||
VL_TRACE_OFFLOAD_DEBUG("Command CHG_EVENT " << top);
|
||||
traceBufp->chgEvent(oldp, *reinterpret_cast<const VlEvent*>(readp));
|
||||
traceBufp->chgEvent(oldp, reinterpret_cast<const VlEventBase*>(readp));
|
||||
continue;
|
||||
|
||||
//===
|
||||
@@ -328,10 +328,7 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::traceInit() VL_MT_UNSAFE {
|
||||
// Call all initialize callbacks, which will:
|
||||
// - Call decl* for each signal (these eventually call ::declCode)
|
||||
// - Store the base code
|
||||
for (uint32_t i = 0; i < m_initCbs.size(); ++i) {
|
||||
const CallbackRecord& cbr = m_initCbs[i];
|
||||
cbr.m_initCb(cbr.m_userp, self(), nextCode());
|
||||
}
|
||||
for (const CallbackRecord& cbr : m_initCbs) cbr.m_initCb(cbr.m_userp, self(), nextCode());
|
||||
|
||||
if (expectedCodes && nextCode() != expectedCodes) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
@@ -378,13 +375,12 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::traceInit() VL_MT_UNSAFE {
|
||||
}
|
||||
|
||||
template <>
|
||||
bool VerilatedTrace<VL_SUB_T, VL_BUF_T>::declCode(uint32_t code, const char* namep, uint32_t bits,
|
||||
bool tri) {
|
||||
bool VerilatedTrace<VL_SUB_T, VL_BUF_T>::declCode(uint32_t code, const std::string& declName,
|
||||
uint32_t bits) {
|
||||
if (VL_UNCOVERABLE(!code)) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", "Internal: internal trace problem, code 0 is illegal");
|
||||
}
|
||||
// To keep it simple, this is O(enables * signals), but we expect few enables
|
||||
std::string declName = namePrefix() + namep;
|
||||
bool enabled = false;
|
||||
if (m_dumpvars.empty()) enabled = true;
|
||||
for (const auto& item : m_dumpvars) {
|
||||
@@ -410,10 +406,7 @@ bool VerilatedTrace<VL_SUB_T, VL_BUF_T>::declCode(uint32_t code, const char* nam
|
||||
break;
|
||||
}
|
||||
|
||||
// Note: The tri-state flag is not used by Verilator, but is here for
|
||||
// compatibility with some foreign code.
|
||||
int codesNeeded = VL_WORDS_I(bits);
|
||||
if (tri) codesNeeded *= 2;
|
||||
m_nextCode = std::max(m_nextCode, code + codesNeeded);
|
||||
++m_numSignals;
|
||||
m_maxBits = std::max(m_maxBits, bits);
|
||||
@@ -457,7 +450,7 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::dumpvars(int level, const std::string&
|
||||
for (auto& i : hierSpaced) {
|
||||
if (i == '.') i = ' ';
|
||||
}
|
||||
m_dumpvars.push_back(std::make_pair(level, hierSpaced));
|
||||
m_dumpvars.emplace_back(level, hierSpaced);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,16 +491,15 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::runCallbacks(const std::vector<Callback
|
||||
// Main thread executes all jobs with index % threads == 0
|
||||
std::vector<ParallelWorkerData*> mainThreadWorkerData;
|
||||
// Enqueue all the jobs
|
||||
for (unsigned i = 0; i < cbVec.size(); ++i) {
|
||||
const CallbackRecord& cbr = cbVec[i];
|
||||
for (const CallbackRecord& cbr : cbVec) {
|
||||
// Always get the trace buffer on the main thread
|
||||
Buffer* const bufp = getTraceBuffer();
|
||||
Buffer* const bufp = getTraceBuffer(cbr.m_fidx);
|
||||
// Create new work item
|
||||
workerData.emplace_back(cbr.m_dumpCb, cbr.m_userp, bufp);
|
||||
// Grab the new work item
|
||||
ParallelWorkerData* const itemp = &workerData.back();
|
||||
// Enqueue task to thread pool, or main thread
|
||||
if (unsigned rem = i % threads) {
|
||||
if (unsigned rem = cbr.m_fidx % threads) {
|
||||
threadPoolp->workerp(rem - 1)->addTask(parallelWorkerTask, itemp);
|
||||
} else {
|
||||
mainThreadWorkerData.push_back(itemp);
|
||||
@@ -530,7 +522,7 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::runCallbacks(const std::vector<Callback
|
||||
}
|
||||
// Fall back on sequential execution
|
||||
for (const CallbackRecord& cbr : cbVec) {
|
||||
Buffer* const traceBufferp = getTraceBuffer();
|
||||
Buffer* const traceBufferp = getTraceBuffer(cbr.m_fidx);
|
||||
cbr.m_dumpCb(cbr.m_userp, traceBufferp);
|
||||
commitTraceBuffer(traceBufferp);
|
||||
}
|
||||
@@ -541,7 +533,7 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::runOffloadedCallbacks(
|
||||
const std::vector<CallbackRecord>& cbVec) {
|
||||
// Fall back on sequential execution
|
||||
for (const CallbackRecord& cbr : cbVec) {
|
||||
Buffer* traceBufferp = getTraceBuffer();
|
||||
Buffer* traceBufferp = getTraceBuffer(cbr.m_fidx);
|
||||
cbr.m_dumpOffloadCb(cbr.m_userp, static_cast<OffloadBuffer*>(traceBufferp));
|
||||
commitTraceBuffer(traceBufferp);
|
||||
}
|
||||
@@ -610,11 +602,17 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::dump(uint64_t timeui) VL_MT_SAFE_EXCLUD
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < m_cleanupCbs.size(); ++i) {
|
||||
const CallbackRecord& cbr = m_cleanupCbs[i];
|
||||
cbr.m_cleanupCb(cbr.m_userp, self());
|
||||
if (VL_UNLIKELY(m_constDump)) {
|
||||
m_constDump = false;
|
||||
if (offload()) {
|
||||
runOffloadedCallbacks(m_constOffloadCbs);
|
||||
} else {
|
||||
runCallbacks(m_constCbs);
|
||||
}
|
||||
}
|
||||
|
||||
for (const CallbackRecord& cbr : m_cleanupCbs) cbr.m_cleanupCb(cbr.m_userp, self());
|
||||
|
||||
if (offload() && VL_LIKELY(bufferp)) {
|
||||
// Mark end of the offload buffer we just filled
|
||||
*m_offloadBufferWritep++ = VerilatedTraceOffloadCommand::END;
|
||||
@@ -695,37 +693,40 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addInitCb(initCb_t cb, void* userp) VL_
|
||||
addCallbackRecord(m_initCbs, CallbackRecord{cb, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addFullCb(dumpCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_fullCbs, CallbackRecord{cb, userp});
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addConstCb(dumpCb_t cb, uint32_t fidx,
|
||||
void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_constCbs, CallbackRecord{cb, fidx, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addFullCb(dumpOffloadCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_fullOffloadCbs, CallbackRecord{cb, userp});
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addConstCb(dumpOffloadCb_t cb, uint32_t fidx,
|
||||
void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_constOffloadCbs, CallbackRecord{cb, fidx, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addChgCb(dumpCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_chgCbs, CallbackRecord{cb, userp});
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addFullCb(dumpCb_t cb, uint32_t fidx,
|
||||
void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_fullCbs, CallbackRecord{cb, fidx, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addChgCb(dumpOffloadCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_chgOffloadCbs, CallbackRecord{cb, userp});
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addFullCb(dumpOffloadCb_t cb, uint32_t fidx,
|
||||
void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_fullOffloadCbs, CallbackRecord{cb, fidx, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addChgCb(dumpCb_t cb, uint32_t fidx,
|
||||
void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_chgCbs, CallbackRecord{cb, fidx, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addChgCb(dumpOffloadCb_t cb, uint32_t fidx,
|
||||
void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_chgOffloadCbs, CallbackRecord{cb, fidx, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addCleanupCb(cleanupCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_cleanupCbs, CallbackRecord{cb, userp});
|
||||
}
|
||||
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::pushNamePrefix(const std::string& prefix) {
|
||||
m_namePrefixStack.push_back(m_namePrefixStack.back() + prefix);
|
||||
}
|
||||
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::popNamePrefix(unsigned count) {
|
||||
while (count--) m_namePrefixStack.pop_back();
|
||||
assert(!m_namePrefixStack.empty());
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Primitives converting binary values to strings...
|
||||
|
||||
@@ -839,7 +840,7 @@ void VerilatedTraceBuffer<VL_BUF_T>::fullBit(uint32_t* oldp, CData newval) {
|
||||
}
|
||||
|
||||
template <>
|
||||
void VerilatedTraceBuffer<VL_BUF_T>::fullEvent(uint32_t* oldp, VlEvent newval) {
|
||||
void VerilatedTraceBuffer<VL_BUF_T>::fullEvent(uint32_t* oldp, const VlEventBase* newval) {
|
||||
const uint32_t code = oldp - m_sigs_oldvalp;
|
||||
*oldp = 1; // Do we really store an "event" ?
|
||||
emitEvent(code, newval);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user