Compare commits

...
233 Commits
Author SHA1 Message Date
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
1100 changed files with 89513 additions and 37529 deletions
+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
+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.024
HOMEPAGE_URL https://verilator.org
LANGUAGES CXX
)
+111 -2
View File
@@ -8,12 +8,121 @@ The changes in each Verilator version are described below. The
contributors that suggested a given feature are shown in []. Thanks!
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'.
@@ -271,7 +380,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]
+55 -26
View File
@@ -112,7 +112,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 +203,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 +236,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 +294,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 +306,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 +333,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 +368,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 +427,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 +438,7 @@ PY_PROGRAMS = \
src/cppcheck_filtered \
src/flexfix \
src/vlcovgen \
src/.gdbinit.py \
test_regress/t/*.pf \
nodist/clang_check_attributes \
nodist/code_coverage \
+4 -4
View File
@@ -66,9 +66,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,12 +80,12 @@ 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
Verilator has typically similar or better performance versus
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
+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,";
+66 -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
@@ -383,7 +401,6 @@ 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
@@ -404,24 +421,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 +471,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 +494,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 +510,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
+6 -6
View File
@@ -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 ||
sudo apt-get install gdb gtkwave lcov libfl-dev ccache jq
# 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
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
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-
+4 -25
View File
@@ -10,7 +10,7 @@
# 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.024 2024-04-05],
[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],
@@ -319,15 +305,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 +424,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 +475,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)
+13
View File
@@ -4,6 +4,7 @@ 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
@@ -18,10 +19,12 @@ Andrew Nolte
Anthony Donlon
Arkadiusz Kozdra
Aylon Chaim Porat
Bartłomiej Chmiel
Cameron Kirk
Chih-Mao Chen
Chris Randall
Chuxuan Wang
Chykon
Conor McCullough
Dan Petrisko
Daniel Bates
@@ -43,6 +46,7 @@ february cozzocrea
Felix Neumärker
Felix Yan
Frans Skarman
Fuad Ismail
G-A. Kamendje
Garrett Smith
Geza Lore
@@ -73,6 +77,7 @@ James Shi
Jamey Hicks
Jamie Iles
Jan Van Winkel
Jiangjie Weng
Jean Berniolles
Jeremy Bennett
Jesse Taube
@@ -86,6 +91,7 @@ John Coiner
John Demme
John Wehle
Jonathan Drolet
Jonathan Schröter
Jordan McConnon
Jose Loyola
Josep Sans
@@ -98,8 +104,10 @@ Justin Thiel
Kaleb Barrett
Kamil Rakoczy
Kanad Kanhere
Kefa Chen
Keith Colbert
Kevin Kiningham
Kevin Nygaard
Kritik Bhimani
Krzysztof Bieganski
Krzysztof Boronski
@@ -130,10 +138,13 @@ Mostafa Gamal
Nandu Raj
Nathan Kohagen
Nathan Myers
Nolan Poe
Oleh Maksymenko
Patrick Stewart
Paul Swirhun
Paul Wright
Pawel Sagan
Pengcheng Xu
Peter Debacker
Peter Horvath
Peter Monsson
@@ -159,6 +170,7 @@ Srinivasan Venkataramanan
Stefan Wallentowitz
Stephen Henry
Steven Hugg
Szymon Gizler
Sören Tempel
Teng Huang
Tim Hutt
@@ -181,6 +193,7 @@ Vito Gamberini
William D. Jones
Wilson Snyder
Xi Zhang
Yan Xu
Yinan Xu
Yoda Lee
Yossi Nivin
+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.
+1 -1
View File
@@ -500,7 +500,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.
+5
View File
@@ -118,6 +118,11 @@ associated programs.
See :ref:`Installation` for more details.
.. 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
+160 -17
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
@@ -1128,11 +1174,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 +1238,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 +1294,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 +1307,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 +1321,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 +1519,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 +1549,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
@@ -1695,19 +1799,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
+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
+3 -2
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
+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.
+80 -12
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.
@@ -283,7 +283,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 +479,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 +707,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 +763,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:
@@ -1328,10 +1328,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 +1732,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 +1974,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 +1990,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 +2006,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 +2021,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 +2156,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
+113 -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.
@@ -1696,6 +1696,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 +1846,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 +1921,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 +1976,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 +2033,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 +2079,9 @@ simultaneously.
--vltmt
Run Verilator tests in multithreaded mode.
--xrun
Run Cadence Xcelium simulator tests.
--xsim
Run Xilinx XSim simulator tests.
+21
View File
@@ -71,6 +71,7 @@ Deadman
Debacker
Deepa
Defparams
Delm
Denio
Deprecations
Deroo
@@ -146,6 +147,7 @@ Grulfen
Gu
Gunter
Guo
Hameed
Hao
Haojin
Harboe
@@ -180,9 +182,11 @@ Jannis
Jasen
Jens
Jeras
Jiaxun
Jiuyang
Joannou
Joly
Josse
Jullien
Junji
Junyi
@@ -437,6 +441,7 @@ Verilog
Vighnesh
Viktor
Vilp
Vlip
Vm
Vukobratovic
Wai
@@ -460,6 +465,7 @@ Xiaoliang
Xiaoyi
Xuan
Xuanqi
Yao
Yazdanbakhsh
Yernagula
Yi
@@ -519,6 +525,7 @@ buildenv
bv
bvs
callValueCbs
callgrind
casex
casez
casted
@@ -583,6 +590,7 @@ der
dereference
desassign
destructor
desynchronization
detections
dev
devcontainer
@@ -613,6 +621,7 @@ dut
dx
dynarray
elab
eliasphanna
elike
elsif
endcase
@@ -635,6 +644,7 @@ envvar
eof
errae
erroring
esynr
et
eval
evals
@@ -666,6 +676,7 @@ foreach
fprintf
fprofile
fread
freloop
frewind
fs
fscanf
@@ -688,6 +699,7 @@ genvars
getenv
getline
ggdb
glibc
gmake
gmon
gotFinish
@@ -732,6 +744,7 @@ ish
isunbounded
isunknown
jobserver
json
jwoutersymatra
killua
lang
@@ -902,6 +915,7 @@ recrem
redeclaring
regs
reloop
replaceShiftOp
resetall
respecified
rodata
@@ -940,6 +954,7 @@ stdin
stdout
stime
stmts
str
strcasecmp
stringification
stringified
@@ -957,8 +972,11 @@ sv
svBitVal
svBitVecVal
svGet
svGetTime
svGetTimePrecision
svLogicVal
svdpi
svgGetTimeUnit
swrite
sys
systemc
@@ -1014,8 +1032,10 @@ unsup
untyped
urandom
uselib
utimes
uwire
uwires
valgrind
vc
vcd
vcddiff
@@ -1047,6 +1067,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
+4 -9
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
@@ -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");
+186 -36
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
*/
@@ -367,22 +372,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 +548,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 +558,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 +580,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 +590,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 +613,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 +623,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 +859,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 +882,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 +1542,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 +1646,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 +1842,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 +2113,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 +2126,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 +3446,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 +5072,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 +5116,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 +5171,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 +5198,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 +5318,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 +5335,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 +5463,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 +5544,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 +5582,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 +5648,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 +5681,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 +5712,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 +5815,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 +5853,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 +5886,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 +5907,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 +5957,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 +6086,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
+245 -100
View File
@@ -71,6 +71,11 @@
# 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
@@ -107,7 +112,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 +141,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 +169,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 +183,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 +605,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 +794,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 +803,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 +812,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 +886,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 +946,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 +979,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 +1047,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 +1088,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
@@ -1196,7 +1206,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 +1215,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 +1370,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 +1439,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 +1510,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 +1731,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;
}
@@ -1860,13 +1874,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 +1945,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;
@@ -2096,10 +2110,11 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) {
if (VL_UNLIKELY(m_end != ~0ULL && m_addr <= m_end && !m_anyAddr)) {
VL_WARN_MT(m_filename.c_str(), m_linenum, "",
"$readmem file ended before specified final address (IEEE 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;
@@ -2248,6 +2263,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 +2418,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 +2454,14 @@ 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_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 +2491,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 +2567,10 @@ std::string VerilatedContext::profVltFilename() const VL_MT_SAFE {
const VerilatedLockGuard lock{m_mutex};
return m_ns.m_profVltFilename;
}
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 +2638,16 @@ void VerilatedContext::internalsDump() const VL_MT_SAFE {
}
void VerilatedContext::addModel(VerilatedModel* modelp) {
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();
}
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 +2680,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 +2740,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 +2752,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 +2777,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 +2824,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 +2856,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 %d threads; alloced %0.0f MB\n", cputime,
threadsInModels(), modelMB);
}
//======================================================================
// VerilatedContext:: Methods - scopes
@@ -2835,6 +2924,37 @@ 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");
return;
}
{
// 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 +3089,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 +3115,29 @@ 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 for 1.5x need, but suggest 2x so small model increase won't cause warning
// if the user follows the suggestions
if (VL_UNLIKELY(haveSize && needSize && haveSize < (needSize + needSize / 2))) {
VL_PRINTF_MT("%%Warning: System has stack size %" PRIu64 " kb"
" which may be too small; suggest 'ulimit -s %" PRIu64 "' or larger\n",
haveSize / 1024, (needSize * 2) / 1024);
}
#else
(void)needSize; // Unused argument
#endif
}
void Verilated::mkdir(const char* dirname) VL_MT_UNSAFE {
#if defined(_WIN32) || defined(__MINGW32__)
::mkdir(dirname);
@@ -3168,8 +3311,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 +3331,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 +3341,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 +3399,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"
+43 -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,24 @@ 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
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 +414,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 +500,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 +516,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 +566,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 +597,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);
@@ -599,6 +632,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 +934,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 +1008,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
-3
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)
+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
+170 -20
View File
@@ -125,19 +125,27 @@ 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;
@@ -255,7 +263,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 +313,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
@@ -511,6 +522,7 @@ static inline void VL_ASSIGNBIT_WO(int bit, WDataOutP owp) VL_MT_SAFE {
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 +1277,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 +1288,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 +1301,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 +1578,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 +1599,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 +2126,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 +2433,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)};
+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];
}
+2 -2
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();
@@ -80,7 +80,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();
+8 -8
View File
@@ -180,7 +180,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,7 +189,7 @@ 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;
@@ -260,7 +260,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 +308,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 +362,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 +374,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 +393,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 +415,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
+23 -12
View File
@@ -179,6 +179,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 +219,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 +249,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
@@ -582,7 +593,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) {
+11 -21
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
+43 -45
View File
@@ -263,7 +263,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 +274,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");
}
//===================================================================
@@ -615,7 +615,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 +776,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 +790,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 +817,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 {
@@ -948,7 +948,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 +1077,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 +1086,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 +1094,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 +1113,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 +1123,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 +1132,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 +1142,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 +1162,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 {
@@ -1592,7 +1590,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 +1646,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 +1656,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 +1671,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 +1686,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 +1705,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 +1749,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
+129 -55
View File
@@ -263,33 +263,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 +410,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 +460,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 +505,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 +584,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 +630,7 @@ public:
void invalidate() { m_id = 0; }
};
struct VerilatedVpiTimedCbsCmp {
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 {
@@ -855,6 +890,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;
};
//======================================================================
@@ -1372,11 +1408,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 +1695,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 +2004,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 +2060,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 +2116,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));
+1 -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"
+48 -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,45 @@ 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
namespace VlOs {
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 +658,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 +683,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
//=========================================================================
+103
View File
@@ -0,0 +1,103 @@
// -*- 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
}
//=========================================================================
} //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)
+20
View File
@@ -20,6 +20,26 @@ document pnt
Verilator: Print AstNode NODEP's tree
end
# Source python-based gdb config with jshow/jdiff definitions
# (Stored in separate file, so it can be highlighted/linted/formatted as Python)
python
import os
if "VERILATOR_ROOT" in os.environ:
gdbinit_py = os.environ["VERILATOR_ROOT"] + "/src/.gdbinit.py"
gdb.execute("source" + gdbinit_py)
end
define jstash
call (char*) &(AstNode::dumpTreeJsonGdb($arg0)[0])
end
document jstash
Verilator: Perform a JSON dump of the given AST node and save it in value history (e.g. $1) for later
inspection using jtree. The node can be a pointer identifier or an address literal.
end
alias -a js=jstash
alias -a jt=jtree
define dtf
call AstNode::dumpTreeFileGdb($arg0, 0)
end
+80
View File
@@ -0,0 +1,80 @@
# pylint: disable=line-too-long,invalid-name,multiple-statements,missing-function-docstring,missing-class-docstring,missing-module-docstring,no-else-return,too-few-public-methods,unused-argument
# DESCRIPTION: Verilator: GDB startup file with useful define
#
# Copyright 2023 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify the Verilator internals under the terms
# of either the GNU Lesser General Public License Version 3 or the Perl
# Artistic License Version 2.0.
#
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
######################################################################
import tempfile
import gdb # pylint: disable=import-error
def _vltgdb_get_dump(node):
gdb.execute(f'set $_gdb_dump_json_str = AstNode::dumpTreeJsonGdb({node})')
dump = gdb.execute('printf "%s", $_gdb_dump_json_str', to_string=True)
gdb.execute('call free($_gdb_dump_json_str)')
return dump
def _vltgdb_tmpfile():
return tempfile.NamedTemporaryFile(mode="wt") # write, text mode
def _vltgdb_fwrite(file, s):
"""Write to file and flush buffer before passing the file to astsee"""
file.write(s)
file.flush()
class AstseeCmd(gdb.Command):
"""Verilator: Pretty print or diff nodes using `astsee`. A node can be:
* an pointer identifier,
* an address literal,
* a GDB value (like `$1`) that stores a dump previously done by the `jstash` command.
Apart from not taking input from a file, it works exactly like `verilator_astsee`:
* passing one node gives you a pretty print,
* passing two nodes gives you a diff,
* for more options see `astsee` readme/help.
For examples see internals.rst
"""
def __init__(self):
super().__init__("jtree", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION)
def _null_check(self, old, new):
err = ""
if old == "<nullptr>\n": err += "old == <nullptr>\n"
if new == "<nullptr>\n": err += "new == <nullptr>"
if err: raise gdb.GdbError(err.strip("\n"))
def invoke(self, arg_str, from_tty):
from astsee import verilator_cli as astsee # pylint: disable=import-error,import-outside-toplevel
# we import it here so "no module X" error would occur on typing `jtree` rather than on every gdb start
# We hack `astsee_verilator`'s arg parser to find arguments with nodes
# After finding them, we replace them with proper files
astsee_args = astsee.parser.parse_args(gdb.string_to_argv(arg_str))
with _vltgdb_tmpfile() as oldfile, _vltgdb_tmpfile(
) as newfile, _vltgdb_tmpfile() as metafile:
if astsee_args.file:
_vltgdb_fwrite(oldfile, _vltgdb_get_dump(astsee_args.file))
astsee_args.file = oldfile.name
if astsee_args.newfile:
_vltgdb_fwrite(newfile, _vltgdb_get_dump(astsee_args.newfile))
astsee_args.newfile = newfile.name
if astsee_args.meta is None:
# pass
gdb.execute(
f'call AstNode::dumpJsonMetaFileGdb("{metafile.name}")')
astsee_args.meta = metafile.name
try:
astsee.main(astsee_args)
except SystemExit as e: # astsee prints nice errmsgs on exit(), so rethrow it as GdbError to suppress cryptic python trace
raise gdb.GdbError("astsee exited with non-zero code") from e
AstseeCmd()
+16 -4
View File
@@ -62,8 +62,10 @@ set(HEADERS
V3DepthBlock.h
V3Descope.h
V3Dfg.h
V3DfgCache.h
V3DfgOptimizer.h
V3DfgPasses.h
V3DfgPatternStats.h
V3DfgPeephole.h
V3DfgVertices.h
V3DupFinder.h
@@ -77,6 +79,7 @@ set(HEADERS
V3EmitV.h
V3EmitXml.h
V3Error.h
V3ExecGraph.h
V3Expand.h
V3File.h
V3FileLine.h
@@ -119,6 +122,7 @@ set(HEADERS
V3OptionParser.h
V3Options.h
V3Order.h
V3OrderInternal.h
V3OrderGraph.h
V3OrderMoveGraph.h
V3Os.h
@@ -127,10 +131,9 @@ set(HEADERS
V3Parse.h
V3ParseImp.h
V3ParseSym.h
V3Partition.h
V3PartitionGraph.h
V3PchAstMT.h
V3PchAstNoMT.h
V3PreExpr.h
V3PreLex.h
V3PreProc.h
V3PreShell.h
@@ -149,6 +152,7 @@ set(HEADERS
V3Split.h
V3SplitAs.h
V3SplitVar.h
V3StackCount.h
V3Stats.h
V3StdFuture.h
V3String.h
@@ -211,11 +215,13 @@ set(COMMON_SOURCES
V3Descope.cpp
V3Dfg.cpp
V3DfgAstToDfg.cpp
V3DfgCache.cpp
V3DfgDecomposition.cpp
V3DfgDfgToAst.cpp
V3DfgOptimizer.cpp
V3DfgPasses.cpp
V3DfgPeephole.cpp
V3DfgRegularize.cpp
V3DupFinder.cpp
V3Timing.cpp
V3EmitCBase.cpp
@@ -233,6 +239,7 @@ set(COMMON_SOURCES
V3EmitV.cpp
V3EmitXml.cpp
V3Error.cpp
V3ExecGraph.cpp
V3Expand.cpp
V3File.cpp
V3FileLine.cpp
@@ -258,8 +265,8 @@ set(COMMON_SOURCES
V3LinkDot.cpp
V3LinkInc.cpp
V3LinkJump.cpp
V3LinkLevel.cpp
V3LinkLValue.cpp
V3LinkLevel.cpp
V3LinkParse.cpp
V3LinkResolve.cpp
V3Localize.cpp
@@ -269,9 +276,13 @@ set(COMMON_SOURCES
V3OptionParser.cpp
V3Options.cpp
V3Order.cpp
V3OrderGraphBuilder.cpp
V3OrderMoveGraph.cpp
V3OrderParallel.cpp
V3OrderProcessDomains.cpp
V3OrderSerial.cpp
V3Os.cpp
V3Param.cpp
V3Partition.cpp
V3PreShell.cpp
V3Premit.cpp
V3ProtectLib.cpp
@@ -289,6 +300,7 @@ set(COMMON_SOURCES
V3Split.cpp
V3SplitAs.cpp
V3SplitVar.cpp
V3StackCount.cpp
V3Stats.cpp
V3StatsReport.cpp
V3String.cpp
+9 -1
View File
@@ -228,11 +228,13 @@ RAW_OBJS_PCH_ASTNOMT = \
V3Descope.o \
V3Dfg.o \
V3DfgAstToDfg.o \
V3DfgCache.o \
V3DfgDecomposition.o \
V3DfgDfgToAst.o \
V3DfgOptimizer.o \
V3DfgPasses.o \
V3DfgPeephole.o \
V3DfgRegularize.o \
V3DupFinder.o \
V3EmitCMain.o \
V3EmitCMake.o \
@@ -240,6 +242,7 @@ RAW_OBJS_PCH_ASTNOMT = \
V3EmitCSyms.o \
V3EmitMk.o \
V3EmitXml.o \
V3ExecGraph.o \
V3Expand.o \
V3Force.o \
V3Fork.o \
@@ -263,8 +266,12 @@ RAW_OBJS_PCH_ASTNOMT = \
V3MergeCond.o \
V3Name.o \
V3Order.o \
V3OrderGraphBuilder.o \
V3OrderMoveGraph.o \
V3OrderParallel.o \
V3OrderProcessDomains.o \
V3OrderSerial.o \
V3Param.o \
V3Partition.o \
V3Premit.o \
V3ProtectLib.o \
V3Randomize.o \
@@ -281,6 +288,7 @@ RAW_OBJS_PCH_ASTNOMT = \
V3Split.o \
V3SplitAs.o \
V3SplitVar.o \
V3StackCount.o \
V3Subst.o \
V3TSP.o \
V3Table.o \
+6 -7
View File
@@ -97,8 +97,8 @@ protected:
result = vertexp->user();
break;
case LatchDetectGraphVertex::VT_BLOCK: // (OR of potentially many siblings)
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
if (latchCheckInternal(castVertexp(edgep->top()))) {
for (V3GraphEdge& edge : vertexp->outEdges()) {
if (latchCheckInternal(castVertexp(edge.top()))) {
result = true;
break;
}
@@ -106,9 +106,8 @@ protected:
break;
case LatchDetectGraphVertex::VT_BRANCH: // (AND of both sibling)
// A BRANCH vertex always has exactly 2 siblings
LatchDetectGraphVertex* const ifp = castVertexp(vertexp->outBeginp()->top());
LatchDetectGraphVertex* const elsp
= castVertexp(vertexp->outBeginp()->outNextp()->top());
LatchDetectGraphVertex* const ifp = castVertexp(vertexp->outEdges().frontp()->top());
LatchDetectGraphVertex* const elsp = castVertexp(vertexp->outEdges().backp()->top());
result = latchCheckInternal(ifp) && latchCheckInternal(elsp);
break;
}
@@ -170,7 +169,7 @@ public:
for (const auto& vrp : m_outputs) {
LatchDetectGraphVertex* const vertp = castVertexp(vrp->varp()->user1p());
vertp->user(true); // Identify the output vertex we are checking paths _to_
if (!latchCheckInternal(castVertexp(verticesBeginp()))) latch_detected = true;
if (!latchCheckInternal(castVertexp(vertices().frontp()))) latch_detected = true;
if (latch_detected && !latch_expected) {
nodep->v3warn(
LATCH,
@@ -648,5 +647,5 @@ public:
void V3Active::activeAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{ ActiveVisitor{nodep}; } // Destruct before checking
V3Global::dumpCheckGlobalTree("active", 0, dumpTreeLevel() >= 3);
V3Global::dumpCheckGlobalTree("active", 0, dumpTreeEitherLevel() >= 3);
}
+16 -1
View File
@@ -77,6 +77,21 @@ class ActiveTopVisitor final : public VNVisitor {
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return;
}
// Delete empty procedures
for (AstNode *stmtp = nodep->stmtsp(), *nextp; stmtp; stmtp = nextp) {
nextp = stmtp->nextp();
if (AstNodeProcedure* const procp = VN_CAST(stmtp, NodeProcedure)) {
if (!procp->stmtsp()) VL_DO_DANGLING(pushDeletep(procp->unlinkFrBack()), stmtp);
}
}
// Delete empty actives
if (!nodep->stmtsp()) {
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return;
}
// Move the SENTREE for each active up to the global level.
// This way we'll easily see what clock domains are identical
AstSenTree* const wantp = m_finder.getSenTree(sensesp);
@@ -142,5 +157,5 @@ public:
void V3ActiveTop::activeTopAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{ ActiveTopVisitor{nodep}; } // Destruct before checking
V3Global::dumpCheckGlobalTree("activetop", 0, dumpTreeLevel() >= 3);
V3Global::dumpCheckGlobalTree("activetop", 0, dumpTreeEitherLevel() >= 3);
}
+68 -31
View File
@@ -26,6 +26,13 @@ VL_DEFINE_DEBUG_FUNCTIONS;
// Assert class functions
class AssertVisitor final : public VNVisitor {
// TYPES
enum assertType_e : uint8_t {
ASSERT_TYPE_INTRINSIC, // AstNodeAssertIntrinsinc
ASSERT_TYPE_SVA, // SVA, PSL
ASSERT_TYPE_CASE, // unique/unique0/priority case related checks
ASSERT_TYPE_IF // unique/unique0/priority if related checks
};
// NODE STATE/TYPES
// Cleared on netlist
// AstNode::user() -> bool. True if processed
@@ -47,6 +54,12 @@ class AssertVisitor final : public VNVisitor {
bool m_inSampled = false; // True inside a sampled expression
// METHODS
static bool assertTypeOn(assertType_e assertType) {
if (assertType == ASSERT_TYPE_INTRINSIC) return true;
if (v3Global.opt.assertOn()) return true;
if (assertType == ASSERT_TYPE_CASE && v3Global.opt.assertCaseOn()) return true;
return false;
}
string assertDisplayMessage(AstNode* nodep, const string& prefix, const string& message,
VDisplayType severity) {
if (severity == VDisplayType::DT_ERROR || severity == VDisplayType::DT_FATAL) {
@@ -99,7 +112,7 @@ class AssertVisitor final : public VNVisitor {
varrefp->classOrPackagep(v3Global.rootp()->dollarUnitPkgAddp());
return varrefp;
}
AstNode* newIfAssertOn(AstNode* nodep, bool force) {
AstNode* newIfAssertOn(AstNode* nodep, assertType_e assertType) {
// Add a internal if to check assertions are on.
// Don't make this a AND term, as it's unlikely to need to test this.
FileLine* const fl = nodep->fileline();
@@ -107,8 +120,9 @@ class AssertVisitor final : public VNVisitor {
// If assertions are off, have constant propagation rip them out later
// This allows syntax errors and such to be detected normally.
AstNodeExpr* const condp
= force ? static_cast<AstNodeExpr*>(new AstConst{fl, AstConst::BitTrue{}})
: v3Global.opt.assertOn()
= assertType == ASSERT_TYPE_INTRINSIC
? static_cast<AstNodeExpr*>(new AstConst{fl, AstConst::BitTrue{}})
: assertTypeOn(assertType)
? static_cast<AstNodeExpr*>(
new AstCExpr{fl, "vlSymsp->_vm_contextp__->assertOn()", 1})
: static_cast<AstNodeExpr*>(new AstConst{fl, AstConst::BitFalse{}});
@@ -118,20 +132,23 @@ class AssertVisitor final : public VNVisitor {
return newp;
}
AstNode* newFireAssertUnchecked(AstNode* nodep, const string& message) {
AstNode* newFireAssertUnchecked(AstNode* nodep, const string& message,
AstNodeExpr* exprsp = nullptr) {
// Like newFireAssert() but omits the asserts-on check
AstDisplay* const dispp
= new AstDisplay{nodep->fileline(), VDisplayType::DT_ERROR, message, nullptr, nullptr};
dispp->fmtp()->timeunit(m_modp->timeunit());
AstNode* const bodysp = dispp;
replaceDisplay(dispp, "%%Error"); // Convert to standard DISPLAY format
bodysp->addNext(new AstStop{nodep->fileline(), true});
if (exprsp) dispp->fmtp()->exprsp()->addNext(exprsp);
if (v3Global.opt.stopFail()) bodysp->addNext(new AstStop{nodep->fileline(), true});
return bodysp;
}
AstNode* newFireAssert(AstNode* nodep, const string& message) {
AstNode* bodysp = newFireAssertUnchecked(nodep, message);
bodysp = newIfAssertOn(bodysp, false);
AstNode* newFireAssert(AstNode* nodep, assertType_e assertType, const string& message,
AstNodeExpr* exprsp = nullptr) {
AstNode* bodysp = newFireAssertUnchecked(nodep, message, exprsp);
bodysp = newIfAssertOn(bodysp, assertType);
return bodysp;
}
@@ -153,7 +170,7 @@ class AssertVisitor final : public VNVisitor {
if (m_procedurep) {
// To support this need queue of asserts to activate
nodep->v3error("Unsupported: Procedural concurrent assertion with"
" clocking event inside always (IEEE 1800-2017 16.14.6)");
" clocking event inside always (IEEE 1800-2023 16.14.6)");
}
}
//
@@ -183,16 +200,17 @@ class AssertVisitor final : public VNVisitor {
} else {
++m_statAsNotImm;
}
const bool force = VN_IS(nodep, AssertIntrinsic);
if (passsp) passsp = newIfAssertOn(passsp, force);
if (failsp) failsp = newIfAssertOn(failsp, force);
const assertType_e assertType
= VN_IS(nodep, AssertIntrinsic) ? ASSERT_TYPE_INTRINSIC : ASSERT_TYPE_SVA;
if (passsp) passsp = newIfAssertOn(passsp, assertType);
if (failsp) failsp = newIfAssertOn(failsp, assertType);
if (!passsp && !failsp) failsp = newFireAssertUnchecked(nodep, "'assert' failed.");
ifp = new AstIf{nodep->fileline(), propp, passsp, failsp};
ifp->isBoundsCheck(true); // To avoid LATCH warning
// It's more LIKELY that we'll take the nullptr if clause
// than the sim-killing else clause:
ifp->branchPred(VBranchPred::BP_LIKELY);
bodysp = newIfAssertOn(ifp, force);
bodysp = newIfAssertOn(ifp, assertType);
} else {
nodep->v3fatalSrc("Unknown node type");
}
@@ -263,9 +281,9 @@ class AssertVisitor final : public VNVisitor {
= ((allow_none || hasDefaultElse)
? static_cast<AstNodeExpr*>(new AstOneHot0{nodep->fileline(), propp})
: static_cast<AstNodeExpr*>(new AstOneHot{nodep->fileline(), propp}));
AstIf* const checkifp
= new AstIf{nodep->fileline(), new AstLogNot{nodep->fileline(), ohot},
newFireAssert(nodep, "'unique if' statement violated"), newifp};
AstIf* const checkifp = new AstIf{
nodep->fileline(), new AstLogNot{nodep->fileline(), ohot},
newFireAssert(nodep, ASSERT_TYPE_IF, "'unique if' statement violated"), newifp};
checkifp->isBoundsCheck(true); // To avoid LATCH warning
checkifp->branchPred(VBranchPred::BP_UNLIKELY);
nodep->replaceWith(checkifp);
@@ -284,13 +302,20 @@ class AssertVisitor final : public VNVisitor {
itemp = VN_AS(itemp->nextp(), CaseItem)) {
if (itemp->isDefault()) has_default = true;
}
const AstNodeDType* exprDtypep = nodep->exprp()->dtypep()->skipRefp();
string valFmt;
if (exprDtypep->isIntegralOrPacked())
valFmt = " for '" + cvtToStr(exprDtypep->widthMin()) + "'h%X'";
if (nodep->fullPragma() || nodep->priorityPragma()) {
// Need to add a default if there isn't one already
++m_statAsFull;
if (!has_default) {
nodep->addItemsp(new AstCaseItem{
nodep->fileline(), nullptr /*DEFAULT*/,
newFireAssert(nodep, "synthesis full_case, but non-match found")});
newFireAssert(nodep, ASSERT_TYPE_CASE,
nodep->pragmaString() + ", but non-match found" + valFmt,
valFmt.empty() ? nullptr
: nodep->exprp()->cloneTreePure(false))});
}
}
if (nodep->parallelPragma() || nodep->uniquePragma() || nodep->unique0Pragma()) {
@@ -328,20 +353,32 @@ class AssertVisitor final : public VNVisitor {
}
// Empty case means no property
if (!propp) propp = new AstConst{nodep->fileline(), AstConst::BitFalse{}};
const bool allow_none = has_default || nodep->unique0Pragma();
AstNodeExpr* const ohot
= (allow_none ? static_cast<AstNodeExpr*>(
new AstOneHot0{nodep->fileline(), propp})
: static_cast<AstNodeExpr*>(
new AstOneHot{nodep->fileline(), propp}));
AstIf* const ifp = new AstIf{
nodep->fileline(), new AstLogNot{nodep->fileline(), ohot},
newFireAssert(nodep,
"synthesis parallel_case, but multiple matches found")};
ifp->isBoundsCheck(true); // To avoid LATCH warning
ifp->branchPred(VBranchPred::BP_UNLIKELY);
nodep->addNotParallelp(ifp);
// The following assertion lools as below.
// if (!$onehot(propp)) begin
// if (propp == '0) begin if (!allow_none) $error("none match"); end
// else $error("multiple match");
// end
AstNodeExpr* const ohot = new AstOneHot{nodep->fileline(), propp};
AstIf* const ohotIfp
= new AstIf{nodep->fileline(), new AstLogNot{nodep->fileline(), ohot}};
AstIf* const zeroIfp
= new AstIf{nodep->fileline(),
new AstLogNot{nodep->fileline(), propp->cloneTreePure(false)}};
AstNodeExpr* const exprp = nodep->exprp();
const string pragmaStr = nodep->pragmaString();
if (!allow_none)
zeroIfp->addThensp(newFireAssert(
nodep, ASSERT_TYPE_CASE, pragmaStr + ", but none matched" + valFmt,
valFmt.empty() ? nullptr : exprp->cloneTreePure(false)));
zeroIfp->addElsesp(
newFireAssert(nodep, ASSERT_TYPE_CASE,
pragmaStr + ", but multiple matches found" + valFmt,
valFmt.empty() ? nullptr : exprp->cloneTreePure(false)));
ohotIfp->addThensp(zeroIfp);
ohotIfp->isBoundsCheck(true); // To avoid LATCH warning
ohotIfp->branchPred(VBranchPred::BP_UNLIKELY);
nodep->addNotParallelp(ohotIfp);
}
}
}
@@ -540,5 +577,5 @@ public:
void V3Assert::assertAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{ AssertVisitor{nodep}; } // Destruct before checking
V3Global::dumpCheckGlobalTree("assert", 0, dumpTreeLevel() >= 3);
V3Global::dumpCheckGlobalTree("assert", 0, dumpTreeEitherLevel() >= 3);
}
+20 -15
View File
@@ -115,8 +115,9 @@ private:
AstArg* const argp = tconnect.second;
AstNode* const pinp = argp->exprp()->unlinkFrBack();
replaceVarRefsWithExprRecurse(propExprp, portp, pinp);
VL_DO_DANGLING(pushDeletep(pinp), pinp);
}
// Handle case with 2 disable iff statement (IEEE 1800-2017 16.12.1)
// Handle case with 2 disable iff statement (IEEE 1800-2023 16.12.1)
if (nodep->disablep() && propExprp->disablep()) {
nodep->v3error("disable iff expression before property call and in its "
"body is not legal");
@@ -160,7 +161,7 @@ private:
FileLine* const flp = nodep->fileline();
V3Const::constifyEdit(nodep->skewp());
if (!VN_IS(nodep->skewp(), Const)) {
nodep->skewp()->v3error("Skew must be constant (IEEE 1800-2017 14.4)");
nodep->skewp()->v3error("Skew must be constant (IEEE 1800-2023 14.4)");
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return;
}
@@ -176,7 +177,7 @@ private:
skewedRefp->user1(true);
AstAssign* const assignp = new AstAssign{flp, exprp->cloneTreePure(false), skewedRefp};
if (skewp->isZero()) {
// Drive the var in Re-NBA (IEEE 1800-2017 14.16)
// Drive the var in Re-NBA (IEEE 1800-2023 14.16)
m_clockingp->addNextHere(new AstAlwaysReactive{
flp, new AstSenTree{flp, m_clockingp->sensesp()->cloneTree(false)}, assignp});
} else if (skewp->fileline()->timingOn()) {
@@ -189,7 +190,9 @@ private:
m_clockingp->addNextHere(new AstAlwaysObserved{
flp, new AstSenTree{flp, m_clockingp->sensesp()->cloneTree(false)}, forkp});
if (v3Global.opt.timing().isSetTrue()) {
assignp->timingControlp(new AstDelay{flp, skewp->unlinkFrBack(), false});
AstDelay* const delayp = new AstDelay{flp, skewp->unlinkFrBack(), false};
delayp->timeunit(m_modp->timeunit());
assignp->timingControlp(delayp);
} else if (v3Global.opt.timing().isSetFalse()) {
nodep->v3warn(E_NOTIMING,
"Clocking output skew greater than #0 requires --timing");
@@ -204,12 +207,12 @@ private:
AstVarRef* const refp = new AstVarRef{flp, varp, VAccess::WRITE};
refp->user1(true);
if (skewp->num().is1Step()) {
// Assign the sampled expression to the clockvar (IEEE 1800-2017 14.13)
// Assign the sampled expression to the clockvar (IEEE 1800-2023 14.13)
AstSampled* const sampledp = new AstSampled{flp, exprp->cloneTreePure(false)};
sampledp->dtypeFrom(exprp);
m_clockingp->addNextHere(new AstAssignW{flp, refp, sampledp});
} else if (skewp->isZero()) {
// #0 means the var has to be sampled in Observed (IEEE 1800-2017 14.13)
// #0 means the var has to be sampled in Observed (IEEE 1800-2023 14.13)
AstAssign* const assignp = new AstAssign{flp, refp, exprp->cloneTreePure(false)};
m_clockingp->addNextHere(new AstAlwaysObserved{
flp, new AstSenTree{flp, m_clockingp->sensesp()->cloneTree(false)}, assignp});
@@ -254,13 +257,13 @@ private:
if (!nodep->isCycleDelay()) {
if (m_inSynchDrive) {
nodep->v3error("Only cycle delays can be used in synchronous drives"
" (IEEE 1800-2017 14.16)");
" (IEEE 1800-2023 14.16)");
}
return;
}
if (m_inAssign && !m_inSynchDrive) {
nodep->v3error("Cycle delays not allowed as intra-assignment delays"
" (IEEE 1800-2017 14.11)");
" (IEEE 1800-2023 14.11)");
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return;
}
@@ -271,12 +274,14 @@ private:
if (constp->isZero()) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: ##0 delays");
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
VL_DO_DANGLING(valuep->deleteTree(), valuep);
return;
}
if (!m_defaultClockingp) {
nodep->v3error("Usage of cycle delays requires default clocking"
" (IEEE 1800-2017 14.11)");
" (IEEE 1800-2023 14.11)");
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
VL_DO_DANGLING(valuep->deleteTree(), valuep);
return;
}
AstEventControl* const controlp = new AstEventControl{
@@ -300,24 +305,24 @@ private:
void visit(AstSenTree* nodep) override {
if (m_inSynchDrive) {
nodep->v3error("Event controls cannot be used in "
"synchronous drives (IEEE 1800-2017 14.16)");
"synchronous drives (IEEE 1800-2023 14.16)");
}
}
void visit(AstNodeVarRef* nodep) override {
if (AstClockingItem* const itemp = VN_CAST(nodep->varp()->user1p(), ClockingItem)) {
if (nodep->access().isReadOrRW() && !nodep->user1()
&& itemp->direction() == VDirection::OUTPUT) {
nodep->v3error("Cannot read from output clockvar (IEEE 1800-2017 14.3)");
nodep->v3error("Cannot read from output clockvar (IEEE 1800-2023 14.3)");
}
if (nodep->access().isWriteOrRW()) {
if (itemp->direction() == VDirection::OUTPUT) {
if (!m_inAssignDlyLhs) {
nodep->v3error("Only non-blocking assignments can write "
"to clockvars (IEEE 1800-2017 14.16)");
"to clockvars (IEEE 1800-2023 14.16)");
}
if (m_inAssign) m_inSynchDrive = true;
} else if (!nodep->user1() && itemp->direction() == VDirection::INPUT) {
nodep->v3error("Cannot write to input clockvar (IEEE 1800-2017 14.3)");
nodep->v3error("Cannot write to input clockvar (IEEE 1800-2023 14.3)");
}
}
}
@@ -461,7 +466,7 @@ private:
if (clockingp->isDefault()) {
if (m_defaultClockingp) {
clockingp->v3error("Only one default clocking block allowed per module"
" (IEEE 1800-2017 14.12)");
" (IEEE 1800-2023 14.12)");
}
m_defaultClockingp = clockingp;
}
@@ -493,5 +498,5 @@ public:
void V3AssertPre::assertPreAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{ AssertPreVisitor{nodep}; } // Destruct before checking
V3Global::dumpCheckGlobalTree("assertpre", 0, dumpTreeLevel() >= 3);
V3Global::dumpCheckGlobalTree("assertpre", 0, dumpTreeEitherLevel() >= 3);
}
+79 -21
View File
@@ -17,11 +17,11 @@
#include "V3PchAstMT.h"
#include "V3Broken.h"
#include "V3EmitV.h"
#include "V3File.h"
#include <iomanip>
#include <memory>
#include <sstream>
VL_DEFINE_DEBUG_FUNCTIONS;
@@ -1116,6 +1116,7 @@ bool AstNode::sameTreeIter(const AstNode* node1p, const AstNode* node2p, bool ig
void AstNode::checkTreeIter(const AstNode* prevBackp) const VL_MT_STABLE {
// private: Check a tree and children
UASSERT_OBJ(prevBackp == this->backp(), this, "Back node inconsistent");
// cppcheck-suppress danglingTempReference
const VNTypeInfo& typeInfo = *type().typeInfo();
for (int i = 1; i <= 4; i++) {
AstNode* nodep = nullptr;
@@ -1126,6 +1127,7 @@ void AstNode::checkTreeIter(const AstNode* prevBackp) const VL_MT_STABLE {
case 4: nodep = op4p(); break;
default: this->v3fatalSrc("Bad case"); break;
}
// cppcheck-suppress danglingTempReference
const char* opName = typeInfo.m_opNamep[i - 1];
switch (typeInfo.m_opType[i - 1]) {
case VNTypeInfo::OP_UNUSED:
@@ -1142,7 +1144,7 @@ void AstNode::checkTreeIter(const AstNode* prevBackp) const VL_MT_STABLE {
case VNTypeInfo::OP_LIST:
if (const AstNode* const headp = nodep) {
const AstNode* backp = this;
const AstNode* tailp = headp;
const AstNode* tailp;
const AstNode* opp = headp;
do {
opp->checkTreeIter(backp);
@@ -1168,8 +1170,50 @@ void AstNode::checkTreeIter(const AstNode* prevBackp) const VL_MT_STABLE {
default: this->v3fatalSrc("Bad case"); break;
}
}
if (v3Global.opt.debugWidth() && v3Global.widthMinUsage() == VWidthMinUsage::VERILOG_WIDTH) {
if (const AstNodeExpr* const exprp = VN_CAST(this, NodeExpr)) {
const char* const whyp = exprp->widthMismatch();
if (whyp) {
auto dtypeStr = [](const AstNodeExpr* exprp) VL_MT_STABLE {
std::ostringstream ss;
exprp->dtypep()->dumpSmall(ss);
return ss.str();
};
if (const AstNodeUniop* const uniopp = VN_CAST(exprp, NodeUniop)) {
UASSERT_OBJ(!whyp, uniopp,
"widthMismatch detected " << whyp << "OUT:" << dtypeStr(uniopp)
<< " LHS:" << dtypeStr(uniopp->lhsp()));
} else if (const AstNodeBiop* const biopp = VN_CAST(exprp, NodeBiop)) {
UASSERT_OBJ(!whyp, biopp,
"widthMismatch detected " << whyp << "OUT:" << dtypeStr(biopp)
<< " LHS:" << dtypeStr(biopp->lhsp())
<< " RHS:" << dtypeStr(biopp->rhsp()));
} else {
UASSERT_OBJ(false, exprp,
"widthMismatch detected " << whyp << " in an unexpected type");
}
}
}
}
}
// cppcheck-suppress unusedFunction // Debug only
char* AstNode::dumpTreeJsonGdb(const AstNode* nodep) {
if (!nodep) return strdup("{\"addr\":\"NULL\"}\n");
std::stringstream nodepStream;
nodep->dumpTreeJson(nodepStream);
const std::string str = nodepStream.rdbuf()->str();
return strdup(str.c_str());
}
// cppcheck-suppress unusedFunction // Debug only
// identity func to allow for passing already done dumps to jtree
char* AstNode::dumpTreeJsonGdb(const char* str) { return strdup(str); }
// cppcheck-suppress unusedFunction // Debug only
// allow for passing pointer literals like 0x42.. without manual cast
char* AstNode::dumpTreeJsonGdb(intptr_t nodep) {
if (!nodep) return strdup("{\"addr\":\"NULL\"}\n");
return dumpTreeJsonGdb((const AstNode*)nodep);
}
// cppcheck-suppress unusedFunction // Debug only
void AstNode::dumpGdb(const AstNode* nodep) { // For GDB only // LCOV_EXCL_LINE
if (!nodep) {
@@ -1273,7 +1317,7 @@ void AstNode::dumpTreeAndNext(std::ostream& os, const string& indent, int maxDep
}
}
void AstNode::dumpTreeFile(const string& filename, bool doDump, bool doCheck) {
void AstNode::dumpTreeFile(const string& filename, bool doDump) {
// Not const function as calls checkTree
if (doDump) {
{ // Write log & close
@@ -1291,14 +1335,6 @@ void AstNode::dumpTreeFile(const string& filename, bool doDump, bool doCheck) {
}
}
}
if (doDump && v3Global.opt.debugEmitV()) V3EmitV::debugEmitV(filename + ".v");
if (doCheck && (v3Global.opt.debugCheck() || ::dumpTreeLevel())) {
// Error check
checkTree();
// Broken isn't part of check tree because it can munge iterp's
// set by other steps if it is called in the middle of other operations
if (AstNetlist* const netp = VN_CAST(this, Netlist)) V3Broken::brokenAll(netp);
}
}
static void drawChildren(std::ostream& os, const AstNode* thisp, const AstNode* childp,
@@ -1328,6 +1364,29 @@ void AstNode::dumpTreeDot(std::ostream& os) const {
drawChildren(os, this, m_op4p, "op4");
}
void AstNode::dumpTreeJsonFile(const string& filename, bool doDump) {
if (!doDump) return;
UINFO(2, "Dumping " << filename << endl);
const std::unique_ptr<std::ofstream> treejsonp{V3File::new_ofstream(filename)};
if (treejsonp->fail()) v3fatal("Can't write " << filename);
dumpTreeJson(*treejsonp);
*treejsonp << '\n';
}
void AstNode::dumpJsonMetaFileGdb(const char* filename) { dumpJsonMetaFile(filename); }
void AstNode::dumpJsonMetaFile(const string& filename) {
UINFO(2, "Dumping " << filename << endl);
const std::unique_ptr<std::ofstream> treejsonp{V3File::new_ofstream(filename)};
if (treejsonp->fail()) v3fatalStatic("Can't write " << filename);
*treejsonp << '{';
FileLine::fileNameNumMapDumpJson(*treejsonp);
*treejsonp << ',';
v3Global.idPtrMapDumpJson(*treejsonp);
*treejsonp << ',';
v3Global.ptrNamesDumpJson(*treejsonp);
*treejsonp << "}\n";
}
void AstNode::dumpTreeDotFile(const string& filename, bool doDump) {
if (doDump) {
UINFO(2, "Dumping " << filename << endl);
@@ -1505,8 +1564,7 @@ static VCastable computeCastableImp(const AstNodeDType* toDtp, const AstNodeDTyp
return VCastable::ENUM_IMPLICIT;
if (fromNumericable) return VCastable::ENUM_EXPLICIT;
} else if (VN_IS(toDtp, ClassRefDType) && VN_IS(fromConstp, Const)) {
if (VN_IS(fromConstp, Const) && VN_AS(fromConstp, Const)->num().isNull())
return VCastable::COMPATIBLE;
if (fromConstp->isNull()) return VCastable::COMPATIBLE;
} else if (VN_IS(toDtp, ClassRefDType) && VN_IS(fromDtp, ClassRefDType)) {
const auto toClassp = VN_AS(toDtp, ClassRefDType)->classp();
const auto fromClassp = VN_AS(fromDtp, ClassRefDType)->classp();
@@ -1532,26 +1590,26 @@ VCastable AstNode::computeCastable(const AstNodeDType* toDtp, const AstNodeDType
return castable;
}
AstNodeDType* AstNode::getCommonClassTypep(AstNode* nodep1, AstNode* nodep2) {
// Return the class type that both nodep1 and nodep2 are castable to.
AstNodeDType* AstNode::getCommonClassTypep(AstNode* node1p, AstNode* node2p) {
// Return the class type that both node1p and node2p are castable to.
// If both are null, return the type of null constant.
// If one is a class and one is null, return AstClassRefDType that points to that class.
// If no common class type exists, return nullptr.
// First handle cases with null values and when one class is a super class of the other.
if (VN_IS(nodep1, Const)) std::swap(nodep1, nodep2);
if (VN_IS(node1p, Const)) std::swap(node1p, node2p);
{
const VCastable castable = computeCastable(nodep1->dtypep(), nodep2->dtypep(), nodep2);
const VCastable castable = computeCastable(node1p->dtypep(), node2p->dtypep(), node2p);
if (castable == VCastable::SAMEISH || castable == VCastable::COMPATIBLE) {
return nodep1->dtypep();
return node1p->dtypep();
} else if (castable == VCastable::DYNAMIC_CLASS) {
return nodep2->dtypep();
return node2p->dtypep();
}
}
AstClassRefDType* classDtypep1 = VN_CAST(nodep1->dtypep(), ClassRefDType);
AstClassRefDType* classDtypep1 = VN_CAST(node1p->dtypep(), ClassRefDType);
while (classDtypep1) {
const VCastable castable = computeCastable(classDtypep1, nodep2->dtypep(), nodep2);
const VCastable castable = computeCastable(classDtypep1, node2p->dtypep(), node2p);
if (castable == VCastable::COMPATIBLE) return classDtypep1;
AstClassExtends* const extendsp = classDtypep1->classp()->extendsp();
classDtypep1 = extendsp ? VN_AS(extendsp->dtypep(), ClassRefDType) : nullptr;

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