Compare commits

...
337 Commits
Author SHA1 Message Date
Wilson Snyder cd693ce02b Version bump 2024-06-15 08:43:45 -04:00
Wilson Snyder 2641bc98aa Update include/gtkwave from upstream 2024-06-15 08:14:43 -04:00
Wilson Snyder ad2862ce3f Fix DPI import of null C-string (#5179). 2024-06-14 22:50:54 -04:00
Bartłomiej Chmiel 4695967185 Fix signed types emitted in hierarchical Verilation (#5178)
Signed-off-by: Bartłomiej Chmiel <[email protected]>
2024-06-14 08:07:32 -04:00
Wilson Snyder f96e99542c Internals: Fix cppcheck warnings. No functional change. 2024-06-13 21:29:03 -04:00
Wilson Snyder 7de193c2e9 Commentary: Changes update 2024-06-13 18:04:57 -04:00
Arkadiusz Kozdra 442c9bc316 Support parsing and otherwise ignoring inline constraints (#5126) 2024-06-13 08:38:20 -04:00
Arkadiusz Kozdra 3203019408 Fix coroutines without awaits to have a co_return (#4208) (#5175)
After the V3Timing refactoring the V3SchedTiming phase could apparently
move away all awaits from a coroutine without adding a co_return
statement.

Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-06-12 15:13:52 -04:00
Geza Lore bc853e260b Support StructSel in unpacked array assignments (#5176) 2024-06-12 17:07:33 +01:00
github action d6e5703298 Apply 'make format' 2024-06-12 11:44:29 +00:00
Alex Solomatnikov a9e50327fd Fix hierarchical compilation with nested -F (#5114) (#5124) 2024-06-12 07:42:52 -04:00
Wilson Snyder 6f0a36318e Tests: Fix test stability (#5167 update). 2024-06-11 20:55:01 -04:00
Wilson Snyder 221fecad0b Commentary 2024-06-11 19:47:53 -04:00
Wilson Snyder fd1e4d9e45 Add assertion on reusing VerilatedContext (#5167). 2024-06-11 19:38:58 -04:00
Wilson Snyder 920ed5ca3d Internals: Avoid unordered_map/set. No functional change intended. 2024-06-11 18:52:09 -04:00
Arthur Rosa 2537431273 Fix table optimization when applied on real data type (#5172) (#5173) 2024-06-11 13:26:11 -04:00
Bartłomiej Chmiel 13114f2efe Fix SystemC BITS_PER_DIGIT in VL_ASSIGN_SBW (#5170)
The BITS_PER_DIGIT macro value differs between SystemC versions,
thus referencing it directly is required.
2024-06-10 20:45:49 -04:00
Arkadiusz Kozdra e9f59e44a5 Fix non-constant replication in concats (#5171)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-06-10 11:21:43 -04:00
Arkadiusz Kozdra d4c3e35f97 Support $psprintf system function (#4314) (#5169)
`$psprintf` is a non-standard system function present in some other
simulators, and has been rejected for standardization by IEEE because
of being basically the same as `$sformatf`.

To encourage users to fix their codebase, a warning is emitted by
default, but it gets otherwise interpreted as `$sformatf` as early as
during lexing.

Signed-off-by: Arkadiusz Kozdra <[email protected]>

* wording/formatting

Signed-off-by: Arkadiusz Kozdra <[email protected]>

---------

Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-06-10 08:38:26 -04:00
Wilson Snyder 02dd33b60e Commentary: Changes update 2024-06-09 17:10:53 -04:00
Geza Lore 2bc883f3b3 Extend out-of-range select (#5159) (#5164) 2024-06-09 17:05:14 -04:00
Geza Lore 29db25b70e Reset radix in width warnings (#5166) 2024-06-09 14:39:17 +01:00
Geza Lore d6bc0c712a Disable ASLR for more tests. (#5165)
These show spurious errors with some toolchains due to an address sanitizer bug.
2024-06-09 14:32:31 +01:00
github action 962efa3691 Apply 'make format' 2024-06-09 02:45:26 +00:00
Valentin Atepalikhin 4babba16d6 Support 2D dynamic array initialization (#4700) (#5122)
* Support 2D dynamic array initialization (#4700)
- new[] on sub arrays (as per original issue)
- Built-in methods for sub-arrays
- Initialization and literals assignmensts
- Dynamic array as an element for other arrays and queues
2024-06-08 22:44:45 -04:00
Wilson Snyder 5363d89870 Tests: Disable msbuild executable running (#5163) 2024-06-08 19:37:31 -04:00
Wilson Snyder 44acb08ea9 Tests: Commentary - enable msbuild debug 2024-06-08 19:36:50 -04:00
Yutetsu TAKATSUKASA 6584b4d426 Fix assertion failure in V3Gate (#5101) 2024-06-08 08:37:01 -04:00
Paul Bowen-Huggett 9ff06c1664 Fix 'experimental/coroutine' file not found on macOS (#5030) (#5031) (#5151)
libcxx has removed the experimental/coroutine include file in favor of
the C++20-standard coroutine include. If the latter is available we
use it otherwise falling back to the existing experimental version (in
which case we also disable the deprecated-experimental-coroutine warning).

(See also https://reviews.llvm.org/D108697.)
2024-06-08 08:33:50 -04:00
github action 1537c9badc Apply 'make format' 2024-06-08 03:05:01 +00:00
Wilson Snyder 708f875b31 Fix MSVC warnings. No functional change intended. 2024-06-07 22:52:56 -04:00
Kaleb Barrett 0d3cb86a44 Fix VerilatedVpiPutHolder class (#5156) 2024-06-07 22:25:33 -04:00
Wilson Snyder 5c2b9d55b2 Fix MSVC C4805 == type mismatch warning 2024-06-07 22:14:32 -04:00
Arkadiusz Kozdra 1dbf1be3e6 Support inout clocking items (#5160) 2024-06-07 08:30:58 -04:00
Wilson SnyderandDercury 3f886f7c61 Fix select value too wide (#5148) (#5153).
Co-authored-by: Dercury <[email protected]>
2024-06-07 08:27:03 -04:00
Wilson Snyder 7c9fa8647c Fix string to be more standard (#5082) (#5083). 2024-05-31 21:51:12 -04:00
Wilson Snyder dbf68a99e8 Tests: SHow expected values in t_typenames 2024-05-30 22:54:40 -04:00
Andrew NolteandAndrew Nolte 53c2e416f4 Tests: Extend t_typenames (#5083)
Co-authored-by: Andrew Nolte <[email protected]>
2024-05-30 22:32:14 -04:00
github action e834b5be2d Apply 'make format' 2024-05-29 20:56:45 +00:00
Kaleb Barrett bd7689f59a Fix overflow of string on VPI reads (#5145) (#5146) 2024-05-29 16:55:46 -04:00
Kaleb Barrett 3496eb80a5 Improve VerilatedVpiPutHolder storage requirements (#5144) 2024-05-29 08:39:08 -04:00
Ryszard Rozak 839c3bf444 Commentary: Fix docs of verilator_coverage (#5149)
Signed-off-by: Ryszard Rozak <[email protected]>
2024-05-29 08:11:35 -04:00
Geza Lore d4b3583307 Apply DFG regularization to cyclic graphs (#5142)
The Dfg2Ast conversion assumes the 'regularize' pass was run, but we
failed to run it on cyclic sub-graphs. Do so now.

Fixes #5130.
2024-05-26 12:01:30 +01:00
Wilson Snyder ee130cb20d Tests: Skip if no constraint solver 2024-05-23 22:25:14 -04:00
github action 552a146f9c Apply 'make format' 2024-05-22 11:54:22 +00:00
Pawel Jewstafjew 913679f261 Fix output C++ type error on change detect of I/O arrays (#5125) (#5131)
operand order reversed for AstCMethodHard "neq"
interface between C-style arrays and VlUnpacked
overloads added to VlUnpacked::neq(), VlUnpacked::assign()
VlUnpacked::operator=() added

Fixes  #5125
2024-05-22 12:53:28 +01:00
Ethan Sifferman d9078df650 Fix 4-state value support for $readmem (#5070) (#5078) 2024-05-21 17:27:32 -04:00
Wilson Snyder f84592af49 Fix x-valued parameters with --x-assign unique (#5129). 2024-05-21 08:07:57 -04:00
Wilson Snyder 5f85c89425 Commentary: Changes update 2024-05-18 17:48:52 -04:00
Wilson Snyder 94f789b677 Update issue template 2024-05-18 17:41:36 -04:00
Arkadiusz Kozdra 739be2f782 Support constrained randomization with external solvers (#4947) 2024-05-17 10:38:34 -04:00
Krzysztof Bieganski 25b9a16bc7 Fix references to ports in forks (#5123)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-05-17 07:38:36 -04:00
Arkadiusz Kozdra 9a8e68928d Internals: Move getenvStr to verilatedos. (#5118)
* Internals: Move getenvStr to verilatedos. No functional change intended.
* Fix POS34-C. Do not call putenv() with a pointer to an automatic variable as the argument.

Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-05-13 10:23:51 -04:00
Todd Strader 19cccd170e Fix vpiInertialDelay for memories (#5113) 2024-05-10 18:49:43 -04:00
Wilson Snyder d99c8f5d44 Fix redundant AstExtend breaks DFG (#5112) 2024-05-10 18:48:09 -04:00
Geza Lore cf111d2e1f Do not create aliases for forced port signals (#5105)
+ don't remove forced signals in V3Const and Dfg

Fixes #5062
2024-05-10 18:19:51 +01:00
Arkadiusz Kozdra 45eb5b8a5c Fix method calls parsing in constraints (#5110) 2024-05-10 06:37:19 -04:00
Yinan Xu ce5cad17a8 Add increasing of stack size when possible (#5071) (#5104) 2024-05-08 22:40:42 -04:00
Wilson Snyder ed01befc25 Fix tracing interface functions (#5108). 2024-05-08 22:23:53 -04:00
Wilson Snyder 69a2bfee68 Commentary: Changes update 2024-05-08 08:41:56 -04:00
Wilson Snyder 1cc37ad6ce Internals: Add missing VL_DO_DANGLING. No functional change intended. 2024-05-08 08:36:24 -04:00
2a9f29912c Add parameterless assert control system tasks (#5010)
Signed-off-by: Bartłomiej Chmiel <[email protected]>
Co-authored-by: Ryszard Rozak <[email protected]>
Co-authored-by: Wilson Snyder <[email protected]>
Co-authored-by: Arkadiusz Kozdra <[email protected]>
2024-05-08 08:31:34 -04:00
Wilson Snyder 298e0f24d1 Add traceCapable indication to model header (#5053). 2024-05-03 20:18:06 -04:00
Geza Lore 80b08b71aa Support NBAs to arrays inside loops (#5092)
For NBAs that might execute a dynamic number of times in a single
evaluation (specifically: those that assign to array elements inside
loops), we introduce a new run-time VlNBACommitQueue data-structure
(currently a vector), which stores all pending updates and the necessary
info to reconstruct the LHS reference of the AstAssignDly at run-time.

All variables needing a commit queue has their corresponding unique
commit queue.

All NBAs to a variable that requires a commit queue go through the
commit queue. This is necessary to preserve update order in sequential
code, e.g.:
 a[7] <= 10
 for (int i = 1 ; i < 10; ++i) a[i] <= i;
 a[2] <= 10
needs to end with array elements 1..9 being 1, 10, 3, 4, 5, 6, 7, 8, 9.

This enables supporting common forms of NBAs to arrays on the left hand
side of <= in non-suspendable/non-fork code. (Suspendable/fork
implementation is unclear to me so I left it unchanged, see #5084).

Any NBA that does not need a commit queue (i.e.: those that were
supported before), use the same scheme as before, and this patch should
have no effect on the generated code for those NBAs.
2024-05-03 07:45:49 -04:00
Vito Gamberini 64ba569f0d Fix MacOS missing <type_traits> header (#5096) (#5097) 2024-05-02 21:38:36 -04:00
Wilson Snyder 3cb4033c97 Fix width extension of unpacked array select (#5095). 2024-05-02 20:41:39 -04:00
github action 6509bac59e Apply 'make format' 2024-05-02 23:03:39 +00:00
Wilson Snyder ec45a77d93 Fix macro expansion in strings per 1800-2023 (#5094). 2024-05-02 19:02:28 -04:00
Wilson Snyder 8044833c74 Fix $typename on array.min and others (#5049). 2024-05-01 20:07:13 -04:00
Geza Lore 3f89bdcfac Defer conversion of set flag based AssignDlys (#5091)
No functional change. Postpone the conversion of all AstAssignDlys that
use the 'VdlySet' scheme for array LHSs until after the complete
traversal of the netlist. The next patch takes advantage of this by
using some extra information also gathered through the traversal to
change the conversion.

AstAssignDlys inside suspendable or fork are not deferred and are
processed identical to the previous version.

There are some TODOs in this patch that are fixed in the next patch.

Output code perturbed due to variable ordering.

MULTIDRIVEN message ordering perturbed due to processing order change.
2024-05-02 00:24:00 +01:00
Todd Strader c99364b81a Support vpiInertialDelay (#5087) 2024-05-01 18:56:50 -04:00
Geza Lore d841a791e6 Refactor V3Delayed to enable algorithmic extension (#5090)
No functional change.

This patch is just cleanup with some non-functional changes to enable
the next patch. Most importantly createDlyOnSet, which implements NBAs
for arrays, has a new streamlined implementation that does the same
thing. Some output code is perturbed due to statement/local variable
insertion order.

Also renamed Vdlyvfoo to VdlyFoo for easier readability of the generated
code.
2024-05-01 23:06:25 +01:00
Geza Lore b5b937e2f2 Fix missed optimization in V3Delayed (#5089)
Checking the wrong node meant we never actually pushed constant
bit-select indices into the delayed update, as was the intention, but
always generated a temporary instead.
2024-05-01 16:22:56 +01:00
Todd Strader 4a41f69293 Internals: Remove C-style cast in VPI_HANDLE (#5088) 2024-05-01 10:11:44 -04:00
Wilson Snyder 8fd038f88e Add --localize-max-size option and optimization (#5072). 2024-04-30 19:46:54 -04:00
Wilson Snyder 4982f63da2 Update coverage for last commit 2024-04-30 19:34:41 -04:00
Wilson Snyder 71bc60fb91 Add error on zero width select (#5028). 2024-04-30 18:38:37 -04:00
Wilson Snyder 0da7ecf753 Commentary: Changes update 2024-04-30 07:37:06 -04:00
Andrea Calabrese 25ca1af8b3 Internals: Fix missing const (#4899) 2024-04-29 22:57:56 -04:00
Wilson Snyder 5d54fa8e6f Fix missing parameters with comma to be errors (#4979) (#5012). 2024-04-29 22:41:16 -04:00
Christopher Taylor e8c5b9faad Fix missing flex include path variable (#4970) (#4971) 2024-04-29 22:01:09 -04:00
Aleksander Kiryk 8e0301c287 Fix bound queue printing (#5032) 2024-04-29 21:52:06 -04:00
Iztok Jeras 3f625fc359 Tests: Add unsupported streaming LHS tests (#4302) 2024-04-29 21:35:19 -04:00
Geza Lore 72b96d5069 tests: disable ASLR for t_trace_ub_misaligned_address (#5075)
This works around an address-sanitizer bug hit with some GCC versions
2024-04-29 15:38:00 +01:00
Bartłomiej Chmiel d1b45b8d32 Fix attempted to destroy locked thread pool error (#5040) 2024-04-29 07:59:24 -04:00
Wilson Snyder 5601056ed0 Tests: Check for bad event methods 2024-04-28 13:10:25 -04:00
Wilson Snyder 8ed269c77f Make 'disable isn't underneath a begin' into UNSUPPORTED error (#4699). 2024-04-27 21:30:40 -04:00
Geza Lore 27b7e70218 Fix DFG assertion with SystemC (#5076)
Fixes #5050
2024-04-27 13:41:10 +01:00
Geza Lore 97680656d3 Remove unknown '--' form cmake -E (#5073)
After #5063, with cmake 3.22.1, I get test failures, saying:
    cmake -E env: unknown option '--'
The '--' is necessary so removing.
2024-04-27 11:09:59 +01:00
Michael Bikovitsky 4202ec2ab2 Fix CMake builds to export VERILATOR_ROOT (#5063) 2024-04-26 19:29:10 -04:00
Wilson Snyder 4f3a816fb0 Fix false ASSIGNIN on functions with explicit port map (#5069). 2024-04-26 19:26:21 -04:00
Todd Strader 25fd8ef5c0 Add VPI eval needed tracking (#5065) 2024-04-25 09:07:31 -04:00
Gökçe Aydos a9664b8d16 Remove $(info) which cannot be silenced by -MAKEFLAGS '--quiet' (#5059) 2024-04-20 08:48:16 -05:00
Wilson Snyder 26a5729514 Add CITATION.cff (#5057) (#5058). 2024-04-19 20:33:11 -04:00
Arkadiusz Kozdra 5b839699ac Support empty queue as dynarray default value (#5055)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-04-18 11:53:23 -05:00
Wilson Snyder 1315aa31ed Commentary 2024-04-13 08:18:45 -04:00
Wilson Snyder 5d8da6b4ac Fix width extension on delays (#5045). 2024-04-13 08:16:59 -04:00
Wilson Snyder aac2563a07 Commentary: Changes update 2024-04-13 08:03:57 -04:00
Wilson Snyder 8e44487354 Tests: update style 2024-04-13 08:02:25 -04:00
Wilson Snyder 1012c054e6 Fix $system with string argument (#5042). 2024-04-11 17:31:14 -04:00
Paul Wright a8b5738b44 Support __en/__out signals on top level inout ports (#4812) (#4856) 2024-04-11 09:02:58 -04:00
Wilson Snyder 72845167e6 Commenary: Fix README badge paragraph 2024-04-10 17:02:07 -04:00
Krzysztof Bieganski 7ca2d6470a Fix consecutive zero-delays (#5038)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-04-05 16:48:47 -04:00
Wilson Snyder 33e999e01a devel release 2024-04-05 06:23:30 -04:00
Wilson Snyder 522bead374 Version bump 2024-04-05 05:52:00 -04:00
Wilson Snyder 030286142f Commentary: Changes update 2024-04-04 22:11:33 -04:00
Wilson Snyder 8a4ceb5717 Tests: Fix test failure, last commit. 2024-04-02 07:04:27 -04:00
Andrew Nolte 63fa6accc4 [Vpi] Fix missing scopes 2 (#4965) 2024-04-01 23:11:15 -04:00
Wilson Snyder 28718f964a Fix tracing replicated hierarchical models (#5027) (#5029) 2024-03-30 16:00:52 -04:00
Wilson Snyder 1d486e3a59 Rename statsPrintSummary() 2024-03-30 13:19:47 -04:00
Wilson Snyder 9b396f7125 Fix pylint warning 2024-03-30 13:13:51 -04:00
Wilson Snyder e16cbce52e Internals: Fix clang_check_attributes false error print 2024-03-30 11:58:34 -04:00
Wilson Snyder 840970e8f7 Internals: Add VL_MT_SAFE flags 2024-03-30 11:54:29 -04:00
Wilson Snyder e390d6779d Internals: Rename threadsInModel() 2024-03-30 11:13:14 -04:00
Wilson Snyder 39ee522f92 Commentary: Changes update 2024-03-28 08:22:15 -04:00
Wilson Snyder 9526efcf72 Fix V3Hash MacOS ambiguity (#5011) 2024-03-28 08:11:48 -04:00
github action d397e0d838 Apply 'make format' 2024-03-28 11:32:57 +00:00
Szymon Gizler 8301fdc6d3 Add JSON AST dumps (#5020) 2024-03-28 07:32:18 -04:00
Arkadiusz Kozdra f645382f11 Support inside range with implicit type conversion (#5026)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-03-28 07:31:45 -04:00
Wilson Snyder 1ed5557d2d Support 1800-2023 class and function :initial, :extends, :final virtual overrides (#5025). (#5025) 2024-03-27 23:57:58 -04:00
Wilson Snyder 28b9216f8a Fix tracing class parameters (#5014). 2024-03-27 20:07:46 -04:00
Wilson Snyder 0114cb67ca Fix $readmem with missing newline (#5019). 2024-03-27 18:42:20 -04:00
Wilson Snyder ea8f86dd30 Internals: Prefer '(void)' to avoid unused var. No functional change. 2024-03-27 18:07:14 -04:00
Wilson Snyder 0ff77fc352 Internals: Remove extra single-line {}. No functional change. 2024-03-27 17:57:49 -04:00
Wilson Snyder 341963e820 Internals: Avoid '%Error' so can grep logs for real errors 2024-03-27 09:00:34 -04:00
Wilson Snyder db60b92613 Fix internal error on missing pattern key (#5023) 2024-03-27 08:41:58 -04:00
Geza Lore 98206a4f04 Improve V3List user interface (#4996) 2024-03-25 23:06:25 +00:00
Wilson Snyder 4df9e2e0e5 Add printing summary reports (#4909) (#5018) 2024-03-25 07:03:17 -04:00
Wilson Snyder 34e4cffb62 Add stats on output size 2024-03-24 10:50:53 -04:00
Wilson Snyder 71d76c993c Fix MSVC++ warnings. No functional change. 2024-03-24 10:19:26 -04:00
Wilson Snyder e67bdb4c08 Commentary 2024-03-24 09:23:37 -04:00
Wilson Snyder 23f013f2d7 Add stats on input size etc (#5017) 2024-03-24 09:14:31 -04:00
Geza Lore 9b729b80e0 Plug memory leaks (#5016) 2024-03-23 22:12:43 +00:00
Wilson Snyder 38ad328956 Remove duplicate stop ignored messages 2024-03-22 19:35:42 -04:00
Wilson Snyder f767f0cfaa Commentary 2024-03-22 19:35:13 -04:00
Fuad Ismail 1c79df8630 Support stream operation on unpacked array (#4714) (#5006) 2024-03-21 18:26:42 -04:00
Wilson Snyder 248573205b Commentary: Changes update 2024-03-20 18:27:35 -04:00
Arkadiusz Kozdra 88831ca21b Fix preprocessor to respect strings in joins (#5007)
This adheres more to the wording used in IEEE 1800-2017 22.5.1,
specifying the join operator to be more of a delimiter than join:

> A `` delimits lexical tokens without introducing white space,
> allowing identifiers to be constructed from arguments.

Before, string RHS arguments to the join operator were silently dropped.

Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-03-20 08:54:23 -04:00
Arkadiusz Kozdra 26f15e11c4 Fix unique {} constraints missing semicolon (#5001)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-03-19 08:22:39 -04:00
Ryszard Rozak 5c0a7e06dc Fix inout ports of unpacked stuct type (#5000) 2024-03-19 06:43:06 -04:00
Andrew Nolte 290b313dc0 Fix missing VPI scopes (#4918) 2024-03-18 20:47:28 -04:00
Wilson Snyder 93e5ca3f6d Fix class type as an associative array parameter (#4997). 2024-03-18 20:44:18 -04:00
Geza Lore 6ffff8565f Use the same serial ordering within MTasks as we use in serial mode (#4994)
The goal here is to use as single ordering heuristic (which can be
improved later) within MTasks as we do for serial code ordering. The
heuristic itself is factored out into the new OrderMoveGraphSerializer.
This also yields slightly nicer ordering than the previously use
GraphStream, so we end up with fewer trigger (domain) conditionals in
the MTasks, this can be worth a few percent speedup.

This has the somewhat nice side-effect of reusing OrderMoveGraphVertex
for both serial and parallel mode, so MTaskMoveGraphVertex can be
removed.

Serial mode yields identical output.
2024-03-17 13:15:39 +00:00
Geza Lore 494e05b326 Fix install instructions for attribute checks, do the same in CI (#4995)
On Ubuntu 22.04, pip install clang picks up a mismatched version by
default. There are 'apt' packages with correct dependencies, so use
those instead.
2024-03-17 12:10:13 +00:00
Kevin Nygaard a24f61403a Support implicitly-typed variable definitions in for-loop initializers (#4945) (#4986)
- Adds support for C-style for-loop initializers
    - Current implementation supports: for (x a = 1, y b = 2, ...)
    - This patch extends support to:   for (x a = 1,   b = 2, ...)
- Adds unit test for new feature
2024-03-16 19:02:37 -04:00
Geza Lore 292cc54768 Compute MTask affinity in V3VariableOrder (#4991)
Instead of carrying around MTask affinity from scheduling, compute it in
V3VariableOrder (where it is used), by tracing through the code. This
simplifies some code and has the benefit of handling variables
introduced after scheduling. It's worth a few % speed at run-time, and
the new implementation of V3VariableOrder is slightly more efficient,
though the speed/space is still dominated by the TSP sort.
2024-03-16 16:32:12 +00:00
Geza Lore e8a9662eb5 Simplify LogicMTask/ExecMTask IDs (#4990)
There is no strong need to re-map LogicMTask IDs and it just adds extra
processing. Instead we just allocate a separate set of ExecMTask IDs as
they are created, which can also be used as the unique profiling ID as
well. The only effect on the output of this is the change in mtask IDs
emitted, which was fairly arbitrary to begin with.
2024-03-16 14:02:17 +00:00
Wilson Snyder 0262819c20 Fix object assignment from conditionals (#4968). 2024-03-16 09:12:18 -04:00
Wilson Snyder d3b93a1113 Fix object reference to conditional null : null 2024-03-16 09:12:18 -04:00
Wilson Snyder 5f8c06c805 Internals: Add AstNode::isNull(). No functional change. 2024-03-16 09:12:18 -04:00
Kevin Nygaard a5ad26cd28 Fix tests on macOS (#4984) (#4985) 2024-03-16 09:08:03 -04:00
Fuad Ismail 5802818b9a Add error when pass net to function argument (#4132) (#4966) 2024-03-16 08:25:42 -04:00
Geza Lore df519ff16e Fix --prof-exec predicted time values (#4988)
Wrapping the functions in #4933 broke --prof-exec report as the
predicted MTask times are computed during thread packing, but are
emitted in the wrapping functions.
2024-03-16 12:17:24 +00:00
Geza Lore bf8a88a0ad Do not create any empty ExecMTasks (#4987) 2024-03-16 12:00:32 +00:00
Geza Lore 878204db73 Do not feed any empty logic into scheduling (#4972) 2024-03-16 10:35:56 +00:00
Nolan Poe 08c76b1da6 Fix GCC14 warnings on template specialization syntax (#4974) (#4975) 2024-03-15 22:21:08 -04:00
Wilson Snyder e82c9db6da Fix unpacked structure upper bit cleaning (#4978). 2024-03-15 21:56:24 -04:00
Wilson Snyder 65c3cb4708 Tests: stop testing if --fail-max tests fail 2024-03-15 21:11:24 -04:00
Wilson Snyder 0cab076b86 CI: Reenable address sanitizer and fix core dumps (#4983) 2024-03-15 21:06:21 -04:00
Wilson Snyder 3a28ed24ea Revert last bin/verilator change. 2024-03-15 10:34:50 -04:00
Wilson Snyder 71775eae4c sanitize 2024-03-15 10:32:31 -04:00
Wilson Snyder 953249aa43 CI: Add dist-vlt-3 to avoid out of disk space 2024-03-12 07:49:01 -04:00
Wilson Snyder 229dbbb100 Tests: RUn same job count as CPU instead of +1 to reduce CI congestion 2024-03-11 20:13:23 -04:00
Wilson Snyder 4a439beae5 Add error on missing pure virtual functions (#4961). 2024-03-11 18:56:30 -04:00
Wilson Snyder 49022c3e73 Add error on calling static function without object (#4962). 2024-03-11 18:23:55 -04:00
Geza Lore c92ced4ac7 Do not defer deletion in const-bit-op-tree
Deferring deletion of unused terms is not necessary, but can cause huge
memory usage increases in some bad cases.
2024-03-11 17:33:40 +00:00
Wilson Snyder ba47da6587 Internals: Move vl_timescaled_double to verilated_funcs.h. No functional change intended 2024-03-10 22:34:32 -04:00
Wilson Snyder 2c27f22900 Remove unused vltstd::exchange, should be using C++14 std::exchange instead 2024-03-10 22:32:51 -04:00
Geza Lore c0391990ad Increase graph ParallelismReprot values to uint64_t 2024-03-10 18:56:31 +00:00
Geza Lore 2247e1e345 Cleanup/simplify V3OrderParallel (#4959)
No functional change.
2024-03-10 18:15:45 +00:00
Geza Lore e4847464d4 Split V3Partition into logically separate pieces (#4958)
V3Partition used to contain 2 conceptually separate set of algorithms

- The MTask partitioning/coarsening algorithm used by V3Order. This has
  been moved to V3OrderParallel.cpp

- The lowering of AstExecGraph into per thread functions by packing
  tasks into threads and creating additional code
  (V3Partition::finalize). This has been moved to the new
  V3ExecGraph.cpp

This patch is just code movement/rename with minimal fixes required to
do so.
2024-03-10 15:58:58 +00:00
Wilson Snyder 7694a7bf41 Fix suggestion of ulimit -s (#4956) 2024-03-10 11:20:25 -04:00
Geza Lore a686e547cf Factor out graph parallelism report into a generic algorithm (#4957)
This is a generic algorithm parametrised by a cost function, so
implement it as such for easy reuse.
2024-03-10 14:56:43 +00:00
Geza Lore 1481d34959 Add candidate item count to MergeCond stats 2024-03-09 22:11:04 +00:00
Nolan Poe 04512e5d04 Add custom version for verilator --version packaging (#4954) 2024-03-09 16:44:25 -05:00
Geza Lore 9a3aed57b1 Internals: Simplify/cleanup V3OrderSerial (#4955). No functional change.
Remove redundant data structures and simplify/cleanup implementation.

No functional change. Output is identical.
2024-03-09 16:19:35 -05:00
Geza Lore 5a69321be3 Split V3Order into further part and decouple various components (#4953)
Continuing the idea of decoupling the implementations of the various algorithms.

The main points:

-Move the former "processDomain" stuff, dealing with assigning combinational logic into the relevant sensitivity domains into V3OrderProcessDomains.cpp

-Move the parallel code construction in V3OrderParallel.cpp (Could combine this with some parts of V3Partition - those not called from V3Partition::finalize - but that's not for this patch).

-Move the serial code construction into V3OrderSerial.cpp

-Factored the very small common code between the parallel and serial code construction (processMoveOneLogic) into V3OrderCFuncEmitter.cpp
2024-03-09 12:43:09 +00:00
Wilson Snyder 5ee938fd1c Fix assignment of null into struct member (#4952). 2024-03-08 17:33:51 -05:00
Arkadiusz Kozdra f78783e187 Internals: Use LogOr/LogAnd on inside operator expansion (#4951)
This will help introducing constrained randomization, as SMT solvers
treat booleans and 1-bit vectors as incompatible types.
2024-03-08 08:17:41 -05:00
Wilson Snyder 11bfe7a7bb cppcheck fixes. No functional change. 2024-03-07 19:20:00 -05:00
Wilson Snyder 8ba494c71f Fix null characters in shortened identifiers (#4946). 2024-03-07 18:09:55 -05:00
Geza Lore acb63c929b Split V3Order.cpp into multiple smaller files (#4950). No functional change intended.
Move OrderBuildVisitor into V3OrderGraphBuilder.cpp (and rename to
V3OrderGraphBuilder). Move ProcessMoveBuildGraph to
V3OrderMoveGraphBuilder.cpp (and rename to V3OrderGraphBuilder).

This patch is pure code movement/rename, no refactoring at all.
2024-03-07 17:12:19 -05:00
Geza Lore 26dd5d4550 Add some missing VNUserInUse (#4949) 2024-03-07 20:26:58 +00:00
Bartłomiej Chmiel 32f288084a Add UNUSEDLOOP when unused loop is removed (#4926) 2024-03-07 08:33:49 -05:00
Andrew Nolte 6db149c588 Fix generate blocks in vpi_iterate (#3609) (#4913) 2024-03-06 18:33:30 -05:00
Geza Lore 0fed5f8b3e Avoid creating redundant vertices in V3DfgPeephole (#4944)
Add a new data-structure V3DfgCache, which can be used to retrieve
existing vertices with some given inputs vertices. Use this in
V3DfgPeephole to eliminate the creation of redundant vertices.

Overall this is performance neutral, but is in prep for some future
work.
2024-03-06 18:01:52 +00:00
Geza Lore a30930bdcc Fix unsound temporary name generation in V3DfgRegularize
Sadly used to produce some conflicting names.
2024-03-05 19:17:41 +00:00
Geza Lore 3a1355fb54 Fix bad assertion in DFG variable elimination
Fixes #4943
2024-03-05 18:51:46 +00:00
Andrew Nolte 97db128d66 Tests: Add VPI dump testcases (#4838) 2024-03-05 12:08:22 -05:00
Wilson Snyder 3d57256070 Commentary: Changes update 2024-03-04 08:22:36 -05:00
Wilson Snyder 5dc8fb5b4f Commentary (#4930) 2024-03-04 08:04:39 -05:00
Wilson Snyder 3f0d434f82 Gtkwave: Update from upstream for warning cleanup (#4941) 2024-03-03 19:24:03 -05:00
Wilson Snyder 2cdc5ea48b Fix unaligned access in --trace --runtime-debug (#4941). 2024-03-03 12:33:11 -05:00
Geza Lore 745605efe3 Fix DFG removing forceable signals (#4942)
DFG could remove forceable signals by replacing them with their
in-design driver. This is a bit of a pain to prevent, and ideally the
forcing transform should happen before DFG, but implementing it there is
a pain due to having to rewrite ports based on direction.  This is an
attempted fix in DFG. More cases might remain.
2024-03-03 16:22:41 +00:00
Wilson Snyder 0fbd4313b2 Fix __Vlip undefined error in --freloop (#4824). 2024-03-03 11:10:46 -05:00
Wilson Snyder 9f8f61ef2f Internals: Only show SimulateVisitor note once per type 2024-03-03 11:10:19 -05:00
github action 4b1f4938b8 Apply 'make format' 2024-03-03 15:23:47 +00:00
Kefa Chen 5f1dc73a1b Support public packed struct / union (#860) (#4878) 2024-03-03 10:23:04 -05:00
Geza Lore 5e1fc6e24d Add DFG 'regularize' pass, and improve variable removal (#4937)
This functionality used to be distributed in the removeVars pass and the
final dfgToAst conversion. Instead added a new 'regularize' pass to
convert DFGs into forms that can be trivially converted back to Ast, and
a new 'eliminateVars' pass to remove/repalce redundant variables. This
simplifies dfgToAst significantly and makes the code a bit easier to
follow.

The new 'regularize' pass will ensure that every sub-expression with
multiple uses is assigned to a temporary (unless it's a trivial memory
reference or constant), and will also eliminate or replace redundant
variables. Overall it is a performance neutral change but it does
enable some later improvements which required the graph to be in this
form, and this also happens to be the form required for the dfgToAst
conversion.
2024-03-02 19:49:29 +00:00
Wilson Snyder 0ec32ee404 Parse 1800-2023 map expressions and throw UNSUPPORTED 2024-03-02 10:15:19 -05:00
Wilson Snyder 97b21b3849 Parse 1800-2023 2024-03-02 10:15:19 -05:00
Wilson Snyder 214173c6b8 Support 1800-2023 preprocessor ifdef expressions; add PREPROC zero warning. 2024-03-02 10:15:19 -05:00
Wilson Snyder 3786f59e03 Change to IEEE 1800-2023 warning mentions 2024-03-02 10:15:19 -05:00
Wilson Snyder fa7234ff68 Support 1800-2023 DPI headers, svGetTime/svgGetTimeUnit/svGetTimePrecision methods. 2024-03-02 10:15:19 -05:00
Wilson Snyder 91dd3c5fac Support 1800-2023 keywords. 2024-03-02 10:15:19 -05:00
Wilson Snyder a378dbd9b2 Tests: Fix t_dist_whitespace 2024-03-02 10:14:54 -05:00
Yutetsu TAKATSUKASA da9521a351 Internals: Add --debug-width option for developers to check width consistency (#4923) 2024-03-02 08:57:26 -05:00
Wilson Snyder af51107587 Fix statistics missing some additions. 2024-03-01 20:27:57 -05:00
Wilson Snyder e60f652a64 Commentary (#4936) 2024-03-01 17:32:26 -05:00
Wilson Snyder a4813ec677 Add warning on TOP-named modules (#4935). 2024-03-01 17:28:12 -05:00
Kamil Rakoczy 01dadb0a8d Fix try-lock spuriously fails (#4931) (#4938) 2024-03-01 15:29:13 -05:00
Geza Lore 9dcb7ea6a9 Fix minor V3DfgPatternStats coding issues 2024-03-01 14:56:35 +00:00
github action adfe072b89 Apply 'make format' 2024-03-01 14:15:34 +00:00
Yan Xu b12f8b3d73 Fix V3Unknown unpacked struct x-assign (#4934) 2024-03-01 09:14:49 -05:00
Geza Lore f56f318217 Make installation relocatable, and the installation testable (#4927)
Fixes #4893
2024-03-01 00:08:28 +00:00
Geza Lore 3af0eb7fa0 Internals: Emit a separate CFunc for each MTask body (#4932) (#4933) 2024-02-29 16:53:53 -05:00
Wilson Snyder a69cb9b044 Tests: Avoid verilated.v include in most tests 2024-02-27 18:08:37 -05:00
Geza Lore b68a696859 Ignore all JSON tree dumps in test-snap/test-diff 2024-02-27 17:16:34 +00:00
Wilson Snyder e320b0b581 Internals: Favor const_iterators. No functional change intended. 2024-02-25 17:12:13 -05:00
Wilson Snyder 42041f2403 Fix invalid cast on string structure creation (#4921). 2024-02-25 08:19:53 -05:00
Wilson Snyder 881c6ee655 devel release 2024-02-24 07:52:19 -05:00
Wilson Snyder d8b2993974 Version bump 2024-02-24 07:39:16 -05:00
Wilson Snyder 30e711aa5c Commentary: Changes update 2024-02-23 11:49:42 -05:00
Yutetsu TAKATSUKASA 51ae8e13fb Add --assert-case option (#4919) 2024-02-23 23:05:53 +09:00
Geza Lore 0892b39ad2 Fix incorrect code generation for change expression on typedefed unpacked array (#4915) 2024-02-23 03:53:42 -05:00
Geza Lore 5964d5cf63 Fix inconsistent driver resolution with typedefs (#4917) 2024-02-22 18:33:23 +00:00
Wilson Snyder 2162a31d3a Commentary: Changes update 2024-02-22 03:57:56 -05:00
Paul Swirhun e00e4d4245 Fix whitespace in pragma protect version (#4914) 2024-02-22 03:29:57 -05:00
Yutetsu TAKATSUKASA 4b9532fe24 Improve message for priority case assertion failure (#4905) 2024-02-22 03:09:14 -05:00
Jiangjie Weng c3ff52208a Commentary: Fix typo in the call condition of designp->nextTimeSlot() (#4912) 2024-02-21 10:15:29 -05:00
Andrew NolteandAndrew Nolte cfb73923bd Test driver: Add -xrun Xcelium support (#4896)
Co-authored-by: Andrew Nolte <[email protected]>
2024-02-20 14:41:05 -05:00
Yutetsu TAKATSUKASAandWilson Snyder a951446f9b Add --[no]-stop-fail option (#4904)
Co-authored-by: Wilson Snyder <[email protected]>
2024-02-19 21:26:58 +09:00
Wilson Snyder a187a16e56 Commentary: Changes update 2024-02-13 21:47:09 -05:00
Wilson Snyder d1dec38f38 Fix integer compare warning (#4887). No functional change. 2024-02-13 18:37:41 -05:00
Yutetsu TAKATSUKASA 65b632a7dd Improve assertion for unique case (#4892)
- Use parallel_case, unique, and unique0 in error message
- Distinguish multiple match and no match
- Show the case value that triggers the assertion
2024-02-13 21:53:32 +09:00
Geza Lore ec0787015e Ignore JSON tree dumps and DFG stats in test-snap/test-diff 2024-02-11 20:38:16 +00:00
Geza Lore cbc76a7816 Dump DFG patterns with --stats (#4889)
With --stats, we will print DFG pattern combinations, one per line, as
S-expressions to new stat files, together with their frequency, to aid
discovery of new peephole patterns.
2024-02-11 15:41:10 +00:00
Szymon Gizler d667b73e8d Add --json-only and related JSON dumping (#4715) (#4831). 2024-02-09 17:50:09 -05:00
Wilson Snyder 248de2be2e Fix coverage with member 2024-02-08 21:51:36 -05:00
Wilson Snyder 365537d8e3 Fix coverage of delayed nets 2024-02-08 20:25:17 -05:00
Wilson Snyder a23cf1ceea Fix toggle coverage dataDeclp error on multi-edge driven signals. 2024-02-08 19:21:44 -05:00
Wilson Snyder be471e9ccc Internals: Minor coverage reformatting/renaming. No functional change. 2024-02-08 19:10:38 -05:00
Wilson Snyder d0e7eaafc9 Tests: Define stop uniformly. No functional change. 2024-02-08 18:39:13 -05:00
Wilson Snyder 13b7cce8be Fix compile error on structs with queues (and ignore toggle coverage on queues). 2024-02-08 08:44:27 -05:00
Wilson Snyder efff630763 Fix tautological-compare warnings. 2024-02-07 22:16:08 -05:00
Wilson Snyder e2e0795538 Fix toggle coverage of unpacked unions with reals. 2024-02-07 21:03:32 -05:00
Wilson Snyder c20634e4f8 Fix coverage of real arrays giving operator^ not defined 2024-02-07 20:11:27 -05:00
Wilson Snyder 715dce546f Fix debug infinite loop when bad coverage pointers 2024-02-07 19:57:02 -05:00
Wilson Snyder 07d86bf91d Allow loop unrolling with coverage 2024-02-07 19:56:32 -05:00
Krzysztof Bieganski fe8c7c5a94 Fix timing with expr on assign LHS (#4880)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-02-06 07:27:19 -05:00
Wilson Snyder 7ada5195d8 Fix this in member initialization (#4710). (#4876) 2024-02-04 19:44:10 -05:00
Wilson Snyder a6ad85244f Backout (#4710) due to leak 2024-02-04 18:13:22 -05:00
Wilson Snyder f13f2296de Fix this in member initialization (#4710). 2024-02-04 16:09:01 -05:00
Wilson Snyder b1d901f100 Tests: Hardcode copyright exceptions (#4874) 2024-02-04 15:43:01 -05:00
Wilson Snyder 8ab576f7e6 Internals: Use std::to_string. No functional change intended. 2024-02-04 14:38:25 -05:00
Wilson Snyder 6f92c9c974 CI: Update upload-artifacts/download-artifacts version (#4875) 2024-02-04 10:29:34 -05:00
Wilson Snyder 7425037db6 Fix Copyright 2024-02-04 09:35:19 -05:00
Geza Lore 6ca60429ce Fix incorrect temporary insertion in loop conditions with statements (#4873)
When the condition of an AstWhile loop contains a statement (e.g.
through an AstExprStmt), temporaries inserted in that statement need to
go before that statement, not in the AstWhile precondition.
2024-02-04 09:19:54 -05:00
Bartłomiej ChmielandBartłomiej Chmiel c702fc944e Fix SystemC biguint sign desynchronization (#4870)
* Fix writing to SystemC values with `VL_ASSIGN_SBW`

Signed-off-by: Krzysztof Bieganski <[email protected]>
Co-authored-by: Bartłomiej Chmiel <[email protected]>
2024-02-02 07:00:13 -05:00
Yutetsu TAKATSUKASA 999c9ae21c Fix #4864 of wrong runtime result (#4867)
* Fix #4864. Ignore if EQ/NE is under SHIFTR.
2024-01-30 00:00:00 +09:00
Szymon Gizler c715cfc254 Add --valgrind switch (#4828) 2024-01-29 07:50:05 -05:00
Wilson Snyder 22687a6901 Internals: Use C++14 quoted literal std::string 2024-01-28 21:00:20 -05:00
Wilson Snyder eecdf4b0f3 Internals: Use C++14 exchange 2024-01-28 21:00:20 -05:00
Wilson Snyder e3e5f30ba1 Check for C++14 without also accepting GNU C++11 (#4865) 2024-01-28 19:42:29 -05:00
Wilson Snyder ce174743bb Fix some MSVC warnings 2024-01-28 14:47:14 -05:00
Wilson Snyder a84be1844f MSVC fix, part of fix of null (#4862). 2024-01-28 11:05:38 -05:00
Wilson Snyder 9ccef4180f Fix $fwrite of null (#4862). 2024-01-28 09:05:50 -05:00
Wilson Snyder 3bf896f7db Commentary: Changes update 2024-01-28 09:04:29 -05:00
Yutetsu TAKATSUKASA e4a0e5aad6 Fix #4857 consider NOT when checking EQ/NEQ under AND/OR tree (#4863) 2024-01-28 22:36:09 +09:00
Wilson Snyder d6f8ccd20b Add unroll_disable and unroll_full loop control metacomments (#3260). 2024-01-26 07:49:07 -05:00
Wilson Snyder 94460867d3 Fix nondeterministic fork/tristate ordering (#4690). 2024-01-25 20:33:43 -05:00
Wilson Snyder 5b70325e52 Internals: Style/debug cleanups. No functional change. 2024-01-25 20:26:56 -05:00
Wilson Snyder 3aece189ac Fix tracing chandles (#4860). 2024-01-25 08:13:52 -05:00
Wilson Snyder 188f0eb4ad Tests: Add t_enum_enumvalue_struct_bad (#2855) 2024-01-25 07:57:45 -05:00
Wilson Snyder d4c8a15407 Add --runtime-debug for Verilated executable runtime debugging. 2024-01-25 07:34:30 -05:00
Wilson Snyder 354a534d68 Add '--decorations node' for inserting debug comments into emitted code. 2024-01-24 21:51:47 -05:00
Wilson Snyder c8a40e0b52 Commentary; Tests: Check summary options match guide options 2024-01-24 19:28:46 -05:00
Wilson Snyder 771cb5f60b Tests: Fix last commit when no coroutines. 2024-01-24 18:48:27 -05:00
Wilson Snyder 23836ee8d0 Document gprof steps better. Add t_prof_timing test to show GCC bug (#4858). 2024-01-24 17:55:23 -05:00
github action 8a7f36c34b Apply 'make format' 2024-01-24 12:46:22 +00:00
Jonathan Schröter 31262e81f9 Fix to not emit already waived warnings in waiver output (#4574) (#4818) 2024-01-24 07:45:38 -05:00
github action 3d006afacc Apply 'make format' 2024-01-24 03:08:39 +00:00
Wilson Snyder 74ec50f933 Support interface class diamond relationship. 2024-01-23 22:07:35 -05:00
Wilson Snyder 21e85f87bc Fix compilation error on multi-inherited interface class usage (#4819). 2024-01-23 19:36:11 -05:00
github action 0b8daf4ae4 Apply 'make format' 2024-01-23 18:06:10 +00:00
Paul Swirhun 6c0c88cfc4 Fix unsafe write in wide array insertion (#4850) (#4855) 2024-01-23 13:05:27 -05:00
Wilson Snyder f0d010d9c5 Github: Update actions (#4852) 2024-01-22 22:32:00 -05:00
Wilson Snyder 2989e54eaa Add unsupported warning on property iff (#4848) 2024-01-21 16:18:48 -05:00
Wilson Snyder 1a2c9ca813 Updat GTKwave libraries from upstream 2024-01-21 13:59:54 -05:00
Wilson Snyder e3f3e3399f Commentary: Changes update 2024-01-21 13:50:27 -05:00
Yutetsu TAKATSUKASA 6b8531f0a6 Fix widthMin in replaceShiftOp (#4837) (#4841) (#4849) 2024-01-21 10:30:01 -05:00
Yutetsu TAKATSUKASA 50df902b54 Fix incorrect bit-op-tree NOT optimization (#4832) (#4847)
* Fix #4832. Bit-op-tree opt. should not touch a subtree under NOT in AND/OR tree.
2024-01-21 07:25:24 -05:00
Wilson Snyder 3a5248a919 Internals: Mark structs final/VL_NOT_FINAL. No functional change intended. 2024-01-20 15:06:46 -05:00
Wilson Snyder 1a92502788 Add --main support for dumping coverage, and +verilator+coverage+file runtime option. 2024-01-20 12:28:49 -05:00
Wilson Snyder a38fea1f9e Tests: Use context coverage write 2024-01-20 11:19:42 -05:00
Wilson Snyder d595d4c7ac Tests: Use --binary with some --timing tests 2024-01-20 10:57:00 -05:00
Wilson Snyder a43fd06f85 Tests: Imply no driver.pl make when using --build. No functional change intended 2024-01-20 10:37:35 -05:00
Wilson Snyder 375a121377 Tests: Use lint() where able instead of compile(). No functional change intended. 2024-01-20 10:25:17 -05:00
Wilson Snyder fef0502d50 Tests: Imply make_main=>0 on --main tests 2024-01-20 10:17:35 -05:00
Wilson Snyder c30b9d04a8 Change unused vars to standard void syntax. No functional change intended. 2024-01-20 08:57:22 -05:00
Wilson Snyder 89cfa0737f Internals: Fix cppcheck warnings 2024-01-17 19:48:07 -05:00
Wilson Snyder 8b03f2d47b Commentary 2024-01-17 19:47:07 -05:00
Anthony Donlon f80c167d65 Fix warnings in verilated_sc_trace.h for Clang. No functional change. (#4807) (#4827) 2024-01-17 19:30:42 -05:00
Szymon Gizler db3ce29b36 Fix wrong utimes() param (#4829) 2024-01-17 08:32:44 -05:00
Wilson Snyder 6f96c6763d Commentary 2024-01-17 08:25:54 -05:00
Szymon Gizler 372cdf1fc8 Tests: Let debugger handle signals instead of test driver (#4817) 2024-01-16 11:18:20 -05:00
github action 54922c036a Apply 'make format' 2024-01-14 00:53:31 +00:00
Adrian Sampson 2e999a5441 Fix too null pointer dereference (#4810) (#4825) 2024-01-13 20:52:50 -04:00
Tim Hutt 5073f208af Internals: Use more standard syntax for avoiding unused variable warnings (#4826) 2024-01-13 15:34:59 -05:00
Larry Doolittle c9d7486d16 Fix maybe-uninitialized compiler warning (#4820) (#4822) 2024-01-12 13:09:34 -05:00
Wilson Snyder 27d906a6b3 Commentary: Changes update 2024-01-12 08:20:53 -05:00
Wilson Snyder 21bf2d62d2 Fix mis-splitting of dump control functions (#4821). 2024-01-12 08:19:30 -05:00
Wilson Snyder fcdd8e5da6 Fix missing includes with multiple inheritance (#3819 partial) 2024-01-11 20:19:48 -05:00
Andrew Nolte ab47fc6656 Fix localparam elaboration (#3858) (#4794) 2024-01-11 07:49:07 -05:00
Szymon Gizler 5f52c066e5 Internals: Add serializeOnly() and dumpTreeEitherLevel() (#4815) (#4715). No functional change intended. 2024-01-09 10:35:13 -05:00
Wilson Snyder 19cb366e5d Update ifdef (#4805) (#4807). No functional change. 2024-01-08 07:35:34 -05:00
Anthony Donlon 55d1b87b34 Support parsing anonymous primitive instantiations (#4809) 2024-01-07 10:59:56 -05:00
Wilson Snyder eec41fd039 Fix lint_off disables on preprocessor warnings (#4703). 2024-01-06 18:49:19 -05:00
Wilson Snyder 69043549d6 Fix const anon union (#4800) 2024-01-06 17:26:07 -05:00
Wilson Snyder 68e4eeb53e Add predicted stack overflow warning (#4799). 2024-01-06 16:16:14 -05:00
Wilson Snyder 0ca90257a5 Add predicted stack overflow warning (#4799). 2024-01-06 16:14:58 -05:00
Anthony Donlon 7507c5f56c Support SystemC 3.0.0 public review version (#4805) (#4807) 2024-01-06 06:01:35 -05:00
Wilson Snyder acbbb2594a Tests: Make some tests single-threaded only, for faster regressions 2024-01-05 18:25:39 -05:00
Wilson Snyder 5294140753 Fix delays using wrong timeunits when modules inlined (#4806). 2024-01-05 18:07:24 -05:00
Wilson Snyder a36a07c297 Internals: Favor UASSERT over v3fatalSrc. No functional change intended. 2024-01-05 18:00:06 -05:00
Wilson Snyder 47b129bf07 Commentary 2024-01-05 07:14:40 -05:00
Chykon 1a0c8f1573 Commentary: Add a link to Create-Binary Execution to the list of examples (#4802) 2024-01-04 10:47:22 -05:00
Wilson Snyder 2be6f03848 Commentary: runtime debugging 2024-01-03 21:03:17 -05:00
github action 4172c0f29e Apply 'make format' 2024-01-03 12:13:21 +00:00
Pengcheng Xu ec01008fe3 Change zero replication width error to ZEROREPL warning (#4753) (#4762) 2024-01-03 07:11:50 -05:00
Marlon James 8ea814e4b4 Fix VPI parameter iteration (#4798) 2024-01-02 18:57:34 -05:00
Marlon James 0195fe9dfd Add vpiConstType support to vpi_get_str() (#4797) 2024-01-02 18:52:57 -05:00
Marlon James e430ea13f4 Fix vpi_get() and vpi_get64() to return vpiUndefined on errors (#4795)
See IEEE 1800-2017 section 38.6 and 38.7.
2024-01-02 16:25:14 -05:00
Mariusz Glebocki 719954a24a Internals: Make V3Const.cpp parseable by non-compilers (#4796) 2024-01-02 14:51:40 -05:00
Paul Wright 3adb31f53b Fix $time not rounding up (#4790) (#4792) 2024-01-01 20:11:46 -05:00
Wilson Snyder 3eaed3b6f5 Remove deprecated 32-bit pointer mode (#4791). 2024-01-01 10:16:48 -05:00
Wilson Snyder 22de598456 devel release 2024-01-01 03:46:48 -05:00
1296 changed files with 98565 additions and 38969 deletions
+2
View File
@@ -18,3 +18,5 @@ What 'verilator --version' are you using? Did you try it with the git master ve
What OS and distribution are you using?
May we assist you in trying to fix this in Verilator yourself?
(Please avoid attaching screenshots that show text - you can convert images to text using e.g. https://ocr.space)
+32 -47
View File
@@ -17,6 +17,8 @@ env:
CCACHE_COMPRESS: 1
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_LIMIT_MULTIPLE: 0.95
INSTALL_DIR: ${{ github.workspace }}/install
RELOC_DIR: ${{ github.workspace }}/relloc
defaults:
run:
@@ -37,43 +39,29 @@ jobs:
compiler:
- { cc: clang, cxx: clang++ }
- { cc: gcc, cxx: g++ }
# 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' }}
# - os: ${{ github.event_name == 'pull_request' && 'ubuntu-20.04' || 'do-not-exclude' }}
# - m32: ${{ github.event_name == 'pull_request' && 1 || 'do-not-exclude' }}
# Build -m32 only on ubuntu-22.04 clang++
- {os: ubuntu-18.04, m32: 1}
- {os: ubuntu-20.04, m32: 1}
- compiler: { cc: gcc, cxx: g++ }
m32: 1
include:
# Build GCC 10 on ubuntu-20.04
- os: ubuntu-20.04
compiler: { cc: gcc-10, cxx: g++-10 }
m32: 0
runs-on: ${{ matrix.os }}
name: Build | ${{ matrix.os }} | ${{ matrix.compiler.cc }} ${{ matrix.m32 && '| -m32' || '' }}
name: Build | ${{ matrix.os }} | ${{ matrix.compiler.cc }}
env:
CI_BUILD_STAGE_NAME: build
CI_RUNS_ON: ${{ matrix.os }}
CI_M32: ${{ matrix.m32 }}
CC: ${{ matrix.compiler.cc }}
CXX: ${{ matrix.compiler.cxx }}
CACHE_BASE_KEY: build-${{ matrix.os }}-${{ matrix.compiler.cc }}-m32=${{ matrix.m32 }}
CACHE_BASE_KEY: build-${{ matrix.os }}-${{ matrix.compiler.cc }}
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
VERILATOR_ARCHIVE: verilator-${{ github.sha }}-${{ matrix.os }}-${{ matrix.compiler.cc }}.tar.gz
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: repo
- name: Cache $CCACHE_DIR
uses: actions/cache@v3
uses: actions/cache@v4
env:
CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache
with:
@@ -93,7 +81,7 @@ jobs:
run: tar --posix -c -z -f ${{ env.VERILATOR_ARCHIVE }} repo
- name: Upload tar archive
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
path: ${{ github.workspace }}/${{ env.VERILATOR_ARCHIVE }}
name: ${{ env.VERILATOR_ARCHIVE }}
@@ -108,40 +96,38 @@ jobs:
compiler:
- { cc: clang, cxx: clang++ }
- { cc: gcc, cxx: g++ }
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
# - os: ${{ github.event_name == 'pull_request' && 'ubuntu-18.04' || 'do-not-exclude' }}
# - os: ${{ github.event_name == 'pull_request' && 'ubuntu-20.04' || 'do-not-exclude' }}
# - m32: ${{ github.event_name == 'pull_request' && 1 || 'do-not-exclude' }}
# Build -m32 only on ubuntu-22.04
- {os: ubuntu-18.04, m32: 1}
- {os: ubuntu-20.04, m32: 1}
- compiler: { cc: gcc, cxx: g++ }
m32: 1
reloc: [0]
suite: [dist-vlt-0, dist-vlt-1, dist-vlt-2, dist-vlt-3, vltmt-0, vltmt-1]
include:
# Test with GCC 10 on ubuntu-20.04 without m32
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: dist-vlt-0}
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: dist-vlt-1}
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: dist-vlt-2}
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: vltmt-0}
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: vltmt-1}
# Test with GCC 10 on ubuntu-20.04
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: dist-vlt-0}
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: dist-vlt-1}
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: dist-vlt-2}
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: dist-vlt-3}
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: vltmt-0}
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: vltmt-1}
# Test relocated installation - on most common platform only
- {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: dist-vlt-0}
- {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: dist-vlt-1}
- {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: dist-vlt-2}
- {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: dist-vlt-3}
- {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: vltmt-0}
- {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: vltmt-1}
runs-on: ${{ matrix.os }}
name: Test | ${{ matrix.os }} | ${{ matrix.compiler.cc }} | ${{ matrix.suite }} ${{ matrix.m32 && '| -m32' || '' }}
name: Test | ${{ matrix.os }} | ${{ matrix.compiler.cc }} | ${{ matrix.reloc && 'reloc | ' || '' }} ${{ matrix.suite }}
env:
CI_BUILD_STAGE_NAME: test
CI_RUNS_ON: ${{ matrix.os }}
CI_M32: ${{ matrix.m32 }}
CI_RELOC: ${{ matrix.reloc }}
CC: ${{ matrix.compiler.cc }}
CXX: ${{ matrix.compiler.cxx }}
CACHE_BASE_KEY: test-${{ matrix.os }}-${{ matrix.compiler.cc }}-m32=${{ matrix.m32 }}-${{ matrix.suite }}
CACHE_BASE_KEY: test-${{ matrix.os }}-${{ matrix.compiler.cc }}-${{ matrix.reloc }}-${{ matrix.suite }}
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
VERILATOR_ARCHIVE: verilator-${{ github.sha }}-${{ matrix.os }}-${{ matrix.compiler.cc }}.tar.gz
steps:
- name: Download tar archive
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: ${{ env.VERILATOR_ARCHIVE }}
path: ${{ github.workspace }}
@@ -151,9 +137,9 @@ jobs:
run: tar -x -z -f ${{ env.VERILATOR_ARCHIVE }}
- name: Cache $CCACHE_DIR
uses: actions/cache@v3
uses: actions/cache@v4
env:
CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache
CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache2
with:
path: ${{ env.CCACHE_DIR }}
key: ${{ env.CACHE_KEY }}-${{ github.sha }}
@@ -174,10 +160,9 @@ jobs:
env:
CI_BUILD_STAGE_NAME: build
CI_RUNS_ON: ubuntu-22.04
CI_M32: 0
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: repo
+1 -1
View File
@@ -13,5 +13,5 @@ jobs:
name: "'docs/CONTRIBUTORS' was signed"
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: test_regress/t/t_dist_contributors.pl
+3 -4
View File
@@ -11,7 +11,6 @@ on:
env:
CI_OS_NAME: linux
CI_COMMIT: ${{ github.sha }}
CI_M32: 0
COVERAGE: 1
VERILATOR_ARCHIVE: verilator-coverage-${{ github.sha }}.tar.gz
@@ -31,7 +30,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: repo
@@ -46,7 +45,7 @@ jobs:
run: tar --posix -c -z -f ${{ env.VERILATOR_ARCHIVE }} repo
- name: Upload tar archive
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
path: ${{ github.workspace }}/${{ env.VERILATOR_ARCHIVE }}
name: ${{ env.VERILATOR_ARCHIVE }}
@@ -81,7 +80,7 @@ jobs:
steps:
- name: Download tar archive
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: ${{ env.VERILATOR_ARCHIVE }}
path: ${{ github.workspace }}
+1 -1
View File
@@ -35,7 +35,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Extract context variables
run: |
+1 -2
View File
@@ -16,10 +16,9 @@ jobs:
CI_OS_NAME: linux
CI_RUNS_ON: ubuntu-22.04
CI_COMMIT: ${{ github.sha }}
CI_M32: 0
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Install packages for build
+3 -3
View File
@@ -32,11 +32,11 @@ jobs:
name: run on windows
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
path: repo
- name: Cache $CCACHE_DIR
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ env.CCACHE_DIR }}
key: msbuild-msvc-cmake
@@ -49,7 +49,7 @@ jobs:
- name: Zip up repository
run: Compress-Archive -LiteralPath install -DestinationPath verilator.zip
- name: Upload zip archive
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
path: ${{ github.workspace }}/repo/verilator.zip
name: verilator-win.zip
+2
View File
@@ -44,3 +44,5 @@ verilator-config-version.cmake
/.idea/
/cmake-build-*/
/test_regress/snapshot/
xmverilog.*
xrun.history
+27
View File
@@ -0,0 +1,27 @@
# See https://citation-file-format.github.io/
cff-version: 1.2.0
title: Verilator
message: >-
If you use this software, please cite it using the
metadata from this file.
type: software
authors:
- given-names: Wilson
family-names: Snyder
email: [email protected]
affiliation: Veripool
- given-names: Paul
family-names: Wasson
- given-names: Duane
family-names: Galbi
- name: 'et al'
repository-code: 'https://github.com/verilator/verilator'
url: 'https://verilator.org'
abstract: >-
The Verilator package converts Verilog and SystemVerilog hardware
description language (HDL) designs into a fast C++ or SystemC model
that, after compiling, can be executed. Verilator is not a
traditional simulator but a compiler.
license:
- LGPL-3.0-only
- Artistic-2.0
+1 -1
View File
@@ -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.020
VERSION 5.026
HOMEPAGE_URL https://verilator.org
LANGUAGES CXX
)
+179 -2
View File
@@ -8,12 +8,188 @@ The changes in each Verilator version are described below. The
contributors that suggested a given feature are shown in []. Thanks!
Verilator 5.026 2024-06-15
==========================
**Major:**
* Support constrained randomization with external solvers (#4947). [Arkadiusz Kozdra, Antmicro Ltd.]
**Minor:**
* Support `$psprintf` system function (#4314) (#5169). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support 2D dynamic array initialization (#4700) (#5122). [Valentin Atepalikhin]
* Support __en/__out signals on top level inout ports (#4812) (#4856). [Paul Wright]
* Support empty queue as dynarray default value (#5055). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support vpiInertialDelay (#5087). [Todd Strader]
* Support NBAs to arrays inside loops (#5092). [Geza Lore]
* Support parsing and otherwise ignoring inline constraints (#5126). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support `inout` clocking items (#5160). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support StructSel in unpacked array assignments (#5176). [Geza Lore]
* Add error on zero width select (#5028).
* Add CITATION.cff (#5057) (#5058). [Gijs Burghoorn]
* Add VPI eval needed tracking (#5065). [Todd Strader]
* Add `--localize-max-size` option and optimization (#5072).
* Add parameterless assert control system tasks (#5010). [Bartłomiej Chmiel]
* Add traceCapable indication to model header (#5053). [Vito Gamberini]
* Add increasing of stack size when possible (#5071) (#5104). [Yinan Xu]
* Add assertion on reusing VerilatedContext (#5167).
* Improve DFG regularization in cyclic graphs (#5142). [Geza Lore]
* Improve VerilatedVpiPutHolder storage requirements (#5144). [Kaleb Barrett]
* Fix coroutines without awaits to have a co_return (#4208) (#5175). [Arkadiusz Kozdra, Antmicro Ltd.]
* Fix missing flex include path variable (#4970) (#4971). [Christopher Taylor]
* Fix missing parameters with comma to be errors (#4979) (#5012). [Paul Swirhun]
* Fix 'experimental/coroutine' file not found on MacOS (#5030) (#5031) (#5151). [Paul Bowen-Huggett]
* Fix bound queue printing (#5032). [Aleksander Kiryk, Antmicro Ltd.]
* Fix consecutive zero-delays (#5038). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix attempted to destroy locked thread pool error (#5040). [Bartłomiej Chmiel, Antmicro Ltd.]
* Fix `$system` with string argument (#5042).
* Fix width extension on delays (#5043).
* Fix `$typename` on array.min and others (#5049). [Gökçe Aydos]
* Fix `make $(info)` which cannot be silenced (#5059). [Gökçe Aydos]
* Fix CMake builds to export VERILATOR_ROOT (#5063). [Michael Bikovitsky]
* Fix false ASSIGNIN on functions with explicit port map (#5069).
* Fix 4-state value support for $readmem (#5070) (#5078). [Ethan Sifferman]
* Fix DFG assertion with SystemC (#5076). [Geza Lore]
* Fix `$typename` string to be more standard (#5082) (#5083). [Andrew Nolte]
* Fix missed optimization in V3Delayed (#5089). [Geza Lore]
* Fix macro expansion in strings per 1800-2023 (#5094). [Geza Lore]
* Fix width extension of unpacked array select (#5095). [Varun Koyyalagunta]
* Fix MacOS missing <type_traits> header (#5096) (#5097). [Vito Gamberini]
* Fix assertion failure in V3Gate (#5101). [Yutetsu TAKATSUKASA]
* Fix aliases for forced port signals (#5105). [Geza Lore]
* Fix tracing interface functions (#5108). [Alex Solomatnikov]
* Fix method calls parsing in constraints (#5110). [Arkadiusz Kozdra, Antmicro Ltd.]
* Fix vpiInertialDelay for memories (#5113). [Todd Strader]
* Fix hierarchical compilation with nested -F (#5114) (#5124). [Alex Solomatnikov]
* Fix references to ports in forks (#5123). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix output C++ type error on change detect of I/O arrays (#5125) (#5131). [Pawel Jewstafjew]
* Fix x-valued parameters with `--x-assign unique` (#5129). [Ethan Sifferman]
* Fix overflow of string on VPI reads (#5145) (#5146). [Kaleb Barrett]
* Fix VerilatedVpiPutHolder class (#5156). [Kaleb Barrett]
* Fix extending out-of-range select (#5159) (#5164). [Geza Lore]
* Fix radix in width warnings (#5166). [Geza Lore]
* Fix SystemC BITS_PER_DIGIT in VL_ASSIGN_SBW (#5170). [Bartłomiej Chmiel, Antmicro Ltd.]
* Fix non-constant replication in concats (#5171). [Arkadiusz Kozdra, Antmicro Ltd.]
* Fix table optimization when applied on real data type (#5172) (#5173). [Arthur Rosa]
* Fix DPI import of null C-string (#5179).
Verilator 5.024 2024-04-05
==========================
**Major:**
* Add printing summary reports, use `--quiet` or `+verilator+quiet` to suppress (#4909).
* Support 1800-2023 keywords, and parsing with UNDEFINED warnings.
* Support 1800-2023 preprocessor ifdef expressions.
**Minor:**
* Change 1800-2023 to be default language version.
* Add DFG 'regularize' pass, and improve variable removal (#4937). [Geza Lore]
* Add error when pass net to function argument (#4132) (#4966). [Fuad Ismail]
* Add `UNUSEDLOOP` when unused loop is removed (#4926). [Bartłomiej Chmiel, Antmicro Ltd.]
* Add custom version for verilator --version packaging (#4954). [Nolan Poe]
* Add error on missing pure virtual functions (#4961).
* Add error on calling static function without object (#4962).
* Add JSON AST dumps (#5020). [Szymon Gizler]
* Support 1800-2023 DPI headers, svGetTime/svgGetTimeUnit/svGetTimePrecision methods.
* Support 1800-2023 class and function :initial, :extends, :final virtual overrides (#5025).
* Support public packed struct / union (#860) (#4878). [Kefa Chen]
* Support stream operation on unpacked array (#4714) (#5006). [Fuad Ismail]
* Support implicitly-typed variable definitions in for-loop initializers (#4945) (#4986). [Kevin Nygaard]
* Support inside range with implicit type conversion (#5026). [Arkadiusz Kozdra, Antmicro Ltd.]
* Improve installation to be relocatable (#4927). [Geza Lore]
* Improve internal ordering code (#4957) (#4990) (#4994) et al. [Geza Lore]
* Fix generate blocks in vpi_iterate (#3609) (#4913). [Andrew Nolte]
* Fix __Vlip undefined error in --freloop (#4824). [Justin Yao Du]
* Fix missing VPI scopes (#4918). [Andrew Nolte]
* Fix invalid cast on string structure creation (#4921).
* Fix try-lock spuriously fails (#4931) (#4938). [Kamil Rakoczy]
* Fix V3Unknown unpacked struct x-assign (#4934). [Yan Xu]
* Fix DFG removing forceable signals (#4942). [Geza Lore]
* Fix null characters in shortened identifiers (#4946). [Abdul Hameed]
* Fix assignment of null into struct member (#4952).
* Fix VPI missing scopes 2 (#4965). [Andrew Nolte]
* Fix object assignment from conditionals (#4968).
* Fix GCC14 warnings on template specialization syntax (#4974) (#4975). [Nolan Poe]
* Fix unpacked structure upper bit cleaning (#4978).
* Fix tests on MacOS (#4984) (#4985). [Kevin Nygaard]
* Fix `--prof-exec` predicted time values (#4988). [Geza Lore]
* Fix class type as an associative array parameter (#4997).
* Fix inout ports of unpacked struct type (#5000). [Ryszard Rozak, Antmicro Ltd.]
* Fix `unique {}` constraints missing semicolon (#5001).
* Fix preprocessor to respect strings in joins (#5007).
* Fix tracing class parameters (#5014).
* Fix memory leaks (#5016). [Geza Lore]
* Fix $readmem with missing newline (#5019). [Josse Van Delm]
* Fix internal error on missing pattern key (#5023).
* Fix tracing replicated hierarchical models (#5027).
Verilator 5.022 2024-02-24
==========================
**Minor:**
* Add predicted stack overflow warning (#4799).
* Add `+verilator+coverage+file` runtime option.
* Add `--assert-case` option (#4919). [Yutetsu TAKATSUKASA]
* Add `--decorations node` for inserting debug comments into emitted code.
* Add `--json-only` and related JSON dumping (#4715) (#4831). [Szymon Gizler, Antmicro Ltd.]
* Add `--[no]-stop-fail` option for continuing after assertions (#4904). [Yutetsu TAKATSUKASA]
* Add `--runtime-debug` for Verilated executable runtime debugging.
* Add `--valgrind` switch (#4828). [Szymon Gizler]
* Add `unroll_disable` and `unroll_full` loop control metacomments (#3260). [Jiaxun Yang]
* Remove deprecated 32-bit pointer mode (`gcc -m32`).
* Deprecate --xml-only and XML dumping (#4715) (#4831).
* Change zero replication width error to ZEROREPL warning (#4753) (#4762). [Pengcheng Xu]
* Improve message for priority case assertion failure (#4905). [Yutetsu TAKATSUKASA]
* Support dumping coverage with `--main`.
* Support dumping DFG patterns with `--stats` (#4889). [Geza Lore]
* Support `vpiConstType` in `vpi_get_str()` (#4797). [Marlon James]
* Support SystemC 3.0.0 public review version (#4805) (#4807). [Anthony Donlon]
* Support parsing anonymous primitive instantiations (#4809). [Anthony Donlon]
* Fix to not emit already waived warnings in waiver output (#4574) (#4818). [Jonathan Schröter]
* Fix `this` in member initialization (#4710). [eliasphanna]
* Fix localparam elaboration (#3858) (#4794). [Andrew Nolte]
* Fix lint_off disables on preprocessor warnings (#4703). [Srinivasan Venkataramanan]
* Fix $time not rounding up (#4790) (#4792). [Paul Wright]
* Fix `vpi_get()` and `vpi_get64()` to return vpiUndefined on errors (#4795). [Marlon James]
* Fix VPI parameter iteration (#4798). [Marlon James]
* Fix delays using wrong timeunit when modules inlined (#4806). [Paul Wright]
* Fix warnings in verilated_sc_trace.h for Clang. (#4807) (#4827). [Anthony Donlon]
* Fix null pointer dereference (#4810) (#4825). [Adrian Sampson]
* Fix compilation error on multi-inherited interface class usage (#4819).
* Fix maybe-uninitialized compiler warning (#4820) (#4822). [Larry Doolittle]
* Fix mis-splitting of dump control functions (#4821). [Fan Shupei]
* Fix wrong utimes() parameter (#4829). [Szymon Gizler]
* Fix incorrect bit-op-tree NOT optimization (#4832) (#4847). [Yutetsu TAKATSUKASA]
* Fix width calculation in replaceShiftOp (#4837) (#4841) (#4849). [Yutetsu TAKATSUKASA]
* Fix unsafe write in wide array insertion (#4850) (#4855). [Paul Swirhun]
* Fix NOT when checking EQ/NEQ under AND/OR tree (#4857) (#4863). [Yutetsu TAKATSUKASA]
* Fix tracing chandles (#4860). [Nathan Graybeal]
* Fix $fwrite of null (#4862). [Jose Tejada]
* Fix -fno-const-bit-op-tree wrong runtime result (#4864) (#4867). [Yutetsu TAKATSUKASA]
* Fix SystemC biguint sign desynchronization (#4870). [Bartłomiej Chmiel]
* Fix incorrect temporary insertion in loop conditions with statements (#4873). [Geza Lore]
* Fix timing with expr on assign LHS (#4880). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix assertion for unique case (#4892). [Yutetsu TAKATSUKASA]
* Fix GCC tautological-compare warnings.
* Fix compile error on structs with queues (and ignore toggle coverage on queues).
* Fix toggle coverage error on multi-edge driven signals.
* Fix whitespace in `pragma protect version` (#4902) (#4914). [Paul Swirhun]
* Fix incorrect code generation for change expression on typedefed unpacked array (#4915). [Geza Lore]
* Fix inconsistent driver resolution with typedefs (#4917). [Geza Lore]
Verilator 5.020 2024-01-01
==========================
**Major:**
* Support compilation with precompiled headers with Make and GCC or CLang.
* 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'.
@@ -71,6 +247,7 @@ Verilator 5.020 2024-01-01
* 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)
* Fix select value too wide (#5148) (#5153). [Dercury]
Verilator 5.018 2023-10-30
@@ -271,7 +448,7 @@ Verilator 5.012 2023-06-13
* Optimize VPI callValueCbs (#4155). [Hennadii Chernyshchyk]
* Configure for faster C++ linking using 'mold', if it is installed.
* Fix crash on duplicate imported modules (#3231). [Robert Balas]
* Fix false WIDTHEXPAND on array declarations (#3959). [JOTEGO]
* Fix false WIDTHEXPAND on array declarations (#3959). [Jose Tejada]
* Fix marking overridden methods as coroutines (#4120) (#4169). [Krzysztof Bieganski, Antmicro Ltd]
* Fix SystemC signal copy macro use (#4135). [Josep Sans]
* Fix duplicate static names in blocks in functions (#4144) (#4160). [Stefan Wallentowitz]
+56 -26
View File
@@ -91,6 +91,7 @@ datarootdir = @datarootdir@
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
CFG_WITH_SOLVER = @CFG_WITH_SOLVER@
PACKAGE_VERSION = @PACKAGE_VERSION@
#### End of system configuration section. ####
@@ -112,7 +113,7 @@ SUBDIRS = docs src test_regress \
examples/make_tracing_c \
examples/make_tracing_sc \
examples/make_protect_lib \
examples/xml_py \
examples/json_py \
INFOS = verilator.html verilator.pdf
@@ -203,11 +204,21 @@ verilator.html:
verilator.pdf: Makefile
$(MAKE) -C docs verilator.pdf
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
VL_INST_BIN_FILES = verilator verilator_bin$(EXEEXT) verilator_bin_dbg$(EXEEXT) verilator_coverage_bin_dbg$(EXEEXT) \
verilator_ccache_report verilator_coverage verilator_difftree verilator_gantt verilator_includer verilator_profcfunc
# Some scripts go into both the search path and pkgdatadir,
# so they can be found by the user, and under $VERILATOR_ROOT.
# Public executables intended to be invoked directly by the user
# Don't put wildcards in these variables, it might cause an uninstall of other stuff
VL_INST_PUBLIC_SCRIPT_FILES = verilator \
verilator_coverage \
verilator_gantt \
verilator_profcfunc \
VL_INST_PUBLIC_BIN_FILES = verilator_bin$(EXEEXT) \
verilator_bin_dbg$(EXEEXT) \
verilator_coverage_bin_dbg$(EXEEXT) \
# Private executabels intended to be invoked by internals
# Don't put wildcards in these variables, it might cause an uninstall of other stuff
VL_INST_PRIVATE_SCRIPT_FILES = verilator_ccache_report \
verilator_includer \
VL_INST_INC_BLDDIR_FILES = \
include/verilated_config.h \
@@ -226,19 +237,34 @@ VL_INST_DATA_SRCDIR_FILES = \
examples/*/Makefile* \
examples/*/vl_* \
installbin:
$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator $(DESTDIR)$(bindir)/verilator )
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_coverage $(DESTDIR)$(bindir)/verilator_coverage )
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_gantt $(DESTDIR)$(bindir)/verilator_gantt )
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_profcfunc $(DESTDIR)$(bindir)/verilator_profcfunc )
( cd bin ; $(INSTALL_PROGRAM) verilator_bin$(EXEEXT) $(DESTDIR)$(bindir)/verilator_bin$(EXEEXT) )
( cd bin ; $(INSTALL_PROGRAM) verilator_bin_dbg$(EXEEXT) $(DESTDIR)$(bindir)/verilator_bin_dbg$(EXEEXT) )
( cd bin ; $(INSTALL_PROGRAM) verilator_coverage_bin_dbg$(EXEEXT) $(DESTDIR)$(bindir)/verilator_coverage_bin_dbg$(EXEEXT) )
mkbindirs:
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/bin
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer )
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_ccache_report $(DESTDIR)$(pkgdatadir)/bin/verilator_ccache_report )
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_difftree $(DESTDIR)$(pkgdatadir)/bin/verilator_difftree )
$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
installbin: | mkbindirs
cd $(srcdir)/bin; \
for p in $(VL_INST_PUBLIC_SCRIPT_FILES) ; do \
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkgdatadir)/bin/$$p; \
done
cd bin; \
for p in $(VL_INST_PUBLIC_BIN_FILES) ; do \
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkgdatadir)/bin/$$p; \
done
cd $(srcdir)/bin; \
for p in $(VL_INST_PRIVATE_SCRIPT_FILES) ; do \
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkgdatadir)/bin/$$p; \
done
installredirect: installbin | mkbindirs
cp ${srcdir}/bin/redirect ${srcdir}/bin/redirect.tmp
perl -p -i -e 'use File::Spec;' \
-e' $$path = File::Spec->abs2rel("$(realpath $(DESTDIR)$(pkgdatadir)/bin)", "$(realpath $(DESTDIR)$(bindir))");' \
-e 's/RELPATH.*/"$$path";/g' -- "${srcdir}/bin/redirect.tmp"
cd $(srcdir)/bin; \
for p in $(VL_INST_PUBLIC_SCRIPT_FILES) $(VL_INST_PUBLIC_BIN_FILES) ; do \
$(INSTALL_PROGRAM) redirect.tmp $(DESTDIR)$(bindir)/$$p; \
done
rm ${srcdir}/bin/redirect.tmp
# Man files can either be part of the original kit, or built in current directory
# So important we use $^ so VPATH is searched
@@ -269,7 +295,7 @@ installdata:
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_c
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_sc
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_protect_lib
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/xml_py
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/json_py
cd $(srcdir) \
; for p in $(VL_INST_DATA_SRCDIR_FILES) ; do \
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
@@ -281,8 +307,11 @@ installdata:
# We don't trust rm -rf, so rmdir instead as it will fail if user put in other files
uninstall:
-cd $(DESTDIR)$(bindir) && rm -f $(VL_INST_BIN_FILES)
-cd $(DESTDIR)$(pkgdatadir)/bin && rm -f $(VL_INST_BIN_FILES)
-cd $(DESTDIR)$(bindir) && rm -f $(VL_INST_PUBLIC_SCRIPT_FILES)
-cd $(DESTDIR)$(bindir) && rm -f $(VL_INST_PUBLIC_BIN_FILES)
-cd $(DESTDIR)$(pkgdatadir)/bin && rm -f $(VL_INST_PUBLIC_SCRIPT_FILES)
-cd $(DESTDIR)$(pkgdatadir)/bin && rm -f $(VL_INST_PUBLIC_BIN_FILES)
-cd $(DESTDIR)$(pkgdatadir)/bin && rm -f $(VL_INST_PRIVATE_SCRIPT_FILES)
-cd $(DESTDIR)$(mandir)/man1 && rm -f $(VL_INST_MAN_FILES)
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_BLDDIR_FILES)
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_SRCDIR_FILES)
@@ -305,13 +334,13 @@ uninstall:
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_c
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_sc
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_protect_lib
-rmdir $(DESTDIR)$(pkgdatadir)/examples/xml_py
-rmdir $(DESTDIR)$(pkgdatadir)/examples/json_py
-rmdir $(DESTDIR)$(pkgdatadir)/examples
-rmdir $(DESTDIR)$(pkgdatadir)
-rmdir $(DESTDIR)$(pkgconfigdir)
install: all_nomsg install-all
install-all: installbin installman installdata install-msg
install-all: installbin installredirect installman installdata install-msg
install-here: installman info
@@ -340,7 +369,7 @@ CPPCHECK_FLAGS = --enable=all --inline-suppr \
--suppress=useStlAlgorithm
CPPCHECK_FLAGS += --xml
CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CHECK_CPP))
CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/src/obj_dbg -I$(srcdir)/src
CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/include/gtkwave -I$(srcdir)/include/vltstd -I$(srcdir)/src/obj_dbg -I$(srcdir)/src
cppcheck: cppcheck-1 cppcheck-2 cppcheck-3 cppcheck-4 cppcheck-5 cppcheck-6 cppcheck-7 cppcheck-8
cppcheck-1:
@@ -399,8 +428,8 @@ PY_PROGRAMS = \
bin/verilator_gantt \
bin/verilator_includer \
bin/verilator_profcfunc \
examples/xml_py/vl_file_copy \
examples/xml_py/vl_hier_graph \
examples/json_py/vl_file_copy \
examples/json_py/vl_hier_graph \
docs/guide/conf.py \
docs/bin/vl_sphinx_extract \
docs/bin/vl_sphinx_fix \
@@ -410,6 +439,7 @@ PY_PROGRAMS = \
src/cppcheck_filtered \
src/flexfix \
src/vlcovgen \
src/.gdbinit.py \
test_regress/t/*.pf \
nodist/clang_check_attributes \
nodist/code_coverage \
+18 -17
View File
@@ -1,21 +1,23 @@
.. Github doesn't render images unless absolute URL
.. Do not know of a conditional tag, "only: github" nor "github display" works
.. image:: https://img.shields.io/badge/Website-Verilator.org-181717.svg
|badge1| |badge2| |badge3| |badge4| |badge5| |badge6| |badge7| |badge8|
.. |badge1| image:: https://img.shields.io/badge/Website-Verilator.org-181717.svg
:target: https://verilator.org
.. image:: https://img.shields.io/badge/License-LGPL%20v3-blue.svg
.. |badge2| image:: https://img.shields.io/badge/License-LGPL%20v3-blue.svg
:target: https://www.gnu.org/licenses/lgpl-3.0
.. image:: https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg
.. |badge3| image:: https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg
:target: https://opensource.org/licenses/Artistic-2.0
.. image:: https://repology.org/badge/tiny-repos/verilator.svg?header=distro%20packages
.. |badge4| image:: https://repology.org/badge/tiny-repos/verilator.svg?header=distro%20packages
:target: https://repology.org/project/verilator/versions
.. image:: https://img.shields.io/docker/pulls/verilator/verilator
.. |badge5| image:: https://img.shields.io/docker/pulls/verilator/verilator
:target: https://hub.docker.com/r/verilator/verilator
.. image:: https://api.codacy.com/project/badge/Grade/fa78caa433c84a4ab9049c43e9debc6f
.. |badge6| image:: https://api.codacy.com/project/badge/Grade/fa78caa433c84a4ab9049c43e9debc6f
:target: https://www.codacy.com/gh/verilator/verilator
.. image:: https://codecov.io/gh/verilator/verilator/branch/master/graph/badge.svg
.. |badge7| image:: https://codecov.io/gh/verilator/verilator/branch/master/graph/badge.svg
:target: https://codecov.io/gh/verilator/verilator
.. image:: https://github.com/verilator/verilator/workflows/build/badge.svg
.. |badge8| image:: https://github.com/verilator/verilator/workflows/build/badge.svg
:target: https://github.com/verilator/verilator/actions?query=workflow%3Abuild
@@ -66,9 +68,9 @@ executable performs the design simulation. Verilator also supports linking
Verilated generated libraries, optionally encrypted, into other simulators.
Verilator may not be the best choice if you are expecting a full-featured
replacement for a closed-source Verilog simulator, needs SDF annotation,
replacement for a closed-source Verilog simulator, need SDF annotation,
mixed-signal simulation, or are doing a quick class project (we recommend
`Icarus Verilog`_ for classwork.) However, if you are looking for a path
`Icarus Verilog`_ for classwork). However, if you are looking for a path
to migrate SystemVerilog to C++/SystemC, or want high-speed simulation of
designs, Verilator is the tool for you.
@@ -80,17 +82,16 @@ Verilator does not directly translate Verilog HDL to C++ or SystemC. Rather,
Verilator compiles your code into a much faster optimized and optionally
thread-partitioned model, which is in turn wrapped inside a C++/SystemC
module. The results are a compiled Verilog model that executes even on a
single-thread over 10x faster than standalone SystemC, and on a single
single thread over 10x faster than standalone SystemC, and on a single
thread is about 100 times faster than interpreted Verilog simulators such
as `Icarus Verilog`_. Another 2-10x speedup might be gained from
multithreading (yielding 200-1000x total over interpreted simulators).
Verilator has typically similar or better performance versus the
closed-source Verilog simulators (e.g., Carbon Design Systems Carbonator,
Modelsim/Questa, Cadence Incisive/NC-Verilog, Synopsys VCS, VTOC, and
Pragmatic CVer/CVC). But, Verilator is open-sourced, so you can spend on
computes rather than licenses. Thus, Verilator gives you the best
simulation cycles/dollar.
Verilator has typically similar or better performance versus closed-source
Verilog simulators (e.g., Aldec Riviera-Pro, Cadence Incisive/NC-Verilog,
Mentor ModelSim/Questa, Synopsys VCS, VTOC, and Pragmatic CVer/CVC). But,
Verilator is open-sourced, so you can spend on computes rather than
licenses. Thus, Verilator gives you the best simulation cycles/dollar.
Installation & Documentation
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env perl
######################################################################
#
# 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
#
######################################################################
require 5.006_001;
use warnings;
use FindBin qw($RealBin $RealScript);
use strict;
my $relpath = RELPATH; # Substituted during Verilator 'make install'
unshift @ARGV, $RealScript;
exec { "$RealBin/$relpath/$RealScript" } @ARGV;
die "%Error: Exec failed,";
+68 -36
View File
@@ -15,6 +15,7 @@ use Getopt::Long;
use FindBin qw($RealBin $RealScript);
use IO::File;
use Pod::Usage;
use Cwd qw(realpath);
use strict;
use vars qw($Debug @Opt_Verilator_Sw);
@@ -32,6 +33,7 @@ my $opt_rr;
my $opt_gdbbt;
my $opt_quiet_exit;
my $opt_unlimited_stack = 1;
my $opt_valgrind;
# No arguments can't do anything useful. Give help
if ($#ARGV < 0) {
@@ -56,15 +58,29 @@ if (! GetOptions(
# Switches
"gdb!" => \$opt_gdb,
"gdbbt!" => \$opt_gdbbt,
"quiet!" => \$opt_quiet_exit, # As -quiet implies -quiet-exit
"quiet-exit!" => \$opt_quiet_exit,
"rr!" => \$opt_rr,
"unlimited-stack!" => \$opt_unlimited_stack,
"valgrind!" => \$opt_valgrind,
# Additional parameters
"<>" => sub {}, # Ignored
)) {
pod2usage(-exitstatus => 2, -verbose => 0);
}
my $verilator_root = realpath("$RealBin/..");
if (defined $ENV{VERILATOR_ROOT}) {
if ((!-d $ENV{VERILATOR_ROOT}) || $verilator_root ne realpath($ENV{VERILATOR_ROOT})) {
warn "%Error: verilator: VERILATOR_ROOT is set to inconsistent path. Suggest leaving it unset.\n";
warn "%Error: VERILATOR_ROOT=$ENV{VERILATOR_ROOT}\n";
exit 1;
}
} else {
print "export VERILATOR_ROOT='$verilator_root'\n" if $Debug;
$ENV{VERILATOR_ROOT} = $verilator_root;
}
if ($opt_gdbbt && !gdb_works()) {
warn "-Info: --gdbbt ignored: gdb doesn't seem to be working\n" if $Debug;
$opt_gdbbt = 0;
@@ -109,6 +125,18 @@ if ($opt_gdb) {
. " -ex \"run " . join(' ', @quoted_sw)."\""
. " -ex 'set width 0'"
. " -ex 'bt' -ex 'quit'");
} elsif ($opt_valgrind) {
# Run under valgrind
my $valgrind_bin = ($ENV{VERILATOR_VALGRIND} || "valgrind --error-exitcode=1 --max-stackframe=2815880"
# Magic number sugested by valgrind, may need to be increased in future
# if you get warnings. See: https://valgrind.org/docs/manual/manual-core.html#opt.max-stackframe
);
run (ulimit_stack_unlimited()
. aslr_off()
. $valgrind_bin
. " " . verilator_bin()
. " " . join(' ', @quoted_sw));
} elsif ($Debug) {
# Debug
run(ulimit_stack_unlimited()
@@ -137,30 +165,13 @@ sub debug {
# Builds
sub verilator_bin {
my $bin = "";
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
my $basename = ($ENV{VERILATOR_BIN}
|| ($Debug ? "verilator_bin_dbg" : "verilator_bin"));
if (defined($ENV{VERILATOR_ROOT})) {
my $dir = $ENV{VERILATOR_ROOT};
if (-x "$dir/bin/$basename"
|| -x "$dir/bin/$basename.exe") { # From a "make install" into VERILATOR_ROOT
$bin = "$dir/bin/$basename";
} else {
$bin = "$dir/$basename"; # From pointing to kit directory
}
if (-x "$RealBin/$basename" || -x "$RealBin/$basename.exe") {
return "$RealBin/$basename";
} else {
if (-x "$RealBin/$basename"
|| -x "$RealBin/$basename.exe") {
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
} else {
$bin = $basename; # Find in PATH
}
# Note we don't look under bin/$basename which would be right if running
# in the kit dir. Running that would likely break, since
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
return $basename; # Find in PATH
}
return $bin;
}
#######################################################################
@@ -298,7 +309,9 @@ detailed descriptions of these arguments.
+1800-2009ext+<ext> Use SystemVerilog 2009 with file extension <ext>
+1800-2012ext+<ext> Use SystemVerilog 2012 with file extension <ext>
+1800-2017ext+<ext> Use SystemVerilog 2017 with file extension <ext>
+1800-2023ext+<ext> Use SystemVerilog 2023 with file extension <ext>
--assert Enable all assertions
--assert-case Enable unique/unique0/priority case related checks
--autoflush Flush streams after all $displays
--bbox-sys Blackbox unknown $system calls
--bbox-unsup Blackbox unsupported language features
@@ -307,7 +320,6 @@ detailed descriptions of these arguments.
--build-dep-bin <filename> Override build dependency Verilator binary
--build-jobs <jobs> Parallelism for --build
--cc Create C++ output
--cdc Clock domain crossing analysis
-CFLAGS <flags> C++ compiler arguments for makefile
--clk <signal-name> Mark specified signal as clock
--no-clk <signal-name> Prevent marking specified signal as clock
@@ -325,7 +337,8 @@ detailed descriptions of these arguments.
--no-debug-leak Disable leaking memory in --debug mode
--debugi <level> Enable debugging at a specified level
--debugi-<srcfile> <level> Enable debugging a source file at a level
--no-decoration Disable comments and symbol decorations
--decorations <level> Set output comment and spacing level
--no-decoration Disable comments and lower spacing level
--default-language <lang> Default language to parse
+define+<var>=<value> Set preprocessor define
--dpi-hdr-only Only produce the DPI header file
@@ -334,10 +347,13 @@ detailed descriptions of these arguments.
--dump-graph Enable dumping V3Graphs to .dot files
--dump-tree Enable dumping Ast .tree files
--dump-tree-addrids Use short identifiers instead of addresses
--dump-tree-dot Enable dumping Ast .tree.dot debug files
--dump-tree-json Enable dumping Ast .tree.json files and .tree.meta.json file
--dump-<srcfile> Enable dumping everything in source file
--dumpi-dfg <level> Enable dumping DfgGraphs to .dot files at level
--dumpi-graph <level> Enable dumping V3Graphs to .dot files at level
--dumpi-tree <level> Enable dumping Ast .tree files at level
--dumpi-tree-json <level> Enable dumping Ast .tree.json files at level
--dumpi-<srcfile> <level> Enable dumping everything in source file at level
-E Preprocess, but do not compile
--error-limit <value> Abort after this number of errors
@@ -347,6 +363,8 @@ detailed descriptions of these arguments.
-f <file> Parse arguments from a file
-FI <file> Force include of a file
--flatten Force inlining of all modules, tasks and functions
--future0 <option> Ignore an option for compatibility
--future1 <option> Ignore an option with argument for compatibility
-fno-<optimization> Disable internal optimization stage
-G<name>=<value> Overwrite top-level parameter
--gate-stmts <value> Tune gate optimizer depth
@@ -355,7 +373,7 @@ detailed descriptions of these arguments.
--generate-key Create random key for --protect-key
--getenv <var> Get environment variable with defaults
--get-supported <feature> Get if feature is supported
--help Display this help
--help Show this help
--hierarchical Enable hierarchical Verilation
-I<dir> Directory to search for includes
--if-depth <value> Tune IFDEPTH warning
@@ -369,6 +387,7 @@ detailed descriptions of these arguments.
--lib-create <name> Create a DPI library
+libext+<ext>+[ext]... Extensions for finding modules
--lint-only Lint, but do not make output
--localize-max-size <value> Tune localize optimization variable size
--make <build-tool> Generate scripts for specified build tool
-MAKEFLAGS <flags> Arguments to pass to make during --build
--main Generate C++ main() file
@@ -383,12 +402,12 @@ detailed descriptions of these arguments.
-O3 High-performance optimizations
-O<optimization-letter> Selectable optimizations
-o <executable> Name of final executable
--no-order-clock-delay Disable ordering clock enable assignments
--output-split <statements> Split .cpp files into pieces
--output-split-cfuncs <statements> Split model functions
--output-split-ctrace <statements> Split tracing functions
-P Disable line numbers and blanks with -E
--pins-bv <bits> Specify types for top-level ports
--pins-inout-enables Specify that __en and __out signals be created for inouts
--pins-sc-biguint Specify types for top-level ports
--pins-sc-uint Specify types for top-level ports
--pins-uint8 Specify types for top-level ports
@@ -404,24 +423,29 @@ detailed descriptions of these arguments.
--protect-ids Hash identifier names for obscurity
--protect-key <key> Key for symbol protection
--protect-lib <name> Create a DPI protected library
--public Debugging; see docs
--public Mark signals as public; see docs
--public-depth <level> Mark public to specified module depth
--public-params Mark all parameters as public_flat
--public-flat-rw Mark all variables, etc as public_flat_rw
-pvalue+<name>=<value> Overwrite toplevel parameter
--quiet Minimize additional printing
--quiet-exit Don't print the command on failure
--quiet-stats Don't print statistics
--relative-includes Resolve includes relative to current file
--reloop-limit Minimum iterations for forming loops
--report-unoptflat Extra diagnostics for UNOPTFLAT
--rr Run Verilator and record with rr
--runtime-debug Enable model runtime debugging
--savable Enable model save-restore
--sc Create SystemC output
--no-skip-identical Disable skipping identical output
--stats Create statistics file
--stats-vars Provide statistics on variables
--no-std Prevent parsing standard library
--no-stop-fail Do not call $stop when assertion fails
--structs-packed Convert all unpacked structures to packed structures
-sv Enable SystemVerilog parsing
+systemverilogext+<ext> Synonym for +1800-2017ext+<ext>
+systemverilogext+<ext> Synonym for +1800-2023ext+<ext>
--threads <threads> Enable multithreading
--threads-dpi <mode> Enable multithreaded DPI
--threads-max-mtasks <mtasks> Tune maximum mtask partitioning
@@ -449,11 +473,12 @@ detailed descriptions of these arguments.
--unused-regexp <regexp> Tune UNUSED lint signals
-V Verbose version and config
-v <filename> Verilog library
--valgrind Run Verilator under valgrind
--verilate-jobs Job threads for Verilation stage
--no-verilate Skip Verilation and just compile previously Verilated code
+verilog1995ext+<ext> Synonym for +1364-1995ext+<ext>
+verilog2001ext+<ext> Synonym for +1364-2001ext+<ext>
--version Displays program version and exits
--version Show program version and exits
--vpi Enable VPI compiles
--waiver-output <filename> Create a waiver file based on the linter warnings
-Wall Enable all style warnings
@@ -471,6 +496,11 @@ detailed descriptions of these arguments.
--x-assign <mode> Assign non-initial Xs to this value
--x-initial <mode> Assign initial Xs to this value
--x-initial-edge Enable initial X->0 and X->1 edge triggers
--no-json-edit-nums Don't dump editNum in .tree.json files
--no-json-ids Don't use short identifiers instead of adresses/paths in .tree.json
--json-only Create JSON parser output (.tree.json and .meta.json)
--json-only-output .tree.json output filename
--json-only-meta-output .tree.meta.json output filename
--xml-only Create XML parser output
--xml-output XML output filename
-y <dir> Directory to search for modules
@@ -482,19 +512,21 @@ description of these arguments.
=for VL_SPHINX_EXTRACT "_build/gen/args_verilated.rst"
+verilator+debug Enable debugging
+verilator+debugi+<value> Enable debugging at a level
+verilator+error+limit+<value> Set error limit
+verilator+help Display help
+verilator+noassert Disable assert checking
+verilator+debug Enable debugging
+verilator+debugi+<value> Enable debugging at a level
+verilator+coverage+file+<filename> Set coverage output filename
+verilator+error+limit+<value> Set error limit
+verilator+help Show help
+verilator+noassert Disable assert checking
+verilator+prof+exec+file+<filename> Set execution profile filename
+verilator+prof+exec+start+<value> Set execution profile starting point
+verilator+prof+exec+window+<value> Set execution profile duration
+verilator+prof+vlt+file+<filename> Set PGO profile filename
+verilator+rand+reset+<value> Set random reset technique
+verilator+seed+<value> Set random seed
+verilator+V Verbose version and config
+verilator+version Show version and exit
+verilator+quiet Minimize additional printing
+verilator+rand+reset+<value> Set random reset technique
+verilator+seed+<value> Set random seed
+verilator+V Show verbose version and config
+verilator+version Show version and exit
=head1 DISTRIBUTION
+8 -8
View File
@@ -154,9 +154,9 @@ verilator_coverage - Verilator coverage analyzer
verilator_coverage --annotate <obj>
verilator_coverage -write merged.dat -read <datafiles>...
verilator_coverage -write merged.dat <datafiles>...
verilator_coverage -write-info merged.info -read <datafiles>...
verilator_coverage -write-info merged.info <datafiles>...
Verilator_coverage processes Verilated model-generated coverage reports.
@@ -177,12 +177,12 @@ L<https://verilator.org/guide/latest/exe_verilator_coverage.html>.
--write <filename> Write aggregate coverage results.
--write-info <filename.info> Write lcov .info.
+libext+I<ext>+I<ext>... Extensions for Verilog files.
+define+I<var>+I<value> Defines the given variable.
-DI<var>=I<value> Defines the given variable.
+incdir+I<dir> Add directory for finding include files.
-II<dir> Add directory for finding include files.
-y I<dir> Specifies module search directory.
+libext+<ext>+<ext>... Extensions for Verilog files.
+define+<var>+<value> Defines the given variable.
-D<var>=<value> Defines the given variable.
+incdir+<dir> Add directory for finding include files.
-I<dir> Add directory for finding include files.
-y <dir> Specifies module search directory.
=head1 DISTRIBUTION
+8 -21
View File
@@ -27,12 +27,6 @@ fatal() {
echo "ERROR: $(basename "$0"): $1" >&2; exit 1;
}
if [ "$CI_M32" = "0" ]; then
unset CI_M32
elif [ "$CI_M32" != "1" ]; then
fatal "\$CI_M32 must be '0' or '1'";
fi
if [ "$CI_OS_NAME" = "linux" ]; then
MAKE=make
elif [ "$CI_OS_NAME" = "osx" ]; then
@@ -77,10 +71,6 @@ if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
if [ "$COVERAGE" = 1 ]; then
yes yes | sudo cpan -fi Parallel::Forker
fi
if [ "$CI_M32" = 1 ]; then
sudo apt-get install gcc-multilib g++-multilib ||
sudo apt-get install gcc-multilib g++-multilib
fi
elif [ "$CI_OS_NAME" = "osx" ]; then
brew update
brew install ccache perl gperftools
@@ -102,29 +92,24 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
sudo apt-get update ||
sudo apt-get update
# libfl-dev needed for internal coverage's test runs
sudo apt-get install gdb gtkwave lcov libfl-dev ccache ||
sudo apt-get install gdb gtkwave lcov libfl-dev ccache
sudo apt-get install gdb gtkwave lcov libfl-dev ccache jq z3 ||
sudo apt-get install gdb gtkwave lcov libfl-dev ccache jq z3
# Required for test_regress/t/t_dist_attributes.pl
if [ "$CI_RUNS_ON" = "ubuntu-22.04" ]; then
sudo apt-get install libclang-dev mold ||
sudo apt-get install libclang-dev mold
pip3 install clang==14.0
sudo apt-get install python3-clang mold ||
sudo apt-get install python3-clang mold
fi
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ] || [ "$CI_RUNS_ON" = "ubuntu-22.04" ]; then
sudo apt-get install libsystemc-dev ||
sudo apt-get install libsystemc-dev
fi
if [ "$CI_M32" = 1 ]; then
sudo apt-get install lib32z1-dev gcc-multilib g++-multilib ||
sudo apt-get install lib32z1-dev gcc-multilib g++-multilib
fi
elif [ "$CI_OS_NAME" = "osx" ]; then
brew update
# brew cask install gtkwave # fst2vcd hangs at launch, so don't bother
brew install ccache perl
brew install ccache perl jq z3
elif [ "$CI_OS_NAME" = "freebsd" ]; then
# fst2vcd fails with "Could not open '<input file>', exiting."
sudo pkg install -y ccache gmake perl5 python3
sudo pkg install -y ccache gmake perl5 python3 jq z3
else
fatal "Unknown os: '$CI_OS_NAME'"
fi
@@ -134,6 +119,8 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
fi
yes yes | sudo cpan -M $CI_CPAN_REPO -fi Parallel::Forker
install-vcddiff
# Workaround -fsanitize=address crash
sudo sysctl -w vm.mmap_rnd_bits=28
else
##############################################################################
# Unknown build stage
+24 -13
View File
@@ -21,12 +21,6 @@ fatal() {
echo "ERROR: $(basename "$0"): $1" >&2; exit 1;
}
if [ "$CI_M32" = "0" ]; then
unset CI_M32
elif [ "$CI_M32" != "1" ]; then
fatal "\$CI_M32 must be '0' or '1'";
fi
if [ "$CI_OS_NAME" = "linux" ]; then
export MAKE=make
NPROC=$(nproc)
@@ -46,7 +40,7 @@ if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
if [ "$COVERAGE" != 1 ]; then
autoconf
./configure --enable-longtests --enable-ccwarn ${CI_M32:+--enable-m32}
./configure --enable-longtests --enable-ccwarn --prefix="$INSTALL_DIR"
ccache -z
"$MAKE" -j "$NPROC" -k
# 22.04: ccache -s -v
@@ -91,25 +85,42 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
fi
# Run sanitize on Ubuntu 22.04 only
[ "$CI_RUNS_ON" = 'ubuntu-22.04' ] && [ "$CI_M32" = "" ] && sanitize='--sanitize' || sanitize=''
[ "$CI_RUNS_ON" = 'ubuntu-22.04' ] && sanitize='--sanitize' || sanitize=''
TEST_REGRESS=test_regress
if [ "$CI_RELOC" == 1 ]; then
# Testing that the installation is relocatable.
"$MAKE" install
mkdir -p "$RELOC_DIR"
mv "$INSTALL_DIR" "$RELOC_DIR/relocated-install"
export VERILATOR_ROOT="$RELOC_DIR/relocated-install/share/verilator"
TEST_REGRESS="$RELOC_DIR/test_regress"
mv test_regress "$TEST_REGRESS"
# Feeling brave?
find . -delete
ls -la .
fi
# Run the specified test
ccache -z
case $TESTS in
dist-vlt-0)
"$MAKE" -C test_regress SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=0/3
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=0/4
;;
dist-vlt-1)
"$MAKE" -C test_regress SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=1/3
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=1/4
;;
dist-vlt-2)
"$MAKE" -C test_regress SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=2/3
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=2/4
;;
dist-vlt-3)
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=3/4
;;
vltmt-0)
"$MAKE" -C test_regress SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=0/2
"$MAKE" -C "$TEST_REGRESS" SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=0/2
;;
vltmt-1)
"$MAKE" -C test_regress SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=1/2
"$MAKE" -C "$TEST_REGRESS" SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=1/2
;;
coverage-all)
nodist/code_coverage --stages 1-
+13
View File
@@ -1,3 +1,15 @@
# DESCRIPTION: Verilator: CI Windows Power Shell - Compile Verilator
#
# Copyright 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
################################################################################
Set-PSDebug -Trace 1
if (-Not (Test-Path $PWD/../.ccache/win_bison.exe)) {
git clone --depth 1 https://github.com/lexxmark/winflexbison
cd winflexbison
@@ -8,6 +20,7 @@ if (-Not (Test-Path $PWD/../.ccache/win_bison.exe)) {
cmake --install . --prefix $PWD/../../../.ccache
cd ../..
}
mkdir build
cd build
cmake .. --install-prefix $PWD/../install
+17 -1
View File
@@ -1,3 +1,16 @@
# DESCRIPTION: Verilator: CI Windows Power Shell - Verilate a test
#
# Copyright 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
################################################################################
Set-PSDebug -Trace 1
cd install
$Env:VERILATOR_ROOT=$PWD
cd examples/cmake_tracing_c
@@ -5,6 +18,9 @@ mkdir build
cd build
cmake ..
cmake --build . --config Release -j 3
Release/example.exe
# TODO put this back in, see issue# 5163
# Release/example.exe
cd ..
Remove-Item -path build -recurse
+1
View File
@@ -43,6 +43,7 @@ RUN apt-get update \
perl \
python3 \
wget \
z3 \
zlib1g \
zlib1g-dev \
&& apt-get clean \
+27 -26
View File
@@ -5,12 +5,12 @@
# General Public License Version 3 or the Perl Artistic License Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
# When releasing, also update header of Changes file, and CmakeLists.txt,
# When releasing, also update header of Changes file, and CMakeLists.txt,
# and commit using "devel release" or "Version bump" message
# Then 'make maintainer-dist'
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[5.020 2024-01-01],
AC_INIT([Verilator],[5.026 2024-06-15],
[https://verilator.org],
[verilator],[https://verilator.org])
@@ -67,20 +67,6 @@ AC_ARG_ENABLE([tcmalloc],
[CFG_WITH_TCMALLOC=check;])
AC_MSG_RESULT($CFG_WITH_TCMALLOC)
# Flag to enable -m32 build
AC_MSG_CHECKING(whether to use -m32)
AC_ARG_ENABLE([m32],
[AS_HELP_STRING([--enable-m32],
[Use -m32 for all compilation and link,
including Verilator and generated models.])],
[case "${enableval}" in
yes) CFG_ENABLE_M32=yes ;;
no) CFG_ENABLE_M32=no ;;
*) AC_MSG_ERROR([bad value '${enableval}' for --enable-m32]) ;;
esac],
CFG_ENABLE_M32=no)
AC_MSG_RESULT($CFG_ENABLE_M32)
# Flag to enable coverage build
AC_MSG_CHECKING(whether to build for coverage collection)
AC_ARG_ENABLE([coverage],
@@ -148,6 +134,28 @@ AC_ARG_ENABLE([longtests],
AC_SUBST(CFG_WITH_LONGTESTS)
AC_MSG_RESULT($CFG_WITH_LONGTESTS)
AC_CHECK_PROG(HAVE_Z3,z3,yes)
AC_CHECK_PROG(HAVE_CVC5,cvc5,yes)
AC_CHECK_PROG(HAVE_CVC4,cvc4,yes)
# Special Substitutions - CFG_WITH_SOLVER
AC_MSG_CHECKING(for SMT solver)
AC_ARG_WITH([solver],
[AS_HELP_STRING([--with-solver='z3 --in'],
[set default SMT solver for constrained randomization])],
[CFG_WITH_SOLVER="${withval}"],
[CFG_WITH_SOLVER=no
if test "x$HAVE_Z3" = "xyes"; then
CFG_WITH_SOLVER="z3 --in"
elif test "x$HAVE_CVC5" = "xyes"; then
CFG_WITH_SOLVER="cvc5 --incremental"
elif test "x$HAVE_CVC4" = "xyes"; then
CFG_WITH_SOLVER="cvc4 --lang=smt2 --incremental"
fi]
)
AC_SUBST(CFG_WITH_SOLVER)
AC_MSG_RESULT($CFG_WITH_SOLVER)
# Compiler flags (ensure they are not empty to avoid configure defaults)
CFLAGS="$CFLAGS "
CPPFLAGS="$CPPFLAGS "
@@ -319,15 +327,7 @@ AC_DEFUN([_MY_LDLIBS_CHECK_OPT],
_MY_LDLIBS_CHECK_IFELSE($2, $1="$$1 $2")
])
# When using -m32. Check this first as later checks may fail with the -m32 flag.
if test "$CFG_ENABLE_M32" = "yes"; then
_MY_CXX_CHECK_IFELSE(
-m32,
[CXX="$CXX -m32"],
[AC_MSG_ERROR([--enable-m32 was given but compiler does not support -m32])])
fi
# Similarly, add the coverage flags early as they influence later checks.
# Add the coverage flags early as they influence later checks.
if test "$CFG_ENABLE_COVERAGE" = "yes"; then
_MY_CXX_CHECK_OPT(CXX,--coverage)
# Otherwise inline may not show as uncovered
@@ -446,11 +446,11 @@ m4_foreach([cflag],[
[-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-tautological-compare],
[-Wno-uninitialized],
[-Wno-unused-but-set-parameter],
[-Wno-unused-but-set-variable],
@@ -497,6 +497,7 @@ AC_SUBST(CFG_LDFLAGS_VERILATED)
# pthreads is harmless otherwise.
CFG_LIBS="$LIBS $CFG_LIBS"
_MY_LDLIBS_CHECK_OPT(CFG_LIBS, -lpthread)
_MY_LDLIBS_CHECK_OPT(CFG_LIBS, -latomic)
# Check libraries for MingW
_MY_LDLIBS_CHECK_OPT(CFG_LIBS, -lbcrypt)
+23
View File
@@ -4,24 +4,31 @@ under the Developer Certificate of Origin (https://developercertificate.org/).
Please see the Verilator manual for 200+ additional contributors. Thanks to all.
Adam Bagley
Adrian Sampson
Adrien Le Masle
Ahmed El-Mahmoudy
Aleksander Kiryk
Alex Chadwick
Alex Solomatnikov
Àlex Torregrosa
Aliaksei Chapyzhenka
Ameya Vikram Singh
Andrea Calabrese
Andreas Kuster
Andrei Kostovski
Andrew Miloradovsky
Andrew Nolte
Anthony Donlon
Arkadiusz Kozdra
Arthur Rosa
Aylon Chaim Porat
Bartłomiej Chmiel
Cameron Kirk
Chih-Mao Chen
Chris Randall
Christopher Taylor
Chuxuan Wang
Chykon
Conor McCullough
Dan Petrisko
Daniel Bates
@@ -30,6 +37,7 @@ David Ledger
David Metz
David Stanford
David Turner
Dercury
Don Williamson
Drew Ranck
Drew Taussig
@@ -43,10 +51,12 @@ february cozzocrea
Felix Neumärker
Felix Yan
Frans Skarman
Fuad Ismail
G-A. Kamendje
Garrett Smith
Geza Lore
Gianfranco Costamagna
Gijs Burghoorn
Glen Gibb
Gökçe Aydos
Graham Rushton
@@ -73,6 +83,7 @@ James Shi
Jamey Hicks
Jamie Iles
Jan Van Winkel
Jiangjie Weng
Jean Berniolles
Jeremy Bennett
Jesse Taube
@@ -86,6 +97,7 @@ John Coiner
John Demme
John Wehle
Jonathan Drolet
Jonathan Schröter
Jordan McConnon
Jose Loyola
Josep Sans
@@ -98,8 +110,10 @@ Justin Thiel
Kaleb Barrett
Kamil Rakoczy
Kanad Kanhere
Kefa Chen
Keith Colbert
Kevin Kiningham
Kevin Nygaard
Kritik Bhimani
Krzysztof Bieganski
Krzysztof Boronski
@@ -119,6 +133,7 @@ Marshal Qiao
Martin Schmidt
Martin Stadler
Matthew Ballance
Michael Bikovitsky
Michael Killough
Michaël Lefebvre
Michal Czyz
@@ -130,10 +145,15 @@ Mostafa Gamal
Nandu Raj
Nathan Kohagen
Nathan Myers
Nolan Poe
Oleh Maksymenko
Patrick Stewart
Paul Bowen-Huggett
Paul Swirhun
Paul Wright
Pawel Jewstafjew
Pawel Sagan
Pengcheng Xu
Peter Debacker
Peter Horvath
Peter Monsson
@@ -159,6 +179,7 @@ Srinivasan Venkataramanan
Stefan Wallentowitz
Stephen Henry
Steven Hugg
Szymon Gizler
Sören Tempel
Teng Huang
Tim Hutt
@@ -173,6 +194,7 @@ Tudor Timi
Tymoteusz Blazejczyk
Udi Finkelstein
Unai Martinez-Corral
Valentin Atepalikhin
Varun Koyyalagunta
Vassilis Papaefstathiou
Veripool API Bot
@@ -181,6 +203,7 @@ Vito Gamberini
William D. Jones
Wilson Snyder
Xi Zhang
Yan Xu
Yinan Xu
Yoda Lee
Yossi Nivin
+1 -1
View File
@@ -1,6 +1,6 @@
.. comment: generated by t_lint_multidriven_bad
.. code-block::
%Warning-MULTIDRIVEN: example.v:1:22 Signal has multiple driving blocks with different clocking: 'out2'
%Warning-MULTIDRIVEN: example.v:1:22 Signal has multiple driving blocks with different clocking: 't.mem'
example.v:1:7 ... Location of first driving block
example.v:1:7 ... Location of other driving block
+1 -1
View File
@@ -45,7 +45,7 @@ def setup(app):
# -- Project information
project = 'Verilator'
copyright = '2022 by Wilson Snyder, under LGPL-3.0 or Artistic-2.0'
copyright = '2024 by Wilson Snyder, under LGPL-3.0 or Artistic-2.0'
author = 'Wilson Snyder'
# The master toctree document.
+11 -1
View File
@@ -407,6 +407,16 @@ only a couple of instructions.
For signal callbacks to work the main loop of the program must call
:code:`VerilatedVpi::callValueCbs()`.
Verilator also tracks when the model state has been modified via the VPI with
an :code:`evalNeeded` flag. This flag can be checked with :code:`VerilatedVpi::evalNeeded()`
and it can be cleared with :code:`VerilatedVpi::clearEvalNeeded()`. Used together
it is possible to skip :code:`eval()` calls if no model state has been changed
since the last :code:`eval()`.
Any data written via :code:`vpi_put_value` with :code:`vpiInertialDelay` will
be deferred for later. These delayed values can be flushed to the model with
:code:`VerilatedVpi::doInertialPuts()`.
.. _VPI Example:
@@ -500,7 +510,7 @@ the user should call:
any delayed events pending,
* :code:`designp->nextTimeSlot()`, which returns the simulation time of the
next delayed event. This method can only be called if
:code:`designp->nextTimeSlot()` returned :code:`true`.
:code:`designp->eventsPending()` returned :code:`true`.
Call :code:`eventsPending()` to check if you should continue with the
simulation, and then :code:`nextTimeSlot()` to move simulation time forward.
+4 -5
View File
@@ -6,7 +6,7 @@ Deprecations
The following deprecated items are scheduled for future removal:
C++11 compiler support
C++14 compiler support
Verilator currently requires a C++20 or newer compiler for timing, and a
C++14 or newer compiler for both compiling Verilator and compiling
Verilated models with --no-timing.
@@ -14,7 +14,6 @@ C++11 compiler support
Verilator will require C++20 or newer compilers for both compiling
Verilator and compiling all Verilated models no sooner than January 2025.
32-bit 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.
XML output
Verilator currently supports XML parser output (enabled with `--xml-only`).
Support for `--xml-*` options will be deprecated no sooner than January 2025.
+11
View File
@@ -118,6 +118,17 @@ associated programs.
See :ref:`Installation` for more details.
.. option:: VERILATOR_SOLVER
If set, the command to run as a constrained randomization backend, such
as :command:`cvc4 --lang=smt2 --incremental`. If not specified, it will use
the one supplied or found during configure, or :command:`z3 --in` if empty.
.. option:: VERILATOR_VALGRIND
If set, the command to run when using the :vlopt:`--valgrind` option, such as
"valgrind --tool=callgrind". If not specified, it will use "valgrind".
Make Variables
==============
+1
View File
@@ -9,6 +9,7 @@ Examples
This section covers the following examples:
* :ref:`Example Create-Binary Execution`
* :ref:`Example C++ Execution`
* :ref:`Example SystemC Execution`
* :ref:`Examples in the Distribution`
+14
View File
@@ -19,11 +19,20 @@ Summary:
.. include:: ../_build/gen/args_verilated.rst
.. option:: +verilator+coverage+file+<filename>
When a model was Verilated using :vlopt:`--coverage`, sets the filename
to write coverage data into. Defaults to :file:`coverage.dat`.
.. option:: +verilator+debug
Enable simulation runtime debugging. Equivalent to
:vlopt:`+verilator+debugi+4 <+verilator+debugi+\<value\>>`.
To be useful, the model typically must first be compiled with debug
capabilities by Verilating with :vlopt:`--runtime-debug` or `-CFLAGS
-DVL_DEBUG=1`.
.. option:: +verilator+debugi+<value>
Enable simulation runtime debugging at the provided level.
@@ -83,6 +92,11 @@ Summary:
profile-guided optimization data runtime filename to dump to. Defaults
to :file:`profile.vlt`.
.. option:: +verilator+quiet
Disable printing the simulation summary report, see :ref:`Simulation
Summary Report`.
.. option:: +verilator+rand+reset+<value>
When a model was Verilated using
+175 -20
View File
@@ -51,6 +51,8 @@ Summary:
.. option:: +1800-2017ext+<ext>
.. option:: +1800-2023ext+<ext>
Specifies the language standard to be used with a specific filename
extension, <ext>.
@@ -85,7 +87,11 @@ Summary:
.. option:: --assert
Enable all assertions.
Enable all assertions. Implies :vlopt:`--assert-case`.
.. option:: --assert-case
Enable unique/unique0/priority case related checks.
.. option:: --autoflush
@@ -195,9 +201,10 @@ Summary:
.. option:: --compiler <compiler-name>
Enables workarounds for the specified C++ compiler (list below).
This does not change any performance tuning options, but it may
in the future.
Enables workarounds for the specified C++ compiler (list below). This
does not change any performance tuning options, but it may in the
future. This also does not change default compiler flags; these are
determined when Verilator was configured.
clang
Tune for clang. This may reduce execution speed as it enables several
@@ -304,19 +311,47 @@ Summary:
detailed messages. See :vlopt:`--debug` for other implications of
enabling debug.
.. option:: --decorations none
.. option:: --decorations medium
.. option:: --decorations node
When creating output Verilated code, set level of comment and whitespace
decoration.
With "--decorations none",
Minimize comments, white space, symbol names, and other decorative
items, at the cost of reduced readability. This may assist C++ compile
times. This will not typically change the ultimate model's
performance, but may in some cases. See also :vlopt:`--no-decoration`
option.
With "--decorations medium",
The default, put a small amount of comments and white space, for
typical level of readability.
With "--decorations node",
Include comments indicating what caused generation of the following
text, including what node pointer (corresponding to
:vlopt:`--dump-tree` .tree printed data), and the source Verilog
filename and line number. If subsequent following statements etc have
the same filename/line number these comments are omitted. This
enables easy debug when looking at the C++ code to determine what
Verilog source may be related. As node pointers are not stable
between different Verilator runs, this may harm compile caching and
should only be used for debug.
.. option:: --no-decoration
When creating output Verilated code, minimize comments, white space,
symbol names, and other decorative items, at the cost of reduced
readability. This may assist C++ compile times. This will not typically
change the ultimate model's performance, but may in some cases.
Alias for ``--decorations none``.
.. option:: --default-language <value>
Select the language used by default when first processing each
Verilog file. The language value must be "VAMS", "1364-1995",
"1364-2001", "1364-2001-noconfig", "1364-2005", "1800-2005",
"1800-2009", "1800-2012", "1800-2017", or "1800+VAMS".
"1800-2009", "1800-2012", "1800-2017", "1800-2023", or "1800+VAMS".
Any language associated with a particular file extension (see the
various +<lang>*\ ext+ options) will be used in preference to the
@@ -329,7 +364,7 @@ Summary:
``+<lang>ext+`` options should be used.
If no language is specified, either by this option or ``+<lang>ext+``
options, then the latest SystemVerilog language (IEEE 1800-2017) is
options, then the latest SystemVerilog language (IEEE 1800-2023) is
used.
.. option:: +define+<var>=<value>
@@ -378,6 +413,12 @@ Summary:
:vlopt:`--debug --no-dump-tree <--dump-tree>` may be useful if the dump
files are large and not desired.
.. option:: --dump-tree-json
Rarely needed. Enable dumping Ast .json.tree debug files with dumping level 3,
which dumps the standard critical stages. For details on the format, see
the Verilator Internals manual.
.. option:: --dump-tree-dot
Rarely needed. Enable dumping Ast .tree.dot debug files in Graphviz
@@ -413,6 +454,11 @@ Summary:
Rarely needed - for developer use. Set internal Ast dumping level
globally to the specified value.
.. option:: --dumpi-tree-json <level>
Rarely needed - for developer use. Set internal Ast JSON dumping level
globally to the specified value.
.. option:: --dumpi-<srcfile> <level>
Rarely needed - for developer use. Set the dumping level in the
@@ -771,6 +817,11 @@ Summary:
If the design is not to be completely Verilated, see also the
:vlopt:`--bbox-sys` and :vlopt:`--bbox-unsup` options.
.. option:: --localize-max-size <value>
Rarely needed. Set the maximum variable size in bytes for it to be
subject to localizing-to-stack optimization. Defaults to 1024.
.. option:: --make <build-tool>
Generates a script for the specified build tool.
@@ -939,6 +990,13 @@ Summary:
:option:`/*verilator&32;sc_bv*/` metacomment to select specific ports to
be sc_bv.
.. option:: --pins-inout-enables
Specifies that the __en and __out outputs will always be created for
inouts in the top-level module. The __en variable has a one in a bit
position to indicate the corresponding bit of the __out variable has
a value being driven from within the Verilated model.
.. option:: --pins-sc-uint
Specifies SystemC inputs/outputs greater than 2 bits wide should use
@@ -1128,11 +1186,20 @@ Summary:
Overwrites the given parameter(s) of the top-level module. See
:vlopt:`-G <-G<name>>` for a detailed description.
.. option:: --quiet
Alias for :vlopt:`--quiet-exit` :vlopt:`--quiet-stats`.
.. option:: --quiet-exit
When exiting due to an error, do not display the "Exiting due to Errors"
nor "Command Failed" messages.
.. option:: --quiet-stats
Disable printing the Verilation statistics report, see :ref:`Verilation
Summary Report`.
.. option:: --relative-includes
When a file references an include file, resolve the filename relative to
@@ -1183,6 +1250,40 @@ Summary:
Run Verilator and record with the :command:`rr` command. See
`https://rr-project.org <https://rr-project.org>`_.
.. option:: --runtime-debug
Enable including debug assertions in the generated model. This may
significantly decrease model performance. This option will only work
with gcc/clang.
This option has the same effect as the following flags:
:vlopt:`--decorations node <--decorations>`
Instructs Verilator to add comments to the Verilated C++ code to
assist determining what Verilog code was responsible for each C++
statement.
``-CFLAGS -ggdb -LDFLAGS -ggdb``
Instructs the compiler and linker to enable debugger symbols.
``-CFLAGS -fsanitize=address,undefined -LDFLAGS -fsanitize=address,undefined``
Instructs the compiler and linker to enable the address sanitizer, and
undefined behavior sanitizer.
``-CFLAGS -D_GLIBCXX_DEBUG``
Instructs the compiler to enable C++ library (glibc) internal
assertions to find library-misuse issues.
``-CFLAGS -DVL_DEBUG=1``
Instructs the compiler to enable Verilator's runtime assertions and
debug capabilities. To enable debug print messages at runtime, see
:vlopt:`+verilator+debug`.
The :vlopt:`-CFLAGS` and/or :vlopt:`-LDFLAGS` options used here pass the
following argument into the generated Makefile for use as compiler or
linker options respectively. If you are using your own Makefiles, adapt
appropriately to pass the suggested flags to the compiler and linker.
.. option:: --savable
Enable including save and restore functions in the generated model. See
@@ -1205,6 +1306,8 @@ Summary:
Creates a dump file with statistics on the design in
:file:`<prefix>__stats.txt`.
Also dumps DFG patterns to
:file:`<prefix>__stats_dfg_patterns__*.txt`.
.. option:: --stats-vars
@@ -1216,6 +1319,10 @@ Summary:
Prevents parsing standard library.
.. option:: --no-stop-fail
Don't call $stop when assertion fails. Simulation will continue.
.. option:: --structs-packed
Converts all unpacked structures to packed structures, and issues an
@@ -1226,12 +1333,12 @@ Summary:
.. option:: -sv
Specifies SystemVerilog language features should be enabled; equivalent
to :vlopt:`--language 1800-2017 <--language>`. This option is selected
to :vlopt:`--language 1800-2023 <--language>`. This option is selected
by default; it exists for compatibility with other simulators.
.. option:: +systemverilogext+<ext>
A synonym for :vlopt:`+1800-2017ext+\<ext\>`.
A synonym for :vlopt:`+1800-2023ext+\<ext\>`.
.. option:: --threads <threads>
@@ -1424,13 +1531,17 @@ Summary:
.. option:: --unroll-count <loops>
Rarely needed. Specifies the maximum number of loop iterations that may be
unrolled. See also :option:`BLKLOOPINIT` warning.
Rarely needed. Specifies the maximum number of loop iterations that may
be unrolled. See also :option:`BLKLOOPINIT` warning, and
:option:`/*verilator&32;unroll_disable*/` and
:option:`/*verilator&32;unroll_full*/` metacomments.
.. 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.
that loop to be unrolled. See also :option:`BLKLOOPINIT` warning, and
:option:`/*verilator&32;unroll_disable*/` and
:option:`/*verilator&32;unroll_full*/` metacomments.
.. option:: --unused-regexp <regexp>
@@ -1450,6 +1561,11 @@ Summary:
used to resolve instances in the top-level module, otherwise, they are
ignored. Note "-v" is relatively standard across Verilog tools.
.. option:: --valgrind
Run Verilator under `Valgrind <https://valgrind.org/>`_. The command may be
changed with :option:`VERILATOR_VALGRIND`.
.. option:: --no-verilate
When using :vlopt:`--build`, disable the generation of C++/SystemC code, and
@@ -1628,9 +1744,9 @@ Summary:
.. note::
This option applies only to values explicitly written as X
in modules (not classes) in the Verilog source code. Initial values
of clocks are set to 0 unless `--x-initial-edge` is
This option applies only to values explicitly written as X in modules
(not classes, nor parameters) in the Verilog source code. Initial
values of clocks are set to 0 unless `--x-initial-edge` is
specified. Initial values of all other state holding variables are
controlled with `--x-initial`.
@@ -1695,19 +1811,58 @@ Summary:
iterations. This may be another indication of problems with the
modeled design that should be addressed.
.. option:: --json-only
Create JSON output only, do not create any other output.
The JSON format is intended to be used to leverage Verilator's parser and
elaboration to feed to other downstream tools. For details on the format, see
the Verilator Internals manual. Be aware that the JSON
format is still evolving; there will be some changes in future versions.
This option disables some more aggressive transformations and dumps only
the final state of the AST. For more granular and unaltered dumps, meant
mainly for debugging see :vlopt:`--dump-tree-json`.
.. option:: --json-only-meta-output <filename>
Specifies the filename for the metadata output file (`.tree.meta.json`) of --json-only.
Using this option automatically sets :vlopt:`--json-only`.
.. option:: --json-only-output <filename>
Specifies the filename for the main output file (`.tree.json`) of --json-only.
Using this option automatically sets :vlopt:`--json-only`.
.. option:: --no-json-edit-nums
Don't dump edit number in .tree.json files. This may make the file more
run-to-run stable for easier comparison.
.. option:: --no-json-ids
Don't use short identifiers instead of addresses/paths in .tree.json.
.. option:: --xml-only
Create XML output only, do not create any other output.
The XML format is intended to be used to leverage Verilator's parser and
elaboration to feed to other downstream tools. Be aware that the XML
format is still evolving; there will be some changes in future versions.
elaboration to feed to other downstream tools.
.. note::
This feature is deprecated in favor of :vlopt:`--json-only`.
.. option:: --xml-output <filename>
Specifies the filename for the XML output file. Using this option
automatically sets :vlopt:`--xml-only`.
.. note::
This feature is deprecated in favor of :vlopt:`--json-only`.
.. option:: -y <dir>
Add the directory to the list of directories that should be searched to find
+2 -2
View File
@@ -37,9 +37,9 @@ verilator_coverage Example Usage
verilator_coverage --annotate <obj>
verilator_coverage -write merged.dat -read <datafiles>...
verilator_coverage -write merged.dat <datafiles>...
verilator_coverage -write-info merged.info -read <datafiles>...
verilator_coverage -write-info merged.info <datafiles>...
verilator_coverage Arguments
+23 -3
View File
@@ -36,8 +36,7 @@ or "`ifdef`"'s may break other tools.
.. option:: """ [string] """
A triple-quoted block specifies a string that may include newlines and
single quotes. This extension is experimental and may be removed
without deprecation.
single quotes. This extension was standardized in IEEE 1800-2023.
.. option:: $c([string], ...);
@@ -577,6 +576,10 @@ or "`ifdef`"'s may break other tools.
.. option:: /*verilator&32;trace_init_task*/
Removed.
In versions before 5.024:
Attached to a DPI import to indicate that function should be called when
initializing tracing. This attribute is indented only to be used
internally in code that Verilator generates when :vlopt:`--lib-create`
@@ -594,6 +597,23 @@ or "`ifdef`"'s may break other tools.
Re-enable waveform tracing for all future signals or instances that are
declared.
.. option:: /*verilator&32;unroll_disable*/
Used in a statement position to indicate the immediately following loop
at the same statement level should not be unrolled by Verilator,
ignoring :vlopt:`--unroll-count`. This is similar to clang's ``#pragma
clang loop unroll(disable)``.
This option does not currently disable the C++ compiler's unrolling (or
not) of any loops that make it through to the Verilated C++ code.
.. option:: /*verilator&32;unroll_full*/
Rarely needed. Used in a statement position to indicate the immediately
following loop at the same statement level should always be fully
unrolled by Verilator, ignoring :vlopt:`--unroll-count`. This is
similar to clang's ``#pragma clang loop unroll(full)``.
.. option:: $stacktrace
Called as a task, print a stack trace. Called as a function, return a
@@ -602,4 +622,4 @@ or "`ifdef`"'s may break other tools.
symbols. Also, the data represents the C++ stack; the SystemVerilog
functions/tasks involved may be renamed and/or inlined before becoming
the C++ functions that may be visible in the stack trace. This
extension is experimental and may be removed without deprecation.
extension was standardized in IEEE 1800-2023.
+15 -10
View File
@@ -128,10 +128,13 @@ How do I generate waveforms (traces) in C++?
See also the next question for tracing in SystemC mode.
A. Pass the :vlopt:`--trace` option to Verilator, and in your top-level C
code, call ``Verilated::traceEverOn(true)``. Then you may use
``$dumpfile`` and ``$dumpvars`` to enable traces, the same as with any
Verilog simulator. See ``examples/make_tracing_c`` in the distribution.
A. Pass the :vlopt:`--trace` option to Verilator. Then you may use ``$dumpfile`` and
``$dumpvars`` to enable traces, the same as with any Verilog simulator,
although Verilator ignores the arguments to ``$dumpvars``. See
``examples/make_tracing_c`` in the distribution.
If writing the top-level C code, call ``Verilated::traceEverOn(true)``;
this is done for you if using :vlopt:`--binary`.
B. Or, for finer-grained control, or C++ files with multiple Verilated
modules, you may also create the trace purely from C++. Create a
@@ -226,12 +229,14 @@ How do I generate FST waveforms (traces) in C++ or SystemC?
FST is a trace file format developed by GTKWave. Verilator provides basic
FST support. To dump traces in FST format, add the :vlopt:`--trace-fst`
option to Verilator and either A. use :code:`$dumpfile & $dumpvars` in
Verilog as described in the VCD example above,
option to Verilator and either:
Use :code:`$dumpfile & $dumpvars` in Verilog as described in the VCD
example above,
Or, in C++ change the include described in the VCD example above:
.. code-block:: C++
.. code-block:: C++
#include "verilated_fst_c.h"
VerilatedFstC* tfp = new VerilatedFstC;
@@ -239,14 +244,14 @@ Or, in C++ change the include described in the VCD example above:
Or, in SystemC, change the include described in the VCD example above:
.. code-block:: C++
.. code-block:: C++
#include "verilated_fst_sc.h"
VerilatedFstC* tfp = new VerilatedFstSc;
Currently, supporting FST and VCD in a single simulation is impossible, but
such requirement should be rare. You can however ifdef around the trace
Currently, supporting FST and VCD in a single simulation is not supported,
but such usage should be unlikely. You can however ifdef around the trace
format in your C++ main loop, and select VCD or FST at compile time.
+4
View File
@@ -112,6 +112,10 @@ In specific debug and other modes, it also creates:
* - *{prefix}*\ .xml
- XML tree information (from --xml)
* - *{prefix}*\ .tree.json
- JSON tree information (from --json-only)
* - *{prefix}*\ .tree.meta.json
- JSON tree metadata (from --json-only)
* - *{prefix}*\ __cdc.txt
- Clock Domain Crossing checks (from --cdc)
* - *{prefix}*\ __stats.txt
+17 -4
View File
@@ -126,8 +126,9 @@ Those developing Verilator itself may also want these (see internals.rst):
::
sudo apt-get install clang clang-format-14 cmake gdb gprof graphviz lcov
sudo apt-get install libclang-dev yapf3 bear
sudo pip3 install clang sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe ruff
sudo apt-get install python3-clang yapf3 bear jq
sudo pip3 install sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe ruff
sudo pip3 install git+https://github.com/antmicro/astsee.git
cpan install Pod::Perldoc
cpan install Parallel::Forker
@@ -151,6 +152,17 @@ To make use of Verilator FST tracing you will want `GTKwave
required at Verilator build time.
Install Z3
^^^^^^^^^^
In order to use constrained randomization the `Z3 Theorem Prover
<https://github.com/z3prover/z3#readme>`__ must be installed, however this is
not required at Verilator build time. There are other compatible SMT solvers,
like CVC5/CVC4, but they are not guaranteed to work. Since different solvers are
faster for different scenarios, the solver to use at run-time can be specified
by the environment variable :option:`VERILATOR_SOLVER`.
.. _Obtain Sources:
Obtain Sources
@@ -192,8 +204,9 @@ Eventual Installation Options
Before configuring the build, you must decide how you're going to
eventually install Verilator onto your system. Verilator will be compiling
the current value of the environment variables :option:`VERILATOR_ROOT`,
:option:`SYSTEMC_INCLUDE`, and :option:`SYSTEMC_LIBDIR` as defaults into
the executable, so they must be correct before configuring.
:option:`VERILATOR_SOLVER`, :option:`SYSTEMC_INCLUDE`, and
:option:`SYSTEMC_LIBDIR` as defaults into the executable, so they must be
correct before configuring.
These are the installation options:
+12 -1
View File
@@ -62,12 +62,23 @@ Verilator supports the 2017 "for" loop constructs and several cleanups IEEE
made in 1800-2017.
SystemVerilog 2023 (IEEE 1800-2023) Support
-------------------------------------------
Verilator supports some of the 2023 improvements, including triple-quoted
string blocks that may include newlines and single quotes.
Verilator implements a full IEEE 1800-2023 compliant preprocessor,
including triple-quoted strings, and \`ifdef expressions.
Verilog AMS Support
-------------------
Verilator implements a very small subset of Verilog AMS (Verilog Analog and
Mixed-Signal Extensions) with the subset corresponding to those VMS
keywords with near-equivalents in Verilog 2005 or SystemVerilog 2017.
keywords with near-equivalents in Verilog IEEE 1364 or SystemVerilog
IEEE 1800.
AMS parsing is enabled with :vlopt:`--language VAMS <--language>` or
:vlopt:`--language 1800+VAMS <--language>`.
+5 -5
View File
@@ -23,12 +23,12 @@ resulting model's C++ or SystemC code is output as .cpp and .h files. This
is referred to as "Verilating", and the process is "to Verilate"; the
output is a "Verilated" model.
2. For simulation, a small-user written C++ wrapper file is required, the
2. For simulation, a small user-written C++ wrapper file is required, the
"wrapper". This wrapper defines the C++ standard function "main()", which
instantiates the Verilated model as a C++/SystemC object.
3. The user C++ wrapper, the files created by Verilator, a "runtime
library" provided by Verilator, and, if applicable SystemC libraries are
library" provided by Verilator, and, if applicable, SystemC libraries are
then compiled using a C++ compiler to create a simulation executable.
4. The resulting executable will perform the actual simulation during
@@ -50,6 +50,6 @@ The best place to get started is to try the :ref:`Examples`.
.. [#] SystemVerilog is defined by the `Institute of Electrical and
Electronics Engineers (IEEE) Standard for SystemVerilog - Unified
Hardware Design, Specification, and Verification Language`, Standard
1800, released in 2005, 2009, 2012, and 2017. The Verilator
documentation uses the shorthand e.g., "IEEE 1800-2017", to refer to
the, e.g., 2017 version of this standard.
1800, released in 2005, 2009, 2012, 2017, and 2023. The Verilator
documentation uses the shorthand e.g., "IEEE 1800-2023", to refer to
the, e.g., 2023 version of this standard.
+101 -20
View File
@@ -12,6 +12,60 @@ Verilated model's executable. For the runtime arguments to a simulated
model, see :ref:`Simulation Runtime Arguments`.
.. _Simulation Summary Report:
Simulation Summary Report
=========================
When simulation finishes, it will print a report to stdout summarizing the
simulation. This requires the model being Verilated with :vlopt:`--main`.
The report may be disabled with :vlopt:`+verilator+quiet`.
For example:
.. code-block::
- S i m u l a t i o n R e p o r t: Verilator ...
- Verilator: End at simtime 123 ns; walltime 1234.001 s; speed 123 ns/s
- Verilator: cpu 22.001 s on 4 threads; alloced 123 MB
The information in this report is:
.. describe:: "Verilator ..."
Program version.
.. describe:: "End at simtime 123 ns"
Verilog $time at which the model finished or stopped.
.. describe:: "walltime 1234.001 s"
Real elapsed wall time in seconds.
.. describe:: "speed 123.1 ns/s"
Simulated time (if non-zero) divided by wall time. e.g. `123 ns/s` means
123 simulated nanoseconds took 1 second of wall time; for a model with
only a 1 GHz clock that would be equivalent to 123.1 cycles per
second. The units are automatically selected to give a number between 1
and 1000. The wall time includes initialization, initial and final
process blocks, so indicates a slower speed than if the model had a
longer runtime.
.. describe:: "cpu 22 s"
CPU time used total across all CPU threads in seconds.
.. describe:: "4 threads"
Number of simultaneous threads used.
.. describe:: "alloced 123 MB"
Total memory used during simulation in megabytes.
.. _Benchmarking & Optimization:
Benchmarking & Optimization
@@ -230,14 +284,20 @@ Coverage Collection
When any coverage flag is used to Verilate, Verilator will add appropriate
coverage point insertions into the model and collect the coverage data.
To get the coverage data from the model, in the user wrapper code,
typically at the end once a test passes, call
:code:`Verilated::threadContextp()->coveragep()->write` with an argument of the filename for
the coverage data file to write coverage data to (typically
"logs/coverage.dat").
To get the coverage data from the model, write the coverage with either:
1. Using :vlopt:`--binary` or :vlopt:`--main`, and Verilator will dump
coverage when the test completes to the filename specified with
:vlopt:`+verilator+coverage+file+\<filename\>`.
2. In the user wrapper code, typically at the end once a test passes, call
:code:`Verilated::threadContextp()->coveragep()->write` with an argument
of the filename for the coverage data file to write coverage data to
(typically "logs/coverage.dat").
Run each of your tests in different directories, potentially in parallel.
Each test will create a :file:`logs/coverage.dat` file.
Each test will create the file specified above,
e.g. :file:`logs/coverage.dat`.
After running all of the tests, execute the :command:`verilator_coverage`
command, passing arguments pointing to the filenames of all the
@@ -273,13 +333,17 @@ profiled C++ code functions.
To use profiling:
#. Use Verilator's :vlopt:`--prof-cfuncs`.
#. Make sure the Verilog code will call `$finish` at the end of simulation
(otherwise the C library may not correctly create the `gmon.out` file in
the later steps below).
#. Run Verilator, adding the :vlopt:`--prof-cfuncs` option.
#. Build and run the simulation model.
#. The model will create gmon.out.
#. Run :command:`gprof` to see where in the C++ code the time is spent.
#. Run the gprof output through the :command:`verilator_profcfunc` program,
and it will tell you what Verilog line numbers on which most of the time
is being spent.
#. The model will create `gmon.out`.
#. Run :command:`gprof gmon.out > gprof.log` to see where in the C++ code
the time is spent.
#. Run :command:`verilator_profcfunc gprof.log > profcfunc.log` to take the
gprof output and translate into output showing the Verilog line numbers
on which most of the time is being spent.
.. _Execution Profiling:
@@ -505,13 +569,30 @@ documentation.
Runtime Debugging
=================
To debug a Verilated executable, use the standard GNU debugger ``gdb`` or a
similar tool. Typically you will want to have debugger symbols inserted by
the compiler, assertions enabled in the C library, and assertions enabled
in the Verilated library. (These options slow down the executable, so do
this only when debugging.) To enable this, Verilate with:
To debug a Verilated executable, Verilate with :vlopt:`--runtime-debug`.
This will instruct the compiler to insert debugger, and enable various
library assertions. These options slow down the executable, so do this
only when debugging.
-CFLAGS -ggdb -LDFLAGS -ggdb -CFLAGS -DVL_DEBUG=1 -CFLAGS -D_GLIBCXX_DEBUG
If you are using your own Makefiles, adapt appropriately to pass the
options documented under :vlopt:`--runtime-debug` to the compiler and
linker.
The :vlopt:`-CFLAGS` and/or :vlopt:`-LDFLAGS` options pass arguments
directly to the compiler or linker.
Once you have a debugging-enabled executable, run it using the the standard
GNU debugger ``gdb`` or a similar tool, and create a backtrace; e.g.:
.. code-block:: bash
gdb obj_dir/Vtop
run {Vtop_command_arguments}
{Vtop prints output, perhaps a segmentation faults}
bt
Rarely the bug may disappear with :vlopt:`--runtime-debug`; if so, try
instead using the sub-options that :vlopt:`--runtime-debug` documents, to
find the maximum subset that still shows the issue. E.g. it is likely that
using `-CFLAGS -D_GLIBCXX_DEBUG` will not hide any bug, so may be used.
Using :vlopt:`--runtime-debug` or `-CFLAGS -DVL_DEBUG=1` will only print a
message if something goes wrong. To enable debug print messages at
runtime, additionally use the :vlopt:`+verilator+debug` runtime option.
+75
View File
@@ -498,3 +498,78 @@ The search paths can be configured by setting some variables:
Sets the installation prefix of an installed SystemC library. (Same as
SYSTEMC_ROOT).
.. _Verilation Summary Report:
Verilation Summary Report
=========================
When Verilator generates code, unless :vlopt:`--quiet-stats` is used, it
will print a report to stdout summarizing the build. For example:
.. code-block::
- V e r i l a t i o n R e p o r t: Verilator ....
- Verilator: Built from 354 MB sources in 247 modules,
into 74 MB in 89 C++ files needing 0.192 MB
- Verilator: Walltime 26.580 s (elab=2.096, cvt=18.268,
bld=2.100); cpu 26.548 s on 1 threads; alloced 2894.672 MB
The information in this report is:
.. describe:: "Verilator ..."
Program version.
.. describe:: "234 MB sources"
Characters of post-preprocessed text in all input
Verilog and Verilator Control files in megabytes.
.. describe:: "247 modules"
Number of interfaces/modules/classes/packages in design before
elaboration.
.. describe:: "into 74 MB"
Characters of output C++ code, including comments in megabytes.
.. describe:: "89 C++ files"
Number of .cpp files created.
.. describe:: "needing 192MB"
Verilation-time minimum-bound estimate of memory needed to run model in
megabytes. (Expect to need significantly more.)
.. describe:: "Walltime 26.580 s"
Real elapsed wall time for Verilation and build.
.. describe:: "elab=2.096"
Wall time to read in files and complete elaboration.
.. describe:: "cvt=18.268"
Wall time for Verilator to process and write output.
.. describe:: "bld=2.1"
Wall time to compile gcc/clang (if using :vlopt:`--build`).
.. describe:: "cpu 22.548 s"
CPU time used, total across all CPU threads.
.. describe:: "4 threads"
Number of simultaneous threads used.
.. describe:: "alloced 123 MB"
Total memory used during build by Verilator executable (excludes
:vlopt:`--build` compiler's usage) in megabytes.
+110 -21
View File
@@ -161,8 +161,8 @@ List Of Warnings
.. option:: BADSTDPRAGMA
An error that a pragma is badly formed, for pragmas defined by IEEE
1800-2017. For example, an empty pragma line, or an incorrectly used
'pragma protect'. Third-party pragmas not defined by IEEE 1800-2017 are
1800-2023. For example, an empty pragma line, or an incorrectly used
'pragma protect'. Third-party pragmas not defined by IEEE 1800-2023 are
ignored.
@@ -210,22 +210,35 @@ List Of Warnings
.. option:: BLKLOOPINIT
.. TODO better example
This indicates that the initialization of an array needs to use
non-delayed assignments. This is done in the interest of speed; if
delayed assignments were used, the simulator would have to copy large
arrays every cycle. (In smaller loops, loop unrolling allows the
delayed assignment to work, though it's a bit slower than a non-delayed
assignment.) Here's an example
Indicates certain constructs where non-blocking assignments to unpacked
arrays (memories) are not supported inside loops. These typically appear in
initialization/reset code:
.. code-block:: sv
always @(posedge clk)
if (~reset_l)
for (i=0; i<`ARRAY_SIZE; i++)
array[i] = 0; // Non-delayed for verilator
array[i] <= 0; // Non-blocking assignment inside loop
else
array[address] <= data;
While this is supported in typical synthesizeable code (including the
example above), some complicated cases are not supported. Namely:
1. If the above loop is inside a suspendable process or fork statement.
2. If the variable is also the target of a '<=' non-blocking assignment
in a suspendable process or fork statement (in addition to a synthesizable
loop).
3. If the element type of the array is a compound type.
4. In versions before 5.026, any delayed assignment to an array.
It might slightly improve run-time performance if you change the
non-blocking assignment inside the loop into a blocking assignment
(that is: use '=' instead of '<='), if possible.
This message is only seen on large or complicated loops because
Verilator generally unrolls small loops. You may want to try increasing
@@ -283,7 +296,7 @@ List Of Warnings
Unique case statements that select on an enumerated variable, where all
of the enumerated values are covered by case items, are considered
complete even if the case statement does not cover illegal
non-enumerated values (IEEE 1800-2017 12.5.3). To check that illegal
non-enumerated values (IEEE 1800-2023 12.5.3). To check that illegal
values are not hit, use :vlopt:`--assert`.
Ignoring this warning will only suppress the lint check; it will
@@ -479,7 +492,7 @@ List Of Warnings
.. code-block::
%Warning-DEFPARAM: example.v:5:15: defparam is deprecated (IEEE 1800-2017 C.4.1)
%Warning-DEFPARAM: example.v:5:15: defparam is deprecated (IEEE 1800-2023 C.4.1)
: ... Suggest use instantiation with #(.MY_PARAM(...etc...))
To repair use :code:`#(.PARAMETER(...))` syntax. Repaired Example:
@@ -707,7 +720,7 @@ List Of Warnings
.. code-block::
%Warning-GENUNNAMED: example.v:2:9: Unnamed generate block (IEEE 1800-2017 27.6)
%Warning-GENUNNAMED: example.v:2:9: Unnamed generate block (IEEE 1800-2023 27.6)
To fix this assign a label (often with the naming convention prefix of
:code:`gen_` or :code:`g_`), for example:
@@ -763,7 +776,7 @@ List Of Warnings
.. code-block::
%Warning-IGNOREDRETURN: example.v:5:9: Ignoring return value of non-void function (IEEE 1800-2017 13.4.1)
%Warning-IGNOREDRETURN: example.v:5:9: Ignoring return value of non-void function (IEEE 1800-2023 13.4.1)
The portable way to suppress this warning (in SystemVerilog) is to use a
void cast, for example:
@@ -1204,6 +1217,14 @@ List Of Warnings
:vlopt:`--no-timing` option.
.. option:: NONSTD
Warns when a non-standard language feature is used that has a standard
equivalent, which might behave differently in corner cases. For example
:code:`$psprintf` system function is replaced by its standard equivalent
:code:`$sformatf`.
.. option:: NULLPORT
Warns that a null port was detected in the module definition port
@@ -1328,10 +1349,35 @@ List Of Warnings
.. TODO better example
An error that a package/class appears to have been referenced that has not
yet been declared. According to IEEE 1800-2017 26.3, all packages must
yet been declared. According to IEEE 1800-2023 26.3, all packages must
be declared before being used.
.. option:: PREPROCZERO
Warns that a preprocessor \`ifdef/\`ifndef expression (added in IEEE
1800-2023) evaluates a define value which has a value of :code:`0`.
This will evaluate in the expression as :code:`1` because the define has
a definition, unlike in the C preprocessor, which evaluates using the
define's value (of :code:`1`).
Referring to a define with an empty value does not give this warning, as
in C, the preprocessor will give an error on a preprocessor expression
of a define that is empty.
.. code-block:: sv
:linenos:
:emphasize-lines: 2
`define ZERO 0
`ifdef (ZERO || ZERO) //<--- warning PREPROCZERO
`error This_will_error_which_might_be_not_the_intent
`endif
The portable way to suppress this warning is to use a define value other
than zero to when used in a preprocessor expression.
.. option:: PROCASSWIRE
.. TODO better example
@@ -1707,7 +1753,7 @@ List Of Warnings
.. code-block::
%Warning-TIMESCALEMOD: example.v:1:8: Timescale missing on this module as other modules have it (IEEE 1800-2017 3.14.2.3)
%Warning-TIMESCALEMOD: example.v:1:8: Timescale missing on this module as other modules have it (IEEE 1800-2023 3.14.2.3)
Recommend using :vlopt:`--timescale` argument, or in front of all
modules use:
@@ -1949,7 +1995,7 @@ List Of Warnings
.. option:: USERERROR
A SystemVerilog elaboration-time assertion error was executed.
IEEE 1800-2017 20.11 requires this error.
IEEE 1800-2023 20.11 requires this error.
Faulty example:
@@ -1965,7 +2011,7 @@ List Of Warnings
.. option:: USERFATAL
A SystemVerilog elaboration-time assertion fatal was executed.
IEEE 1800-2017 20.11 requires this error.
IEEE 1800-2023 20.11 requires this error.
Faulty example:
@@ -1981,7 +2027,7 @@ List Of Warnings
.. option:: USERINFO
A SystemVerilog elaboration-time assertion print was executed. This is
not an error or warning, and IEEE 1800-2017 20.11 requires this
not an error or warning, and IEEE 1800-2023 20.11 requires this
behavior.
Example:
@@ -1996,7 +2042,7 @@ List Of Warnings
.. option:: USERWARN
A SystemVerilog elaboration-time assertion warning was executed.
IEEE 1800-2017 20.11 requires this warning.
IEEE 1800-2023 20.11 requires this warning.
Faulty example:
@@ -2131,3 +2177,46 @@ List Of Warnings
Inactive region. Such processes do get resumed in the same time slot
somewhere in the Active region. Issued only if Verilator is run with the
:vlopt:`--timing` option.
.. option:: ZEROREPL
Warns that zero is used as the replication value in the replication
operator. This is specified as an error by IEEE 1800-2023 11.4.12.1.
Faulty example:
.. code-block:: sv
:linenos:
:emphasize-lines: 5
module dut
#(parameter int MY_PARAM = 0);
reg [7:0] data;
always @* begin
data = {MY_PARAM{1'b1}}; //<--- WARNING
end
endmodule
Results in the following error:
.. code-block::
%Error-ZEROREPL: test.v:5:22: Replication value of 0 is only legal under a concatenation (IEEE 1800-2023 11.4.12.1)
Note that in some cases, this warning may be false, when a condition
upstream or downstream of the access means the zero replication will
never execute or be used.
Repaired example:
.. code-block:: sv
:linenos:
:emphasize-lines: 2
module dut
#(parameter int MY_PARAM = 1); //<--- REPAIRED
reg [7:0] data;
always @* begin
data = {MY_PARAM{1'b1}};
end
endmodule
+202 -11
View File
@@ -224,7 +224,7 @@ Scheduling
----------
Verilator implements the Active and NBA regions of the SystemVerilog scheduling
model as described in IEEE 1800-2017 chapter 4, and in particular sections
model as described in IEEE 1800-2023 chapter 4, and in particular sections
4.5 and Figure 4.1. The static (Verilation time) scheduling of SystemVerilog
processes is performed by code in the ``V3Sched`` namespace. The single
entry point to the scheduling algorithm is ``V3Sched::schedule``. Some
@@ -312,7 +312,7 @@ Scheduling of clocked and combinational logic
For performance, clocked and combinational logic needs to be ordered.
Conceptually this minimizes the iterations through the evaluation loop
presented in the reference algorithm in the SystemVerilog standard (IEEE
1800-2017 section 4.5), by evaluating logic constructs in data-flow order.
1800-2023 section 4.5), by evaluating logic constructs in data-flow order.
Without going into a lot of detail here, accept that well thought out ordering
is crucial to good simulation performance, and also enables further
optimizations later on.
@@ -407,7 +407,7 @@ triggered due to a combinational signal change from the previous evaluation
pass, and a combinational loop settling due to hybrid logic, if the clocked
logic reads the not yet settled combinationally driven signal. Such a race
is indeed possible, but our evaluation is consistent with the SystemVerilog
scheduling semantics (IEEE 1800-2017 chapter 4), and therefore any program
scheduling semantics (IEEE 1800-2023 chapter 4), and therefore any program
that exhibits such a race has non-deterministic behavior according to the
SystemVerilog semantics, so we accept this.
@@ -1031,6 +1031,91 @@ the evaluation process records a bitmask of variables that might have
changed; if clear, checking those signals for changes may be skipped.
Constrained randomization
-------------------------
Because general constrained randomization is a co-NP-hard problem, not all
cases are implemented in Verilator, and an external specialized SMT solver is
used for any non-obvious ones.
The ``randomize()`` method spawns an SMT solver in a sub-process. Then the
solver gets a setup query, then the definition of variables, then all the
constraints (SMT assertions) about the variables. Since the solver has no
information about the class' PRNG state, if the problem is satisfiable,
the solution space is further constrained by adding extra random constraints,
and querying the values satisfying the problem statement.
The constraint is currently constructed as fixing a simple xor of randomly
chosen bits of the variables being randomized.
The runtime classes used for handling the randomization are defined in
``verilated_random.h`` and ``verilated_random.cpp``.
``VlSubprocess``
~~~~~~~~~~~~~~~~
Subprocess handle, responsible for keeping track of the resources like child
PID, read and write file descriptors, and presenting them as a C++ iostream.
``VlRandomizer``
~~~~~~~~~~~~~~~~
Randomizer class, responsible for keeping track of variables and constraints,
and communicating with the solver subprocess.
The solver gets the constraints in `SMT-LIB2
<https://smtlib.cs.uiowa.edu/>`__ textual format in the following syntax:
::
(set-info :smt-lib-version 2.0)
(set-option :produce-models true)
(set-logic QF_BV)
(declare-fun v () (_ BitVec 16))
(declare-fun w () (_ BitVec 64))
(declare-fun x () (_ BitVec 48))
(declare-fun z () (_ BitVec 24))
(declare-fun t () (_ BitVec 23))
(assert (or (= v #x0003) (= v #x0008)))
(assert (= w #x0000000000000009))
(assert (or (or (= x #x000000000001) (= x #x000000000002)) (or (= x #x000000000004) (= x #x000000000009))))
(assert (bvult ((_ zero_extend 8) z) #x00000015))
(assert (bvugt ((_ zero_extend 8) z) #x0000000d))
(check-sat)
The solver responds with either ``sat`` or ``unsat``. Then the initial solution
is queried with:
::
(get-value (v w x z t ))
The solver then responds with e.g.:
::
((v #x0008)
(w #x0000000000000005)
(x #x000000000002)
(z #x000010)
(t #b00000000000000000000000))
And then a follow-up query (or a series thereof) is asked, and the solver gets
reset, so that it can be reused by subsequent randomization attempts:
::
(assert (= (bvxor (bvxor <...> (bvxor ((_ extract 21 21) z) ((_ extract 39 39) x)) ((_ extract 5 5) w)) <...> ((_ extract 10 10) w)) #b0))
(check-sat)
(get-value)
...
(reset)
Coding Conventions
==================
@@ -1696,6 +1781,84 @@ Similarly, the ``NETLIST`` has a list of modules referred to by its
``op1p()`` pointer.
.tree.json Output
-----------------
``.tree.json``` is an alternative dump format to ``.tree`` that is meant for
programmatic processing (e.g. with `astsee <https://github.com/antmicro/astsee>`_).
To enable this dump format, use :vlopt:`--dump-tree-json` or :vlopt:`--json-only`.
Structure:
::
{
/* Attributes that are common to all types of nodes */
"type": "VAR",
"name": "cyc",
/* By default addresses and filenames use short/stable ids rather than real value */
"addr": "(H)",
"loc": "a,25:12,26:15", /* "fileid,firstLine:firstCol,lastLine:endCol" (endCol is right exclusive) */
"editNum": 602,
/* Fields that are specific to AstVar nodes: */
"origName": "cyc",
"isSc": false,
"ioDirection": "NONE",
"isConst": false,
"isPullup": false,
"isPulldown": false,
"isUsedClock": false,
"isSigPublic": false,
"isLatched": false,
"isUsedLoopIdx": false,
"noReset": false,
"attrIsolateAssign": false,
"attrFileDescr": false,
"isDpiOpenArray": false,
"isFuncReturn": false,
"isFuncLocal": false,
"attrClocker": "UNKNOWN",
"lifetime": "NONE",
"varType": "VAR",
/* Lists of child nodes (which use similar structure as their parent): */
"childDTypep": [ /* ... */ ],
"delayp": [ /* ... */ ],
"valuep": [ /* ... */ ],
"attrsp": [ /* ... */ ]
}
.tree.meta.json Output
----------------
.tree.meta.json contains metadata that is common across the whole AST tree
(in case of --dump-tree-json, multiple trees share one meta file).
Besides de-duplication of data shared between multiple stages, .meta.json enables offloading
unstable data (that can vary from machine-to-machine or run-to-run) from main .tree.json.
This offloading allows, for example, to use byte-to-byte comparisons of AST dumps in tests.
::
{"files": {
/* Map id to filename, and other metadata */
"d": {"filename":"/home/ant/tmp/verilator/include/verilated_std.sv", "realpath":"/home/ant/tmp/verilator/include/verilated_std.sv", "language":"1800-2023"},
"a": {"filename":"<built-in>", "realpath":"<built-in>", "language":"1800-2023"},
"b": {"filename":"<command-line>", "realpath":"<command-line>", "language":"1800-2023"},
"c": {"filename":"input.vc", "realpath":"/home/ant/tmp/verilator/test_regress/input.vc", "language":"1800-2023"},
"e": {"filename":"t/t_EXAMPLE.v", "realpath":"/home/ant/tmp/verilator/test_regress/t/t_EXAMPLE.v", "language":"1800-2023"}
},"pointers": {
/* Map id to real address */
"(AG)": "0x562997289180",
"(YF)": "0x5629971c50b0",
"(WF)": "0x5629971e7ae0",
/* ... /*
},"ptrFieldNames": [
/* List of fields that are used for storing pointers */
"aboveScopep",
"voidp",
"addr",
/* ... */
]}
.tree.dot Output
----------------
@@ -1768,6 +1931,20 @@ To print a node:
pnt nodep
# or: call dumpTreeGdb(nodep) # aliased to "pnt" in src/.gdbinit
``src/.gdbinit`` and ``src/.gdbinit.py`` define handy utilities for working with
JSON AST dumps. For example:
* ``jstash nodep`` - Perform a JSON AST dump and save it into GDB value history (e.g. ``$1``)
* ``jtree nodep`` - Perform a JSON AST dump and pretty print it using ``astsee_verilator``.
* ``jtree $1`` - Pretty print a dump that was previously saved by ``jstash``.
* ``jtree nodep -d '.file, .timeunit'`` - Perform a JSON AST dump, filter out some fields and pretty print it.
* ``jtree 0x55555613dca0`` - Pretty print using address literal (rather than actual pointer).
* ``jtree $1 nodep`` - Diff ``nodep`` against an older dump.
A detailed description of ``jstash`` and ``jtree`` can be displayed using ``gdb``'s ``help`` command.
These commands require `astsee <https://github.com/antmicro/astsee>`_ to be installed.
When GDB halts, it is useful to understand that the backtrace will commonly
show the iterator functions between each invocation of ``visit`` in the
backtrace. You will typically see a frame sequence something like:
@@ -1829,21 +2006,21 @@ Verilator ideally would support all of IEEE, and has the goal to get close
to full support. However the following IEEE sections and features are not
anticipated to be ever implemented for the reasons indicated.
IEEE 1800-2017 3.3 modules within modules
IEEE 1800-2023 3.3 modules within modules
Little/no tool support, and arguably not a good practice.
IEEE 1800-2017 6.12 "shortreal"
IEEE 1800-2023 6.12 "shortreal"
Little/no tool support, and easily promoted to real.
IEEE 1800-2017 11.11 Min, typ, max
IEEE 1800-2023 11.11 Min, typ, max
No SDF support, so will always use typical.
IEEE 1800-2017 20.16 Stochastic analysis
IEEE 1800-2023 20.16 Stochastic analysis
Little industry use.
IEEE 1800-2017 20.17 PLA modeling
IEEE 1800-2023 20.17 PLA modeling
Little industry use and outdated technology.
IEEE 1800-2017 31 Timing checks
IEEE 1800-2023 31 Timing checks
No longer relevant with static timing analysis tools.
IEEE 1800-2017 32 SDF annotation
IEEE 1800-2023 32 SDF annotation
No longer relevant with static timing analysis tools.
IEEE 1800-2017 33 Config
IEEE 1800-2023 33 Config
Little industry use.
@@ -1884,6 +2061,10 @@ driver.pl Non-Scenario Arguments
files with dumping level 3, which dumps the standard critical stages.
For details on the format see `.tree Output`.
--fail-max <numtests>
Set the number of failing tests, after which the driver will stop running
additional tests. Defaults to 20, 0 disables.
--gdb
Same as ``verilator --gdb``: Run Verilator under the debugger.
@@ -1937,6 +2118,9 @@ driver.pl Non-Scenario Arguments
--trace
Set the simulator specific flags to request waveform tracing.
--valgrind
Same as ``verilator --valgrind``: Run Verilator under `Valgrind <https://valgrind.org/>`_.
--verbose
Compile and run the test in verbose mode. This means ``TEST_VERBOSE``
will be defined for the test (Verilog and any C++/SystemC wrapper).
@@ -1980,6 +2164,9 @@ simultaneously.
--vltmt
Run Verilator tests in multithreaded mode.
--xrun
Run Cadence Xcelium simulator tests.
--xsim
Run Xilinx XSim simulator tests.
@@ -2023,6 +2210,10 @@ VERILATOR_ROOT
Standard path to Verilator distribution root; see primary Verilator
documentation.
VERILATOR_SOLVER
SMT solver command for constrained randomization; see primary Verilator
documentation.
VERILATOR_TESTS_SITE
Used with ``--site``, a colon-separated list of directories with tests to
be added to testlist.
+30
View File
@@ -40,6 +40,7 @@ Brej
Briquet
Brownlee
Buckenmaier
Burghoorn
Bybell
CLang
CMake
@@ -71,6 +72,7 @@ Deadman
Debacker
Deepa
Defparams
Delm
Denio
Deprecations
Deroo
@@ -130,6 +132,7 @@ Gernot
Gerst
Gielda
Gigerl
Gijs
Gileadi
Giri
Gisselquist
@@ -146,6 +149,7 @@ Grulfen
Gu
Gunter
Guo
Hameed
Hao
Haojin
Harboe
@@ -162,6 +166,7 @@ Homebrew
Hornung
Hossell
Hsu
Huggett
Hutt
Hyperthreading
Ibrahim
@@ -180,9 +185,11 @@ Jannis
Jasen
Jens
Jeras
Jiaxun
Jiuyang
Joannou
Joly
Josse
Jullien
Junji
Junyi
@@ -437,6 +444,7 @@ Verilog
Vighnesh
Viktor
Vilp
Vlip
Vm
Vukobratovic
Wai
@@ -460,6 +468,7 @@ Xiaoliang
Xiaoyi
Xuan
Xuanqi
Yao
Yazdanbakhsh
Yernagula
Yi
@@ -519,6 +528,7 @@ buildenv
bv
bvs
callValueCbs
callgrind
casex
casez
casted
@@ -583,6 +593,7 @@ der
dereference
desassign
destructor
desynchronization
detections
dev
devcontainer
@@ -613,6 +624,7 @@ dut
dx
dynarray
elab
eliasphanna
elike
elsif
endcase
@@ -635,6 +647,7 @@ envvar
eof
errae
erroring
esynr
et
eval
evals
@@ -666,6 +679,7 @@ foreach
fprintf
fprofile
fread
freloop
frewind
fs
fscanf
@@ -688,6 +702,7 @@ genvars
getenv
getline
ggdb
glibc
gmake
gmon
gotFinish
@@ -732,6 +747,7 @@ ish
isunbounded
isunknown
jobserver
json
jwoutersymatra
killua
lang
@@ -829,6 +845,7 @@ parallelized
param
parameterization
parameterized
parameterless
params
parens
pawel
@@ -872,6 +889,7 @@ profcfunc
profiler
prototyptes
ps
psprintf
pthread
ptr
pulldown
@@ -902,6 +920,7 @@ recrem
redeclaring
regs
reloop
replaceShiftOp
resetall
respecified
rodata
@@ -940,6 +959,7 @@ stdin
stdout
stime
stmts
str
strcasecmp
stringification
stringified
@@ -953,13 +973,18 @@ submakes
submodule
submodules
substring
suspendable
sv
svBitVal
svBitVecVal
svGet
svGetTime
svGetTimePrecision
svLogicVal
svdpi
svgGetTimeUnit
swrite
synthesizeable
sys
systemc
tenghtt
@@ -978,6 +1003,7 @@ toolchain
topcell
toplevel
toupper
traceCapable
traceEverOn
tran
treei
@@ -1014,8 +1040,10 @@ unsup
untyped
urandom
uselib
utimes
uwire
uwires
valgrind
vc
vcd
vcddiff
@@ -1040,6 +1068,7 @@ vluint
vpi
vpiConstType
vpiDefName
vpiInertialDelay
vpiInstance
vpiLeftRange
vpiModule
@@ -1047,6 +1076,7 @@ vpiSize
vpiSuppressVal
vpiTimeUnit
vpiType
vpiUndefined
vpm
vpp
warmup
+1
View File
@@ -30,6 +30,7 @@ endif()
# Create a new executable target that will contain all your sources
add_executable(example ../make_hello_c/sim_main.cpp)
target_compile_features(example PUBLIC cxx_std_14)
# Add the Verilated circuit to the target
verilate(example
+1 -1
View File
@@ -31,7 +31,7 @@ endif
ifeq ($(shell which cmake),)
TARGET := nocmake
else
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
CMAKE_VERSION := $(shell cmake --version | grep -o '[0-9][.0-9]\+')
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
+1
View File
@@ -37,6 +37,7 @@ find_package(SystemCLanguage QUIET)
# Create a new executable target that will contain all your sources
add_executable(example ../make_hello_sc/sc_main.cpp)
target_compile_features(example PUBLIC cxx_std_14)
set_property(
TARGET example
+1 -1
View File
@@ -31,7 +31,7 @@ endif
ifeq ($(shell which cmake),)
TARGET := nocmake
else
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
CMAKE_VERSION := $(shell cmake --version | grep -o '[0-9][.0-9]\+')
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
@@ -30,9 +30,12 @@ endif()
# Create the main executable target
add_executable(example ../make_protect_lib/sim_main.cpp)
target_compile_features(example PUBLIC cxx_std_14)
# Create a secret library
add_library(verilated_secret STATIC) # or SHARED for a shared library
target_compile_features(verilated_secret PUBLIC cxx_std_14)
target_link_libraries(example PRIVATE verilated_secret)
# To create both libraries on CMake >= 3.12 replace the above 2 lines with the following:
# add_library(verilated_secret OBJECT)
+1 -1
View File
@@ -31,7 +31,7 @@ endif
ifeq ($(shell which cmake),)
TARGET := nocmake
else
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
CMAKE_VERSION := $(shell cmake --version | grep -o '[0-9][.0-9]\+')
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
+1
View File
@@ -30,6 +30,7 @@ endif()
# Create a new executable target that will contain all your sources
add_executable(example ../make_tracing_c/sim_main.cpp)
target_compile_features(example PUBLIC cxx_std_14)
# Add the Verilated circuit to the target
verilate(example COVERAGE TRACE
+1 -1
View File
@@ -31,7 +31,7 @@ endif
ifeq ($(shell which cmake),)
TARGET := nocmake
else
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
CMAKE_VERSION := $(shell cmake --version | grep -o '[0-9][.0-9]\+')
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
+1
View File
@@ -38,6 +38,7 @@ find_package(SystemCLanguage QUIET)
# Create a new executable target that will contain all your sources
add_executable(example ../make_tracing_sc/sc_main.cpp)
target_compile_features(example PUBLIC cxx_std_14)
set_property(
TARGET example
+1 -1
View File
@@ -31,7 +31,7 @@ endif
ifeq ($(shell which cmake),)
TARGET := nocmake
else
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
CMAKE_VERSION := $(shell cmake --version | grep -o '[0-9][.0-9]\+')
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
@@ -1,15 +1,15 @@
#!/usr/bin/env python3
# -*- Python -*- See copyright, etc below
# pylint: disable=C0114,C0115,C0209,R0903
# pylint: disable=C0103,C0114,C0115,C0209,R0903
######################################################################
import argparse
import json
import os
import re
import subprocess
import tempfile
import xml.etree.ElementTree as ET
from shutil import copy2
from tempfile import NamedTemporaryFile
# from pprint import pprint, pformat
#######################################################################
@@ -25,29 +25,30 @@ class VlFileCopy:
self.debug = debug
with tempfile.NamedTemporaryFile() as xml_temp:
with NamedTemporaryFile() as tree_temp, NamedTemporaryFile(
) as meta_temp:
vargs = [
'--xml-output',
xml_temp.name,
'--json-only-output',
tree_temp.name,
'--json-only-meta-output',
meta_temp.name,
'--bbox-sys', # Parse some stuff can't translate
'--bbox-unsup',
'--prefix vlxml'
] # So we know name of .xml output
'--prefix vljson'
]
vargs += verilator_args
self.run_verilator(vargs)
self.tree = ET.parse(xml_temp.name)
self.tree = json.load(tree_temp)
self.meta = json.load(meta_temp)
os.makedirs(output_dir, 0o777, True)
# Find and copy the files
root = self.tree.getroot()
xfiles = root.find('files')
for xfile in xfiles.findall('file'):
filename = xfile.get('filename')
if not re.match('^<', filename): # e.g. <built-in>
for file_id in self.meta['files']:
path = self.meta['files'][file_id]['realpath']
if not re.match('^<', path): # e.g. <built-in>
if self.debug:
print("\tcp %s %s" % (filename, output_dir))
copy2(filename, output_dir)
print("\tcp %s %s" % (path, output_dir))
copy2(path, output_dir)
def run_verilator(self, vargs):
"""Run Verilator command, check errors"""
@@ -71,7 +72,7 @@ if __name__ == '__main__':
allow_abbrev=False,
formatter_class=argparse.RawTextHelpFormatter,
description=
"""Example of using Verilator XML output to copy a list of files to an
"""Example of using Verilator JSON output to copy a list of files to an
output directory (-odir, defaults to 'copied'), e.g. to easily create a
tarball of the design to pass to others.
@@ -4,10 +4,10 @@
######################################################################
import argparse
import json
import os
import subprocess
import tempfile
import xml.etree.ElementTree as ET
from tempfile import NamedTemporaryFile
# from pprint import pprint, pformat
#######################################################################
@@ -22,19 +22,23 @@ class VlHierGraph:
output_filename='graph.dot'): # output filename
self.debug = debug
self.next_vertex_number = 0
self.name_to_number = {}
self.addr_to_number = {}
with tempfile.NamedTemporaryFile() as xml_temp:
with NamedTemporaryFile() as tree_temp, NamedTemporaryFile(
) as meta_temp:
vargs = [
'--xml-output',
xml_temp.name,
'--json-only-output',
tree_temp.name,
'--json-only-meta-output',
meta_temp.name,
'--bbox-sys', # Parse some stuff can't translate
'--bbox-unsup',
'--prefix vlxml'
] # So we know name of .xml output
'--prefix vljson'
]
vargs += verilator_args
self.run_verilator(vargs)
self.tree = ET.parse(xml_temp.name)
self.tree = json.load(tree_temp)
self.meta = json.load(meta_temp)
with open(output_filename, "w", encoding="utf8") as fh:
# For more serious purposes, use the python graphviz package instead
@@ -46,31 +50,45 @@ class VlHierGraph:
)
fh.write(" edge [fontsize=6]")
# Find cells
root = self.tree.getroot()
netlist = root.find('netlist')
for module in netlist.findall('module'):
modules = self.flatten(self.tree, lambda n: n['type'] == "MODULE")
top_module = True
for mod in modules:
# origNames are before parameterization, name if after
mod_name = module.get('name')
mod_number = self.name_to_vertex_number(mod_name)
fh.write(" n%d [label=\"%s\"" % (mod_number, mod_name))
if module.get('topModule'):
mod_number = self.addr_to_vertex_number(mod['addr'])
fh.write(" n%d [label=\"%s\"" % (mod_number, mod['name']))
if top_module:
fh.write(" color=\"red\" rank=1")
top_module = False
fh.write("];\n")
for instance in module.findall('instance'):
inst_name = instance.get('name')
def_name = instance.get('defName')
def_number = self.name_to_vertex_number(def_name)
cells = self.flatten(mod, lambda n: n['type'] == "CELL")
for cell in cells:
def_number = self.addr_to_vertex_number(cell['modp'])
fh.write(" n%d->n%d [label=\"%s\"];\n" %
(mod_number, def_number, inst_name))
(mod_number, def_number, cell['name']))
fh.write("}\n")
def name_to_vertex_number(self, name):
if name not in self.name_to_number:
def flatten(self, node, accept_cb=lambda n: True):
"""Flatten tree to list using DFS.
accept_cb(node) should return True for nodes you want to save"""
arr = []
self.dfs(node, lambda n: accept_cb(n) and arr.append(n))
return arr
def dfs(self, node, node_cb):
"""Traverse given tree using DFS and apply node_cb(node) on each one"""
node_cb(node)
for _, v in node.items():
if isinstance(v, list): # childlist
for child in v:
self.dfs(child, node_cb)
def addr_to_vertex_number(self, name):
if name not in self.addr_to_number:
self.next_vertex_number += 1
self.name_to_number[name] = self.next_vertex_number
return self.name_to_number[name]
self.addr_to_number[name] = self.next_vertex_number
return self.addr_to_number[name]
def run_verilator(self, vargs):
"""Run Verilator command, check errors"""
@@ -94,7 +112,7 @@ if __name__ == '__main__':
allow_abbrev=False,
formatter_class=argparse.RawTextHelpFormatter,
description=
"""Example of using Verilator XML output to create a .dot file showing the
"""Example of using Verilator JSON output to create a .dot file showing the
design module hierarchy.
Example usage:
+2 -2
View File
@@ -19,14 +19,14 @@ int main(int argc, char** argv) {
// e.g. examples/c_tracing.
// Construct a VerilatedContext to hold simulation time, etc.
VerilatedContext* contextp = new VerilatedContext;
VerilatedContext* const contextp = new VerilatedContext;
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
// This needs to be called before you create any model
contextp->commandArgs(argc, argv);
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
Vtop* top = new Vtop{contextp};
Vtop* const top = new Vtop{contextp};
// Simulate until $finish
while (!contextp->gotFinish()) {
+1 -1
View File
@@ -25,7 +25,7 @@ int sc_main(int argc, char* argv[]) {
// e.g. examples/c_tracing.
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
Vtop* top = new Vtop{"top"};
Vtop* const top = new Vtop{"top"};
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
// This needs to be called before you create any model
+5 -10
View File
@@ -17,16 +17,17 @@
#endif
int main(int argc, char** argv) {
if (false && argc && argv) {}
(void)argc;
(void)argv;
// Construct context to hold simulation time, etc
VerilatedContext* contextp = new VerilatedContext;
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
contextp->debug(0);
contextp->randReset(2);
contextp->commandArgs(argc, argv);
// Construct the Verilated model, including the secret module
Vtop* top = new Vtop{contextp};
const std::unique_ptr<Vtop> top{new Vtop{contextp.get(), "TOP"}};
#if VM_TRACE
// When tracing, the contents of the secret module will not be seen
@@ -46,12 +47,12 @@ int main(int argc, char** argv) {
// Simulate until $finish
while (!contextp->gotFinish()) {
contextp->timeInc(1);
top->clk = ~top->clk & 0x1;
top->eval();
#if VM_TRACE
if (tfp) tfp->dump(contextp->time());
#endif
contextp->timeInc(1);
}
// Final model cleanup
@@ -65,12 +66,6 @@ int main(int argc, char** argv) {
}
#endif
// Destroy model
delete top;
top = nullptr;
delete contextp;
contextp = nullptr;
// Return good completion status
// Don't use exit() or destructor won't get called
return 0;
+3 -3
View File
@@ -20,9 +20,6 @@ double sc_time_stamp() { return 0; }
int main(int argc, char** argv) {
// This is a more complicated example, please also see the simpler examples/make_hello_c.
// Prevent unused variable warnings
if (false && argc && argv) {}
// Create logs/ directory in case we have traces to put under it
Verilated::mkdir("logs");
@@ -120,6 +117,9 @@ int main(int argc, char** argv) {
contextp->coveragep()->write("logs/coverage.dat");
#endif
// Final simulation summary
contextp->statsPrintSummary();
// Return good completion status
// Don't use exit() or destructor won't get called
return 0;
-3
View File
@@ -29,9 +29,6 @@ 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.
// Prevent unused variable warnings
if (false && argc && argv) {}
// Create logs/ directory in case we have traces to put under it
Verilated::mkdir("logs");
+188 -37
View File
@@ -34,7 +34,6 @@
* FST_DEBUG : not for production use, only enable for development
* FST_REMOVE_DUPLICATE_VC : glitch removal (has writer performance impact)
* HAVE_LIBPTHREAD -> FST_WRITER_PARALLEL : enables inclusion of parallel writer code
* FST_DO_MISALIGNED_OPS (defined automatically for x86 and some others) : CPU architecture can handle misaligned loads/stores
* _WAVE_HAVE_JUDY : use Judy arrays instead of Jenkins (undefine if LGPL is not acceptable)
*
*/
@@ -132,10 +131,6 @@ void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint3
#define FST_GZIO_LEN (32768)
#define FST_HDR_FOURPACK_DUO_SIZE (4*1024*1024)
#if defined(__i386__) || defined(__x86_64__) || defined(_AIX) || defined(__aarch64__)
#define FST_DO_MISALIGNED_OPS
#endif
#if defined(__APPLE__) && defined(__MACH__)
#define FST_MACOSX
#include <sys/sysctl.h>
@@ -192,6 +187,16 @@ void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint3
/* 01234567 */
/*
* report abort messages
*/
static void chk_report_abort(const char *s)
{
fprintf(stderr,"Triggered %s security check, exiting.\n", s);
abort();
}
/*
* prevent old file overwrite when currently being read
*/
@@ -342,8 +347,9 @@ return(NULL);
static void *fstMmap2(size_t __len, int __fd, fst_off_t __off)
{
DWORD64 len64 = __len; /* Must be 64-bit for shift below */
HANDLE handle = CreateFileMapping((HANDLE)_get_osfhandle(__fd), NULL,
PAGE_READWRITE, (DWORD)(__len >> 32),
PAGE_READWRITE, (DWORD)(len64 >> 32),
(DWORD)__len, NULL);
if (!handle) { return NULL; }
@@ -367,22 +373,15 @@ return ptr;
/*
* regular and variable-length integer access functions
*/
#ifdef FST_DO_MISALIGNED_OPS
#define fstGetUint32(x) (*(uint32_t *)(x))
#else
static uint32_t fstGetUint32(unsigned char *mem)
{
uint32_t u32;
unsigned char *buf = (unsigned char *)(&u32);
buf[0] = mem[0];
buf[1] = mem[1];
buf[2] = mem[2];
buf[3] = mem[3];
memcpy(buf, mem, sizeof(uint32_t));
return(*(uint32_t *)buf);
}
#endif
static int fstWriterUint64(FILE *handle, uint64_t v)
@@ -550,7 +549,8 @@ return(rc);
static uint32_t fstReaderVarint32(FILE *f)
{
unsigned char buf[5];
int chk_len = 5; /* TALOS-2023-1783 */
unsigned char buf[chk_len];
unsigned char *mem = buf;
uint32_t rc = 0;
int ch;
@@ -559,7 +559,9 @@ do
{
ch = fgetc(f);
*(mem++) = ch;
} while(ch & 0x80);
} while((ch & 0x80) && (--chk_len));
if(ch & 0x80) chk_report_abort("TALOS-2023-1783");
mem--;
for(;;)
@@ -579,7 +581,8 @@ return(rc);
static uint32_t fstReaderVarint32WithSkip(FILE *f, uint32_t *skiplen)
{
unsigned char buf[5];
int chk_len = 5; /* TALOS-2023-1783 */
unsigned char buf[chk_len];
unsigned char *mem = buf;
uint32_t rc = 0;
int ch;
@@ -588,7 +591,9 @@ do
{
ch = fgetc(f);
*(mem++) = ch;
} while(ch & 0x80);
} while((ch & 0x80) && (--chk_len));
if(ch & 0x80) chk_report_abort("TALOS-2023-1783");
*skiplen = mem - buf;
mem--;
@@ -609,7 +614,8 @@ return(rc);
static uint64_t fstReaderVarint64(FILE *f)
{
unsigned char buf[16];
int chk_len = 16; /* TALOS-2023-1783 */
unsigned char buf[chk_len];
unsigned char *mem = buf;
uint64_t rc = 0;
int ch;
@@ -618,9 +624,12 @@ do
{
ch = fgetc(f);
*(mem++) = ch;
} while(ch & 0x80);
} while((ch & 0x80) && (--chk_len));
if(ch & 0x80) chk_report_abort("TALOS-2023-1783");
mem--;
for(;;)
{
rc <<= 7;
@@ -851,11 +860,7 @@ unsigned char *pnt = buf;
uint32_t nxt;
uint32_t len;
#ifdef FST_DO_MISALIGNED_OPS
(*(uint32_t *)(pnt)) = (*(uint32_t *)(u));
#else
memcpy(pnt, u, sizeof(uint32_t));
#endif
pnt += 4;
while((nxt = v>>7))
@@ -878,11 +883,7 @@ unsigned char *pnt = buf;
uint32_t nxt;
uint32_t len;
#ifdef FST_DO_MISALIGNED_OPS
(*(uint32_t *)(pnt)) = (*(uint32_t *)(u));
#else
memcpy(pnt, u, sizeof(uint32_t));
#endif
pnt += 4;
while((nxt = v>>7))
@@ -1542,7 +1543,7 @@ for(i=0;i<xc->maxhandle;i++)
dmem = packmem = (unsigned char *)malloc(packmemlen = (wrlen * 2) + 2);
}
rc = (xc->fourpack) ? LZ4_compress((char *)scratchpnt, (char *)dmem, wrlen) : fastlz_compress(scratchpnt, wrlen, dmem);
rc = (xc->fourpack) ? LZ4_compress_default((char *)scratchpnt, (char *)dmem, wrlen, packmemlen) : fastlz_compress(scratchpnt, wrlen, dmem);
if(rc < destlen)
{
#ifndef FST_DYNAMIC_ALIAS_DISABLE
@@ -1646,7 +1647,11 @@ if(1)
{
if(vm4ip[2] != prev_alias)
{
fpos += fstWriterSVarint(f, (((int64_t)((int32_t)(prev_alias = vm4ip[2]))) << 1) | 1);
int32_t t_i32 = ((int32_t)(prev_alias = vm4ip[2])); /* vm4ip is generic unsigned data */
int64_t t_i64 = (int64_t)t_i32; /* convert to signed */
uint64_t t_u64 = (uint64_t)t_i64; /* sign extend through 64b */
fpos += fstWriterSVarint(f, (int64_t)((t_u64 << 1) | 1)); /* all in this block was: fpos += fstWriterSVarint(f, (((int64_t)((int32_t)(prev_alias = vm4ip[2]))) << 1) | 1); */
}
else
{
@@ -1838,6 +1843,14 @@ if(xc->parallel_enabled)
xc->xc_parent = xc;
memcpy(xc2, xc, sizeof(struct fstWriterContext));
if(sizeof(size_t) < sizeof(uint64_t))
{
/* TALOS-2023-1777 for 32b overflow */
uint64_t chk_64 = xc->maxhandle * 4 * sizeof(uint32_t);
size_t chk_32 = xc->maxhandle * 4 * sizeof(uint32_t);
if(chk_64 != chk_32) chk_report_abort("TALOS-2023-1777");
}
xc2->valpos_mem = (uint32_t *)malloc(xc->maxhandle * 4 * sizeof(uint32_t));
memcpy(xc2->valpos_mem, xc->valpos_mem, xc->maxhandle * 4 * sizeof(uint32_t));
@@ -2101,7 +2114,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
{
fstWriterMmapSanity(hmem = (unsigned char *)fstMmap(NULL, xc->hier_file_len, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->hier_handle), 0), __FILE__, __LINE__, "hmem");
}
packed_len = LZ4_compress((char *)hmem, (char *)mem, xc->hier_file_len);
packed_len = LZ4_compress_default((char *)hmem, (char *)mem, xc->hier_file_len, lz4_maxlen);
fstMunmap(hmem, xc->hier_file_len);
fourpack_duo = (!xc->repack_on_close) && (xc->hier_file_len > FST_HDR_FOURPACK_DUO_SIZE); /* double pack when hierarchy is large */
@@ -2114,7 +2127,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
lz4_maxlen_duo = LZ4_compressBound(packed_len);
mem_duo = (unsigned char *)malloc(lz4_maxlen_duo);
packed_len_duo = LZ4_compress((char *)mem, (char *)mem_duo, packed_len);
packed_len_duo = LZ4_compress_default((char *)mem, (char *)mem_duo, packed_len, lz4_maxlen_duo);
fstWriterVarint(xc->handle, packed_len); /* 1st round compressed length */
fstFwrite(mem_duo, packed_len_duo, 1, xc->handle);
@@ -3434,7 +3447,7 @@ return(rc);
#ifndef FST_WRITEX_DISABLE
static void fstWritex(struct fstReaderContext *xc, void *v, int len)
static void fstWritex(struct fstReaderContext *xc, void *v, uint32_t len) /* TALOS-2023-1793: change len to unsigned */
{
unsigned char *s = (unsigned char *)v;
@@ -5060,6 +5073,7 @@ if(fv)
for(;;)
{
uint32_t *tc_head = NULL;
uint32_t tc_head_items = 0;
traversal_mem_offs = 0;
fstReaderFseeko(xc, xc->f, blkpos, SEEK_SET);
@@ -5103,12 +5117,12 @@ for(;;)
}
mem_required_for_traversal = fstReaderUint64(xc->f);
mem_for_traversal = (unsigned char *)malloc(mem_required_for_traversal + 66); /* add in potential fastlz overhead */
mem_required_for_traversal = fstReaderUint64(xc->f) + 66; /* add in potential fastlz overhead */
mem_for_traversal = (unsigned char *)malloc(mem_required_for_traversal);
#ifdef FST_DEBUG
fprintf(stderr, FST_APIMESS "sec: %u seclen: %d begtim: %d endtim: %d\n",
secnum, (int)seclen, (int)beg_tim, (int)end_tim);
fprintf(stderr, FST_APIMESS "mem_required_for_traversal: %d\n", (int)mem_required_for_traversal);
fprintf(stderr, FST_APIMESS "mem_required_for_traversal: %d\n", (int)mem_required_for_traversal-66);
#endif
/* process time block */
{
@@ -5158,6 +5172,22 @@ for(;;)
}
free(time_table);
if(sizeof(size_t) < sizeof(uint64_t))
{
/* TALOS-2023-1792 for 32b overflow */
uint64_t chk_64 = tsec_nitems * sizeof(uint64_t);
size_t chk_32 = ((size_t)tsec_nitems) * sizeof(uint64_t);
if(chk_64 != chk_32) chk_report_abort("TALOS-2023-1792");
}
else
{
uint64_t chk_64 = tsec_nitems * sizeof(uint64_t);
if((chk_64/sizeof(uint64_t)) != tsec_nitems)
{
chk_report_abort("TALOS-2023-1792");
}
}
time_table = (uint64_t *)calloc(tsec_nitems, sizeof(uint64_t));
tpnt = ucdata;
tpval = 0;
@@ -5169,7 +5199,23 @@ for(;;)
tpnt += skiplen;
}
tc_head = (uint32_t *)calloc(tsec_nitems /* scan-build */ ? tsec_nitems : 1, sizeof(uint32_t));
tc_head_items = tsec_nitems /* scan-build */ ? tsec_nitems : 1;
if(sizeof(size_t) < sizeof(uint64_t))
{
/* TALOS-2023-1792 for 32b overflow */
uint64_t chk_64 = tc_head_items * sizeof(uint32_t);
size_t chk_32 = ((size_t)tc_head_items) * sizeof(uint32_t);
if(chk_64 != chk_32) chk_report_abort("TALOS-2023-1792");
}
else
{
uint64_t chk_64 = tc_head_items * sizeof(uint32_t);
if((chk_64/sizeof(uint32_t)) != tc_head_items)
{
chk_report_abort("TALOS-2023-1792");
}
}
tc_head = (uint32_t *)calloc(tc_head_items, sizeof(uint32_t));
free(ucdata);
}
@@ -5273,6 +5319,10 @@ for(;;)
{
if(value_change_callback)
{
if(xc->signal_lens[idx] > xc->longest_signal_value_len)
{
chk_report_abort("TALOS-2023-1797");
}
memcpy(xc->temp_signal_value_buf, mu+sig_offs, xc->signal_lens[idx]);
xc->temp_signal_value_buf[xc->signal_lens[idx]] = 0;
value_change_callback(user_callback_data_pointer, beg_tim, idx+1, xc->temp_signal_value_buf);
@@ -5286,6 +5336,10 @@ for(;;)
vcd_id[0] = (xc->signal_typs[idx] != FST_VT_VCD_PORT) ? 'b' : 'p';
fstWritex(xc, vcd_id, 1);
if((sig_offs + xc->signal_lens[idx]) > frame_uclen)
{
chk_report_abort("TALOS-2023-1793");
}
fstWritex(xc,mu+sig_offs, xc->signal_lens[idx]);
vcd_id[0] = ' '; /* collapse 3 writes into one I/O call */
@@ -5410,7 +5464,44 @@ for(;;)
free(chain_table_lengths);
vc_maxhandle_largest = vc_maxhandle;
if(!(vc_maxhandle+1))
{
chk_report_abort("TALOS-2023-1798");
}
if(sizeof(size_t) < sizeof(uint64_t))
{
/* TALOS-2023-1798 for 32b overflow */
uint64_t chk_64 = (vc_maxhandle+1) * sizeof(fst_off_t);
size_t chk_32 = ((size_t)(vc_maxhandle+1)) * sizeof(fst_off_t);
if(chk_64 != chk_32) chk_report_abort("TALOS-2023-1798");
}
else
{
uint64_t chk_64 = (vc_maxhandle+1) * sizeof(fst_off_t);
if((chk_64/sizeof(fst_off_t)) != (vc_maxhandle+1))
{
chk_report_abort("TALOS-2023-1798");
}
}
chain_table = (fst_off_t *)calloc((vc_maxhandle+1), sizeof(fst_off_t));
if(sizeof(size_t) < sizeof(uint64_t))
{
/* TALOS-2023-1798 for 32b overflow */
uint64_t chk_64 = (vc_maxhandle+1) * sizeof(uint32_t);
size_t chk_32 = ((size_t)(vc_maxhandle+1)) * sizeof(uint32_t);
if(chk_64 != chk_32) chk_report_abort("TALOS-2023-1798");
}
else
{
uint64_t chk_64 = (vc_maxhandle+1) * sizeof(uint32_t);
if((chk_64/sizeof(uint32_t)) != (vc_maxhandle+1))
{
chk_report_abort("TALOS-2023-1798");
}
}
chain_table_lengths = (uint32_t *)calloc((vc_maxhandle+1), sizeof(uint32_t));
}
@@ -5454,6 +5545,11 @@ for(;;)
uint64_t val = fstGetVarint32(pnt, &skiplen);
fstHandle loopcnt = val >> 1;
if((idx+loopcnt-1) > vc_maxhandle) /* TALOS-2023-1789 */
{
chk_report_abort("TALOS-2023-1789");
}
for(i=0;i<loopcnt;i++)
{
chain_table[idx++] = 0;
@@ -5487,6 +5583,12 @@ for(;;)
else
{
fstHandle loopcnt = val >> 1;
if((idx+loopcnt-1) > vc_maxhandle) /* TALOS-2023-1789 */
{
chk_report_abort("TALOS-2023-1789");
}
for(i=0;i<loopcnt;i++)
{
chain_table[idx++] = 0;
@@ -5547,6 +5649,11 @@ for(;;)
unsigned long destlen = val;
unsigned long sourcelen = chain_table_lengths[i];
if(traversal_mem_offs >= mem_required_for_traversal)
{
chk_report_abort("TALOS-2023-1785");
}
if(mc_mem_len < chain_table_lengths[i])
{
free(mc_mem);
@@ -5575,6 +5682,12 @@ for(;;)
{
int destlen = chain_table_lengths[i] - skiplen;
unsigned char *mu = mem_for_traversal + traversal_mem_offs;
if(traversal_mem_offs >= mem_required_for_traversal)
{
chk_report_abort("TALOS-2023-1785");
}
fstFread(mu, destlen, 1, xc->f);
/* data to process is for(j=0;j<destlen;j++) in mu[j] */
headptr[i] = traversal_mem_offs;
@@ -5600,6 +5713,11 @@ for(;;)
tdelta = vli >> 1;
}
if(tdelta >= tc_head_items)
{
chk_report_abort("TALOS-2023-1791");
}
scatterptr[i] = tc_head[tdelta];
tc_head[tdelta] = i+1;
}
@@ -5698,6 +5816,11 @@ for(;;)
shamt = 2 << (vli & 1);
tdelta = vli >> shamt;
if((tdelta+i) >= tc_head_items)
{
chk_report_abort("TALOS-2023-1791");
}
scatterptr[idx] = tc_head[i+tdelta];
tc_head[i+tdelta] = idx+1;
}
@@ -5731,6 +5854,14 @@ for(;;)
vcdid_len = fstVcdIDForFwrite(vcd_id+1, idx+1);
{
if(sizeof(size_t) < sizeof(uint64_t))
{
/* TALOS-2023-1790 for 32b overflow */
uint64_t chk_64 = len*4 + 1;
size_t chk_32 = len*4 + 1;
if(chk_64 != chk_32) chk_report_abort("TALOS-2023-1790");
}
unsigned char *vesc = (unsigned char *)malloc(len*4 + 1);
int vlen = fstUtilityBinToEsc(vesc, vdata, len);
fstWritex(xc, vesc, vlen);
@@ -5756,6 +5887,11 @@ for(;;)
vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[idx]);
tdelta = vli >> 1;
if((tdelta+i) >= tc_head_items)
{
chk_report_abort("TALOS-2023-1791");
}
scatterptr[idx] = tc_head[i+tdelta];
tc_head[i+tdelta] = idx+1;
}
@@ -5772,6 +5908,11 @@ for(;;)
if(xc->signal_typs[idx] != FST_VT_VCD_REAL)
{
if(len > xc->longest_signal_value_len)
{
chk_report_abort("TALOS-2023-1797");
}
if(!(vli & 1))
{
int byte = 0;
@@ -5817,8 +5958,13 @@ for(;;)
if(fv)
{
unsigned char ch_bp = (xc->signal_typs[idx] != FST_VT_VCD_PORT) ? 'b' : 'p';
uint64_t mem_required_for_traversal_chk = vdata - mem_for_traversal + len;
fstWritex(xc, &ch_bp, 1);
if(mem_required_for_traversal_chk > mem_required_for_traversal)
{
chk_report_abort("TALOS-2023-1793");
}
fstWritex(xc, vdata, len);
}
}
@@ -5941,6 +6087,11 @@ for(;;)
vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[idx]);
tdelta = vli >> 1;
if((tdelta+i) >= tc_head_items)
{
chk_report_abort("TALOS-2023-1791");
}
scatterptr[idx] = tc_head[i+tdelta];
tc_head[i+tdelta] = idx+1;
}
+2240 -972
View File
File diff suppressed because it is too large Load Diff
+771 -265
View File
File diff suppressed because it is too large Load Diff
+323 -143
View File
@@ -71,12 +71,23 @@
# include <execinfo.h>
# define _VL_HAVE_STACKTRACE
#endif
#if defined(__linux) || (defined(__APPLE__) && defined(__MACH__))
# include <sys/time.h>
# include <sys/resource.h>
# define _VL_HAVE_GETRLIMIT
#endif
#include "verilated_threads.h"
// clang-format on
#include "verilated_trace.h"
#ifdef VM_SOLVER_DEFAULT
#define VL_SOLVER_DEFAULT VM_SOLVER_DEFAULT
#else
#define VL_SOLVER_DEFAULT "z3 --in"
#endif
// Max characters in static char string for VL_VALUE_STRING
constexpr unsigned VL_VALUE_STRING_MAX_WIDTH = 8192;
@@ -107,7 +118,8 @@ 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) {} // Unused argument
// hier is unused in the default implementation.
(void)hier;
VL_PRINTF( // Not VL_PRINTF_MT, already on main thread
"- %s:%d: Verilog $finish\n", filename, linenum);
Verilated::threadContextp()->gotFinish(true);
@@ -135,7 +147,8 @@ void vl_stop(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE {
#ifndef VL_USER_FATAL ///< Define this to override the vl_fatal function
void vl_fatal(const char* filename, int linenum, const char* hier, const char* msg) VL_MT_UNSAFE {
if (false && hier) {}
// hier is unused in the default implementation.
(void)hier;
Verilated::threadContextp()->gotError(true);
Verilated::threadContextp()->gotFinish(true);
if (filename && filename[0]) {
@@ -162,9 +175,12 @@ void vl_stop_maybe(const char* filename, int linenum, const char* hier, bool may
Verilated::threadContextp()->errorCountInc();
if (maybe
&& Verilated::threadContextp()->errorCount() < Verilated::threadContextp()->errorLimit()) {
VL_PRINTF( // Not VL_PRINTF_MT, already on main thread
"-Info: %s:%d: %s\n", filename, linenum,
"Verilog $stop, ignored due to +verilator+error+limit");
// Do just once when cross error limit
if (Verilated::threadContextp()->errorCount() == 1) {
VL_PRINTF( // Not VL_PRINTF_MT, already on main thread
"-Info: %s:%d: %s\n", filename, linenum,
"Verilog $stop, ignored due to +verilator+error+limit");
}
} else {
vl_stop(filename, linenum, hier);
}
@@ -173,7 +189,8 @@ void vl_stop_maybe(const char* filename, int linenum, const char* hier, bool may
#ifndef VL_USER_WARN ///< Define this to override the vl_warn function
void vl_warn(const char* filename, int linenum, const char* hier, const char* msg) VL_MT_UNSAFE {
if (false && hier) {}
// hier is unused in the default implementation.
(void)hier;
if (filename && filename[0]) {
// Not VL_PRINTF_MT, already on main thread
VL_PRINTF("%%Warning: %s:%d: %s\n", filename, linenum, msg);
@@ -594,7 +611,7 @@ WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, const WDataInP
const int words = VL_WORDS_I(obits);
VL_ZERO_W(obits, owp);
EData lor = 0; // 0=all zeros, ~0=all ones, else mix
for (int i = 1; i < (words - 1); ++i) { lor |= lwp[i]; }
for (int i = 1; i < (words - 1); ++i) lor |= lwp[i];
lor |= ((lwp[words - 1] == VL_MASK_E(rbits)) ? ~VL_EUL(0) : 0);
if (lor == 0 && lwp[0] == 0) { // "X" so return 0
return owp;
@@ -783,7 +800,7 @@ std::string _vl_vsformat_time(char* tmp, T ld, int timeunit, bool left, size_t w
}
}
const int needmore = width - digits;
const int needmore = static_cast<int>(width) - digits;
std::string padding;
if (needmore > 0) padding.append(needmore, ' '); // Pad with spaces
return left ? (tmp + padding) : (padding + tmp);
@@ -792,7 +809,7 @@ std::string _vl_vsformat_time(char* tmp, T ld, int timeunit, bool left, size_t w
// Do a va_arg returning a quad, assuming input argument is anything less than wide
#define VL_VA_ARG_Q_(ap, bits) (((bits) <= VL_IDATASIZE) ? va_arg(ap, IData) : va_arg(ap, QData))
void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SAFE {
void _vl_vsformat(std::string& output, const std::string& format, va_list ap) VL_MT_SAFE {
// Format a Verilog $write style format into the output list
// The format must be pre-processed (and lower cased) by Verilator
// Arguments are in "width, arg-value (or WDataIn* if wide)" form
@@ -801,24 +818,24 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
// Note also assumes variables < 64 are not wide, this assumption is
// sometimes not true in low-level routines written here in verilated.cpp
static thread_local char t_tmp[VL_VALUE_STRING_MAX_WIDTH];
const char* pctp = nullptr; // Most recent %##.##g format
std::string::const_iterator pctit = format.end(); // Most recent %##.##g format
bool inPct = false;
bool widthSet = false;
bool left = false;
size_t width = 0;
for (const char* pos = formatp; *pos; ++pos) {
for (std::string::const_iterator pos = format.cbegin(); pos != format.cend(); ++pos) {
if (!inPct && pos[0] == '%') {
pctp = pos;
pctit = pos;
inPct = true;
widthSet = false;
width = 0;
} else if (!inPct) { // Normal text
// Fast-forward to next escape and add to output
const char* ep = pos;
while (ep[0] && ep[0] != '%') ++ep;
std::string::const_iterator ep = pos;
while (ep != format.end() && ep[0] != '%') ++ep;
if (ep != pos) {
output.append(pos, ep - pos);
pos += ep - pos - 1;
output.append(pos, ep);
pos = ep - 1;
}
} else { // Format character
inPct = false;
@@ -875,14 +892,13 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
case '^': { // Realtime
const int lbits = va_arg(ap, int);
const double d = va_arg(ap, double);
if (lbits) {} // UNUSED - always 64
(void)lbits; // UNUSED - always 64
if (fmt == '^') { // Realtime
if (!widthSet) width = Verilated::threadContextp()->impp()->timeFormatWidth();
const int timeunit = va_arg(ap, int);
output += _vl_vsformat_time(t_tmp, d, timeunit, left, width);
} else {
const size_t len = pos - pctp + 1;
const std::string fmts{pctp, len};
const std::string fmts{pctit, pos + 1};
VL_SNPRINTF(t_tmp, VL_VALUE_STRING_MAX_WIDTH, fmts.c_str(), d);
output += t_tmp;
}
@@ -936,20 +952,20 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
if (VL_SIGN_E(lbits, lwp[VL_WORDS_I(lbits) - 1])) {
VlWide<VL_VALUE_STRING_MAX_WIDTH / 4 + 2> neg;
VL_NEGATE_W(VL_WORDS_I(lbits), neg, lwp);
append = std::string{"-"} + VL_DECIMAL_NW(lbits, neg);
append = "-"s + VL_DECIMAL_NW(lbits, neg);
} else {
append = VL_DECIMAL_NW(lbits, lwp);
}
digits = append.length();
digits = static_cast<int>(append.length());
}
const int needmore = width - digits;
const int needmore = static_cast<int>(width) - digits;
if (needmore > 0) {
std::string padding;
if (left) {
padding.append(needmore, ' '); // Pre-pad spaces
output += append + padding;
} else {
if (pctp && pctp[0] && pctp[1] == '0') { // %0
if (pctit != format.end() && pctit[0] && pctit[1] == '0') { // %0
padding.append(needmore, '0'); // Pre-pad zero
} else {
padding.append(needmore, ' '); // Pre-pad spaces
@@ -969,16 +985,16 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
append = t_tmp;
} else {
append = VL_DECIMAL_NW(lbits, lwp);
digits = append.length();
digits = static_cast<int>(append.length());
}
const int needmore = width - digits;
const int needmore = static_cast<int>(width) - digits;
if (needmore > 0) {
std::string padding;
if (left) {
padding.append(needmore, ' '); // Pre-pad spaces
output += append + padding;
} else {
if (pctp && pctp[0] && pctp[1] == '0') { // %0
if (pctit != format.end() && pctit[0] && pctit[1] == '0') { // %0
padding.append(needmore, '0'); // Pre-pad zero
} else {
padding.append(needmore, ' '); // Pre-pad spaces
@@ -1037,7 +1053,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
}
} // switch
const int needmore = width - digits;
const int needmore = static_cast<int>(width) - digits;
if (needmore > 0) {
std::string padding;
if (left) {
@@ -1078,7 +1094,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
}
break;
default: { // LCOV_EXCL_START
const std::string msg = std::string{"Unknown _vl_vsformat code: "} + pos[0];
const std::string msg = "Unknown _vl_vsformat code: "s + pos[0];
VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str());
break;
} // LCOV_EXCL_STOP
@@ -1161,8 +1177,8 @@ static char* _vl_vsss_read_bin(FILE* fp, int& floc, const WDataInP fromp, const
static void _vl_vsss_setbit(WDataOutP iowp, int obits, int lsb, int nbits, IData ld) VL_MT_SAFE {
for (; nbits && lsb < obits; nbits--, lsb++, ld >>= 1) VL_ASSIGNBIT_WI(lsb, iowp, ld & 1);
}
static void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp,
size_t posstart, size_t posend) VL_MT_SAFE {
void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp, size_t posstart,
size_t posend) VL_MT_SAFE {
// Read in base "2^^baseLog2" digits from strp[posstart..posend-1] into owp of size obits.
VL_ZERO_W(obits, owp);
int lsb = 0;
@@ -1196,7 +1212,7 @@ static void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* s
IData _vl_vsscanf(FILE* fp, // If a fscanf
int fbits, const WDataInP fromp, // Else if a sscanf
const std::string& fstr, // if a sscanf to string
const char* formatp, va_list ap) VL_MT_SAFE {
const std::string& format, va_list ap) VL_MT_SAFE {
// Read a Verilog $sscanf/$fscanf style format into the output list
// The format must be pre-processed (and lower cased) by Verilator
// Arguments are in "width, arg-value (or WDataIn* if wide)" form
@@ -1205,15 +1221,15 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
IData got = 0;
bool inPct = false;
bool inIgnore = false;
const char* pos = formatp;
for (; *pos && !_vl_vsss_eof(fp, floc); ++pos) {
std::string::const_iterator pos = format.cbegin();
for (; pos != format.cend() && !_vl_vsss_eof(fp, floc); ++pos) {
// VL_DBG_MSGF("_vlscan fmt='"<<pos[0]<<"' floc="<<floc<<" file='"<<_vl_vsss_peek(fp, floc,
// fromp, fstr)<<"'\n");
if (!inPct && pos[0] == '%') {
inPct = true;
inIgnore = false;
} else if (!inPct && std::isspace(pos[0])) { // Format spaces
while (std::isspace(pos[1])) pos++;
while (std::isspace(pos[1])) ++pos;
_vl_vsss_skipspace(fp, floc, fromp, fstr);
} else if (!inPct) { // Expected Format
_vl_vsss_skipspace(fp, floc, fromp, fstr);
@@ -1360,7 +1376,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
break;
}
default: { // LCOV_EXCL_START
const std::string msg = std::string{"Unknown _vl_vsscanf code: "} + pos[0];
const std::string msg = "Unknown _vl_vsscanf code: "s + pos[0];
VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str());
break;
} // LCOV_EXCL_STOP
@@ -1429,8 +1445,8 @@ void _vl_string_to_vint(int obits, void* destp, size_t srclen, const char* srcp)
char* op = reinterpret_cast<char*>(destp);
if (srclen > bytes) srclen = bytes; // Don't overflow destination
size_t i = 0;
for (i = 0; i < srclen; ++i) { *op++ = srcp[srclen - 1 - i]; }
for (; i < bytes; ++i) { *op++ = 0; }
for (i = 0; i < srclen; ++i) *op++ = srcp[srclen - 1 - i];
for (; i < bytes; ++i) *op++ = 0;
}
static IData getLine(std::string& str, IData fpi, size_t maxLen) VL_MT_SAFE {
@@ -1500,149 +1516,153 @@ void VL_FCLOSE_I(IData fdi) VL_MT_SAFE {
Verilated::threadContextp()->impp()->fdClose(fdi);
}
void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) VL_MT_SAFE {
void VL_SFORMAT_NX(int obits, CData& destr, const std::string& format, int argc, ...) VL_MT_SAFE {
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
_vl_vsformat(t_output, formatp, ap);
va_start(ap, argc);
_vl_vsformat(t_output, format, ap);
va_end(ap);
_vl_string_to_vint(obits, &destr, t_output.length(), t_output.c_str());
}
void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...) VL_MT_SAFE {
void VL_SFORMAT_NX(int obits, SData& destr, const std::string& format, int argc, ...) VL_MT_SAFE {
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
_vl_vsformat(t_output, formatp, ap);
va_start(ap, argc);
_vl_vsformat(t_output, format, ap);
va_end(ap);
_vl_string_to_vint(obits, &destr, t_output.length(), t_output.c_str());
}
void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...) VL_MT_SAFE {
void VL_SFORMAT_NX(int obits, IData& destr, const std::string& format, int argc, ...) VL_MT_SAFE {
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
_vl_vsformat(t_output, formatp, ap);
va_start(ap, argc);
_vl_vsformat(t_output, format, ap);
va_end(ap);
_vl_string_to_vint(obits, &destr, t_output.length(), t_output.c_str());
}
void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...) VL_MT_SAFE {
void VL_SFORMAT_NX(int obits, QData& destr, const std::string& format, int argc, ...) VL_MT_SAFE {
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
_vl_vsformat(t_output, formatp, ap);
va_start(ap, argc);
_vl_vsformat(t_output, format, ap);
va_end(ap);
_vl_string_to_vint(obits, &destr, t_output.length(), t_output.c_str());
}
void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) VL_MT_SAFE {
void VL_SFORMAT_NX(int obits, void* destp, const std::string& format, int argc, ...) VL_MT_SAFE {
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
_vl_vsformat(t_output, formatp, ap);
va_start(ap, argc);
_vl_vsformat(t_output, format, ap);
va_end(ap);
_vl_string_to_vint(obits, destp, t_output.length(), t_output.c_str());
}
void VL_SFORMAT_X(int obits_ignored, std::string& output, const char* formatp, ...) VL_MT_SAFE {
if (obits_ignored) {}
void VL_SFORMAT_NX(int obits_ignored, std::string& output, const std::string& format, int argc,
...) VL_MT_SAFE {
(void)obits_ignored; // So VL_SFORMAT_NNX function signatures all match
std::string temp_output;
va_list ap;
va_start(ap, formatp);
_vl_vsformat(temp_output, formatp, ap);
va_start(ap, argc);
_vl_vsformat(temp_output, format, ap);
va_end(ap);
output = temp_output;
}
std::string VL_SFORMATF_NX(const char* formatp, ...) VL_MT_SAFE {
std::string VL_SFORMATF_N_NX(const std::string& format, int argc, ...) VL_MT_SAFE {
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
_vl_vsformat(t_output, formatp, ap);
va_start(ap, argc);
_vl_vsformat(t_output, format, ap);
va_end(ap);
return t_output;
}
void VL_WRITEF(const char* formatp, ...) VL_MT_SAFE {
void VL_WRITEF_NX(const std::string& format, int argc, ...) VL_MT_SAFE {
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
_vl_vsformat(t_output, formatp, ap);
va_start(ap, argc);
_vl_vsformat(t_output, format, ap);
va_end(ap);
VL_PRINTF_MT("%s", t_output.c_str());
}
void VL_FWRITEF(IData fpi, const char* formatp, ...) VL_MT_SAFE {
void VL_FWRITEF_NX(IData fpi, const std::string& format, int argc, ...) VL_MT_SAFE {
// While threadsafe, each thread can only access different file handles
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
_vl_vsformat(t_output, formatp, ap);
va_start(ap, argc);
_vl_vsformat(t_output, format, ap);
va_end(ap);
Verilated::threadContextp()->impp()->fdWrite(fpi, t_output);
}
IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) VL_MT_SAFE {
IData VL_FSCANF_INX(IData fpi, const std::string& format, int argc, ...) VL_MT_SAFE {
// While threadsafe, each thread can only access different file handles
FILE* const fp = VL_CVT_I_FP(fpi);
if (VL_UNLIKELY(!fp)) return ~0U; // -1
va_list ap;
va_start(ap, formatp);
const IData got = _vl_vsscanf(fp, 0, nullptr, "", formatp, ap);
va_start(ap, argc);
const IData got = _vl_vsscanf(fp, 0, nullptr, "", format, ap);
va_end(ap);
return got;
}
IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) VL_MT_SAFE {
IData VL_SSCANF_IINX(int lbits, IData ld, const std::string& format, int argc, ...) VL_MT_SAFE {
VlWide<VL_WQ_WORDS_E> fnw;
VL_SET_WI(fnw, ld);
va_list ap;
va_start(ap, formatp);
const IData got = _vl_vsscanf(nullptr, lbits, fnw, "", formatp, ap);
va_start(ap, argc);
const IData got = _vl_vsscanf(nullptr, lbits, fnw, "", format, ap);
va_end(ap);
return got;
}
IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...) VL_MT_SAFE {
IData VL_SSCANF_IQNX(int lbits, QData ld, const std::string& format, int argc, ...) VL_MT_SAFE {
VlWide<VL_WQ_WORDS_E> fnw;
VL_SET_WQ(fnw, ld);
va_list ap;
va_start(ap, formatp);
const IData got = _vl_vsscanf(nullptr, lbits, fnw, "", formatp, ap);
va_start(ap, argc);
const IData got = _vl_vsscanf(nullptr, lbits, fnw, "", format, ap);
va_end(ap);
return got;
}
IData VL_SSCANF_IWX(int lbits, const WDataInP lwp, const char* formatp, ...) VL_MT_SAFE {
IData VL_SSCANF_IWNX(int lbits, const WDataInP lwp, const std::string& format, int argc,
...) VL_MT_SAFE {
va_list ap;
va_start(ap, formatp);
const IData got = _vl_vsscanf(nullptr, lbits, lwp, "", formatp, ap);
va_start(ap, argc);
const IData got = _vl_vsscanf(nullptr, lbits, lwp, "", format, ap);
va_end(ap);
return got;
}
IData VL_SSCANF_INX(int, const std::string& ld, const char* formatp, ...) VL_MT_SAFE {
IData VL_SSCANF_INNX(int, const std::string& ld, const std::string& format, int argc,
...) VL_MT_SAFE {
va_list ap;
va_start(ap, formatp);
const IData got = _vl_vsscanf(nullptr, ld.length() * 8, nullptr, ld, formatp, ap);
va_start(ap, argc);
const IData got
= _vl_vsscanf(nullptr, static_cast<int>(ld.length() * 8), nullptr, ld, format, ap);
va_end(ap);
return got;
}
@@ -1717,7 +1737,7 @@ std::string VL_STACKTRACE_N() VL_MT_SAFE {
if (!strings) return "Unable to backtrace\n";
std::string result = "Backtrace:\n";
for (int j = 0; j < nptrs; j++) result += std::string{strings[j]} + std::string{"\n"};
for (int j = 0; j < nptrs; j++) result += std::string{strings[j]} + "\n"s;
free(strings);
return result;
}
@@ -1735,7 +1755,10 @@ IData VL_SYSTEM_IQ(QData lhs) VL_MT_SAFE {
IData VL_SYSTEM_IW(int lhswords, const WDataInP lhsp) VL_MT_SAFE {
char filenamez[VL_VALUE_STRING_MAX_CHARS + 1];
_vl_vint_to_string(lhswords * VL_EDATASIZE, filenamez, lhsp);
const int code = std::system(filenamez); // Yes, std::system() is threadsafe
return VL_SYSTEM_IN(filenamez);
}
IData VL_SYSTEM_IN(const std::string& lhs) VL_MT_SAFE {
const int code = std::system(lhs.c_str()); // Yes, std::system() is threadsafe
return code >> 8; // Want exit status
}
@@ -1860,13 +1883,13 @@ const char* vl_mc_scan_plusargs(const char* prefixp) VL_MT_SAFE {
//===========================================================================
// Heavy string functions
std::string VL_TO_STRING(CData lhs) { return VL_SFORMATF_NX("'h%0x", 8, lhs); }
std::string VL_TO_STRING(SData lhs) { return VL_SFORMATF_NX("'h%0x", 16, lhs); }
std::string VL_TO_STRING(IData lhs) { return VL_SFORMATF_NX("'h%0x", 32, lhs); }
std::string VL_TO_STRING(QData lhs) { return VL_SFORMATF_NX("'h%0x", 64, lhs); }
std::string VL_TO_STRING(double lhs) { return VL_SFORMATF_NX("%d", 64, lhs); }
std::string VL_TO_STRING(CData lhs) { return VL_SFORMATF_N_NX("'h%0x", 0, 8, lhs); }
std::string VL_TO_STRING(SData lhs) { return VL_SFORMATF_N_NX("'h%0x", 0, 16, lhs); }
std::string VL_TO_STRING(IData lhs) { return VL_SFORMATF_N_NX("'h%0x", 0, 32, lhs); }
std::string VL_TO_STRING(QData lhs) { return VL_SFORMATF_N_NX("'h%0x", 0, 64, lhs); }
std::string VL_TO_STRING(double lhs) { return VL_SFORMATF_N_NX("%d", 0, 64, lhs); }
std::string VL_TO_STRING_W(int words, const WDataInP obj) {
return VL_SFORMATF_NX("'h%0x", words * VL_EDATASIZE, obj);
return VL_SFORMATF_N_NX("'h%0x", 0, words * VL_EDATASIZE, obj);
}
std::string VL_TOLOWER_NN(const std::string& ld) VL_PURE {
@@ -1931,7 +1954,7 @@ std::string VL_SUBSTR_N(const std::string& lhs, IData rhs, IData ths) VL_PURE {
IData VL_ATOI_N(const std::string& str, int base) VL_PURE {
std::string str_mod = str;
// IEEE 1800-2017 6.16.9 says '_' may exist.
// IEEE 1800-2023 6.16.9 says '_' may exist.
str_mod.erase(std::remove(str_mod.begin(), str_mod.end(), '_'), str_mod.end());
errno = 0;
@@ -2023,22 +2046,26 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) {
if (VL_UNLIKELY(!m_fp)) return false;
valuer = "";
// Prep for reading
bool indata = false;
bool ignore_to_eol = false;
bool ignore_to_cmt = false;
bool reading_addr = false;
int lastc = ' ';
bool inData = false;
bool ignoreToEol = false;
bool ignoreToComment = false;
bool readingAddress = false;
int lastCh = ' ';
// Read the data
// We process a character at a time, as then we don't need to deal
// with changing buffer sizes dynamically, etc.
while (true) {
int c = std::fgetc(m_fp);
if (VL_UNLIKELY(c == EOF)) break;
const bool chIs4StateBin
= c == '0' || c == '1' || c == 'x' || c == 'X' || c == 'z' || c == 'Z';
const bool chIs2StateHex = std::isxdigit(c);
const bool chIs4StateHex = std::isxdigit(c) || chIs4StateBin;
// printf("%d: Got '%c' Addr%lx IN%d IgE%d IgC%d\n",
// m_linenum, c, m_addr, indata, ignore_to_eol, ignore_to_cmt);
// m_linenum, c, m_addr, inData, ignoreToEol, ignoreToComment);
// See if previous data value has completed, and if so return
if (c == '_') continue; // Ignore _ e.g. inside a number
if (indata && !std::isxdigit(c) && c != 'x' && c != 'X') {
if (inData && !chIs4StateHex) {
// printf("Got data @%lx = %s\n", m_addr, valuer.c_str());
ungetc(c, m_fp);
addrr = m_addr;
@@ -2048,58 +2075,55 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) {
// Parse line
if (c == '\n') {
++m_linenum;
ignore_to_eol = false;
reading_addr = false;
ignoreToEol = false;
readingAddress = false;
} else if (c == '\t' || c == ' ' || c == '\r' || c == '\f') {
reading_addr = false;
readingAddress = false;
}
// Skip // comments and detect /* comments
else if (ignore_to_cmt && lastc == '*' && c == '/') {
ignore_to_cmt = false;
reading_addr = false;
} else if (!ignore_to_eol && !ignore_to_cmt) {
if (lastc == '/' && c == '*') {
ignore_to_cmt = true;
} else if (lastc == '/' && c == '/') {
ignore_to_eol = true;
else if (ignoreToComment && lastCh == '*' && c == '/') {
ignoreToComment = false;
readingAddress = false;
} else if (!ignoreToEol && !ignoreToComment) {
if (lastCh == '/' && c == '*') {
ignoreToComment = true;
} else if (lastCh == '/' && c == '/') {
ignoreToEol = true;
} else if (c == '/') { // Part of /* or //
} else if (c == '#') {
ignore_to_eol = true;
ignoreToEol = true;
} else if (c == '@') {
reading_addr = true;
readingAddress = true;
m_anyAddr = true;
m_addr = 0;
}
// Check for hex or binary digits as file format requests
else if (std::isxdigit(c) || (!reading_addr && (c == 'x' || c == 'X'))) {
} else if (readingAddress && chIs2StateHex) {
c = std::tolower(c);
const int value
= (c >= 'a' ? (c == 'x' ? VL_RAND_RESET_I(4) : (c - 'a' + 10)) : (c - '0'));
if (reading_addr) {
// Decode @ addresses
m_addr = (m_addr << 4) + value;
} else {
indata = true;
valuer += static_cast<char>(c);
// printf(" Value width=%d @%x = %c\n", width, m_addr, c);
if (VL_UNLIKELY(value > 1 && !m_hex)) {
VL_FATAL_MT(m_filename.c_str(), m_linenum, "",
"$readmemb (binary) file contains hex characters");
}
const int addressValue = (c >= 'a') ? (c - 'a' + 10) : (c - '0');
m_addr = (m_addr << 4) + addressValue;
} else if (readingAddress && chIs4StateHex) {
VL_FATAL_MT(m_filename.c_str(), m_linenum, "",
"$readmem address contains 4-state characters");
} else if (chIs4StateHex) {
inData = true;
valuer += static_cast<char>(c);
if (VL_UNLIKELY(!m_hex && !chIs4StateBin)) {
VL_FATAL_MT(m_filename.c_str(), m_linenum, "",
"$readmemb (binary) file contains hex characters");
}
} else {
VL_FATAL_MT(m_filename.c_str(), m_linenum, "", "$readmem file syntax error");
}
}
lastc = c;
lastCh = c;
}
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 1800-2017 21.4)");
"$readmem file ended before specified final address (IEEE 1800-2023 21.4)");
}
return false; // EOF
addrr = m_addr;
return inData; // EOF
}
void VlReadMem::setData(void* valuep, const std::string& rhs) {
const QData shift = m_hex ? 4ULL : 1ULL;
@@ -2107,8 +2131,9 @@ void VlReadMem::setData(void* valuep, const std::string& rhs) {
// Shift value in
for (const auto& i : rhs) {
const char c = std::tolower(i);
const int value
= (c >= 'a' ? (c == 'x' ? VL_RAND_RESET_I(4) : (c - 'a' + 10)) : (c - '0'));
const int value = (c == 'x' || c == 'z') ? VL_RAND_RESET_I(m_hex ? 4 : 1)
: (c >= 'a') ? (c - 'a' + 10)
: (c - '0');
if (m_bits <= 8) {
CData* const datap = reinterpret_cast<CData*>(valuep);
if (!innum) *datap = 0;
@@ -2248,6 +2273,7 @@ void VL_READMEM_N(bool hex, // Hex format, else binary
QData addr = 0;
std::string value;
if (rmem.get(addr /*ref*/, value /*ref*/)) {
// printf("readmem.get [%" PRIu64 "]=%s\n", addr, value.c_str());
if (VL_UNLIKELY(addr < static_cast<QData>(array_lsb)
|| addr >= static_cast<QData>(array_lsb + depth))) {
VL_FATAL_MT(filename.c_str(), rmem.linenum(), "",
@@ -2402,6 +2428,22 @@ uint64_t vl_time_pow10(int n) {
return pow10[n];
}
std::string vl_timescaled_double(double value, const char* format) 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-12) { suffixp = "ps"; value *= 1e12; }
else if (value >= 1e-15) { suffixp = "fs"; value *= 1e15; }
else if (value >= 1e-18) { suffixp = "as"; value *= 1e18; }
// clang-format on
char valuestr[100];
VL_SNPRINTF(valuestr, 100, format, value, suffixp);
return std::string{valuestr}; // Gets converted to string, so no ref to stack
}
void VL_PRINTTIMESCALE(const char* namep, const char* timeunitp,
const VerilatedContext* contextp) VL_MT_SAFE {
VL_PRINTF_MT("Time scale of %s is %s / %s\n", namep, timeunitp,
@@ -2422,12 +2464,15 @@ VerilatedContext::VerilatedContext()
: m_impdatap{new VerilatedContextImpData} {
Verilated::lastContextp(this);
Verilated::threadContextp(this);
m_ns.m_coverageFilename = "coverage.dat";
m_ns.m_profExecFilename = "profile_exec.dat";
m_ns.m_profVltFilename = "profile.vlt";
m_ns.m_solverProgram = VlOs::getenvStr("VERILATOR_SOLVER", VL_SOLVER_DEFAULT);
m_fdps.resize(31);
std::fill(m_fdps.begin(), m_fdps.end(), static_cast<FILE*>(nullptr));
m_fdFreeMct.resize(30);
for (std::size_t i = 0, id = 1; i < m_fdFreeMct.size(); ++i, ++id) m_fdFreeMct[i] = id;
IData id = 1;
for (std::size_t i = 0; i < m_fdFreeMct.size(); ++i, ++id) m_fdFreeMct[i] = id;
}
// Must declare here not in interface, as otherwise forward declarations not known
@@ -2457,6 +2502,14 @@ void VerilatedContext::calcUnusedSigs(bool flag) VL_MT_SAFE {
const VerilatedLockGuard lock{m_mutex};
m_s.m_calcUnusedSigs = flag;
}
void VerilatedContext::coverageFilename(const std::string& flag) VL_MT_SAFE {
const VerilatedLockGuard lock{m_mutex};
m_ns.m_coverageFilename = flag;
}
std::string VerilatedContext::coverageFilename() const VL_MT_SAFE {
const VerilatedLockGuard lock{m_mutex};
return m_ns.m_coverageFilename;
}
void VerilatedContext::dumpfile(const std::string& flag) VL_MT_SAFE_EXCLUDES(m_timeDumpMutex) {
const VerilatedLockGuard lock{m_timeDumpMutex};
m_dumpfile = flag;
@@ -2525,6 +2578,18 @@ std::string VerilatedContext::profVltFilename() const VL_MT_SAFE {
const VerilatedLockGuard lock{m_mutex};
return m_ns.m_profVltFilename;
}
void VerilatedContext::solverProgram(const std::string& flag) VL_MT_SAFE {
const VerilatedLockGuard lock{m_mutex};
m_ns.m_solverProgram = flag;
}
std::string VerilatedContext::solverProgram() const VL_MT_SAFE {
const VerilatedLockGuard lock{m_mutex};
return m_ns.m_solverProgram;
}
void VerilatedContext::quiet(bool flag) VL_MT_SAFE {
const VerilatedLockGuard lock{m_mutex};
m_s.m_quiet = flag;
}
void VerilatedContext::randReset(int val) VL_MT_SAFE {
const VerilatedLockGuard lock{m_mutex};
m_s.m_randReset = val;
@@ -2592,8 +2657,24 @@ void VerilatedContext::internalsDump() const VL_MT_SAFE {
}
void VerilatedContext::addModel(VerilatedModel* modelp) {
threadPoolp(); // Ensure thread pool is created, so m_threads cannot change any more
if (!quiet()) {
// CPU time isn't read as starting point until model creation, so that quiet() is set
// Thus if quiet(), avoids slow OS read affecting some usages that make many models
const VerilatedLockGuard lock{m_mutex};
m_ns.m_cpuTimeStart.start();
m_ns.m_wallTimeStart.start();
}
// We look for time passing, as opposed to post-eval(), as embedded
// models might get added inside initial blocks.
if (VL_UNLIKELY(time()))
VL_FATAL_MT(
"", 0, "",
"Adding model when time is non-zero. ... Suggest check time(), or for restarting"
" model use a new VerilatedContext");
threadPoolp(); // Ensure thread pool is created, so m_threads cannot change any more
m_threadsInModels += modelp->threads();
if (VL_UNLIKELY(modelp->threads() > m_threads)) {
std::ostringstream msg;
msg << "VerilatedContext has " << m_threads << " threads but model '"
@@ -2626,6 +2707,7 @@ VerilatedContext::enableExecutionProfiler(VerilatedVirtualBase* (*construct)(Ver
//======================================================================
// VerilatedContextImp:: Methods - command line
void VerilatedContextImp::commandArgsGuts(int argc, const char** argv)
VL_MT_SAFE_EXCLUDES(m_argMutex) {
const VerilatedLockGuard lock{m_argMutex};
@@ -2685,7 +2767,7 @@ std::pair<int, char**> VerilatedContextImp::argc_argv() VL_MT_SAFE_EXCLUDES(m_ar
int in = 0;
for (const auto& i : m_args.m_argVec) {
s_argvp[in] = new char[i.length() + 1];
std::strcpy(s_argvp[in], i.c_str());
std::memcpy(s_argvp[in], i.c_str(), i.length() + 1);
++in;
}
s_argvp[s_argc] = nullptr;
@@ -2697,7 +2779,9 @@ void VerilatedContextImp::commandArgVl(const std::string& arg) {
if (0 == std::strncmp(arg.c_str(), "+verilator+", std::strlen("+verilator+"))) {
std::string str;
uint64_t u64;
if (arg == "+verilator+debug") {
if (commandArgVlString(arg, "+verilator+coverage+file+", str)) {
coverageFilename(str);
} else if (arg == "+verilator+debug") {
Verilated::debug(4);
} else if (commandArgVlUint64(arg, "+verilator+debugi+", u64, 0,
std::numeric_limits<int>::max())) {
@@ -2720,6 +2804,8 @@ void VerilatedContextImp::commandArgVl(const std::string& arg) {
profExecFilename(str);
} else if (commandArgVlString(arg, "+verilator+prof+vlt+file+", str)) {
profVltFilename(str);
} else if (arg == "+verilator+quiet") {
quiet(true);
} else if (commandArgVlUint64(arg, "+verilator+rand+reset+", u64, 0, 2)) {
randReset(static_cast<int>(u64));
} else if (commandArgVlUint64(arg, "+verilator+seed+", u64, 1,
@@ -2765,7 +2851,7 @@ bool VerilatedContextImp::commandArgVlUint64(const std::string& arg, const std::
VL_FATAL_MT("COMMAND_LINE", 0, "", msg.c_str());
};
if (std::any_of(str.begin(), str.end(), [](int c) { return !std::isdigit(c); })) fail();
if (std::any_of(str.cbegin(), str.cend(), [](int c) { return !std::isdigit(c); })) fail();
char* end;
valuer = std::strtoull(str.c_str(), &end, 10);
if (errno == ERANGE) fail("Value out of range of uint64_t");
@@ -2797,6 +2883,36 @@ uint64_t VerilatedContextImp::randSeedDefault64() const VL_MT_SAFE {
}
}
//======================================================================
// VerilatedContext:: Statistics
double VerilatedContext::statCpuTimeSinceStart() const VL_MT_SAFE_EXCLUDES(m_mutex) {
const VerilatedLockGuard lock{m_mutex};
return m_ns.m_cpuTimeStart.deltaTime();
}
double VerilatedContext::statWallTimeSinceStart() const VL_MT_SAFE_EXCLUDES(m_mutex) {
const VerilatedLockGuard lock{m_mutex};
return m_ns.m_wallTimeStart.deltaTime();
}
void VerilatedContext::statsPrintSummary() VL_MT_UNSAFE {
if (quiet()) return;
VL_PRINTF("- S i m u l a t i o n R e p o r t: %s %s\n", Verilated::productName(),
Verilated::productVersion());
const std::string endwhy = gotError() ? "$stop" : gotFinish() ? "$finish" : "end";
const double simtimeInUnits = VL_TIME_Q() * vl_time_multiplier(timeunit())
* vl_time_multiplier(timeprecision() - timeunit());
const std::string simtime = vl_timescaled_double(simtimeInUnits);
const double walltime = statWallTimeSinceStart();
const double cputime = statCpuTimeSinceStart();
const std::string simtimePerf
= vl_timescaled_double((cputime != 0.0) ? (simtimeInUnits / cputime) : 0, "%0.3f %s");
VL_PRINTF("- Verilator: %s at %s; walltime %0.3f s; speed %s/s\n", endwhy.c_str(),
simtime.c_str(), walltime, simtimePerf.c_str());
const double modelMB = VlOs::memUsageBytes() / 1024.0 / 1024.0;
VL_PRINTF("- Verilator: cpu %0.3f s on %u threads; alloced %0.0f MB\n", cputime,
threadsInModels(), modelMB);
}
//======================================================================
// VerilatedContext:: Methods - scopes
@@ -2835,6 +2951,36 @@ const VerilatedScopeNameMap* VerilatedContext::scopeNameMap() VL_MT_SAFE {
return &(impp()->m_impdatap->m_nameMap);
}
//======================================================================
// VerilatedContext:: Methods - trace
void VerilatedContext::trace(VerilatedTraceBaseC* tfp, int levels, int options) VL_MT_SAFE {
VL_DEBUG_IF(VL_DBG_MSGF("+ VerilatedContext::trace\n"););
if (tfp->isOpen()) {
VL_FATAL_MT("", 0, "",
"Testbench C call to 'VerilatedContext::trace()' must not be called"
" after 'VerilatedTrace*::open()'\n");
}
{
// Legacy usage may call {modela}->trace(...) then {modelb}->trace(...)
// So check for and suppress second and later calls
if (tfp->modelConnected()) return;
tfp->modelConnected(true);
}
// We rely on m_ns.m_traceBaseModelCbs being stable when trace() is called
// nope: const VerilatedLockGuard lock{m_mutex};
if (m_ns.m_traceBaseModelCbs.empty())
VL_FATAL_MT("", 0, "",
"Testbench C call to 'VerilatedContext::trace()' requires model(s) Verilated"
" with --trace or --trace-vcd option");
for (auto& cbr : m_ns.m_traceBaseModelCbs) cbr(tfp, levels, options);
}
void VerilatedContext::traceBaseModelCbAdd(traceBaseModelCb_t cb) VL_MT_SAFE {
// Model creation registering a callback for when Verilated::trace() called
const VerilatedLockGuard lock{m_mutex};
m_ns.m_traceBaseModelCbs.push_back(cb);
}
//======================================================================
// VerilatedSyms:: Methods
@@ -2969,7 +3115,7 @@ void Verilated::nullPointerError(const char* filename, int linenum) VL_MT_SAFE {
void Verilated::overWidthError(const char* signame) VL_MT_SAFE {
// Slowpath - Called only when signal sets too high of a bit
const std::string msg = (std::string{"Testbench C set input '"} + signame
const std::string msg = ("Testbench C set input '"s + signame
+ "' to value that overflows what the signal's width can fit");
VL_FATAL_MT("unknown", 0, "", msg.c_str());
VL_UNREACHABLE;
@@ -2995,6 +3141,38 @@ void Verilated::scTraceBeforeElaborationError() VL_MT_SAFE {
VL_UNREACHABLE;
}
void Verilated::stackCheck(QData needSize) VL_MT_UNSAFE {
// Slowpath - Called only when constructing
#ifdef _VL_HAVE_GETRLIMIT
QData haveSize = 0;
rlimit rlim;
if (0 == getrlimit(RLIMIT_STACK, &rlim)) {
haveSize = rlim.rlim_cur;
if (haveSize == RLIM_INFINITY) haveSize = rlim.rlim_max;
if (haveSize == RLIM_INFINITY) haveSize = 0;
}
// VL_PRINTF_MT("-Info: stackCheck(%" PRIu64 ") have %" PRIu64 "\n", needSize, haveSize);
// Check and request for 1.5x need. This is automated so the user doesn't need to do anything.
QData requestSize = needSize + needSize / 2;
if (VL_UNLIKELY(haveSize && needSize && haveSize < requestSize)) {
// Try to increase the stack limit to the requested size
rlim.rlim_cur = requestSize;
if (
#ifdef _VL_TEST_RLIMIT_FAIL
true ||
#endif
setrlimit(RLIMIT_STACK, &rlim)) {
VL_PRINTF_MT("%%Warning: System has stack size %" PRIu64 " kb"
" which may be too small; failed to request more"
" using 'ulimit -s %" PRIu64 "'\n",
haveSize / 1024, requestSize);
}
}
#else
(void)needSize; // Unused argument
#endif
}
void Verilated::mkdir(const char* dirname) VL_MT_UNSAFE {
#if defined(_WIN32) || defined(__MINGW32__)
::mkdir(dirname);
@@ -3168,8 +3346,7 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap, boo
} else {
// We could have a linked list of ranges, but really this whole thing needs
// to be generalized to support structs and unions, etc.
const std::string msg
= std::string{"Unsupported multi-dimensional public varInsert: "} + namep;
const std::string msg = "Unsupported multi-dimensional public varInsert: "s + namep;
VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str());
}
}
@@ -3189,10 +3366,9 @@ VerilatedVar* VerilatedScope::varFind(const char* namep) const VL_MT_SAFE_POSTIN
void* VerilatedScope::exportFindNullError(int funcnum) VL_MT_SAFE {
// Slowpath - Called only when find has failed
const std::string msg
= (std::string{"Testbench C called '"} + VerilatedImp::exportName(funcnum)
+ "' but scope wasn't set, perhaps due to dpi import call without "
+ "'context', or missing svSetScope. See IEEE 1800-2017 35.5.3.");
const std::string msg = ("Testbench C called '"s + VerilatedImp::exportName(funcnum)
+ "' but scope wasn't set, perhaps due to dpi import call without "
+ "'context', or missing svSetScope. See IEEE 1800-2023 35.5.3.");
VL_FATAL_MT("unknown", 0, "", msg.c_str());
return nullptr;
}
@@ -3200,7 +3376,7 @@ void* VerilatedScope::exportFindNullError(int funcnum) VL_MT_SAFE {
void* VerilatedScope::exportFindError(int funcnum) const VL_MT_SAFE {
// Slowpath - Called only when find has failed
const std::string msg
= (std::string{"Testbench C called '"} + VerilatedImp::exportName(funcnum)
= ("Testbench C called '"s + VerilatedImp::exportName(funcnum)
+ "' but this DPI export function exists only in other scopes, not scope '" + name()
+ "'");
VL_FATAL_MT("unknown", 0, "", msg.c_str());
@@ -3258,3 +3434,7 @@ void VlDeleter::deleteAll() VL_EXCLUDES(m_mutex) VL_EXCLUDES(m_deleteMutex) VL_M
}
//===========================================================================
// OS functions (last, so we have minimal OS dependencies above)
#define VL_ALLOW_VERILATEDOS_C
#include "verilatedos_c.h"
+48 -5
View File
@@ -73,6 +73,8 @@
#endif
// clang-format on
using namespace std::literals; // "<std::string literal>"s; see SF.7 core guideline
//=============================================================================
// Switches
@@ -99,6 +101,7 @@ class VerilatedScope;
class VerilatedScopeNameMap;
template <class, class>
class VerilatedTrace;
class VerilatedTraceBaseC;
class VerilatedTraceConfig;
class VerilatedVar;
class VerilatedVarNameMap;
@@ -345,20 +348,25 @@ class VerilatedContext VL_NOT_FINAL {
friend class VerilatedContextImp;
protected:
// TYPES
using traceBaseModelCb_t
= std::function<void(VerilatedTraceBaseC*, int, int)>; // Type of traceBaseModel callbacks
// MEMBERS
// Slow path variables
mutable VerilatedMutex m_mutex; // Mutex for most s_s/s_ns members
struct Serialized { // All these members serialized/deserialized
struct Serialized final { // All these members serialized/deserialized
// No std::strings or pointers or will serialize badly!
// Fast path
uint64_t m_time = 0; // Current $time (unscaled), 0=at zero, or legacy
bool m_assertOn = true; // Assertions are enabled
bool m_calcUnusedSigs = false; // Waves file on, need all signals calculated
bool m_fatalOnError = true; // Fatal on $stop/non-fatal error
bool m_fatalOnVpiError = true; // Fatal on vpi error/unsupported
bool m_gotError = false; // A $finish statement executed
bool m_gotFinish = false; // A $finish or $stop statement executed
uint64_t m_time = 0; // Current $time (unscaled), 0=at zero, or legacy
bool m_quiet = false; // Quiet, no summary report
// Slow path
int8_t m_timeunit; // Time unit as 0..15
int8_t m_timeprecision; // Time precision as 0..15
@@ -379,20 +387,25 @@ protected:
std::string m_timeFormatSuffix VL_GUARDED_BY(m_timeDumpMutex); // $timeformat printf format
std::string m_dumpfile VL_GUARDED_BY(m_timeDumpMutex); // $dumpfile setting
struct NonSerialized { // Non-serialized information
struct NonSerialized final { // Non-serialized information
// These are reloaded from on command-line settings, so do not need to persist
// Fast path
uint64_t m_profExecStart = 1; // +prof+exec+start time
uint32_t m_profExecWindow = 2; // +prof+exec+window size
// Slow path
std::string m_coverageFilename; // +coverage+file filename
std::string m_profExecFilename; // +prof+exec+file filename
std::string m_profVltFilename; // +prof+vlt filename
std::string m_solverProgram; // SMT solver program
VlOs::DeltaCpuTime m_cpuTimeStart{false}; // CPU time, starts when create first model
VlOs::DeltaWallTime m_wallTimeStart{false}; // Wall time, starts when create first model
std::vector<traceBaseModelCb_t> m_traceBaseModelCbs; // Callbacks to traceRegisterModel
} m_ns;
mutable VerilatedMutex m_argMutex; // Protect m_argVec, m_argVecLoaded
// no need to be save-restored (serialized) the
// assumption is that the restore is allowed to pass different arguments
struct NonSerializedCommandArgs {
struct NonSerializedCommandArgs final {
// Medium speed
std::vector<std::string> m_argVec; // Argument list
bool m_argVecLoaded = false; // Ever loaded argument list
@@ -402,6 +415,8 @@ protected:
const std::unique_ptr<VerilatedContextImpData> m_impdatap;
// Number of threads to use for simulation (size of m_threadPool + 1 for main thread)
unsigned m_threads = std::thread::hardware_concurrency();
// Number of threads in added models
unsigned m_threadsInModels = 0;
// The thread pool shared by all models added to this context
std::unique_ptr<VerilatedVirtualBase> m_threadPool;
// The execution profiler shared by all models added to this context
@@ -486,6 +501,10 @@ public:
void gotFinish(bool flag) VL_MT_SAFE;
/// Return if got a $finish or $stop/error
bool gotFinish() const VL_MT_SAFE { return m_s.m_gotFinish; }
/// Enable quiet (also prevents need for OS calls to get CPU time)
void quiet(bool flag) VL_MT_SAFE;
/// Return if quiet enabled
bool quiet() const VL_MT_SAFE { return m_s.m_quiet; }
/// Select initial value of otherwise uninitialized signals.
/// 0 = Set to zeros
/// 1 = Set all bits to one
@@ -498,6 +517,13 @@ public:
/// Set default random seed, 0 = seed it automatically
int randSeed() const VL_MT_SAFE { return m_s.m_randSeed; }
/// Return statistic: CPU time delta from model created until now
double statCpuTimeSinceStart() const VL_MT_SAFE_EXCLUDES(m_mutex);
/// Return statistic: Wall time delta from model created until now
double statWallTimeSinceStart() const VL_MT_SAFE_EXCLUDES(m_mutex);
/// Print statistics summary (if not quiet)
void statsPrintSummary() VL_MT_UNSAFE;
// Time handling
/// Returns current simulation time in units of timeprecision().
///
@@ -541,10 +567,14 @@ public:
/// Get number of threads used for simulation (including the main thread)
unsigned threads() const { return m_threads; }
/// Get number of threads in added models (for statistical use only)
unsigned threadsInModels() const { return m_threadsInModels; }
/// Set number of threads used for simulation (including the main thread)
/// Can only be called before the thread pool is created (before first model is added).
void threads(unsigned n);
/// Trace signals in models within the context; called by application code
void trace(VerilatedTraceBaseC* tfp, int levels, int options = 0);
/// Allow traces to at some point be enabled (disables some optimizations)
void traceEverOn(bool flag) VL_MT_SAFE {
if (flag) calcUnusedSigs(true);
@@ -568,14 +598,18 @@ public:
return reinterpret_cast<const VerilatedContextImp*>(this);
}
// Internal: Model and thread setup
void addModel(VerilatedModel*);
VerilatedVirtualBase* threadPoolp();
void prepareClone();
VerilatedVirtualBase* threadPoolpOnClone();
VerilatedVirtualBase*
enableExecutionProfiler(VerilatedVirtualBase* (*construct)(VerilatedContext&));
// Internal: coverage
void coverageFilename(const std::string& flag) VL_MT_SAFE;
std::string coverageFilename() const VL_MT_SAFE;
// Internal: $dumpfile
void dumpfile(const std::string& flag) VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
std::string dumpfile() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
@@ -591,6 +625,10 @@ public:
void profVltFilename(const std::string& flag) VL_MT_SAFE;
std::string profVltFilename() const VL_MT_SAFE;
// Internal: SMT solver program
void solverProgram(const std::string& flag) VL_MT_SAFE;
std::string solverProgram() const VL_MT_SAFE;
// Internal: Find scope
const VerilatedScope* scopeFind(const char* namep) const VL_MT_SAFE;
const VerilatedScopeNameMap* scopeNameMap() VL_MT_SAFE;
@@ -599,6 +637,9 @@ public:
static constexpr size_t serialized1Size() VL_PURE { return sizeof(m_s); }
void* serialized1Ptr() VL_MT_UNSAFE { return &m_s; }
// Internal: trace registration
void traceBaseModelCbAdd(traceBaseModelCb_t cb) VL_MT_SAFE;
// Internal: Check magic number
static void checkMagic(const VerilatedContext* contextp);
void selfTestClearMagic() { m_magic = 0x2; }
@@ -898,6 +939,7 @@ public:
static void overWidthError(const char* signame) VL_ATTR_NORETURN VL_MT_SAFE;
static void scTimePrecisionError(int sc_prec, int vl_prec) VL_ATTR_NORETURN VL_MT_SAFE;
static void scTraceBeforeElaborationError() VL_ATTR_NORETURN VL_MT_SAFE;
static void stackCheck(QData needSize) VL_MT_UNSAFE;
// Internal: Get and set DPI context
static const VerilatedScope* dpiScope() VL_MT_SAFE { return t_s.t_dpiScopep; }
@@ -971,6 +1013,7 @@ void VerilatedContext::timeprecision(int value) VL_MT_SAFE {
} else if (sc_res == sc_core::sc_time(1, sc_core::SC_FS)) {
sc_prec = 15;
}
// SC_AS, SC_ZS, SC_YS not supported as no Verilog equivalent; will error below
#endif
}
#if VM_SC
-4
View File
@@ -101,9 +101,6 @@ LDFLAGS += $(CFG_LDFLAGS_VERILATED)
#OPT = -ggdb -DPRINTINITSTR
CPPFLAGS += $(OPT)
CPPFLAGS += $(M32)
LDFLAGS += $(M32)
# On macOS, specify all weak symbols as dynamic_lookup.
# Otherwise, you get undefined symbol errors.
ifeq ($(UNAME_S),Darwin)
@@ -228,7 +225,6 @@ endif
# 1. Extract object files from .a
# 2. Create a new archive from extracted .o and given .o
%.a: | %.verilator_deplist.tmp
$(info Archive $(AR) -rcs $@ $^)
$(foreach L, $(filter-out %.a,$^), $(shell echo $L >>[email protected]_deplist.tmp))
@if test $(words $(filter %.a,$^)) -eq 0; then \
$(RM) -f $@; \
+17 -11
View File
@@ -106,6 +106,7 @@ private:
using ItemList = std::deque<VerilatedCovImpItem*>;
// MEMBERS
VerilatedContext* const m_contextp; // Context VerilatedCovImp is pointed-to by
mutable VerilatedMutex m_mutex; // Protects all members
ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); // Unique arbitrary value for values
IndexValueMap m_indexValues VL_GUARDED_BY(m_mutex); // Unique arbitrary value for keys
@@ -120,7 +121,8 @@ private:
public:
// CONSTRUCTORS
VerilatedCovImp() = default;
explicit VerilatedCovImp(VerilatedContext* contextp)
: m_contextp{contextp} {}
VL_UNCOPYABLE(VerilatedCovImp);
protected:
@@ -166,11 +168,11 @@ private:
const std::string& value) VL_PURE {
std::string name;
if (key.length() == 1 && std::isalpha(key[0])) {
name += std::string{"\001"} + key;
name += "\001"s + key;
} else {
name += std::string{"\001"} + dequote(key);
name += "\001"s + dequote(key);
}
name += std::string{"\002"} + dequote(value);
name += "\002"s + dequote(value);
return name;
}
static std::string combineHier(const std::string& old, const std::string& add) VL_PURE {
@@ -253,6 +255,7 @@ private:
public:
// PUBLIC METHODS
std::string defaultFilename() VL_MT_SAFE { return m_contextp->coverageFilename(); }
void forcePerInstance(const bool flag) VL_MT_SAFE_EXCLUDES(m_mutex) {
Verilated::quiesce();
const VerilatedLockGuard lock{m_mutex};
@@ -302,7 +305,7 @@ public:
// First two key/vals are filename
ckeyps[0] = "filename";
valps[0] = m_insertFilenamep;
const std::string linestr = vlCovCvtToStr(m_insertLineno);
const std::string linestr = std::to_string(m_insertLineno);
ckeyps[1] = "lineno";
valps[1] = linestr.c_str();
// Default page if not specified
@@ -354,14 +357,14 @@ public:
m_insertp = nullptr;
}
void write(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
void write(const std::string& filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
Verilated::quiesce();
const VerilatedLockGuard lock{m_mutex};
selftest();
std::ofstream os{filename};
if (os.fail()) {
const std::string msg = std::string{"%Error: Can't write '"} + filename + "'";
const std::string msg = "%Error: Can't write '"s + filename + "'";
VL_FATAL_MT("", 0, "", msg.c_str());
return;
}
@@ -426,6 +429,7 @@ public:
//=============================================================================
// VerilatedCovContext
std::string VerilatedCovContext::defaultFilename() VL_MT_SAFE { return impp()->defaultFilename(); }
void VerilatedCovContext::forcePerInstance(bool flag) VL_MT_SAFE {
impp()->forcePerInstance(flag);
}
@@ -434,7 +438,9 @@ void VerilatedCovContext::clearNonMatch(const char* matchp) VL_MT_SAFE {
impp()->clearNonMatch(matchp);
}
void VerilatedCovContext::zero() VL_MT_SAFE { impp()->zero(); }
void VerilatedCovContext::write(const char* filenamep) VL_MT_SAFE { impp()->write(filenamep); }
void VerilatedCovContext::write(const std::string& filename) VL_MT_SAFE {
impp()->write(filename);
}
void VerilatedCovContext::_inserti(uint32_t* itemp) VL_MT_SAFE {
impp()->inserti(new VerilatedCoverItemSpec<uint32_t>{itemp});
}
@@ -484,8 +490,8 @@ void VerilatedCovContext::_insertp(A(0), A(1), A(2), A(3), A(4), A(5), A(6), A(7
// Backward compatibility for Verilator
void VerilatedCovContext::_insertp(A(0), A(1), K(2), int val2, K(3), int val3, K(4),
const std::string& val4, A(5), A(6), A(7)) VL_MT_SAFE {
std::string val2str = vlCovCvtToStr(val2);
std::string val3str = vlCovCvtToStr(val3);
const std::string val2str = std::to_string(val2);
const std::string val3str = std::to_string(val3);
_insertp(C(0), C(1), key2, val2str.c_str(), key3, val3str.c_str(), key4, val4.c_str(), C(5),
C(6), C(7), N(8), N(9), N(10), N(11), N(12), N(13), N(14), N(15), N(16), N(17), N(18),
N(19), N(20), N(21), N(22), N(23), N(24), N(25), N(26), N(27), N(28), N(29));
@@ -516,7 +522,7 @@ VerilatedCovContext* VerilatedContext::coveragep() VL_MT_SAFE {
const VerilatedLockGuard lock{s_mutex};
// cppcheck-suppress identicalInnerCondition
if (VL_LIKELY(!m_coveragep)) { // LCOV_EXCL_LINE // Not redundant, prevents race
m_coveragep.reset(new VerilatedCovImp);
m_coveragep.reset(new VerilatedCovImp{this});
}
}
return reinterpret_cast<VerilatedCovContext*>(m_coveragep.get());
+14 -22
View File
@@ -63,26 +63,18 @@ class VerilatedCovImp;
/// for (int i = 0; i < 10; ++i) m_cases[i] = 0;
/// // Insert
/// for (int i = 0; i < 10; ++i)
/// VL_COVER_INSERT(&m_cases[i], "comment", "Coverage Case", "i", cvtToNumStr(i));
/// VL_COVER_INSERT(covp, name(), &m_cases[i], "comment", "Coverage Case",
/// "i", cvtToNumStr(i));
/// }
#define VL_COVER_INSERT(covcontextp, countp, ...) \
#define VL_COVER_INSERT(covcontextp, name, countp, ...) \
do { \
covcontextp->_inserti(countp); \
covcontextp->_insertf(__FILE__, __LINE__); \
covcontextp->_insertp("hier", name(), __VA_ARGS__); \
auto const ccontextp = covcontextp; \
ccontextp->_inserti(countp); \
ccontextp->_insertf(__FILE__, __LINE__); \
ccontextp->_insertp("hier", name, __VA_ARGS__); \
} while (false)
//=============================================================================
// Convert VL_COVER_INSERT value arguments to strings, is \internal
template <class T>
std::string vlCovCvtToStr(const T& t) VL_PURE {
std::ostringstream os;
os << t;
return os.str();
}
//=============================================================================
// VerilatedCov
/// Per-VerilatedContext coverage data class.
@@ -96,12 +88,13 @@ class VerilatedCovContext VL_NOT_FINAL : public VerilatedVirtualBase {
public:
// METHODS
/// Return default filename
static const char* defaultFilename() VL_PURE { return "coverage.dat"; }
/// Return default filename, may override with +verilator+coverage+file
std::string defaultFilename() VL_MT_SAFE;
/// Make all data per_instance, overriding point's per_instance
void forcePerInstance(bool flag) VL_MT_SAFE;
/// Write all coverage data to a file
void write(const char* filenamep = defaultFilename()) VL_MT_SAFE;
void write(const std::string& filename) VL_MT_SAFE;
void write() VL_MT_SAFE { write(defaultFilename()); }
/// Clear coverage points (and call delete on all items)
void clear() VL_MT_SAFE;
/// Clear items not matching the provided string
@@ -170,11 +163,10 @@ class VerilatedCov final {
public:
// METHODS
/// Return default filename for the current thread
static const char* defaultFilename() VL_PURE { return VerilatedCovContext::defaultFilename(); }
static std::string defaultFilename() VL_MT_SAFE { return threadCovp()->defaultFilename(); }
/// Write all coverage data to a file for the current thread
static void write(const char* filenamep = defaultFilename()) VL_MT_SAFE {
threadCovp()->write(filenamep);
}
static void write(const std::string& filename) VL_MT_SAFE { threadCovp()->write(filename); }
static void write() VL_MT_SAFE { write(defaultFilename()); }
/// Clear coverage points (and call delete on all items) for the current thread
static void clear() VL_MT_SAFE { threadCovp()->clear(); }
/// Clear items not matching the provided string for the current thread
+30
View File
@@ -770,6 +770,36 @@ int svGetCallerInfo(const char** fileNamepp, int* lineNumberp) {
return true;
}
//======================================================================
// Time
int svGetTime(const svScope scope, svTimeVal* time) {
if (VL_UNLIKELY(!time)) return -1;
const QData qtime = VL_TIME_Q();
VlWide<2> itime;
VL_SET_WQ(itime, qtime);
time->low = itime[0];
time->high = itime[1];
return 0;
}
int svGetTimeUnit(const svScope scope, int32_t* time_unit) {
if (VL_UNLIKELY(!time_unit)) return -1;
const VerilatedScope* const vscopep = reinterpret_cast<const VerilatedScope*>(scope);
if (!vscopep) { // Null asks for global, not unlikely
*time_unit = Verilated::threadContextp()->timeunit();
} else {
*time_unit = vscopep->timeunit();
}
return 0;
}
int svGetTimePrecision(const svScope scope, int32_t* time_precision) {
if (VL_UNLIKELY(!time_precision)) return -1;
*time_precision = Verilated::threadContextp()->timeprecision();
return 0;
}
//======================================================================
// Disables
+2 -1
View File
@@ -29,6 +29,7 @@
// GTKWave configuration
#define HAVE_LIBPTHREAD
#define FST_WRITER_PARALLEL
#define LZ4_DISABLE_DEPRECATE_WARNINGS
// Include the GTKWave implementation directly
#define FST_CONFIG_INCLUDE "fst_config.h"
@@ -174,7 +175,7 @@ void VerilatedFst::declare(uint32_t code, const char* name, int dtypenum,
if (dtypenum > 0) fstWriterEmitEnumTableRef(m_fst, m_local2fstdtype[dtypenum]);
fstVarDir varDir;
fstVarDir varDir = FST_VD_IMPLICIT;
switch (direction) {
case VerilatedTraceSigDirection::INOUT: varDir = FST_VD_INOUT; break;
case VerilatedTraceSigDirection::OUTPUT: varDir = FST_VD_OUTPUT; break;
+6 -3
View File
@@ -192,7 +192,7 @@ class VerilatedFstBuffer VL_NOT_FINAL {
/// Create a FST dump file in C standalone (no SystemC) simulations.
/// Also derived for use in SystemC simulations.
class VerilatedFstC VL_NOT_FINAL {
class VerilatedFstC VL_NOT_FINAL : public VerilatedTraceBaseC {
VerilatedFst m_sptrace; // Trace file being created
// CONSTRUCTORS
@@ -208,11 +208,14 @@ public:
// METHODS - User called
/// Return if file is open
bool isOpen() const VL_MT_SAFE { return m_sptrace.isOpen(); }
bool isOpen() const override VL_MT_SAFE { return m_sptrace.isOpen(); }
/// Open a new FST file
virtual void open(const char* filename) VL_MT_SAFE { m_sptrace.open(filename); }
/// Close dump
void close() VL_MT_SAFE { m_sptrace.close(); }
void close() VL_MT_SAFE {
m_sptrace.close();
modelConnected(false);
}
/// Flush dump
void flush() VL_MT_SAFE { m_sptrace.flush(); }
/// Write one cycle of dump data
+184 -27
View File
@@ -115,6 +115,9 @@ extern void VL_PRINTTIMESCALE(const char* namep, const char* timeunitp,
extern WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP const lwp, WDataInP const rwp,
bool is_modulus) VL_MT_SAFE;
extern void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp,
size_t posstart, size_t posend) VL_MT_SAFE;
extern IData VL_FGETS_IXI(int obits, void* destp, IData fpi) VL_MT_SAFE;
extern void VL_FFLUSH_I(IData fdi) VL_MT_SAFE;
@@ -125,25 +128,34 @@ extern void VL_FCLOSE_I(IData fdi) VL_MT_SAFE;
extern IData VL_FREAD_I(int width, int array_lsb, int array_size, void* memp, IData fpi,
IData start, IData count) VL_MT_SAFE;
extern void VL_WRITEF(const char* formatp, ...) VL_MT_SAFE;
extern void VL_FWRITEF(IData fpi, const char* formatp, ...) VL_MT_SAFE;
extern void VL_WRITEF_NX(const std::string& format, int argc, ...) VL_MT_SAFE;
extern void VL_FWRITEF_NX(IData fpi, const std::string& format, int argc, ...) VL_MT_SAFE;
extern IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) VL_MT_SAFE;
extern IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) VL_MT_SAFE;
extern IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...) VL_MT_SAFE;
extern IData VL_SSCANF_IWX(int lbits, WDataInP const lwp, const char* formatp, ...) VL_MT_SAFE;
extern IData VL_FSCANF_INX(IData fpi, const std::string& format, int argc, ...) VL_MT_SAFE;
extern IData VL_SSCANF_IINX(int lbits, IData ld, const std::string& format, int argc,
...) VL_MT_SAFE;
extern IData VL_SSCANF_IQNX(int lbits, QData ld, const std::string& format, int argc,
...) VL_MT_SAFE;
extern IData VL_SSCANF_IWNX(int lbits, WDataInP const lwp, const std::string& format, int argc,
...) VL_MT_SAFE;
extern void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) VL_MT_SAFE;
extern void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...) VL_MT_SAFE;
extern void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...) VL_MT_SAFE;
extern void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...) VL_MT_SAFE;
extern void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) VL_MT_SAFE;
extern void VL_SFORMAT_NX(int obits, CData& destr, const std::string& format, int argc,
...) VL_MT_SAFE;
extern void VL_SFORMAT_NX(int obits, SData& destr, const std::string& format, int argc,
...) VL_MT_SAFE;
extern void VL_SFORMAT_NX(int obits, IData& destr, const std::string& format, int argc,
...) VL_MT_SAFE;
extern void VL_SFORMAT_NX(int obits, QData& destr, const std::string& format, int argc,
...) VL_MT_SAFE;
extern void VL_SFORMAT_NX(int obits, void* destp, const std::string& format, int argc,
...) VL_MT_SAFE;
extern void VL_STACKTRACE() VL_MT_SAFE;
extern std::string VL_STACKTRACE_N() VL_MT_SAFE;
extern IData VL_SYSTEM_IW(int lhswords, WDataInP const lhsp) VL_MT_SAFE;
extern IData VL_SYSTEM_IQ(QData lhs) VL_MT_SAFE;
inline IData VL_SYSTEM_II(IData lhs) VL_MT_SAFE { return VL_SYSTEM_IQ(lhs); }
extern IData VL_SYSTEM_IN(const std::string& lhs) VL_MT_SAFE;
extern IData VL_TESTPLUSARGS_I(const std::string& format) VL_MT_SAFE;
extern const char* vl_mc_scan_plusargs(const char* prefixp) VL_MT_SAFE; // PLIish
@@ -207,6 +219,10 @@ static inline QData VL_CVT_Q_D(double lhs) VL_PURE {
return u.q;
}
// clang-format on
// Return string from DPI char*
static inline std::string VL_CVT_N_CSTR(const char* lhsp) VL_PURE {
return lhsp ? std::string{lhsp} : ""s;
}
// Return double from lhs (numeric) unsigned
double VL_ITOR_D_W(int lbits, WDataInP const lwp) VL_PURE;
@@ -230,7 +246,7 @@ static inline double VL_ISTOR_D_Q(int lbits, QData lhs) VL_MT_SAFE {
VL_SET_WQ(lwp, lhs);
return VL_ISTOR_D_W(lbits, lwp);
}
// Return QData from double (numeric)
// Return IData truncated from double (numeric)
static inline IData VL_RTOI_I_D(double lhs) VL_PURE { return static_cast<int32_t>(VL_TRUNC(lhs)); }
// Sign extend such that if MSB set, we get ffff_ffff, else 0s
@@ -255,7 +271,7 @@ static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) VL_PURE {
extern void _vl_debug_print_w(int lbits, WDataInP const iwp) VL_MT_SAFE;
//=========================================================================
// Pli macros
// Time handling
// clang-format off
@@ -305,13 +321,16 @@ uint64_t VerilatedContext::time() const VL_MT_SAFE {
// Time scaled from 1-per-precision into a module's time units ("Unit"-ed, not "United")
// Optimized assuming scale is always constant.
// Can't use multiply in Q flavor, as might lose precision
#define VL_TIME_UNITED_Q(scale) (VL_TIME_Q() / static_cast<QData>(scale))
#define VL_TIME_ROUND(t, p) (((t) + ((p) / 2)) / (p))
#define VL_TIME_UNITED_Q(scale) VL_TIME_ROUND(VL_TIME_Q(), static_cast<QData>(scale))
#define VL_TIME_UNITED_D(scale) (VL_TIME_D() / static_cast<double>(scale))
// Return time precision as multiplier of time units
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;
// Return time as string with timescale suffix
std::string vl_timescaled_double(double value, const char* format = "%0.0f%s") VL_PURE;
//=========================================================================
// Functional macros/routines
@@ -493,24 +512,24 @@ static inline void VL_ASSIGNBIT_WO(int bit, WDataOutP owp) VL_MT_SAFE {
{ (svar).write(rd); }
#define VL_ASSIGN_SBQ(obits, svar, rd) \
{ (svar).write(rd); }
#define VL_SC_BITS_PER_DIGIT 30 // This comes from sc_nbdefs.h BITS_PER_DIGIT
#define VL_ASSIGN_SBW(obits, svar, rwp) \
{ \
sc_dt::sc_biguint<(obits)> _butemp; \
int32_t lsb = 0; \
uint32_t* chunkp = _butemp.get_raw(); \
while (lsb + VL_SC_BITS_PER_DIGIT < (obits)) { \
while (lsb + BITS_PER_DIGIT < (obits)) { \
static_assert(std::is_same<IData, EData>::value, "IData and EData mismatch"); \
const uint32_t data = VL_SEL_IWII(lsb + VL_SC_BITS_PER_DIGIT + 1, (rwp).data(), lsb, \
VL_SC_BITS_PER_DIGIT); \
*chunkp = data & VL_MASK_E(VL_SC_BITS_PER_DIGIT); \
const uint32_t data \
= VL_SEL_IWII(lsb + BITS_PER_DIGIT + 1, (rwp).data(), lsb, BITS_PER_DIGIT); \
*chunkp = data & VL_MASK_E(BITS_PER_DIGIT); \
++chunkp; \
lsb += VL_SC_BITS_PER_DIGIT; \
lsb += BITS_PER_DIGIT; \
} \
if (lsb < (obits)) { \
const uint32_t msb_data = VL_SEL_IWII((obits) + 1, (rwp).data(), lsb, (obits)-lsb); \
*chunkp = msb_data & VL_MASK_E((obits)-lsb); \
} \
_butemp.set(0, *(rwp).data() & 1); /* force update the sign */ \
(svar).write(_butemp); \
}
@@ -1265,6 +1284,7 @@ static inline void _vl_insert_QQ(QData& lhsr, QData ld, int hbit, int lbit, int
}
static inline void _vl_insert_WI(WDataOutP iowp, IData ld, int hbit, int lbit,
int rbits = 0) VL_MT_SAFE {
// Insert value ld into iowp at bit slice [hbit:lbit]. iowp is rbits wide.
const int hoffset = VL_BITBIT_E(hbit);
const int loffset = VL_BITBIT_E(lbit);
const int roffset = VL_BITBIT_E(rbits);
@@ -1275,7 +1295,7 @@ static inline void _vl_insert_WI(WDataOutP iowp, IData ld, int hbit, int lbit,
if (hoffset == VL_SIZEBITS_E && loffset == 0) {
// Fast and common case, word based insertion
iowp[VL_BITWORD_E(lbit)] = ld & cleanmask;
iowp[lword] = ld & cleanmask;
} else {
const EData lde = static_cast<EData>(ld);
if (hword == lword) { // know < EData bits because above checks it
@@ -1288,12 +1308,36 @@ static inline void _vl_insert_WI(WDataOutP iowp, IData ld, int hbit, int lbit,
const EData linsmask = (VL_MASK_E((VL_EDATASIZE - 1) - loffset + 1)) << loffset;
const int nbitsonright = VL_EDATASIZE - loffset; // bits that end up in lword
iowp[lword] = (iowp[lword] & ~linsmask) | ((lde << loffset) & linsmask);
iowp[hword]
= (iowp[hword] & ~hinsmask) | ((lde >> nbitsonright) & (hinsmask & cleanmask));
// Prevent unsafe write where lword was final writable location and hword is
// out-of-bounds.
if (VL_LIKELY(!(hword == rword && roffset == 0))) {
iowp[hword]
= (iowp[hword] & ~hinsmask) | ((lde >> nbitsonright) & (hinsmask & cleanmask));
}
}
}
}
// Copy bits from lwp[hbit:lbit] to low bits of lhsr. rbits is real width of lshr
static inline void _vl_insert_IW(IData& lhsr, WDataInP const lwp, int hbit, int lbit,
int rbits = 0) VL_MT_SAFE {
const int hoffset = VL_BITBIT_E(hbit);
const int loffset = VL_BITBIT_E(lbit);
const int hword = VL_BITWORD_E(hbit);
const int lword = VL_BITWORD_E(lbit);
const IData cleanmask = VL_MASK_I(rbits);
if (hword == lword) {
const IData insmask = (VL_MASK_I(hoffset - loffset + 1));
lhsr = (lhsr & ~insmask) | ((lwp[lword] >> loffset) & (insmask & cleanmask));
} else {
const int nbitsonright = VL_IDATASIZE - loffset; // bits that filled by lword
const IData hinsmask = (VL_MASK_E(hoffset - 0 + 1)) << nbitsonright;
const IData linsmask = VL_MASK_E(VL_EDATASIZE - loffset);
lhsr = (lhsr & ~linsmask) | ((lwp[lword] >> loffset) & (linsmask & cleanmask));
lhsr = (lhsr & ~hinsmask) | ((lwp[hword] << nbitsonright) & (hinsmask & cleanmask));
}
}
// INTERNAL: Stuff large LHS bit 0++ into OUTPUT at specified offset
// lwp may be "dirty"
static inline void _vl_insert_WW(WDataOutP iowp, WDataInP const lwp, int hbit, int lbit,
@@ -1541,6 +1585,13 @@ static inline void VL_ASSIGN_DYN_Q(VlQueue<T>& q, int elem_size, int lbits, QDat
for (int i = 0; i < size; ++i) q.at(i) = (T)((from >> (i * elem_size)) & mask);
}
template <typename T, std::size_t T_Depth>
static inline void VL_ASSIGN_UNPACK_Q(VlUnpacked<T, T_Depth>& q, size_t elem_size, QData from) {
const QData mask = VL_MASK_Q(elem_size);
for (size_t i = 0; i < T_Depth; ++i)
q[i] = (T)((from >> ((T_Depth - 1 - i) * elem_size)) & mask);
}
template <typename T>
static inline IData VL_DYN_TO_I(const VlQueue<T>& q, int elem_size) {
IData ret = 0;
@@ -1555,6 +1606,20 @@ static inline QData VL_DYN_TO_Q(const VlQueue<T>& q, int elem_size) {
return ret;
}
template <typename T, std::size_t T_Depth>
static inline IData VL_UNPACK_TO_I(const VlUnpacked<T, T_Depth>& q, size_t elem_size) {
IData ret = 0;
for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * elem_size);
return ret;
}
template <typename T, std::size_t T_Depth>
static inline QData VL_UNPACK_TO_Q(const VlUnpacked<T, T_Depth>& q, size_t elem_size) {
QData ret = 0;
for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * elem_size);
return ret;
}
// Because concats are common and wide, it's valuable to always have a clean output.
// Thus we specify inputs must be clean, so we don't need to clean the output.
// Note the bit shifts are always constants, so the adds in these constify out.
@@ -2068,6 +2133,97 @@ static inline void VL_ASSIGNSEL_WW(int rbits, int obits, int lsb, WDataOutP iowp
_vl_insert_WW(iowp, rwp, lsb + obits - 1, lsb, rbits);
}
//====================================================
// Range assignments
// These additional functions copy bits range [obis+roffset-1:roffset] from rhs to lower bits
// of lhs(select before assigning). Rhs should always be wider than lhs.
static inline void VL_SELASSIGN_II(int rbits, int obits, CData& lhsr, IData rhs,
int roffset) VL_PURE {
_vl_insert_II(lhsr, rhs >> roffset, obits - 1, 0, rbits);
}
static inline void VL_SELASSIGN_II(int rbits, int obits, SData& lhsr, IData rhs,
int roffset) VL_PURE {
_vl_insert_II(lhsr, rhs >> roffset, obits - 1, 0, rbits);
}
static inline void VL_SELASSIGN_II(int rbits, int obits, IData& lhsr, IData rhs,
int roffset) VL_PURE {
_vl_insert_II(lhsr, rhs >> roffset, obits - 1, 0, rbits);
}
static inline void VL_SELASSIGN_IQ(int rbits, int obits, CData& lhsr, QData rhs,
int roffset) VL_PURE {
// it will be truncated to right CData mask
const CData cleanmask = VL_MASK_I(rbits);
const CData insmask = VL_MASK_I(obits);
lhsr = (lhsr & ~insmask) | (static_cast<CData>(rhs >> roffset) & (insmask & cleanmask));
}
static inline void VL_SELASSIGN_IQ(int rbits, int obits, SData& lhsr, QData rhs,
int roffset) VL_PURE {
// it will be truncated to right CData mask
const SData cleanmask = VL_MASK_I(rbits);
const SData insmask = VL_MASK_I(obits);
lhsr = (lhsr & ~insmask) | (static_cast<SData>(rhs >> roffset) & (insmask & cleanmask));
}
static inline void VL_SELASSIGN_IQ(int rbits, int obits, IData& lhsr, QData rhs,
int roffset) VL_PURE {
const IData cleanmask = VL_MASK_I(rbits);
const IData insmask = VL_MASK_I(obits);
lhsr = (lhsr & ~insmask) | (static_cast<IData>(rhs >> roffset) & (insmask & cleanmask));
}
static inline void VL_SELASSIGN_QQ(int rbits, int obits, QData& lhsr, QData rhs,
int roffset) VL_PURE {
_vl_insert_QQ(lhsr, rhs >> roffset, obits - 1, 0, rbits);
}
static inline void VL_SELASSIGN_IW(int rbits, int obits, CData& lhsr, WDataInP const rhs,
int roffset) VL_MT_SAFE {
IData l = static_cast<IData>(lhsr);
_vl_insert_IW(l, rhs, roffset + obits - 1, roffset, rbits);
lhsr = static_cast<CData>(l);
}
static inline void VL_SELASSIGN_IW(int rbits, int obits, SData& lhsr, WDataInP const rhs,
int roffset) VL_MT_SAFE {
IData l = static_cast<IData>(lhsr);
_vl_insert_IW(l, rhs, roffset + obits - 1, roffset, rbits);
lhsr = static_cast<SData>(l);
}
static inline void VL_SELASSIGN_IW(int rbits, int obits, IData& lhsr, WDataInP const rhs,
int roffset) VL_MT_SAFE {
_vl_insert_IW(lhsr, rhs, roffset + obits - 1, roffset, rbits);
}
static inline void VL_SELASSIGN_QW(int rbits, int obits, QData& lhsr, WDataInP const rhs,
int roffset) VL_MT_SAFE {
// assert VL_QDATASIZE >= rbits > VL_IDATASIZE;
IData low = static_cast<IData>(lhsr);
IData high = static_cast<IData>(lhsr >> VL_IDATASIZE);
if (obits <= VL_IDATASIZE) {
_vl_insert_IW(low, rhs, obits + roffset - 1, roffset, VL_IDATASIZE);
} else {
_vl_insert_IW(low, rhs, roffset + VL_IDATASIZE - 1, roffset, VL_IDATASIZE);
_vl_insert_IW(high, rhs, roffset + obits - 1, roffset + VL_IDATASIZE,
rbits - VL_IDATASIZE);
}
lhsr = (static_cast<QData>(high) << VL_IDATASIZE) | low;
}
static inline void VL_SELASSIGN_WW(int rbits, int obits, WDataOutP iowp, WDataInP const rwp,
int roffset) VL_MT_SAFE {
// assert rbits > VL_QDATASIZE
const int wordoff = roffset / VL_EDATASIZE;
const int lsb = roffset & VL_SIZEBITS_E;
const int upperbits = lsb == 0 ? 0 : VL_EDATASIZE - lsb;
// If roffset is not aligned, we copy some bits to align it.
if (lsb != 0) {
const int w = obits < upperbits ? obits : upperbits;
const int insmask = VL_MASK_E(w);
iowp[0] = (iowp[0] & ~insmask) | ((rwp[wordoff] >> lsb) & insmask);
if (w == obits) return;
obits -= w;
}
_vl_insert_WW(iowp, rwp + wordoff + (lsb != 0), upperbits + obits - 1, upperbits, rbits);
}
//======================================================================
// Triops
@@ -2284,10 +2440,11 @@ extern void VL_READMEM_N(bool hex, int bits, QData depth, int array_lsb,
extern void VL_WRITEMEM_N(bool hex, int bits, QData depth, int array_lsb,
const std::string& filename, const void* memp, QData start,
QData end) VL_MT_SAFE;
extern IData VL_SSCANF_INX(int lbits, const std::string& ld, const char* formatp, ...) VL_MT_SAFE;
extern void VL_SFORMAT_X(int obits_ignored, std::string& output, const char* formatp,
...) VL_MT_SAFE;
extern std::string VL_SFORMATF_NX(const char* formatp, ...) VL_MT_SAFE;
extern IData VL_SSCANF_INNX(int lbits, const std::string& ld, const std::string& format, int argc,
...) VL_MT_SAFE;
extern void VL_SFORMAT_NX(int obits_ignored, std::string& output, const std::string& format,
int argc, ...) VL_MT_SAFE;
extern std::string VL_SFORMATF_N_NX(const std::string& format, int argc, ...) VL_MT_SAFE;
extern void VL_TIMEFORMAT_IINI(int units, int precision, const std::string& suffix, int width,
VerilatedContext* contextp) VL_MT_SAFE;
extern IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_MT_SAFE;
+4 -4
View File
@@ -54,7 +54,7 @@ class VerilatedScope;
class VerilatedMsg final {
public:
// TYPES
struct Cmp {
struct Cmp final {
bool operator()(const VerilatedMsg& a, const VerilatedMsg& b) const {
return a.mtaskId() < b.mtaskId();
}
@@ -221,7 +221,7 @@ class VerilatedContextImp final : VerilatedContext {
// Internal note: Globals may multi-construct, see verilated.cpp top.
// Medium speed, so uses singleton accessing
struct Statics {
struct Statics final {
VerilatedMutex s_randMutex; // Mutex protecting s_randSeedEpoch
// Number incrementing on each reseed, 0=illegal
int s_randSeedEpoch = 1; // Reads ok, wish had a VL_WRITE_GUARDED_BY(s_randMutex)
@@ -294,7 +294,7 @@ public: // But only for verilated*.cpp
std::fill(m_fdps.begin() + start, m_fdps.end(), static_cast<FILE*>(nullptr));
m_fdFree.resize(excess);
for (std::size_t i = 0, id = start; i < m_fdFree.size(); ++i, ++id) {
m_fdFree[i] = id;
m_fdFree[i] = static_cast<IData>(id);
}
}
const IData idx = m_fdFree.back();
@@ -552,7 +552,7 @@ public:
const VerilatedLockGuard lock{s().m_exportMutex};
const auto& it = s().m_exportMap.find(namep);
if (VL_LIKELY(it != s().m_exportMap.end())) return it->second;
const std::string msg = (std::string{"%Error: Testbench C called "} + namep
const std::string msg = ("%Error: Testbench C called "s + namep
+ " but no such DPI export function name exists in ANY model");
VL_FATAL_MT("unknown", 0, "", msg.c_str());
return -1;
+1 -1
View File
@@ -116,7 +116,7 @@ IData VL_DIST_ERLANG(IData& seedr, IData uk, IData umean) VL_MT_SAFE {
return 0;
}
double x = 1.0;
for (int32_t i = 1; i <= k; i++) { x = x * _vl_dbase_uniform(seedr, 0, 1); }
for (int32_t i = 1; i <= k; i++) x = x * _vl_dbase_uniform(seedr, 0, 1);
const double a = static_cast<double>(mean);
const double b = static_cast<double>(k);
double r = -a * log(x) / b;
+1 -1
View File
@@ -106,7 +106,7 @@ VerilatedVirtualBase* VlExecutionProfiler::construct(VerilatedContext& context)
if (VlThreadPool* const threadPoolp = static_cast<VlThreadPool*>(context.threadPoolp())) {
for (int i = 0; i < threadPoolp->numThreads(); ++i) {
// Data to pass to worker thread initialization
struct Data {
struct Data final {
VlExecutionProfiler* const selfp;
const uint32_t threadId;
} data{selfp, static_cast<uint32_t>(i + 1)};
+424
View File
@@ -0,0 +1,424 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Code available from: https://verilator.org
//
// Copyright 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 randomization implementation code
///
/// This file must be compiled and linked against all Verilated objects
/// that use randomization features.
///
/// See the internals documentation docs/internals.rst for details.
///
//=========================================================================
#include "verilated_random.h"
#include <iostream>
#include <sstream>
#include <streambuf>
#define _VL_SOLVER_HASH_LEN 1
#define _VL_SOLVER_HASH_LEN_TOTAL 4
// clang-format off
#if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
# define _VL_SOLVER_PIPE // Allow pipe SMT solving. Needs fork()
#endif
#ifdef _VL_SOLVER_PIPE
# include <sys/wait.h>
# include <fcntl.h>
#endif
#if defined(_WIN32) || defined(__MINGW32__)
# include <io.h> // open, read, write, close
#endif
// clang-format on
class Process final : private std::streambuf, public std::iostream {
static constexpr int BUFFER_SIZE = 4096;
const char* const* m_cmd = nullptr; // fork() process argv
#ifdef _VL_SOLVER_PIPE
pid_t m_pid = 0; // fork() process id
#else
int m_pid = 0; // fork() process id - always zero as disabled
#endif
bool m_pidExited = true; // If subprocess has exited and can be opened
int m_pidStatus = 0; // fork() process exit status, valid if m_pidExited
int m_writeFd = -1; // File descriptor TO subprocess
int m_readFd = -1; // File descriptor FROM subprocess
char m_readBuf[BUFFER_SIZE];
char m_writeBuf[BUFFER_SIZE];
public:
typedef std::streambuf::traits_type traits_type;
protected:
int overflow(int c = traits_type::eof()) override {
char c2 = static_cast<char>(c);
if (pbase() == pptr()) return 0;
size_t size = pptr() - pbase();
ssize_t n = ::write(m_writeFd, pbase(), size);
if (n == -1) perror("write");
if (n <= 0) {
wait_report();
return traits_type::eof();
}
if (n == size)
setp(m_writeBuf, m_writeBuf + sizeof(m_writeBuf));
else
setp(m_writeBuf + n, m_writeBuf + sizeof(m_writeBuf));
if (c != traits_type::eof()) sputc(c2);
return 0;
}
int underflow() override {
sync();
ssize_t n = ::read(m_readFd, m_readBuf, sizeof(m_readBuf));
if (n == -1) perror("read");
if (n <= 0) {
wait_report();
return traits_type::eof();
}
setg(m_readBuf, m_readBuf, m_readBuf + n);
return traits_type::to_int_type(m_readBuf[0]);
}
int sync() override {
overflow();
return 0;
}
public:
explicit Process(const char* const* const cmd = nullptr)
: std::streambuf{}
, std::iostream{this}
, m_cmd{cmd} {
open(cmd);
}
void wait_report() {
if (m_pidExited) return;
#ifdef _VL_SOLVER_PIPE
if (waitpid(m_pid, &m_pidStatus, 0) != m_pid) return;
if (m_pidStatus) {
std::stringstream msg;
msg << "Subprocess command `" << m_cmd[0];
for (const char* const* arg = m_cmd + 1; *arg; arg++) msg << ' ' << *arg;
msg << "' failed: ";
if (WIFSIGNALED(m_pidStatus))
msg << strsignal(WTERMSIG(m_pidStatus))
<< (WCOREDUMP(m_pidStatus) ? " (core dumped)" : "");
else if (WIFEXITED(m_pidStatus))
msg << "exit status " << WEXITSTATUS(m_pidStatus);
const std::string str = msg.str();
VL_WARN_MT("", 0, "Process", str.c_str());
}
#endif
m_pidExited = true;
m_pid = 0;
closeFds();
}
void closeFds() {
if (m_writeFd != -1) {
close(m_writeFd);
m_writeFd = -1;
}
if (m_readFd != -1) {
close(m_readFd);
m_readFd = -1;
}
}
bool open(const char* const* const cmd) {
setp(std::begin(m_writeBuf), std::end(m_writeBuf));
setg(m_readBuf, m_readBuf, m_readBuf);
#ifdef _VL_SOLVER_PIPE
if (!cmd || !cmd[0]) return false;
m_cmd = cmd;
int fd_stdin[2]; // Can't use std::array
int fd_stdout[2]; // Can't use std::array
constexpr int P_RD = 0;
constexpr int P_WR = 1;
if (pipe(fd_stdin) != 0) {
perror("Process::open: pipe");
return false;
}
if (pipe(fd_stdout) != 0) {
perror("Process::open: pipe");
close(fd_stdin[P_RD]);
close(fd_stdin[P_WR]);
return false;
}
if (fd_stdin[P_RD] <= 2 || fd_stdin[P_WR] <= 2 || fd_stdout[P_RD] <= 2
|| fd_stdout[P_WR] <= 2) {
// We'd have to rearrange all of the FD usages in this case.
// Too unlikely; verilator isn't a daemon.
fprintf(stderr, "stdin/stdout closed before pipe opened\n");
close(fd_stdin[P_RD]);
close(fd_stdin[P_WR]);
close(fd_stdout[P_RD]);
close(fd_stdout[P_WR]);
return false;
}
const pid_t pid = fork();
if (pid < 0) {
perror("Process::open: fork");
close(fd_stdin[P_RD]);
close(fd_stdin[P_WR]);
close(fd_stdout[P_RD]);
close(fd_stdout[P_WR]);
return false;
}
if (pid == 0) {
// Child
close(fd_stdin[P_WR]);
dup2(fd_stdin[P_RD], STDIN_FILENO);
close(fd_stdout[P_RD]);
dup2(fd_stdout[P_WR], STDOUT_FILENO);
execvp(cmd[0], const_cast<char* const*>(cmd));
std::stringstream msg;
msg << "Process::open: execvp(" << cmd[0] << ")";
const std::string str = msg.str();
perror(str.c_str());
_exit(127);
}
// Parent
m_pid = pid;
m_pidExited = false;
m_pidStatus = 0;
m_readFd = fd_stdout[P_RD];
m_writeFd = fd_stdin[P_WR];
close(fd_stdin[P_RD]);
close(fd_stdout[P_WR]);
return true;
#else
return false;
#endif
}
};
static Process& getSolver() {
static Process s_solver;
static bool s_done = false;
if (s_done) return s_solver;
s_done = true;
static std::vector<const char*> s_argv;
static std::string s_program = Verilated::threadContextp()->solverProgram();
s_argv.emplace_back(&s_program[0]);
for (char* arg = &s_program[0]; *arg; arg++) {
if (*arg == ' ') {
*arg = '\0';
s_argv.emplace_back(arg + 1);
}
}
s_argv.emplace_back(nullptr);
const char* const* const cmd = &s_argv[0];
s_solver.open(cmd);
s_solver << "(set-logic QF_BV)\n";
s_solver << "(check-sat)\n";
s_solver << "(reset)\n";
std::string s;
getline(s_solver, s);
if (s == "sat") return s_solver;
std::stringstream msg;
msg << "Unable to communicate with SAT solver, please check its installation or specify a "
"different one in VERILATOR_SOLVER environment variable.\n";
msg << " ... Tried: $";
for (const char* const* arg = cmd; *arg; arg++) msg << ' ' << *arg;
msg << '\n';
const std::string str = msg.str();
VL_WARN_MT("", 0, "randomize", str.c_str());
while (getline(s_solver, s)) {}
return s_solver;
}
//======================================================================
// VlRandomizer:: Methods
void VlRandomVar::emit(std::ostream& s) const { s << m_name; }
void VlRandomConst::emit(std::ostream& s) const {
s << "#b";
for (int i = 0; i < m_width; i++) s << (VL_BITISSET_Q(m_val, m_width - i - 1) ? '1' : '0');
}
void VlRandomBinOp::emit(std::ostream& s) const {
s << '(' << m_op << ' ';
m_lhs->emit(s);
s << ' ';
m_rhs->emit(s);
s << ')';
}
void VlRandomExtract::emit(std::ostream& s) const {
s << "((_ extract " << m_idx << ' ' << m_idx << ") ";
m_expr->emit(s);
s << ')';
}
bool VlRandomVar::set(std::string&& val) const {
VlWide<VL_WQ_WORDS_E> qowp;
VL_SET_WQ(qowp, 0ULL);
WDataOutP owp = qowp;
int obits = width();
if (obits > VL_QUADSIZE) owp = reinterpret_cast<WDataOutP>(datap());
int i;
for (i = 0; val[i] && val[i] != '#'; i++) {}
if (val[i++] != '#') return false;
switch (val[i++]) {
case 'b': _vl_vsss_based(owp, obits, 1, &val[i], 0, val.size() - i); break;
case 'o': _vl_vsss_based(owp, obits, 3, &val[i], 0, val.size() - i); break;
case 'h': // FALLTHRU
case 'x': _vl_vsss_based(owp, obits, 4, &val[i], 0, val.size() - i); break;
default:
VL_WARN_MT(__FILE__, __LINE__, "randomize",
"Internal: Unable to parse solver's randomized number");
return false;
}
if (obits <= VL_BYTESIZE) {
CData* const p = static_cast<CData*>(datap());
*p = VL_CLEAN_II(obits, obits, owp[0]);
} else if (obits <= VL_SHORTSIZE) {
SData* const p = static_cast<SData*>(datap());
*p = VL_CLEAN_II(obits, obits, owp[0]);
} else if (obits <= VL_IDATASIZE) {
IData* const p = static_cast<IData*>(datap());
*p = VL_CLEAN_II(obits, obits, owp[0]);
} else if (obits <= VL_QUADSIZE) {
QData* const p = static_cast<QData*>(datap());
*p = VL_CLEAN_QQ(obits, obits, VL_SET_QW(owp));
} else {
_vl_clean_inplace_w(obits, owp);
}
return true;
}
std::shared_ptr<const VlRandomExpr> VlRandomizer::randomConstraint(VlRNG& rngr, int bits) {
unsigned long long hash = VL_RANDOM_RNG_I(rngr) & ((1 << bits) - 1);
std::shared_ptr<const VlRandomExpr> concat = nullptr;
std::vector<std::shared_ptr<const VlRandomExpr>> varbits;
for (const auto& var : m_vars) {
for (int i = 0; i < var.second->width(); i++)
varbits.emplace_back(std::make_shared<const VlRandomExtract>(var.second, i));
}
for (int i = 0; i < bits; i++) {
std::shared_ptr<const VlRandomExpr> bit = nullptr;
for (unsigned j = 0; j * 2 < varbits.size(); j++) {
unsigned idx = j + VL_RANDOM_RNG_I(rngr) % (varbits.size() - j);
auto sel = varbits[idx];
std::swap(varbits[idx], varbits[j]);
bit = bit == nullptr ? sel : std::make_shared<const VlRandomBinOp>("bvxor", bit, sel);
}
concat = concat == nullptr ? bit
: std::make_shared<const VlRandomBinOp>("concat", concat, bit);
}
return std::make_shared<const VlRandomBinOp>(
"=", concat, std::make_shared<const VlRandomConst>(hash, bits));
}
bool VlRandomizer::next(VlRNG& rngr) {
if (m_vars.empty()) return true;
std::iostream& f = getSolver();
if (!f) return false;
f << "(set-option :produce-models true)\n";
f << "(set-logic QF_BV)\n";
for (const auto& var : m_vars) {
f << "(declare-fun " << var.second->name() << " () (_ BitVec " << var.second->width()
<< "))\n";
}
for (const std::string& constraint : m_constraints) { f << "(assert " << constraint << ")\n"; }
f << "(check-sat)\n";
bool sat = parseSolution(f);
if (!sat) {
f << "(reset)\n";
return false;
}
for (int i = 0; i < _VL_SOLVER_HASH_LEN_TOTAL && sat; i++) {
f << "(assert ";
randomConstraint(rngr, _VL_SOLVER_HASH_LEN)->emit(f);
f << ")\n";
f << "\n(check-sat)\n";
sat = parseSolution(f);
}
f << "(reset)\n";
return true;
}
bool VlRandomizer::parseSolution(std::iostream& f) {
std::string sat;
do { std::getline(f, sat); } while (sat == "");
if (sat == "unsat") return false;
if (sat != "sat") {
std::stringstream msg;
msg << "Internal: Solver error: " << sat;
const std::string str = msg.str();
VL_WARN_MT(__FILE__, __LINE__, "randomize", str.c_str());
return false;
}
f << "(get-value (";
for (const auto& var : m_vars) f << var.second->name() << ' ';
f << "))\n";
// Quasi-parse S-expression of the form ((x #xVALUE) (y #bVALUE) (z #xVALUE))
char c;
f >> c;
if (c != '(') {
VL_WARN_MT(__FILE__, __LINE__, "randomize",
"Internal: Unable to parse solver's response: invalid S-expression");
return false;
}
while (true) {
f >> c;
if (c == ')') break;
if (c != '(') {
VL_WARN_MT(__FILE__, __LINE__, "randomize",
"Internal: Unable to parse solver's response: invalid S-expression");
return false;
}
std::string name, value;
f >> name;
std::getline(f, value, ')');
auto it = m_vars.find(name);
if (it == m_vars.end()) continue;
it->second->set(std::move(value));
}
return true;
}
void VlRandomizer::hard(std::string&& constraint) {
m_constraints.emplace_back(std::move(constraint));
}
#ifdef VL_DEBUG
void VlRandomizer::dump() const {
for (const auto& var : m_vars) {
VL_PRINTF("Variable (%d): %s\n", var.second->width(), var.second->name());
}
for (const std::string& c : m_constraints) VL_PRINTF("Constraint: %s\n", c.c_str());
}
#endif
+120
View File
@@ -0,0 +1,120 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Code available from: https://verilator.org
//
// Copyright 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 randomization header
///
/// This file is included automatically by Verilator in some of the C++ files
/// it generates if randomization features are used.
///
/// This file is not part of the Verilated public-facing API.
/// It is only for internal use.
///
/// See the internals documentation docs/internals.rst for details.
///
//*************************************************************************
#ifndef VERILATOR_VERILATED_RANDOM_H_
#define VERILATOR_VERILATED_RANDOM_H_
#include "verilated.h"
//=============================================================================
// VlRandomExpr and subclasses represent expressions for the constraint solver.
class VlRandomExpr VL_NOT_FINAL {
public:
virtual void emit(std::ostream& s) const = 0;
};
class VlRandomVar final : public VlRandomExpr {
const char* const m_name; // Variable name
void* const m_datap; // Reference to variable data
const int m_width; // Variable width in bits
public:
VlRandomVar(const char* name, int width, void* datap)
: m_name{name}
, m_datap{datap}
, m_width{width} {}
const char* name() const { return m_name; }
int width() const { return m_width; }
void* datap() const { return m_datap; }
bool set(std::string&&) const;
void emit(std::ostream& s) const override;
};
class VlRandomConst final : public VlRandomExpr {
const QData m_val; // Constant value
const int m_width; // Constant width in bits
public:
VlRandomConst(QData val, int width)
: m_val{val}
, m_width{width} {
assert(width <= sizeof(m_val) * 8);
}
void emit(std::ostream& s) const override;
};
class VlRandomExtract final : public VlRandomExpr {
const std::shared_ptr<const VlRandomExpr> m_expr; // Sub-expression
const unsigned m_idx; // Extracted index
public:
VlRandomExtract(std::shared_ptr<const VlRandomExpr> expr, unsigned idx)
: m_expr{expr}
, m_idx{idx} {}
void emit(std::ostream& s) const override;
};
class VlRandomBinOp final : public VlRandomExpr {
const char* const m_op; // Binary operation identifier
const std::shared_ptr<const VlRandomExpr> m_lhs, m_rhs; // Sub-expressions
public:
VlRandomBinOp(const char* op, std::shared_ptr<const VlRandomExpr> lhs,
std::shared_ptr<const VlRandomExpr> rhs)
: m_op{op}
, m_lhs{lhs}
, m_rhs{rhs} {}
void emit(std::ostream& s) const override;
};
//=============================================================================
// VlRandomizer is the object holding constraints and variable references.
class VlRandomizer final {
// MEMBERS
std::vector<std::string> m_constraints; // Solver-dependent constraints
std::map<std::string, std::shared_ptr<const VlRandomVar>>
m_vars; // Solver-dependent variables
// PRIVATE METHODS
std::shared_ptr<const VlRandomExpr> randomConstraint(VlRNG& rngr, int bits);
bool parseSolution(std::iostream& file);
public:
// METHODS
// Finds the next solution satisfying the constraints
bool next(VlRNG& rngr);
template <typename T>
void write_var(T& var, int width, const char* name) {
auto it = m_vars.find(name);
if (it != m_vars.end()) return;
m_vars[name] = std::make_shared<const VlRandomVar>(name, width, &var);
}
void hard(std::string&& constraint);
#ifdef VL_DEBUG
void dump() const;
#endif
};
#endif // Guard
+1 -2
View File
@@ -114,8 +114,7 @@ void VerilatedDeserialize::trailer() VL_MT_UNSAFE_ONE {
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, std::strlen(VLTSAVE_TRAILER_STR)))) {
const std::string fn = filename();
const std::string msg
= std::string{"Can't deserialize; file has wrong end-of-file signature: "}
+ filename();
= "Can't deserialize; file has wrong end-of-file signature: "s + filename();
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
// Die before we close() as close would infinite loop
}
+44 -9
View File
@@ -24,8 +24,13 @@
#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
#if SYSTEMC_VERSION >= 20140417 && SYSTEMC_VERSION < 20231124
// SystemC's simulation phase callback introduced in 2.3.1, and removed since 3.0.0 (PubRev)
#define _VL_HAVE_SYSTEMC_PHASE_CALLBACK
#endif
#if SYSTEMC_VERSION >= 20231124
// SystemC's stage callback introduced in 3.0.0 (PubRev)
#define _VL_HAVE_SYSTEMC_STAGE_CALLBACK
#endif
//=============================================================================
@@ -49,6 +54,9 @@
/// instead.
class VerilatedScTraceBase VL_NOT_FINAL : private sc_core::sc_object,
#ifdef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
private sc_core::sc_stage_callback_if,
#endif
private sc_core::sc_trace_file {
bool m_enableDeltaCycles = false;
bool m_traceFileAdded = false;
@@ -56,8 +64,8 @@ class VerilatedScTraceBase VL_NOT_FINAL : private sc_core::sc_object,
public:
void enableDeltaCycles(bool flag = true) {
#ifndef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
using namespace sc_core;
#ifdef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
// 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
@@ -70,6 +78,13 @@ public:
}
// Restore the old handler
sc_report_handler::set_handler(oldHandler);
#endif
#ifdef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
if (flag) {
sc_register_stage_callback(*this, SC_POST_UPDATE);
} else {
sc_unregister_stage_callback(*this, SC_POST_UPDATE);
}
#endif
m_enableDeltaCycles = flag;
}
@@ -81,15 +96,22 @@ protected:
registerTraceCallback();
};
~VerilatedScTraceBase() override {
#if SYSTEMC_VERSION >= 20140417 // remove_trace_file added in 2.3.1
using namespace sc_core;
#ifdef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
// remove_trace_file added in 2.3.1 and removed in 3.0.0
// 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);
#else
(void)m_traceFileAdded;
#endif
#ifdef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
sc_unregister_stage_callback(*this, SC_PRE_TIMESTEP | SC_POST_UPDATE);
#endif
};
void registerTraceCallback() {
#ifndef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
using namespace sc_core;
#ifdef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
// 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
@@ -98,13 +120,18 @@ protected:
phase_cb_mask cb_mask = sc_object::register_simulation_phase_callback(SC_BEFORE_TIMESTEP);
if (cb_mask == SC_UNITIALIZED) {
#endif
#if SYSTEMC_VERSION < 20231124 // add_trace_file removed in 3.0.0
// Phase callback not enabled, use trace file instead
simcontext()->add_trace_file(this);
m_traceFileAdded = true;
#ifndef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
#endif
#ifdef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
}
// Restore the old handler
sc_report_handler::set_handler(oldHandler);
#endif
#ifdef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
sc_register_stage_callback(*this, SC_PRE_TIMESTEP);
#endif
}
static std::string getScTimeUnit() {
@@ -129,9 +156,13 @@ protected:
}
// METHODS - for SC kernel
#ifndef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
#ifdef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
// Override sc_object. Called if using phase callback
void simulation_phase_callback() final { cycle(); }
#endif
#ifdef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
// Override sc_stage_callback_if. Called if using stage callback
void stage_callback(const sc_core::sc_stage&) final { cycle(); }
#endif
// Override sc_trace_file. Called if using trace file
void cycle(bool delta_cycle) final {
@@ -155,6 +186,7 @@ private:
// SystemC 2.1.v1
void write_comment(const std::string&) override {}
void trace(sc_core::sc_trace_file*) const override {}
void trace(const unsigned int&, const std::string&, const char**) override {}
#define DECL_TRACE_METHOD_A(tp) \
@@ -205,8 +237,11 @@ private:
#undef DECL_TRACE_METHOD_B
};
#ifdef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
#undef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
#ifdef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
#undef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
#endif
#ifdef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
#undef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
#endif
#endif // Guard
+1 -1
View File
@@ -42,7 +42,7 @@
// Types
// Class to sort maps keyed by const char*'s
struct VerilatedCStrCmp {
struct VerilatedCStrCmp final {
bool operator()(const char* a, const char* b) const { return std::strcmp(a, b) < 0; }
};
+3 -3
View File
@@ -127,7 +127,7 @@ public:
class VlWorkerThread final {
private:
// TYPES
struct ExecRec {
struct ExecRec final {
VlExecFnp m_fnp = nullptr; // Function to execute
VlSelfP m_selfp = nullptr; // Symbol table to execute
bool m_evenCycle = false; // Even/odd for flag alternation
@@ -214,10 +214,10 @@ public:
~VlThreadPool() override;
// METHODS
int numThreads() const { return m_workers.size(); }
int numThreads() const { return static_cast<int>(m_workers.size()); }
VlWorkerThread* workerp(int index) {
assert(index >= 0);
assert(static_cast<size_t>(index) < m_workers.size());
assert(index < static_cast<int>(m_workers.size()));
return m_workers[index];
}
+11 -4
View File
@@ -59,7 +59,7 @@ void VlDelayScheduler::resume() {
#endif
bool resumed = false;
while (!m_queue.empty() && (m_queue.begin()->first == m_context.time())) {
while (!m_queue.empty() && (m_queue.cbegin()->first == m_context.time())) {
VlCoroutineHandle handle = std::move(m_queue.begin()->second);
m_queue.erase(m_queue.begin());
handle.resume();
@@ -67,9 +67,16 @@ void VlDelayScheduler::resume() {
}
if (!m_zeroDelayed.empty()) {
for (auto&& handle : m_zeroDelayed) handle.resume();
m_zeroDelayed.clear();
// First, we need to move the coroutines out of the queue, as a resumed coroutine can
// suspend on #0 again, adding itself to the queue, which can result in reallocating the
// queue mid-iteration.
// We swap with the m_zeroDlyResumed field to keep the allocated buffer.
m_zeroDlyResumed.swap(m_zeroDelayed);
for (auto&& handle : m_zeroDlyResumed) handle.resume();
m_zeroDlyResumed.clear();
resumed = true;
// We are now in the Active region, so any coroutines added to m_zeroDelayed in the
// meantime will have to wait until the next Inactive region.
}
if (!resumed) {
@@ -80,7 +87,7 @@ void VlDelayScheduler::resume() {
}
uint64_t VlDelayScheduler::nextTimeSlot() const {
if (!m_queue.empty()) return m_queue.begin()->first;
if (!m_queue.empty()) return m_queue.cbegin()->first;
if (m_zeroDelayed.empty())
VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: There is no next time slot scheduled");
return m_context.time();
+26 -19
View File
@@ -32,14 +32,18 @@
// clang-format off
// Some preprocessor magic to support both Clang and GCC coroutines with both libc++ and libstdc++
#if defined _LIBCPP_VERSION // libc++
# if __clang_major__ > 13 // Clang > 13 warns that coroutine types in std::experimental are deprecated
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-experimental-coroutine"
# if defined(__has_include) && !__has_include(<coroutine>) && __has_include(<experimental/coroutine>)
# if __clang_major__ > 13 // Clang > 13 warns that coroutine types in std::experimental are deprecated
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-experimental-coroutine"
# endif
# include <experimental/coroutine>
namespace std {
using namespace experimental; // Bring std::experimental into the std namespace
}
# else
# include <coroutine>
# endif
# include <experimental/coroutine>
namespace std {
using namespace experimental; // Bring std::experimental into the std namespace
}
#else
# 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++
@@ -165,6 +169,9 @@ class VlDelayScheduler final {
VerilatedContext& m_context;
VlDelayedCoroutineQueue m_queue; // Coroutines to be restored at a certain simulation time
std::vector<VlCoroutineHandle> m_zeroDelayed; // Coroutines waiting for #0
std::vector<VlCoroutineHandle> m_zeroDlyResumed; // Coroutines that waited for #0 and are
// to be resumed. Kept as a field to avoid
// reallocation.
public:
// CONSTRUCTORS
@@ -180,7 +187,7 @@ public:
bool empty() const { return m_queue.empty() && m_zeroDelayed.empty(); }
// Are there coroutines to resume at the current simulation time?
bool awaitingCurrentTime() const {
return (!m_queue.empty() && (m_queue.begin()->first <= m_context.time()))
return (!m_queue.empty() && (m_queue.cbegin()->first <= m_context.time()))
|| !m_zeroDelayed.empty();
}
#ifdef VL_DEBUG
@@ -189,13 +196,13 @@ public:
// Used by coroutines for co_awaiting a certain simulation time
auto delay(uint64_t delay, VlProcessRef process, const char* filename = VL_UNKNOWN,
int lineno = 0) {
struct Awaitable {
struct Awaitable final {
VlProcessRef process; // Data of the suspended process, null if not needed
VlDelayedCoroutineQueue& queue;
std::vector<VlCoroutineHandle>& queueZeroDelay;
uint64_t delay;
VlDelayPhase phase;
VlFileLineDebug fileline;
const uint64_t delay;
const VlDelayPhase phase;
const VlFileLineDebug fileline;
bool await_ready() const { return false; } // Always suspend
void await_suspend(std::coroutine_handle<> coro) {
@@ -208,7 +215,7 @@ public:
void await_resume() const {}
};
VlDelayPhase phase = (delay == 0) ? VlDelayPhase::INACTIVE : VlDelayPhase::ACTIVE;
const VlDelayPhase phase = (delay == 0) ? VlDelayPhase::INACTIVE : VlDelayPhase::ACTIVE;
#ifdef VL_DEBUG
if (phase == VlDelayPhase::INACTIVE) {
VL_WARN_MT(filename, lineno, VL_UNKNOWN,
@@ -260,7 +267,7 @@ public:
const char* filename = VL_UNKNOWN, int lineno = 0) {
VL_DEBUG_IF(VL_DBG_MSGF(" Suspending process waiting for %s at %s:%d\n",
eventDescription, filename, lineno););
struct Awaitable {
struct Awaitable final {
VlCoroutineVec& suspended; // Coros waiting on trigger
VlProcessRef process; // Data of the suspended process, null if not needed
VlFileLineDebug fileline;
@@ -308,7 +315,7 @@ class VlDynamicTriggerScheduler final {
// METHODS
auto awaitable(VlProcessRef process, VlCoroutineVec& queue, const char* filename, int lineno) {
struct Awaitable {
struct Awaitable final {
VlProcessRef process; // Data of the suspended process, null if not needed
VlCoroutineVec& suspended; // Coros waiting on trigger
VlFileLineDebug fileline;
@@ -362,7 +369,7 @@ public:
// VlForever is a helper awaitable type for suspending coroutines forever. Used for constant
// wait statements.
struct VlForever {
struct VlForever final {
bool await_ready() const { return false; } // Always suspend
void await_suspend(std::coroutine_handle<> coro) const { coro.destroy(); }
void await_resume() const {}
@@ -374,7 +381,7 @@ struct VlForever {
class VlForkSync final {
// VlJoin stores the handle of a suspended coroutine that did a fork..join or fork..join_any.
// If the counter reaches 0, the suspended coroutine shall be resumed.
struct VlJoin {
struct VlJoin final {
size_t m_counter = 0; // When reaches 0, resume suspended coroutine
VlCoroutineHandle m_susp; // Coroutine to resume
};
@@ -393,7 +400,7 @@ public:
assert(m_join);
VL_DEBUG_IF(
VL_DBG_MSGF(" Awaiting join of fork at: %s:%d\n", filename, lineno););
struct Awaitable {
struct Awaitable final {
VlProcessRef process; // Data of the suspended process, null if not needed
const std::shared_ptr<VlJoin> join; // Join to await on
VlFileLineDebug fileline;
@@ -415,7 +422,7 @@ public:
class VlCoroutine final {
private:
// TYPES
struct VlPromise {
struct VlPromise final {
std::coroutine_handle<> m_continuation; // Coroutine to resume after this one finishes
VlCoroutine* m_corop = nullptr; // Pointer to the coroutine return object
+27 -15
View File
@@ -30,8 +30,9 @@
#include <condition_variable>
#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <type_traits>
#include <map>
#include <set>
#include <vector>
#include <deque>
@@ -179,6 +180,21 @@ public:
, m_useFstWriterThread{useFstWriterThread} {}
};
//=============================================================================
// VerilatedTraceBaseC - base class of all Verilated*C trace classes
// Internal use only
class VerilatedTraceBaseC VL_NOT_FINAL {
bool m_modelConnected = false; // Model connected by calling Verilated::trace()
public:
/// True if file currently open
virtual bool isOpen() const VL_MT_SAFE = 0;
// internal use only
bool modelConnected() const VL_MT_SAFE { return m_modelConnected; }
void modelConnected(bool flag) VL_MT_SAFE { m_modelConnected = flag; }
};
//=============================================================================
// VerilatedTrace
@@ -204,16 +220,12 @@ private:
friend Buffer;
friend OffloadBuffer;
struct CallbackRecord {
// Note: would make these fields const, but some old STL implementations
// (the one in Ubuntu 14.04 with GCC 4.8.4 in particular) use the
// assignment operator on inserting into collections, so they don't work
// with const fields...
const union { // The callback
initCb_t m_initCb;
dumpCb_t m_dumpCb;
dumpOffloadCb_t m_dumpOffloadCb;
cleanupCb_t m_cleanupCb;
struct CallbackRecord final {
union { // The callback
const initCb_t m_initCb;
const dumpCb_t m_dumpCb;
const dumpOffloadCb_t m_dumpOffloadCb;
const cleanupCb_t m_cleanupCb;
};
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)
@@ -238,7 +250,7 @@ private:
bool m_offload = false; // Use the offload thread
bool m_parallel = false; // Use parallel tracing
struct ParallelWorkerData {
struct ParallelWorkerData final {
const dumpCb_t m_cb; // The callback
void* const m_userp; // The use pointer to pass to the callback
Buffer* const m_bufp; // The buffer pointer to pass to the callback
@@ -283,7 +295,7 @@ private:
uint64_t m_timeLastDump = 0; // Last time we did a dump
bool m_didSomeDump = false; // Did at least one dump (i.e.: m_timeLastDump is valid)
VerilatedContext* m_contextp = nullptr; // The context used by the traced models
std::unordered_set<const VerilatedModel*> m_models; // The collection of models being traced
std::set<const VerilatedModel*> m_models; // The collection of models being traced
void addCallbackRecord(std::vector<CallbackRecord>& cbVec, CallbackRecord&& cbRec)
VL_MT_SAFE_EXCLUDES(m_mutex);
@@ -582,7 +594,7 @@ public:
m_offloadBufferWritep[0] = (bits << 4) | VerilatedTraceOffloadCommand::CHG_WDATA;
m_offloadBufferWritep[1] = code;
m_offloadBufferWritep += 2;
for (int i = 0; i < (bits + 31) / 32; ++i) { *m_offloadBufferWritep++ = newvalp[i]; }
for (int i = 0; i < (bits + 31) / 32; ++i) *m_offloadBufferWritep++ = newvalp[i];
VL_DEBUG_IF(assert(m_offloadBufferWritep <= m_offloadBufferEndp););
}
void chgDouble(uint32_t code, double newval) {
+15 -24
View File
@@ -60,22 +60,6 @@ static double timescaleToDouble(const char* unitp) VL_PURE {
return value;
}
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-12) { suffixp = "ps"; value *= 1e12; }
else if (value >= 1e-15) { suffixp = "fs"; value *= 1e15; }
else if (value >= 1e-18) { suffixp = "as"; value *= 1e18; }
// clang-format on
char valuestr[100];
VL_SNPRINTF(valuestr, 100, "%0.0f%s", value, suffixp);
return valuestr; // Gets converted to string, so no ref to stack
}
//=========================================================================
// Buffer management
@@ -190,13 +174,16 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::offloadWorkerThreadMain() {
//===
// Rare commands
case VerilatedTraceOffloadCommand::TIME_CHANGE:
case VerilatedTraceOffloadCommand::TIME_CHANGE: {
VL_TRACE_OFFLOAD_DEBUG("Command TIME_CHANGE " << top);
readp -= 1; // No code in this command, undo increment
emitTimeChange(*reinterpret_cast<const uint64_t*>(readp));
const uint64_t timeui
= static_cast<uint64_t>(*reinterpret_cast<const uint32_t*>(readp)) << 32ULL
| static_cast<uint64_t>(*reinterpret_cast<const uint32_t*>(readp + 1));
emitTimeChange(timeui);
readp += 2;
continue;
}
case VerilatedTraceOffloadCommand::TRACE_BUFFER:
VL_TRACE_OFFLOAD_DEBUG("Command TRACE_BUFFER " << top);
readp -= 1; // No code in this command, undo increment
@@ -418,7 +405,7 @@ bool VerilatedTrace<VL_SUB_T, VL_BUF_T>::declCode(uint32_t code, const std::stri
template <>
std::string VerilatedTrace<VL_SUB_T, VL_BUF_T>::timeResStr() const {
return doubleToTimescale(m_timeRes);
return vl_timescaled_double(m_timeRes);
}
//=========================================================================
@@ -574,7 +561,10 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::dump(uint64_t timeui) VL_MT_SAFE_EXCLUD
// Tell worker to update time point
m_offloadBufferWritep[0] = VerilatedTraceOffloadCommand::TIME_CHANGE;
*reinterpret_cast<uint64_t*>(m_offloadBufferWritep + 1) = timeui;
*reinterpret_cast<uint32_t*>(m_offloadBufferWritep + 1)
= static_cast<uint32_t>(timeui >> 32ULL);
*reinterpret_cast<uint32_t*>(m_offloadBufferWritep + 2)
= static_cast<uint32_t>(timeui);
m_offloadBufferWritep += 3;
} else {
// Update time point
@@ -643,12 +633,13 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addModel(VerilatedModel* modelp)
// Validate
if (!newModel) { // LCOV_EXCL_START
VL_FATAL_MT(__FILE__, __LINE__, "",
"The same model has already been added to this trace file");
VL_FATAL_MT(
__FILE__, __LINE__, "",
"The same model has already been added to this trace file or VerilatedContext");
}
if (VL_UNCOVERABLE(m_contextp && contextp != m_contextp)) {
VL_FATAL_MT(__FILE__, __LINE__, "",
"A trace file instance can only handle models from the same context");
"A trace file instance can only handle models from the same VerilatedContext");
}
if (VL_UNCOVERABLE(m_didSomeDump)) {
VL_FATAL_MT(__FILE__, __LINE__, "",
+247 -50
View File
@@ -36,7 +36,6 @@
#include <memory>
#include <set>
#include <string>
#include <unordered_set>
#include <utility>
//=========================================================================
@@ -263,7 +262,7 @@ public:
inline std::string VL_TO_STRING(const VlEventBase& e);
inline std::string VL_TO_STRING(const VlEvent& e) {
return std::string{"triggered="} + (e.isTriggered() ? "true" : "false");
return "triggered="s + (e.isTriggered() ? "true" : "false");
}
inline std::string VL_TO_STRING(const VlAssignableEvent& e) {
@@ -274,7 +273,7 @@ inline std::string VL_TO_STRING(const VlEventBase& e) {
if (const VlAssignableEvent& assignable = dynamic_cast<const VlAssignableEvent&>(e)) {
return VL_TO_STRING(assignable);
}
return std::string{"triggered="} + (e.isTriggered() ? "true" : "false");
return "triggered="s + (e.isTriggered() ? "true" : "false");
}
//===================================================================
@@ -415,8 +414,20 @@ public:
static int _vl_cmp_w(int words, WDataInP const lwp, WDataInP const rwp) VL_PURE;
template <std::size_t T_Words>
struct VlWide;
// Type trait to check if a type is VlWide
template <typename>
struct VlIsVlWide : public std::false_type {};
template <std::size_t T_Words>
struct VlIsVlWide<VlWide<T_Words>> : public std::true_type {};
template <std::size_t T_Words>
struct VlWide final {
static constexpr size_t Words = T_Words;
// MEMBERS
// This should be the only data member, otherwise generated static initializers need updating
EData m_storage[T_Words]; // Contents of the packed array
@@ -615,7 +626,7 @@ public:
// inside (set membership operator)
bool inside(const T_Value& value) const {
return std::find(m_deque.begin(), m_deque.end(), value) != m_deque.end();
return std::find(m_deque.cbegin(), m_deque.cend(), value) != m_deque.cend();
}
// Return slice q[lsb:msb]
@@ -776,13 +787,13 @@ public:
// Reduction operators
VlQueue min() const {
if (m_deque.empty()) return VlQueue{};
const auto it = std::min_element(m_deque.begin(), m_deque.end());
const auto it = std::min_element(m_deque.cbegin(), m_deque.cend());
return VlQueue::cons(*it);
}
template <typename Func>
VlQueue min(Func with_func) const {
if (m_deque.empty()) return VlQueue{};
const auto it = std::min_element(m_deque.begin(), m_deque.end(),
const auto it = std::min_element(m_deque.cbegin(), m_deque.cend(),
[&with_func](const IData& a, const IData& b) {
return with_func(0, a) < with_func(0, b);
});
@@ -790,13 +801,13 @@ public:
}
VlQueue max() const {
if (m_deque.empty()) return VlQueue{};
const auto it = std::max_element(m_deque.begin(), m_deque.end());
const auto it = std::max_element(m_deque.cbegin(), m_deque.cend());
return VlQueue::cons(*it);
}
template <typename Func>
VlQueue max(Func with_func) const {
if (m_deque.empty()) return VlQueue{};
const auto it = std::max_element(m_deque.begin(), m_deque.end(),
const auto it = std::max_element(m_deque.cbegin(), m_deque.cend(),
[&with_func](const IData& a, const IData& b) {
return with_func(0, a) < with_func(0, b);
});
@@ -817,40 +828,40 @@ public:
}
T_Value r_product() const {
if (m_deque.empty()) return T_Value(0);
auto it = m_deque.begin();
auto it = m_deque.cbegin();
T_Value out{*it};
++it;
for (; it != m_deque.end(); ++it) out *= *it;
for (; it != m_deque.cend(); ++it) out *= *it;
return out;
}
template <typename Func>
T_Value r_product(Func with_func) const {
if (m_deque.empty()) return T_Value(0);
auto it = m_deque.begin();
auto it = m_deque.cbegin();
IData index = 0;
T_Value out{with_func(index, *it)};
++it;
++index;
for (; it != m_deque.end(); ++it) out *= with_func(index++, *it);
for (; it != m_deque.cend(); ++it) out *= with_func(index++, *it);
return out;
}
T_Value r_and() const {
if (m_deque.empty()) return T_Value(0);
auto it = m_deque.begin();
auto it = m_deque.cbegin();
T_Value out{*it};
++it;
for (; it != m_deque.end(); ++it) out &= *it;
for (; it != m_deque.cend(); ++it) out &= *it;
return out;
}
template <typename Func>
T_Value r_and(Func with_func) const {
if (m_deque.empty()) return T_Value(0);
auto it = m_deque.begin();
auto it = m_deque.cbegin();
IData index = 0;
T_Value out{with_func(index, *it)};
++it;
++index;
for (; it != m_deque.end(); ++it) out &= with_func(index, *it);
for (; it != m_deque.cend(); ++it) out &= with_func(index, *it);
return out;
}
T_Value r_or() const {
@@ -891,8 +902,8 @@ public:
}
};
template <class T_Value>
std::string VL_TO_STRING(const VlQueue<T_Value>& obj) {
template <class T_Value, size_t T_MaxSize>
std::string VL_TO_STRING(const VlQueue<T_Value, T_MaxSize>& obj) {
return obj.to_string();
}
@@ -948,7 +959,7 @@ public:
// Return last element. Verilog: function int last(ref index)
int last(T_Key& indexr) const {
const auto it = m_map.crbegin();
if (it == m_map.rend()) return 0;
if (it == m_map.crend()) return 0;
indexr = it->first;
return 1;
}
@@ -1077,7 +1088,7 @@ public:
template <typename Func>
VlQueue<T_Value> find_first(Func with_func) const {
const auto it
= std::find_if(m_map.begin(), m_map.end(), [=](const std::pair<T_Key, T_Value>& i) {
= std::find_if(m_map.cbegin(), m_map.cend(), [=](const std::pair<T_Key, T_Value>& i) {
return with_func(i.first, i.second);
});
if (it == m_map.end()) return VlQueue<T_Value>{};
@@ -1086,7 +1097,7 @@ public:
template <typename Func>
VlQueue<T_Key> find_first_index(Func with_func) const {
const auto it
= std::find_if(m_map.begin(), m_map.end(), [=](const std::pair<T_Key, T_Value>& i) {
= std::find_if(m_map.cbegin(), m_map.cend(), [=](const std::pair<T_Key, T_Value>& i) {
return with_func(i.first, i.second);
});
if (it == m_map.end()) return VlQueue<T_Value>{};
@@ -1094,19 +1105,17 @@ public:
}
template <typename Func>
VlQueue<T_Value> find_last(Func with_func) const {
const auto it
= std::find_if(m_map.rbegin(), m_map.rend(), [=](const std::pair<T_Key, T_Value>& i) {
return with_func(i.first, i.second);
});
const auto it = std::find_if(
m_map.crbegin(), m_map.crend(),
[=](const std::pair<T_Key, T_Value>& i) { return with_func(i.first, i.second); });
if (it == m_map.rend()) return VlQueue<T_Value>{};
return VlQueue<T_Value>::cons(it->second);
}
template <typename Func>
VlQueue<T_Key> find_last_index(Func with_func) const {
const auto it
= std::find_if(m_map.rbegin(), m_map.rend(), [=](const std::pair<T_Key, T_Value>& i) {
return with_func(i.first, i.second);
});
const auto it = std::find_if(
m_map.crbegin(), m_map.crend(),
[=](const std::pair<T_Key, T_Value>& i) { return with_func(i.first, i.second); });
if (it == m_map.rend()) return VlQueue<T_Value>{};
return VlQueue<T_Key>::cons(it->first);
}
@@ -1115,7 +1124,7 @@ public:
VlQueue<T_Value> min() const {
if (m_map.empty()) return VlQueue<T_Value>();
const auto it = std::min_element(
m_map.begin(), m_map.end(),
m_map.cbegin(), m_map.cend(),
[](const std::pair<T_Key, T_Value>& a, const std::pair<T_Key, T_Value>& b) {
return a.second < b.second;
});
@@ -1125,7 +1134,7 @@ public:
VlQueue<T_Value> min(Func with_func) const {
if (m_map.empty()) return VlQueue<T_Value>();
const auto it = std::min_element(
m_map.begin(), m_map.end(),
m_map.cbegin(), m_map.cend(),
[&with_func](const std::pair<T_Key, T_Value>& a, const std::pair<T_Key, T_Value>& b) {
return with_func(a.first, a.second) < with_func(b.first, b.second);
});
@@ -1134,7 +1143,7 @@ public:
VlQueue<T_Value> max() const {
if (m_map.empty()) return VlQueue<T_Value>();
const auto it = std::max_element(
m_map.begin(), m_map.end(),
m_map.cbegin(), m_map.cend(),
[](const std::pair<T_Key, T_Value>& a, const std::pair<T_Key, T_Value>& b) {
return a.second < b.second;
});
@@ -1144,7 +1153,7 @@ public:
VlQueue<T_Value> max(Func with_func) const {
if (m_map.empty()) return VlQueue<T_Value>();
const auto it = std::max_element(
m_map.begin(), m_map.end(),
m_map.cbegin(), m_map.cend(),
[&with_func](const std::pair<T_Key, T_Value>& a, const std::pair<T_Key, T_Value>& b) {
return with_func(a.first, a.second) < with_func(b.first, b.second);
});
@@ -1164,36 +1173,36 @@ public:
}
T_Value r_product() const {
if (m_map.empty()) return T_Value(0);
auto it = m_map.begin();
auto it = m_map.cbegin();
T_Value out{it->second};
++it;
for (; it != m_map.end(); ++it) out *= it->second;
for (; it != m_map.cend(); ++it) out *= it->second;
return out;
}
template <typename Func>
T_Value r_product(Func with_func) const {
if (m_map.empty()) return T_Value(0);
auto it = m_map.begin();
auto it = m_map.cbegin();
T_Value out{with_func(it->first, it->second)};
++it;
for (; it != m_map.end(); ++it) out *= with_func(it->first, it->second);
for (; it != m_map.cend(); ++it) out *= with_func(it->first, it->second);
return out;
}
T_Value r_and() const {
if (m_map.empty()) return T_Value(0);
auto it = m_map.begin();
auto it = m_map.cbegin();
T_Value out{it->second};
++it;
for (; it != m_map.end(); ++it) out &= it->second;
for (; it != m_map.cend(); ++it) out &= it->second;
return out;
}
template <typename Func>
T_Value r_and(Func with_func) const {
if (m_map.empty()) return T_Value(0);
auto it = m_map.begin();
auto it = m_map.cbegin();
T_Value out{with_func(it->first, it->second)};
++it;
for (; it != m_map.end(); ++it) out &= with_func(it->first, it->second);
for (; it != m_map.cend(); ++it) out &= with_func(it->first, it->second);
return out;
}
T_Value r_or() const {
@@ -1311,7 +1320,11 @@ public:
// Similar to 'neq' above, *this = that used for change detection
void assign(const VlUnpacked<T_Value, T_Depth>& that) { *this = that; }
bool operator==(const VlUnpacked<T_Value, T_Depth>& that) const { return !neq(that); }
bool operator!=(const VlUnpacked<T_Value, T_Depth>& that) { return neq(that); }
bool operator!=(const VlUnpacked<T_Value, T_Depth>& that) const { return neq(that); }
// interface to C style arrays (used in ports), see issue #5125
bool neq(const T_Value that[T_Depth]) const { return neq(*this, that); }
void assign(const T_Value that[T_Depth]) { std::copy_n(that, T_Depth, m_storage); }
void operator=(const T_Value that[T_Depth]) { assign(that); }
// inside (set membership operator)
bool inside(const T_Value& value) const {
@@ -1388,7 +1401,7 @@ public:
VlQueue<T_Key> unique_index(Func with_func) const {
VlQueue<T_Key> out;
IData index = 0;
std::unordered_set<T_Value> saw;
std::set<T_Value> saw;
for (const auto& i : m_storage) {
const auto i_mapped = with_func(index, i);
auto it = saw.find(i_mapped);
@@ -1501,6 +1514,15 @@ private:
return false;
}
template <typename T_Val, std::size_t T_Dep>
static bool neq(const VlUnpacked<T_Val, T_Dep>& a, const T_Val b[T_Dep]) {
for (size_t i = 0; i < T_Dep; ++i) {
// Recursive 'neq', in case T_Val is also a VlUnpacked<_, _>
if (neq(a.m_storage[i], b[i])) return true;
}
return false;
}
template <typename T_Other> //
static bool neq(const T_Other& a, const T_Other& b) {
// Base case (T_Other is not VlUnpacked<_, _>), fall back on !=
@@ -1513,6 +1535,181 @@ std::string VL_TO_STRING(const VlUnpacked<T_Value, T_Depth>& obj) {
return obj.to_string();
}
//===================================================================
// Helper to apply the given indices to a target expression
template <size_t Curr, size_t Rank, typename T_Target>
struct VlApplyIndices final {
VL_ATTR_ALWINLINE
static auto& apply(T_Target& target, const size_t* indicesp) {
return VlApplyIndices<Curr + 1, Rank, decltype(target[indicesp[Curr]])>::apply(
target[indicesp[Curr]], indicesp);
}
};
template <size_t Rank, typename T_Target>
struct VlApplyIndices<Rank, Rank, T_Target> final {
VL_ATTR_ALWINLINE
static T_Target& apply(T_Target& target, const size_t*) { return target; }
};
//===================================================================
// Commit queue for NBAs - currently only for unpacked arrays
//
// This data-structure is used to handle non-blocking assignments
// that might execute a variable number of times in a single
// evaluation. It has 2 operations:
// - 'enqueue' will add an update to the queue
// - 'commit' will apply all enqueued updates to the target variable,
// in the order they were enqueued. This ensures the last NBA
// takes effect as it is expected.
// There are 2 specializations of this class below:
// - A version when a partial element update is not required,
// e.g, to handle:
// logic [31:0] array[N];
// for (int i = 0 ; i < N ; ++i) array[i] <= x;
// Here 'enqueue' takes the RHS ('x'), and the array indices ('i')
// as arguments.
// - A different version when a partial element update is required,
// e.g. for:
// logic [31:0] array[N];
// for (int i = 0 ; i < N ; ++i) array[i][3:1] <= y;
// Here 'enqueue' takes one additional argument, which is a bitmask
// derived from the bit selects (_[3:1]), which masks the bits that
// need to be updated, and additionally the RHS is widened to a full
// element size, with the bits inserted into the masked region.
template <typename T_Target, // Type of the variable this commit queue updates
bool Partial, // Whether partial element updates are necessary
// The following we could figure out from 'T_Target using type traits, but passing
// explicitly to avoid template expansion, as Verilator already knows them
typename T_Element, // Non-array leaf element type of T_Target array
std::size_t T_Rank // Rank of T_Target (i.e.: how many dimensions it has)
>
class VlNBACommitQueue;
// Specialization for whole element updates only
template <typename T_Target, typename T_Element, std::size_t T_Rank>
class VlNBACommitQueue<T_Target, /* Partial: */ false, T_Element, T_Rank> final {
// TYPES
struct Entry final {
T_Element value;
size_t indices[T_Rank];
};
// STATE
std::vector<Entry> m_pending; // Pending updates, in program order
public:
// CONSTRUCTOR
VlNBACommitQueue() = default;
VL_UNCOPYABLE(VlNBACommitQueue);
// METHODS
template <typename... Args>
void enqueue(const T_Element& value, Args... indices) {
m_pending.emplace_back(Entry{value, {indices...}});
}
// Note: T_Commit might be different from T_Target. Specifically, when the signal is a
// top-level IO port, T_Commit will be a native C array, while T_Target, will be a VlUnpacked
template <typename T_Commit>
void commit(T_Commit& target) {
if (m_pending.empty()) return;
for (const Entry& entry : m_pending) {
VlApplyIndices<0, T_Rank, T_Commit>::apply(target, entry.indices) = entry.value;
}
m_pending.clear();
}
};
// With partial element updates
template <typename T_Target, typename T_Element, std::size_t T_Rank>
class VlNBACommitQueue<T_Target, /* Partial: */ true, T_Element, T_Rank> final {
// TYPES
struct Entry final {
T_Element value;
T_Element mask;
size_t indices[T_Rank];
};
// STATE
std::vector<Entry> m_pending; // Pending updates, in program order
// STATIC METHODS
// Binary & | ~ for elements to use for masking in partial updates. Sorry for the templates.
template <typename T>
VL_ATTR_ALWINLINE static typename std::enable_if<!VlIsVlWide<T>::value, T>::type
bAnd(const T& a, const T& b) {
return a & b;
}
template <typename T>
VL_ATTR_ALWINLINE static typename std::enable_if<VlIsVlWide<T>::value, T>::type
bAnd(const T& a, const T& b) {
T result;
for (size_t i = 0; i < T::Words; ++i) {
result.m_storage[i] = a.m_storage[i] & b.m_storage[i];
}
return result;
}
template <typename T>
VL_ATTR_ALWINLINE static typename std::enable_if<!VlIsVlWide<T>::value, T>::type
bOr(const T& a, const T& b) {
return a | b;
}
template <typename T>
VL_ATTR_ALWINLINE static typename std::enable_if<VlIsVlWide<T>::value, T>::type //
bOr(const T& a, const T& b) {
T result;
for (size_t i = 0; i < T::Words; ++i) {
result.m_storage[i] = a.m_storage[i] | b.m_storage[i];
}
return result;
}
template <typename T>
VL_ATTR_ALWINLINE static typename std::enable_if<!VlIsVlWide<T>::value, T>::type
bNot(const T& a) {
return ~a;
}
template <typename T>
VL_ATTR_ALWINLINE static typename std::enable_if<VlIsVlWide<T>::value, T>::type
bNot(const T& a) {
T result;
for (size_t i = 0; i < T::Words; ++i) result.m_storage[i] = ~a.m_storage[i];
return result;
}
public:
// CONSTRUCTOR
VlNBACommitQueue() = default;
VL_UNCOPYABLE(VlNBACommitQueue);
// METHODS
template <typename... Args>
void enqueue(const T_Element& value, const T_Element& mask, Args... indices) {
m_pending.emplace_back(Entry{value, mask, {indices...}});
}
// Note: T_Commit might be different from T_Target. Specifically, when the signal is a
// top-level IO port, T_Commit will be a native C array, while T_Target, will be a VlUnpacked
template <typename T_Commit>
void commit(T_Commit& target) {
if (m_pending.empty()) return;
for (const Entry& entry : m_pending) { //
auto& ref = VlApplyIndices<0, T_Rank, T_Commit>::apply(target, entry.indices);
// Maybe inefficient, but it works for now ...
const auto oldValue = ref;
ref = bOr(bAnd(entry.value, entry.mask), bAnd(oldValue, bNot(entry.mask)));
}
m_pending.clear();
}
};
//===================================================================
// Object that VlDeleter is capable of deleting
@@ -1592,7 +1789,7 @@ public:
// Represents the null pointer. Used for setting VlClassRef to null instead of
// via nullptr_t, to prevent the implicit conversion of 0 to nullptr.
struct VlNull {
struct VlNull final {
operator bool() const { return false; }
};
@@ -1648,7 +1845,7 @@ public:
}
// cppcheck-suppress noExplicitConstructor
VlClassRef(VlClassRef&& moved)
: m_objp{vlstd::exchange(moved.m_objp, nullptr)} {}
: m_objp{std::exchange(moved.m_objp, nullptr)} {}
// cppcheck-suppress noExplicitConstructor
template <typename T_OtherClass>
VlClassRef(const VlClassRef<T_OtherClass>& copied)
@@ -1658,7 +1855,7 @@ public:
// cppcheck-suppress noExplicitConstructor
template <typename T_OtherClass>
VlClassRef(VlClassRef<T_OtherClass>&& moved)
: m_objp{vlstd::exchange(moved.m_objp, nullptr)} {}
: m_objp{std::exchange(moved.m_objp, nullptr)} {}
~VlClassRef() { refCountDec(); }
// METHODS
@@ -1673,7 +1870,7 @@ public:
VlClassRef& operator=(VlClassRef&& moved) {
if (m_objp == moved.m_objp) return *this;
refCountDec();
m_objp = vlstd::exchange(moved.m_objp, nullptr);
m_objp = std::exchange(moved.m_objp, nullptr);
return *this;
}
template <typename T_OtherClass>
@@ -1688,7 +1885,7 @@ public:
VlClassRef& operator=(VlClassRef<T_OtherClass>&& moved) {
if (m_objp == moved.m_objp) return *this;
refCountDec();
m_objp = vlstd::exchange(moved.m_objp, nullptr);
m_objp = std::exchange(moved.m_objp, nullptr);
return *this;
}
// Assign with nullptr
@@ -1707,7 +1904,7 @@ public:
T_Class* operator->() const { return m_objp; }
// For 'if (ptr)...'
operator bool() const { return m_objp; }
// In SV A == B iff both are handles to the same object (IEEE 1800-2017 8.4)
// In SV A == B iff both are handles to the same object (IEEE 1800-2023 8.4)
template <typename T_OtherClass>
bool operator==(const VlClassRef<T_OtherClass>& rhs) const {
return m_objp == rhs.m_objp;
@@ -1751,7 +1948,7 @@ template <typename T_Sampled>
class VlSampleQueue final {
// TYPES
// Type representing a single value sample at a point in time
struct VlSample {
struct VlSample final {
uint64_t m_timestamp; // Timestamp at which the value was sampled
T_Sampled m_value; // The sampled value
};
+5 -6
View File
@@ -118,11 +118,11 @@ void VerilatedVcd::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
printStr(" $end\n");
// Scope and signal definitions
assert(m_indent == 0);
assert(m_indent >= 0);
++m_indent;
Super::traceInit();
--m_indent;
assert(m_indent == 0);
assert(m_indent >= 0);
printStr("$enddefinitions $end\n\n\n");
@@ -268,7 +268,7 @@ void VerilatedVcd::bufferFlush() VL_MT_UNSAFE_ONE {
// We add output data to m_writep.
// When it gets nearly full we dump it using this routine which calls write()
// This is much faster than using buffered I/O
if (VL_UNLIKELY(!isOpen())) return;
if (VL_UNLIKELY(!m_isOpen)) return;
const char* wp = m_wrBufp;
while (true) {
const ssize_t remaining = (m_writep - wp);
@@ -282,8 +282,7 @@ void VerilatedVcd::bufferFlush() VL_MT_UNSAFE_ONE {
if (VL_UNCOVERABLE(errno != EAGAIN && errno != EINTR)) {
// LCOV_EXCL_START
// write failed, presume error (perhaps out of disk space)
const std::string msg
= std::string{"VerilatedVcd::bufferFlush: "} + std::strerror(errno);
const std::string msg = "VerilatedVcd::bufferFlush: "s + std::strerror(errno);
VL_FATAL_MT("", 0, "", msg.c_str());
closeErr();
break;
@@ -301,7 +300,7 @@ void VerilatedVcd::bufferFlush() VL_MT_UNSAFE_ONE {
void VerilatedVcd::printIndent(int level_change) {
if (level_change < 0) m_indent += level_change;
for (int i = 0; i < m_indent; i++) printStr(" ");
for (int i = 0; i < m_indent; ++i) printStr(" ");
if (level_change > 0) m_indent += level_change;
}
+7 -4
View File
@@ -50,7 +50,7 @@ private:
bool m_isOpen = false; // True indicates open file
std::string m_filename; // Filename we're writing to (if open)
uint64_t m_rolloverSize = 0; // File size to rollover at
unsigned m_indent = 0; // Indentation depth
int m_indent = 0; // Indentation depth
char* m_wrBufp; // Output buffer
char* m_wrFlushp; // Output buffer flush trigger location
@@ -251,7 +251,7 @@ public:
/// Class representing a VCD dump file in C standalone (no SystemC)
/// simulations. Also derived for use in SystemC simulations.
class VerilatedVcdC VL_NOT_FINAL {
class VerilatedVcdC VL_NOT_FINAL : public VerilatedTraceBaseC {
VerilatedVcd m_sptrace; // Trace file being created
// CONSTRUCTORS
@@ -267,7 +267,7 @@ public:
// METHODS - User called
/// Return if file is open
bool isOpen() const VL_MT_SAFE { return m_sptrace.isOpen(); }
bool isOpen() const override VL_MT_SAFE { return m_sptrace.isOpen(); }
/// Open a new VCD file
/// This includes a complete header dump each time it is called,
/// just as if this object was deleted and reconstructed.
@@ -283,7 +283,10 @@ public:
/// first may be removed. Cat files together to create viewable vcd.
void rolloverSize(size_t size) VL_MT_SAFE { m_sptrace.rolloverSize(size); }
/// Close dump
void close() VL_MT_SAFE { m_sptrace.close(); }
void close() VL_MT_SAFE {
m_sptrace.close();
modelConnected(false);
}
/// Flush dump
void flush() VL_MT_SAFE { m_sptrace.flush(); }
/// Write one cycle of dump data
+351 -136
View File
@@ -31,11 +31,14 @@
#include "verilated.h"
#include "verilated_imp.h"
#include "vltstd/vpi_user.h"
#include <cstdarg>
#include <cstdio>
#include <list>
#include <map>
#include <set>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
@@ -263,33 +266,24 @@ class VerilatedVpioScope VL_NOT_FINAL : public VerilatedVpio {
protected:
const VerilatedScope* const m_scopep;
bool m_toplevel = false;
const char* m_name;
const char* m_fullname;
public:
explicit VerilatedVpioScope(const VerilatedScope* scopep)
: m_scopep{scopep} {
std::string scopename = m_scopep->name();
std::string::size_type pos = std::string::npos;
// Look for '.' not inside escaped identifier
size_t i = 0;
while (i < scopename.length()) {
if (scopename[i] == '\\') {
while (i < scopename.length() && scopename[i] != ' ') ++i;
++i; // Proc ' ', it should always be there. Then grab '.' on next cycle
} else {
while (i < scopename.length() && scopename[i] != '.') ++i;
if (i < scopename.length()) pos = i++;
}
}
if (VL_UNLIKELY(pos == std::string::npos)) m_toplevel = true;
m_fullname = m_scopep->name();
if (std::strncmp(m_fullname, "TOP.", 4) == 0) m_fullname += 4;
m_name = m_scopep->identifier();
}
~VerilatedVpioScope() override = default;
static VerilatedVpioScope* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioScope*>(reinterpret_cast<VerilatedVpio*>(h));
}
uint32_t type() const override { return vpiScope; }
uint32_t type() const override { return vpiGenScope; }
const VerilatedScope* scopep() const { return m_scopep; }
const char* name() const override { return m_scopep->name(); }
const char* fullname() const override { return m_scopep->name(); }
const char* name() const override { return m_name; }
const char* fullname() const override { return m_fullname; }
bool toplevel() const { return m_toplevel; }
};
@@ -419,10 +413,19 @@ public:
}
if (m_onlyParams && !m_it->second.isParam()) continue;
if (VL_UNLIKELY(m_topscopep)) {
if (const VerilatedVar* topvarp = m_topscopep->varFind(m_it->second.name()))
return ((new VerilatedVpioVar{topvarp, m_topscopep})->castVpiHandle());
if (const VerilatedVar* topvarp = m_topscopep->varFind(m_it->second.name())) {
if (topvarp->isParam()) {
return ((new VerilatedVpioParam{topvarp, m_topscopep})->castVpiHandle());
} else {
return ((new VerilatedVpioVar{topvarp, m_topscopep})->castVpiHandle());
}
}
}
if (m_it->second.isParam()) {
return ((new VerilatedVpioParam{&(m_it->second), m_scopep})->castVpiHandle());
} else {
return ((new VerilatedVpioVar{&(m_it->second), m_scopep})->castVpiHandle());
}
return ((new VerilatedVpioVar{&(m_it->second), m_scopep})->castVpiHandle());
}
}
};
@@ -460,22 +463,29 @@ public:
};
class VerilatedVpioModule final : public VerilatedVpioScope {
const char* m_name;
const char* m_fullname;
public:
explicit VerilatedVpioModule(const VerilatedScope* modulep)
: VerilatedVpioScope{modulep} {
m_fullname = m_scopep->name();
if (std::strncmp(m_fullname, "TOP.", 4) == 0) m_fullname += 4;
m_name = m_scopep->identifier();
// Look for '.' not inside escaped identifier
const std::string scopename = m_fullname;
std::string::size_type pos = std::string::npos;
size_t i = 0;
while (i < scopename.length()) {
if (scopename[i] == '\\') {
while (i < scopename.length() && scopename[i] != ' ') ++i;
++i; // Proc ' ', it should always be there. Then grab '.' on next cycle
} else {
while (i < scopename.length() && scopename[i] != '.') ++i;
if (i < scopename.length()) pos = i++;
}
}
if (VL_UNLIKELY(pos == std::string::npos)) m_toplevel = true;
}
static VerilatedVpioModule* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioModule*>(reinterpret_cast<VerilatedVpio*>(h));
}
uint32_t type() const override { return vpiModule; }
const char* name() const override { return m_name; }
const char* fullname() const override { return m_fullname; }
};
class VerilatedVpioModuleIter final : public VerilatedVpio {
@@ -498,35 +508,63 @@ public:
delete this; // IEEE 37.2.2 vpi_scan at end does a vpi_release_handle
return nullptr;
}
const VerilatedScope::Type type = (*m_it)->type();
const VerilatedScope* const modp = *m_it++;
if (type == VerilatedScope::SCOPE_MODULE) {
const VerilatedScope::Type itype = modp->type();
if (itype == VerilatedScope::SCOPE_MODULE) {
return (new VerilatedVpioModule{modp})->castVpiHandle();
}
}
}
};
class VerilatedVpioScopeIter final : public VerilatedVpio {
const std::vector<const VerilatedScope*>* m_vec;
std::vector<const VerilatedScope*>::const_iterator m_it;
public:
explicit VerilatedVpioScopeIter(const std::vector<const VerilatedScope*>& vec)
: m_vec{&vec} {
m_it = m_vec->begin();
}
~VerilatedVpioScopeIter() override = default;
static VerilatedVpioScopeIter* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioScopeIter*>(reinterpret_cast<VerilatedVpio*>(h));
}
uint32_t type() const override { return vpiIterator; }
vpiHandle dovpi_scan() override {
while (true) {
if (m_it == m_vec->end()) {
delete this; // IEEE 37.2.2 vpi_scan at end does a vpi_release_handle
return nullptr;
}
const VerilatedScope* const modp = *m_it++;
const VerilatedScope::Type itype = modp->type();
if (itype == VerilatedScope::SCOPE_OTHER) {
return (new VerilatedVpioScope{modp})->castVpiHandle();
} else if (itype == VerilatedScope::SCOPE_MODULE) {
return (new VerilatedVpioModule{modp})->castVpiHandle();
}
}
}
};
static const char* d_unit = "$unit";
class VerilatedVpioPackage final : public VerilatedVpioScope {
std::string m_name;
std::string m_fullname;
std::string m_fullname_string;
public:
explicit VerilatedVpioPackage(const VerilatedScope* modulep)
: VerilatedVpioScope{modulep} {
const char* fullname = m_scopep->name();
if (std::strncmp(fullname, "TOP.", 4) == 0) fullname += 4;
m_fullname = std::string{fullname} + "::";
if (m_fullname == "\\$unit ::") m_fullname = "$unit::";
m_name = std::string(m_scopep->identifier());
if (m_name == "\\$unit ") m_name = "$unit";
m_fullname_string = std::string{m_fullname} + "::";
if (m_fullname_string == "\\$unit ::") m_fullname_string = "$unit::";
if (strcmp(m_name, "\\$unit ") == 0) m_name = d_unit;
}
static VerilatedVpioPackage* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioPackage*>(reinterpret_cast<VerilatedVpio*>(h));
}
const char* fullname() const override { return m_fullname_string.c_str(); }
uint32_t type() const override { return vpiPackage; }
const char* name() const override { return m_name.c_str(); }
const char* fullname() const override { return m_fullname.c_str(); }
};
class VerilatedVpioInstanceIter final : public VerilatedVpio {
@@ -549,12 +587,12 @@ public:
delete this; // IEEE 37.2.2 vpi_scan at end does a vpi_release_handle
return nullptr;
}
const VerilatedScope::Type type = (*m_it)->type();
const VerilatedScope::Type itype = (*m_it)->type();
const VerilatedScope* const modp = *m_it++;
if (type == VerilatedScope::SCOPE_MODULE) {
if (itype == VerilatedScope::SCOPE_MODULE) {
return (new VerilatedVpioModule{modp})->castVpiHandle();
}
if (type == VerilatedScope::SCOPE_PACKAGE) {
if (itype == VerilatedScope::SCOPE_PACKAGE) {
return (new VerilatedVpioPackage{modp})->castVpiHandle();
}
}
@@ -595,7 +633,147 @@ public:
void invalidate() { m_id = 0; }
};
struct VerilatedVpiTimedCbsCmp {
class VerilatedVpiPutHolder final {
VerilatedVpioVar m_var;
s_vpi_value m_value;
union Storage {
char init = 0; // to ensure trivial constructor
std::string str;
std::vector<s_vpi_vecval> vec;
~Storage() noexcept {/* handled by VerilatedVpiPutHolder */};
} m_storage{};
public:
VerilatedVpiPutHolder(const VerilatedVpioVar* vop, p_vpi_value valuep)
: m_var{vop} {
m_value.format = valuep->format;
switch (valuep->format) {
case vpiBinStrVal: // FALLTHRU
case vpiOctStrVal: // FALLTHRU
case vpiDecStrVal: // FALLTHRU
case vpiHexStrVal: // FALLTHRU
case vpiStringVal: {
new (&m_storage.str) std::string{valuep->value.str};
m_value.value.str = const_cast<char*>(m_storage.str.c_str());
break;
}
case vpiScalarVal: {
m_value.value.scalar = valuep->value.scalar;
break;
}
case vpiIntVal: {
m_value.value.integer = valuep->value.integer;
break;
}
case vpiRealVal: {
m_value.value.real = valuep->value.real;
break;
}
case vpiVectorVal: {
size_t words = 0;
switch (vop->varp()->vltype()) {
case VLVT_UINT8:
case VLVT_UINT16:
case VLVT_UINT32: {
words = 1;
break;
}
case VLVT_UINT64: {
words = 2;
break;
}
case VLVT_WDATA: {
words = VL_WORDS_I(vop->varp()->packed().elements());
break;
}
default: break;
}
new (&m_storage.vec)
std::vector<s_vpi_vecval>{valuep->value.vector, &valuep->value.vector[words]};
m_value.value.vector = m_storage.vec.data();
break;
}
}
}
VerilatedVpiPutHolder(VerilatedVpiPutHolder const& o)
: m_var{o.m_var}
, m_value{o.m_value} {
switch (m_value.format) {
case vpiBinStrVal: // FALLTHRU
case vpiOctStrVal: // FALLTHRU
case vpiDecStrVal: // FALLTHRU
case vpiHexStrVal: // FALLTHRU
case vpiStringVal: {
new (&m_storage.str) std::string{o.m_storage.str};
break;
}
case vpiVectorVal: {
new (&m_storage.vec) std::vector<s_vpi_vecval>{o.m_storage.vec};
break;
}
}
}
VerilatedVpiPutHolder(VerilatedVpiPutHolder&& o) noexcept
: m_var{std::move(o.m_var)}
, m_value{std::move(o.m_value)} {
switch (m_value.format) {
case vpiBinStrVal: // FALLTHRU
case vpiOctStrVal: // FALLTHRU
case vpiDecStrVal: // FALLTHRU
case vpiHexStrVal: // FALLTHRU
case vpiStringVal: {
new (&m_storage.str) std::string{std::move(o.m_storage.str)};
break;
}
case vpiVectorVal: {
new (&m_storage.vec) std::vector<s_vpi_vecval>{std::move(o.m_storage.vec)};
break;
}
}
}
~VerilatedVpiPutHolder() noexcept {
switch (m_value.format) {
case vpiBinStrVal: // FALLTHRU
case vpiOctStrVal: // FALLTHRU
case vpiDecStrVal: // FALLTHRU
case vpiHexStrVal: // FALLTHRU
case vpiStringVal: m_storage.str.~basic_string(); break;
case vpiVectorVal: m_storage.vec.~vector(); break;
}
}
VerilatedVpioVar* varp() { return &m_var; }
p_vpi_value valuep() { return &m_value; }
static bool canInertialDelay(p_vpi_value valuep) {
switch (valuep->format) {
case vpiBinStrVal: // FALLTHRU
case vpiOctStrVal: // FALLTHRU
case vpiDecStrVal: // FALLTHRU
case vpiHexStrVal: // FALLTHRU
case vpiStringVal: {
if (VL_UNLIKELY(!valuep->value.str)) return false;
break;
}
case vpiScalarVal: // FALLTHRU
case vpiIntVal: // FALLTHRU
case vpiRealVal: break;
case vpiVectorVal: {
if (VL_UNLIKELY(!valuep->value.vector)) return false;
break;
}
default: {
return false;
}
}
return true;
}
};
struct VerilatedVpiTimedCbsCmp final {
// Ordering sets keyed by time, then callback unique id
bool operator()(const std::pair<QData, uint64_t>& a,
const std::pair<QData, uint64_t>& b) const {
@@ -617,9 +795,11 @@ class VerilatedVpiImp final {
std::array<VpioCbList, CB_ENUM_MAX_VALUE> m_cbCurrentLists;
VpioFutureCbs m_futureCbs; // Time based callbacks for future timestamps
VpioFutureCbs m_nextCbs; // cbNextSimTime callbacks
std::list<VerilatedVpiPutHolder> m_inertialPuts; // Pending vpi puts due to vpiInertialDelay
VerilatedVpiError* m_errorInfop = nullptr; // Container for vpi error info
VerilatedAssertOneThread m_assertOne; // Assert only called from single thread
uint64_t m_nextCallbackId = 1; // Id to identify callback
bool m_evalNeeded = false; // Model has had signals updated via vpi_put_value()
static VerilatedVpiImp& s() { // Singleton
static VerilatedVpiImp s_s;
@@ -741,7 +921,7 @@ public:
assertOneCheck();
VpioCbList& cbObjList = s().m_cbCurrentLists[cbValueChange];
bool called = false;
std::unordered_set<VerilatedVpioVar*> update; // set of objects to update after callbacks
std::set<VerilatedVpioVar*> update; // set of objects to update after callbacks
if (cbObjList.empty()) return called;
const auto last = std::prev(cbObjList.end()); // prevent looping over newly added elements
for (auto it = cbObjList.begin(); true;) {
@@ -778,6 +958,17 @@ public:
}
static void dumpCbs() VL_MT_UNSAFE_ONE;
static VerilatedVpiError* error_info() VL_MT_UNSAFE_ONE; // getter for vpi error info
static void evalNeeded(bool evalNeeded) { s().m_evalNeeded = evalNeeded; }
static bool evalNeeded() { return s().m_evalNeeded; }
static void inertialDelay(const VerilatedVpioVar* vop, p_vpi_value valuep) {
s().m_inertialPuts.emplace_back(vop, valuep);
}
static void doInertialPuts() {
for (auto& it : s().m_inertialPuts) {
vpi_put_value(it.varp()->castVpiHandle(), it.valuep(), nullptr, vpiNoDelay);
}
s().m_inertialPuts.clear();
}
};
//======================================================================
@@ -855,6 +1046,7 @@ public:
static const char* strFromVpiMethod(PLI_INT32 vpiVal) VL_PURE;
static const char* strFromVpiCallbackReason(PLI_INT32 vpiVal) VL_PURE;
static const char* strFromVpiProp(PLI_INT32 vpiVal) VL_PURE;
static const char* strFromVpiConstType(PLI_INT32 vpiVal) VL_PURE;
};
//======================================================================
@@ -879,6 +1071,11 @@ PLI_INT32 VerilatedVpioReasonCb::dovpi_remove_cb() {
return 1;
}
void VerilatedVpi::clearEvalNeeded() VL_MT_UNSAFE_ONE { VerilatedVpiImp::evalNeeded(false); }
bool VerilatedVpi::evalNeeded() VL_MT_UNSAFE_ONE { return VerilatedVpiImp::evalNeeded(); }
void VerilatedVpi::doInertialPuts() VL_MT_UNSAFE_ONE { VerilatedVpiImp::doInertialPuts(); }
//======================================================================
// VerilatedVpiImp implementation
@@ -1372,11 +1569,27 @@ const char* VerilatedVpiError::strFromVpiProp(PLI_INT32 vpiVal) VL_PURE {
if (vpiVal == vpiUndefined) return "vpiUndefined";
return names[(vpiVal <= vpiIsProtected) ? vpiVal : 0];
}
const char* VerilatedVpiError::strFromVpiConstType(PLI_INT32 constType) VL_PURE {
// clang-format off
static const char* const names[] = {
"*undefined*",
"vpiDecConst",
"vpiRealConst",
"vpiBinaryConst",
"vpiOctConst",
"vpiHexConst",
"vpiStringConst",
"vpiIntConst",
"vpiTimeConst",
};
// clang-format on
if (VL_UNCOVERABLE(constType < 0)) return names[0];
return names[(constType <= vpiTimeConst) ? constType : 0];
}
#define SELF_CHECK_RESULT_CSTR(got, exp) \
if (0 != std::strcmp((got), (exp))) { \
const std::string msg \
= std::string{"%Error: "} + "GOT = '" + (got) + "'" + " EXP = '" + (exp) + "'"; \
const std::string msg = "%Error: GOT = '"s + (got) + "'" + " EXP = '" + (exp) + "'"; \
VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str()); \
}
@@ -1643,6 +1856,15 @@ void VerilatedVpiError::selfTest() VL_MT_UNSAFE_ONE {
SELF_CHECK_ENUM_STR(strFromVpiProp, vpiOffset);
SELF_CHECK_ENUM_STR(strFromVpiProp, vpiStop);
SELF_CHECK_ENUM_STR(strFromVpiProp, vpiIsProtected);
SELF_CHECK_ENUM_STR(strFromVpiConstType, vpiDecConst);
SELF_CHECK_ENUM_STR(strFromVpiConstType, vpiRealConst);
SELF_CHECK_ENUM_STR(strFromVpiConstType, vpiBinaryConst);
SELF_CHECK_ENUM_STR(strFromVpiConstType, vpiOctConst);
SELF_CHECK_ENUM_STR(strFromVpiConstType, vpiHexConst);
SELF_CHECK_ENUM_STR(strFromVpiConstType, vpiStringConst);
SELF_CHECK_ENUM_STR(strFromVpiConstType, vpiIntConst);
SELF_CHECK_ENUM_STR(strFromVpiConstType, vpiTimeConst);
}
#undef SELF_CHECK_ENUM_STR
@@ -1943,13 +2165,21 @@ vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle object) {
return ((new VerilatedVpioVarIter{vop, true})->castVpiHandle());
}
case vpiModule: {
const VerilatedVpioModule* const vop = VerilatedVpioModule::castp(object);
const VerilatedVpioScope* const vop = VerilatedVpioScope::castp(object);
const VerilatedHierarchyMap* const map = VerilatedImp::hierarchyMap();
const VerilatedScope* const modp = vop ? vop->scopep() : nullptr;
const auto it = vlstd::as_const(map)->find(const_cast<VerilatedScope*>(modp));
if (it == map->end()) return nullptr;
return ((new VerilatedVpioModuleIter{it->second})->castVpiHandle());
}
case vpiInternalScope: {
const VerilatedVpioScope* const vop = VerilatedVpioScope::castp(object);
const VerilatedHierarchyMap* const map = VerilatedImp::hierarchyMap();
const VerilatedScope* const modp = vop ? vop->scopep() : nullptr;
const auto it = vlstd::as_const(map)->find(const_cast<VerilatedScope*>(modp));
if (it == map->end()) return nullptr;
return ((new VerilatedVpioScopeIter{it->second})->castVpiHandle());
}
case vpiInstance: {
if (object) return nullptr;
const VerilatedHierarchyMap* const map = VerilatedImp::hierarchyMap();
@@ -1991,41 +2221,41 @@ PLI_INT32 vpi_get(PLI_INT32 property, vpiHandle object) {
}
case vpiType: {
const VerilatedVpio* const vop = VerilatedVpio::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
if (VL_UNLIKELY(!vop)) return vpiUndefined;
return vop->type();
}
case vpiConstType: {
const VerilatedVpio* const vop = VerilatedVpio::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
if (VL_UNLIKELY(!vop)) return vpiUndefined;
return vop->constType();
}
case vpiDirection: {
// By forethought, the directions already are vpi enumerated
const VerilatedVpioVarBase* const vop = VerilatedVpioVarBase::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
if (VL_UNLIKELY(!vop)) return vpiUndefined;
return vop->varp()->vldir();
}
case vpiScalar: // FALLTHRU
case vpiVector: {
const VerilatedVpioVarBase* const vop = VerilatedVpioVarBase::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
if (VL_UNLIKELY(!vop)) return vpiUndefined;
return (property == vpiVector) ^ (vop->varp()->dims() == 0);
}
case vpiSize: {
const VerilatedVpioVarBase* const vop = VerilatedVpioVarBase::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
if (VL_UNLIKELY(!vop)) return vpiUndefined;
return vop->size();
}
default:
VL_VPI_WARNING_(__FILE__, __LINE__, "%s: Unsupported type %s, nothing will be returned",
__func__, VerilatedVpiError::strFromVpiProp(property));
return 0;
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported property %s, nothing will be returned",
__func__, VerilatedVpiError::strFromVpiProp(property));
return vpiUndefined;
}
}
PLI_INT64 vpi_get64(PLI_INT32 /*property*/, vpiHandle /*object*/) {
VL_VPI_UNIMP_();
return 0;
return vpiUndefined;
}
PLI_BYTE8* vpi_get_str(PLI_INT32 property, vpiHandle object) {
@@ -2047,6 +2277,11 @@ PLI_BYTE8* vpi_get_str(PLI_INT32 property, vpiHandle object) {
case vpiType: {
return const_cast<PLI_BYTE8*>(VerilatedVpiError::strFromVpiObjType(vop->type()));
}
case vpiConstType: {
const PLI_INT32 constType = vpi_get(vpiConstType, object);
VL_VPI_ERROR_RESET_();
return const_cast<PLI_BYTE8*>(VerilatedVpiError::strFromVpiConstType(constType));
}
default:
VL_VPI_WARNING_(__FILE__, __LINE__, "%s: Unsupported type %s, nothing will be returned",
__func__, VerilatedVpiError::strFromVpiProp(property));
@@ -2120,13 +2355,28 @@ bool vl_check_format(const VerilatedVar* varp, const p_vpi_value valuep, const c
return status;
}
static void vl_strprintf(std::string& buffer, char const* fmt, ...) {
va_list args, args_copy;
va_start(args, fmt);
buffer.clear();
// Make copy of args since we may need to call VL_VSNPRINTF more than once
va_copy(args_copy, args);
// Try VL_VSNPRINTF in existing buffer
const int result
= VL_VSNPRINTF(const_cast<char*>(buffer.data()), buffer.capacity(), fmt, args_copy);
va_end(args_copy);
const int required = result + 1; // Returned size doesn't include NUL terminator
// If there wasn't enough space, reallocate and try again
if (buffer.capacity() < required) {
buffer.reserve(required * 2);
VL_VSNPRINTF(const_cast<char*>(buffer.data()), buffer.capacity(), fmt, args);
}
va_end(args);
}
void vl_get_value(const VerilatedVar* varp, void* varDatap, p_vpi_value valuep,
const char* fullname) {
if (!vl_check_format(varp, valuep, fullname, true)) return;
// Maximum required size is for binary string, one byte per bit plus null termination
static thread_local char t_outStr[VL_VALUE_STRING_MAX_WORDS * VL_EDATASIZE + 1];
// cppcheck-suppress variableScope
static const thread_local int t_outStrSz = sizeof(t_outStr) - 1;
// string data type is dynamic and may vary in size during simulation
static thread_local std::string t_outDynamicStr;
// We used to presume vpiValue.format = vpiIntVal or if single bit vpiScalarVal
@@ -2170,43 +2420,21 @@ void vl_get_value(const VerilatedVar* varp, void* varDatap, p_vpi_value valuep,
return;
}
} else if (valuep->format == vpiBinStrVal) {
valuep->value.str = t_outStr;
int bits = varp->packed().elements();
t_outDynamicStr.resize(bits);
const CData* datap = (reinterpret_cast<CData*>(varDatap));
int i;
if (bits > t_outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
VL_VPI_WARNING_(
__FILE__, __LINE__,
"%s: Truncating string value of %s for %s"
" as buffer size (%d, VL_VALUE_STRING_MAX_WORDS=%d) is less than required (%d)",
__func__, VerilatedVpiError::strFromVpiVal(valuep->format), fullname, t_outStrSz,
VL_VALUE_STRING_MAX_WORDS, bits);
bits = t_outStrSz;
}
for (i = 0; i < bits; ++i) {
for (size_t i = 0; i < bits; ++i) {
const char val = (datap[i >> 3] >> (i & 7)) & 1;
t_outStr[bits - i - 1] = val ? '1' : '0';
t_outDynamicStr[bits - i - 1] = val ? '1' : '0';
}
t_outStr[i] = '\0';
valuep->value.str = const_cast<PLI_BYTE8*>(t_outDynamicStr.c_str());
return;
} else if (valuep->format == vpiOctStrVal) {
valuep->value.str = t_outStr;
int chars = (varp->packed().elements() + 2) / 3;
t_outDynamicStr.resize(chars);
const int bytes = VL_BYTES_I(varp->packed().elements());
const CData* datap = (reinterpret_cast<CData*>(varDatap));
int i;
if (chars > t_outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
VL_VPI_WARNING_(
__FILE__, __LINE__,
"%s: Truncating string value of %s for %s"
" as buffer size (%d, VL_VALUE_STRING_MAX_WORDS=%d) is less than required (%d)",
__func__, VerilatedVpiError::strFromVpiVal(valuep->format), fullname, t_outStrSz,
VL_VALUE_STRING_MAX_WORDS, chars);
chars = t_outStrSz;
}
for (i = 0; i < chars; ++i) {
for (size_t i = 0; i < chars; ++i) {
const div_t idx = div(i * 3, 8);
int val = datap[idx.quot];
if ((idx.quot + 1) < bytes) {
@@ -2225,46 +2453,31 @@ void vl_get_value(const VerilatedVar* varp, void* varDatap, p_vpi_value valuep,
val &= (1 << rem) - 1;
}
}
t_outStr[chars - i - 1] = '0' + (val & 7);
t_outDynamicStr[chars - i - 1] = '0' + (val & 7);
}
t_outStr[i] = '\0';
valuep->value.str = const_cast<PLI_BYTE8*>(t_outDynamicStr.c_str());
return;
} else if (valuep->format == vpiDecStrVal) {
valuep->value.str = t_outStr;
// outStrSz does not include nullptr termination so add one
if (varp->vltype() == VLVT_UINT8) {
VL_SNPRINTF(t_outStr, t_outStrSz + 1, "%hhu",
static_cast<unsigned char>(*(reinterpret_cast<CData*>(varDatap))));
return;
vl_strprintf(t_outDynamicStr, "%hhu",
static_cast<unsigned char>(*(reinterpret_cast<CData*>(varDatap))));
} else if (varp->vltype() == VLVT_UINT16) {
VL_SNPRINTF(t_outStr, t_outStrSz + 1, "%hu",
static_cast<unsigned short>(*(reinterpret_cast<SData*>(varDatap))));
return;
vl_strprintf(t_outDynamicStr, "%hu",
static_cast<unsigned short>(*(reinterpret_cast<SData*>(varDatap))));
} else if (varp->vltype() == VLVT_UINT32) {
VL_SNPRINTF(t_outStr, t_outStrSz + 1, "%u",
static_cast<unsigned int>(*(reinterpret_cast<IData*>(varDatap))));
return;
vl_strprintf(t_outDynamicStr, "%u",
static_cast<unsigned int>(*(reinterpret_cast<IData*>(varDatap))));
} else if (varp->vltype() == VLVT_UINT64) {
VL_SNPRINTF(t_outStr, t_outStrSz + 1, "%llu",
static_cast<unsigned long long>(*(reinterpret_cast<QData*>(varDatap))));
return;
vl_strprintf(t_outDynamicStr, "%llu",
static_cast<unsigned long long>(*(reinterpret_cast<QData*>(varDatap))));
}
valuep->value.str = const_cast<PLI_BYTE8*>(t_outDynamicStr.c_str());
return;
} else if (valuep->format == vpiHexStrVal) {
valuep->value.str = t_outStr;
int chars = (varp->packed().elements() + 3) >> 2;
t_outDynamicStr.resize(chars);
const CData* datap = (reinterpret_cast<CData*>(varDatap));
int i;
if (chars > t_outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
VL_VPI_WARNING_(
__FILE__, __LINE__,
"%s: Truncating string value of %s for %s"
" as buffer size (%d, VL_VALUE_STRING_MAX_WORDS=%d) is less than required (%d)",
__func__, VerilatedVpiError::strFromVpiVal(valuep->format), fullname, t_outStrSz,
VL_VALUE_STRING_MAX_WORDS, chars);
chars = t_outStrSz;
}
for (i = 0; i < chars; ++i) {
for (size_t i = 0; i < chars; ++i) {
char val = (datap[i >> 1] >> ((i & 1) << 2)) & 15;
if (i == (chars - 1)) {
// most significant char, mask off nonexistent bits when vector
@@ -2275,9 +2488,9 @@ void vl_get_value(const VerilatedVar* varp, void* varDatap, p_vpi_value valuep,
val &= (1 << rem) - 1;
}
}
t_outStr[chars - i - 1] = "0123456789abcdef"[static_cast<int>(val)];
t_outDynamicStr[chars - i - 1] = "0123456789abcdef"[static_cast<int>(val)];
}
t_outStr[i] = '\0';
valuep->value.str = const_cast<PLI_BYTE8*>(t_outDynamicStr.c_str());
return;
} else if (valuep->format == vpiStringVal) {
if (varp->vltype() == VLVT_STRING) {
@@ -2290,26 +2503,15 @@ void vl_get_value(const VerilatedVar* varp, void* varDatap, p_vpi_value valuep,
return;
}
} else {
valuep->value.str = t_outStr;
int bytes = VL_BYTES_I(varp->packed().elements());
t_outDynamicStr.resize(bytes);
const CData* datap = (reinterpret_cast<CData*>(varDatap));
int i;
if (bytes > t_outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
VL_VPI_WARNING_(__FILE__, __LINE__,
"%s: Truncating string value of %s for %s"
" as buffer size (%d, VL_VALUE_STRING_MAX_WORDS=%d) is less than "
"required (%d)",
__func__, VerilatedVpiError::strFromVpiVal(valuep->format),
fullname, t_outStrSz, VL_VALUE_STRING_MAX_WORDS, bytes);
bytes = t_outStrSz;
}
for (i = 0; i < bytes; ++i) {
for (size_t i = 0; i < bytes; ++i) {
const char val = datap[bytes - i - 1];
// other simulators replace [leading?] zero chars with spaces, replicate here.
t_outStr[i] = val ? val : ' ';
t_outDynamicStr[i] = val ? val : ' ';
}
t_outStr[i] = '\0';
valuep->value.str = const_cast<PLI_BYTE8*>(t_outDynamicStr.c_str());
return;
}
} else if (valuep->format == vpiIntVal) {
@@ -2358,7 +2560,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value valuep) {
}
vpiHandle vpi_put_value(vpiHandle object, p_vpi_value valuep, p_vpi_time /*time_p*/,
PLI_INT32 /*flags*/) {
PLI_INT32 flags) {
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_put_value %p %p\n", object, valuep););
VerilatedVpiImp::assertOneCheck();
VL_VPI_ERROR_RESET_();
@@ -2366,11 +2568,24 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value valuep, p_vpi_time /*time_
VL_VPI_WARNING_(__FILE__, __LINE__, "Ignoring vpi_put_value with nullptr value pointer");
return nullptr;
}
PLI_INT32 delay_mode = flags & 0xfff;
if (const VerilatedVpioVar* const vop = VerilatedVpioVar::castp(object)) {
if (delay_mode == vpiInertialDelay) {
if (!VerilatedVpiPutHolder::canInertialDelay(valuep)) {
VL_VPI_WARNING_(
__FILE__, __LINE__,
"%s: Unsupported p_vpi_value as requested for '%s' with vpiInertialDelay",
__func__, vop->fullname());
return nullptr;
}
VerilatedVpiImp::inertialDelay(vop, valuep);
return object;
}
VL_DEBUG_IF_PLI(
VL_DBG_MSGF("- vpi: vpi_put_value name=%s fmt=%d vali=%d\n", vop->fullname(),
valuep->format, valuep->value.integer);
VL_DBG_MSGF("- vpi: varp=%p putatp=%p\n", vop->varp()->datap(), vop->varDatap()););
VerilatedVpiImp::evalNeeded(true);
if (VL_UNLIKELY(!vop->varp()->isPublicRW())) {
VL_VPI_WARNING_(__FILE__, __LINE__,
+8 -1
View File
@@ -30,7 +30,7 @@
#include "verilated_syms.h"
//======================================================================
// From IEEE 1800-2017 annex M
// From IEEE 1800-2023 annex M
#include "vltstd/sv_vpi_user.h"
@@ -54,6 +54,13 @@ public:
static QData cbNextDeadline() VL_MT_UNSAFE_ONE;
/// Debug dump of callbacks
static void dumpCbs() VL_MT_UNSAFE_ONE;
/// Checks VPI dirty state (i.e. whether vpi_put_value() has
/// been called since the last clearEvalNeeded())
static bool evalNeeded() VL_MT_UNSAFE_ONE;
/// Clears VPI dirty state (see evalNeeded())
static void clearEvalNeeded() VL_MT_UNSAFE_ONE;
/// Perform inertially delayed puts
static void doInertialPuts() VL_MT_UNSAFE_ONE;
// Self test, for internal use only
static void selfTest() VL_MT_UNSAFE_ONE;
+53 -10
View File
@@ -58,6 +58,9 @@
# define VL_ATTR_PRINTF(fmtArgNum) __attribute__((format(printf, (fmtArgNum), (fmtArgNum) + 1)))
# define VL_ATTR_PURE __attribute__((pure))
# define VL_ATTR_UNUSED __attribute__((unused))
#ifndef VL_ATTR_WARN_UNUSED_RESULT
# define VL_ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#endif
# if !defined(_WIN32) && !defined(__MINGW32__)
// All VL_ATTR_WEAK symbols must be marked with the macOS -U linker flag in verilated.mk.in
# define VL_ATTR_WEAK __attribute__((weak))
@@ -164,6 +167,9 @@
#ifndef VL_ATTR_UNUSED
# define VL_ATTR_UNUSED ///< Attribute that function that may be never used
#endif
#ifndef VL_ATTR_WARN_UNUSED_RESULT
# define VL_ATTR_WARN_UNUSED_RESULT ///< Attribute that return value of function must be used
#endif
#ifndef VL_ATTR_WEAK
# define VL_ATTR_WEAK ///< Attribute that function external that is optionally defined
#endif
@@ -260,7 +266,7 @@
//=========================================================================
// C++-2014
#if __cplusplus >= 201402L || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(VL_CPPCHECK) || defined(_MSC_VER)
#if __cplusplus >= 201402L || defined(VL_CPPCHECK) || defined(_MSC_VER)
#else
# error "Verilator requires a C++14 or newer compiler"
#endif
@@ -337,6 +343,7 @@ extern "C" void __gcov_dump();
#include <cstdint>
#include <cinttypes>
#include <cmath>
#include <ctime>
#ifndef VL_NO_LEGACY
using vluint8_t = uint8_t; ///< 8-bit unsigned type (backward compatibility)
@@ -604,6 +611,50 @@ static inline double VL_ROUND(double n) {
#define VL_OFFSETOF(type, field) \
(reinterpret_cast<size_t>(&(reinterpret_cast<type*>(0x10000000)->field)) - 0x10000000)
//=========================================================================
// Time and performance
#include <string>
namespace VlOs {
/// Get environment variable
extern std::string getenvStr(const std::string& envvar,
const std::string& defaultValue) VL_MT_SAFE;
extern uint64_t memUsageBytes() VL_MT_SAFE; ///< Return memory usage in bytes, or 0 if unknown
// Internal: Record CPU time, starting point on construction, and current delta from that
class DeltaCpuTime final {
double m_start{}; // Time constructed at
static double gettime() VL_MT_SAFE;
public:
// Construct, and if startit is true, start() timer
explicit DeltaCpuTime(bool startit) {
if (startit) start();
}
void start() VL_MT_SAFE { m_start = gettime(); } // Start timer; record current time
double deltaTime() const VL_MT_SAFE { // Return time between now and start()
return (m_start == 0.0) ? 0.0 : gettime() - m_start;
}
};
// Internal: Record wall time, starting point on construction, and current delta from that
class DeltaWallTime final {
double m_start{}; // Time constructed at
static double gettime() VL_MT_SAFE;
public:
// Construct, and if startit is true, start() timer
explicit DeltaWallTime(bool startit) {
if (startit) start();
}
void start() VL_MT_SAFE { m_start = gettime(); } // Start timer; record current time
double deltaTime() const VL_MT_SAFE { // Return time between now and start()
return (m_start == 0.0) ? 0.0 : gettime() - m_start;
}
};
} //namespace VlOs
//=========================================================================
// Conversions
@@ -612,7 +663,7 @@ static inline double VL_ROUND(double n) {
namespace vlstd {
template <typename T>
struct reverse_wrapper {
struct reverse_wrapper final {
const T& m_v;
explicit reverse_wrapper(const T& a_v)
@@ -637,14 +688,6 @@ T const& as_const(T& v) VL_MT_SAFE {
return v;
}
// C++14's std::exchange
template <class T, class U = T>
T exchange(T& obj, U&& new_value) {
T old_value = std::move(obj);
obj = std::forward<U>(new_value);
return old_value;
}
}; // namespace vlstd
//=========================================================================
+129
View File
@@ -0,0 +1,129 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Code available from: https://verilator.org
//
// 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
//
//*************************************************************************
///
/// \file
/// \brief Verilated/Verilator common implementation for OS portability
///
/// This is compiled as part of other .cpp files to reduce compile time
/// and as such is a .h file rather than .cpp file.
///
//*************************************************************************
#ifndef VL_ALLOW_VERILATEDOS_C
#error "This file should be included only from V3Os.cpp/Verilated.cpp"
#endif
#include "verilatedos.h"
// clang-format off
#if defined(_WIN32) || defined(__MINGW32__)
# include <windows.h> // LONG for bcrypt.h on MINGW
# include <processthreadsapi.h> // GetProcessTimes
# include <psapi.h> // GetProcessMemoryInfo
#endif
// clang-format on
namespace VlOs {
//=========================================================================
// VlOs::VlGetCpuTime/VlGetWallTime implementation
double DeltaCpuTime::gettime() VL_MT_SAFE {
#if defined(_WIN32) || defined(__MINGW32__)
FILETIME lpCreationTime, lpExitTime, lpKernelTime, lpUserTime;
if (0
!= GetProcessTimes(GetCurrentProcess(), &lpCreationTime, &lpExitTime, &lpKernelTime,
&lpUserTime)) {
return static_cast<double>(static_cast<uint64_t>(lpUserTime.dwLowDateTime)
| static_cast<uint64_t>(lpUserTime.dwHighDateTime) << 32ULL)
* 1e-7;
}
#else
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
timespec ts;
if (0 != clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts)) // MT-Safe
return ts.tv_sec + ts.tv_nsec * 1e-9;
#endif
return 0.0;
}
double DeltaWallTime::gettime() VL_MT_SAFE {
#if defined(_WIN32) || defined(__MINGW32__)
FILETIME ft; // contains number of 0.1us intervals since the beginning of 1601 UTC.
GetSystemTimeAsFileTime(&ft);
const uint64_t tenthus
= ((static_cast<uint64_t>(ft.dwHighDateTime) << 32) + ft.dwLowDateTime + 5ULL);
return static_cast<double>(tenthus) * 1e-7;
#else
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
timespec ts;
if (0 == clock_gettime(CLOCK_MONOTONIC, &ts)) // MT-Safe
return ts.tv_sec + ts.tv_nsec * 1e-9;
return 0.0;
#endif
}
//=========================================================================
// VlOs::memUsageBytes implementation
uint64_t memUsageBytes() VL_MT_SAFE {
#if defined(_WIN32) || defined(__MINGW32__)
const HANDLE process = GetCurrentProcess();
PROCESS_MEMORY_COUNTERS pmc;
if (GetProcessMemoryInfo(process, &pmc, sizeof(pmc))) {
// The best we can do using simple Windows APIs is to get the size of the working set.
return pmc.WorkingSetSize;
}
return 0;
#else
// Highly unportable. Sorry
const char* const statmFilename = "/proc/self/statm";
FILE* const fp = fopen(statmFilename, "r");
if (!fp) return 0;
uint64_t size, resident, share, text, lib, data, dt; // All in pages
const int items = fscanf(
fp, "%" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64,
&size, &resident, &share, &text, &lib, &data, &dt);
fclose(fp);
if (VL_UNCOVERABLE(7 != items)) return 0;
return (text + data) * getpagesize();
#endif
}
//=========================================================================
// VlOs::getenvStr implementation
std::string getenvStr(const std::string& envvar, const std::string& defaultValue) VL_MT_SAFE {
std::string ret;
#if defined(_MSC_VER)
// Note: MinGW does not offer _dupenv_s
const char* envvalue = nullptr;
_dupenv_s((char**)&envvalue, nullptr, envvar.c_str());
if (envvalue != nullptr) {
const std::string result{envvalue};
free((void*)envvalue);
ret = result;
} else {
ret = defaultValue;
}
#else
if (const char* const envvalue = getenv(envvar.c_str())) {
ret = envvalue;
} else {
ret = defaultValue;
}
#endif
return ret;
}
//=========================================================================
} //namespace VlOs
+17 -2
View File
@@ -150,10 +150,21 @@ extern "C" {
#define vpiIntegerNet 681
#define vpiLogicNet vpiNet
#define vpiTimeNet 682
#define vpiUnionNet 525
#define vpiShortRealNet 526
#define vpiRealNet 527
#define vpiByteNet 528
#define vpiShortIntNet 529
#define vpiIntNet 530
#define vpiLongIntNet 531
#define vpiBitNet 532
#define vpiInterconnectNet 533
#define vpiInterconnectArray 534
#define vpiStructNet 683
#define vpiBreak 684
#define vpiContinue 685
#define vpiPackedArrayNet 693
#define vpiNettypeDecl 523
#define vpiConstraintExpr 747
#define vpiElseConst 748
#define vpiImplication 749
@@ -174,6 +185,8 @@ extern "C" {
#define vpiBaseTypespec 703
#define vpiElemTypespec 704
#define vpiNetTypedefAlias 705
#define vpiInputSkew 706
#define vpiOutputSkew 707
#define vpiGlobalClocking 708
@@ -206,7 +219,8 @@ extern "C" {
#define vpiMessages 735
#define vpiLoopVars 737
#define vpiConcurrentAssertions 740
#define vpiConcurrentAssertion 740
#define vpiConcurrentAssertions vpiConcurrentAssertion
#define vpiMatchItem 741
#define vpiMember 742
#define vpiElement 743
@@ -221,6 +235,7 @@ extern "C" {
/**************************************************************************/
/************************ generic object properties ***********************/
/**************************************************************************/
#define vpiTop 600
#define vpiUnit 602
@@ -255,7 +270,6 @@ extern "C" {
#define vpiModportPort 2
/* vpiPort is also a port type. It is defined in vpi_user.h */
#define vpiConstantVariable 612
#define vpiStructUnionMember 615
@@ -407,6 +421,7 @@ extern "C" {
/***************************** structure *****************************/
/**************************** CALLBACK REASONS ****************************/
#define vpiMethodFuncCall 648
#define cbStartOfThread 600 /* callback on thread creation */
#define cbEndOfThread 601 /* callback on thread termination */
#define cbEnterThread 602 /* callback on reentering thread */
+51 -6
View File
@@ -7,7 +7,7 @@
* This file contains the constant definitions, structure definitions,
* and routine declarations used by SystemVerilog DPI.
*
* This file is from the SystemVerilog IEEE 1800-2017 Annex I.
* This file is from the SystemVerilog IEEE 1800-2023 Annex I.
*/
#ifndef INCLUDED_SVDPI
@@ -111,6 +111,26 @@ typedef uint32_t svBitVecVal;
((N) == 32 ? (VALUE) : \
(((VALUE) & (1 << (N))) ? ((VALUE) | ~SV_MASK(N)) : ((VALUE) & SV_MASK(N))))
#ifndef VPI_TIME
#define VPI_TIME
typedef struct t_vpi_time {
int32_t type;
uint32_t high, low;
double real;
} s_vpi_time, *p_vpi_time;
#define vpiScaledRealTime 1
#define vpiSimTime 2
#define vpiSuppressTime 3
#endif
/* time value */
typedef s_vpi_time svTimeVal;
/* time value types */
#define sv_scaled_real_time vpiScaledRealTime
#define sv_sim_time vpiSimTime
/*
* Implementation-dependent representation.
*/
@@ -277,7 +297,7 @@ XXTERN svScope svGetScope( void );
/*
* Set context for subsequent export function execution.
* This function must be called before calling an export function, unless
* This function shall be called before calling an export function, unless
* the export function is called while executing an import function. In that
* case the export function shall inherit the scope of the surrounding import
* function. This is known as the "default scope".
@@ -297,7 +317,7 @@ XXTERN svScope svGetScopeFromName(const char* scopeName);
/*
* Store an arbitrary user data pointer for later retrieval by svGetUserData()
* The userKey is generated by the user. It must be guaranteed by the user to
* The userKey is generated by the user. It needs to be guaranteed by the user to
* be unique from all other userKey's for all unique data storage requirements
* It is recommended that the address of static functions or variables in the
* user's C code be used as the userKey.
@@ -329,24 +349,49 @@ XXTERN void* svGetUserData(const svScope scope, void* userKey);
* modified. Whether this information is available or not is implementation-
* specific. Note that the string provided (if any) is owned by the SV
* implementation and is valid only until the next call to any SV function.
* Applications must not modify this string or free it
* Applications shall not modify this string or free it.
*/
XXTERN int svGetCallerInfo(const char** fileName, int *lineNumber);
/*
* Returns 1 if the current execution thread is in the disabled state.
* Disable protocol must be adhered to if in the disabled state.
* Disable protocol shall be adhered to if in the disabled state.
*/
XXTERN int svIsDisabledState( void );
/*
* Imported functions call this API function during disable processing to
* acknowledge that they are correctly participating in the DPI disable protocol.
* This function must be called before returning from an imported function that is
* This function shall be called before returning from an imported function that is
* in the disabled state.
*/
XXTERN void svAckDisabledState( void );
/* Mantis 5713/D9
* Retrieve the current simulation time, scaled to the time unit of the scope.
* If scope is NULL, then time is scaled to the simulation time unit.
* It is an error to call svGetTime() with an invalid svScope.
* This function returns -1 for all error cases, 0 upon success.
*/
XXTERN int svGetTime(const svScope scope, svTimeVal* time);
/*
* Retrieve the time unit for scope.
* If scope is NULL, then simulation time unit is retrieved.
* It is an error to call svGetTimeUnit() with an invalid svScope.
* This function returns -1 for all error cases, 0 upon success.
*/
XXTERN int svGetTimeUnit(const svScope scope, int32_t* time_unit);
/*
* Retrieve the time precision for scope.
* If scope is NULL, then simulation time unit is retrieved.
* It is an error to call svGetTimePrecision() with an invalid svScope.
* This function returns -1 for all error cases, 0 upon success.
*/
XXTERN int svGetTimePrecision(const svScope scope, int32_t* time_precision);
/*
**********************************************************
* DEPRECATED PORTION OF FILE STARTS FROM HERE.
+11 -4
View File
@@ -1,7 +1,7 @@
/*******************************************************************************
* vpi_user.h
*
* IEEE Std 1800-2017 Programming Language Interface (PLI)
* IEEE Std 1800-2023 Programming Language Interface (PLI)
*
* This file contains the constant definitions, structure definitions, and
* routine declarations used by the SystemVerilog Verification Procedural
@@ -344,6 +344,9 @@ typedef PLI_UINT32 *vpiHandle;
#define vpiSupply0 11 /* supply-0 net */
#define vpiNone 12 /* no default net type (1364-2001) */
#define vpiUwire 13 /* unresolved wire net (1364-2005) */
#define vpiNettypeNet 14 /* user-defined nettype net */
#define vpiNettypeNetSelect 15 /* user-defined nettype net subelement */
#define vpiInterconnect 16 /* interconnect net */
#define vpiExplicitScalared 23 /* explicitly scalared (Boolean) */
#define vpiExplicitVectored 24 /* explicitly vectored (Boolean) */
@@ -573,6 +576,9 @@ typedef PLI_UINT32 *vpiHandle;
/******************************* time structure *******************************/
#ifndef VPI_TIME /* added in 1800-2023 */
#define VPI_TIME
typedef struct t_vpi_time
{
PLI_INT32 type; /* [vpiScaledRealTime, vpiSimTime,
@@ -587,6 +593,8 @@ typedef struct t_vpi_time
#define vpiSimTime 2
#define vpiSuppressTime 3
#endif
/****************************** delay structures ******************************/
typedef struct t_vpi_delay
@@ -741,9 +749,8 @@ typedef struct t_vpi_arrayvalue
typedef struct t_vpi_systf_data
{
PLI_INT32 type; /* vpiSysTask, vpiSysFunc */
PLI_INT32 sysfunctype; /* vpiSysTask, vpi[Int,Real,Time,Sized,
SizedSigned]Func */
PLI_BYTE8 *tfname; /* first character must be '$' */
PLI_INT32 sysfunctype; /* vpi[Int,Real,Time,Sized,SizedSigned]Func */
PLI_BYTE8 *tfname; /* first character has to be '$' */
PLI_INT32 (*calltf)(PLI_BYTE8 *);
PLI_INT32 (*compiletf)(PLI_BYTE8 *);
PLI_INT32 (*sizetf)(PLI_BYTE8 *); /* for sized function callbacks only */
+1 -1
View File
@@ -434,7 +434,7 @@ class CallAnnotationsValidator:
self.process_translation_unit(translation_unit)
self._main_source_file = ""
self._defines = {}
else:
elif len(errors) != 0:
print(f"%Error: parsing failed: {filename}", file=sys.stderr)
for error in errors:
print(f" {error}", file=sys.stderr)

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