Compare commits

...
373 Commits
Author SHA1 Message Date
Wilson Snyder d6ba65ba75 Version bump 2024-10-27 09:38:06 -04:00
Wilson Snyder f496138855 Commentary: Changes update 2024-10-27 09:33:54 -04:00
Wilson Snyder 2f272a4190 Fix $countbits in assert with non-tristates (#5566). 2024-10-27 09:30:54 -04:00
Wilson Snyder 469eca7de2 Commentary: Changes update 2024-10-25 18:54:39 -04:00
Todd Strader ec2eae607a Fix enum name method (#5563) 2024-10-25 18:49:45 -04:00
Ryszard Rozak 292c2e289e Support rand dynamic arrays of objects (#5557) (#5564) 2024-10-25 12:00:43 -04:00
Ryszard Rozak 87ac61140d Tests: Don't use indices in check_rand (#5561)
Signed-off-by: Ryszard Rozak <[email protected]>
2024-10-25 11:06:32 -04:00
Geza Lore 81ee89de15 Properly skip t_ccache_report when no ccache (#5562) 2024-10-25 14:33:26 +01:00
Todd Strader 83081aaefc Fix struct literal on pattern assignment (#5552) (#5559) 2024-10-24 18:50:57 -04:00
Tomasz Gorochowik fd2917c928 Commentary: Fix sv-bugpoint paragraph typo (#5558) 2024-10-24 09:41:27 -04:00
Ryszard Rozak 4cd69f9feb Fix queue element access (#5551) 2024-10-24 09:40:54 -04:00
Eric Müller 4e5c7f4568 Fix build on gcc when using the spack wrapper (#5555) 2024-10-24 07:53:11 -04:00
Tomasz Gorochowik 647af27274 Commentary: Mention sv-bugpoint in the contributing guidelines (#5553) 2024-10-24 07:42:57 -04:00
Todd Strader 8cc7e180ca Fix array trace splitting (#5549) 2024-10-23 11:51:48 -04:00
Todd Strader d3d45c0be5 Tests: Fix file_grep_count() error message (#5550) 2024-10-23 10:07:03 -04:00
Wilson Snyder 549dd31224 Commentary: Changes update 2024-10-22 09:34:09 -04:00
Wilson Snyder 36888fac5d Fix long module names crashing string handling (#5546). 2024-10-22 09:25:58 -04:00
Yilou WangandUdaya Raj Subedi 2409f32d87 Fix multi-range indices assignment (#5534) (#5547)
Co-authored-by: Udaya Raj Subedi <[email protected]>
2024-10-21 09:56:50 -04:00
Yilou Wang 8c3cc3af8f Fix struct array assignment (#5455) (#5537) 2024-10-21 09:54:33 -04:00
Todd Strader 76fe224e7c Fix complex user type problem with --x-assign (#5543) 2024-10-18 19:52:25 -04:00
Krzysztof Boroński 7ccc93d9df Fix reduction methods for verilated types (#5542) 2024-10-18 19:51:44 -04:00
Geza Lore 55661e7f71 Install public executables into bindir instead of pkgdatadir (#5140) (#5544)
Instead of installing redirect scripts in to bindir, and real
executables in to pkgdatadir/bin, we now put the real executables into
bindir, and add redirect scripts into pkgdatadir/bin. (That is, we
redirect in the opposite direction as before).

This enables the same relocatable and testable installations as before
without putting architecture specific binaries into pkgdatadir, so
hopefully we now conform to the Linux Filesystem Hierarchy Standard.

This requires a small fixup in the installed `verilator` script to
hardcode the relative path between bindir and pkgdatadir.

Fixes #5140
2024-10-18 10:06:28 +01:00
Aidan McNay ece0613e09 Commentary: Fix CMake comments (#5545) 2024-10-17 16:39:51 -04:00
Ryszard Rozak 0dce97b09d Fix assignments of concatenation to queues and dynamic arrays (#5540) 2024-10-15 07:35:59 -04:00
Ryszard Rozak a3d0cc6522 Fix static function wrappers (#5536)
Signed-off-by: Ryszard Rozak <[email protected]>
2024-10-14 07:41:17 -04:00
Wilson Snyder 1df20f7076 Remove driver.pl - deprecated earlier with driver.py 2024-10-13 21:55:31 -04:00
Wilson Snyder 2fc94557a0 Fix error on enums with x/z using .name(), and internal refactoring 2024-10-11 22:37:48 -04:00
Vito GamberiniandWilson Snyder 789698cb5c Fix coverage counts missing due to table optimization (#5473) (#5474).
Co-authored-by: Wilson Snyder <[email protected]>
2024-10-10 21:22:06 -04:00
Yilou Wang 3cced9baad Fix foreach on associative arr with the same logic and update the tests (#5530) 2024-10-10 12:50:43 -04:00
Yilou Wang f3cc32554c Fix foreach with 2-D queues and dynamic arrays (#5525) (#5529) 2024-10-10 10:50:37 -04:00
Ryszard Rozak 2a905c1d6e Fix copy constructor of classes that use std::process (#5528)
Signed-off-by: Ryszard Rozak <[email protected]>
2024-10-10 14:40:07 +02:00
Wilson Snyder 230b145c04 Commentary 2024-10-10 08:14:21 -04:00
Wilson Snyder 9f34764f4b Tests: Find filenames with fix me 2024-10-10 07:48:23 -04:00
Wilson Snyder 69ac3c14e8 Fix crash with internal assertion on short array initializer (partial #5511) 2024-10-10 07:20:44 -04:00
Wilson Snyder f98637e122 Internals: Cleanup style of coverage visitors. No functional change. Ignore whitespace if diff. 2024-10-09 18:13:23 -04:00
Wilson Snyder 6d936654ba Commentary: Changes update 2024-10-09 18:01:34 -04:00
Wilson Snyder 4dd4047c47 Internals: Less verbose docs build 2024-10-09 18:01:30 -04:00
Zhou Shen 1710b6bab4 Support for wired nets, wor/trior/wand/triand. (#5496) 2024-10-09 17:53:46 -04:00
Geza Lore 041f6603c3 Make incorrect soft ordering constraint into a hard constraint. (#5520)
An ordering constraint between NBA commit blocks ('Post' logic) and the
written variable were previously added as soft constraints (cutable
edges). However these are required for correctness, so if it ever is
cut we will have incorrect simulation results.

Change these into hard constraints instead. This necessitates adding a
flag on AstVar to ignore special variables constructed during V3Delayed
that might otherwise appear as degenerate logic loops. E.g.:

if (VdlySet) {
   VdlySet = 0;  // <- This write to VdlySet can and must be ignored
   LHS = VdlyVal;
}

No functional change, but you might get an error if this constraint was
ever violated. (Theoretically it should never be, as these variables
were inserted in a way that does not require violating these constraints
...)
2024-10-09 11:43:53 +01:00
Geza Lore 5acced1e33 Refactor V3Delay for extensibility (#5516)
* Refactor V3Delay for extensibility

Introduce the concept of an "NBA Scheme", which is the lowering pattern
we can use for various variables that are the targets of NBAs.
E.g.:
 - ShadowVariable (old default scheme)
 - FlagShared (old array set flag scheme)
 - ValueQueueWhole (recent dynamic commit queue)

We now analyse all AstAssignDly before making any decisions on which
scheme to apply. We then choose a specific scheme for each variable that
is the target of an NBA, and then all NBAs targeting that variable use
the same scheme. This enables easy mix and match of schemes as needed,
while remaining consistent by design after extensions.

Output is perturbed due to node insertion order, but no functional
or performance change is intended.
2024-10-09 10:39:40 +01:00
Yilou Wang 920c8012de Support unconstrained randomization for associative array and queue (#5515) 2024-10-08 10:54:20 -04:00
Geza Lore 8f1ea09558 Add lsb index to V3Number::setMask (#5522) 2024-10-08 13:15:36 +01:00
Wilson Snyder b873c23cf2 Internals: Refactor into V3Width enumSelect function 2024-10-07 21:44:07 -04:00
Wilson Snyder 13c7b6e827 Tests: Faster first retry 2024-10-07 21:44:07 -04:00
Wilson Snyder bbce7926b9 Tests: Remove unused clk input 2024-10-07 21:44:07 -04:00
Wilson Snyder 2c445e4bfd Commentary: Changes update 2024-10-07 21:44:07 -04:00
Furqan Nadir 338d54fd34 Commentary: Add name to CONTRIBUTORS (#5519) 2024-10-07 14:10:43 -04:00
Ryszard Rozak 009d1f2f5b Fix -j option without argument in hierarchical verilation (#5514)
Signed-off-by: Ryszard Rozak <[email protected]>
2024-10-07 07:31:59 -04:00
github action 08279645ca Apply 'make format' 2024-10-06 22:10:07 +00:00
Wilson Snyder 28ecd8e908 Support local and protected on typedef (#5460). 2024-10-06 18:08:40 -04:00
Wilson Snyder bc8a332ee8 Tests: Disable last test due to clang warning 2024-10-06 05:00:57 -04:00
Wilson Snyder d52822781c Tests: Fix driver for --iv etc 2024-10-06 04:49:53 -04:00
github action bdd37e40fe Apply 'make format' 2024-10-06 08:02:10 +00:00
Wilson Snyder 4b713e9882 Fix pattern initialization with typedef key (#5512). 2024-10-06 04:01:15 -04:00
Wilson Snyder fd9f5ab34e Fix not reporting class reference with extra parameters (#5467). 2024-10-04 05:38:36 -04:00
Wilson Snyder d06f986b51 Add elaboration dot-error message context, plus debug improvements 2024-10-04 05:38:05 -04:00
Wilson Snyder 8638e46cb7 Fix IEEE version number 2024-10-04 05:22:09 -04:00
Wilson Snyder 85909f02b3 Commentary 2024-10-04 05:21:18 -04:00
Nathan Graybeal 3572bd2f1a Fix configure inserting absolute paths for Python and Perl (#5504) (#5505)
* Migrate all tools to AC_CHECK_PROG
2024-10-04 10:08:44 +01:00
Wilson Snyder ff1d20d50c Tests: Add t_struct_initial_assign, still fails (#5380) (#5381). 2024-10-03 20:36:23 -04:00
Wilson Snyder c300075a20 Tests: Remove driver Python version package requirement (#5505) 2024-10-03 19:39:28 -04:00
Wilson Snyder 4bdfc653a3 Add error on misused genvar (#408). 2024-10-03 18:54:30 -04:00
Wilson Snyder 554653900a Commentary: Move C++20 deprec to after Ubuntu 20.04 EOL 2024-10-03 18:15:51 -04:00
Wilson Snyder b90b81e12c Tests: Fix string !== for other simulators. 2024-10-03 18:14:53 -04:00
Han Qi bf2b4e1b6a Fix equivalence checking when replacing type parameters (#5213) (#5255) 2024-10-03 21:19:07 +01:00
Yilou Wang c05c48aaf3 Support unpacked array Constrained Randomization (#5437) (#5489) 2024-10-02 10:29:47 -04:00
Fabian Keßler 39143cc15a Fix explicit CMAKE_INSTALL_PREFIX usages (#5500) 2024-10-01 13:38:16 -04:00
Wilson Snyder 03012da11c Internals: astgen: Detect bad node types after edits.
Also add checks for nodes that can be multiple types with syntax
`AstNode<AstNodeExpr|AstNodeDType>`
2024-09-30 22:25:28 -04:00
0547108e3f Add -output-groups to build with concatenated .cpp files (#5257)
Signed-off-by: Bartłomiej Chmiel <[email protected]>
Signed-off-by: Ryszard Rozak <[email protected]>
Signed-off-by: Arkadiusz Kozdra <[email protected]>
Co-authored-by: Mariusz Glebocki <[email protected]>
Co-authored-by: Arkadiusz Kozdra <[email protected]>
Co-authored-by: Bartłomiej Chmiel <[email protected]>
Co-authored-by: Wilson Snyder <[email protected]>
Co-authored-by: Ryszard Rozak <[email protected]>
2024-09-30 21:42:36 -04:00
Bartłomiej Chmiel 1a31aa5d62 Internals: Fix annotation checker not considering base class virtual function annotations (#5459) 2024-09-30 21:34:34 -04:00
Wilson Snyder 13a1240359 Commentary: Changes update 2024-09-29 21:41:05 -04:00
Wilson Snyder b7e5486baa Internals: Fix astgen spacing 2024-09-29 16:56:50 -04:00
Wilson Snyder afeca21d73 Internals: For debug, quote symbol table to see spaces. 2024-09-29 16:56:32 -04:00
Wilson Snyder d0ec6092b3 Change package import/export to link post-parsing, prep for later commit. 2024-09-28 20:55:22 -04:00
Wilson Snyder 5c923d6629 Fix to avoid IMPLICIT creation if data type of same name. 2024-09-28 17:58:26 -04:00
Wilson Snyder 1dc6fd3d93 Internals: Move interface error to later phase, prep for later commit. No functional change intended. 2024-09-28 17:37:44 -04:00
Arkadiusz Kozdra 5b56c80830 Better error recovery (#5493)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-09-27 20:38:49 +02:00
Wilson Snyder 2291d3d4c6 Tests: Fix some non-IEEE issues in tests. 2024-09-27 09:00:20 -04:00
Arkadiusz Kozdra 02e7767886 Fix randomize with foreach constraints (#5492)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-09-26 19:31:06 +02:00
Geza Lore 2a01365f9b Fix V3Table trying to generate 'x' bits in the lookup table. (#5491)
Due to out of range selects, V3Table attempted to create a table in the
constant pool with an 'x' value in it, which caused an internal error.

Ensure V3Table behaves the same for out of range selects as the original
logic would.

There is a related bug #5490, about leaving partially out of range
selects in the logic after inserting bounds checks in V3Unknown.
2024-09-26 16:31:47 +01:00
Arkadiusz KozdraandSzymon Gizler 91c8866ac3 Fix exponential ConcatN (#5488)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
Co-authored-by: Szymon Gizler <[email protected]>
2024-09-26 05:12:24 -04:00
Wilson Snyder 798bbe98e8 Add syntax error on empty case items, per IEEE grammar. 2024-09-25 22:40:28 -04:00
Wilson Snyder a3bbf13506 Internals: Minor parser reorgs in prep for future pull. No functional change intended. 2024-09-25 20:41:49 -04:00
Wilson Snyder 650da7beb2 Examples: Cleanup some spacing 2024-09-25 14:24:01 -04:00
Geza Lore 3bc09d49fb Generate one trigger per SenItem instead of per SenTree (#5483) 2024-09-25 10:35:50 +01:00
Wilson Snyder 6c61a9aff3 Support objcache when compiling Verilated files with cmake. 2024-09-24 20:55:11 -04:00
Wilson Snyder a4085f3a06 Internals: Standardize format of CMake files with gersemi. No functional change intended. 2024-09-24 20:43:19 -04:00
Wilson Snyder 3ae18af8dd Fix short-circuting on method calls (#5486). 2024-09-24 20:24:27 -04:00
Wilson Snyder 811eab8fa5 Fix short-circuting with associative array access (#5484). 2024-09-24 19:24:01 -04:00
Wilson Snyder 4ec75b2618 Fix over-permissive parsing of UDPs without identifiers 2024-09-24 18:53:32 -04:00
Wilson Snyder 5a65d27851 Internals: bisonpre: Support -Wcounterexamples 2024-09-23 21:42:02 -04:00
Chris Bachhuber 685ea0bc65 Add Docker pre-commit hook (#5238) (#5452) 2024-09-23 07:37:24 -04:00
Wilson Snyder c48d80592e Fix extra dot in coverage point hierarchy when using name()=''. 2024-09-23 07:34:12 -04:00
Wilson Snyder 0aa8356eca Change --main and --binary to use a TOP hierarchy name of "" (#5482). 2024-09-22 23:03:51 -04:00
Wilson Snyder 670b7c5243 Support DPI imports and exports with double underscores (#5481). 2024-09-22 22:11:01 -04:00
Wilson Snyder 706679e6b1 Support DPI imports and exports with double underscores. 2024-09-22 22:06:39 -04:00
Wilson Snyder d288488b7f Fix --binary with .cpp PLI filenames under relative directory paths. 2024-09-22 16:47:15 -04:00
Chris Bachhuber b17619296a Documentation: Highlight syntax in install.rst (#5478) 2024-09-22 15:55:12 -04:00
Wilson Snyder 88bd479bc7 Add error on instances without parenthesis. 2024-09-22 12:25:35 -04:00
Wilson Snyder 2584befa5a Internals: Show tree traversal in V3LinkDot Resolve debug. No functional change intended. 2024-09-22 10:46:04 -04:00
Wilson Snyder 90215878f8 Tests: Improve t_dist_warn_coverage.py 2024-09-22 09:10:03 -04:00
Wilson Snyder a1a74cb1d9 Fix mis-parsing of constraint = new. 2024-09-22 09:10:01 -04:00
Wilson Snyder 9f9770e722 Parse elaboration-time nettype declarations (as UNSUPPORTED) 2024-09-21 21:00:02 -04:00
Wilson Snyder 888af29a72 Delay struct type determination until elaboration 2024-09-21 20:27:55 -04:00
Wilson Snyder 5f39c69d19 Delay parameter type assignment determination until elaboration 2024-09-21 20:27:41 -04:00
Wilson Snyder e7de2c5a05 Remove warning on unsized numbers exceeding 32-bits. 2024-09-21 19:19:12 -04:00
Geza Lore 59b07529b1 driver.py: fix aslr_off (#5477) 2024-09-21 16:37:51 +01:00
Geza Lore a6e9bce0dd driver.py: consume all stdout from subprocess (#5476) 2024-09-21 16:24:45 +01:00
Wilson Snyder 2c52119d6c Tests: Rename some tests into proper groups. No functional change. 2024-09-21 10:04:58 -04:00
Wilson Snyder 48faf8d036 Fix tracing when name() is empty (#5470). 2024-09-21 08:25:14 -04:00
Wilson Snyder 0484143282 Tests: Update t_timing_finish (#5472) 2024-09-21 07:46:04 -04:00
Wilson Snyder 0ee214a157 Tests: Fix t_timing_fork_comb_bad committed earlier 2024-09-20 22:16:00 -04:00
Wilson Snyder 774ec42be4 Internals: Experimental cleanup; avoid :: on package symbol tables 2024-09-20 20:39:49 -04:00
Wilson Snyder 5a6f2b661d Tests: Avoid multiple lint/compile runs in one test; hard to debug 2024-09-20 20:34:35 -04:00
Wilson Snyder 80cba789f4 Internals: Remove V3LinkParse's need of class links. No functional change intended. 2024-09-20 18:26:23 -04:00
Wilson Snyder 92dd8ee8f5 Fix timing mode not exiting on empty events (#5472). 2024-09-20 17:46:27 -04:00
Todd Strader 1665d15d4d Fix user-type parameter overlap (#5469) 2024-09-20 14:29:31 -04:00
Wilson Snyder f0fb0b05ff Internals: Misc V3Param cleanups. 2024-09-20 08:59:10 -04:00
Wilson Snyder 02e88e3848 Fix suppression of WIDTH* warnings when immediately under a size cast (#3417). 2024-09-19 22:56:47 -04:00
Wilson Snyder 87eef36b1c Tests: Fix driver race sometimes missing final log data 2024-09-19 22:49:40 -04:00
Wilson Snyder 579257bc42 Tests: Fix driver not accepting debug pass-down flags to Verilator, broke earlier commit. 2024-09-19 22:08:40 -04:00
Wilson Snyder e2041f7450 Commentary: Changes update 2024-09-19 20:29:39 -04:00
Yilou Wang 70112438c3 Support packed/unpacked and dynamic array unconstrained randomization (#5414) (#5415) 2024-09-19 20:07:05 -04:00
Wilson Snyder 175e1dde73 Tests: Run t_hier_block_cmake.py first so finishes 2024-09-19 19:33:43 -04:00
Wilson Snyder e990415ee0 Tests: Improve driver performance with forkserver 2024-09-19 19:28:07 -04:00
Wilson Snyder 1543b202b2 Tests: Move per-command expect= to instead check logfiles 2024-09-19 18:53:22 -04:00
Wilson Snyder f63168a5b5 CI: More parallelism 2024-09-19 18:51:33 -04:00
Wilson Snyder 49bccb5f1b Commentary 2024-09-19 17:58:37 -04:00
Wilson Snyder c7e1358bb7 Tests: Fix --gdb with one test (#5466) 2024-09-19 17:06:32 -04:00
Geza Lore 62a58f420c Fix latest pylint issues (#5465) 2024-09-19 15:51:13 +01:00
Arkadiusz Kozdra dd95e033e7 Support inside array constraints (#5448)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-09-19 07:27:59 -04:00
Wilson Snyder 371a4055b0 Fix false LIFETIME warning on repeat in fork-join (#5456). 2024-09-18 21:20:17 -04:00
Wilson Snyder f251f7b774 Tests: CONSTRIAINTIGN, ZERODLY no longer need suppression on UVM 2024-09-17 21:21:08 -04:00
Wilson Snyder 0f3e0de891 Commentary 2024-09-17 20:58:14 -04:00
Wilson Snyder 7081ea0ede Support as a task call 2024-09-17 20:53:08 -04:00
Wilson Snyder fb04765c0e Fix class reference with pin that is a class reference (#5454). 2024-09-17 17:38:18 -04:00
Wilson Snyder b8bda729d4 Tests: Fix debug message 2024-09-16 20:29:23 -04:00
Wilson Snyder 195a665293 Internals: Fix V3LinkDot debug message print 2024-09-15 21:18:51 -04:00
Wilson Snyder c8de3630a5 Tests: Fix driver error report, and passing --dumpi-tree 2024-09-15 21:10:44 -04:00
Wilson Snyder 99a29acca0 CI: One-time yamlfix cleanups. No functional change intended. 2024-09-15 14:37:09 -04:00
Wilson Snyder 48a607cc78 Internals: Cleanup Makefile.in to commented sections. No functional change intended. 2024-09-15 13:55:43 -04:00
Wilson Snyder 19170badd3 Fix warning IEEE reference (#5453) 2024-09-15 11:05:48 -04:00
Wilson Snyder 77fc771ed0 Tests: Fix missing stdout on execute() 2024-09-14 18:01:49 -04:00
github action 9b9a554489 Apply 'make format' 2024-09-14 00:46:48 +00:00
Wilson Snyder 0fe8c73d19 Fix $fatal to not be affected by +verilator+error+limit (#5135). 2024-09-13 20:45:44 -04:00
Wilson Snyder eb66e137db Fix fault on defparam with UNSUPPORTED ignored (#5450). 2024-09-13 18:31:55 -04:00
Wilson Snyder c2b82c293f Tests: Fix driver creating .out with --gold 2024-09-13 18:31:35 -04:00
Arkadiusz Kozdra 0b7510befa Support basic dist constraints (#5431) 2024-09-12 05:20:36 -07:00
Arkadiusz Kozdra 140eb0a6e5 Re-sync parser on endclass
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-09-11 15:57:45 +02:00
Arkadiusz Kozdra 6b8f253ecd Re-sync parser in constraints and cross coverpoints
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-09-11 15:57:45 +02:00
Arkadiusz Kozdra ac29393ec9 Do not parse covergroup identifiers as types
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-09-11 15:57:45 +02:00
Wilson Snyder 22d6bb8180 Fix display with multiple string formats (#5311). 2024-09-11 08:41:11 -04:00
Wilson Snyder f4e4602dcb Tests: Fix driver handling of interrupts 2024-09-10 20:29:26 -04:00
Wilson Snyder 521c5c2f75 Fix extra events in traces (#5405). 2024-09-10 19:14:52 -04:00
Wilson Snyder 3525484730 Commentary 2024-09-10 19:04:55 -04:00
Arkadiusz Kozdra 4a58997604 Support basic constrained queue randomization (#5413)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-09-10 09:33:14 -04:00
Arkadiusz Kozdra ef259f63ca Fix randomize treated as std::randomize in classes (#5436) 2024-09-10 09:10:36 -04:00
Arkadiusz Kozdra 2f690c0530 Fix foreach colliding index names (#5444)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-09-10 07:17:21 -04:00
Wilson Snyder 283a5edbdb Tests: Make GCOV_PREFIX path directories 2024-09-09 21:47:47 -04:00
Wilson Snyder e566b5a4f5 Change .vlt config files to be read before .v files (#5185). 2024-09-09 20:18:54 -04:00
Wilson Snyder 4e4fdd3b66 Fix multidimensional function return value selects (#5382). 2024-09-09 19:56:09 -04:00
Wilson Snyder 434896d50c Tests: test class IGNOREDRETURN. 2024-09-09 19:48:15 -04:00
Andrew Nolte 1e7611edea Change to use maximum for cover point aggregation (#5402) 2024-09-09 14:20:18 -04:00
Geza Lore 2890126110 Remove out of range Sel in V3Unknown (#5443)
Fixes #5393
2024-09-09 14:09:29 +01:00
Wilson Snyder 07bb8c701d Convert test driver to Python (#5427) 2024-09-08 13:00:03 -04:00
Wilson Snyder 55ae48ac13 Commentary 2024-09-08 11:11:20 -04:00
Wilson Snyder c83ee391bb Fix associative array next/prev/first/last mis-propagating constants (#5435). 2024-09-07 15:25:35 -04:00
Wilson Snyder d01b917062 Commentary: Changes update 2024-09-07 15:24:06 -04:00
Wilson Snyder b21117091b CI: Add Ubuntu 24.04 GCC; combine reloc with GCC-10 runs 2024-09-07 13:43:47 -04:00
Wilson Snyder 3a73d83741 Tests: Fix clang 18 warning 2024-09-07 10:20:59 -04:00
Wilson Snyder 9643232d36 CI: Add Ubuntu 24.04 script (not enabled yet) 2024-09-07 10:12:35 -04:00
Wilson Snyder 7b41d2046d Fix GTKWave clang 18 warning 2024-09-07 10:12:09 -04:00
Wilson Snyder 7eb1b6c32b Tests: Fix GCC 13.2.0 issues. No functional change. 2024-09-06 22:04:49 -04:00
Andrew Nolte 083fb7e9c2 Add partial coverage symbol and branch data in lcov info files (#5388) 2024-09-06 18:15:18 -04:00
Krzysztof Bieganski afb8428db4 Support IEEE-compliant intra-assign delays (#3711) (#5441) 2024-09-06 18:13:52 -04:00
Bartłomiej Chmiel d6923c8571 Improve performance of V3VariableOrder with parallelization (#5406) 2024-09-06 08:04:26 -04:00
Wilson Snyder 1c38744fd1 Tests: Fix requiring core dump 2024-09-04 20:10:05 -04:00
Krzysztof Bieganski 51691dfde5 Fix driving clocking block in Reactive
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-09-04 07:57:51 -04:00
Arkadiusz Kozdra 409efa1249 Internals: Factor out creating clocking event. No functional change.
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-09-04 07:57:51 -04:00
Wilson Snyder e4ff0909dc Tests: Misc test cleanups from Python branch. 2024-09-03 21:42:06 -04:00
Wilson Snyder d3670b6890 Test: Remove old test 2024-09-03 21:32:09 -04:00
Wilson Snyder 7a74ddc1af Internals: Fix some getter/setter ordering. No functional change intended. 2024-09-02 18:48:49 -04:00
Wilson Snyder 551862a55e Tests: Move some misplaced files. No functional change. 2024-09-02 15:50:40 -04:00
Arkadiusz Kozdra d3fcec3e84 Fix clearing trigger of events with no sentrees (#5426)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-09-02 18:19:49 +02:00
Krzysztof Bieganski 088862d449 Support appending to queue via [] (#5421) 2024-09-02 09:45:47 -04:00
github action e9f758ce67 Apply 'make format' 2024-09-02 01:13:41 +00:00
Wilson Snyder b698bfd850 Tests: Untabify some tests. 2024-09-01 21:12:37 -04:00
Wilson Snyder c9970ff822 Tests: Fix --verbose broken display 2024-09-01 21:01:07 -04:00
Wilson Snyder df594ee430 Tests: Fix ll scan test. 2024-09-01 20:59:42 -04:00
Todd Strader 201e343795 Fix sformatf internal error on initial automatics (#5423) 2024-08-30 19:35:47 -04:00
Wilson Snyder 9a307c4abd Tests: Cleanup trace_filename use. No test functionality change. 2024-08-30 18:34:42 -04:00
Krzysztof Bieganski 657d7f257b Support named event locals (#5422)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-30 17:10:47 +02:00
Wilson Snyder 0ec5e02ce1 Improve hex too many digits error (#5419). 2024-08-30 07:48:00 -04:00
Wilson Snyder cdfb2221bb Tests: Remove ancient GCC 4.4 skip. 2024-08-29 19:25:22 -04:00
Krzysztof Bieganski f133a2811f Fix capturing params in randomize() with (#5416) (#5418)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-29 23:02:21 +02:00
Krzysztof Bieganski aecf38e3ad Fix V3Randomize compile error on old GCC (#5403) (#5417).
No functional change intended.
2024-08-29 10:39:54 -04:00
Wilson Snyder fa32d10f39 Fix performance of V3Trace when many activity blocks (#5372). 2024-08-28 20:45:51 -04:00
Wilson Snyder f4fe89a8c4 Commentary: Changes update 2024-08-28 17:32:57 -04:00
Krzysztof Bieganski 675d9a641e Call pre/post_randomize on randomize() with (#5412)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-28 19:42:49 +02:00
Krzysztof Bieganski d896f1ff08 Fix queue [$-i] select as reference argument (#5411)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-28 17:29:12 +02:00
Arkadiusz Kozdra 5cb6f370e9 Internals: Emit rand constraint right away. No functional change intended. (#5409)
This change gets rid of most of the shared pointers and useless memory
allocations.  Also takes advantage of higher-arity bvxor/concat to
reduce amount of data sent to the solver.

Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-08-28 16:11:39 +02:00
Kaleb Barrett e04ef5d83a Add method to check if there are VPI callbacks of the given type (#5399) 2024-08-27 17:36:51 -04:00
Krzysztof Bieganski 155dcc5658 Fix empty foreach in if in constraints (#5408)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-27 15:39:36 +02:00
Wilson Snyder e927536099 Reduce --debugi 2 verbosity 2024-08-27 07:28:27 -04:00
Krzysztof Bieganski f623db7d68 Normalize types in constraints (#5407)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-27 12:53:44 +02:00
Wilson Snyder d40f7f5167 Tests: Fix lint-py (last commit) 2024-08-27 05:31:40 -04:00
Wilson Snyder 34bb013941 Tests: Fix broken t_proc.pl, and misc cleanups. 2024-08-26 21:53:36 -04:00
Wilson Snyder ae35be9102 Internals: Reformat with new settings (last commit). No functional change. 2024-08-26 21:53:36 -04:00
Wilson Snyder bde4097df2 Internals: Add .style.yapf 2024-08-26 21:53:36 -04:00
Wilson Snyder 17b70788df Internals: Run yapf3 in parallel 2024-08-26 21:53:36 -04:00
Krzysztof Bieganski b1927e4fb5 Fix infinite recursion due to recursive functions/tasks (#5398) 2024-08-26 12:18:52 -04:00
Yilou Wang c4cb26fa9a Support unconstrained randomization for unions (#5395) (#5396) 2024-08-26 11:04:45 -04:00
Wilson Snyder 4e86e60491 Tests: Use only case-sensitve non-extended regexps 2024-08-26 08:14:39 -04:00
Wilson Snyder d3e07b6ad9 Internals: Always use parallel for make -j 4 clang-format yapf format-pl-exec
make[1]: Entering directory '/svaha/wsnyder/SandBox/homecvs/v4/verilator'
yapf3 -i bin/verilator_ccache_report bin/verilator_difftree bin/verilator_gantt bin/verilator_includer bin/verilator_profcfunc 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 src/astgen src/bisonpre src/config_rev src/cppcheck_filtered src/flexfix src/vlcovgen src/.gdbinit.py test_regress/t/*.pf nodist/clang_check_attributes nodist/code_coverage nodist/dot_importer nodist/fuzzer/actual_fail nodist/fuzzer/generate_dictionary nodist/install_test nodist/log_changes  nodist/code_coverage.dat
chmod a+x test_regress/t/*.pl
clang-format-14 -i ./include/verilated.cpp ./include/verilated_cov.cpp ./include/verilated_dpi.cpp ./include/verilated_fst_c.cpp ./include/verilated_fst_sc.cpp ./include/verilated_probdist.cpp ./include/verilated_profiler.cpp ./include/verilated_random.cpp ./include/verilated_save.cpp ./include/verilated_threads.cpp ./include/verilated_timing.cpp ./include/verilated_vcd_c.cpp ./include/verilated_vcd_sc.cpp ./include/verilated_vpi.cpp ./examples/make_hello_c/sim_main.cpp ./examples/make_hello_sc/sc_main.cpp ./examples/make_protect_lib/sim_main.cpp ./examples/make_tracing_c/sim_main.cpp ./examples/make_tracing_sc/sc_main.cpp ./src/VlcMain.cpp ./src/VlcTop.cpp ./src/V3Active.cpp ./src/V3ActiveTop.cpp ./src/V3Assert.cpp ./src/V3AssertPre.cpp ./src/V3Ast.cpp ./src/V3AstNodes.cpp ./src/V3Begin.cpp ./src/V3Branch.cpp ./src/V3Broken.cpp ./src/V3CCtors.cpp ./src/V3CUse.cpp ./src/V3Case.cpp ./src/V3Cast.cpp ./src/V3Class.cpp ./src/V3Clean.cpp ./src/V3Clock.cpp ./src/V3Combine.cpp ./src/V3Common.cpp ./src/V3Config.cpp ./src/V3Const.cpp ./src/V3Coverage.cpp ./src/V3CoverageJoin.cpp ./src/V3Dead.cpp ./src/V3Delayed.cpp ./src/V3Depth.cpp ./src/V3DepthBlock.cpp ./src/V3Descope.cpp ./src/V3Dfg.cpp ./src/V3DfgAstToDfg.cpp ./src/V3DfgCache.cpp ./src/V3DfgDecomposition.cpp ./src/V3DfgDfgToAst.cpp ./src/V3DfgOptimizer.cpp ./src/V3DfgPasses.cpp ./src/V3DfgPeephole.cpp ./src/V3DfgRegularize.cpp ./src/V3DupFinder.cpp ./src/Verilator.cpp ./src/V3EmitCBase.cpp ./src/V3EmitCConstPool.cpp ./src/V3EmitCFunc.cpp ./src/V3EmitCHeaders.cpp ./src/V3EmitCImp.cpp ./src/V3EmitCInlines.cpp ./src/V3EmitCMain.cpp ./src/V3EmitCMake.cpp ./src/V3EmitCModel.cpp ./src/V3EmitCPch.cpp ./src/V3EmitCSyms.cpp ./src/V3EmitMk.cpp ./src/V3EmitV.cpp ./src/V3EmitXml.cpp ./src/V3Error.cpp ./src/V3ExecGraph.cpp ./src/V3Expand.cpp ./src/V3File.cpp ./src/V3FileLine.cpp ./src/V3Force.cpp ./src/V3Fork.cpp ./src/V3Gate.cpp ./src/V3Global.cpp ./src/V3Graph.cpp ./src/V3GraphAcyc.cpp ./src/V3GraphAlg.cpp ./src/V3GraphPathChecker.cpp ./src/V3GraphTest.cpp ./src/V3Hash.cpp ./src/V3Hasher.cpp ./src/V3HierBlock.cpp ./src/V3Inline.cpp ./src/V3Inst.cpp ./src/V3InstrCount.cpp ./src/V3Interface.cpp ./src/V3Param.cpp ./src/V3ParseGrammar.cpp ./src/V3ParseImp.cpp ./src/V3ParseLex.cpp ./src/V3PreProc.cpp ./src/V3PreShell.cpp ./src/V3Premit.cpp ./src/V3ProtectLib.cpp ./src/V3Randomize.cpp ./src/V3Reloop.cpp ./src/V3Sampled.cpp ./src/V3Sched.cpp ./src/V3SchedAcyclic.cpp ./src/V3SchedPartition.cpp ./src/V3SchedReplicate.cpp ./src/V3SchedTiming.cpp ./src/V3SchedVirtIface.cpp ./src/V3Scope.cpp ./src/V3Scoreboard.cpp ./src/V3Slice.cpp ./src/V3Split.cpp ./src/V3SplitAs.cpp ./src/V3SplitVar.cpp ./src/V3StackCount.cpp ./src/V3Stats.cpp ./src/V3StatsReport.cpp ./src/V3String.cpp ./src/V3Subst.cpp ./src/V3TSP.cpp ./src/V3Table.cpp ./src/V3Task.cpp ./src/V3ThreadPool.cpp ./src/V3Timing.cpp ./src/V3Trace.cpp ./src/V3TraceDecl.cpp ./src/V3Tristate.cpp ./src/V3Undriven.cpp ./src/V3Unknown.cpp ./src/V3Unroll.cpp ./src/V3VariableOrder.cpp ./src/V3Waiver.cpp ./src/V3Width.cpp ./src/V3WidthCommit.cpp ./src/V3WidthSel.cpp ./src/V3Life.cpp ./src/V3LifePost.cpp ./src/V3LinkCells.cpp ./src/V3LinkDot.cpp ./src/V3LinkInc.cpp ./src/V3LinkJump.cpp ./src/V3LinkLValue.cpp ./src/V3LinkLevel.cpp ./src/V3LinkParse.cpp ./src/V3LinkResolve.cpp ./src/V3Localize.cpp ./src/V3MergeCond.cpp ./src/V3Name.cpp ./src/V3Number.cpp ./src/V3OptionParser.cpp ./src/V3Options.cpp ./src/V3Order.cpp ./src/V3OrderGraphBuilder.cpp ./src/V3OrderMoveGraph.cpp ./src/V3OrderParallel.cpp ./src/V3OrderProcessDomains.cpp ./src/V3OrderSerial.cpp ./src/V3Os.cpp ./src/V3Param.cpp ./src/V3ParseGrammar.cpp ./src/V3ParseImp.cpp ./src/V3ParseLex.cpp ./src/V3PreProc.cpp ./src/V3PreShell.cpp ./src/V3Premit.cpp ./src/V3ProtectLib.cpp ./src/V3Randomize.cpp ./src/V3Reloop.cpp ./src/V3Sampled.cpp ./src/V3Sched.cpp ./src/V3SchedAcyclic.cpp ./src/V3SchedPartition.cpp ./src/V3SchedReplicate.cpp ./src/V3SchedTiming.cpp ./src/V3SchedVirtIface.cpp ./src/V3Scope.cpp ./src/V3Scoreboard.cpp ./src/V3Slice.cpp ./src/V3Split.cpp ./src/V3SplitAs.cpp ./src/V3SplitVar.cpp ./src/V3StackCount.cpp ./src/V3Stats.cpp ./src/V3StatsReport.cpp ./src/V3String.cpp ./src/V3Subst.cpp ./src/V3TSP.cpp ./src/V3Table.cpp ./src/V3Task.cpp ./src/V3ThreadPool.cpp ./src/V3Timing.cpp ./src/V3Trace.cpp ./src/V3TraceDecl.cpp ./src/V3Tristate.cpp ./src/V3Undriven.cpp ./src/V3Unknown.cpp ./src/V3Unroll.cpp ./src/V3VariableOrder.cpp ./src/V3Waiver.cpp ./src/V3Width.cpp ./src/V3WidthCommit.cpp ./src/V3WidthSel.cpp ./include/verilated.h ./include/verilated_config.h ./include/verilated_cov.h ./include/verilated_cov_key.h ./include/verilated_dpi.h ./include/verilated_fst_c.h ./include/verilated_fst_sc.h ./include/verilated_funcs.h ./include/verilated_imp.h ./include/verilated_intrinsics.h ./include/verilated_profiler.h ./include/verilated_random.h ./include/verilated_save.h ./include/verilated_sc.h ./include/verilated_sc_trace.h ./include/verilated_sym_props.h ./include/verilated_syms.h ./include/verilated_threads.h ./include/verilated_timing.h ./include/verilated_trace.h ./include/verilated_trace_imp.h ./include/verilated_types.h ./include/verilated_vcd_c.h ./include/verilated_vcd_sc.h ./include/verilated_vpi.h ./include/verilatedos.h ./include/verilatedos_c.h ./src/V3Active.h ./src/V3ActiveTop.h ./src/V3Assert.h ./src/V3AssertPre.h ./src/V3Ast.h ./src/V3AstInlines.h ./src/V3AstNodeDType.h ./src/V3AstNodeExpr.h ./src/V3AstNodeOther.h ./src/V3AstUserAllocator.h ./src/V3Begin.h ./src/V3Branch.h ./src/V3Broken.h ./src/V3CCtors.h ./src/V3CUse.h ./src/V3Case.h ./src/V3Cast.h ./src/V3Class.h ./src/V3Clean.h ./src/V3Clock.h ./src/V3Combine.h ./src/V3Common.h ./src/V3Config.h ./src/V3Const.h ./src/V3Coverage.h ./src/V3CoverageJoin.h ./src/V3Dead.h ./src/V3Delayed.h ./src/V3Depth.h ./src/V3DepthBlock.h ./src/V3Descope.h ./src/V3Dfg.h ./src/V3DfgCache.h ./src/V3DfgOptimizer.h ./src/V3DfgPasses.h ./src/V3DfgPatternStats.h ./src/V3DfgPeephole.h ./src/V3DfgVertices.h ./src/V3DupFinder.h ./src/V3EmitC.h ./src/V3EmitCBase.h ./src/V3EmitCConstInit.h ./src/V3EmitCFunc.h ./src/V3EmitCMain.h ./src/V3EmitCMake.h ./src/V3EmitMk.h ./src/V3EmitV.h ./src/V3EmitXml.h ./src/V3Error.h ./src/V3ExecGraph.h ./src/V3Expand.h ./src/V3File.h ./src/V3FileLine.h ./src/V3Force.h ./src/V3Fork.h ./src/V3FunctionTraits.h ./src/V3Gate.h ./src/V3Global.h ./src/V3Graph.h ./src/V3GraphAlg.h ./src/V3GraphPathChecker.h ./src/V3GraphStream.h ./src/V3Hash.h ./src/V3Hasher.h ./src/V3HierBlock.h ./src/V3Inline.h ./src/V3Inst.h ./src/V3InstrCount.h ./src/V3Interface.h ./src/V3LangCode.h ./src/V3LanguageWords.h ./src/V3Life.h ./src/V3LifePost.h ./src/V3LinkCells.h ./src/V3LinkDot.h ./src/V3LinkInc.h ./src/V3LinkJump.h ./src/V3LinkLValue.h ./src/V3LinkLevel.h ./src/V3LinkParse.h ./src/V3LinkResolve.h ./src/V3List.h ./src/V3Localize.h ./src/V3MemberMap.h ./src/V3MergeCond.h ./src/V3Mutex.h ./src/V3Name.h ./src/V3Number.h ./src/V3OptionParser.h ./src/V3Options.h ./src/V3Order.h ./src/V3OrderCFuncEmitter.h ./src/V3OrderGraph.h ./src/V3OrderInternal.h ./src/V3OrderMoveGraph.h ./src/V3Os.h ./src/V3PairingHeap.h ./src/V3Param.h ./src/V3Parse.h ./src/V3ParseImp.h ./src/V3ParseSym.h ./src/V3PchAstMT.h ./src/V3PchAstNoMT.h ./src/V3PreExpr.h ./src/V3PreLex.h ./src/V3PreProc.h ./src/V3PreShell.h ./src/V3Premit.h ./src/V3ProtectLib.h ./src/V3Randomize.h ./src/V3Reloop.h ./src/V3Rtti.h ./src/V3Sampled.h ./src/V3Sched.h ./src/V3Scope.h ./src/V3Scoreboard.h ./src/V3SenExprBuilder.h ./src/V3SenTree.h ./src/V3Simulate.h ./src/V3Slice.h ./src/V3Split.h ./src/V3SplitAs.h ./src/V3SplitVar.h ./src/V3StackCount.h ./src/V3Stats.h ./src/V3StdFuture.h ./src/V3String.h ./src/V3Subst.h ./src/V3SymTable.h ./src/V3TSP.h ./src/V3Table.h ./src/V3Task.h ./src/V3ThreadPool.h ./src/V3Timing.h ./src/V3Trace.h ./src/V3TraceDecl.h ./src/V3Tristate.h ./src/V3Undriven.h ./src/V3UniqueNames.h ./src/V3Unknown.h ./src/V3Unroll.h ./src/V3VariableOrder.h ./src/V3Waiver.h ./src/V3Width.h ./src/V3WidthCommit.h ./src/V3WidthRemove.h ./src/VlcBucket.h ./src/VlcOptions.h ./src/VlcPoint.h ./src/VlcSource.h ./src/VlcTest.h ./src/VlcTop.h ./src/config_build.h ./src/config_package.h ./src/config_rev.h ./src/verilog.y ./src/V3PreLex.l ./src/verilog.l test_regress/t/*.c* test_regress/t/*.h
make[1]: Leaving directory '/svaha/wsnyder/SandBox/homecvs/v4/verilator'
2024-08-26 05:01:37 -04:00
Wilson Snyder fa4af38b0a configure: Print inbound CXX setting 2024-08-26 04:58:59 -04:00
Wilson Snyder a9635aaa2c Tests: Default to check_finished=>1 2024-08-24 19:27:59 -04:00
Wilson Snyder f0cd6dd95c Fix REALCVT warning on integral timescale conversions (#5378). 2024-08-24 08:01:28 -04:00
Wilson Snyder d8fdfa6be2 Internals: git ignore nohup.out 2024-08-24 07:56:48 -04:00
Wilson Snyder f9511e9755 Internals: Make V3Number::selfTest() 2024-08-24 05:41:22 -04:00
Wilson Snyder cfe1f23fff Commentary: Changes update 2024-08-23 18:45:54 -04:00
Wilson Snyder 8741fd17ad Internals: cppcheck cleanups. No functional change intended. 2024-08-23 18:24:34 -04:00
ffe76717c6 Thread pool rewrite (#5161)
Signed-off-by: Krzysztof Bieganski <[email protected]>
Signed-off-by: Bartłomiej Chmiel <[email protected]>
Signed-off-by: Arkadiusz Kozdra <[email protected]>
Co-authored-by: Krzysztof Bieganski <[email protected]>
Co-authored-by: Arkadiusz Kozdra <[email protected]>
Co-authored-by: Wilson Snyder <[email protected]>
2024-08-23 08:36:49 -04:00
Krzysztof Bieganski eb8bbcda05 Internals: Simplify CaptureVisitor in V3Randomize (#5397) 2024-08-23 07:57:57 -04:00
Arkadiusz Kozdra ed7040adc0 Fix dot fallback finding wrong symbols (#5394) 2024-08-22 15:49:08 -04:00
Wilson Snyder 48776277bd devel release 2024-08-21 08:55:53 -04:00
Wilson Snyder 8ca45df9c7 Version bump 2024-08-21 08:40:24 -04:00
Wilson Snyder 8db9c1d227 Commentary: Changes update 2024-08-21 08:40:14 -04:00
Krzysztof Bieganski 930f35acc9 Support constraint_mode (#5338) 2024-08-21 06:16:44 -04:00
Krzysztof Bieganski 13e0fc7c27 Fix virtual interface null checks (#5391) 2024-08-21 05:40:52 -04:00
Bartłomiej Chmiel a730daabef Support 'parameter type' in hierarchical blocks (#5309) (#5333) 2024-08-21 05:30:59 -04:00
Andrew Nolte 3c28b72897 Tests: Add info files to golden (#5390) 2024-08-21 06:44:02 +03:00
Wilson Snyder 05e5f1955e Update include/gtkwave from upstream 2024-08-20 15:23:53 -04:00
Wilson Snyder 378800ee4a Commentary: Changes update 2024-08-20 15:13:44 -04:00
Wilson Snyder 43a57da950 Add quotes to not-found filenames 2024-08-20 14:47:43 -04:00
James BaileyandJames Bailey 99a43b7695 Fix +: and -: unpacked array slicing when array has nonzero low index (#5345) (#5387)
Co-authored-by: James Bailey <[email protected]>
2024-08-20 14:20:48 -04:00
Krzysztof Bieganski 59d2eea302 Fix capturing fields from superclass in randomize() with (#5389)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-20 13:25:58 -04:00
Kaleb Barrett 6f3f64e63f Add --timing flag as Verilated cc define (#5383) 2024-08-18 20:02:54 +03:00
Drew Ranck 48c71ef76c Support default value on module input (#5358) (#5373) 2024-08-15 10:04:07 -04:00
Ryszard Rozak 563faeb33f Internals: Fix removing nodes in V3Life (#5365) 2024-08-14 09:23:24 +02:00
Wilson Snyder 9c5c77c69c Favor use of more general idAny in parser 2024-08-13 15:25:07 -04:00
Wilson Snyder 4573e04488 Fix segfault after unsupported member call (#5359). 2024-08-13 14:39:37 -04:00
Krzysztof Bieganski 6cb0a41857 Support inline random variable control (#5317)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-13 14:20:31 -04:00
Geza Lore 124e3463fc Fix cache config file resolution performance (#5369)
V3ConfigWildcardResolver::resolve used to only cache the result of a
name lookup if there were any directives applied to the queried name.

This can be a performance problem. E.g. the module resolver is invoked
for every variable to check for attributes. If you had 'n' variables in
the design, and you also had 'k' directives that apply to specific
modules not involving most of the 'n' variables, then checking the
attributes involved O(n*k) operations. This can be very expensive
for large 'n' and 'k'.

In this patch we resolve every name exactly once, so the same above is
now O(n) in the worst case, and often a lot smaller due to repeat
lookups.
2024-08-13 19:52:23 +02:00
Ethan Sifferman 1b15509a9c Fix lint_off on Errors (#5351) (#5363) 2024-08-11 21:04:46 +02:00
Wilson Snyder eb3f10399a Internal: Rename tokenPipeScanTypeEq. No functional change. 2024-08-11 12:15:20 -04:00
Wilson Snyder 4660806c8f Internals: Remove wrong = new grammar rule. 2024-08-11 11:03:28 -04:00
Wilson Snyder 6f5d1037b4 Commentary 2024-08-11 10:33:04 -04:00
Wilson Snyder 24b097b228 Improve new class error (#5359) 2024-08-11 10:09:05 -04:00
Wilson Snyder a0ea96b355 Favor use of more general idAny in parser 2024-08-09 18:00:36 -04:00
Wilson Snyder a663da7393 Internals: Split idType from simple_type. No functional change intended 2024-08-09 17:45:54 -04:00
Tim Hutt c812a9b18f Fix shortened module names when searching for files (#5196) (#5246) 2024-08-09 17:23:00 -04:00
Arkadiusz Kozdra 367249ec84 Add parsing but otherwise ignore std::randomize (#5354) 2024-08-09 17:21:32 -04:00
Wilson Snyder f4acc59b82 Tests: Check for wrong quotes in docs (#5355) 2024-08-09 17:18:59 -04:00
Luca Colagrande d1da1664f0 Docs: Fix typos in :vlopt: command usage in docs (#5355) (#5356) 2024-08-09 14:17:36 +01:00
Krzysztof Bieganski b100615726 Internals: Relax requirements for AstClass iteration methods (#5335)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-09 10:05:52 +01:00
Krzysztof Bieganski ec0815e9ac Fix NBAs in suspendables (#5348)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-08 22:12:00 +01:00
Krzysztof Bieganski 97e9996f0b Fix optimized-out sentrees with --timing (#5080) (#5349)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-08 21:57:12 +01:00
Krzysztof Bieganski b7af859ba3 Fix forks capturing non-input ports in tasks (#5237) (#5343)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-08 21:55:46 +01:00
Krzysztof Bieganski 701fa5438a Fix output clockvar overwriting signal (#5320) (#5347)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-08 21:48:25 +01:00
Geza Lore 004865a8b2 Fix tracing_{on,off} in the presence of non-inlined modules (#5346)
Previously "*.foo.*" failed to match non-inlined instances called 'foo'.
2024-08-08 17:16:54 +01:00
Arkadiusz Kozdra 3e5859e5da Support constraining AstSel (#5344)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-08-08 15:37:08 +01:00
Arkadiusz Kozdra 78555b683c Fix missing type coercion in 'inside {array}' (#5340) 2024-08-08 03:46:41 -04:00
Wilson Snyder c2e44dbd99 Fix $sformat with array arguments (#5330). 2024-08-08 03:32:07 -04:00
Wilson Snyder 18fc3e6089 Internals: Favor idAny in typedefs. 2024-08-07 18:45:53 -04:00
Wilson Snyder f4f8ea0dcf Internals: Change cast fileline to point to cast operator 2024-08-07 18:45:53 -04:00
Arkadiusz Kozdra f78c4e8490 Fix compilation error on unreachable disable fork / wait fork (#5339)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-08-07 18:44:02 -04:00
Arkadiusz Kozdra e6fe367bdb Support streams to/from arrays of wide data (#5334) 2024-08-06 16:18:16 +01:00
Ryszard Rozak 3426ee5170 Fix purity of functions with AstJumpBlock or AstStmtExpr (#5332) 2024-08-06 16:07:38 +01:00
Arkadiusz Kozdra a32b8d80f9 Support streaming operator on arrays and wide data (#5326)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-08-06 08:48:46 -04:00
Bartłomiej Chmiel 3b81654c72 Fix -Wunused-but-set-variable clang warning (#5331)
Signed-off-by: Bartłomiej Chmiel <[email protected]>
2024-08-06 08:48:12 -04:00
Wilson Snyder 6abd556f5a Tests: Fix GCC 11.4.0 hang 2024-08-06 08:47:28 -04:00
Varun Koyyalagunta 31c1df638b Fix assert on wide expression (#5319) (#5324) 2024-08-06 01:45:57 -04:00
Krzysztof Bieganski f4cb2c8cf2 Add more rand_mode unsupported errors (#5329)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-08-05 17:56:03 -04:00
Bartłomiej Chmiel 7d5e19365e Support assertcontrol directive type (#5310)
Signed-off-by: Bartłomiej Chmiel <[email protected]>
2024-08-05 17:54:13 -04:00
Wilson Snyder 6fa1ade4e0 Commentary: Changes update 2024-08-05 04:03:21 -04:00
Bartłomiej Chmiel 99c619a4c9 Error on static variable initializers using automatic variables in procedures (#5296) 2024-08-05 08:39:43 +01:00
Krzysztof Bieganski 37a4002098 Fix stringify in nested preprocessor macros (#5323) 2024-08-02 11:46:02 -04:00
Krzysztof Boroński 45ee949cc4 Internals: Disambiguate variable references under with clauses of randomize() methods (#5277) 2024-08-02 11:45:17 -04:00
Arkadiusz Kozdra 54f9f4b6a9 Support foreach constraints (#5302)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-08-02 10:03:55 -04:00
Arkadiusz Kozdra a61178bd89 Internals: Convert foreach loops in V3Begin as well as V3Width (#5283) 2024-08-02 08:29:05 -04:00
Krzysztof Bieganski 2f5c58b345 Support rand_mode (#5273)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-07-31 22:30:48 +01:00
Wilson Snyder 403a197e23 Python lint fix 2024-07-28 14:57:29 -04:00
Wilson Snyder 3a659d460d Fix ==? and !=? with X values. 2024-07-28 14:40:55 -04:00
Wilson Snyder 8707c88787 Tests: Close misc internal code coverage holes 2024-07-28 14:18:24 -04:00
github action 167cba723e Apply 'make format' 2024-07-28 17:59:13 +00:00
Wilson Snyder 7f40dd8b5b CI: Fix codecov upload 2024-07-28 13:58:26 -04:00
Wilson Snyder 1609c23fea Fix cputime being zero 2024-07-28 13:14:10 -04:00
Wilson Snyder 216fc8a212 CI: Fix codecov upload 2024-07-27 07:18:50 -04:00
Wilson Snyder 5136ea1082 CI: Fix codecov upload 2024-07-27 07:02:18 -04:00
Wilson Snyder 5b931faf2b CI: Fix codecov upload 2024-07-27 06:31:20 -04:00
Wilson Snyder a2496e041e CI: Change to action-based codecov upload 2024-07-26 14:07:53 -04:00
Wilson Snyder fab268f772 CI: Change to action-based codecov upload 2024-07-26 10:39:08 -04:00
Wilson Snyder 550d47b7f4 CI: Change to action-based codecov upload 2024-07-26 10:27:00 -04:00
Markus Krause a01a21db86 Fix make flows to pass PYTHON3 (like perl) (#5307) (#5308)
Fixes #5307
2024-07-26 09:35:37 -04:00
Wilson Snyder 2082f1aa9e Internals: Update fastcov.py from upstream 2024-07-26 08:48:12 -04:00
Wilson Snyder 50a5a1ff5b Tests: Fix some verilog.y parser coverage holes 2024-07-26 07:29:15 -04:00
Arkadiusz Kozdra 1600cc01a4 Internals: clean up begin blocks and lifetimes in foreach loops (#5306)
According to IEEE 1800-2023 12.7.3, the loop creates an implicit block
around it, containing declarations of the loop variables with automatic
lifetime.

No functional change intended.

Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-07-26 05:50:29 -04:00
Ryszard Rozak b9e1d55262 Fix handling of rand fields not referenced in constraints (#5305)
Signed-off-by: Ryszard Rozak <[email protected]>
2024-07-26 05:46:30 -04:00
Geza Lore 0d43c14b93 Internals: Remove redundant hash lookup (#5276 partial) (#5303)
Minor help for #5276
2024-07-25 16:07:58 -04:00
Ricardo Barbedo 87d1c10fa7 Fix compiler coroutine check (#5190) (#5300)
The necessary options to support C++ coroutines vary greatly between
compilers, its versions, and the standard library being used. This
patch makes the check for coroutine support more robust by adding a
declaration of a coroutine variable, instead of just including the
header. It also makes sure that the HAVE_COROUTINE and
CFG_CXXFLAGS_COROUTINES flags are always set together, and only when
coroutine support is detected.
2024-07-24 17:21:14 -04:00
Udaya Raj Subedi a2506a6f96 Fix monitor block sensitivity items (#4400) (#5294) 2024-07-24 07:18:57 -04:00
Bartłomiej Chmiel 20dba7464d Support--compiler-include headers in user-supplied cpp files (#5271)
Signed-off-by: Bartłomiej Chmiel <[email protected]>
2024-07-24 06:40:39 -04:00
Wilson Snyder cb5d03ff0b Fix WIDTHEXPAND on left shift of intuitive amount (#5284). 2024-07-24 06:39:27 -04:00
github action 2727c33219 Apply 'make format' 2024-07-24 10:07:59 +00:00
Wilson Snyder 0419ed0430 Fix initializing static array in dynamic arrays and queues (#5287). 2024-07-24 06:06:57 -04:00
Wilson Snyder 1e3c7a5496 Fix inline function ref port persistence 2024-07-23 18:47:04 -04:00
Wilson Snyder d2dfcbca53 Internals: Add log_changes for updating Changes file 2024-07-23 18:36:57 -04:00
Wilson Snyder e779934443 Commentary: Changes update 2024-07-22 17:22:37 -04:00
Arkadiusz Kozdra a3b255b054 Internal: Suppress new clang-tidy messages (#5293)
The two most useless warning classes are llvmlibc-* on virtually every
identifier use that it does not resolve to __llvm_libc:: namespace, and
altera-* ones that warn on virtually every loop statement that it could
be unrolled with a pragma.  No functional change.

Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-07-22 13:11:50 -04:00
Krzysztof Bieganski f5caa4b7dc Fix randomizing current object with rand class instance member (#5292)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-07-22 14:41:12 +02:00
Wilson Snyder 8f4490628f Commentary: Clarify some warning messages. 2024-07-20 17:50:14 -04:00
Wilson Snyder df566bdf4d Improve PINMISSING to show related port 2024-07-20 17:37:33 -04:00
Wilson Snyder 981d3ce782 Add suggestions on misspelled PLI functions. 2024-07-20 07:20:10 -04:00
Wilson Snyder b7345eb5d5 Tests: Add checkp macro. No test functionality change. 2024-07-20 06:51:50 -04:00
Krzysztof Bieganski 2bd2b9324f Fix inline constraints creating class random generator (#5280) 2024-07-19 13:03:48 -04:00
Arkadiusz Kozdra 298faa84ee Fix elaborating foreach loops (#5285) 2024-07-19 14:56:30 +02:00
Arkadiusz Kozdra 43377ed8b0 Add support for this.randomize with (#5282)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-07-19 09:14:56 +02:00
Krzysztof Bieganski b18037b7e7 Internals: Move non-visit methods to the proper place (#5279) 2024-07-18 08:57:39 -04:00
Yutetsu TAKATSUKASA 095b1ccb67 Fix incorrect result of width mismatch (#5186) (#5189) 2024-07-17 11:54:58 +02:00
Krzysztof Bieganski 2a30a87580 Fix randomization when used with inheritance (#5268)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-07-17 08:21:45 +02:00
Krzysztof Bieganski e11bc6beeb Internals: Refactor function argument traits (#5269)
No functional change intended.

Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-07-16 20:55:04 +02:00
Arkadiusz Kozdra 0a9b31bb30 Add warning on dist in constraints (#5264) 2024-07-15 21:01:33 -04:00
Krzysztof Bieganski 34e37d7bd0 Keep one member map for randomize method creation (#5263)
No functional change intended.

Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-07-15 16:42:41 +02:00
Yangyu Chen 164a7a7c5d Improve emitted code to use a reference for VlSelf (#5254) 2024-07-15 09:44:01 -04:00
Krzysztof Obłonczek 67ea819d82 Fix toggle coverage aggregation on same line (#5248)
Documentation states that minimum of all reported coverage of all signals in a line should be taken.
Previous logic would break if there were any signals with zero coverage followed by signals with
nonzero coverage - a minimum from those nonzero toggle count would be taken, disregarding zero
coverage of previous signals.

Internal-tag: [#62193]

Signed-off-by: Krzysztof Obłonczek <[email protected]>
2024-07-14 17:05:58 -04:00
Andrew Nolte 60f9e21d8c Fix --x-assign to be independent from +verilator+rand+reset (#5214) 2024-07-14 17:04:00 -04:00
Wilson Snyder dc037db1cd Internals: Make upcase clean. No functional change. 2024-07-14 15:28:00 -04:00
Wilson Snyder 0658af90f5 Fix classes/modules of case-similar names (#5109). 2024-07-14 13:57:16 -04:00
Wilson Snyder 131623de34 Internals: Favor s string literals. No functional change. 2024-07-14 11:39:45 -04:00
Wilson Snyder 74ae879c2f Internals: Remove duplicate filenameNonExt. No functional change. 2024-07-14 11:31:32 -04:00
Wilson Snyder 8c3b754bac Internals: Rename some filename functions. No functional change. 2024-07-14 09:34:54 -04:00
Wilson Snyder e080f5c0cb Fix tracing with --main-top-name - (#5261). 2024-07-14 07:35:26 -04:00
Wilson Snyder 2284cf595d Commentary: Changes update 2024-07-14 07:34:36 -04:00
Wilson Snyder b1cc0c54c1 Tests: Fail with test.pl-file-needs-have_solver()-call if forget have_solver() 2024-07-13 08:55:06 -04:00
Geza Lore 4cf017d7fe Tests: Skip t_randomize_method_constraints when no solver is installed (#5260) 2024-07-13 08:31:16 -04:00
Geza Lore 25f5db4b5f DFG: Allow inlining of variabels driven from forced vars (#5259)
Not sure why this was disabled before, but it seems legal to me to
change

'forced A' -> 'B' -> 'C'

into

'forced A' -> 'B',
'forced A' -> 'C'

Fixes #5249
2024-07-13 12:35:09 +01:00
Krzysztof Boroński 3cf9606ea9 Support inline constraints for class randomization methods (#5234)
Signed-off-by: Krzysztof Boronski <[email protected]>
2024-07-12 16:18:18 +02:00
Wilson Snyder 6882f8c55e Commentary: Surfer (#5253) 2024-07-11 18:33:35 -04:00
Krzysztof Bieganski 2696a9a5bd Fix unconstrained randomization of unpacked structs (#5252)
Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-07-11 16:43:56 +02:00
Krzysztof Bieganski abb46c9cb2 Refactor AstMemberSel creation with AstVar (#5251)
No functional change intended.

Signed-off-by: Krzysztof Bieganski <[email protected]>
2024-07-11 16:42:58 +02:00
Wilson Snyder bbb223f217 Fix error on empty generate with -O0 (#5250). 2024-07-11 06:59:15 -04:00
Arkadiusz Kozdra 570e1bc35a Support conditional constraints (#5245) 2024-07-10 11:30:18 -04:00
11da07d3b9 Support $assertcontrol assertion_type (#5236)
Signed-off-by: Bartłomiej Chmiel <[email protected]>
Signed-off-by: Ryszard Rozak <[email protected]>
Co-authored-by: Ryszard Rozak <[email protected]>
Co-authored-by: Wilson Snyder <[email protected]>
2024-07-10 05:06:13 -04:00
Arkadiusz Kozdra 2cfec0ecc3 Support clocking blocks in virtual interfaces (#5235) 2024-07-09 18:31:58 -04:00
Wilson Snyder e3e7b3f2b5 Fix errors on using string in incorrect format (#5240). 2024-07-09 08:30:20 -04:00
Wilson Snyder fe0b210a0c Fix errors on using string in incorrect format (#5340). 2024-07-09 08:29:22 -04:00
Chris Bachhuber c383f4868f Commentary: Mention docker hub explicitly (#5241) 2024-07-09 06:59:43 -04:00
Wilson Snyder b66fdd7421 Fix unknown conversion on queues (#5220). 2024-07-08 10:19:51 -04:00
Wilson Snyder 83878325a7 Commentary: Update git issue templates. 2024-07-08 08:12:58 -04:00
github action 490bc63eb5 Apply 'make format' 2024-07-06 12:13:35 +00:00
Ryan Ziegler 947b6fd23f Add --emit-accessors (#5182) (#5227) 2024-07-06 13:12:53 +01:00
Wilson Snyder de44ca8df3 Fix top-level unpacked structure resets (#5221). 2024-07-05 17:22:26 -04:00
Wilson Snyder 3cee54dfdf Commentary: Changes update 2024-07-05 17:17:29 -04:00
Geza Lore dace2c0a9a Tests: Skip t_constraint_state when no solver is installed (#5224) 2024-07-04 11:42:53 +01:00
Liam Braun ca4858eb7f Fix concurrency for mailbox and semaphores (#5222) 2024-07-03 22:29:32 +01:00
Wilson SnyderandSeth Pellegrino a6d438d111 Fix mis-removing $value$plusargs calls (#5127) (#5137). [Seth Pellegrino]
Co-authored-by: Seth Pellegrino <[email protected]>
2024-07-02 18:46:58 -04:00
Bartłomiej Chmiel 955ed3f193 Fix splitting if statements with impure conditions (#5219) 2024-07-02 15:17:10 -04:00
Wilson Snyder 8bffb8c391 Fix table optimizing logic with side effect (#5137 prep) 2024-07-02 09:22:56 -04:00
Arkadiusz Kozdra 85356f464f State-dependent constraints (#5217)
Signed-off-by: Arkadiusz Kozdra <[email protected]>
2024-07-01 20:19:15 +02:00
Arkadiusz Kozdra 72993ec3dd Support cross-module clockvars access (#5184) 2024-06-30 15:19:02 -04:00
404allen404 d6a294b784 Commentary: Fix typo in for --trace-max-array and --trace-max-width options (#5205) 2024-06-27 21:25:21 -04:00
Bartłomiej Chmiel 864a852bca Add --compiler-include for additional C++ includes (#5139) (#5202) 2024-06-27 18:53:44 -04:00
Wilson Snyder b0992406aa Commentary: Changes update 2024-06-25 19:22:00 -04:00
Bartłomiej Chmiel 9e2c8aefc8 Add --pins-sc-uint-bool to force SystemC uint type (#5192) 2024-06-25 05:27:09 -04:00
Gus Smith 4c584c17e6 Add -std=gnu++20 (#5200) 2024-06-25 05:23:50 -04:00
Wilson Snyder 3315a6e431 Internals: Also cleanup gettes/setters in .cpp. No functional change intended. 2024-06-22 19:50:59 -04:00
github action ba0183131c Apply 'make format' 2024-06-22 22:58:42 +00:00
Ryan Ziegler e1580b9c3d Internals: Reorder class getters/setters (#5197). No functional change intended. 2024-06-22 18:57:54 -04:00
Tim Hutt aadd5ea509 Fix linking with pthreads on CMake (#5194) 2024-06-21 10:34:11 -04:00
Philip Axer 833df6d9ea Fix CMake installation missing verilated.mk (#5187) (#5188) 2024-06-19 08:07:17 -04:00
Wilson Snyder 607c19a67d Fix isPure to be superset of isOutputter.
This may cause some additional SIDEEFFECT warnings that previously were not shown.
2024-06-16 21:43:30 -04:00
Wilson Snyder d5cfe1a379 Fix fusing macro arguments to not ignore whitespace (#5061). 2024-06-15 09:21:21 -04:00
Wilson Snyder 6e557791c8 devel release 2024-06-15 08:49:57 -04:00
5935 changed files with 103406 additions and 123287 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
Checks: '*,-hicpp*,-android-cloexec-fopen,-cert-dcl50-cpp,-cert-env33-c,-cert-err34-c,-cert-err58-cpp,-clang-analyzer-core.UndefinedBinaryOperatorResult,-clang-analyzer-security*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-no-malloc,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-special-member-functions,-fuchsia-*,-google-default-arguments,-google-readability-todo,-google-runtime-references,-llvm-header-guard,-llvm-include-order,-misc-string-integer-assignment,-misc-string-literal-with-embedded-nul,-modernize-use-auto,-modernize-use-trailing-return-type,-readability-braces-around-statements,-readability-container-size-empty,-readability-delete-null-pointer,-readability-else-after-return,-readability-implicit-bool-conversion,-readability-named-parameter,-readability-static-accessed-through-instance'
Checks: '*,-hicpp*,-android-cloexec-fopen,-cert-dcl50-cpp,-cert-env33-c,-cert-err34-c,-cert-err58-cpp,-clang-analyzer-core.UndefinedBinaryOperatorResult,-clang-analyzer-security*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-no-malloc,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-special-member-functions,-fuchsia-*,-google-default-arguments,-google-readability-todo,-google-runtime-references,-llvm-header-guard,-llvm-include-order,-misc-string-integer-assignment,-misc-string-literal-with-embedded-nul,-modernize-use-auto,-modernize-use-trailing-return-type,-readability-braces-around-statements,-readability-container-size-empty,-readability-delete-null-pointer,-readability-else-after-return,-readability-implicit-bool-conversion,-readability-named-parameter,-readability-static-accessed-through-instance,-llvmlibc-*,-altera-*'
WarningsAsErrors: ''
HeaderFilterRegex: ''
FormatStyle: none
+4 -4
View File
@@ -1,6 +1,6 @@
---
exclude_paths:
- '.github/**'
- 'ci/build_verilator.sh'
- 'include/vltstd/**'
- 'nodist/fastcov.py'
- ".github/**"
- "ci/build_verilator.sh"
- "include/vltstd/**"
- "nodist/fastcov.py"
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "Verilator Build Environment",
"name": "Verilator Build Environment",
"build": {
"build": {
"dockerfile": "../ci/docker/buildenv/Dockerfile"
}
+2
View File
@@ -11,6 +11,8 @@ Thanks for taking the time to report this.
What would you like added/supported?
What 'verilator --version' are you using? Did you try it with the git master version?
Can you attach an example that runs on other simulators? (Must be openly licensed, ideally in test_regress format.)
May we assist you in trying to fix this in Verilator yourself?
+2
View File
@@ -8,3 +8,5 @@ assignees: ''
---
How may we help - what is your question?
(If reporting a bug or requesting a feature please use one of the other issue templates.)
+84 -84
View File
@@ -1,3 +1,4 @@
---
# DESCRIPTION: Github actions config
# This name is key to badges in README.rst, so we use the name build
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
@@ -9,7 +10,7 @@ on:
pull_request:
workflow_dispatch:
schedule:
- cron: '0 0 * * 0' # weekly
- cron: '0 0 * * 0' # weekly
env:
CI_OS_NAME: linux
@@ -35,14 +36,14 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, ubuntu-20.04]
os: [ubuntu-24.04, ubuntu-22.04, ubuntu-20.04]
compiler:
- { cc: clang, cxx: clang++ }
- { cc: gcc, cxx: g++ }
- {cc: clang, cxx: clang++}
- {cc: gcc, cxx: g++}
include:
# Build GCC 10 on ubuntu-20.04
- os: ubuntu-20.04
compiler: { cc: gcc-10, cxx: g++-10 }
compiler: {cc: gcc-10, cxx: g++-10}
runs-on: ${{ matrix.os }}
name: Build | ${{ matrix.os }} | ${{ matrix.compiler.cc }}
env:
@@ -51,41 +52,40 @@ jobs:
CC: ${{ matrix.compiler.cc }}
CXX: ${{ matrix.compiler.cxx }}
CACHE_BASE_KEY: build-${{ matrix.os }}-${{ matrix.compiler.cc }}
CCACHE_MAXSIZE: 1000M # Per build matrix entry (* 5 = 5000M in total)
CCACHE_MAXSIZE: 1000M # Per build matrix entry (* 5 = 5000M in total)
VERILATOR_ARCHIVE: verilator-${{ github.sha }}-${{ matrix.os }}-${{ matrix.compiler.cc }}.tar.gz
steps:
- name: Checkout
uses: actions/checkout@v4
with:
path: repo
- name: Checkout
uses: actions/checkout@v4
with:
path: repo
- name: Cache $CCACHE_DIR
uses: actions/cache@v4
env:
CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache
with:
path: ${{ env.CCACHE_DIR }}
key: ${{ env.CACHE_KEY }}-${{ github.sha }}
restore-keys: |
${{ env.CACHE_KEY }}-
- name: Cache $CCACHE_DIR
uses: actions/cache@v4
env:
CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache
with:
path: ${{ env.CCACHE_DIR }}
key: ${{ env.CACHE_KEY }}-${{ github.sha }}
restore-keys: |
${{ env.CACHE_KEY }}-
- name: Install packages for build
run: ./ci/ci-install.bash
- name: Install packages for build
run: ./ci/ci-install.bash
- name: Build
run: ./ci/ci-script.bash
- name: Build
run: ./ci/ci-script.bash
- name: Tar up repository
working-directory: ${{ github.workspace }}
run: tar --posix -c -z -f ${{ env.VERILATOR_ARCHIVE }} repo
- name: Upload tar archive
uses: actions/upload-artifact@v4
with:
path: ${{ github.workspace }}/${{ env.VERILATOR_ARCHIVE }}
name: ${{ env.VERILATOR_ARCHIVE }}
- name: Tar up repository
working-directory: ${{ github.workspace }}
run: tar --posix -c -z -f ${{ env.VERILATOR_ARCHIVE }} repo
- name: Upload tar archive
uses: actions/upload-artifact@v4
with:
path: ${{ github.workspace }}/${{ env.VERILATOR_ARCHIVE }}
name: ${{ env.VERILATOR_ARCHIVE }}
test:
needs: build
@@ -94,25 +94,25 @@ jobs:
matrix:
os: [ubuntu-22.04, ubuntu-20.04]
compiler:
- { cc: clang, cxx: clang++ }
- { cc: gcc, cxx: g++ }
- {cc: clang, cxx: clang++}
- {cc: gcc, cxx: g++}
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
- {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}
# Test with GCC 10 on ubuntu-20.04, also test relocation
- {os: ubuntu-20.04, compiler: {cc: gcc-10, cxx: g++-10}, reloc: 1, suite: dist-vlt-0}
- {os: ubuntu-20.04, compiler: {cc: gcc-10, cxx: g++-10}, reloc: 1, suite: dist-vlt-1}
- {os: ubuntu-20.04, compiler: {cc: gcc-10, cxx: g++-10}, reloc: 1, suite: dist-vlt-2}
- {os: ubuntu-20.04, compiler: {cc: gcc-10, cxx: g++-10}, reloc: 1, suite: dist-vlt-3}
- {os: ubuntu-20.04, compiler: {cc: gcc-10, cxx: g++-10}, reloc: 1, suite: vltmt-0}
- {os: ubuntu-20.04, compiler: {cc: gcc-10, cxx: g++-10}, reloc: 1, suite: vltmt-1}
# Ubuntu 24.04 only on GCC; not passing on clang yet
- {os: ubuntu-24.04, compiler: {cc: gcc, cxx: g++}, suite: dist-vlt-0}
- {os: ubuntu-24.04, compiler: {cc: gcc, cxx: g++}, suite: dist-vlt-1}
- {os: ubuntu-24.04, compiler: {cc: gcc, cxx: g++}, suite: dist-vlt-2}
- {os: ubuntu-24.04, compiler: {cc: gcc, cxx: g++}, suite: dist-vlt-3}
- {os: ubuntu-24.04, compiler: {cc: gcc, cxx: g++}, suite: vltmt-0}
- {os: ubuntu-24.04, compiler: {cc: gcc, cxx: g++}, suite: vltmt-1}
runs-on: ${{ matrix.os }}
name: Test | ${{ matrix.os }} | ${{ matrix.compiler.cc }} | ${{ matrix.reloc && 'reloc | ' || '' }} ${{ matrix.suite }}
env:
@@ -122,37 +122,37 @@ jobs:
CC: ${{ matrix.compiler.cc }}
CXX: ${{ matrix.compiler.cxx }}
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)
CCACHE_MAXSIZE: 100M # Per build per suite (* 5 * 5 = 2500M in total)
VERILATOR_ARCHIVE: verilator-${{ github.sha }}-${{ matrix.os }}-${{ matrix.compiler.cc }}.tar.gz
steps:
- name: Download tar archive
uses: actions/download-artifact@v4
with:
name: ${{ env.VERILATOR_ARCHIVE }}
path: ${{ github.workspace }}
- name: Download tar archive
uses: actions/download-artifact@v4
with:
name: ${{ env.VERILATOR_ARCHIVE }}
path: ${{ github.workspace }}
- name: Unpack tar archive
working-directory: ${{ github.workspace }}
run: tar -x -z -f ${{ env.VERILATOR_ARCHIVE }}
- name: Unpack tar archive
working-directory: ${{ github.workspace }}
run: tar -x -z -f ${{ env.VERILATOR_ARCHIVE }}
- name: Cache $CCACHE_DIR
uses: actions/cache@v4
env:
CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache2
with:
path: ${{ env.CCACHE_DIR }}
key: ${{ env.CACHE_KEY }}-${{ github.sha }}
restore-keys: |
${{ env.CACHE_KEY }}-
- name: Cache $CCACHE_DIR
uses: actions/cache@v4
env:
CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache2
with:
path: ${{ env.CCACHE_DIR }}
key: ${{ env.CACHE_KEY }}-${{ github.sha }}
restore-keys: |
${{ env.CACHE_KEY }}-
- name: Install test dependencies
run: ./ci/ci-install.bash
- name: Install test dependencies
run: ./ci/ci-install.bash
- name: Test
env:
TESTS: ${{ matrix.suite }}
run: ./ci/ci-script.bash
- name: Test
env:
TESTS: ${{ matrix.suite }}
run: ./ci/ci-script.bash
lint-py:
runs-on: ubuntu-22.04
@@ -161,21 +161,21 @@ jobs:
CI_BUILD_STAGE_NAME: build
CI_RUNS_ON: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
path: repo
- name: Checkout
uses: actions/checkout@v4
with:
path: repo
- name: Install packages for build
run: ./ci/ci-install.bash
- name: Install packages for build
run: ./ci/ci-install.bash
# We use specific version numbers, otherwise a Python package
# update may add a warning and break our build
- name: Install packages for lint
run: sudo pip3 install pylint==3.0.2 ruff==0.1.3 clang sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe ruff
- name: Install packages for lint
run: sudo pip3 install pylint==3.0.2 ruff==0.1.3 clang sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe ruff
- name: Configure
run: autoconf && ./configure --enable-longtests --enable-ccwarn
- name: Configure
run: autoconf && ./configure --enable-longtests --enable-ccwarn
- name: Lint
run: make -k lint-py
- name: Lint
run: make -k lint-py
+4 -5
View File
@@ -1,17 +1,16 @@
---
# DESCRIPTION: Github actions config
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
#
name: Contributor Agreement
on:
push:
pull_request:
workflow_dispatch:
jobs:
Test:
name: "'docs/CONTRIBUTORS' was signed"
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- run: test_regress/t/t_dist_contributors.pl
- uses: actions/checkout@v4
- run: test_regress/t/t_dist_contributors.py
+42 -48
View File
@@ -1,3 +1,4 @@
---
# DESCRIPTION: Github actions config
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
@@ -6,7 +7,7 @@ name: coverage
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 0' # weekly
- cron: '0 0 * * 0' # weekly
env:
CI_OS_NAME: linux
@@ -21,7 +22,6 @@ defaults:
jobs:
Build:
runs-on: ubuntu-22.04
env:
@@ -29,49 +29,36 @@ jobs:
CI_RUNS_ON: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
path: repo
- name: Checkout
uses: actions/checkout@v4
with:
path: repo
- name: Install packages for build
run: ./ci/ci-install.bash
- name: Install packages for build
run: ./ci/ci-install.bash
- name: Build
run: ./ci/ci-script.bash
- name: Build
run: ./ci/ci-script.bash
- name: Tar up repository
working-directory: ${{ github.workspace }}
run: tar --posix -c -z -f ${{ env.VERILATOR_ARCHIVE }} repo
- name: Upload tar archive
uses: actions/upload-artifact@v4
with:
path: ${{ github.workspace }}/${{ env.VERILATOR_ARCHIVE }}
name: ${{ env.VERILATOR_ARCHIVE }}
- name: Tar up repository
working-directory: ${{ github.workspace }}
run: tar --posix -c -z -f ${{ env.VERILATOR_ARCHIVE }} repo
- name: Upload tar archive
uses: actions/upload-artifact@v4
with:
path: ${{ github.workspace }}/${{ env.VERILATOR_ARCHIVE }}
name: ${{ env.VERILATOR_ARCHIVE }}
Test:
needs: Build
strategy:
fail-fast: false
matrix:
test:
- vlt-
- vltmt-
num:
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
test: [vlt-, vltmt-]
num: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
include:
- { test: dist, num: '' }
- {test: dist, num: ''}
runs-on: ubuntu-22.04
name: test-${{ matrix.test }}${{ matrix.num }}
env:
@@ -79,20 +66,27 @@ jobs:
CI_RUNS_ON: ubuntu-22.04
steps:
- name: Download tar archive
uses: actions/download-artifact@v4
with:
name: ${{ env.VERILATOR_ARCHIVE }}
path: ${{ github.workspace }}
- name: Download tar archive
uses: actions/download-artifact@v4
with:
name: ${{ env.VERILATOR_ARCHIVE }}
path: ${{ github.workspace }}
- name: Unpack tar archive
working-directory: ${{ github.workspace }}
run: tar -x -z -f ${{ env.VERILATOR_ARCHIVE }}
- name: Unpack tar archive
working-directory: ${{ github.workspace }}
run: tar -x -z -f ${{ env.VERILATOR_ARCHIVE }}
- name: Install test dependencies
run: ./ci/ci-install.bash
- name: Install test dependencies
run: ./ci/ci-install.bash
- name: Test
env:
TESTS: coverage-${{ matrix.test }}${{ matrix.num }}
run: ./ci/ci-script.bash
- name: Test
env:
TESTS: coverage-${{ matrix.test }}${{ matrix.num }}
run: ./ci/ci-script.bash
- name: Upload coverage data to Codecov
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: |
find . -name '*.gcno' -exec rm {} \;
./ci/codecov -v upload-process -Z --sha ${{ github.sha }} -f nodist/obj_dir/coverage/app_total.info
+43 -42
View File
@@ -1,3 +1,4 @@
---
# Build and push verilator docker image when tags are pushed to the repository.
# The following variable(s) must be configured in the github repository:
# DOCKER_HUB_NAMESPACE: docker hub namespace.
@@ -8,7 +9,7 @@ name: Build Verilator Container
on:
push:
tags: [ 'v*' ]
tags: ['v*']
workflow_dispatch:
inputs:
manual_tag:
@@ -34,52 +35,52 @@ jobs:
# - "ci/docker/buildenv:verilator-buildenv"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v4
- name: Extract context variables
run: |
echo "${{ matrix.contexts }}" | sed -r 's/(.*):.*/build_context=\1/' >> "$GITHUB_ENV"
echo "${{ matrix.contexts }}" | sed -r 's/.*:(.*)/image_name=\1/' >> "$GITHUB_ENV"
echo "git_tag=${GITHUB_REF#refs/*/}" >> "$GITHUB_ENV"
- name: Extract context variables
run: |
echo "${{ matrix.contexts }}" | sed -r 's/(.*):.*/build_context=\1/' >> "$GITHUB_ENV"
echo "${{ matrix.contexts }}" | sed -r 's/.*:(.*)/image_name=\1/' >> "$GITHUB_ENV"
echo "git_tag=${GITHUB_REF#refs/*/}" >> "$GITHUB_ENV"
- name: Use manual tag
if: ${{ inputs.manual_tag }}
run: |
echo "git_tag=${{ inputs.manual_tag }}" >> "$GITHUB_ENV"
- name: Use manual tag
if: ${{ inputs.manual_tag }}
run: |
echo "git_tag=${{ inputs.manual_tag }}" >> "$GITHUB_ENV"
- name: Docker meta
id: docker_meta
uses: docker/metadata-action@v4
with:
images: |
${{ vars.DOCKER_HUB_NAMESPACE }}/${{ env.image_name }}
tags: |
type=match,pattern=(v.*),group=1,enable=${{ startsWith(github.ref, 'refs/tags/v') }}
type=raw,value=${{ inputs.manual_tag }},enable=${{ inputs.manual_tag != '' }}
type=raw,value=latest,enable=${{ inputs.add_latest_tag == true }}
- name: Docker meta
id: docker_meta
uses: docker/metadata-action@v4
with:
images: |
${{ vars.DOCKER_HUB_NAMESPACE }}/${{ env.image_name }}
tags: |
type=match,pattern=(v.*),group=1,enable=${{ startsWith(github.ref, 'refs/tags/v') }}
type=raw,value=${{ inputs.manual_tag }},enable=${{ inputs.manual_tag != '' }}
type=raw,value=latest,enable=${{ inputs.add_latest_tag == true }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
buildkitd-flags: --debug
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_USER }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_USER }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Build and Push to Docker
uses: docker/build-push-action@v4
if: startsWith(github.ref, 'refs/tags/v')
with:
context: ${{ env.build_context }}
build-args: SOURCE_COMMIT=${{ env.git_tag }}
platforms: linux/arm64,linux/amd64
push: ${{ !env.ACT && startsWith(github.ref, 'refs/tags/v') }}
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
- name: Build and Push to Docker
uses: docker/build-push-action@v4
if: startsWith(github.ref, 'refs/tags/v')
with:
context: ${{ env.build_context }}
build-args: SOURCE_COMMIT=${{ env.git_tag }}
platforms: linux/arm64,linux/amd64
push: ${{ !env.ACT && startsWith(github.ref, 'refs/tags/v') }}
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
+2 -3
View File
@@ -1,13 +1,12 @@
---
# DESCRIPTION: Github actions config
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
#
name: format
on:
push:
pull_request_target:
workflow_dispatch:
jobs:
format:
runs-on: ubuntu-22.04
+25 -30
View File
@@ -1,55 +1,50 @@
---
# DESCRIPTION: Github actions config
# This name is key to badges in README.rst, so we use the name build
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
#
name: msbuild
on:
push:
pull_request:
workflow_dispatch:
schedule:
- cron: '0 0 * * 0' # weekly
- cron: 0 0 * * 0 # weekly
env:
CI_OS_NAME: win
CI_COMMIT: ${{ github.sha }}
CCACHE_COMPRESS: 1
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_LIMIT_MULTIPLE: 0.95
defaults:
run:
working-directory: repo
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}
cancel-in-progress: true
jobs:
windows:
windows:
name: run on windows
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
with:
path: repo
- name: Cache $CCACHE_DIR
uses: actions/cache@v4
with:
path: ${{ env.CCACHE_DIR }}
key: msbuild-msvc-cmake
- name: compile
env:
WIN_FLEX_BISON: ${{ github.workspace }}/.ccache
run: ./ci/ci-win-compile.ps1
- name: test build
run: ./ci/ci-win-test.ps1
- name: Zip up repository
run: Compress-Archive -LiteralPath install -DestinationPath verilator.zip
- name: Upload zip archive
uses: actions/upload-artifact@v4
with:
path: ${{ github.workspace }}/repo/verilator.zip
name: verilator-win.zip
- uses: actions/checkout@v4
with:
path: repo
- name: Cache $CCACHE_DIR
uses: actions/cache@v4
with:
path: ${{ env.CCACHE_DIR }}
key: msbuild-msvc-cmake
- name: compile
env:
WIN_FLEX_BISON: ${{ github.workspace }}/.ccache
run: ./ci/ci-win-compile.ps1
- name: test build
run: ./ci/ci-win-test.ps1
- name: Zip up repository
run: Compress-Archive -LiteralPath install -DestinationPath verilator.zip
- name: Upload zip archive
uses: actions/upload-artifact@v4
with:
path: ${{ github.workspace }}/repo/verilator.zip
name: verilator-win.zip
+8 -4
View File
@@ -29,14 +29,15 @@ dddrun*
doxygen-doc
gdbrun*
gmon.out
ncverilog.history
internals.txt
ncverilog.history
nohup.out
verilator-config-version.cmake
verilator-config.cmake
verilator.pc
verilator.txt
verilator_bin*
verilator_coverage_bin*
verilator.pc
verilator-config.cmake
verilator-config-version.cmake
**/__pycache__/*
**/_build/*
**/obj_dir/*
@@ -46,3 +47,6 @@ verilator-config-version.cmake
/test_regress/snapshot/
xmverilog.*
xrun.history
# Normal CMake build directory
/build
+8
View File
@@ -0,0 +1,8 @@
---
- id: verilator
name: verilator-lint
description: Runs verilator Docker image to lint (System) Verilog designs
args: [--lint-only]
language: docker_image
entry: verilator/verilator:latest
types_or: [verilog, system-verilog]
+4
View File
@@ -0,0 +1,4 @@
[style]
based_on_style = pep8
column_limit = 99
#split_before_arithmetic_operator=True
+74 -34
View File
@@ -14,36 +14,44 @@
cmake_minimum_required(VERSION 3.15)
cmake_policy(SET CMP0091 NEW) # Use MSVC_RUNTIME_LIBRARY to select the runtime
project(Verilator
VERSION 5.026
project(
Verilator
VERSION 5.030
HOMEPAGE_URL https://verilator.org
LANGUAGES CXX
)
option(DEBUG_AND_RELEASE_AND_COVERAGE
"Builds both the debug and release binaries, overriding CMAKE_BUILD_TYPE. Not supported under MSBuild.")
option(
DEBUG_AND_RELEASE_AND_COVERAGE
"Builds both the debug and release binaries, overriding CMAKE_BUILD_TYPE. Not supported under MSBuild."
)
find_package(Python3 COMPONENTS Interpreter)
set(PYTHON3 Python3::Interpreter)
set(CMAKE_INSTALL_DATADIR ${CMAKE_INSTALL_PREFIX})
set(PYTHON3 ${Python3_EXECUTABLE})
# See also CMake built-in; CMAKE_INSTALL_PREFIX is applied by the install command.
set(CMAKE_INSTALL_DATADIR .)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
include(CheckStructHasMember)
include(ExternalProject)
include(FindThreads)
if (NOT WIN32)
if(NOT WIN32)
message(WARNING "CMake support on Linux/OSX is experimental.")
endif()
if (WIN32)
if (DEFINED ENV{WIN_FLEX_BISON})
if(WIN32)
if(DEFINED ENV{WIN_FLEX_BISON})
set(WIN_FLEX_BISON "$ENV{WIN_FLEX_BISON}")
endif()
if (EXISTS ${WIN_FLEX_BISON})
if(EXISTS ${WIN_FLEX_BISON})
list(APPEND CMAKE_PREFIX_PATH ${WIN_FLEX_BISON})
endif()
if (NOT WIN_FLEX_BISON)
message(FATAL_ERROR "Please install https://github.com/lexxmark/winflexbison and set WIN_FLEX_BISON environment variable. Please use install cmake target after a successful build.")
if(NOT WIN_FLEX_BISON)
message(
FATAL_ERROR
"Please install https://github.com/lexxmark/winflexbison and set WIN_FLEX_BISON environment variable. Please use install cmake target after a successful build."
)
endif()
set(CMAKE_CXX_STANDARD 20)
endif()
@@ -51,20 +59,25 @@ endif()
set(OBJCACHE "" CACHE STRING "Path for ccache, auto-detected if empty")
option(OBJCACHE_ENABLED "Compile Verilator with ccache" ON)
if (OBJCACHE_ENABLED)
if (OBJCACHE STREQUAL "")
if(OBJCACHE_ENABLED)
if(OBJCACHE STREQUAL "")
find_program(OBJCACHE_PATH ccache)
if (OBJCACHE_PATH STREQUAL "OBJCACHE_PATH-NOTFOUND")
if(OBJCACHE_PATH STREQUAL "OBJCACHE_PATH-NOTFOUND")
set(OBJCACHE_PATH "")
endif()
else()
set(OBJCACHE_PATH "${OBJCACHE}")
endif()
if (NOT OBJCACHE_PATH STREQUAL "")
execute_process(COMMAND "${OBJCACHE_PATH}" --version
OUTPUT_VARIABLE objcache_version)
if(NOT OBJCACHE_PATH STREQUAL "")
execute_process(
COMMAND "${OBJCACHE_PATH}" --version
OUTPUT_VARIABLE objcache_version
)
string(REGEX MATCH "[^\n\r]+" objcache_version "${objcache_version}")
message(STATUS "Found ccache: ${OBJCACHE_PATH} (\"${objcache_version}\")")
message(
STATUS
"Found ccache: ${OBJCACHE_PATH} (\"${objcache_version}\")"
)
set(CMAKE_CXX_COMPILER_LAUNCHER "${OBJCACHE_PATH}")
endif()
endif()
@@ -75,8 +88,8 @@ find_package(FLEX)
# Build
#set_property(GLOBAL PROPERTY JOB_POOLS one_job=1)
if (DEBUG_AND_RELEASE_AND_COVERAGE)
if (CMAKE_GENERATOR MATCHES "^Visual Studio ")
if(DEBUG_AND_RELEASE_AND_COVERAGE)
if(CMAKE_GENERATOR MATCHES "^Visual Studio ")
error("%Error: The DEBUG_AND_RELEASE_AND_COVERAGE option is not supported in MSBuild-based builds.")
endif()
set(saved_build_type ${CMAKE_BUILD_TYPE})
@@ -95,42 +108,69 @@ endif()
set(PACKAGE_NAME ${PROJECT_NAME})
set(PACKAGE_VERSION ${PROJECT_VERSION})
set(CXX ${CMAKE_CXX_COMPILER})
set(AR ${CMAKE_AR})
configure_file(include/verilated_config.h.in include/verilated_config.h @ONLY)
configure_file(include/verilated.mk.in include/verilated.mk @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/verilated_config.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
configure_package_config_file(verilator-config.cmake.in verilator-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/include/verilated_config.h
DESTINATION include
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/include/verilated.mk
DESTINATION include
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/verilator-config.cmake DESTINATION ${CMAKE_INSTALL_PREFIX})
configure_package_config_file(verilator-config-version.cmake.in verilator-config-version.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}
configure_package_config_file(
verilator-config.cmake.in
verilator-config.cmake
INSTALL_DESTINATION .
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/verilator-config-version.cmake DESTINATION ${CMAKE_INSTALL_PREFIX})
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/verilator-config.cmake
DESTINATION .
)
foreach (program
configure_package_config_file(
verilator-config-version.cmake.in
verilator-config-version.cmake
INSTALL_DESTINATION .
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/verilator-config-version.cmake
DESTINATION .
)
foreach(
program
verilator
verilator_gantt
verilator_ccache_report
verilator_difftree
verilator_profcfunc
verilator_includer
)
install(PROGRAMS bin/${program} TYPE BIN)
endforeach()
install(DIRECTORY examples TYPE DATA FILES_MATCHING
install(
DIRECTORY examples
TYPE DATA
FILES_MATCHING
PATTERN "examples/*/*.[chv]*"
PATTERN "examples/*/Makefile*"
PATTERN "examples/*/CMakeLists.txt"
)
install(DIRECTORY include TYPE DATA FILES_MATCHING
install(
DIRECTORY include
TYPE DATA
FILES_MATCHING
PATTERN "include/verilated_config.h"
PATTERN "include/verilated.mk"
PATTERN "include/*.[chv]"
PATTERN "include/*.cpp"
PATTERN "include/*.sv"
+187 -3
View File
@@ -8,6 +8,183 @@ The changes in each Verilator version are described below. The
contributors that suggested a given feature are shown in []. Thanks!
Verilator 5.030 2024-10-27
==========================
**Major:**
* Add `-output-groups` to build with concatenated .cpp files (#5257). [Mariusz Glebocki]
* Self-tests have been converted to Python, run `{test_name}.py` instead of `{test_name}.pl`.
**Minor:**
* Change .vlt config files to be read before .v files (#5185). [David Moberg]
* Change to use maximum for cover point aggregation (#5402). [Andrew Nolte]
* Change `--main` and `--binary` to use a TOP hierarchy name of "" (#5482).
* Change install of public executables into bindir instead of pkgdatadir (#5140) (#5544). [Geza Lore]
* Support IEEE-compliant intra-assign delays (#3711) (#5441). [Krzysztof Bieganski, Antmicro Ltd.]
* Support `wor`, `trior`, `wand`, `triand` (#5386) (#5496). [Zhou Shen]
* Support unconstrained randomization for unions (#5395) (#5396). [Yilou Wang]
* Support basic constrained queue randomization (#5413). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support packed/unpacked and dynamic array unconstrained randomization (#5414) (#5415). [Yilou Wang]
* Support appending to queue via `[]` (#5421). [Krzysztof Bieganski, Antmicro Ltd.]
* Support named event locals (#5422). [Krzysztof Bieganski, Antmicro Ltd.]
* Support basic `dist` constraints (#5431). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support unpacked array constrained randomization (#5437) (#5489). [Yilou Wang]
* Support inside array constraints (#5448). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support DPI imports and exports with double underscores (#5481).
* Support ccache when compiling Verilated files with cmake.
* Support `local` and `protected` on `typedef` (#5460).
* Support unconstrained randomization for associative array and queue (#5515). [Yilou Wang]
* Support `rand` dynamic arrays of objects (#5557) (#5564). [Ryszard Rozak, Antmicro Ltd.]
* Add error on misused genvar (#408). [Alex Solomatnikov]
* Add error on instances without parenthesis.
* Add Docker pre-commit hook (#5238) (#5452). [Chris Bachhuber]
* Add partial coverage symbol and branch data in lcov info files (#5388). [Andrew Nolte]
* Add method to check if there are VPI callbacks of the given type (#5399). [Kaleb Barrett]
* Remove warning on unsized numbers exceeding 32-bits.
* Improve Verilation thread pool (#5161). [Bartłomiej Chmiel, Antmicro Ltd.]
* Improve performance of V3VariableOrder with parallelism (#5406). [Bartłomiej Chmiel, Antmicro Ltd.]
* Improve parser error handling (#5493). [Arkadiusz Kozdra, Antmicro Ltd.]
* Improve process trigger performance (#5483). [Geza Lore]
* Fix suppression of WIDTH* warnings when immediately under a size cast (#3417).
* Fix `$fatal` to not be affected by `+verilator+error+limit` (#5135). [Gökçe Aydos]
* Fix equivalence checking when replacing type parameters (#5213) (#5255). [Han Qi]
* Fix display with multiple string formats (#5311). [Luiza de Melo]
* Fix performance of V3Trace when many activity blocks (#5372). [Deniz Güzel]
* Fix REALCVT warning on integral timescale conversions (#5378). [Liam Braun]
* Fix multidimensional function return value selects (#5382). [Gökçe Aydos]
* Fix internal error in out-of-range select (#5393) (#5443). [Geza Lore]
* Fix dot fallback finding wrong symbols (#5394). [Arkadiusz Kozdra, Antmicro Ltd.]
* Fix infinite recursion due to recursive functions/tasks (#5398). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix V3Randomize compile error on old GCC (#5403) (#5417). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix extra events in traces (#5405).
* Fix empty `foreach` in `if` in constraints (#5408). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix queue `[$-i]` select as reference argument (#5411). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix `pre`/`post_randomize` on `randomize() with` (#5412). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix capturing params in `randomize() with` (#5416) (#5418). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix `sformatf` internal error on initial automatics (#5423). [Todd Strader]
* Fix clearing trigger of events with no sensitivity trees (#5426). [Arkadiusz Kozdra, Antmicro Ltd.]
* Fix driving clocking block in reactive region (#5430). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix associative array next/prev/first/last mis-propagating constants (#5435). [Ethan Sifferman]
* Fix randomize treated as std::randomize in classes (#5436). [Arkadiusz Kozdra, Antmicro Ltd.]
* Fix `foreach` colliding index names (#5444). [Arkadiusz Kozdra, Antmicro Ltd.]
* Fix fault on defparam with UNSUPPORTED ignored (#5450). [Luiza de Melo]
* Fix class reference with pin that is a class reference (#5454).
* Fix not reporting class reference with extra parameters (#5467).
* Fix user-type parameter overlap (#5469). [Todd Strader]
* Fix tracing when name() is empty (#5470). [Sam Shahrestani]
* Fix timing mode not exiting on empty events (#5472).
* Fix coverage counts missing due to table optimization (#5473) (#5474). [Vito Gamberini]
* Fix `--binary` with .cpp PLI filenames under relative directory paths.
* Fix extra dot in coverage point hierarchy when using name()=''.
* Fix short-circuiting with associative array access (#5484). [Ethan Sifferman]
* Fix short-circuiting on method calls (#5486). [Ethan Sifferman]
* Fix exponential concatenate performance (#5488). [Arkadiusz Kozdra, Antmicro Ltd.]
* Fix V3Table trying to generate 'x' bits in the lookup table. (#5491). [Geza Lore]
* Fix randomize with foreach constraints (#5492). [Arkadiusz Kozdra, Antmicro Ltd.]
* Fix explicit CMAKE_INSTALL_PREFIX usages (#5500). [Fabian Keßler]
* Fix configure inserting absolute paths for Python and Perl (#5504) (#5505). [Nathan Graybeal]
* Fix pattern initialization with typedef key (#5512). [Eugene Feinberg]
* Fix `-j` option without argument in hierarchical Verilation (#5514). [Ryszard Rozak, Antmicro Ltd.]
* Fix `foreach` with 2-D queues and dynamic arrays (#5525) (#5529). [Yilou Wang]
* Fix struct array assignment (#5455) (#5537). [Yilou Wang]
* Fix copy constructor of classes that use std::process (#5528). [Ryszard Rozak, Antmicro Ltd.]
* Fix foreach on associative array (#5530). [Yilou Wang]
* Fix multi-range indices assignment (#5534) (#5547). [Yilou Wang]
* Fix static function wrappers (#5536). [Ryszard Rozak, Antmicro Ltd.]
* Fix assignments of concatenation to queues and dynamic arrays (#5540). [Ryszard Rozak, Antmicro Ltd.]
* Fix container reduction methods (#5542). [Krzysztof Boroński]
* Fix complex user type problem with `--x-assign` (#5543). [Todd Strader]
* Fix long module names crashing string handling (#5546). [Filip Badáň]
* Fix array trace splitting (#5549). [Todd Strader]
* Fix queue element access (#5551). [Ryszard Rozak, Antmicro Ltd.]
* Fix struct literal on pattern assignment (#5552) (#5559). [Todd Strader]
* Fix build on gcc when using the Spack wrapper (#5555). [Eric Müller]
* Fix enum name method (#5563). [Todd Strader]
* Fix `$countbits` in assert with non-tristates (#5566). [Shou-Li Hsu]
Verilator 5.028 2024-08-21
==========================
**Minor:**
* Support state-dependent constraints (#5217). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support cross-module clocking variable access (#5184). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support inline constraints for class randomization methods (#5234). [Krzysztof Boroński]
* Support clocking blocks in virtual interfaces (#5235). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support `$assertcontrol` assertion_type (#5236). [Bartłomiej Chmiel, Antmicro Ltd.]
* Support conditional constraints (#5245). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support`--compiler-include` headers in user-supplied cpp files (#5271). [Bartłomiej Chmiel, Antmicro Ltd.]
* Support `rand_mode` (#5273). [Krzysztof Bieganski, Antmicro Ltd.]
* Support `this.randomize with` (#5282). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support foreach constraints (#5302). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support `parameter type` in hierarchical blocks (#5309) (#5333). [Bartłomiej Chmiel, Antmicro Ltd.]
* Support assertcontrol directive type (#5310). [Bartłomiej Chmiel, Antmicro Ltd.]
* Support inline random variable control (#5317). [Krzysztof Bieganski, Antmicro Ltd.]
* Support streaming operator on arrays and wide data (#5326). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support streams to/from arrays of wide data (#5334). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support `constraint_mode` (#5338). [Krzysztof Bieganski, Antmicro Ltd.]
* Support constraining AstSel (#5344). [Arkadiusz Kozdra, Antmicro Ltd.]
* Support default value on module input (#5358) (#5373). [Drew Ranck]
* Add `--compiler-include` for additional C++ includes (#5139) (#5202). [Bartłomiej Chmiel, Antmicro Ltd.]
* Add `--emit-accessors` (#5182) (#5227). [Ryan Ziegler]
* Add suggestions on misspelled PLI functions.
* Add warning on dist in constraints (#5264). [Arkadiusz Kozdra, Antmicro Ltd.]
* Add more `rand_mode` unsupported errors (#5329). [Krzysztof Bieganski, Antmicro Ltd.]
* Add parsing but otherwise ignore std::randomize (#5354). [Arkadiusz Kozdra, Antmicro Ltd.]
* Add Verilated cc define when `--timing` used (#5383). [Kaleb Barrett]
* Improve emitted code to use a reference for VlSelf (#5254). [Yangyu Chen]
* Fix monitor block sensitivity items (#4400) (#5294). [Udaya Raj Subedi]
* Fix fusing macro arguments to not ignore whitespace (#5061). [Tudor Timi]
* Fix optimized-out sensitivity trees with `--timing` (#5080) (#5349). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix classes/modules of case-similar names (#5109). [Arkadiusz Kozdra]
* Fix mis-removing $value$plusargs calls (#5127) (#5137). [Seth Pellegrino]
* Fix incorrect result of width mismatch (#5186) (#5189). [Yutetsu TAKATSUKASA]
* Fix compiler coroutine check (#5190) (#5300). [Ricardo Barbedo]
* Fix shortened module names when searching for files (#5196) (#5246). [Tim Hutt]
* Fix `--x-assign` to be independent from `+verilator+rand+reset` (#5214). [Andrew Nolte]
* Fix splitting if statements with impure conditions (#5219). [Bartłomiej Chmiel, Antmicro Ltd.]
* Fix unknown conversion on queues (#5220). [Alex Solomatnikov]
* Fix top-level unpacked structure resets (#5221).
* Fix concurrency for mailbox and semaphores (#5222). [Liam Braun]
* Fix forks capturing non-input ports in tasks (#5237) (#5343). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix toggle coverage aggregation on same line (#5248). [Krzysztof Obłonczek]
* Fix error on empty generate with -O0 (#5250).
* Fix unconstrained randomization of unpacked structs (#5252). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix inlining of variables driven from forced vars (#5259). [Geza Lore]
* Fix tracing with `--main-top-name -` (#5261). [Ethan Sifferman]
* Fix randomization when used with inheritance (#5268). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix inline constraints creating class random generator (#5280). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix WIDTHEXPAND on left shift of intuitive amount (#5284). [Greg Taylor]
* Fix elaborating foreach loops (#5285). [Arkadiusz Kozdra, Antmicro Ltd.]
* Fix initializing static array in dynamic arrays and queues (#5287). [Baruch Sterin]
* Fix static variable initializers in procedures (#5296). [Bartłomiej Chmiel, Antmicro Ltd.]
* Fix randomizing current object with `rand` class instance member (#5292). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix handling of rand fields not referenced in constraints (#5305). [Ryszard Rozak, Antmicro Ltd.]
* Fix Python3 path discovery in make flows to avoid mixing system and user python interpreters (#5307) [Markus Krause]
* Fix make flows to pass PYTHON3 (like PERL) (#5307) (#5308). [Markus Krause]
* Fix assert on wide expression (#5319) (#5324). [Varun Koyyalagunta]
* Fix output clock variable overwriting signal (#5320) (#5347). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix stringify in nested preprocessor macros (#5323). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix $sformat with array arguments (#5330). [Abe Jordan]
* Fix -Wunused-but-set-variable clang warning (#5331). [Bartłomiej Chmiel, Antmicro Ltd.]
* Fix purity of functions with AstJumpBlock or AstStmtExpr (#5332). [Ryszard Rozak, Antmicro Ltd.]
* Fix compilation error on unreachable disable fork / wait fork (#5339). [Arkadiusz Kozdra, Antmicro Ltd.]
* Fix missing type coercion in 'inside {array}' (#5340). [Arkadiusz Kozdra, Antmicro Ltd.]
* Fix +: and -: unpacked array slicing when array has nonzero low index (#5345) (#5387). [James Bailey]
* Fix tracing_{on,off} in the presence of non-inlined modules (#5346). [Geza Lore]
* Fix NBAs in suspendables (#5348). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix lint_off on Errors (#5351) (#5363). [Ethan Sifferman]
* Fix cache config file resolution performance (#5369). [Geza Lore]
* Fix capturing fields from superclass in `randomize() with` (#5389). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix virtual interface null checks (#5391). [Krzysztof Bieganski, Antmicro Ltd.]
* Fix ==? and !=? with X values.
* Fix CPU time being zero.
* Fix inline function ref port persistence.
Verilator 5.026 2024-06-15
==========================
@@ -34,6 +211,7 @@ Verilator 5.026 2024-06-15
* Add traceCapable indication to model header (#5053). [Vito Gamberini]
* Add increasing of stack size when possible (#5071) (#5104). [Yinan Xu]
* Add assertion on reusing VerilatedContext (#5167).
* Add `--pins-sc-uint-bool` to force SystemC uint type (#5192). [Bartłomiej Chmiel, Antmicro Ltd.]
* Improve DFG regularization in cyclic graphs (#5142). [Geza Lore]
* Improve VerilatedVpiPutHolder storage requirements (#5144). [Kaleb Barrett]
* Fix coroutines without awaits to have a co_return (#4208) (#5175). [Arkadiusz Kozdra, Antmicro Ltd.]
@@ -72,7 +250,11 @@ Verilator 5.026 2024-06-15
* Fix SystemC BITS_PER_DIGIT in VL_ASSIGN_SBW (#5170). [Bartłomiej Chmiel, Antmicro Ltd.]
* Fix non-constant replication in concats (#5171). [Arkadiusz Kozdra, Antmicro Ltd.]
* Fix table optimization when applied on real data type (#5172) (#5173). [Arthur Rosa]
* Fix signed types emitted in hierarchical Verilation (#5178). [Bartłomiej Chmiel, Antmicro Ltd.]
* Fix DPI import of null C-string (#5179).
* Fix CMake installation missing verilated.mk (#5187) (#5188). [Philip Axer]
* Fix linking with pthreads on CMake (#5194). [Tim Hutt]
* Fix clang-17 coroutines configuration with -std=gnu++20 (#5200). [Gus Smith]
Verilator 5.024 2024-04-05
@@ -123,9 +305,10 @@ Verilator 5.024 2024-04-05
* 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 `$readmem` with missing newline (#5019). [Josse Van Delm]
* Fix internal error on missing pattern key (#5023).
* Fix tracing replicated hierarchical models (#5027).
* Fix false LIFETIME warning on `repeat` in `fork-join` (#5456).
Verilator 5.022 2024-02-24
@@ -464,7 +647,7 @@ Verilator 5.012 2023-06-13
* Fix wide structure VL_TOSTRING_W generation (#4188) (#4189). [Aylon Chaim Porat]
* Fix references to members of parameterized base classes (#4196). [Ryszard Rozak, Antmicro Ltd]
* Fix tracing undefined alignment (#4201) (#4288) [John Wehle]
* Fix class specific same methods for AstVarScope, AstVar, and AstScope (#4203) (#4250). [John Wehle]
* Fix class-specific same methods for AstVarScope, AstVar, and AstScope (#4203) (#4250). [John Wehle]
* Fix dotted references in parameterized classes (#4206). [Ryszard Rozak, Antmicro Ltd]
* Fix bit selections under parameterized classes (#4210). [Ryszard Rozak, Antmicro Ltd]
* Fix duplicate std:: declaration with -I (#4215). [Harald Pretl]
@@ -620,7 +803,7 @@ Verilator 5.006 2023-01-22
**Minor:**
* Support clocking blocks (#3674). [Krzysztof Bieganski, Antmicro Ltd]
* Support packed structs (#3802). [Aleksander Kiryk, Antmicro Ltd]
* Support unpacked structs (#3802). [Aleksander Kiryk, Antmicro Ltd]
* Support Windows-native builds using cmake (#3814). [Kritik Bhimani]
* Support p format for UnpackArray (#3877). [Aleksander Kiryk, Antmicro Ltd]
* Support property calls without parenthesis (#3879) (#3893). [Ryszard Rozak, Antmicro Ltd]
@@ -1511,6 +1694,7 @@ Verilator 4.026 2020-01-11
* Fix expand optimization slowing --lint-only. Closes #2091. [Thomas Watts]
* Fix %{number}s with strings. #2093. [agrobman]
* Fix shebang breaking some shells. Closes #2067. [zdave]
* Fix errors on using string in incorrect format (#5240). [John Demme]
Verilator 4.024 2019-12-08
+91 -34
View File
@@ -52,6 +52,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
MAKEINFO = makeinfo
POD2TEXT = pod2text
PYTHON3 = @PYTHON3@
MKINSTALLDIRS = $(SHELL) $(srcdir)/src/mkinstalldirs
# Version (for docs/guide/conf.py)
@@ -76,7 +77,7 @@ datadir = @datadir@
# Directory in which to install documentation info files.
infodir = @infodir@
# Directory in which to install package specific files
# Directory in which to install package-specific files
# Generally ${prefix}/share/verilator
pkgdatadir = @pkgdatadir@
@@ -96,6 +97,7 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
#### End of system configuration section. ####
######################################################################
# Main build targets
.SUFFIXES:
@@ -146,6 +148,9 @@ verilator_exe verilator_bin$(EXEEXT) verilator_bin_dbg$(EXEEXT) verilator_covera
@echo "making verilator in src"
$(MAKE) -C src $(OBJCACHE_JOBS)
######################################################################
# Tests
.PHONY:msg_test
msg_test: all_nomsg
@echo "Build complete!"
@@ -156,7 +161,7 @@ msg_test: all_nomsg
.PHONY: test
ifeq ($(CFG_WITH_LONGTESTS),yes) # Local... Else don't burden users
test: smoke-test test_regress
# examples is part of test_regress's test_regress/t/t_a2_examples.pl
# examples is part of test_regress's test_regress/t/t_a2_examples.py
# (because that allows it to run in parallel with other test_regress's)
else
test: smoke-test examples
@@ -168,8 +173,8 @@ endif
@echo
smoke-test: all_nomsg
test_regress/t/t_a1_first_cc.pl
test_regress/t/t_a2_first_sc.pl
test_regress/t/t_a1_first_cc.py
test_regress/t/t_a2_first_sc.py
test_regress: all_nomsg
$(MAKE) -C test_regress
@@ -183,6 +188,9 @@ examples: all_nomsg
$(MAKE) -C $$p VERILATOR_ROOT=`pwd` || exit 10; \
done
######################################################################
# Docs
.PHONY: docs
docs: info
@@ -204,6 +212,20 @@ verilator.html:
verilator.pdf: Makefile
$(MAKE) -C docs verilator.pdf
TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/*.in \
${srcdir}/*.in ${srcdir}/*.pod
TAGS: $(TAGFILES)
etags $(TAGFILES)
.PHONY: doxygen
doxygen:
$(MAKE) -C docs doxygen
######################################################################
# Install
# 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 \
@@ -244,11 +266,15 @@ mkbindirs:
installbin: | mkbindirs
cd $(srcdir)/bin; \
for p in $(VL_INST_PUBLIC_SCRIPT_FILES) ; do \
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkgdatadir)/bin/$$p; \
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
done
perl -p -i -e 'use File::Spec;' \
-e' $$path = File::Spec->abs2rel("$(realpath $(DESTDIR)$(pkgdatadir))", "$(realpath $(DESTDIR)$(bindir))");' \
-e 's/my \$$verilator_pkgdatadir_relpath = .*/my \$$verilator_pkgdatadir_relpath = "$$path";/g' \
-- "$(DESTDIR)/$(bindir)/verilator"
cd bin; \
for p in $(VL_INST_PUBLIC_BIN_FILES) ; do \
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkgdatadir)/bin/$$p; \
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
done
cd $(srcdir)/bin; \
for p in $(VL_INST_PRIVATE_SCRIPT_FILES) ; do \
@@ -258,11 +284,11 @@ installbin: | mkbindirs
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' $$path = File::Spec->abs2rel("$(realpath $(DESTDIR)$(bindir))", "$(realpath $(DESTDIR)$(pkgdatadir)/bin)");' \
-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; \
$(INSTALL_PROGRAM) redirect.tmp $(DESTDIR)$(pkgdatadir)/bin/$$p; \
done
rm ${srcdir}/bin/redirect.tmp
@@ -344,6 +370,19 @@ install-all: installbin installredirect installman installdata install-msg
install-here: installman info
install-msg:
@echo
@echo "Installed binaries to $(DESTDIR)$(bindir)/verilator"
@echo "Installed man to $(DESTDIR)$(mandir)/man1"
@echo "Installed examples to $(DESTDIR)$(pkgdatadir)/examples"
@echo
@echo "For documentation see 'man verilator' or 'verilator --help'"
@echo "For forums and to report bugs see https://verilator.org"
@echo
######################################################################
# Format/Lint
# Use --xml flag to see the cppcheck code to use for suppression
CPPCHECK1_CPP = $(wildcard $(srcdir)/include/*.cpp)
CPPCHECK2_CPP = $(wildcard $(srcdir)/examples/*/*.cpp)
@@ -411,7 +450,8 @@ analyzer-include:
-rm -rf examples/*/obj*
scan-build $(MAKE) -k examples
format: clang-format yapf format-pl-exec
format:
$(MAKE) -j 4 clang-format yapf format-exec
CLANGFORMAT = clang-format-14
CLANGFORMAT_FLAGS = -i
@@ -422,6 +462,20 @@ clang-format:
|| echo "*** You are not using clang-format-14, indents may differ from master's ***"
$(CLANGFORMAT) $(CLANGFORMAT_FLAGS) $(CLANGFORMAT_FILES)
YAMLFIX = YAMLFIX_WHITELINES=1 YAMLFIX_LINE_LENGTH=130 YAMLFIX_preserve_quotes=true yamlfix
yamlfix:
$(YAMLFIX) .
# CMake files
CMAKE_FILES = \
CMakeLists.txt \
examples/*/CMakeLists.txt \
src/CMakeLists.txt \
test_regress/CMakeLists.txt \
*.cmake.in \
# Python programs, subject to format and lint
PY_PROGRAMS = \
bin/verilator_ccache_report \
bin/verilator_difftree \
@@ -440,6 +494,7 @@ PY_PROGRAMS = \
src/flexfix \
src/vlcovgen \
src/.gdbinit.py \
test_regress/*.py \
test_regress/t/*.pf \
nodist/clang_check_attributes \
nodist/code_coverage \
@@ -447,45 +502,55 @@ PY_PROGRAMS = \
nodist/fuzzer/actual_fail \
nodist/fuzzer/generate_dictionary \
nodist/install_test \
nodist/log_changes \
# Python files, subject to format but not lint
PY_FILES = \
$(PY_PROGRAMS) \
nodist/code_coverage.dat \
test_regress/t/*.py \
# Python files, test_regress tests
PY_TEST_FILES = \
test_regress/t/*.py \
YAPF = yapf3
YAPF_FLAGS = -i
YAPF_FLAGS = -i --parallel
yapf:
$(YAPF) $(YAPF_FLAGS) $(PY_FILES)
GERSEMI = gersemi
GERSEMI_FLAGS = -i
format-cmake:
$(GERSEMI) $(GERSEMI_FLAGS) $(CMAKE_FILES)
PYLINT = pylint
PYLINT_FLAGS = --score=n --disable=R0801
PYLINT_FLAGS = --recursive=n --score=n --disable=R0801
PYLINT_TEST_FLAGS = $(PYLINT_FLAGS) --disable=C0103,C0114,C0116,C0209,C0411,C0413,C0301,R0801,R0912,R0915,R0916,R1702,W0511,W0621
RUFF = ruff
RUFF_FLAGS = check --ignore=E402,E501,E701
# "make -k" so can see all tool result errors
lint-py:
$(MAKE) -k lint-py-pylint lint-py-ruff
$(MAKE) -k lint-py-pylint lint-py-pylint-tests lint-py-ruff
lint-py-pylint:
$(PYLINT) $(PYLINT_FLAGS) $(PY_PROGRAMS)
lint-py-pylint-tests:
$(PYLINT) $(PYLINT_TEST_FLAGS) $(PY_TEST_FILES) | $(PYTHON3) nodist/lint_py_test_filter
lint-py-ruff:
$(RUFF) $(RUFF_FLAGS) $(PY_PROGRAMS)
format-pl-exec:
-chmod a+x test_regress/t/*.pl
format-exec:
-chmod a+x test_regress/t/*.py
install-msg:
@echo
@echo "Installed binaries to $(DESTDIR)$(bindir)/verilator"
@echo "Installed man to $(DESTDIR)$(mandir)/man1"
@echo "Installed examples to $(DESTDIR)$(pkgdatadir)/examples"
@echo
@echo "For documentation see 'man verilator' or 'verilator --help'"
@echo "For forums and to report bugs see https://verilator.org"
@echo
######################################################################
# Configure
IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in
@@ -506,6 +571,9 @@ else
autoconf
endif
######################################################################
# Clean
maintainer-clean::
@echo "This command is intended for maintainers to use;"
@echo "rebuilding the deleted files requires autoconf."
@@ -536,17 +604,6 @@ distclean maintainer-clean::
rm -f bin/verilator_bin* bin/verilator_coverage_bin*
rm -f include/verilated.mk include/verilated_config.h
TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/*.in \
${srcdir}/*.in ${srcdir}/*.pod
TAGS: $(TAGFILES)
etags $(TAGFILES)
.PHONY: doxygen
doxygen:
$(MAKE) -C docs doxygen
######################################################################
# Distributions
+10 -3
View File
@@ -69,7 +69,9 @@ if (! GetOptions(
pod2usage(-exitstatus => 2, -verbose => 0);
}
my $verilator_root = realpath("$RealBin/..");
# WARNING: $verilator_pkgdatadir_relpath is substituted during Verilator 'make install'
my $verilator_pkgdatadir_relpath = "..";
my $verilator_root = realpath("$RealBin/$verilator_pkgdatadir_relpath");
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";
@@ -324,6 +326,7 @@ detailed descriptions of these arguments.
--clk <signal-name> Mark specified signal as clock
--no-clk <signal-name> Prevent marking specified signal as clock
--compiler <compiler-name> Tune for specified C++ compiler
--compiler-include Include additional header in the precompiled one
--converge-limit <loops> Tune convergence settle time
--coverage Enable all coverage
--coverage-line Enable line coverage
@@ -356,6 +359,7 @@ detailed descriptions of these arguments.
--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
--emit-accessors Emit getter and setter methods for model top class
--error-limit <value> Abort after this number of errors
--exe Link to create executable
--expand-limit <value> Set expand optimization limit
@@ -375,6 +379,7 @@ detailed descriptions of these arguments.
--get-supported <feature> Get if feature is supported
--help Show this help
--hierarchical Enable hierarchical Verilation
--hierarchical-params-file <name> Internal option that specifies parameters file for hier blocks
-I<dir> Directory to search for includes
--if-depth <value> Tune IFDEPTH warning
+incdir+<dir> Directory to search for includes
@@ -402,6 +407,7 @@ detailed descriptions of these arguments.
-O3 High-performance optimizations
-O<optimization-letter> Selectable optimizations
-o <executable> Name of final executable
--output-groups <numfiles> Group .cpp files into larger ones
--output-split <statements> Split .cpp files into pieces
--output-split-cfuncs <statements> Split model functions
--output-split-ctrace <statements> Split tracing functions
@@ -410,6 +416,7 @@ detailed descriptions of these arguments.
--pins-inout-enables Specify that __en and __out signals be created for inouts
--pins-sc-biguint Specify types for top-level ports
--pins-sc-uint Specify types for top-level ports
--pins-sc-uint-bool Specify types for top-level ports
--pins-uint8 Specify types for top-level ports
--no-pins64 Don't use uint64_t's for 33-64 bit sigs
--pipe-filter <command> Filter all input through a script
@@ -459,8 +466,8 @@ detailed descriptions of these arguments.
--trace-coverage Enable tracing of coverage
--trace-depth <levels> Depth of tracing
--trace-fst Enable FST waveform creation
--trace-max-array <depth> Maximum bit width for tracing
--trace-max-width <width> Maximum array depth for tracing
--trace-max-array <depth> Maximum array depth for tracing
--trace-max-width <width> Maximum bit width for tracing
--trace-params Enable tracing of parameters
--trace-structs Enable tracing structure names
--trace-threads <threads> Enable FST waveform creation on separate threads
+9 -17
View File
@@ -16,8 +16,7 @@ parser = argparse.ArgumentParser(
For documentation see
https://verilator.org/guide/latest/exe_verilator_ccache_report.html""",
epilog=
"""Copyright 2002-2024 by Wilson Snyder. This program is free software; you
epilog="""Copyright 2002-2024 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
@@ -67,30 +66,23 @@ else:
wnames = max(len(_) for _ in results) + 1
wresults = max(len(_) for _ in results.values()) + 1
for k in sorted(results.keys()):
args.o.write("{:{wnames}} : {:{wresults}} : {}s\n".format(
k,
results[k],
elapsed[k].total_seconds(),
wnames=wnames,
wresults=wresults))
args.o.write("{:{wnames}} : {:{wresults}} : {}s\n".format(k,
results[k],
elapsed[k].total_seconds(),
wnames=wnames,
wresults=wresults))
args.o.write("\nSummary:\n")
counts = collections.Counter(_ for _ in results.values())
total = sum(counts.values())
for k in sorted(counts.keys()):
c = counts[k]
args.o.write("{:{width}}| {} ({:.2%})\n".format(k,
c,
c / total,
width=wresults))
args.o.write("{:{width}}| {} ({:.2%})\n".format(k, c, c / total, width=wresults))
args.o.write("\nLongest:\n")
longest = sorted(list(elapsed.items()),
key=lambda kv: -kv[1].total_seconds())
longest = sorted(list(elapsed.items()), key=lambda kv: -kv[1].total_seconds())
for i, (k, v) in enumerate(longest):
args.o.write("{:{width}}| {}s\n".format(k,
v.total_seconds(),
width=wnames))
args.o.write("{:{width}}| {}s\n".format(k, v.total_seconds(), width=wnames))
if i > 4:
break
+3 -8
View File
@@ -47,8 +47,7 @@ def diff_dir(a, b):
diff_file(a, b)
anyfile = True
if not anyfile:
sys.stderr.write(
"%Warning: No .tree files found that have similar base names\n")
sys.stderr.write("%Warning: No .tree files found that have similar base names\n")
def diff_file(a, b):
@@ -109,18 +108,14 @@ parser = argparse.ArgumentParser(
Verilator_difftree is used for debugging Verilator tree output files.
It performs a diff between two files, or all files common between two
directories, ignoring irrelevant pointer differences.""",
epilog=
"""Copyright 2005-2024 by Wilson Snyder. This program is free software; you
epilog="""Copyright 2005-2024 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
parser.add_argument('--debug',
action='store_const',
const=9,
help='enable debug')
parser.add_argument('--debug', action='store_const', const=9, help='enable debug')
parser.add_argument('--no-lineno',
action='store_false',
help='do not show differences in line numbering')
+27 -54
View File
@@ -15,11 +15,7 @@ LongestVcdStrValueLength = 0
Threads = collections.defaultdict(lambda: []) # List of records per thread id
Mtasks = collections.defaultdict(lambda: {'elapsed': 0, 'end': 0})
Cpus = collections.defaultdict(lambda: {'mtask_time': 0})
Global = {
'args': {},
'cpuinfo': collections.defaultdict(lambda: {}),
'stats': {}
}
Global = {'args': {}, 'cpuinfo': collections.defaultdict(lambda: {}), 'stats': {}}
ElapsedTime = None # total elapsed time
ExecGraphTime = 0 # total elapsed time excuting an exec graph
ExecGraphIntervals = [] # list of (start, end) pairs
@@ -31,8 +27,7 @@ def read_data(filename):
with open(filename, "r", encoding="utf8") as fh:
re_thread = re.compile(r'^VLPROFTHREAD (\d+)$')
re_record = re.compile(r'^VLPROFEXEC (\S+) (\d+)(.*)$')
re_payload_mtaskBegin = re.compile(
r'id (\d+) predictStart (\d+) cpu (\d+)')
re_payload_mtaskBegin = re.compile(r'id (\d+) predictStart (\d+) cpu (\d+)')
re_payload_mtaskEnd = re.compile(r'id (\d+) predictCost (\d+)')
re_arg1 = re.compile(r'VLPROF arg\s+(\S+)\+([0-9.]*)\s*')
@@ -57,8 +52,7 @@ def read_data(filename):
tick = int(tick)
payload = payload.strip()
if kind == "SECTION_PUSH":
LongestVcdStrValueLength = max(LongestVcdStrValueLength,
len(payload))
LongestVcdStrValueLength = max(LongestVcdStrValueLength, len(payload))
SectionStack.append(payload)
Sections.append((tick, tuple(SectionStack)))
elif kind == "SECTION_POP":
@@ -66,15 +60,13 @@ def read_data(filename):
SectionStack.pop()
Sections.append((tick, tuple(SectionStack)))
elif kind == "MTASK_BEGIN":
mtask, predict_start, ecpu = re_payload_mtaskBegin.match(
payload).groups()
mtask, predict_start, ecpu = re_payload_mtaskBegin.match(payload).groups()
mtask = int(mtask)
predict_start = int(predict_start)
ecpu = int(ecpu)
mTaskThread[mtask] = thread
records = Threads[thread]
assert not records or records[-1]['start'] <= records[-1][
'end'] <= tick
assert not records or records[-1]['start'] <= records[-1]['end'] <= tick
records.append({
'start': tick,
'mtask': mtask,
@@ -85,8 +77,7 @@ def read_data(filename):
Mtasks[mtask]['thread'] = thread
Mtasks[mtask]['predict_start'] = predict_start
elif kind == "MTASK_END":
mtask, predict_cost = re_payload_mtaskEnd.match(
payload).groups()
mtask, predict_cost = re_payload_mtaskEnd.match(payload).groups()
mtask = int(mtask)
predict_cost = int(predict_cost)
begin = Mtasks[mtask]['begin']
@@ -163,8 +154,7 @@ def report():
print("\nSummary:")
print(" Total elapsed time = {} rdtsc ticks".format(ElapsedTime))
print(" Parallelized code = {:.2%} of elapsed time".format(
ExecGraphTime / ElapsedTime))
print(" Parallelized code = {:.2%} of elapsed time".format(ExecGraphTime / ElapsedTime))
print(" Total threads = %d" % nthreads)
print(" Total CPUs used = %d" % ncpus)
print(" Total mtasks = %d" % len(Mtasks))
@@ -176,15 +166,12 @@ def report():
if nthreads > ncpus:
print()
print("%%Warning: There were fewer CPUs (%d) than threads (%d)." %
(ncpus, nthreads))
print("%%Warning: There were fewer CPUs (%d) than threads (%d)." % (ncpus, nthreads))
print(" : See docs on use of numactl.")
else:
if 'cpu_socket_cores_warning' in Global:
print()
print(
"%Warning: Multiple threads scheduled on same hyperthreaded core."
)
print("%Warning: Multiple threads scheduled on same hyperthreaded core.")
print(" : See docs on use of numactl.")
if 'cpu_sockets_warning' in Global:
print()
@@ -228,8 +215,7 @@ def report_mtasks():
serialTime = ElapsedTime - ExecGraphTime
def subReport(elapsed, work):
print(" Thread utilization = {:7.2%}".format(work /
(elapsed * nthreads)))
print(" Thread utilization = {:7.2%}".format(work / (elapsed * nthreads)))
print(" Speedup = {:6.3}x".format(work / elapsed))
print("\nParallelized code, measured:")
@@ -256,8 +242,7 @@ def report_mtasks():
if Mtasks[mtask]['elapsed'] > 0:
if Mtasks[mtask]['predict_cost'] == 0:
Mtasks[mtask]['predict_cost'] = 1 # don't log(0) below
p2e_ratio = math.log(Mtasks[mtask]['predict_cost'] /
Mtasks[mtask]['elapsed'])
p2e_ratio = math.log(Mtasks[mtask]['predict_cost'] / Mtasks[mtask]['elapsed'])
p2e_ratios.append(p2e_ratio)
if p2e_ratio > max_p2e:
@@ -269,18 +254,14 @@ def report_mtasks():
print("\nMTask statistics:")
print(" Longest mtask id = {}".format(long_mtask))
print(" Longest mtask time = {:.2%} of time elapsed in parallelized code".
format(long_mtask_time / ExecGraphTime))
print(" Longest mtask time = {:.2%} of time elapsed in parallelized code".format(
long_mtask_time / ExecGraphTime))
print(" min log(p2e) = %0.3f" % min_p2e, end="")
print(" from mtask %d (predict %d," %
(min_mtask, Mtasks[min_mtask]['predict_cost']),
end="")
print(" from mtask %d (predict %d," % (min_mtask, Mtasks[min_mtask]['predict_cost']), end="")
print(" elapsed %d)" % Mtasks[min_mtask]['elapsed'])
print(" max log(p2e) = %0.3f" % max_p2e, end="")
print(" from mtask %d (predict %d," %
(max_mtask, Mtasks[max_mtask]['predict_cost']),
end="")
print(" from mtask %d (predict %d," % (max_mtask, Mtasks[max_mtask]['predict_cost']), end="")
print(" elapsed %d)" % Mtasks[max_mtask]['elapsed'])
stddev = statistics.pstdev(p2e_ratios)
@@ -315,8 +296,8 @@ def report_cpus():
model = cpuinfo['model_name']
print(" {:3d} | {:7.2%} / {:16d} | {:>6s} | {:>4s} | {}".format(
cpu, Cpus[cpu]['mtask_time'] / ElapsedTime,
Cpus[cpu]['mtask_time'], socket, core, model))
cpu, Cpus[cpu]['mtask_time'] / ElapsedTime, Cpus[cpu]['mtask_time'], socket, core,
model))
if len(Global['cpu_sockets']) > 1:
Global['cpu_sockets_warning'] = True
@@ -366,8 +347,8 @@ def report_sections():
def printTree(prefix, name, entries, tree):
print(" {:7.2%} | {:7.2%} | {:8} | {:10.2f} | {}".format(
treeSum(tree) / ElapsedTime, tree[0] / ElapsedTime, tree[2],
tree[2] / entries, prefix + name))
treeSum(tree) / ElapsedTime, tree[0] / ElapsedTime, tree[2], tree[2] / entries,
prefix + name))
for k in sorted(tree[1], key=lambda _: -treeSum(tree[1][_])):
printTree(prefix + " ", k, tree[2], tree[1][k])
@@ -438,10 +419,8 @@ def write_vcd(filename):
addValue(code, start, mtask)
addValue(code, end, None)
tStart = sorted(_['start'] for records in Threads.values()
for _ in records)
tEnd = sorted(_['end'] for records in Threads.values()
for _ in records)
tStart = sorted(_['start'] for records in Threads.values() for _ in records)
tEnd = sorted(_['end'] for records in Threads.values() for _ in records)
# Predicted graph
for start, end in ExecGraphIntervals:
@@ -455,11 +434,10 @@ def write_vcd(filename):
# Predict mtasks that fill the time the execution occupied
for mtask in Mtasks:
thread = Mtasks[mtask]['thread']
pred_scaled_start = start + int(
Mtasks[mtask]['predict_start'] * measured_scaling)
pred_scaled_start = start + int(Mtasks[mtask]['predict_start'] * measured_scaling)
pred_scaled_end = start + int(
(Mtasks[mtask]['predict_start'] +
Mtasks[mtask]['predict_cost']) * measured_scaling)
(Mtasks[mtask]['predict_start'] + Mtasks[mtask]['predict_cost']) *
measured_scaling)
if pred_scaled_start == pred_scaled_end:
continue
@@ -545,8 +523,7 @@ Verilator_gantt creates a visual representation to help analyze Verilator
For documentation see
https://verilator.org/guide/latest/exe_verilator_gantt.html""",
epilog=
"""Copyright 2018-2024 by Wilson Snyder. This program is free software; you
epilog="""Copyright 2018-2024 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
@@ -554,12 +531,8 @@ Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
parser.add_argument('--debug', action='store_true', help='enable debug')
parser.add_argument('--no-vcd',
help='disable creating vcd',
action='store_true')
parser.add_argument('--vcd',
help='filename for vcd outpue',
default='profile_exec.vcd')
parser.add_argument('--no-vcd', help='disable creating vcd', action='store_true')
parser.add_argument('--vcd', help='filename for vcd outpue', default='profile_exec.vcd')
parser.add_argument('filename',
help='input profile_exec.dat filename to process',
default='profile_exec.dat')
+11 -22
View File
@@ -34,9 +34,8 @@ def profcfunc(filename):
# Older gprofs have no call column for single-call functions
# %time cumesec selfsec {stuff} name
match = re.match(
r'^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$',
line)
match = re.match(r'^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$',
line)
if match:
pct = float(match.group(1))
sec = float(match.group(2))
@@ -136,19 +135,15 @@ def profcfunc(filename):
design_width = 1
for func, func_item in vfuncs.items():
if design_width < len(func_item['design']):
design_width = len(func_item['design'])
design_width = max(design_width, len(func_item['design']))
print("Verilog code profile:")
print(" These are split into three categories:")
print(" C++: Time in non-Verilated C++ code")
print(" Prof: Time in profile overhead")
print(" VBlock: Time attributable to a block in a" +
" Verilog file and line")
print(" VCommon: Time in a Verilated module," +
" due to all parts of the design")
print(" VLib: Time in Verilated common libraries," +
" called by the Verilated code")
print(" VBlock: Time attributable to a block in a" + " Verilog file and line")
print(" VCommon: Time in a Verilated module," + " due to all parts of the design")
print(" VLib: Time in Verilated common libraries," + " called by the Verilated code")
print()
print(" % cumulative self ")
@@ -156,13 +151,11 @@ def profcfunc(filename):
"s type filename and line number") % "design")
cume = 0
for func in sorted(vfuncs.keys(),
key=lambda f: vfuncs[f]['sec'],
reverse=True):
for func in sorted(vfuncs.keys(), key=lambda f: vfuncs[f]['sec'], reverse=True):
cume += vfuncs[func]['sec']
print(("%6.2f %9.2f %8.2f %10d %-" + str(design_width) + "s %s") %
(vfuncs[func]['pct'], cume, vfuncs[func]['sec'],
vfuncs[func]['calls'], vfuncs[func]['design'], func))
(vfuncs[func]['pct'], cume, vfuncs[func]['sec'], vfuncs[func]['calls'],
vfuncs[func]['design'], func))
######################################################################
@@ -180,18 +173,14 @@ in each Verilog block.
For documentation see
https://verilator.org/guide/latest/exe_verilator_profcfunc.html""",
epilog=
"""Copyright 2002-2024 by Wilson Snyder. This program is free software; you
epilog="""Copyright 2002-2024 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
parser.add_argument('--debug',
action='store_const',
const=9,
help='enable debug')
parser.add_argument('--debug', action='store_const', const=9, help='enable debug')
parser.add_argument('filename', help='input gprof output to process')
Args = parser.parse_args()
+5 -12
View File
@@ -60,17 +60,14 @@ if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
sudo apt-get install libgoogle-perftools-dev ||
sudo apt-get install libgoogle-perftools-dev
fi
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ] || [ "$CI_RUNS_ON" = "ubuntu-22.04" ]; then
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ] || [ "$CI_RUNS_ON" = "ubuntu-22.04" ] || [ "$CI_RUNS_ON" = "ubuntu-24.04" ]; then
sudo apt-get install libsystemc libsystemc-dev ||
sudo apt-get install libsystemc libsystemc-dev
fi
if [ "$CI_RUNS_ON" = "ubuntu-22.04" ]; then
if [ "$CI_RUNS_ON" = "ubuntu-22.04" ] || [ "$CI_RUNS_ON" = "ubuntu-24.04" ]; then
sudo apt-get install bear mold ||
sudo apt-get install bear mold
fi
if [ "$COVERAGE" = 1 ]; then
yes yes | sudo cpan -fi Parallel::Forker
fi
elif [ "$CI_OS_NAME" = "osx" ]; then
brew update
brew install ccache perl gperftools
@@ -94,12 +91,12 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
# libfl-dev needed for internal coverage's test runs
sudo apt-get install gdb gtkwave lcov libfl-dev ccache jq z3 ||
sudo apt-get install gdb gtkwave lcov libfl-dev ccache jq z3
# Required for test_regress/t/t_dist_attributes.pl
if [ "$CI_RUNS_ON" = "ubuntu-22.04" ]; then
# Required for test_regress/t/t_dist_attributes.py
if [ "$CI_RUNS_ON" = "ubuntu-22.04" ] || [ "$CI_RUNS_ON" = "ubuntu-24.04" ]; then
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
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ] || [ "$CI_RUNS_ON" = "ubuntu-22.04" ] || [ "$CI_RUNS_ON" = "ubuntu-24.04" ]; then
sudo apt-get install libsystemc-dev ||
sudo apt-get install libsystemc-dev
fi
@@ -114,10 +111,6 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
fatal "Unknown os: '$CI_OS_NAME'"
fi
# Common installs
if [ "$CI_RUNS_ON" != "ubuntu-14.04" ]; then
CI_CPAN_REPO=https://cpan.org
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
+6 -5
View File
@@ -33,6 +33,7 @@ elif [ "$CI_OS_NAME" = "freebsd" ]; then
else
fatal "Unknown os: '$CI_OS_NAME'"
fi
NPROC=$(expr $NPROC '+' 1)
if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
##############################################################################
@@ -61,6 +62,7 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
# Run tests
export VERILATOR_TEST_NO_CONTRIBUTORS=1 # Separate workflow check
export VERILATOR_TEST_NO_LINT_PY=1 # Separate workflow check
if [ "$CI_OS_NAME" = "osx" ]; then
export VERILATOR_TEST_NO_GDB=1 # Pain to get GDB to work on OS X
@@ -85,7 +87,7 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
fi
# Run sanitize on Ubuntu 22.04 only
[ "$CI_RUNS_ON" = 'ubuntu-22.04' ] && sanitize='--sanitize' || sanitize=''
( [ "$CI_RUNS_ON" = 'ubuntu-22.04' ] || [ "$CI_RUNS_ON" = 'ubuntu-24.04' ] ) && sanitize='--sanitize' || sanitize=''
TEST_REGRESS=test_regress
if [ "$CI_RELOC" == 1 ]; then
@@ -192,13 +194,12 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
fatal "Unknown test: $TESTS"
;;
esac
# To see load average (1 minute, 5 minute, 15 minute)
uptime
# 22.04: ccache -s -v
ccache -s
# Upload coverage data
if [[ $TESTS == coverage-* ]]; then
bash <(cat ci/coverage-upload.sh) -f nodist/obj_dir/coverage/app_total.info
fi
else
##############################################################################
# Unknown build stage
+8 -8
View File
@@ -11,14 +11,14 @@
Set-PSDebug -Trace 1
if (-Not (Test-Path $PWD/../.ccache/win_bison.exe)) {
git clone --depth 1 https://github.com/lexxmark/winflexbison
cd winflexbison
mkdir build
cd build
cmake .. --install-prefix $PWD/../../../.ccache
cmake --build . --config Release -j 3
cmake --install . --prefix $PWD/../../../.ccache
cd ../..
git clone --depth 1 https://github.com/lexxmark/winflexbison
cd winflexbison
mkdir build
cd build
cmake .. --install-prefix $PWD/../../../.ccache
cmake --build . --config Release -j 3
cmake --install . --prefix $PWD/../../../.ccache
cd ../..
}
mkdir build
Executable
BIN
View File
Binary file not shown.
File diff suppressed because it is too large Load Diff
-2
View File
@@ -51,8 +51,6 @@ RUN apt-get update \
WORKDIR /tmp
RUN cpan install -fi Parallel::Forker
RUN git clone https://github.com/veripool/vcddiff.git && \
make -C vcddiff && \
cp -p vcddiff/vcddiff /usr/local/bin/vcddiff && \
+2
View File
@@ -1,6 +1,8 @@
.. Copyright 2003-2024 by Wilson Snyder.
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
.. _Verilator Build Docker Container:
Verilator Build Docker Container
================================
+3 -2
View File
@@ -11,10 +11,11 @@ easily as a docker image, e.g.:
docker run -ti verilator/verilator:latest --version
This will install the container, run the latest Verilator and print
This will pull the container from `docker hub
<https://hub.docker.com/r/verilator/verilator>`_, run the latest Verilator and print
Verilator's version.
Containers are automatically built for all released versions, so you may
Containers are automatically built and pushed to docker hub for all released versions, so you may
easily compare results across versions, e.g.:
::
+15 -17
View File
@@ -1,3 +1,4 @@
---
# DESCRIPTION: codecov.io config
#
# Copyright 2020-2024 by Wilson Snyder. This program is free software; you
@@ -8,31 +9,28 @@
####################
# Validate:
# curl --data-binary @codecov.yml https://codecov.io/validate
#
codecov:
require_ci_to_pass: no
require_ci_to_pass: false
coverage:
precision: 2
round: down
range: "50...100"
range: 50...100
ignore:
- "ci"
- "docs"
- "examples"
- "include/gtkwave"
- "include/vltstd"
- "test_regress"
- "ci" #
- "docs" #
- "examples" #
- "include/gtkwave" #
- "include/vltstd" #
- "test_regress" #
parsers:
gcov:
branch_detection:
conditional: yes
loop: yes
method: no
macro: no
conditional: true
loop: true
method: false
macro: false
comment:
layout: "reach,diff,flags,tree"
behavior: default
require_changes: yes
require_changes: true
+60 -30
View File
@@ -10,7 +10,7 @@
# Then 'make maintainer-dist'
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[5.026 2024-06-15],
AC_INIT([Verilator],[5.030 2024-10-27],
[https://verilator.org],
[verilator],[https://verilator.org])
@@ -29,6 +29,9 @@ AC_DEFINE_UNQUOTED([PACKAGE_VERSION_STRING_CHAR],
[Package version as a number])
AC_SUBST(PACKAGE_VERSION_STRING_CHAR)
######################################################################
## Arguments/flag checking
# Ignore automake flags passed by Ubuntu builds
AC_ARG_ENABLE([dependency-tracking],
[AS_HELP_STRING([--disable-dependency-tracking], [ignored])])
@@ -156,6 +159,11 @@ AC_ARG_WITH([solver],
AC_SUBST(CFG_WITH_SOLVER)
AC_MSG_RESULT($CFG_WITH_SOLVER)
######################################################################
## Compiler checks
AC_MSG_RESULT([compiler CXX inbound is set to... $CXX])
# Compiler flags (ensure they are not empty to avoid configure defaults)
CFLAGS="$CFLAGS "
CPPFLAGS="$CPPFLAGS "
@@ -182,24 +190,26 @@ if test "x$AR" = "x" ; then
AC_MSG_ERROR([Cannot find "ar" in your PATH, please install it])
fi
AC_PATH_PROG(PERL,perl)
AC_CHECK_PROG(PERL,perl,perl)
if test "x$PERL" = "x" ; then
AC_MSG_ERROR([Cannot find "perl" in your PATH, please install it])
fi
AC_PATH_PROG(PYTHON3,python3)
AC_CHECK_PROG(PYTHON3,python3,python3)
if test "x$PYTHON3" = "x" ; then
AC_MSG_ERROR([Cannot find "python3" in your PATH, please install it])
fi
python3_version=$($PYTHON3 --version | head -1)
AC_MSG_RESULT([$PYTHON3 --version = $python3_version])
AC_PATH_PROG(LEX,flex)
AC_CHECK_PROG(LEX,flex,flex)
if test "x$LEX" = "x" ; then
AC_MSG_ERROR([Cannot find "flex" in your PATH, please install it])
fi
flex_version=$($LEX --version | head -1)
AC_MSG_RESULT([$LEX --version = $flex_version])
AC_PATH_PROG(YACC,bison)
AC_CHECK_PROG(YACC,bison,bison)
if test "x$YACC" = "x" ; then
AC_MSG_ERROR([Cannot find "bison" in your PATH, please install it])
fi
@@ -288,6 +298,43 @@ AC_DEFUN([_MY_CXX_CHECK_OPT],
_MY_CXX_CHECK_IFELSE($2, $1="$$1 $2")
])
AC_DEFUN([_MY_CXX_CHECK_CORO_SET],
[# _MY_CXX_CHECK_CORO_SET(variable,option)
# Check if compiler supports coroutines with specific option. If it does,
# set variable to option, only if not previously set.
# Define HAVE_COROUTINES if supported.
if test "$$1" = ""; then
if test "$2" != ""; then
_my_msg_opt=" with $2"
else
_my_msg_opt=""
fi
AC_MSG_CHECKING([whether coroutines are supported by $CXX$_my_msg_opt])
ACO_SAVE_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $2"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([
#if defined(__clang__) && !defined(__cpp_impl_coroutine)
#define __cpp_impl_coroutine 1
#endif
#include <coroutine>
],[[std::coroutine_handle<> h;]])],
[_my_result=yes],
[AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[#include <experimental/coroutine>],
[[std::experimental::coroutine_handle<> h;]])],
[_my_result=yes],
[_my_result=no])])
AC_MSG_RESULT($_my_result)
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
if test "$_my_result" = "yes" ; then
$1="$2"
AC_DEFINE([HAVE_COROUTINES],[1],[Defined if coroutines are supported by $CXX])
fi
fi
])
AC_DEFUN([_MY_LDLIBS_CHECK_FLAG],
[# _MY_LDLIBS_CHECK_FLAG(flag) -- Check if linker supports specific options
# Set $_my_result appropriately
@@ -373,32 +420,12 @@ _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wthread-safety)
AC_SUBST(CFG_CXXFLAGS_WEXTRA)
# Flags for coroutine support for dynamic scheduling
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines-ts)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines-ts -Wno-deprecated-experimental-coroutine)
_MY_CXX_CHECK_CORO_SET(CFG_CXXFLAGS_COROUTINES, "")
_MY_CXX_CHECK_CORO_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines-ts)
_MY_CXX_CHECK_CORO_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines)
_MY_CXX_CHECK_CORO_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines-ts -Wno-deprecated-experimental-coroutine)
_MY_CXX_CHECK_CORO_SET(CFG_CXXFLAGS_COROUTINES,-std=gnu++20)
AC_SUBST(CFG_CXXFLAGS_COROUTINES)
# HAVE_COROUTINES
# Check if coroutines are supported at all
AC_MSG_CHECKING([whether coroutines are supported by $CXX])
ACO_SAVE_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $CFG_CXXFLAGS_COROUTINES"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([
#ifdef __clang__
#define __cpp_impl_coroutine 1
#endif
#include <coroutine>
],[[]])],
[_my_result=yes
AC_DEFINE([HAVE_COROUTINES],[1],[Defined if coroutines are supported by $CXX])],
[AC_LINK_IFELSE(
[AC_LANG_PROGRAM([#include <experimental/coroutine>],[[]])],
[_my_result=yes
AC_DEFINE([HAVE_COROUTINES],[1],[Defined if coroutines are supported by $CXX])],
[_my_result=no])])
AC_MSG_RESULT($_my_result)
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
AC_SUBST(HAVE_COROUTINES)
# Flags for compiling Verilator internals including parser always
@@ -606,6 +633,9 @@ AC_SUBST(HAVE_SYSTEMC)
# Checks for system services
######################################################################
## Output
# Other install directories
pkgdatadir=${datadir}/verilator
AC_SUBST(pkgdatadir)
+19
View File
@@ -7,6 +7,7 @@ Adam Bagley
Adrian Sampson
Adrien Le Masle
Ahmed El-Mahmoudy
Aidan McNay
Aleksander Kiryk
Alex Chadwick
Alex Solomatnikov
@@ -25,6 +26,7 @@ Aylon Chaim Porat
Bartłomiej Chmiel
Cameron Kirk
Chih-Mao Chen
Chris Bachhuber
Chris Randall
Christopher Taylor
Chuxuan Wang
@@ -43,9 +45,12 @@ Drew Ranck
Drew Taussig
Driss Hafdi
Edgar E. Iglesias
Eric Müller
Eric Rippey
Ethan Sifferman
Eyck Jentzsch
Furqan Nadir
Fabian Keßler
Fan Shupei
february cozzocrea
Felix Neumärker
@@ -63,6 +68,7 @@ Graham Rushton
Guokai Chen
Gus Smith
Gustav Svensk
Han Qi
Harald Heckmann
Hennadii Chernyshchyk
Howard Su
@@ -76,6 +82,7 @@ Iru Cai
Ivan Vnučec
Iztok Jeras
Jake Merdich
James Bailey
James Hanlon
James Hutchinson
James Pallister
@@ -118,8 +125,11 @@ Kritik Bhimani
Krzysztof Bieganski
Krzysztof Boronski
Krzysztof Boroński
Krzysztof Obłonczek
Kuba Ober
Larry Doolittle
Liam Braun
Luca Colagrande
Ludwig Rogiers
Lukasz Dalek
Maarten De Braekeleer
@@ -143,6 +153,7 @@ Mladen Slijepcevic
Morten Borup Petersen
Mostafa Gamal
Nandu Raj
Nathan Graybeal
Nathan Kohagen
Nathan Myers
Nolan Poe
@@ -157,6 +168,7 @@ Pengcheng Xu
Peter Debacker
Peter Horvath
Peter Monsson
Philip Axer
Philipp Wagner
Pierre-Henri Horrein
Pieter Kapsenberg
@@ -166,15 +178,18 @@ Quentin Corradi
Rafal Kapuscik
Rasfunk
Raynard Qiao
Ricardo Barbedo
Richard Myers
Risto Pejašinović
Robert Balas
Rupert Swarbrick
Ryan Ziegler
Ryszard Rozak
Samuel Riedel
Sean Cross
Sebastien Van Cauwenberghe
Sergi Granell
Seth Pellegrino
Srinivasan Venkataramanan
Stefan Wallentowitz
Stephen Henry
@@ -194,6 +209,7 @@ Tudor Timi
Tymoteusz Blazejczyk
Udi Finkelstein
Unai Martinez-Corral
Udaya Raj Subedi
Valentin Atepalikhin
Varun Koyyalagunta
Vassilis Papaefstathiou
@@ -204,6 +220,8 @@ William D. Jones
Wilson Snyder
Xi Zhang
Yan Xu
Yangyu Chen
Yilou Wang
Yinan Xu
Yoda Lee
Yossi Nivin
@@ -215,3 +233,4 @@ Zhanglei Wang
Zhou Shen
Zixi Li
أحمد المحمودي
404allen404
+1 -1
View File
@@ -23,7 +23,7 @@ SPHINXBUILD ?= sphinx-build
SOURCEDIR = guide
BUILDDIR = _build
SPHINXOPTS ?= -c guide
SPHINXOPTS ?= -c guide -j 4
ifneq ($(VERILATOR_ANALYTICS_ID),)
SPHINXOPTS += -D html_theme_options.analytics_id=$(VERILATOR_ANALYTICS_ID)
endif
+3 -9
View File
@@ -23,9 +23,7 @@ class VlSphinxExtract:
outname = match.group(1)
print("Writing %s" % outname)
fhw = open(outname, "w", encoding="utf8") # pylint: disable=consider-using-with
fhw.write(
".. comment: generated by vl_sphinx_extract from " +
filename + "\n")
fhw.write(".. comment: generated by vl_sphinx_extract from " + filename + "\n")
fhw.write(".. code-block::\n")
elif re.match(r'^[=a-zA-Z0-9_]', line):
fhw = None
@@ -39,18 +37,14 @@ parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawDescriptionHelpFormatter,
description="""Read a file and extract documentation data.""",
epilog=
""" Copyright 2021-2024 by Wilson Snyder. This package is free software;
epilog=""" Copyright 2021-2024 by Wilson Snyder. This package is free software;
you can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
parser.add_argument('--debug',
action='store_const',
const=9,
help='enable debug')
parser.add_argument('--debug', action='store_const', const=9, help='enable debug')
parser.add_argument('path', help='path to extract from')
Args = parser.parse_args()
+3 -8
View File
@@ -18,8 +18,7 @@ class VlSphinxFix:
if os.path.isdir(path):
for basefile in os.listdir(path):
file = os.path.join(path, basefile)
if ((basefile != ".") and (basefile != "..")
and basefile not in self.SkipBasenames
if ((basefile != ".") and (basefile != "..") and basefile not in self.SkipBasenames
and not os.path.islink(file)):
self.process(file)
elif re.search(r'\.(html|tex)$', path):
@@ -54,18 +53,14 @@ parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawDescriptionHelpFormatter,
description="""Post-process Sphinx HTML.""",
epilog=
""" Copyright 2021-2024 by Wilson Snyder. This package is free software;
epilog=""" Copyright 2021-2024 by Wilson Snyder. This package is free software;
you can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
parser.add_argument('--debug',
action='store_const',
const=9,
help='enable debug')
parser.add_argument('--debug', action='store_const', const=9, help='enable debug')
parser.add_argument('path', help='path to edit')
Args = parser.parse_args()
+1 -1
View File
@@ -1,6 +1,6 @@
.. comment: generated by t_lint_multidriven_bad
.. code-block::
%Warning-MULTIDRIVEN: example.v:1:22 Signal has multiple driving blocks with different clocking: 't.mem'
%Warning-MULTIDRIVEN: example.v:1:22 Signal has multiple driving blocks with different clocking: 'out2'
example.v:1:7 ... Location of first driving block
example.v:1:7 ... Location of other driving block
+11
View File
@@ -0,0 +1,11 @@
.. comment: generated by t_lint_pinmissing_bad
.. code-block:: sv
:linenos:
:emphasize-lines: 2
module t;
sub sub(); // <--- Warning
endmodule
module sub
(output port);
endmodule
+4
View File
@@ -0,0 +1,4 @@
.. comment: generated by t_lint_pinmissing_bad
.. code-block::
%Warning-PINMISSING: example.v:1:8 Cell has missing pin: 'port'
+11
View File
@@ -0,0 +1,11 @@
.. comment: generated by t_lint_pkgnodecl_bad
.. code-block:: sv
:linenos:
:emphasize-lines: 2
module t;
initial Pkg::hello(); //<--- Warning
endmodule
package Pkg;
function void hello(); endfunction
endpackage
+4
View File
@@ -0,0 +1,4 @@
.. comment: generated by t_lint_pkgnodecl_bad
.. code-block::
%Error-PKGNODECL: example.v:1:12 Package/class 'Pkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3)
+2 -4
View File
@@ -23,8 +23,7 @@ def get_vlt_version():
filename = "../../Makefile"
with open(filename, "r", encoding="utf8") as fh:
for line in fh:
match = re.search(r"PACKAGE_VERSION *= *([a-z0-9.]+) +([-0-9]+)",
line)
match = re.search(r"PACKAGE_VERSION *= *([a-z0-9.]+) +([-0-9]+)", line)
if match:
return match.group(1), match.group(2)
match = re.search(r"PACKAGE_VERSION *= *([a-z0-9.]+) +devel", line)
@@ -75,8 +74,7 @@ extensions = []
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = [
'_build', 'Thumbs.db', '.DS_Store', 'internals.rst', 'xml.rst', 'gen/ex_*',
'CONTRIBUTING.rst'
'_build', 'Thumbs.db', '.DS_Store', 'internals.rst', 'xml.rst', 'gen/ex_*', 'CONTRIBUTING.rst'
]
# Warn about refs
+29 -11
View File
@@ -23,24 +23,24 @@ Next, try the :vlopt:`--debug` option. This will enable additional
internal assertions, and may help identify the problem.
Finally, reduce your code to the smallest possible routine that exhibits
the bug. Even better, create a test in the :file:`test_regress/t`
directory, as follows:
the bug (see: :ref:`Minimizing bug-inducing code`). Even better, create
a test in the :file:`test_regress/t` directory, as follows:
.. code-block:: bash
cd test_regress
cp -p t/t_EXAMPLE.pl t/t_BUG.pl
cp -p t/t_EXAMPLE.py t/t_BUG.py
cp -p t/t_EXAMPLE.v t/t_BUG.v
There are many hints on how to write a good test in the
:file:`test_regress/driver.pl` documentation which can be seen by running:
:file:`test_regress/driver.py` documentation which can be seen by running:
.. code-block:: bash
cd $VERILATOR_ROOT # Need the original distribution kit
test_regress/driver.pl --help
test_regress/driver.py --help
Edit :file:`t/t_BUG.pl` to suit your example; you can do anything you want
Edit :file:`t/t_BUG.py` to suit your example; you can do anything you want
in the Verilog code there; just make sure it retains the single clk input
and no outputs. Now, the following should fail:
@@ -48,20 +48,38 @@ and no outputs. Now, the following should fail:
cd $VERILATOR_ROOT # Need the original distribution kit
cd test_regress
t/t_BUG.pl # Run on Verilator
t/t_BUG.pl --debug # Run on Verilator, passing --debug to Verilator
t/t_BUG.pl --vcs # Run on VCS simulator
t/t_BUG.pl --nc|--iv|--ghdl # Likewise on other simulators
t/t_BUG.py # Run on Verilator
t/t_BUG.py --debug # Run on Verilator, passing --debug to Verilator
t/t_BUG.py --vcs # Run on VCS simulator
t/t_BUG.py --nc|--iv|--ghdl # Likewise on other simulators
The test driver accepts a number of options, many of which mirror the main
Verilator options. For example the previous test could have been run with
debugging enabled. The full set of test options can be seen by running
:command:`driver.pl --help` as shown above.
:command:`driver.py --help` as shown above.
Finally, report the bug at `Verilator Issues
<https://verilator.org/issues>`_. The bug will become publicly visible; if
this is unacceptable, mail the bug report to ``[email protected]``.
.. _Minimizing bug-inducing code:
Minimizing bug-inducing code
============================
In some cases, the part of the code that causes the bug is clearly visible
and the design can be easily manually reduced. In other cases, the bug is
caused by a complex interaction of many parts of the design, and it is not
clear which parts are necessary to reproduce the bug. In these cases, an
Open Source tool called `sv-bugpoint
<https://github.com/antmicro/sv-bugpoint>_` can be used to automatically
reduce a SystemVerilog design to the smallest possible reproducer.
It can be used to automatically reduce a design with hundreds of thousands of
lines to a minimal test case while preserving the bug-inducing behavior.
Please refer to the `README
<https://github.com/antmicro/sv-bugpoint/blob/main/README.md>`_ file for more
information on how to use `sv-bugpoint`.
.. Contributing
.. ============
+1 -1
View File
@@ -12,7 +12,7 @@ C++14 compiler support
Verilated models with --no-timing.
Verilator will require C++20 or newer compilers for both compiling
Verilator and compiling all Verilated models no sooner than January 2025.
Verilator and compiling all Verilated models no sooner than May 2025.
XML output
Verilator currently supports XML parser output (enabled with `--xml-only`).
+1
View File
@@ -28,6 +28,7 @@ Now, let's create an example Verilog, and SystemC wrapper file:
cat >sc_main.cpp <<'EOF'
#include "Vour.h"
using namespace sc_core;
int sc_main(int argc, char** argv) {
Verilated::commandArgs(argc, argv);
sc_clock clk{"clk", 10, SC_NS, 0.5, 3, SC_NS, true};
+2 -2
View File
@@ -40,8 +40,8 @@ Summary:
.. option:: +verilator+error+limit+<value>
Set number of non-fatal errors (e.g. assertion failures) before exiting
simulation runtime. Also affects number of $stop calls needed before
exit. Defaults to 1.
simulation runtime. Also affects number of `$stop` calls needed before
exit. Does not affect `$fatal`. Defaults to 1.
.. option:: +verilator+help
+53 -2
View File
@@ -222,6 +222,13 @@ Summary:
expressions into sub-expressions to avoid error C1009, and breaking
deep blocks into functions to avoid error C1061.
.. option:: --compiler-include <header-path>
Specifies additional headers to be included in the final PCH header.
It is required to add them to this header, due to compilers'
limitation that allow only one precompiled header per compilation.
Use this instead of ::vlopt:`-CFLAGS` with `-include <header-path>`.
.. option:: --converge-limit <loops>
Rarely needed. Specifies the maximum number of runtime iterations
@@ -476,6 +483,12 @@ Summary:
See also :vlopt:`--dump-defines`, :vlopt:`-P`, and
:vlopt:`--pp-comments` options.
.. option:: --emit-accessors
Emit getter and setter methods for each top-level signal in the
model top class. Signals are still available as public members,
but with the `__Vm_sig_` prefix.
.. option:: --error-limit <value>
After this number of errors are encountered during Verilator run, exit.
@@ -710,6 +723,13 @@ Summary:
:option:`/*verilator&32;hier_block*/` metacomment is ignored. See
:ref:`Hierarchical Verilation`.
.. option:: --hierarchical-params-file <filename>
Internal flag inserted used during :vlopt:`--hierarchical`; specifies
name of hierarchical parameters file for deparametrized modules with
:option:`/*verilator&32;hier_block*/` metacomment. See
:ref:`Hierarchical Verilation`.
.. option:: -I<dir>
See :vlopt:`-y`.
@@ -938,6 +958,22 @@ Summary:
delayed assignments. This option should only be used when suggested by
the developers.
.. option:: --output-groups <numfiles>
Enables concatenating the output .cpp files into the given number of
effective output .cpp files. This is useful if the compiler startup
overhead from compiling many small files becomes unacceptable,
which can happen in designs making extensive use of SystemVerilog classes,
templates or generate blocks.
Using :vlopt:`--output-groups` can adversely impact caching and stability
(as in reproducibility) of compiled code. Compilation of larger .cpp
files also has higher memory requirements. Too low values might result in
swap thrashing with large designs, high values give no benefits. The
value should range from 2 to 20 for small to medium designs.
Default is zero, which disables this feature.
.. option:: --output-split <statements>
Enables splitting the output .cpp files into multiple outputs. When a
@@ -1004,6 +1040,10 @@ Summary:
:vlopt:`--pins-sc-biguint` combination, it results in sc_uint being used
between 2 and 64 and sc_biguint being used between 65 and 512.
.. option:: --pins-sc-uint-bool
Specifies SystemC inputs/outputs one bit wide should use sc_uint<1>.
.. option:: --pins-sc-biguint
Specifies SystemC inputs/outputs greater than 65 bits wide should use
@@ -1885,8 +1925,12 @@ Configuration Files
In addition to the command line, warnings and other features for the
:command:`verilator` command may be controlled with configuration files,
typically named with the .vlt extension (what makes it a configuration file
is the :option:`\`verilator_config` directive). An example:
typically named with the `.vlt` extension (what makes it a configuration
file is the :option:`\`verilator_config` directive). These files, when
named `.vlt`, are read before source code files; if this behavior is
undesired, name the config file with a `.v` suffix.
An example:
.. code-block:: sv
@@ -1979,6 +2023,13 @@ The grammar of configuration commands is as follows:
that the setting is ignored unless the :vlopt:`--hierarchical` option is
specified. See :ref:`Hierarchical Verilation`.
.. option:: hier_params -module "<modulename>"
Specifies that the module contains parameters a :vlopt:`--hierarchical` block. This option
is used internally to specify parameters for deparametrized hier block instances.
This option should not be used directly.
See :ref:`Hierarchical Verilation`.
.. option:: inline -module "<modulename>"
Specifies the module may be inlined into any modules that use this
+26 -25
View File
@@ -58,32 +58,36 @@ to read multiple inputs. If no data file is specified, by default,
Specifies the directory name to which source files with annotated coverage
data should be written.
Converting from the Verilator coverage data format to the info format is
lossy; the info will have all forms of coverage merged line coverage, and
if there are multiple coverage points on a single line they will merge.
The minimum coverage across all merged points will be used to report
coverage of the line.
Points are children of each line coverage- branches or toggle points.
When point counts are aggregated into a line, the minimum and maximum counts
are used to determine the status of the line (complete, partial, failing)
The count is equal to the maximum of the points.
Coverage data is annotated at the beginning of the line and is formatted
as a special character followed by the number of coverage hits. The special
characters " ,%,+,-" indicate summary of the coverage, and allow use of grep
characters " ,%,~,+,-" indicate summary of the coverage, and allow use of grep
to filter the report.
* " " (whitespace) indicates that all points on the line are above the coverage limit.
* "%" indicates at least one point on the line was below the coverage limit.
* "+" coverage point was at or above the limit. Only used with :option:`--annotate-points`.
* "-" coverage point was below the limit. Only used with :option:`--annotate-points`.
* " " (whitespace) indicates that all points on the line are above the coverage min.
* "%" indicates that all points on the line are below the coverage min.
* "~" indicates that some points on the line are above the coverage min and some are below.
* "+" coverage point was at or above the min. Only used with :option:`--annotate-points`.
* "-" coverage point was below the min. Only used with :option:`--annotate-points`.
.. code-block::
100000 input logic a; // Begins with whitespace, because
// number of hits (100000) is above the limit.
+100000 point: comment=a // Begins with +, because
// number of hits (100000) is above the limit.
%000000 input logic b; // Begins with %, because
// number of hits (0) is below the limit.
-000000 point: comment=b // Begins with -, because
// number of hits (0) is below the limit.
100000 input logic a; // Begins with whitespace, because
// number of hits (100000) is above the min.
+100000 point: comment=a // Begins with +, because
// number of hits (100000) is above the min.
%000000 input logic b; // Begins with %, because
// number of hits (0) is below the min.
-000000 point: comment=b // Begins with -, because
// number of hits (0) is below the min.
~000010 if (cyc!=0) begin // Begins with ~, because
// branches are below and above the min.
+000010 point: comment=if // The if branch is above the min.
-000000 point: comment=else // The else branch is below the min.
.. option:: --annotate-all
@@ -154,10 +158,7 @@ generated from random test runs) into one master coverage file.
Specifies the aggregate coverage results, summed across all the files,
should be written to the given filename in :command:`lcov` .info format.
This may be used to feed into :command:`lcov` to aggregate or generate
reports.
Converting from the Verilator coverage data format to the info format is
lossy; the info will have all forms of coverage merged line coverage, and
if there are multiple coverage points on a single line they will merge.
The minimum coverage across all merged points will be used to report
coverage of the line.
reports. This format lacks the comments for cover points that the
verilator_coverage format has. It can be used with :command:`genhtml`
to generate an HTML report. :command:`genhtml --branch-coverage` will
also display the branch coverage, analogous to :option:`--annotate-points`
+5 -3
View File
@@ -259,9 +259,11 @@ How do I view waveforms (aka dumps or traces)?
""""""""""""""""""""""""""""""""""""""""""""""
Verilator creates standard VCD (Value Change Dump) and FST files. VCD
files are viewable with the open-source GTKWave (recommended), or Dinotrace
(legacy) programs, or any of the many closed-source offerings; FST is
supported only by GTKWave.
files are viewable with the open-source
`GTKWave <http://gtkwave.sourceforge.net/>`_,
`Surfer <https://surfer-project.org/>`_, Dinotrace (legacy), or any of the
many closed-source viewer offerings; FST is supported only by GTKWave and
Surfer.
How do I speed up writing large waveform (trace) files?
+12 -10
View File
@@ -48,12 +48,6 @@ For --cc/--sc, it creates:
- Make include file for compiling (from --make gmake)
* - *{prefix}*\ _classes.mk
- Make include file with class names (from --make gmake)
* - *{prefix}*\ _hier.mk
- Make file for hierarchy blocks (from --make gmake)
* - *{prefix}*\ __hierMkArgs.f
- Arguments for hierarchical Verilation (from --make gmake)
* - *{prefix}*\ __hierCMakeArgs.f
- Arguments for hierarchical Verilation (from --make cmake)
* - *{prefix}*\ .h
- Model header
* - *{prefix}*\ .cpp
@@ -95,16 +89,24 @@ For --cc/--sc, it creates:
* - *{prefix}{each_verilog_module}{__DepSet_hash__n}*\ .cpp
- Additional lower C++ files (hashed to reduce build times)
For --hierarchy mode, it creates:
For --hierarchical mode, it creates:
.. list-table::
* - V\ *{hier_block}*\ /
- Directory to Verilate each hierarchy block (from --hierarchy)
- Directory to Verilate each hierarchical block (from --hierarchical)
* - *{prefix}*\ __hierVer.d
- Make dependencies of the top module (from --hierarchy)
- Make dependencies of the top module (from --hierarchical)
* - *{prefix}*\ _hier.mk
- Make file for hierarchical blocks (from --make gmake)
* - *{prefix}*\ __hierCMakeArgs.f
- Arguments for hierarchical Verilation (from --make cmake)
* - *{prefix}*\ __hierMkArgs.f
- Arguments for hierarchical Verilation (from --make gmake)
* - *{prefix}*\ __hierParameters.v
- Module parameters for hierarchical blocks
* - *{prefix}*\ __hier.dir
- Directory to store .dot, .vpp, .tree of top module (from --hierarchy)
- Directory to store .dot, .vpp, .tree of top module (from --hierarchical)
In specific debug and other modes, it also creates:
+38 -19
View File
@@ -19,13 +19,33 @@ started. (Note packages are unlikely to have the most recent version, so
:ref:`Git Install` might be a better alternative.) To install as a
package:
::
.. code-block:: shell
apt-get install verilator # On Ubuntu
For other distributions, refer to `Repology Verilator Distro Packages
<https://repology.org/project/verilator>`__.
.. _pre-commit Quick Install:
pre-commit Quick Install
=============================
You can use Verilator's `pre-commit <https://pre-commit.com/>`__ hook to
lint your code before committing it. It encapsulates the :ref:`Verilator
Build Docker Container`, so you need docker on your system to use it. The
verilator image will be downloaded automatically.
To use the hook, add the following entry to your :code:`.pre-commit-config.yaml`:
.. code-block:: yaml
repos:
- repo: https://github.com/verilator/verilator
rev: v5.026 # or later
hooks:
- id: verilator
.. _Git Install:
Git Quick Install
@@ -36,7 +56,7 @@ options and details, see :ref:`Detailed Build Instructions` below.
In brief, to install from git:
::
.. code-block:: shell
# Prerequisites:
#sudo apt-get install git help2man perl python3 make autoconf g++ flex bison ccache
@@ -89,7 +109,7 @@ Install Prerequisites
To build or run Verilator, you need these standard packages:
::
.. code-block:: shell
sudo apt-get install git help2man perl python3 make
sudo apt-get install g++ # Alternatively, clang
@@ -101,7 +121,7 @@ To build or run Verilator, you need these standard packages:
To build or run Verilator, the following are optional but should be installed
for good performance:
::
.. code-block:: shell
sudo apt-get install ccache # If present at build, needed for run
sudo apt-get install mold # If present at build, needed for run
@@ -110,27 +130,26 @@ for good performance:
The following is optional but is recommended for nicely rendered command line
help when running Verilator:
::
.. code-block:: shell
sudo apt-get install perl-doc
To build Verilator you will need to install these packages; these do not
need to be present to run Verilator:
::
.. code-block:: shell
sudo apt-get install git autoconf flex bison
Those developing Verilator itself may also want these (see internals.rst):
::
.. code-block:: shell
sudo apt-get install clang clang-format-14 cmake gdb gprof graphviz lcov
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
Install SystemC
@@ -171,14 +190,14 @@ Obtain Sources
Get the sources from the git repository: (You need to do this only once,
ever.)
::
.. code-block:: shell
git clone https://github.com/verilator/verilator # Only first time
## Note the URL above is not a page you can see with a browser; it's for git only
Enter the checkout and determine what version/branch to use:
::
.. code-block:: shell
cd verilator
git pull # Make sure we're up-to-date
@@ -193,7 +212,7 @@ Auto Configure
Create the configuration script:
::
.. code-block:: shell
autoconf # Create ./configure script
@@ -219,7 +238,7 @@ directory (don't run ``make install``). This allows the easiest
experimentation and upgrading, and allows many versions of Verilator to
co-exist on a system.
::
.. code-block:: shell
export VERILATOR_ROOT=`pwd` # if your shell is bash
setenv VERILATOR_ROOT `pwd` # if your shell is csh
@@ -241,7 +260,7 @@ that may support multiple versions of every tool. Tell configure the
eventual destination directory name. We recommend that the destination
location include the Verilator version name:
::
.. code-block:: shell
unset VERILATOR_ROOT # if your shell is bash
unsetenv VERILATOR_ROOT # if your shell is csh
@@ -253,7 +272,7 @@ the ``bin`` directory to your ``PATH``. Or, if you use `modulecmd
<http://modules.sourceforge.net/>`__, you'll want a module file like the
following:
::
.. code-block:: shell
set install_root /CAD_DISK/verilator/{version-number-used-above}
unsetenv VERILATOR_ROOT
@@ -268,7 +287,7 @@ following:
The final option is to eventually install Verilator globally, using
configure's default system paths:
::
.. code-block:: shell
unset VERILATOR_ROOT # if your shell is bash
unsetenv VERILATOR_ROOT # if your shell is csh
@@ -285,7 +304,7 @@ The command to configure the package was described in the previous step.
Developers should configure to have more complete developer tests.
Additional packages may be required for these tests.
::
.. code-block:: shell
export VERILATOR_AUTHOR_SITE=1 # Put in your .bashrc
./configure --enable-longtests ...above options...
@@ -296,7 +315,7 @@ Compile
Compile Verilator:
::
.. code-block:: shell
make -j `nproc` # Or if error on `nproc`, the number of CPUs in system
@@ -306,7 +325,7 @@ Test
Check the compilation by running self-tests:
::
.. code-block:: shell
make test
@@ -318,7 +337,7 @@ If you used any install option other than the `1. Run-in-Place from
VERILATOR_ROOT <#_1_run_in_place_from_verilator_root>`__ scheme, install
the files:
::
.. code-block:: shell
make install
+3 -1
View File
@@ -18,7 +18,9 @@ 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`.
simulation. This requires the model being Verilated with :vlopt:`--main`,
or the user's `main()` calling `VerilatedContext->statsPrintSummary()`.
The report may be disabled with :vlopt:`+verilator+quiet`.
For example:
+2 -2
View File
@@ -304,9 +304,9 @@ GNU Make
========
Verilator defaults to creating GNU Make makefiles for the model. Verilator
will call make automatically when the :vlopt:'--build' option is used.
will call make automatically when the :vlopt:`--build` option is used.
If calling Verilator from a makefile, the :vlopt:'-MMD' option will create
If calling Verilator from a makefile, the :vlopt:`--MMD` option will create
a dependency file, allowing Make to only run Verilator if input Verilog
files change.
+58 -23
View File
@@ -419,9 +419,9 @@ List Of Warnings
.. option:: CONSTRAINTIGN
Warns that Verilator does not support :code:`constraint`,
:code:`constraint_mode`, or :code:`rand_mode`, and the construct was are
ignored.
Warns that Verilator does not support certain forms of
:code:`constraint`, :code:`constraint_mode`, or :code:`rand_mode`, and
the construct was are ignored.
Ignoring this warning may make Verilator randomize() simulations differ
from other simulators.
@@ -1264,7 +1264,7 @@ List Of Warnings
.. option:: PINMISSING
.. TODO better example
.. TODO better example (frequent)
Warns that a module has a pin that is not mentioned in an instance. If
a pin is not missing it should still be specified on the instance
@@ -1273,6 +1273,22 @@ List Of Warnings
Ignoring this warning will only suppress the lint check; it will
simulate correctly.
Faulty example:
.. include:: ../../docs/gen/ex_PKGNODECL_faulty.rst
Results in:
.. include:: ../../docs/gen/ex_PKGNODECL_msg.rst
Repaired example:
.. code-block:: sv
:emphasize-lines: 2
sub sub (
.port());
Other tools with similar warnings: Icarus Verilog's portbind, "warning:
Instantiating module ... with dangling input port (...)". Slang's
unconnected-port, "port '...' has no connection".
@@ -1304,7 +1320,7 @@ List Of Warnings
generate
if (A==0) begin
b b_inst1 (.x(1'b0)); //<--- error nonexistent port
b #(.PX(1'b0)) b_inst2 (); //<--- error nonexistent parameter
b #(.PX(1'b0)) b_inst2 (); //<--- error nonexistent parameter
end
endgenerate
endmodule
@@ -1346,11 +1362,22 @@ List Of Warnings
.. option:: PKGNODECL
.. TODO better example
An error that a package/class appears to have been referenced that has
not yet been declared. According to IEEE 1800-2023 26.3, all packages
must be declared before being used.
An error that a package/class appears to have been referenced that has not
yet been declared. According to IEEE 1800-2023 26.3, all packages must
be declared before being used.
Faulty example:
.. include:: ../../docs/gen/ex_PKGNODECL_faulty.rst
Results in:
.. include:: ../../docs/gen/ex_PKGNODECL_msg.rst
Often the package is declared in its own header file. In this case add
an include of that package header file to the referencing file. (And
make sure you have header guards in the package's header file to prevent
multiple declarations of the package.)
.. option:: PREPROCZERO
@@ -1375,7 +1402,7 @@ List Of Warnings
`endif
The portable way to suppress this warning is to use a define value other
than zero to when used in a preprocessor expression.
than zero, when it is to be used in a preprocessor expression.
.. option:: PROCASSWIRE
@@ -1897,7 +1924,8 @@ List Of Warnings
.. option:: UNPACKED
Warns that unpacked structs and unions are not supported.
Warns that unpacked structs and unions are not supported because
:vlopt:`--structs-packed` was used, or by up through version 5.004.
Ignoring this warning will make Verilator treat the structure as packed,
which may make Verilator simulations differ from other simulators. This
@@ -1948,14 +1976,16 @@ List Of Warnings
.. TODO better example
Warns that the specified genvar is never used/consumed.
Warns that the specified genvar is never used/consumed. See similar
:option:`UNUSEDSIGNAL`.
.. option:: UNUSEDPARAM
.. TODO better example
Warns that the specified parameter is never used/consumed.
Warns that the specified parameter is never used/consumed. See similar
:option:`UNUSEDSIGNAL`.
.. option:: UNUSEDSIGNAL
@@ -2078,10 +2108,6 @@ List Of Warnings
.. option:: WAITCONST
.. code-block:: sv
wait(1); // Blocks forever
Warns that a `wait` statement awaits a constant condition, which means it
either blocks forever or never blocks.
@@ -2089,6 +2115,12 @@ List Of Warnings
something that elaborates to zero), does not warn, as it is presumed the
code is making the intent clear.
Faulty example:
.. code-block:: sv
wait(1); // Blocks forever
.. option:: WIDTH
@@ -2125,7 +2157,7 @@ List Of Warnings
.. include:: ../../docs/gen/ex_WIDTHEXPAND_1_faulty.rst
Results in a WIDTHEXPAND warning:
Results in a :option:`WIDTHEXPAND` warning:
.. include:: ../../docs/gen/ex_WIDTHEXPAND_1_msg.rst
@@ -2136,15 +2168,18 @@ List Of Warnings
.. option:: WIDTHTRUNC
A more granular WIDTH warning, for when a value is truncated.
A more granular :option:`WIDTH` warning, for when a value is
truncated. See :option:`WIDTH`.
.. option:: WIDTHEXPAND
A more granular WIDTH warning, for when a value is zero expanded.
A more granular :option:`WIDTH` warning, for when a value is zero
expanded. See :option:`WIDTH`.
.. option:: WIDTHXZEXPAND
A more granular WIDTH warning, for when a value is X/Z expanded.
A more granular :option:`WIDTH` warning, for when a value is X/Z
expanded. See :option:`WIDTH`.
.. option:: WIDTHCONCAT
@@ -2193,7 +2228,7 @@ List Of Warnings
#(parameter int MY_PARAM = 0);
reg [7:0] data;
always @* begin
data = {MY_PARAM{1'b1}}; //<--- WARNING
data = {MY_PARAM{1'b1}}; //<--- Warning
end
endmodule
@@ -2214,7 +2249,7 @@ List Of Warnings
:emphasize-lines: 2
module dut
#(parameter int MY_PARAM = 1); //<--- REPAIRED
#(parameter int MY_PARAM = 1); //<--- REPAIRED
reg [7:0] data;
always @* begin
data = {MY_PARAM{1'b1}};
+37 -54
View File
@@ -1472,9 +1472,6 @@ For all tests to pass, you must install the following packages:
- SystemC to compile the SystemC outputs, see http://systemc.org
- Parallel::Forker from CPAN to run tests in parallel; you can install
this with e.g. "sudo cpan install Parallel::Forker".
- vcddiff to find differences in VCD outputs. See the readme at
https://github.com/veripool/vcddiff
@@ -1484,7 +1481,7 @@ For all tests to pass, you must install the following packages:
Controlling the Test Driver
---------------------------
The test driver script `driver.pl` runs tests; see the `Test Driver`
The test driver script `driver.py` runs tests; see the `Test Driver`
section. The individual test drivers are written in Perl; see `Test
Language`.
@@ -1497,7 +1494,7 @@ A specific regression test can be executed manually. To start the
::
test_regress/t/t_EXAMPLE.pl
test_regress/t/t_EXAMPLE.py
Regression Testing for Developers
@@ -1517,13 +1514,6 @@ Developers will also want to call ./configure with two extra flags:
disabled by default, as SystemC installation problems would otherwise
falsely indicate a Verilator problem.
When enabling the long tests, some additional Perl modules are needed,
which you can install using cpan.
::
cpan install Parallel::Forker
There are some traps to avoid when running regression tests
- When checking the MANIFEST, the test will fail on unexpected code in the
@@ -1871,7 +1861,7 @@ represent the pointers (``op1p``, ``op2p``, etc) between the nodes.
Debugging with GDB
------------------
The `driver.pl` script accepts ``--debug --gdb`` to start
The `driver.py` script accepts ``--debug --gdb`` to start
Verilator under gdb and break when an error is hit, or the program is about
to exit. You can also use ``--debug --gdbbt`` to just backtrace and then
exit gdb. To debug the Verilated executable, use ``--gdbsim``.
@@ -1882,7 +1872,7 @@ can use ``--debug`` and look at the underlying invocation of
::
t/t_alw_dly.pl --debug
t/t_alw_dly.py --debug
shows it invokes the command:
@@ -1979,7 +1969,7 @@ Generally, what would you do to add a new feature?
Follow the convention described above about the AstNode type hierarchy.
Ordering of definitions is enforced by ``astgen``.
5. Now you can run ``test_regress/t/t_<newtestcase>.pl --debug`` and it'll
5. Now you can run ``test_regress/t/t_<newtestcase>.py --debug`` and it'll
probably fail, but you'll see a
``test_regress/obj_dir/t_<newtestcase>/*.tree`` file which you can examine
to see if the parsing worked. See also the sections above on debugging.
@@ -2028,7 +2018,7 @@ IEEE 1800-2023 33 Config
Test Driver
===========
This section documents the test driver script, `driver.pl`. driver.pl
This section documents the test driver script, `driver.py`. driver.py
invokes Verilator or another simulator on each test file. For test file
contents description see `Test Language`.
@@ -2040,7 +2030,7 @@ the regression tests with OBJCACHE enabled and in parallel on a machine
with many cores. See the -j option and OBJCACHE environment variable.
driver.pl Non-Scenario Arguments
driver.py Non-Scenario Arguments
--------------------------------
--benchmark [<cycles>]
@@ -2110,13 +2100,13 @@ driver.pl Non-Scenario Arguments
memory leaks.
--site
Run site specific tests also.
Run site-specific tests also.
--stop
Stop on the first error.
--trace
Set the simulator specific flags to request waveform tracing.
Set the simulator-specific flags to request waveform tracing.
--valgrind
Same as ``verilator --valgrind``: Run Verilator under `Valgrind <https://valgrind.org/>`_.
@@ -2129,7 +2119,7 @@ driver.pl Non-Scenario Arguments
For tests using the standard C++ wrapper, enable runtime debug mode.
driver.pl Scenario Arguments
driver.py Scenario Arguments
----------------------------
The following options control which simulator is used, and which tests are
@@ -2171,7 +2161,7 @@ simultaneously.
Run Xilinx XSim simulator tests.
driver.pl Environment
driver.py Environment
---------------------
HARNESS_UPDATE_GOLDEN
@@ -2231,30 +2221,30 @@ VERILATOR_XVLOG
Test Language
=============
This section describes the format of the ``test_regress/t/*.pl`` test
language files, executed by `driver.pl`.
This section describes the format of the ``test_regress/t/*.py`` test
language files, executed by `driver.py`.
Test Language Summary
---------------------
For convenience, a summary of the most commonly used features is provided
here, with a reference in a later section. All test files typically have a
call to the ``lint`` or ``compile`` subroutine to compile the test. For
run-time tests, this is followed by a call to the ``execute``
subroutine. Both of these functions can optionally be provided with
arguments specifying additional options.
call to the ``test.lint`` or ``test.compile`` methods to compile the
test. For run-time tests, this is followed by a call to the
``test.execute`` method. Both of these functions can optionally be provided
with arguments specifying additional options.
If those complete, the script calls ``ok`` to increment the count of
successful tests and then returns 1 as its result.
If those complete, the script calls ``test.passes`` to increment the count
of successful tests.
The driver.pl script assumes by default that the source Verilog file name
The driver.py script assumes by default that the source Verilog file name
matches the test script name. So a test whose driver is
``t/t_mytest.pl`` will expect a Verilog source file ``t/t_mytest.v``.
``t/t_mytest.py`` will expect a Verilog source file ``t/t_mytest.v``.
This can be changed using the ``top_filename`` subroutine, for example
::
top_filename("t/t_myothertest.v");
test.top_filename = "t/t_myothertest.v"
By default, all tests will run with major simulators (Icarus Verilog, NC,
VCS, ModelSim, etc.) as well as Verilator, to allow results to be
@@ -2263,26 +2253,25 @@ can use the following:
::
scenarios(vlt => 1);
test.scenarios('vlt')
Of the many options that can be set through arguments to ``compiler`` and
``execute``, the following are particularly useful:
Of the many options that can be set through arguments to ``test.compiler``
and ``test.execute``, the following are particularly useful:
``verilator_flags2``
A list of flags to be passed to verilator when compiling.
``fails``
Set to 1 to indicate that the compilation or execution is intended to fail.
Set true to indicate that the compilation or execution is intended to fail.
For example, the following would specify that compilation requires two
defines and is expected to fail.
::
compile(
test.compile(
verilator_flags2 => ["-DSMALL_CLOCK -DGATED_COMMENT"],
fails => 1,
);
fails = True)
Hints On Writing Tests
----------------------
@@ -2295,10 +2284,10 @@ same name as the test, but with .cpp as suffix
::
compile(
make_top_shell => 0,
make_main => 0,
verilator_flags2 => ["--exe $Self->{t_dir}/$Self->{name}.cpp"], );
test.compile(
make_top_shell=False,
make_main=False,
verilator_flags2=["--exe", test.t_dir + "/" + test.name + ".cpp"])
Tests should be self-checking, rather than producing lots of output. If a
test succeeds it should print ``*-* All Finished *-*`` to standard output
@@ -2338,9 +2327,8 @@ compile time, it is the only option. For example:
::
compile(
fails => 1,
expect_filename => $Self->{golden_filename},
);
fails=True,
expect_filename=test.golden_filename)
Note ``expect_filename`` strips some debugging information from the logfile
when comparing.
@@ -2349,9 +2337,9 @@ when comparing.
Test Language Compile/Lint/Run Arguments
----------------------------------------
This section describes common arguments to ``compile()``, ``lint()``, and
``run()``. The full list of arguments can be found by looking at the
``driver.pl`` source code.
This section describes common arguments to ``test.compile``, ``test.lint``,
and ``test.run``. The full list of arguments can be found by looking at
the ``driver.py`` source code.
all_run_flags
A list of flags to be passed when running the simulator (Verilated model
@@ -2362,11 +2350,6 @@ check_finished
string ``*-* All Finished *-*`` being printed on standard output. This is
the normal way for successful tests to finish.
expect
A quoted list of strings or regular expression to be matched in the
output. See `Hints On Writing Tests` for more detail on how this argument
should be used.
fails
True to indicate this step is expected to fail. Tests that are expected
to fail generally have _bad in their filename.
+28
View File
@@ -20,6 +20,7 @@ Ashutosh
Ast
Atmel
Aurelien
Badáň
Bagri
Balboni
Baltazar
@@ -74,6 +75,7 @@ Deepa
Defparams
Delm
Denio
Deniz
Deprecations
Deroo
Desai
@@ -109,8 +111,10 @@ Eugen
Fabrizio
Faucher
Faure
Feinberg
Fekete
Ferrandi
Filip
Flachs
Flavien
Florian
@@ -149,6 +153,7 @@ Grulfen
Gu
Gunter
Guo
Güzel
Hameed
Hao
Haojin
@@ -243,6 +248,7 @@ Liwei
Lockhart
Longo
Luca
Luiza
Lussier
Lübeck
MMD
@@ -273,6 +279,8 @@ MinW
Mindspeed
MingW
Miodrag
Moberg
Mobert
ModelSim
Modport
Moinak
@@ -354,6 +362,7 @@ Sasselli
Scharrer
Seitz
Shahid
Shahrestani
Shankar
Shanshan
Sharad
@@ -364,6 +373,7 @@ Shi
Shinkarovsky
Shinya
Shirakawa
Shou
Shuba
Shunyao
Slager
@@ -375,10 +385,12 @@ Solaris
Solomatnikov
Solt
Southwell
Spack
Srini
Srinivasan
Stamness
Stephane
Sterin
Stoddard
Stroebel
Strouble
@@ -461,6 +473,7 @@ Wojciech
Wolfel
Wouters
Wpedantic
Wunused
Wwarn
XSim
Xcelium
@@ -497,6 +510,7 @@ architected
args
arrarys
assertOn
assertcontrol
astgen
async
atClone
@@ -513,6 +527,7 @@ basename
bbox
benchmarking
biguint
bindir
biops
bisonpre
bitOpTree
@@ -582,6 +597,7 @@ datadir
datafiles
david
ddd
de
deassign
debugi
defenv
@@ -589,6 +605,7 @@ defname
defparam
demangling
dep
deparametrized
der
dereference
desassign
@@ -701,6 +718,7 @@ genvar
genvars
getenv
getline
getter
ggdb
glibc
gmake
@@ -714,6 +732,7 @@ hh
hier
hierCMakeArgs
hierMkArgs
hierParameters
hierVer
hx
hyperthreading
@@ -845,6 +864,7 @@ parallelized
param
parameterization
parameterized
parameterized
parameterless
params
parens
@@ -858,6 +878,7 @@ phelter
picoChip
pinIndex
pinout
pkgdatadir
plusargs
pmos
poping
@@ -891,6 +912,7 @@ prototyptes
ps
psprintf
pthread
pthreads
ptr
pulldown
pulldowns
@@ -921,6 +943,7 @@ redeclaring
regs
reloop
replaceShiftOp
reproducibility
resetall
respecified
rodata
@@ -973,7 +996,9 @@ submakes
submodule
submodules
substring
superclass
suspendable
suspendables
sv
svBitVal
svBitVecVal
@@ -1008,6 +1033,8 @@ traceEverOn
tran
treei
tri
triand
trior
tristate
tristates
trunc
@@ -1083,6 +1110,7 @@ warmup
waveforms
whitespace
widthed
wor
wreal
writeb
writeme
+7 -3
View File
@@ -24,8 +24,11 @@ cmake_policy(SET CMP0074 NEW)
project(cmake_hello_c)
find_package(verilator HINTS $ENV{VERILATOR_ROOT} ${VERILATOR_ROOT})
if (NOT verilator_FOUND)
message(FATAL_ERROR "Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable")
if(NOT verilator_FOUND)
message(
FATAL_ERROR
"Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable"
)
endif()
# Create a new executable target that will contain all your sources
@@ -35,4 +38,5 @@ target_compile_features(example PUBLIC cxx_std_14)
# Add the Verilated circuit to the target
verilate(example
INCLUDE_DIRS "../make_hello_c"
SOURCES ../make_hello_c/top.v)
SOURCES ../make_hello_c/top.v
)
+8 -7
View File
@@ -24,8 +24,11 @@ cmake_policy(SET CMP0074 NEW)
project(cmake_hello_sc CXX)
find_package(verilator HINTS $ENV{VERILATOR_ROOT} ${VERILATOR_ROOT})
if (NOT verilator_FOUND)
message(FATAL_ERROR "Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable")
if(NOT verilator_FOUND)
message(
FATAL_ERROR
"Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable"
)
endif()
# SystemC dependencies
@@ -39,14 +42,12 @@ find_package(SystemCLanguage QUIET)
add_executable(example ../make_hello_sc/sc_main.cpp)
target_compile_features(example PUBLIC cxx_std_14)
set_property(
TARGET example
PROPERTY CXX_STANDARD ${SystemC_CXX_STANDARD}
)
set_property(TARGET example PROPERTY CXX_STANDARD ${SystemC_CXX_STANDARD})
# Add the Verilated circuit to the target
verilate(example SYSTEMC
INCLUDE_DIRS "../make_hello_sc"
SOURCES ../make_hello_sc/top.v)
SOURCES ../make_hello_sc/top.v
)
verilator_link_systemc(example)
+9 -4
View File
@@ -24,8 +24,11 @@ cmake_policy(SET CMP0074 NEW)
project(cmake_protect_lib)
find_package(verilator HINTS $ENV{VERILATOR_ROOT} ${VERILATOR_ROOT})
if (NOT verilator_FOUND)
message(FATAL_ERROR "Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable")
if(NOT verilator_FOUND)
message(
FATAL_ERROR
"Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable"
)
endif()
# Create the main executable target
@@ -55,9 +58,11 @@ verilate(verilated_secret
VERILATOR_ARGS --protect-lib verilated_secret
--protect-key ${PROTECT_KEY}
DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/verilated_secret
SOURCES ../make_protect_lib/secret_impl.v)
SOURCES ../make_protect_lib/secret_impl.v
)
# Include location of verilated_secret.sv wrapper
verilate(example
VERILATOR_ARGS "-I${CMAKE_CURRENT_BINARY_DIR}/verilated_secret"
SOURCES ../make_protect_lib/top.v)
SOURCES ../make_protect_lib/top.v
)
+7 -3
View File
@@ -24,8 +24,11 @@ cmake_policy(SET CMP0074 NEW)
project(cmake_tracing_c)
find_package(verilator HINTS $ENV{VERILATOR_ROOT} ${VERILATOR_ROOT})
if (NOT verilator_FOUND)
message(FATAL_ERROR "Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable")
if(NOT verilator_FOUND)
message(
FATAL_ERROR
"Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable"
)
endif()
# Create a new executable target that will contain all your sources
@@ -36,4 +39,5 @@ target_compile_features(example PUBLIC cxx_std_14)
verilate(example COVERAGE TRACE
INCLUDE_DIRS "../make_tracing_c"
VERILATOR_ARGS -f ../make_tracing_c/input.vc -x-assign fast
SOURCES ../make_tracing_c/top.v)
SOURCES ../make_tracing_c/top.v
)
+8 -7
View File
@@ -25,8 +25,11 @@ cmake_policy(SET CMP0074 NEW)
project(cmake_tracing_sc_example CXX)
find_package(verilator HINTS $ENV{VERILATOR_ROOT} ${VERILATOR_ROOT})
if (NOT verilator_FOUND)
message(FATAL_ERROR "Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable")
if(NOT verilator_FOUND)
message(
FATAL_ERROR
"Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable"
)
endif()
# SystemC dependencies
@@ -40,15 +43,13 @@ find_package(SystemCLanguage QUIET)
add_executable(example ../make_tracing_sc/sc_main.cpp)
target_compile_features(example PUBLIC cxx_std_14)
set_property(
TARGET example
PROPERTY CXX_STANDARD ${SystemC_CXX_STANDARD}
)
set_property(TARGET example PROPERTY CXX_STANDARD ${SystemC_CXX_STANDARD})
# Add the Verilated circuit to the target
verilate(example SYSTEMC COVERAGE TRACE
INCLUDE_DIRS "../make_tracing_sc"
VERILATOR_ARGS -f ../make_tracing_sc/input.vc -x-assign fast
SOURCES ../make_tracing_sc/top.v)
SOURCES ../make_tracing_sc/top.v
)
verilator_link_systemc(example)
+1 -1
View File
@@ -13,6 +13,6 @@ module sub
);
// Some simple logic
always_comb out = ~ in;
always_comb out = ~in;
endmodule
+5 -14
View File
@@ -25,8 +25,7 @@ class VlFileCopy:
self.debug = debug
with NamedTemporaryFile() as tree_temp, NamedTemporaryFile(
) as meta_temp:
with NamedTemporaryFile() as tree_temp, NamedTemporaryFile() as meta_temp:
vargs = [
'--json-only-output',
tree_temp.name,
@@ -61,8 +60,7 @@ class VlFileCopy:
print("\t%s " % command)
status = subprocess.call(command, shell=True)
if status != 0:
raise RuntimeError("Command failed running Verilator with '" +
command + "', stopped")
raise RuntimeError("Command failed running Verilator with '" + command + "', stopped")
#######################################################################
@@ -71,8 +69,7 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawTextHelpFormatter,
description=
"""Example of using Verilator JSON output to copy a list of files to an
description="""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.
@@ -95,11 +92,7 @@ This file ONLY is placed under the Creative Commons Public Domain, for
any use, without warranty, 2019 by Wilson Snyder.
SPDX-License-Identifier: CC0-1.0
""")
parser.add_argument('-debug',
'--debug',
action='store_const',
const=9,
help='enable debug')
parser.add_argument('-debug', '--debug', action='store_const', const=9, help='enable debug')
parser.add_argument('-odir',
'--odir',
action='store',
@@ -108,9 +101,7 @@ SPDX-License-Identifier: CC0-1.0
help='target output directory')
(args, rem) = parser.parse_known_args()
print(
"NOTE: vl_file_copy is only an example starting point for writing your own tool."
)
print("NOTE: vl_file_copy is only an example starting point for writing your own tool.")
# That is:
# 1. We will accept basic patches
# 2. We are not expecting to make this globally useful. (e.g. we don't cleanup obj_dir)
+7 -20
View File
@@ -24,8 +24,7 @@ class VlHierGraph:
self.next_vertex_number = 0
self.addr_to_number = {}
with NamedTemporaryFile() as tree_temp, NamedTemporaryFile(
) as meta_temp:
with NamedTemporaryFile() as tree_temp, NamedTemporaryFile() as meta_temp:
vargs = [
'--json-only-output',
tree_temp.name,
@@ -45,9 +44,7 @@ class VlHierGraph:
fh.write("digraph {\n")
fh.write(" dpi=300;\n")
fh.write(" order=LR;\n")
fh.write(
" node [fontsize=8 shape=\"box\" margin=0.01 width=0 height=0]"
)
fh.write(" node [fontsize=8 shape=\"box\" margin=0.01 width=0 height=0]")
fh.write(" edge [fontsize=6]")
# Find cells
modules = self.flatten(self.tree, lambda n: n['type'] == "MODULE")
@@ -101,8 +98,7 @@ class VlHierGraph:
print("\t%s " % command)
status = subprocess.call(command, shell=True)
if status != 0:
raise RuntimeError("Command failed running Verilator with '" +
command + "', stopped")
raise RuntimeError("Command failed running Verilator with '" + command + "', stopped")
#######################################################################
@@ -111,8 +107,7 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawTextHelpFormatter,
description=
"""Example of using Verilator JSON output to create a .dot file showing the
description="""Example of using Verilator JSON output to create a .dot file showing the
design module hierarchy.
Example usage:
@@ -134,11 +129,7 @@ This file ONLY is placed under the Creative Commons Public Domain, for
any use, without warranty, 2019 by Wilson Snyder.
SPDX-License-Identifier: CC0-1.0
""")
parser.add_argument('-debug',
'--debug',
action='store_const',
const=9,
help='enable debug')
parser.add_argument('-debug', '--debug', action='store_const', const=9, help='enable debug')
parser.add_argument('-o',
'--o',
action='store',
@@ -147,18 +138,14 @@ SPDX-License-Identifier: CC0-1.0
help='output filename')
(args, rem) = parser.parse_known_args()
print(
"NOTE: vl_hier_graph is only an example starting point for writing your own tool."
)
print("NOTE: vl_hier_graph is only an example starting point for writing your own tool.")
# That is:
# 1. We will accept basic patches
# 2. We are not expecting to make this globally useful. (e.g. we don't cleanup obj_dir)
# 3. "make install" will not install this.
# 4. This has not had production-worthy validation.
fc = VlHierGraph(output_filename=args.o,
debug=args.debug,
verilator_args=rem)
fc = VlHierGraph(output_filename=args.o, debug=args.debug, verilator_args=rem)
######################################################################
# Local Variables:
+4 -4
View File
@@ -13,7 +13,7 @@ module sub
// Example counter/flop
reg [31:0] count_c;
always_ff @ (posedge clk) begin
always_ff @(posedge clk) begin
if (!reset_l) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
@@ -32,11 +32,11 @@ module sub
end
// An example assertion
always_ff @ (posedge clk) begin
AssertionExample: assert (!reset_l || count_c<100);
always_ff @(posedge clk) begin
AssertionExample : assert (!reset_l || count_c < 100);
end
// And example coverage analysis
cover property (@(posedge clk) count_c==3);
cover property (@(posedge clk) count_c == 3);
endmodule
+6 -7
View File
@@ -14,7 +14,7 @@ module sub
// Example counter/flop
reg [31:0] count_f;
always_ff @ (posedge fastclk) begin
always_ff @(posedge fastclk) begin
if (!reset_l) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
@@ -28,7 +28,7 @@ module sub
// Another example flop
reg [31:0] count_c;
always_ff @ (posedge clk) begin
always_ff @(posedge clk) begin
if (!reset_l) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
@@ -38,8 +38,7 @@ module sub
else begin
count_c <= count_c + 1;
if (count_c >= 3) begin
$display("[%0t] fastclk is %0d times faster than clk\n",
$time, count_f/count_c);
$display("[%0t] fastclk is %0d times faster than clk\n", $time, count_f / count_c);
// This write is a magic value the Makefile uses to make sure the
// test completes successfully.
$write("*-* All Finished *-*\n");
@@ -49,11 +48,11 @@ module sub
end
// An example assertion
always_ff @ (posedge clk) begin
AssertionExample: assert(!reset_l || count_c<100);
always_ff @(posedge clk) begin
AssertionExample : assert (!reset_l || count_c < 100);
end
// And example coverage analysis
cover property (@(posedge clk) count_c==3);
cover property (@(posedge clk) count_c == 3);
endmodule
+20 -7
View File
@@ -130,6 +130,7 @@ void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint3
#define FST_HDR_TIMEZERO_SIZE (8)
#define FST_GZIO_LEN (32768)
#define FST_HDR_FOURPACK_DUO_SIZE (4*1024*1024)
#define FST_ZWRAPPER_HDR_SIZE (1+8+8)
#if defined(__APPLE__) && defined(__MACH__)
#define FST_MACOSX
@@ -549,8 +550,9 @@ return(rc);
static uint32_t fstReaderVarint32(FILE *f)
{
int chk_len = 5; /* TALOS-2023-1783 */
unsigned char buf[chk_len];
const int chk_len_max = 5; /* TALOS-2023-1783 */
int chk_len = chk_len_max;
unsigned char buf[chk_len_max];
unsigned char *mem = buf;
uint32_t rc = 0;
int ch;
@@ -581,8 +583,9 @@ return(rc);
static uint32_t fstReaderVarint32WithSkip(FILE *f, uint32_t *skiplen)
{
int chk_len = 5; /* TALOS-2023-1783 */
unsigned char buf[chk_len];
const int chk_len_max = 5; /* TALOS-2023-1783 */
int chk_len = chk_len_max;
unsigned char buf[chk_len_max];
unsigned char *mem = buf;
uint32_t rc = 0;
int ch;
@@ -614,8 +617,9 @@ return(rc);
static uint64_t fstReaderVarint64(FILE *f)
{
int chk_len = 16; /* TALOS-2023-1783 */
unsigned char buf[chk_len];
const int chk_len_max = 16; /* TALOS-2023-1783 */
int chk_len = chk_len_max;
unsigned char buf[chk_len_max];
unsigned char *mem = buf;
uint64_t rc = 0;
int ch;
@@ -4633,9 +4637,14 @@ if(sectype == FST_BL_ZWRAPPER)
}
#endif
fstReaderFseeko(xc, xc->f, 1+8+8, SEEK_SET);
fstReaderFseeko(xc, xc->f, FST_ZWRAPPER_HDR_SIZE, SEEK_SET);
#ifndef __MINGW32__
fflush(xc->f);
#else
/* Windows UCRT runtime library reads one byte ahead in the file
even with buffering disabled and does not synchronise the
file position after fseek. */
_lseek(fileno(xc->f), FST_ZWRAPPER_HDR_SIZE, SEEK_SET);
#endif
zfd = dup(fileno(xc->f));
@@ -6185,7 +6194,9 @@ struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
fst_off_t blkpos = 0, prev_blkpos;
uint64_t beg_tim, end_tim, beg_tim2, end_tim2;
int sectype;
#ifdef FST_DEBUG
unsigned int secnum = 0;
#endif
uint64_t seclen;
uint64_t tsec_uclen = 0, tsec_clen = 0;
uint64_t tsec_nitems;
@@ -6277,7 +6288,9 @@ for(;;)
}
blkpos += seclen;
#ifdef FST_DEBUG
secnum++;
#endif
}
xc->rvat_beg_tim = beg_tim;
+59 -14
View File
@@ -128,6 +128,7 @@ void vl_finish(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE
#ifndef VL_USER_STOP ///< Define this to override the vl_stop function
void vl_stop(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE {
// $stop or $fatal reporting; would break current API to add param as to which
const char* const msg = "Verilog $stop";
Verilated::threadContextp()->gotError(true);
Verilated::threadContextp()->gotFinish(true);
@@ -172,6 +173,7 @@ void vl_fatal(const char* filename, int linenum, const char* hier, const char* m
#ifndef VL_USER_STOP_MAYBE ///< Define this to override the vl_stop_maybe function
void vl_stop_maybe(const char* filename, int linenum, const char* hier, bool maybe) VL_MT_UNSAFE {
// $stop or $fatal
Verilated::threadContextp()->errorCountInc();
if (maybe
&& Verilated::threadContextp()->errorCount() < Verilated::threadContextp()->errorLimit()) {
@@ -412,6 +414,8 @@ IData VL_RAND_RESET_I(int obits) VL_MT_SAFE {
data &= VL_MASK_I(obits);
return data;
}
IData VL_RAND_RESET_ASSIGN_I(int obits) VL_MT_SAFE { return VL_RANDOM_I() & VL_MASK_I(obits); }
QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE {
if (Verilated::threadContextp()->randReset() == 0) return 0;
QData data = ~0ULL;
@@ -421,11 +425,19 @@ QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE {
data &= VL_MASK_Q(obits);
return data;
}
QData VL_RAND_RESET_ASSIGN_Q(int obits) VL_MT_SAFE { return VL_RANDOM_Q() & VL_MASK_Q(obits); }
WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE {
for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = VL_RAND_RESET_I(32);
outwp[VL_WORDS_I(obits) - 1] = VL_RAND_RESET_I(32) & VL_MASK_E(obits);
return outwp;
}
WDataOutP VL_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp) VL_MT_SAFE {
for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = VL_RAND_RESET_ASSIGN_I(32);
outwp[VL_WORDS_I(obits) - 1] = VL_RAND_RESET_ASSIGN_I(32) & VL_MASK_E(obits);
return outwp;
}
WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE {
// Not inlined to speed up compilation of slowpath code
return VL_ZERO_W(obits, outwp);
@@ -1753,9 +1765,8 @@ IData VL_SYSTEM_IQ(QData lhs) VL_MT_SAFE {
return VL_SYSTEM_IW(VL_WQ_WORDS_E, lhsw);
}
IData VL_SYSTEM_IW(int lhswords, const WDataInP lhsp) VL_MT_SAFE {
char filenamez[VL_VALUE_STRING_MAX_CHARS + 1];
_vl_vint_to_string(lhswords * VL_EDATASIZE, filenamez, lhsp);
return VL_SYSTEM_IN(filenamez);
const std::string lhs = VL_CVT_PACK_STR_NW(lhswords, lhsp);
return VL_SYSTEM_IN(lhs);
}
IData VL_SYSTEM_IN(const std::string& lhs) VL_MT_SAFE {
const int code = std::system(lhs.c_str()); // Yes, std::system() is threadsafe
@@ -1905,20 +1916,16 @@ std::string VL_TOUPPER_NN(const std::string& ld) VL_PURE {
std::string VL_CVT_PACK_STR_NW(int lwords, const WDataInP lwp) VL_PURE {
// See also _vl_vint_to_string
char destout[VL_VALUE_STRING_MAX_CHARS + 1];
std::string result;
result.reserve((lwords * VL_EDATASIZE) / 8 + 1);
const int obits = lwords * VL_EDATASIZE;
int lsb = obits - 1;
char* destp = destout;
size_t len = 0;
for (; lsb >= 0; --lsb) {
lsb = (lsb / 8) * 8; // Next digit
const IData charval = VL_BITRSHIFT_W(lwp, lsb) & 0xff;
if (charval) {
*destp++ = static_cast<char>(charval);
++len;
}
if (charval) result += static_cast<char>(charval);
}
return std::string{destout, len};
return result;
}
std::string VL_CVT_PACK_STR_ND(const VlQueue<std::string>& q) VL_PURE {
@@ -2494,9 +2501,47 @@ VerilatedContext::Serialized::Serialized() {
m_timeprecision = picosecond; // Initial value until overridden by _Vconfigure
}
bool VerilatedContext::assertOn() const VL_MT_SAFE { return m_s.m_assertOn; }
void VerilatedContext::assertOn(bool flag) VL_MT_SAFE {
const VerilatedLockGuard lock{m_mutex};
m_s.m_assertOn = flag;
// Set all assert and directive types when true, clear otherwise.
m_s.m_assertOn = VL_MASK_I(ASSERT_ON_WIDTH) * flag;
}
bool VerilatedContext::assertOnGet(VerilatedAssertType_t type,
VerilatedAssertDirectiveType_t directive) const VL_MT_SAFE {
// Check if selected directive type bit in the assertOn is enabled for assertion type.
// Note: it is assumed that this is checked only for one type at the time.
// Flag unspecified assertion types as disabled.
if (type == 0) return false;
// Get index of 3-bit group guarding assertion type status.
// Since the assertOnGet is generated __always__ for a single assert type, we assume that only
// a single bit will be set. Thus, ceil log2 will work fine.
VL_DEBUG_IFDEF(assert((type & (type - 1)) == 0););
const IData typeMaskPosition = VL_CLOG2_I(type);
// Check if directive type bit is enabled in corresponding assertion type bits.
return m_s.m_assertOn & (directive << (typeMaskPosition * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH));
}
void VerilatedContext::assertOnSet(VerilatedAssertType_t types,
VerilatedAssertDirectiveType_t directives) VL_MT_SAFE {
// For each assertion type, set directive bits.
// Iterate through all positions of assertion type bits. If bit for this assertion type is set,
// set directive type bits mask at this group index.
for (int i = 0; i < std::numeric_limits<VerilatedAssertType_t>::digits; ++i) {
if (VL_BITISSET_I(types, i))
m_s.m_assertOn |= directives << (i * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH);
}
}
void VerilatedContext::assertOnClear(VerilatedAssertType_t types,
VerilatedAssertDirectiveType_t directives) VL_MT_SAFE {
// Iterate through all positions of assertion type bits. If bit for this assertion type is set,
// clear directive type bits mask at this group index.
for (int i = 0; i < std::numeric_limits<VerilatedAssertType_t>::digits; ++i) {
if (VL_BITISSET_I(types, i))
m_s.m_assertOn &= ~(directives << (i * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH));
}
}
void VerilatedContext::calcUnusedSigs(bool flag) VL_MT_SAFE {
const VerilatedLockGuard lock{m_mutex};
@@ -2954,7 +2999,7 @@ const VerilatedScopeNameMap* VerilatedContext::scopeNameMap() VL_MT_SAFE {
//======================================================================
// VerilatedContext:: Methods - trace
void VerilatedContext::trace(VerilatedTraceBaseC* tfp, int levels, int options) VL_MT_SAFE {
void VerilatedContext::trace(VerilatedTraceBaseC* tfp, int levels, int options) {
VL_DEBUG_IF(VL_DBG_MSGF("+ VerilatedContext::trace\n"););
if (tfp->isOpen()) {
VL_FATAL_MT("", 0, "",
+108 -74
View File
@@ -55,6 +55,7 @@
#include <cstring>
#include <deque>
#include <functional>
#include <limits>
#include <map>
#include <memory>
#include <set>
@@ -153,6 +154,27 @@ enum VerilatedVarFlags {
VLVF_DPI_CLAY = (1 << 10) // DPI compatible C standard layout
};
// IEEE 1800-2023 Table 20-6
enum class VerilatedAssertType : uint8_t {
ASSERT_TYPE_CONCURRENT = (1 << 0),
ASSERT_TYPE_SIMPLE_IMMEDIATE = (1 << 1),
ASSERT_TYPE_OBSERVED_DEFERRED_IMMEDIATE = (1 << 2),
ASSERT_TYPE_FINAL_DEFERRED_IMMEDIATE = (1 << 3),
ASSERT_TYPE_EXPECT = (1 << 4),
ASSERT_TYPE_UNIQUE = (1 << 5),
ASSERT_TYPE_UNIQUE0 = (1 << 6),
ASSERT_TYPE_PRIORITY = (1 << 7),
};
// IEEE 1800-2023 Table 20-7
enum class VerilatedAssertDirectiveType : uint8_t {
DIRECTIVE_TYPE_ASSERT = (1 << 0),
DIRECTIVE_TYPE_COVER = (1 << 1),
DIRECTIVE_TYPE_ASSUME = (1 << 2),
};
using VerilatedAssertType_t = std::underlying_type<VerilatedAssertType>::type;
using VerilatedAssertDirectiveType_t = std::underlying_type<VerilatedAssertDirectiveType>::type;
//=============================================================================
// Utility functions
@@ -199,19 +221,6 @@ public:
void unlock() VL_RELEASE() VL_MT_SAFE { m_mutex.unlock(); }
/// Try to acquire mutex. Returns true on success, and false on failure.
bool try_lock() VL_TRY_ACQUIRE(true) VL_MT_SAFE { return m_mutex.try_lock(); }
/// Acquire/lock mutex and check for stop request
/// It tries to lock the mutex and if it fails, it check if stop request was send.
/// It returns after locking mutex.
/// This function should be extracted to V3ThreadPool, but due to clang thread-safety
/// limitations it needs to be placed here.
void lockCheckStopRequest(std::function<void()> checkStopRequestFunction)
VL_ACQUIRE() VL_MT_SAFE {
while (true) {
checkStopRequestFunction();
if (m_mutex.try_lock()) return;
VL_CPU_RELAX();
}
}
};
/// Lock guard for mutex (ala std::unique_lock), wrapped to allow -fthread_safety checks
@@ -347,6 +356,19 @@ public:
class VerilatedContext VL_NOT_FINAL {
friend class VerilatedContextImp;
private:
// MEMBERS
// Numer of assertion directive type members. Then each of them will represented as 1-bit in a
// mask.
static constexpr size_t ASSERT_DIRECTIVE_TYPE_MASK_WIDTH = 3;
// Specifies how many groups of directive type bit groups there are based on a number of
// assertion types.
// Note: we add one bit to store information whether Verilator's internal
// directive types are enabled, for example `violation if`s.
static constexpr size_t ASSERT_ON_WIDTH
= ASSERT_DIRECTIVE_TYPE_MASK_WIDTH * std::numeric_limits<VerilatedAssertType_t>::digits
+ 1;
protected:
// TYPES
using traceBaseModelCb_t
@@ -360,7 +382,11 @@ protected:
// 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
std::atomic<uint32_t> m_assertOn{
std::numeric_limits<uint32_t>::max()}; // Enabled assertions,
// for each VerilatedAssertType we store
// 3-bits, one for each directive type. Last
// bit guards internal directive types.
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
@@ -448,14 +474,23 @@ public:
// METHODS - User called
/// Enable assertions
void assertOn(bool flag) VL_MT_SAFE;
/// Return if assertions enabled
bool assertOn() const VL_MT_SAFE { return m_s.m_assertOn; }
/// Enable calculation of unused signals (for traces)
void calcUnusedSigs(bool flag) VL_MT_SAFE;
bool assertOn() const VL_MT_SAFE;
/// Enable all assertion types
void assertOn(bool flag) VL_MT_SAFE;
/// Get enabled status for given assertion types
bool assertOnGet(VerilatedAssertType_t type,
VerilatedAssertDirectiveType_t directive) const VL_MT_SAFE;
/// Set enabled status for given assertion types
void assertOnSet(VerilatedAssertType_t types,
VerilatedAssertDirectiveType_t directives) VL_MT_SAFE;
/// Clear enabled status for given assertion types
void assertOnClear(VerilatedAssertType_t types,
VerilatedAssertDirectiveType_t directives) VL_MT_SAFE;
/// Return if calculating of unused signals (for traces)
bool calcUnusedSigs() const VL_MT_SAFE { return m_s.m_calcUnusedSigs; }
/// Enable calculation of unused signals (for traces)
void calcUnusedSigs(bool flag) VL_MT_SAFE;
/// Record command-line arguments, for retrieval by $test$plusargs/$value$plusargs,
/// and for parsing +verilator+ run-time arguments.
/// This should be called before the first model is created.
@@ -470,52 +505,51 @@ public:
/// Return VerilatedCovContext, allocate if needed
/// Note if get unresolved reference then likely forgot to link verilated_cov.cpp
VerilatedCovContext* coveragep() VL_MT_SAFE;
/// Set debug level
/// Return debug level
static inline int debug() VL_MT_SAFE; /// Set debug level
/// Debug is currently global, but for forward compatibility have a per-context method
static inline void debug(int val) VL_MT_SAFE;
/// Return debug level
static inline int debug() VL_MT_SAFE;
/// Return current number of errors/assertions
int errorCount() const VL_MT_SAFE { return m_s.m_errorCount; }
/// Set current number of errors/assertions
void errorCount(int val) VL_MT_SAFE;
/// Increment current number of errors/assertions
void errorCountInc() VL_MT_SAFE;
/// Return current number of errors/assertions
int errorCount() const VL_MT_SAFE { return m_s.m_errorCount; }
/// Set number of errors/assertions before stop
void errorLimit(int val) VL_MT_SAFE;
/// Return number of errors/assertions before stop
int errorLimit() const VL_MT_SAFE { return m_s.m_errorLimit; }
/// Set to throw fatal error on $stop/non-fatal error
void fatalOnError(bool flag) VL_MT_SAFE;
/// Set number of errors/assertions before stop
void errorLimit(int val) VL_MT_SAFE;
/// Return if to throw fatal error on $stop/non-fatal
bool fatalOnError() const VL_MT_SAFE { return m_s.m_fatalOnError; }
/// Set to throw fatal error on VPI errors
void fatalOnVpiError(bool flag) VL_MT_SAFE;
/// Set to throw fatal error on $stop/non-fatal error
void fatalOnError(bool flag) VL_MT_SAFE;
/// Return if to throw fatal error on VPI errors
bool fatalOnVpiError() const VL_MT_SAFE { return m_s.m_fatalOnVpiError; }
/// Set if got a $stop or non-fatal error
void gotError(bool flag) VL_MT_SAFE;
/// Set to throw fatal error on VPI errors
void fatalOnVpiError(bool flag) VL_MT_SAFE;
/// Return if got a $stop or non-fatal error
bool gotError() const VL_MT_SAFE { return m_s.m_gotError; }
/// Set if got a $finish or $stop/error
void gotFinish(bool flag) VL_MT_SAFE;
/// Set if got a $stop or non-fatal error
void gotError(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;
/// Set if got a $finish or $stop/error
void gotFinish(bool flag) VL_MT_SAFE;
/// Return if quiet enabled
bool quiet() const VL_MT_SAFE { return m_s.m_quiet; }
/// Enable quiet (also prevents need for OS calls to get CPU time)
void quiet(bool flag) VL_MT_SAFE;
/// Return randReset value
int randReset() VL_MT_SAFE { return m_s.m_randReset; }
/// Select initial value of otherwise uninitialized signals.
/// 0 = Set to zeros
/// 1 = Set all bits to one
/// 2 = Randomize all bits
void randReset(int val) VL_MT_SAFE;
/// Return randReset value
int randReset() VL_MT_SAFE { return m_s.m_randReset; }
/// Return default random seed
void randSeed(int val) VL_MT_SAFE;
/// Set default random seed, 0 = seed it automatically
int randSeed() const VL_MT_SAFE { return m_s.m_randSeed; }
/// Return default random seed
void randSeed(int val) VL_MT_SAFE;
/// Return statistic: CPU time delta from model created until now
double statCpuTimeSinceStart() const VL_MT_SAFE_EXCLUDES(m_mutex);
@@ -607,27 +641,27 @@ public:
enableExecutionProfiler(VerilatedVirtualBase* (*construct)(VerilatedContext&));
// Internal: coverage
void coverageFilename(const std::string& flag) VL_MT_SAFE;
std::string coverageFilename() const VL_MT_SAFE;
void coverageFilename(const std::string& flag) 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);
void dumpfile(const std::string& flag) VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
std::string dumpfileCheck() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
// Internal: --prof-exec related settings
void profExecStart(uint64_t flag) VL_MT_SAFE;
uint64_t profExecStart() const VL_MT_SAFE { return m_ns.m_profExecStart; }
void profExecWindow(uint64_t flag) VL_MT_SAFE;
void profExecStart(uint64_t flag) VL_MT_SAFE;
uint32_t profExecWindow() const VL_MT_SAFE { return m_ns.m_profExecWindow; }
void profExecFilename(const std::string& flag) VL_MT_SAFE;
void profExecWindow(uint64_t flag) VL_MT_SAFE;
std::string profExecFilename() const VL_MT_SAFE;
void profVltFilename(const std::string& flag) VL_MT_SAFE;
void profExecFilename(const std::string& flag) VL_MT_SAFE;
std::string profVltFilename() const VL_MT_SAFE;
void profVltFilename(const std::string& flag) VL_MT_SAFE;
// Internal: SMT solver program
void solverProgram(const std::string& flag) VL_MT_SAFE;
std::string solverProgram() const VL_MT_SAFE;
void solverProgram(const std::string& flag) VL_MT_SAFE;
// Internal: Find scope
const VerilatedScope* scopeFind(const char* namep) const VL_MT_SAFE;
@@ -762,8 +796,6 @@ class Verilated final {
public:
// METHODS - User called
/// Enable debug of internal verilated code
static void debug(int level) VL_MT_SAFE;
#ifdef VL_DEBUG
/// Return debug level
/// When multithreaded this may not immediately react to another thread
@@ -773,6 +805,8 @@ public:
/// Return constant 0 debug level, so C++'s optimizer rips up
static constexpr int debug() VL_PURE { return 0; }
#endif
/// Enable debug of internal verilated code
static void debug(int level) VL_MT_SAFE;
/// Set the last VerilatedContext accessed
/// Generally threadContextp(value) should be called instead
@@ -804,18 +838,18 @@ public:
}
#ifndef VL_NO_LEGACY
/// Call VerilatedContext::assertOn using current thread's VerilatedContext
static void assertOn(bool flag) VL_MT_SAFE { Verilated::threadContextp()->assertOn(flag); }
/// Return VerilatedContext::assertOn() using current thread's VerilatedContext
static bool assertOn() VL_MT_SAFE { return Verilated::threadContextp()->assertOn(); }
/// Call VerilatedContext::calcUnusedSigs using current thread's VerilatedContext
static void calcUnusedSigs(bool flag) VL_MT_SAFE {
Verilated::threadContextp()->calcUnusedSigs(flag);
}
/// Call VerilatedContext::assertOn using current thread's VerilatedContext
static void assertOn(bool flag) VL_MT_SAFE { Verilated::threadContextp()->assertOn(flag); }
/// Return VerilatedContext::calcUnusedSigs using current thread's VerilatedContext
static bool calcUnusedSigs() VL_MT_SAFE {
return Verilated::threadContextp()->calcUnusedSigs();
}
/// Call VerilatedContext::calcUnusedSigs using current thread's VerilatedContext
static void calcUnusedSigs(bool flag) VL_MT_SAFE {
Verilated::threadContextp()->calcUnusedSigs(flag);
}
/// Call VerilatedContext::commandArgs using current thread's VerilatedContext
static void commandArgs(int argc, const char** argv) VL_MT_SAFE {
Verilated::threadContextp()->commandArgs(argc, argv);
@@ -831,44 +865,44 @@ public:
static const char* commandArgsPlusMatch(const char* prefixp) VL_MT_SAFE {
return Verilated::threadContextp()->commandArgsPlusMatch(prefixp);
}
/// Call VerilatedContext::errorLimit using current thread's VerilatedContext
static void errorLimit(int val) VL_MT_SAFE { Verilated::threadContextp()->errorLimit(val); }
/// Return VerilatedContext::errorLimit using current thread's VerilatedContext
static int errorLimit() VL_MT_SAFE { return Verilated::threadContextp()->errorLimit(); }
/// Call VerilatedContext::errorLimit using current thread's VerilatedContext
static void errorLimit(int val) VL_MT_SAFE { Verilated::threadContextp()->errorLimit(val); }
/// Return VerilatedContext::fatalOnError using current thread's VerilatedContext
static bool fatalOnError() VL_MT_SAFE { return Verilated::threadContextp()->fatalOnError(); }
/// Call VerilatedContext::fatalOnError using current thread's VerilatedContext
static void fatalOnError(bool flag) VL_MT_SAFE {
Verilated::threadContextp()->fatalOnError(flag);
}
/// Return VerilatedContext::fatalOnError using current thread's VerilatedContext
static bool fatalOnError() VL_MT_SAFE { return Verilated::threadContextp()->fatalOnError(); }
/// Call VerilatedContext::fatalOnVpiError using current thread's VerilatedContext
static void fatalOnVpiError(bool flag) VL_MT_SAFE {
Verilated::threadContextp()->fatalOnVpiError(flag);
}
/// Return VerilatedContext::fatalOnVpiError using current thread's VerilatedContext
static bool fatalOnVpiError() VL_MT_SAFE {
return Verilated::threadContextp()->fatalOnVpiError();
}
/// Call VerilatedContext::gotError using current thread's VerilatedContext
static void gotError(bool flag) VL_MT_SAFE { Verilated::threadContextp()->gotError(flag); }
/// Call VerilatedContext::fatalOnVpiError using current thread's VerilatedContext
static void fatalOnVpiError(bool flag) VL_MT_SAFE {
Verilated::threadContextp()->fatalOnVpiError(flag);
}
/// Return VerilatedContext::gotError using current thread's VerilatedContext
static bool gotError() VL_MT_SAFE { return Verilated::threadContextp()->gotError(); }
/// Call VerilatedContext::gotFinish using current thread's VerilatedContext
static void gotFinish(bool flag) VL_MT_SAFE { Verilated::threadContextp()->gotFinish(flag); }
/// Call VerilatedContext::gotError using current thread's VerilatedContext
static void gotError(bool flag) VL_MT_SAFE { Verilated::threadContextp()->gotError(flag); }
/// Return VerilatedContext::gotFinish using current thread's VerilatedContext
static bool gotFinish() VL_MT_SAFE { return Verilated::threadContextp()->gotFinish(); }
/// Call VerilatedContext::randReset using current thread's VerilatedContext
static void randReset(int val) VL_MT_SAFE { Verilated::threadContextp()->randReset(val); }
/// Call VerilatedContext::gotFinish using current thread's VerilatedContext
static void gotFinish(bool flag) VL_MT_SAFE { Verilated::threadContextp()->gotFinish(flag); }
/// Return VerilatedContext::randReset using current thread's VerilatedContext
static int randReset() VL_MT_SAFE { return Verilated::threadContextp()->randReset(); }
/// Call VerilatedContext::randSeed using current thread's VerilatedContext
static void randSeed(int val) VL_MT_SAFE { Verilated::threadContextp()->randSeed(val); }
/// Call VerilatedContext::randReset using current thread's VerilatedContext
static void randReset(int val) VL_MT_SAFE { Verilated::threadContextp()->randReset(val); }
/// Return VerilatedContext::randSeed using current thread's VerilatedContext
static int randSeed() VL_MT_SAFE { return Verilated::threadContextp()->randSeed(); }
/// Call VerilatedContext::time using current thread's VerilatedContext
static void time(uint64_t val) VL_MT_SAFE { Verilated::threadContextp()->time(val); }
/// Call VerilatedContext::randSeed using current thread's VerilatedContext
static void randSeed(int val) VL_MT_SAFE { Verilated::threadContextp()->randSeed(val); }
/// Return VerilatedContext::time using current thread's VerilatedContext
static uint64_t time() VL_MT_SAFE { return Verilated::threadContextp()->time(); }
/// Call VerilatedContext::time using current thread's VerilatedContext
static void time(uint64_t val) VL_MT_SAFE { Verilated::threadContextp()->time(val); }
/// Call VerilatedContext::timeInc using current thread's VerilatedContext
static void timeInc(uint64_t add) VL_MT_UNSAFE { Verilated::threadContextp()->timeInc(add); }
// Deprecated
@@ -958,8 +992,8 @@ public:
// Internal: Set the mtaskId, called when an mtask starts
// Per thread, so no need to be in VerilatedContext
static void mtaskId(uint32_t id) VL_MT_SAFE { t_s.t_mtaskId = id; }
static uint32_t mtaskId() VL_MT_SAFE { return t_s.t_mtaskId; }
static void mtaskId(uint32_t id) VL_MT_SAFE { t_s.t_mtaskId = id; }
static void endOfEvalReqdInc() VL_MT_SAFE { ++t_s.t_endOfEvalReqd; }
static void endOfEvalReqdDec() VL_MT_SAFE { --t_s.t_endOfEvalReqd; }
+1
View File
@@ -80,6 +80,7 @@ VK_CPPFLAGS_ALWAYS += \
-I$(VERILATOR_ROOT)/include/vltstd \
-DVM_COVERAGE=$(VM_COVERAGE) \
-DVM_SC=$(VM_SC) \
-DVM_TIMING=$(VM_TIMING) \
-DVM_TRACE=$(VM_TRACE) \
-DVM_TRACE_FST=$(VM_TRACE_FST) \
-DVM_TRACE_VCD=$(VM_TRACE_VCD) \
+2 -2
View File
@@ -93,8 +93,8 @@ public:
/// 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 std::string& filename) VL_MT_SAFE;
void write() VL_MT_SAFE { write(defaultFilename()); }
void write(const std::string& filename) VL_MT_SAFE;
/// Clear coverage points (and call delete on all items)
void clear() VL_MT_SAFE;
/// Clear items not matching the provided string
@@ -165,8 +165,8 @@ public:
/// Return default filename for the current thread
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 std::string& filename) VL_MT_SAFE { threadCovp()->write(filename); }
static void write() VL_MT_SAFE { write(defaultFilename()); }
static void write(const std::string& filename) VL_MT_SAFE { threadCovp()->write(filename); }
/// 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
+18 -3
View File
@@ -127,6 +127,7 @@ void VerilatedFst::declDTypeEnum(int dtypenum, const char* name, uint32_t elemen
// TODO: should return std::optional<fstScopeType>, but I can't have C++17
static std::pair<bool, fstScopeType> toFstScopeType(VerilatedTracePrefixType type) {
switch (type) {
case VerilatedTracePrefixType::ROOTIO_MODULE: return {true, FST_ST_VCD_MODULE};
case VerilatedTracePrefixType::SCOPE_MODULE: return {true, FST_ST_VCD_MODULE};
case VerilatedTracePrefixType::SCOPE_INTERFACE: return {true, FST_ST_VCD_INTERFACE};
case VerilatedTracePrefixType::STRUCT_PACKED:
@@ -137,7 +138,20 @@ static std::pair<bool, fstScopeType> toFstScopeType(VerilatedTracePrefixType typ
}
void VerilatedFst::pushPrefix(const std::string& name, VerilatedTracePrefixType type) {
const std::string newPrefix = m_prefixStack.back().first + name;
assert(!m_prefixStack.empty()); // Constructor makes an empty entry
std::string pname = name;
// An empty name means this is the root of a model created with name()=="". The
// tools get upset if we try to pass this as empty, so we put the signals under a
// new scope, but the signals further down will be peers, not children (as usual
// for name()!="")
// Terminate earlier $root?
if (m_prefixStack.back().second == VerilatedTracePrefixType::ROOTIO_MODULE) popPrefix();
if (pname.empty()) { // Start new temporary root
pname = "$rootio"; // VCD names are not backslash escaped
m_prefixStack.emplace_back("", VerilatedTracePrefixType::ROOTIO_WRAPPER);
type = VerilatedTracePrefixType::ROOTIO_MODULE;
}
const std::string newPrefix = m_prefixStack.back().first + pname;
const auto pair = toFstScopeType(type);
const bool properScope = pair.first;
const fstScopeType scopeType = pair.second;
@@ -149,10 +163,11 @@ void VerilatedFst::pushPrefix(const std::string& name, VerilatedTracePrefixType
}
void VerilatedFst::popPrefix() {
assert(!m_prefixStack.empty());
const bool properScope = toFstScopeType(m_prefixStack.back().second).first;
if (properScope) fstWriterSetUpscope(m_fst);
m_prefixStack.pop_back();
assert(!m_prefixStack.empty());
assert(!m_prefixStack.empty()); // Always one left, the constructor's initial one
}
void VerilatedFst::declare(uint32_t code, const char* name, int dtypenum,
@@ -294,7 +309,7 @@ void VerilatedFst::configure(const VerilatedTraceConfig& config) {
// so always inline them.
VL_ATTR_ALWINLINE
void VerilatedFstBuffer::emitEvent(uint32_t code, const VlEventBase* newval) {
void VerilatedFstBuffer::emitEvent(uint32_t code) {
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
fstWriterEmitValueChange(m_fst, m_symbolp[code], "1");
}
+2 -2
View File
@@ -47,7 +47,7 @@ private:
friend VerilatedFstBuffer; // Give the buffer access to the private bits
//=========================================================================
// FST specific internals
// FST-specific internals
void* m_fst = nullptr;
std::map<uint32_t, vlFstHandle> m_code2symbol;
@@ -177,7 +177,7 @@ class VerilatedFstBuffer VL_NOT_FINAL {
// Implementations of duck-typed methods for VerilatedTraceBuffer. These are
// called from only one place (the full* methods), so always inline them.
VL_ATTR_ALWINLINE void emitEvent(uint32_t code, const VlEventBase* newval);
VL_ATTR_ALWINLINE void emitEvent(uint32_t code);
VL_ATTR_ALWINLINE void emitBit(uint32_t code, CData newval);
VL_ATTR_ALWINLINE void emitCData(uint32_t code, CData newval, int bits);
VL_ATTR_ALWINLINE void emitSData(uint32_t code, SData newval, int bits);
+347 -28
View File
@@ -42,19 +42,20 @@ extern void vl_finish(const char* filename, int linenum, const char* hier) VL_MT
/// Routine to call for $stop and non-fatal error
/// User code may wish to replace this function, to do so, define VL_USER_STOP.
/// This code does not have to be thread safe.
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
/// Verilator internal code must call VL_STOP_MT instead, which eventually calls this.
extern void vl_stop(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE;
/// Routine to call for fatal messages
/// User code may wish to replace this function, to do so, define VL_USER_FATAL.
/// This code does not have to be thread safe.
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
/// Verilator internal code must call VL_FATAL_MT instead, which eventually calls this.
extern void vl_fatal(const char* filename, int linenum, const char* hier,
const char* msg) VL_MT_UNSAFE;
/// Routine to call for warning messages
/// User code may wish to replace this function, to do so, define VL_USER_WARN.
/// This code does not have to be thread safe.
/// Verilator internal code must call VL_WARN_MT instead, which eventually calls this.
extern void vl_warn(const char* filename, int linenum, const char* hier,
const char* msg) VL_MT_UNSAFE;
@@ -106,6 +107,14 @@ extern IData VL_RAND_RESET_I(int obits) VL_MT_SAFE;
extern QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE;
/// Random reset a signal of given width (init time only)
extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE;
/// Random reset a signal of given width (assign time only)
extern IData VL_RAND_RESET_ASSIGN_I(int obits) VL_MT_SAFE;
/// Random reset a signal of given width (assign time only)
extern QData VL_RAND_RESET_ASSIGN_Q(int obits) VL_MT_SAFE;
/// Random reset a signal of given width (assign time only)
extern WDataOutP VL_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp) VL_MT_SAFE;
/// Zero reset a signal (slow - else use VL_ZERO_W)
extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE;
@@ -1577,49 +1586,184 @@ static inline WDataOutP VL_STREAML_WWI(int lbits, WDataOutP owp, WDataInP const
return owp;
}
template <typename T>
static inline void VL_ASSIGN_DYN_Q(VlQueue<T>& q, int elem_size, int lbits, QData from) {
const int size = (lbits + elem_size - 1) / elem_size;
q.renew(size);
const QData mask = VL_MASK_Q(elem_size);
for (int i = 0; i < size; ++i) q.at(i) = (T)((from >> (i * elem_size)) & mask);
static inline IData VL_PACK_II(int obits, int lbits, const VlQueue<CData>& q) {
IData ret = 0;
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<IData>(q.at(i)) << (i * lbits);
return ret;
}
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);
static inline IData VL_PACK_II(int obits, int lbits, const VlQueue<SData>& q) {
IData ret = 0;
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<IData>(q.at(i)) << (i * lbits);
return ret;
}
static inline IData VL_PACK_II(int obits, int lbits, const VlQueue<IData>& q) {
IData ret = 0;
for (size_t i = 0; i < q.size(); ++i) ret |= q.at(i) << (i * lbits);
return ret;
}
template <std::size_t T_Depth>
static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked<CData, T_Depth>& q) {
IData ret = 0;
for (size_t i = 0; i < T_Depth; ++i)
q[i] = (T)((from >> ((T_Depth - 1 - i) * elem_size)) & mask);
ret |= static_cast<IData>(q[T_Depth - 1 - i]) << (i * lbits);
return ret;
}
template <typename T>
static inline IData VL_DYN_TO_I(const VlQueue<T>& q, int elem_size) {
template <std::size_t T_Depth>
static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked<SData, T_Depth>& q) {
IData ret = 0;
for (int i = 0; i < q.size(); ++i) ret |= q.at(i) << (i * elem_size);
for (size_t i = 0; i < T_Depth; ++i)
ret |= static_cast<IData>(q[T_Depth - 1 - i]) << (i * lbits);
return ret;
}
template <typename T>
static inline QData VL_DYN_TO_Q(const VlQueue<T>& q, int elem_size) {
QData ret = 0;
for (int i = 0; i < q.size(); ++i) ret |= q.at(i) << (i * 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) {
template <std::size_t T_Depth>
static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked<IData, T_Depth>& q) {
IData ret = 0;
for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * elem_size);
for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * lbits);
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) {
static inline QData VL_PACK_QI(int obits, int lbits, const VlQueue<CData>& q) {
QData ret = 0;
for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * elem_size);
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<QData>(q.at(i)) << (i * lbits);
return ret;
}
static inline QData VL_PACK_QI(int obits, int lbits, const VlQueue<SData>& q) {
QData ret = 0;
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<QData>(q.at(i)) << (i * lbits);
return ret;
}
static inline QData VL_PACK_QI(int obits, int lbits, const VlQueue<IData>& q) {
QData ret = 0;
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<QData>(q.at(i)) << (i * lbits);
return ret;
}
template <std::size_t T_Depth>
static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked<CData, T_Depth>& q) {
QData ret = 0;
for (size_t i = 0; i < T_Depth; ++i)
ret |= static_cast<QData>(q[T_Depth - 1 - i]) << (i * lbits);
return ret;
}
template <std::size_t T_Depth>
static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked<SData, T_Depth>& q) {
QData ret = 0;
for (size_t i = 0; i < T_Depth; ++i)
ret |= static_cast<QData>(q[T_Depth - 1 - i]) << (i * lbits);
return ret;
}
template <std::size_t T_Depth>
static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked<IData, T_Depth>& q) {
QData ret = 0;
for (size_t i = 0; i < T_Depth; ++i)
ret |= static_cast<QData>(q[T_Depth - 1 - i]) << (i * lbits);
return ret;
}
static inline QData VL_PACK_QQ(int obits, int lbits, const VlQueue<QData>& q) {
QData ret = 0;
for (size_t i = 0; i < q.size(); ++i) ret |= q.at(i) << (i * lbits);
return ret;
}
template <std::size_t T_Depth>
static inline QData VL_PACK_QQ(int obits, int lbits, const VlUnpacked<QData, T_Depth>& q) {
QData ret = 0;
for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * lbits);
return ret;
}
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, const VlQueue<CData>& q) {
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
for (size_t i = 0; i < q.size(); ++i)
_vl_insert_WI(owp, q.at(i), i * lbits + lbits - 1, i * lbits);
return owp;
}
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, const VlQueue<SData>& q) {
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
for (size_t i = 0; i < q.size(); ++i)
_vl_insert_WI(owp, q.at(i), i * lbits + lbits - 1, i * lbits);
return owp;
}
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, const VlQueue<IData>& q) {
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
for (size_t i = 0; i < q.size(); ++i)
_vl_insert_WI(owp, q.at(i), i * lbits + lbits - 1, i * lbits);
return owp;
}
template <std::size_t T_Depth>
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp,
const VlUnpacked<CData, T_Depth>& q) {
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
for (size_t i = 0; i < T_Depth; ++i)
_vl_insert_WI(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits);
return owp;
}
template <std::size_t T_Depth>
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp,
const VlUnpacked<SData, T_Depth>& q) {
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
for (size_t i = 0; i < T_Depth; ++i)
_vl_insert_WI(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits);
return owp;
}
template <std::size_t T_Depth>
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp,
const VlUnpacked<IData, T_Depth>& q) {
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
for (size_t i = 0; i < T_Depth; ++i)
_vl_insert_WI(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits);
return owp;
}
static inline WDataOutP VL_PACK_WQ(int obits, int lbits, WDataOutP owp, const VlQueue<QData>& q) {
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
for (size_t i = 0; i < q.size(); ++i)
_vl_insert_WQ(owp, q.at(i), i * lbits + lbits - 1, i * lbits);
return owp;
}
template <std::size_t T_Depth>
static inline WDataOutP VL_PACK_WQ(int obits, int lbits, WDataOutP owp,
const VlUnpacked<QData, T_Depth>& q) {
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
for (size_t i = 0; i < T_Depth; ++i)
_vl_insert_WQ(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits);
return owp;
}
template <std::size_t N>
static inline WDataOutP VL_PACK_WW(int obits, int lbits, WDataOutP owp,
const VlQueue<VlWide<N>>& q) {
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
for (size_t i = 0; i < q.size(); ++i)
_vl_insert_WW(owp, q.at(i), i * lbits + lbits - 1, i * lbits);
return owp;
}
template <std::size_t T_Depth, std::size_t N>
static inline WDataOutP VL_PACK_WW(int obits, int lbits, WDataOutP owp,
const VlUnpacked<VlWide<N>, T_Depth>& q) {
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
for (size_t i = 0; i < T_Depth; ++i)
_vl_insert_WW(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits);
return owp;
}
// 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.
@@ -2059,6 +2203,181 @@ static inline WDataOutP VL_SEL_WWII(int obits, int lbits, WDataOutP owp, WDataIn
//======================================================================
// Expressions needing insert/select
static inline void VL_UNPACK_II(int lbits, int rbits, VlQueue<CData>& q, IData from) {
const size_t size = (rbits + lbits - 1) / lbits;
q.renew(size);
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < size; ++i) q.atWrite(i) = (from >> (i * lbits)) & mask;
}
static inline void VL_UNPACK_II(int lbits, int rbits, VlQueue<SData>& q, IData from) {
const size_t size = (rbits + lbits - 1) / lbits;
q.renew(size);
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < size; ++i) q.atWrite(i) = (from >> (i * lbits)) & mask;
}
static inline void VL_UNPACK_II(int lbits, int rbits, VlQueue<IData>& q, IData from) {
const size_t size = (rbits + lbits - 1) / lbits;
q.renew(size);
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < size; ++i) q.atWrite(i) = (from >> (i * lbits)) & mask;
}
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlQueue<CData>& q, QData from) {
const size_t size = (rbits + lbits - 1) / lbits;
q.renew(size);
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < size; ++i) q.atWrite(i) = (from >> (i * lbits)) & mask;
}
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlQueue<SData>& q, QData from) {
const size_t size = (rbits + lbits - 1) / lbits;
q.renew(size);
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < size; ++i) q.atWrite(i) = (from >> (i * lbits)) & mask;
}
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlQueue<IData>& q, QData from) {
const size_t size = (rbits + lbits - 1) / lbits;
q.renew(size);
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < size; ++i) q.atWrite(i) = (from >> (i * lbits)) & mask;
}
static inline void VL_UNPACK_QQ(int lbits, int rbits, VlQueue<QData>& q, QData from) {
const size_t size = (rbits + lbits - 1) / lbits;
q.renew(size);
const QData mask = VL_MASK_Q(lbits);
for (size_t i = 0; i < size; ++i) q.atWrite(i) = (from >> (i * lbits)) & mask;
}
static inline void VL_UNPACK_IW(int lbits, int rbits, VlQueue<CData>& q, WDataInP rwp) {
const int size = (rbits + lbits - 1) / lbits;
q.renew(size);
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < size; ++i) {
q.atWrite(i) = VL_SEL_IWII(rbits, rwp, i * lbits, lbits) & mask;
}
}
static inline void VL_UNPACK_IW(int lbits, int rbits, VlQueue<SData>& q, WDataInP rwp) {
const int size = (rbits + lbits - 1) / lbits;
q.renew(size);
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < size; ++i) {
q.atWrite(i) = VL_SEL_IWII(rbits, rwp, i * lbits, lbits) & mask;
}
}
static inline void VL_UNPACK_IW(int lbits, int rbits, VlQueue<IData>& q, WDataInP rwp) {
const int size = (rbits + lbits - 1) / lbits;
q.renew(size);
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < size; ++i) {
q.atWrite(i) = VL_SEL_IWII(rbits, rwp, i * lbits, lbits) & mask;
}
}
static inline void VL_UNPACK_QW(int lbits, int rbits, VlQueue<QData>& q, WDataInP rwp) {
const int size = (rbits + lbits - 1) / lbits;
q.renew(size);
const QData mask = VL_MASK_Q(lbits);
for (size_t i = 0; i < size; ++i) {
q.atWrite(i) = VL_SEL_QWII(rbits, rwp, i * lbits, lbits) & mask;
}
}
template <std::size_t N>
static inline void VL_UNPACK_WW(int lbits, int rbits, VlQueue<VlWide<N>>& q, WDataInP rwp) {
const int size = (rbits + lbits - 1) / lbits;
q.renew(size);
for (size_t i = 0; i < size; ++i) {
VL_SEL_WWII(lbits, rbits, q.atWrite(i), rwp, i * lbits, lbits);
}
}
template <std::size_t T_Depth>
static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked<CData, T_Depth>& q, IData from) {
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
}
template <std::size_t T_Depth>
static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked<SData, T_Depth>& q, IData from) {
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
}
template <std::size_t T_Depth>
static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked<IData, T_Depth>& q, IData from) {
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
}
template <std::size_t T_Depth>
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked<CData, T_Depth>& q, QData from) {
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
}
template <std::size_t T_Depth>
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked<SData, T_Depth>& q, QData from) {
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
}
template <std::size_t T_Depth>
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked<IData, T_Depth>& q, QData from) {
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
}
template <std::size_t T_Depth>
static inline void VL_UNPACK_QQ(int lbits, int rbits, VlUnpacked<QData, T_Depth>& q, QData from) {
const QData mask = VL_MASK_Q(lbits);
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
}
template <std::size_t T_Depth>
static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked<CData, T_Depth>& q,
WDataInP rwp) {
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < T_Depth; ++i)
q[i] = VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask;
}
template <std::size_t T_Depth>
static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked<SData, T_Depth>& q,
WDataInP rwp) {
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < T_Depth; ++i)
q[i] = VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask;
}
template <std::size_t T_Depth>
static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked<IData, T_Depth>& q,
WDataInP rwp) {
const IData mask = VL_MASK_I(lbits);
for (size_t i = 0; i < T_Depth; ++i)
q[i] = VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask;
}
template <std::size_t T_Depth>
static inline void VL_UNPACK_QW(int lbits, int rbits, VlUnpacked<QData, T_Depth>& q,
WDataInP rwp) {
const QData mask = VL_MASK_Q(lbits);
for (size_t i = 0; i < T_Depth; ++i)
q[i] = VL_SEL_QWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask;
}
template <std::size_t T_Depth, std::size_t N>
static inline void VL_UNPACK_WW(int lbits, int rbits, VlUnpacked<VlWide<N>, T_Depth>& q,
WDataInP rwp) {
for (size_t i = 0; i < T_Depth; ++i)
VL_SEL_WWII(lbits, rbits, q[i], rwp, (T_Depth - 1 - i) * lbits, lbits);
}
// Return QData from double (numeric)
// EMIT_RULE: VL_RTOIROUND_Q_D: oclean=dirty; lclean==clean/real
static inline QData VL_RTOIROUND_Q_D(double lhs) VL_PURE {
+3 -3
View File
@@ -12,13 +12,13 @@
//*************************************************************************
///
/// \file
/// \brief Verilator common target specific intrinsics header
/// \brief Verilator common target-specific intrinsics header
///
/// This file is not part of the Verilated public-facing API.
///
/// It is only for internal use; code using machine specific intrinsics for
/// It is only for internal use; code using machine-specific intrinsics for
/// optimization should include this header rather than directly including
/// he target specific headers. We provide macros to check for availability
/// the target-specific headers. We provide macros to check for availability
/// of instruction sets, and a common mechanism to disable them.
///
//*************************************************************************
+141 -59
View File
@@ -230,7 +230,7 @@ static Process& getSolver() {
const char* const* const cmd = &s_argv[0];
s_solver.open(cmd);
s_solver << "(set-logic QF_BV)\n";
s_solver << "(set-logic QF_ABV)\n";
s_solver << "(check-sat)\n";
s_solver << "(reset)\n";
std::string s;
@@ -250,32 +250,78 @@ static Process& getSolver() {
return s_solver;
}
std::string readUntilBalanced(std::istream& stream) {
std::string result;
std::string token;
int parenCount = 1;
while (stream >> token) {
for (const char c : token) {
if (c == '(') {
++parenCount;
} else if (c == ')') {
--parenCount;
}
}
result += token + " ";
if (parenCount == 0) break;
}
return result;
}
std::string parseNestedSelect(const std::string& nested_select_expr,
std::vector<std::string>& indices) {
std::istringstream nestedStream(nested_select_expr);
std::string name, idx;
nestedStream >> name;
if (name == "(select") {
const std::string further_nested_expr = readUntilBalanced(nestedStream);
name = parseNestedSelect(further_nested_expr, indices);
}
std::getline(nestedStream, idx, ')');
indices.push_back(idx);
return name;
}
std::string flattenIndices(const std::vector<std::string>& indices, const VlRandomVar* const var) {
int flattenedIndex = 0;
int multiplier = 1;
for (int i = indices.size() - 1; i >= 0; --i) {
int indexValue = 0;
std::string trimmedIndex = indices[i];
trimmedIndex.erase(0, trimmedIndex.find_first_not_of(" \t"));
trimmedIndex.erase(trimmedIndex.find_last_not_of(" \t") + 1);
if (trimmedIndex.find("#x") == 0) {
indexValue = std::strtoul(trimmedIndex.substr(2).c_str(), nullptr, 16);
} else if (trimmedIndex.find("#b") == 0) {
indexValue = std::strtoul(trimmedIndex.substr(2).c_str(), nullptr, 2);
} else {
indexValue = std::strtoul(trimmedIndex.c_str(), nullptr, 10);
}
const int length = var->getLength(i);
if (length == -1) {
VL_WARN_MT(__FILE__, __LINE__, "randomize",
"Internal: Wrong Call: Only RandomArray can call getLength()");
break;
}
flattenedIndex += indexValue * multiplier;
multiplier *= length;
}
std::string hexString = std::to_string(flattenedIndex);
while (hexString.size() < 8) { hexString.insert(0, "0"); }
return "#x" + hexString;
}
//======================================================================
// VlRandomizer:: Methods
void VlRandomVar::emit(std::ostream& s) const { s << m_name; }
void VlRandomConst::emit(std::ostream& s) const {
s << "#b";
for (int i = 0; i < m_width; i++) s << (VL_BITISSET_Q(m_val, m_width - i - 1) ? '1' : '0');
void VlRandomVar::emitGetValue(std::ostream& s) const { s << ' ' << m_name; }
void VlRandomVar::emitExtract(std::ostream& s, int i) const {
s << " ((_ extract " << i << ' ' << i << ") " << m_name << ')';
}
void VlRandomBinOp::emit(std::ostream& s) const {
s << '(' << m_op << ' ';
m_lhs->emit(s);
s << ' ';
m_rhs->emit(s);
s << ')';
}
void VlRandomExtract::emit(std::ostream& s) const {
s << "((_ extract " << m_idx << ' ' << m_idx << ") ";
m_expr->emit(s);
s << ')';
}
bool VlRandomVar::set(std::string&& val) const {
VlWide<VL_WQ_WORDS_E> qowp;
VL_SET_WQ(qowp, 0ULL);
WDataOutP owp = qowp;
int obits = width();
if (obits > VL_QUADSIZE) owp = reinterpret_cast<WDataOutP>(datap());
void VlRandomVar::emitType(std::ostream& s) const { s << "(_ BitVec " << width() << ')'; }
int VlRandomVar::totalWidth() const { return m_width; }
static bool parseSMTNum(int obits, WDataOutP owp, const std::string& val) {
int i;
for (i = 0; val[i] && val[i] != '#'; i++) {}
if (val[i++] != '#') return false;
@@ -289,17 +335,31 @@ bool VlRandomVar::set(std::string&& val) const {
"Internal: Unable to parse solver's randomized number");
return false;
}
return true;
}
bool VlRandomVar::set(const std::string& idx, const std::string& val) const {
VlWide<VL_WQ_WORDS_E> qowp;
VL_SET_WQ(qowp, 0ULL);
WDataOutP owp = qowp;
const int obits = width();
VlWide<VL_WQ_WORDS_E> qiwp;
VL_SET_WQ(qiwp, 0ULL);
if (!idx.empty() && !parseSMTNum(64, qiwp, idx)) return false;
const int nidx = qiwp[0];
if (obits > VL_QUADSIZE) owp = reinterpret_cast<WDataOutP>(datap(nidx));
if (!parseSMTNum(obits, owp, val)) return false;
if (obits <= VL_BYTESIZE) {
CData* const p = static_cast<CData*>(datap());
CData* const p = static_cast<CData*>(datap(nidx));
*p = VL_CLEAN_II(obits, obits, owp[0]);
} else if (obits <= VL_SHORTSIZE) {
SData* const p = static_cast<SData*>(datap());
SData* const p = static_cast<SData*>(datap(nidx));
*p = VL_CLEAN_II(obits, obits, owp[0]);
} else if (obits <= VL_IDATASIZE) {
IData* const p = static_cast<IData*>(datap());
IData* const p = static_cast<IData*>(datap(nidx));
*p = VL_CLEAN_II(obits, obits, owp[0]);
} else if (obits <= VL_QUADSIZE) {
QData* const p = static_cast<QData*>(datap());
QData* const p = static_cast<QData*>(datap(nidx));
*p = VL_CLEAN_QQ(obits, obits, VL_SET_QW(owp));
} else {
_vl_clean_inplace_w(obits, owp);
@@ -307,27 +367,31 @@ bool VlRandomVar::set(std::string&& val) const {
return true;
}
std::shared_ptr<const VlRandomExpr> VlRandomizer::randomConstraint(VlRNG& rngr, int bits) {
unsigned long long hash = VL_RANDOM_RNG_I(rngr) & ((1 << bits) - 1);
std::shared_ptr<const VlRandomExpr> concat = nullptr;
std::vector<std::shared_ptr<const VlRandomExpr>> varbits;
for (const auto& var : m_vars) {
for (int i = 0; i < var.second->width(); i++)
varbits.emplace_back(std::make_shared<const VlRandomExtract>(var.second, i));
}
void VlRandomizer::randomConstraint(std::ostream& os, VlRNG& rngr, int bits) {
const IData hash = VL_RANDOM_RNG_I(rngr) & ((1 << bits) - 1);
int varBits = 0;
for (const auto& var : m_vars) varBits += var.second->totalWidth();
os << "(= #b";
for (int i = bits - 1; i >= 0; i--) os << (VL_BITISSET_I(hash, i) ? '1' : '0');
if (bits > 1) os << " (concat";
for (int i = 0; i < bits; i++) {
std::shared_ptr<const VlRandomExpr> bit = nullptr;
for (unsigned j = 0; j * 2 < varbits.size(); j++) {
unsigned idx = j + VL_RANDOM_RNG_I(rngr) % (varbits.size() - j);
auto sel = varbits[idx];
std::swap(varbits[idx], varbits[j]);
bit = bit == nullptr ? sel : std::make_shared<const VlRandomBinOp>("bvxor", bit, sel);
IData varBitsLeft = varBits;
IData varBitsWant = (varBits + 1) / 2;
if (varBits > 2) os << " (bvxor";
for (const auto& var : m_vars) {
for (int j = 0; j < var.second->totalWidth(); j++, varBitsLeft--) {
const bool doEmit = (VL_RANDOM_RNG_I(rngr) % varBitsLeft) < varBitsWant;
if (doEmit) {
var.second->emitExtract(os, j);
if (--varBitsWant == 0) break;
}
}
if (varBitsWant == 0) break;
}
concat = concat == nullptr ? bit
: std::make_shared<const VlRandomBinOp>("concat", concat, bit);
if (varBits > 2) os << ')';
}
return std::make_shared<const VlRandomBinOp>(
"=", concat, std::make_shared<const VlRandomConst>(hash, bits));
if (bits > 1) os << ')';
os << ')';
}
bool VlRandomizer::next(VlRNG& rngr) {
@@ -336,12 +400,17 @@ bool VlRandomizer::next(VlRNG& rngr) {
if (!f) return false;
f << "(set-option :produce-models true)\n";
f << "(set-logic QF_BV)\n";
f << "(set-logic QF_ABV)\n";
f << "(define-fun __Vbv ((b Bool)) (_ BitVec 1) (ite b #b1 #b0))\n";
f << "(define-fun __Vbool ((v (_ BitVec 1))) Bool (= #b1 v))\n";
for (const auto& var : m_vars) {
f << "(declare-fun " << var.second->name() << " () (_ BitVec " << var.second->width()
<< "))\n";
f << "(declare-fun " << var.second->name() << " () ";
var.second->emitType(f);
f << ")\n";
}
for (const std::string& constraint : m_constraints) {
f << "(assert (= #b1 " << constraint << "))\n";
}
for (const std::string& constraint : m_constraints) { f << "(assert " << constraint << ")\n"; }
f << "(check-sat)\n";
bool sat = parseSolution(f);
@@ -349,10 +418,9 @@ bool VlRandomizer::next(VlRNG& rngr) {
f << "(reset)\n";
return false;
}
for (int i = 0; i < _VL_SOLVER_HASH_LEN_TOTAL && sat; i++) {
f << "(assert ";
randomConstraint(rngr, _VL_SOLVER_HASH_LEN)->emit(f);
randomConstraint(f, rngr, _VL_SOLVER_HASH_LEN);
f << ")\n";
f << "\n(check-sat)\n";
sat = parseSolution(f);
@@ -376,7 +444,7 @@ bool VlRandomizer::parseSolution(std::iostream& f) {
}
f << "(get-value (";
for (const auto& var : m_vars) f << var.second->name() << ' ';
for (const auto& var : m_vars) var.second->emitGetValue(f);
f << "))\n";
// Quasi-parse S-expression of the form ((x #xVALUE) (y #bVALUE) (z #xVALUE))
@@ -396,17 +464,29 @@ bool VlRandomizer::parseSolution(std::iostream& f) {
"Internal: Unable to parse solver's response: invalid S-expression");
return false;
}
std::string name, value;
std::string name, idx, value;
std::vector<std::string> indices;
f >> name;
indices.clear();
if (name == "(select") {
const std::string selectExpr = readUntilBalanced(f);
name = parseNestedSelect(selectExpr, indices);
idx = indices[0];
}
std::getline(f, value, ')');
auto it = m_vars.find(name);
const auto it = m_vars.find(name);
if (it == m_vars.end()) continue;
it->second->set(std::move(value));
const VlRandomVar& varr = *it->second;
if (m_randmode && !varr.randModeIdxNone()) {
if (!(m_randmode->at(varr.randModeIdx()))) continue;
}
if (indices.size() > 1) {
const std::string flattenedIndex = flattenIndices(indices, &varr);
varr.set(flattenedIndex, value);
} else {
varr.set(idx, value);
}
}
return true;
}
@@ -414,6 +494,8 @@ void VlRandomizer::hard(std::string&& constraint) {
m_constraints.emplace_back(std::move(constraint));
}
void VlRandomizer::clear() { m_constraints.clear(); }
#ifdef VL_DEBUG
void VlRandomizer::dump() const {
for (const auto& var : m_vars) {
+167 -48
View File
@@ -27,91 +27,210 @@
#include "verilated.h"
#include <ostream>
//=============================================================================
// VlRandomExpr and subclasses represent expressions for the constraint solver.
class VlRandomExpr VL_NOT_FINAL {
public:
virtual void emit(std::ostream& s) const = 0;
};
class VlRandomVar final : public VlRandomExpr {
class VlRandomVar VL_NOT_FINAL {
const char* const m_name; // Variable name
void* const m_datap; // Reference to variable data
const int m_width; // Variable width in bits
const int m_dimension; //Variable dimension, default is 0
const std::uint32_t m_randModeIdx; // rand_mode index
public:
VlRandomVar(const char* name, int width, void* datap)
VlRandomVar(const char* name, int width, void* datap, int dimension, std::uint32_t randModeIdx)
: m_name{name}
, m_datap{datap}
, m_width{width} {}
, m_width{width}
, m_dimension{dimension}
, m_randModeIdx{randModeIdx} {}
virtual ~VlRandomVar() = default;
const char* name() const { return m_name; }
int width() const { return m_width; }
void* datap() const { return m_datap; }
bool set(std::string&&) const;
void emit(std::ostream& s) const override;
int dimension() const { return m_dimension; }
virtual void* datap(int idx) const { return m_datap; }
std::uint32_t randModeIdx() const { return m_randModeIdx; }
bool randModeIdxNone() const { return randModeIdx() == std::numeric_limits<unsigned>::max(); }
bool set(const std::string& idx, const std::string& val) const;
virtual void emitGetValue(std::ostream& s) const;
virtual void emitExtract(std::ostream& s, int i) const;
virtual void emitType(std::ostream& s) const;
virtual int totalWidth() const;
virtual int getLength(int dimension) const { return -1; }
};
class VlRandomConst final : public VlRandomExpr {
const QData m_val; // Constant value
const int m_width; // Constant width in bits
template <typename T>
class VlRandomQueueVar final : public VlRandomVar {
public:
VlRandomConst(QData val, int width)
: m_val{val}
, m_width{width} {
assert(width <= sizeof(m_val) * 8);
VlRandomQueueVar(const char* name, int width, void* datap, int dimension,
std::uint32_t randModeIdx)
: VlRandomVar{name, width, datap, dimension, randModeIdx} {}
void* datap(int idx) const override {
return &static_cast<T*>(VlRandomVar::datap(idx))->atWrite(idx);
}
void emitSelect(std::ostream& s, int i) const {
s << " (select " << name() << " #x";
for (int j = 28; j >= 0; j -= 4) s << "0123456789abcdef"[(i >> j) & 0xf];
s << ')';
}
void emitGetValue(std::ostream& s) const override {
const int length = static_cast<T*>(VlRandomVar::datap(0))->size();
for (int i = 0; i < length; i++) emitSelect(s, i);
}
void emitType(std::ostream& s) const override {
s << "(Array (_ BitVec 32) (_ BitVec " << width() << "))";
}
int totalWidth() const override {
const int length = static_cast<T*>(VlRandomVar::datap(0))->size();
return width() * length;
}
void emitExtract(std::ostream& s, int i) const override {
const int j = i / width();
i = i % width();
s << " ((_ extract " << i << ' ' << i << ')';
emitSelect(s, j);
s << ')';
}
void emit(std::ostream& s) const override;
};
class VlRandomExtract final : public VlRandomExpr {
const std::shared_ptr<const VlRandomExpr> m_expr; // Sub-expression
const unsigned m_idx; // Extracted index
template <typename T>
class VlRandomArrayVar final : public VlRandomVar {
public:
VlRandomExtract(std::shared_ptr<const VlRandomExpr> expr, unsigned idx)
: m_expr{expr}
, m_idx{idx} {}
void emit(std::ostream& s) const override;
VlRandomArrayVar(const char* name, int width, void* datap, int dimension,
std::uint32_t randModeIdx)
: VlRandomVar{name, width, datap, dimension, randModeIdx} {}
void* datap(int idx) const override {
if (idx < 0) return &static_cast<T*>(VlRandomVar::datap(0))->operator[](0);
std::vector<size_t> indices(dimension());
for (int dim = dimension() - 1; dim >= 0; --dim) {
const int length = getLength(dim);
indices[dim] = idx % length;
idx /= length;
}
return &static_cast<T*>(VlRandomVar::datap(0))->find_element(indices);
}
void emitSelect(std::ostream& s, const std::vector<int>& indices) const {
for (size_t idx = 0; idx < indices.size(); ++idx) s << "(select ";
s << name();
for (size_t idx = 0; idx < indices.size(); ++idx) {
s << " #x";
for (int j = 28; j >= 0; j -= 4) {
s << "0123456789abcdef"[(indices[idx] >> j) & 0xf];
}
s << ")";
}
}
int getLength(int dimension) const override {
const auto var = static_cast<const T*>(datap(-1));
const int lenth = var->find_length(dimension);
return lenth;
}
void emitGetValue(std::ostream& s) const override {
const int total_dimensions = dimension();
std::vector<int> lengths;
for (int dim = 0; dim < total_dimensions; dim++) {
const int len = getLength(dim);
lengths.push_back(len);
}
std::vector<int> indices(total_dimensions, 0);
while (true) {
emitSelect(s, indices);
int currentDimension = total_dimensions - 1;
while (currentDimension >= 0
&& ++indices[currentDimension] >= lengths[currentDimension]) {
indices[currentDimension] = 0;
--currentDimension;
}
if (currentDimension < 0) break;
}
}
void emitType(std::ostream& s) const override {
if (dimension() > 0) {
for (int i = 0; i < dimension(); ++i) s << "(Array (_ BitVec 32) ";
s << "(_ BitVec " << width() << ")";
for (int i = 0; i < dimension(); ++i) s << ")";
}
}
int totalWidth() const override {
int totalLength = 1;
for (int dim = 0; dim < dimension(); ++dim) {
const int length = getLength(dim);
if (length == -1) return 0;
totalLength *= length;
}
return width() * totalLength;
}
void emitExtract(std::ostream& s, int i) const override {
const int j = i / width();
i = i % width();
std::vector<int> indices(dimension());
int idx = j;
for (int dim = dimension() - 1; dim >= 0; --dim) {
int length = getLength(dim);
indices[dim] = idx % length;
idx /= length;
}
s << " ((_ extract " << i << ' ' << i << ')';
emitSelect(s, indices);
s << ')';
}
};
class VlRandomBinOp final : public VlRandomExpr {
const char* const m_op; // Binary operation identifier
const std::shared_ptr<const VlRandomExpr> m_lhs, m_rhs; // Sub-expressions
public:
VlRandomBinOp(const char* op, std::shared_ptr<const VlRandomExpr> lhs,
std::shared_ptr<const VlRandomExpr> rhs)
: m_op{op}
, m_lhs{lhs}
, m_rhs{rhs} {}
void emit(std::ostream& s) const override;
};
//=============================================================================
// VlRandomizer is the object holding constraints and variable references.
class VlRandomizer final {
// MEMBERS
std::vector<std::string> m_constraints; // Solver-dependent constraints
std::map<std::string, std::shared_ptr<const VlRandomVar>>
m_vars; // Solver-dependent variables
std::map<std::string, std::shared_ptr<const VlRandomVar>> m_vars; // Solver-dependent
// variables
const VlQueue<CData>* m_randmode; // rand_mode state;
// PRIVATE METHODS
std::shared_ptr<const VlRandomExpr> randomConstraint(VlRNG& rngr, int bits);
void randomConstraint(std::ostream& os, VlRNG& rngr, int bits);
bool parseSolution(std::iostream& file);
public:
// CONSTRUCTORS
VlRandomizer() = default;
~VlRandomizer() = default;
// METHODS
// Finds the next solution satisfying the constraints
bool next(VlRNG& rngr);
template <typename T>
void write_var(T& var, int width, const char* name) {
auto it = m_vars.find(name);
if (it != m_vars.end()) return;
m_vars[name] = std::make_shared<const VlRandomVar>(name, width, &var);
void write_var(T& var, int width, const char* name, int dimension,
std::uint32_t randmodeIdx = std::numeric_limits<std::uint32_t>::max()) {
if (m_vars.find(name) != m_vars.end()) return;
// TODO: make_unique once VlRandomizer is per-instance not per-ref
m_vars[name]
= std::make_shared<const VlRandomVar>(name, width, &var, dimension, randmodeIdx);
}
template <typename T>
void write_var(VlQueue<T>& var, int width, const char* name, int dimension,
std::uint32_t randmodeIdx = std::numeric_limits<std::uint32_t>::max()) {
if (m_vars.find(name) != m_vars.end()) return;
m_vars[name] = std::make_shared<const VlRandomQueueVar<VlQueue<T>>>(
name, width, &var, dimension, randmodeIdx);
}
template <typename T, std::size_t N>
void write_var(VlUnpacked<T, N>& var, int width, const char* name, int dimension,
std::uint32_t randmodeIdx = std::numeric_limits<std::uint32_t>::max()) {
if (m_vars.find(name) != m_vars.end()) return;
m_vars[name] = std::make_shared<const VlRandomArrayVar<VlUnpacked<T, N>>>(
name, width, &var, dimension, randmodeIdx);
}
void hard(std::string&& constraint);
void clear();
void set_randmode(const VlQueue<CData>& randmode) { m_randmode = &randmode; }
#ifdef VL_DEBUG
void dump() const;
#endif
+1 -2
View File
@@ -95,8 +95,7 @@ void VerilatedDeserialize::header() VL_MT_UNSAFE_ONE {
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_HEADER_STR, std::strlen(VLTSAVE_HEADER_STR)))) {
const std::string fn = filename();
const std::string msg
= std::
string{"Can't deserialize; file has wrong header signature, or file not found: "}
= "Can't deserialize; file has wrong header signature, or file not found: "s
+ filename();
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
// Die before we close() as close would infinite loop
+13 -4
View File
@@ -40,7 +40,7 @@ package std;
task put(T message);
`ifdef VERILATOR_TIMING
if (m_bound != 0)
while (m_bound != 0 && m_queue.size() >= m_bound)
wait (m_queue.size() < m_bound);
m_queue.push_back(message);
`endif
@@ -56,7 +56,9 @@ package std;
task get(ref T message);
`ifdef VERILATOR_TIMING
wait (m_queue.size() > 0);
while (m_queue.size() == 0) begin
wait (m_queue.size() > 0);
end
message = m_queue.pop_front();
`endif
endtask
@@ -71,7 +73,9 @@ package std;
task peek(ref T message);
`ifdef VERILATOR_TIMING
wait (m_queue.size() > 0);
while (m_queue.size() == 0) begin
wait (m_queue.size() > 0);
end
message = m_queue[0];
`endif
endtask
@@ -98,7 +102,9 @@ package std;
task get(int keyCount = 1);
`ifdef VERILATOR_TIMING
wait (m_keyCount >= keyCount);
while (m_keyCount < keyCount) begin
wait (m_keyCount >= keyCount);
end
m_keyCount -= keyCount;
`endif
endtask
@@ -189,4 +195,7 @@ package std;
$urandom(s.atoi()); // Set the seed using a string
endfunction
endclass
function int randomize();
randomize = 0;
endfunction
endpackage
+22 -15
View File
@@ -49,10 +49,12 @@ class VerilatedTraceOffloadBuffer;
//=============================================================================
// Common enumerations
enum class VerilatedTracePrefixType : uint32_t {
enum class VerilatedTracePrefixType : uint8_t {
// Note: Entries must match VTracePrefixType (by name, not necessarily by value)
ARRAY_PACKED,
ARRAY_UNPACKED,
ROOTIO_MODULE, // $rootio, used when name()=="", other modules become peers
ROOTIO_WRAPPER, // "Above" ROOTIO_MODULE
SCOPE_MODULE,
SCOPE_INTERFACE,
STRUCT_PACKED,
@@ -61,7 +63,7 @@ enum class VerilatedTracePrefixType : uint32_t {
};
// Direction attribute for ports
enum class VerilatedTraceSigDirection : uint32_t {
enum class VerilatedTraceSigDirection : uint8_t {
NONE,
INPUT,
OUTPUT,
@@ -69,7 +71,7 @@ enum class VerilatedTraceSigDirection : uint32_t {
};
// Kind of signal. Similar to nettype but with a few more alternatives
enum class VerilatedTraceSigKind : uint32_t {
enum class VerilatedTraceSigKind : uint8_t {
PARAMETER,
SUPPLY0,
SUPPLY1,
@@ -81,7 +83,7 @@ enum class VerilatedTraceSigKind : uint32_t {
};
// Base data type of signal
enum class VerilatedTraceSigType : uint32_t {
enum class VerilatedTraceSigType : uint8_t {
DOUBLE,
INTEGER,
BIT,
@@ -198,8 +200,8 @@ public:
//=============================================================================
// VerilatedTrace
// T_Trace is the format specific subclass of VerilatedTrace.
// T_Buffer is the format specific base class of VerilatedTraceBuffer.
// T_Trace is the format-specific subclass of VerilatedTrace.
// T_Buffer is the format-specific base class of VerilatedTraceBuffer.
template <class T_Trace, class T_Buffer>
class VerilatedTrace VL_NOT_FINAL {
public:
@@ -348,7 +350,7 @@ private:
protected:
//=========================================================================
// Internals available to format specific implementations
// Internals available to format-specific implementations
mutable VerilatedMutex m_mutex; // Ensure dump() etc only called from single thread
@@ -381,7 +383,7 @@ protected:
}
//=========================================================================
// Virtual functions to be provided by the format specific implementation
// Virtual functions to be provided by the format-specific implementation
// Called when the trace moves forward to a new time point
virtual void emitTimeChange(uint64_t timeui) = 0;
@@ -438,7 +440,7 @@ public:
//=============================================================================
// VerilatedTraceBuffer
// T_Buffer is the format specific base class of VerilatedTraceBuffer.
// T_Buffer is the format-specific base class of VerilatedTraceBuffer.
// The format-specific hot-path methods use duck-typing via T_Buffer for performance.
template <class T_Buffer>
class VerilatedTraceBuffer VL_NOT_FINAL : public T_Buffer {
@@ -464,7 +466,7 @@ public:
// Hot path internal interface to Verilator generated code
// Implementation note: We rely on the following duck-typed implementations
// in the derived class T_Derived. These emit* functions record a format
// in the derived class T_Derived. These emit* functions record a format-
// specific trace entry. Normally one would use pure virtual functions for
// these here, but we cannot afford dynamic dispatch for calling these as
// this is very hot code during tracing.
@@ -487,7 +489,8 @@ public:
void fullQData(uint32_t* oldp, QData newval, int bits);
void fullWData(uint32_t* oldp, const WData* newvalp, int bits);
void fullDouble(uint32_t* oldp, double newval);
void fullEvent(uint32_t* oldp, const VlEventBase* newval);
void fullEvent(uint32_t* oldp, const VlEventBase* newvalp);
void fullEventTriggered(uint32_t* oldp);
// In non-offload mode, these are called directly by the trace callbacks,
// and are called chg*. In offload mode, they are called by the worker
@@ -524,9 +527,10 @@ public:
}
}
}
VL_ATTR_ALWINLINE void chgEvent(uint32_t* oldp, const VlEventBase* newval) {
fullEvent(oldp, newval);
VL_ATTR_ALWINLINE void chgEvent(uint32_t* oldp, const VlEventBase* newvalp) {
if (newvalp->isTriggered()) fullEvent(oldp, newvalp);
}
VL_ATTR_ALWINLINE void chgEventTriggered(uint32_t* oldp) { fullEventTriggered(oldp); }
VL_ATTR_ALWINLINE void chgDouble(uint32_t* oldp, double newval) {
double old;
std::memcpy(&old, oldp, sizeof(old));
@@ -537,7 +541,7 @@ public:
//=============================================================================
// VerilatedTraceOffloadBuffer
// T_Buffer is the format specific base class of VerilatedTraceBuffer.
// T_Buffer is the format-specific base class of VerilatedTraceBuffer.
// The format-specific hot-path methods use duck-typing via T_Buffer for performance.
template <class T_Buffer>
class VerilatedTraceOffloadBuffer final : public VerilatedTraceBuffer<T_Buffer> {
@@ -605,7 +609,10 @@ public:
m_offloadBufferWritep += 4;
VL_DEBUG_IF(assert(m_offloadBufferWritep <= m_offloadBufferEndp););
}
void chgEvent(uint32_t code, const VlEventBase* newval) {
void chgEvent(uint32_t code, const VlEventBase* newvalp) {
if (newvalp->isTriggered()) chgEventTriggered(code);
}
void chgEventTriggered(uint32_t code) {
m_offloadBufferWritep[0] = VerilatedTraceOffloadCommand::CHG_EVENT;
m_offloadBufferWritep[1] = code;
m_offloadBufferWritep += 2;
+18 -11
View File
@@ -12,7 +12,7 @@
//=============================================================================
//
// Verilated tracing implementation code template common to all formats.
// This file is included by the format specific implementations and
// This file is included by the format-specific implementations and
// should not be used otherwise.
//
//=============================================================================
@@ -169,7 +169,7 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::offloadWorkerThreadMain() {
continue;
case VerilatedTraceOffloadCommand::CHG_EVENT:
VL_TRACE_OFFLOAD_DEBUG("Command CHG_EVENT " << top);
traceBufp->chgEvent(oldp, reinterpret_cast<const VlEventBase*>(readp));
traceBufp->chgEventTriggered(oldp);
continue;
//===
@@ -299,7 +299,7 @@ VerilatedTrace<VL_SUB_T, VL_BUF_T>::~VerilatedTrace() {
}
//=========================================================================
// Internals available to format specific implementations
// Internals available to format-specific implementations
template <>
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::traceInit() VL_MT_UNSAFE {
@@ -401,7 +401,7 @@ bool VerilatedTrace<VL_SUB_T, VL_BUF_T>::declCode(uint32_t code, const std::stri
}
//=========================================================================
// Internals available to format specific implementations
// Internals available to format-specific implementations
template <>
std::string VerilatedTrace<VL_SUB_T, VL_BUF_T>::timeResStr() const {
@@ -543,7 +543,7 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::dump(uint64_t timeui) VL_MT_SAFE_EXCLUD
Verilated::quiesce();
// Call hook for format specific behaviour
// Call hook for format-specific behaviour
if (VL_UNLIKELY(m_fullDump)) {
if (!preFullDump()) return;
} else {
@@ -667,7 +667,7 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addModel(VerilatedModel* modelp)
VL_FATAL_MT(__FILE__, __LINE__, "", "Cannot use parallel tracing with offloading");
} // LCOV_EXCL_STOP
// Configure format specific sub class
// Configure format-specific sub class
configure(*(configp.get()));
}
@@ -818,8 +818,8 @@ VerilatedTraceBuffer<VL_BUF_T>::VerilatedTraceBuffer(Trace& owner)
, m_sigs_enabledp{owner.m_sigs_enabledp} {}
// These functions must write the new value back into the old value store,
// and subsequently call the format specific emit* implementations. Note
// that this file must be included in the format specific implementation, so
// and subsequently call the format-specific emit* implementations. Note
// that this file must be included in the format-specific implementation, so
// the emit* functions can be inlined for performance.
template <>
@@ -831,10 +831,17 @@ void VerilatedTraceBuffer<VL_BUF_T>::fullBit(uint32_t* oldp, CData newval) {
}
template <>
void VerilatedTraceBuffer<VL_BUF_T>::fullEvent(uint32_t* oldp, const VlEventBase* newval) {
void VerilatedTraceBuffer<VL_BUF_T>::fullEvent(uint32_t* oldp, const VlEventBase* newvalp) {
const uint32_t code = oldp - m_sigs_oldvalp;
*oldp = 1; // Do we really store an "event" ?
emitEvent(code, newval);
// No need to update *oldp
if (newvalp->isTriggered()) emitEvent(code);
}
template <>
void VerilatedTraceBuffer<VL_BUF_T>::fullEventTriggered(uint32_t* oldp) {
const uint32_t code = oldp - m_sigs_oldvalp;
// No need to update *oldp
emitEvent(code);
}
template <>
+141 -99
View File
@@ -485,6 +485,8 @@ private:
public:
using const_iterator = typename Deque::const_iterator;
template <class Func>
using WithFuncReturnType = decltype(std::declval<Func>()(0, std::declval<T_Value>()));
private:
// MEMBERS
@@ -512,28 +514,29 @@ public:
return *this;
}
static VlQueue cons(const T_Value& lhs) {
// Construct new object from _V_alue and/or _C_ontainer child objects
static VlQueue consV(const T_Value& lhs) {
VlQueue out;
out.push_back(lhs);
return out;
}
static VlQueue cons(const T_Value& lhs, const T_Value& rhs) {
static VlQueue consVV(const T_Value& lhs, const T_Value& rhs) {
VlQueue out;
out.push_back(rhs);
out.push_back(lhs);
return out;
}
static VlQueue cons(const VlQueue& lhs, const T_Value& rhs) {
static VlQueue consCV(const VlQueue& lhs, const T_Value& rhs) {
VlQueue out = lhs;
out.push_front(rhs);
return out;
}
static VlQueue cons(const T_Value& lhs, const VlQueue& rhs) {
static VlQueue consVC(const T_Value& lhs, const VlQueue& rhs) {
VlQueue out = rhs;
out.push_back(lhs);
return out;
}
static VlQueue cons(const VlQueue& lhs, const VlQueue& rhs) {
static VlQueue consCC(const VlQueue& lhs, const VlQueue& rhs) {
VlQueue out = rhs;
for (const auto& i : lhs.m_deque) out.push_back(i);
return out;
@@ -592,18 +595,28 @@ public:
return v;
}
// Setting. Verilog: assoc[index] = v
// Can't just overload operator[] or provide a "at" reference to set,
// because we need to be able to insert only when the value is set
T_Value& at(int32_t index) {
// Setting. Verilog: assoc[index] = v (should only be used by dynamic arrays)
T_Value& atWrite(int32_t index) {
// cppcheck-suppress variableScope
static thread_local T_Value t_throwAway;
// Needs to work for dynamic arrays, so does not use T_MaxSize
if (VL_UNLIKELY(index < 0 || index >= m_deque.size())) {
t_throwAway = atDefault();
return t_throwAway;
} else {
return m_deque[index];
}
return m_deque[index];
}
// Setting. Verilog: assoc[index] = v (should only be used by queues)
T_Value& atWriteAppend(int32_t index) {
// cppcheck-suppress variableScope
static thread_local T_Value t_throwAway;
if (VL_UNLIKELY(index < 0 || index > m_deque.size())) {
t_throwAway = atDefault();
return t_throwAway;
} else if (VL_UNLIKELY(index == m_deque.size())) {
push_back(atDefault());
}
return m_deque[index];
}
// Accessing. Verilog: v = assoc[index]
const T_Value& at(int32_t index) const {
@@ -615,7 +628,7 @@ public:
}
}
// Access with an index counted from end (e.g. q[$])
T_Value& atBack(int32_t index) { return at(m_deque.size() - 1 - index); }
T_Value& atWriteAppendBack(int32_t index) { return atWriteAppend(m_deque.size() - 1 - index); }
const T_Value& atBack(int32_t index) const { return at(m_deque.size() - 1 - index); }
// function void q.insert(index, value);
@@ -751,7 +764,7 @@ public:
// Can't use std::find_if as need index number
IData index = 0;
for (const auto& i : m_deque) {
if (with_func(index, i)) return VlQueue::cons(i);
if (with_func(index, i)) return VlQueue::consV(i);
++index;
}
return VlQueue{};
@@ -760,7 +773,7 @@ public:
VlQueue<IData> find_first_index(Func with_func) const {
IData index = 0;
for (const auto& i : m_deque) {
if (with_func(index, i)) return VlQueue<IData>::cons(index);
if (with_func(index, i)) return VlQueue<IData>::consV(index);
++index;
}
return VlQueue<IData>{};
@@ -769,7 +782,7 @@ public:
VlQueue find_last(Func with_func) const {
IData index = m_deque.size() - 1;
for (auto& item : vlstd::reverse_view(m_deque)) {
if (with_func(index, item)) return VlQueue::cons(item);
if (with_func(index, item)) return VlQueue::consV(item);
--index;
}
return VlQueue{};
@@ -778,7 +791,7 @@ public:
VlQueue<IData> find_last_index(Func with_func) const {
IData index = m_deque.size() - 1;
for (auto& item : vlstd::reverse_view(m_deque)) {
if (with_func(index, item)) return VlQueue<IData>::cons(index);
if (with_func(index, item)) return VlQueue<IData>::consV(index);
--index;
}
return VlQueue<IData>{};
@@ -788,7 +801,7 @@ public:
VlQueue min() const {
if (m_deque.empty()) return VlQueue{};
const auto it = std::min_element(m_deque.cbegin(), m_deque.cend());
return VlQueue::cons(*it);
return VlQueue::consV(*it);
}
template <typename Func>
VlQueue min(Func with_func) const {
@@ -797,12 +810,12 @@ public:
[&with_func](const IData& a, const IData& b) {
return with_func(0, a) < with_func(0, b);
});
return VlQueue::cons(*it);
return VlQueue::consV(*it);
}
VlQueue max() const {
if (m_deque.empty()) return VlQueue{};
const auto it = std::max_element(m_deque.cbegin(), m_deque.cend());
return VlQueue::cons(*it);
return VlQueue::consV(*it);
}
template <typename Func>
VlQueue max(Func with_func) const {
@@ -811,7 +824,7 @@ public:
[&with_func](const IData& a, const IData& b) {
return with_func(0, a) < with_func(0, b);
});
return VlQueue::cons(*it);
return VlQueue::consV(*it);
}
T_Value r_sum() const {
@@ -820,70 +833,63 @@ public:
return out;
}
template <typename Func>
T_Value r_sum(Func with_func) const {
T_Value out(0); // Type must have assignment operator
WithFuncReturnType<Func> r_sum(Func with_func) const {
WithFuncReturnType<Func> out = WithFuncReturnType<Func>(0);
IData index = 0;
for (const auto& i : m_deque) out += with_func(index++, i);
return out;
}
T_Value r_product() const {
if (m_deque.empty()) return T_Value(0);
auto it = m_deque.cbegin();
T_Value out{*it};
++it;
for (; it != m_deque.cend(); ++it) out *= *it;
if (m_deque.empty()) return T_Value(0); // The big three do it this way
T_Value out = T_Value(1);
for (const auto& i : m_deque) out *= i;
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.cbegin();
WithFuncReturnType<Func> r_product(Func with_func) const {
if (m_deque.empty()) return WithFuncReturnType<Func>(0); // The big three do it this way
WithFuncReturnType<Func> out = WithFuncReturnType<Func>(1);
IData index = 0;
T_Value out{with_func(index, *it)};
++it;
++index;
for (; it != m_deque.cend(); ++it) out *= with_func(index++, *it);
for (const auto& i : m_deque) out *= with_func(index++, i);
return out;
}
T_Value r_and() const {
if (m_deque.empty()) return T_Value(0);
auto it = m_deque.cbegin();
T_Value out{*it};
++it;
for (; it != m_deque.cend(); ++it) out &= *it;
if (m_deque.empty()) return T_Value(0); // The big three do it this way
T_Value out = ~T_Value(0);
for (const auto& i : m_deque) out &= i;
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.cbegin();
WithFuncReturnType<Func> r_and(Func with_func) const {
if (m_deque.empty()) return WithFuncReturnType<Func>(0); // The big three do it this way
IData index = 0;
T_Value out{with_func(index, *it)};
++it;
++index;
for (; it != m_deque.cend(); ++it) out &= with_func(index, *it);
WithFuncReturnType<Func> out = ~WithFuncReturnType<Func>(0);
for (const auto& i : m_deque) out &= with_func(index++, i);
return out;
}
T_Value r_or() const {
T_Value out(0); // Type must have assignment operator
T_Value out = T_Value(0);
for (const auto& i : m_deque) out |= i;
return out;
}
template <typename Func>
T_Value r_or(Func with_func) const {
T_Value out(0); // Type must have assignment operator
WithFuncReturnType<Func> r_or(Func with_func) const {
WithFuncReturnType<Func> out = WithFuncReturnType<Func>(0);
IData index = 0;
for (const auto& i : m_deque) out |= with_func(index++, i);
return out;
}
T_Value r_xor() const {
T_Value out(0); // Type must have assignment operator
#ifdef VERILATOR_BIG3_NULLARY_ARITHMETICS_QUIRKS
if (m_deque.empty()) return T_Value(0);
#endif
T_Value out = T_Value(0);
for (const auto& i : m_deque) out ^= i;
return out;
}
template <typename Func>
T_Value r_xor(Func with_func) const {
T_Value out(0); // Type must have assignment operator
WithFuncReturnType<Func> r_xor(Func with_func) const {
WithFuncReturnType<Func> out = WithFuncReturnType<Func>(0);
IData index = 0;
for (const auto& i : m_deque) out ^= with_func(index++, i);
return out;
@@ -920,6 +926,9 @@ private:
public:
using const_iterator = typename Map::const_iterator;
template <class Func>
using WithFuncReturnType
= decltype(std::declval<Func>()(std::declval<T_Key>(), std::declval<T_Value>()));
private:
// MEMBERS
@@ -1092,7 +1101,7 @@ public:
return with_func(i.first, i.second);
});
if (it == m_map.end()) return VlQueue<T_Value>{};
return VlQueue<T_Value>::cons(it->second);
return VlQueue<T_Value>::consV(it->second);
}
template <typename Func>
VlQueue<T_Key> find_first_index(Func with_func) const {
@@ -1101,7 +1110,7 @@ public:
return with_func(i.first, i.second);
});
if (it == m_map.end()) return VlQueue<T_Value>{};
return VlQueue<T_Key>::cons(it->first);
return VlQueue<T_Key>::consV(it->first);
}
template <typename Func>
VlQueue<T_Value> find_last(Func with_func) const {
@@ -1109,7 +1118,7 @@ public:
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);
return VlQueue<T_Value>::consV(it->second);
}
template <typename Func>
VlQueue<T_Key> find_last_index(Func with_func) const {
@@ -1117,7 +1126,7 @@ public:
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);
return VlQueue<T_Key>::consV(it->first);
}
// Reduction operators
@@ -1128,7 +1137,7 @@ public:
[](const std::pair<T_Key, T_Value>& a, const std::pair<T_Key, T_Value>& b) {
return a.second < b.second;
});
return VlQueue<T_Value>::cons(it->second);
return VlQueue<T_Value>::consV(it->second);
}
template <typename Func>
VlQueue<T_Value> min(Func with_func) const {
@@ -1138,7 +1147,7 @@ public:
[&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);
});
return VlQueue<T_Value>::cons(it->second);
return VlQueue<T_Value>::consV(it->second);
}
VlQueue<T_Value> max() const {
if (m_map.empty()) return VlQueue<T_Value>();
@@ -1147,7 +1156,7 @@ public:
[](const std::pair<T_Key, T_Value>& a, const std::pair<T_Key, T_Value>& b) {
return a.second < b.second;
});
return VlQueue<T_Value>::cons(it->second);
return VlQueue<T_Value>::consV(it->second);
}
template <typename Func>
VlQueue<T_Value> max(Func with_func) const {
@@ -1157,7 +1166,7 @@ public:
[&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);
});
return VlQueue<T_Value>::cons(it->second);
return VlQueue<T_Value>::consV(it->second);
}
T_Value r_sum() const {
@@ -1166,64 +1175,56 @@ public:
return out;
}
template <typename Func>
T_Value r_sum(Func with_func) const {
T_Value out(0); // Type must have assignment operator
WithFuncReturnType<Func> r_sum(Func with_func) const {
WithFuncReturnType<Func> out = WithFuncReturnType<Func>(0);
for (const auto& i : m_map) out += with_func(i.first, i.second);
return out;
}
T_Value r_product() const {
if (m_map.empty()) return T_Value(0);
auto it = m_map.cbegin();
T_Value out{it->second};
++it;
for (; it != m_map.cend(); ++it) out *= it->second;
if (m_map.empty()) return T_Value(0); // The big three do it this way
T_Value out = T_Value(1);
for (const auto& i : m_map) out *= i.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.cbegin();
T_Value out{with_func(it->first, it->second)};
++it;
for (; it != m_map.cend(); ++it) out *= with_func(it->first, it->second);
WithFuncReturnType<Func> r_product(Func with_func) const {
if (m_map.empty()) return WithFuncReturnType<Func>(0); // The big three do it this way
WithFuncReturnType<Func> out = WithFuncReturnType<Func>(1);
for (const auto& i : m_map) out *= with_func(i.first, i.second);
return out;
}
T_Value r_and() const {
if (m_map.empty()) return T_Value(0);
auto it = m_map.cbegin();
T_Value out{it->second};
++it;
for (; it != m_map.cend(); ++it) out &= it->second;
if (m_map.empty()) return T_Value(0); // The big three do it this way
T_Value out = ~T_Value(0);
for (const auto& i : m_map) out &= i.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.cbegin();
T_Value out{with_func(it->first, it->second)};
++it;
for (; it != m_map.cend(); ++it) out &= with_func(it->first, it->second);
WithFuncReturnType<Func> r_and(Func with_func) const {
if (m_map.empty()) return WithFuncReturnType<Func>(0); // The big three do it this way
WithFuncReturnType<Func> out = ~WithFuncReturnType<Func>(0);
for (const auto& i : m_map) out &= with_func(i.first, i.second);
return out;
}
T_Value r_or() const {
T_Value out(0); // Type must have assignment operator
T_Value out = T_Value(0);
for (const auto& i : m_map) out |= i.second;
return out;
}
template <typename Func>
T_Value r_or(Func with_func) const {
T_Value out(0); // Type must have assignment operator
T_Value out = T_Value(0);
for (const auto& i : m_map) out |= with_func(i.first, i.second);
return out;
}
T_Value r_xor() const {
T_Value out(0); // Type must have assignment operator
T_Value out = T_Value(0);
for (const auto& i : m_map) out ^= i.second;
return out;
}
template <typename Func>
T_Value r_xor(Func with_func) const {
T_Value out(0); // Type must have assignment operator
WithFuncReturnType<Func> r_xor(Func with_func) const {
WithFuncReturnType<Func> out = WithFuncReturnType<Func>(0);
for (const auto& i : m_map) out ^= with_func(i.first, i.second);
return out;
}
@@ -1311,6 +1312,43 @@ public:
WData* data() { return &m_storage[0]; }
const WData* data() const { return &m_storage[0]; }
std::size_t size() const { return T_Depth; }
// To fit C++14
template <std::size_t CurrentDimension = 0, typename U = T_Value>
int find_length(int dimension, std::false_type) const {
return size();
}
template <std::size_t CurrentDimension = 0, typename U = T_Value>
int find_length(int dimension, std::true_type) const {
if (dimension == CurrentDimension) {
return size();
} else {
return m_storage[0].template find_length<CurrentDimension + 1>(dimension);
}
}
template <std::size_t CurrentDimension = 0>
int find_length(int dimension) const {
return find_length<CurrentDimension>(dimension, std::is_class<T_Value>{});
}
template <std::size_t CurrentDimension = 0, typename U = T_Value>
auto& find_element(const std::vector<size_t>& indices, std::false_type) {
return m_storage[indices[CurrentDimension]];
}
template <std::size_t CurrentDimension = 0, typename U = T_Value>
auto& find_element(const std::vector<size_t>& indices, std::true_type) {
return m_storage[indices[CurrentDimension]].template find_element<CurrentDimension + 1>(
indices);
}
template <std::size_t CurrentDimension = 0>
auto& find_element(const std::vector<size_t>& indices) {
return find_element<CurrentDimension>(indices, std::is_class<T_Value>{});
}
T_Value& operator[](size_t index) { return m_storage[index]; }
const T_Value& operator[](size_t index) const { return m_storage[index]; }
@@ -1438,7 +1476,7 @@ public:
// Can't use std::find_if as need index number
IData index = 0;
for (const auto& i : m_storage) {
if (with_func(index, i)) return VlQueue<T_Value>::cons(i);
if (with_func(index, i)) return VlQueue<T_Value>::consV(i);
++index;
}
return VlQueue<T_Value>{};
@@ -1447,7 +1485,7 @@ public:
VlQueue<T_Key> find_first_index(Func with_func) const {
IData index = 0;
for (const auto& i : m_storage) {
if (with_func(index, i)) return VlQueue<IData>::cons(index);
if (with_func(index, i)) return VlQueue<IData>::consV(index);
++index;
}
return VlQueue<T_Key>{};
@@ -1455,14 +1493,14 @@ public:
template <typename Func>
VlQueue<T_Value> find_last(Func with_func) const {
for (int i = T_Depth - 1; i >= 0; i--) {
if (with_func(i, m_storage[i])) return VlQueue<T_Value>::cons(m_storage[i]);
if (with_func(i, m_storage[i])) return VlQueue<T_Value>::consV(m_storage[i]);
}
return VlQueue<T_Value>{};
}
template <typename Func>
VlQueue<T_Key> find_last_index(Func with_func) const {
for (int i = T_Depth - 1; i >= 0; i--) {
if (with_func(i, m_storage[i])) return VlQueue<IData>::cons(i);
if (with_func(i, m_storage[i])) return VlQueue<IData>::consV(i);
}
return VlQueue<T_Key>{};
}
@@ -1470,7 +1508,7 @@ public:
// Reduction operators
VlQueue<T_Value> min() const {
const auto it = std::min_element(std::begin(m_storage), std::end(m_storage));
return VlQueue<T_Value>::cons(*it);
return VlQueue<T_Value>::consV(*it);
}
template <typename Func>
VlQueue<T_Value> min(Func with_func) const {
@@ -1478,11 +1516,11 @@ public:
[&with_func](const IData& a, const IData& b) {
return with_func(0, a) < with_func(0, b);
});
return VlQueue<T_Value>::cons(*it);
return VlQueue<T_Value>::consV(*it);
}
VlQueue<T_Value> max() const {
const auto it = std::max_element(std::begin(m_storage), std::end(m_storage));
return VlQueue<T_Value>::cons(*it);
return VlQueue<T_Value>::consV(*it);
}
template <typename Func>
VlQueue<T_Value> max(Func with_func) const {
@@ -1490,7 +1528,7 @@ public:
[&with_func](const IData& a, const IData& b) {
return with_func(0, a) < with_func(0, b);
});
return VlQueue<T_Value>::cons(*it);
return VlQueue<T_Value>::consV(*it);
}
// Dumping. Verilog: str = $sformatf("%p", assoc)
@@ -1786,12 +1824,16 @@ 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.
// Represents the null pointer. Used for:
// * setting VlClassRef to null instead of via nullptr_t, to prevent the implicit conversion of 0
// to nullptr,
// * comparing interface pointers to null.
struct VlNull final {
operator bool() const { return false; }
bool operator==(const void* ptr) const { return !ptr; }
};
inline bool operator==(const void* ptr, VlNull) { return !ptr; }
//===================================================================
// Verilog class reference container
+23 -12
View File
@@ -305,8 +305,22 @@ void VerilatedVcd::printIndent(int level_change) {
}
void VerilatedVcd::pushPrefix(const std::string& name, VerilatedTracePrefixType type) {
std::string newPrefix = m_prefixStack.back().first + name;
assert(!m_prefixStack.empty()); // Constructor makes an empty entry
std::string pname = name;
// An empty name means this is the root of a model created with name()=="". The
// tools get upset if we try to pass this as empty, so we put the signals under a
// new scope, but the signals further down will be peers, not children (as usual
// for name()!="")
// Terminate earlier $root?
if (m_prefixStack.back().second == VerilatedTracePrefixType::ROOTIO_MODULE) popPrefix();
if (pname.empty()) { // Start new temporary root
pname = "$rootio"; // VCD names are not backslash escaped
m_prefixStack.emplace_back("", VerilatedTracePrefixType::ROOTIO_WRAPPER);
type = VerilatedTracePrefixType::ROOTIO_MODULE;
}
std::string newPrefix = m_prefixStack.back().first + pname;
switch (type) {
case VerilatedTracePrefixType::ROOTIO_MODULE:
case VerilatedTracePrefixType::SCOPE_MODULE:
case VerilatedTracePrefixType::SCOPE_INTERFACE:
case VerilatedTracePrefixType::STRUCT_PACKED:
@@ -326,7 +340,9 @@ void VerilatedVcd::pushPrefix(const std::string& name, VerilatedTracePrefixType
}
void VerilatedVcd::popPrefix() {
assert(!m_prefixStack.empty());
switch (m_prefixStack.back().second) {
case VerilatedTracePrefixType::ROOTIO_MODULE:
case VerilatedTracePrefixType::SCOPE_MODULE:
case VerilatedTracePrefixType::SCOPE_INTERFACE:
case VerilatedTracePrefixType::STRUCT_PACKED:
@@ -338,7 +354,7 @@ void VerilatedVcd::popPrefix() {
default: break;
}
m_prefixStack.pop_back();
assert(!m_prefixStack.empty());
assert(!m_prefixStack.empty()); // Always one left, the constructor's initial one
}
void VerilatedVcd::declare(uint32_t code, const char* name, const char* wirep, bool array,
@@ -573,16 +589,11 @@ void VerilatedVcdBuffer::finishLine(uint32_t code, char* writep) {
// so always inline them.
VL_ATTR_ALWINLINE
void VerilatedVcdBuffer::emitEvent(uint32_t code, const VlEventBase* newval) {
const bool triggered = newval->isTriggered();
// TODO : It seems that untriggered events are not filtered
// should be tested before this last step
if (triggered) {
// Don't prefetch suffix as it's a bit too late;
char* wp = m_writep;
*wp++ = '1';
finishLine(code, wp);
}
void VerilatedVcdBuffer::emitEvent(uint32_t code) {
// Don't prefetch suffix as it's a bit too late;
char* wp = m_writep;
*wp++ = '1';
finishLine(code, wp);
}
VL_ATTR_ALWINLINE
+2 -2
View File
@@ -43,7 +43,7 @@ private:
friend VerilatedVcdBuffer; // Give the buffer access to the private bits
//=========================================================================
// VCD specific internals
// VCD-specific internals
VerilatedVcdFile* m_filep; // File we're writing to
bool m_fileNewed; // m_filep needs destruction
@@ -214,7 +214,7 @@ class VerilatedVcdBuffer VL_NOT_FINAL {
// Implementation of VerilatedTraceBuffer interface
// Implementations of duck-typed methods for VerilatedTraceBuffer. These are
// called from only one place (the full* methods), so always inline them.
VL_ATTR_ALWINLINE void emitEvent(uint32_t code, const VlEventBase* newval);
VL_ATTR_ALWINLINE void emitEvent(uint32_t code);
VL_ATTR_ALWINLINE void emitBit(uint32_t code, CData newval);
VL_ATTR_ALWINLINE void emitCData(uint32_t code, CData newval, int bits);
VL_ATTR_ALWINLINE void emitSData(uint32_t code, SData newval, int bits);
+11 -3
View File
@@ -896,6 +896,9 @@ public:
if (VL_LIKELY(it != s().m_futureCbs.cend())) return it->first.first;
return ~0ULL; // maxquad
}
static bool hasCbs(const uint32_t reason) VL_MT_UNSAFE_ONE {
return !s().m_cbCurrentLists[reason].empty();
}
static bool callCbs(const uint32_t reason) VL_MT_UNSAFE_ONE {
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: callCbs reason=%u\n", reason););
assertOneCheck();
@@ -958,8 +961,8 @@ public:
}
static void dumpCbs() VL_MT_UNSAFE_ONE;
static VerilatedVpiError* error_info() VL_MT_UNSAFE_ONE; // getter for vpi error info
static void evalNeeded(bool evalNeeded) { s().m_evalNeeded = evalNeeded; }
static bool evalNeeded() { return s().m_evalNeeded; }
static void evalNeeded(bool evalNeeded) { s().m_evalNeeded = evalNeeded; }
static void inertialDelay(const VerilatedVpioVar* vop, p_vpi_value valuep) {
s().m_inertialPuts.emplace_back(vop, valuep);
}
@@ -1056,6 +1059,10 @@ bool VerilatedVpi::callCbs(uint32_t reason) VL_MT_UNSAFE_ONE {
return VerilatedVpiImp::callCbs(reason);
}
bool VerilatedVpi::hasCbs(uint32_t reason) VL_MT_UNSAFE_ONE {
return VerilatedVpiImp::hasCbs(reason);
}
// Historical, before we had multiple kinds of timed callbacks
void VerilatedVpi::callTimedCbs() VL_MT_UNSAFE_ONE { VerilatedVpiImp::callCbs(cbAfterDelay); }
@@ -2468,7 +2475,7 @@ void vl_get_value(const VerilatedVar* varp, void* varDatap, p_vpi_value valuep,
vl_strprintf(t_outDynamicStr, "%u",
static_cast<unsigned int>(*(reinterpret_cast<IData*>(varDatap))));
} else if (varp->vltype() == VLVT_UINT64) {
vl_strprintf(t_outDynamicStr, "%llu",
vl_strprintf(t_outDynamicStr, "%llu", // lintok-format-ll
static_cast<unsigned long long>(*(reinterpret_cast<QData*>(varDatap))));
}
valuep->value.str = const_cast<PLI_BYTE8*>(t_outDynamicStr.c_str());
@@ -2690,7 +2697,8 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value valuep, p_vpi_time /*time_
} else if (valuep->format == vpiDecStrVal) {
char remainder[16];
unsigned long long val;
const int success = std::sscanf(valuep->value.str, "%30llu%15s", &val, remainder);
const int success = std::sscanf(valuep->value.str, "%30llu%15s", // lintok-format-ll
&val, remainder);
if (success < 1) {
VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Parsing failed for '%s' as value %s for %s",
__func__, valuep->value.str,
+3
View File
@@ -49,6 +49,9 @@ public:
/// Call callbacks of arbitrary types.
/// User wrapper code should call this from their main loops.
static bool callCbs(uint32_t reason) VL_MT_UNSAFE_ONE;
/// Returns true if there are callbacks of the given reason registered.
/// User wrapper code should call this from their main loops.
static bool hasCbs(uint32_t reason) VL_MT_UNSAFE_ONE;
/// Returns time of the next registered VPI callback, or
/// ~(0ULL) if none are registered
static QData cbNextDeadline() VL_MT_UNSAFE_ONE;
+16 -5
View File
@@ -200,6 +200,11 @@
// Comment tag that Function is pure (and thus also VL_MT_SAFE)
#define VL_PURE VL_CLANG_ATTR(annotate("PURE"))
// Annotated function can be called only in MT_DISABLED context, i.e. either in a code unit
// compiled with VL_MT_DISABLED_CODE_UNIT preprocessor definition, or in the main thread.
#define VL_MT_DISABLED \
VL_CLANG_ATTR(annotate("MT_DISABLED")) \
VL_EXCLUDES(VlOs::MtScopeMutex::s_haveThreadScope)
// Comment tag that function is threadsafe
#define VL_MT_SAFE VL_CLANG_ATTR(annotate("MT_SAFE"))
// Comment tag that function is threadsafe, only if
@@ -216,7 +221,7 @@
// protected to make sure single-caller
#define VL_MT_UNSAFE_ONE VL_CLANG_ATTR(annotate("MT_UNSAFE_ONE"))
// Comment tag that function is entry point of parallelization
#define VL_MT_START VL_CLANG_ATTR(annotate("MT_START"))
#define VL_MT_START VL_CLANG_ATTR(annotate("MT_START")) VL_REQUIRES(VlOs::MtScopeMutex::s_haveThreadScope)
#ifndef VL_NO_LEGACY
# define VL_ULL(c) (c##ULL) // Add appropriate suffix to 64-bit constant (deprecated)
@@ -463,8 +468,6 @@ using ssize_t = uint32_t; ///< signed size_t; returned from read()
#define VL_VALUE_STRING_MAX_WORDS 64 ///< Max size in words of String conversion operation
#endif
#define VL_VALUE_STRING_MAX_CHARS (VL_VALUE_STRING_MAX_WORDS * VL_EDATASIZE / VL_BYTESIZE)
//=========================================================================
// Base macros
@@ -588,9 +591,9 @@ static inline double VL_ROUND(double n) {
#endif
//=========================================================================
// Macros controlling target specific optimizations
// Macros controlling target-specific optimizations
// Define VL_PORTABLE_ONLY to disable all target specific optimizations
// Define VL_PORTABLE_ONLY to disable all target-specific optimizations
#ifndef VL_PORTABLE_ONLY
# ifdef __x86_64__
# define VL_X86_64 1
@@ -653,6 +656,14 @@ public:
return (m_start == 0.0) ? 0.0 : gettime() - m_start;
}
};
// Used by clang's -fthread-safety, ensures that only one instance of V3ThreadScope
// is created at a time
class VL_CAPABILITY("mutex") MtScopeMutex final {
public:
static MtScopeMutex s_haveThreadScope;
};
} //namespace VlOs
//=========================================================================
+4 -4
View File
@@ -51,10 +51,10 @@ double DeltaCpuTime::gettime() VL_MT_SAFE {
#else
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
timespec ts;
if (0 != clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts)) // MT-Safe
if (0 == clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts)) // MT-Safe // LCOV_EXCL_BR_LINE
return ts.tv_sec + ts.tv_nsec * 1e-9;
#endif
return 0.0;
return 0.0; // LCOV_EXCL_LINE
}
double DeltaWallTime::gettime() VL_MT_SAFE {
#if defined(_WIN32) || defined(__MINGW32__)
@@ -66,9 +66,9 @@ double DeltaWallTime::gettime() VL_MT_SAFE {
#else
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
timespec ts;
if (0 == clock_gettime(CLOCK_MONOTONIC, &ts)) // MT-Safe
if (0 == clock_gettime(CLOCK_MONOTONIC, &ts)) // MT-Safe // LCOV_EXCL_BR_LINE
return ts.tv_sec + ts.tv_nsec * 1e-9;
return 0.0;
return 0.0; // LCOV_EXCL_LINE
#endif
}
+165 -222
View File
@@ -48,9 +48,11 @@ def fully_qualified_name(node):
if node.kind == CursorKind.TRANSLATION_UNIT:
return []
res = fully_qualified_name(node.semantic_parent)
displayname = node.displayname
displayname = [displayname] if displayname else []
if res:
return res + ([node.displayname] if node.displayname else [])
return [node.displayname] if node.displayname else []
return res + displayname
return displayname
# Returns True, if `class_node` contains node
@@ -106,9 +108,8 @@ class VlAnnotations:
def is_mt_safe_call(self):
return (not self.is_mt_unsafe_call()
and (self.mt_safe or self.mt_safe_postinit or self.pure
or self.requires or self.excludes or self.acquire
or self.release))
and (self.mt_safe or self.mt_safe_postinit or self.pure or self.requires
or self.excludes or self.acquire or self.release))
def is_pure_call(self):
return self.pure
@@ -140,31 +141,32 @@ class VlAnnotations:
result = VlAnnotations()
for node in nodes:
if node.kind == CursorKind.ANNOTATE_ATTR:
if node.displayname == "MT_START":
displayname = node.displayname
if displayname == "MT_START":
result.mt_start = True
elif node.displayname == "MT_SAFE":
elif displayname == "MT_SAFE":
result.mt_safe = True
elif node.displayname == "MT_STABLE":
elif displayname == "MT_STABLE":
result.stable_tree = True
elif node.displayname == "MT_SAFE_POSTINIT":
elif displayname == "MT_SAFE_POSTINIT":
result.mt_safe_postinit = True
elif node.displayname == "MT_UNSAFE":
elif displayname == "MT_UNSAFE":
result.mt_unsafe = True
elif node.displayname == "MT_UNSAFE_ONE":
elif displayname == "MT_UNSAFE_ONE":
result.mt_unsafe_one = True
elif node.displayname == "MT_DISABLED":
elif displayname == "MT_DISABLED":
result.mt_disabled = True
elif node.displayname == "PURE":
elif displayname == "PURE":
result.pure = True
elif node.displayname in ["ACQUIRE", "ACQUIRE_SHARED"]:
elif displayname in ["ACQUIRE", "ACQUIRE_SHARED"]:
result.acquire = True
elif node.displayname in ["RELEASE", "RELEASE_SHARED"]:
elif displayname in ["RELEASE", "RELEASE_SHARED"]:
result.release = True
elif node.displayname == "REQUIRES":
elif displayname == "REQUIRES":
result.requires = True
elif node.displayname in ["EXCLUDES", "MT_SAFE_EXCLUDES"]:
elif displayname in ["EXCLUDES", "MT_SAFE_EXCLUDES"]:
result.excludes = True
elif node.displayname == "GUARDED_BY":
elif displayname == "GUARDED_BY":
result.guarded = True
# Attributes are always at the beginning
elif not node.kind.is_attribute():
@@ -203,9 +205,7 @@ class FunctionInfo:
annotations: VlAnnotations
ftype: FunctionType
_hash: Optional[int] = dataclasses.field(default=None,
init=False,
repr=False)
_hash: Optional[int] = dataclasses.field(default=None, init=False, repr=False)
@property
def name(self):
@@ -220,15 +220,13 @@ class FunctionInfo:
return self._hash
def __eq__(self, other):
return (self.usr == other.usr and self.file == other.file
and self.line == other.line)
return (self.usr == other.usr and self.file == other.file and self.line == other.line)
def copy(self, /, **changes):
return dataclasses.replace(self, **changes)
@staticmethod
def from_decl_file_line_and_refd_node(file: str, line: int,
refd: clang.cindex.Cursor,
def from_decl_file_line_and_refd_node(file: str, line: int, refd: clang.cindex.Cursor,
annotations: VlAnnotations):
file = os.path.abspath(file)
refd = refd.canonical
@@ -277,14 +275,11 @@ class Diagnostic:
source_ctx: FunctionInfo
kind: DiagnosticKind
_hash: Optional[int] = dataclasses.field(default=None,
init=False,
repr=False)
_hash: Optional[int] = dataclasses.field(default=None, init=False, repr=False)
def __hash__(self):
if not self._hash:
self._hash = hash(
hash(self.target) ^ hash(self.source_ctx) ^ hash(self.kind))
self._hash = hash(hash(self.target) ^ hash(self.source_ctx) ^ hash(self.kind))
return self._hash
@@ -292,9 +287,9 @@ class CallAnnotationsValidator:
def __init__(self, diagnostic_cb: Callable[[Diagnostic], None],
is_ignored_top_level: Callable[[clang.cindex.Cursor], bool],
is_ignored_def: Callable[
[clang.cindex.Cursor, clang.cindex.Cursor], bool],
is_ignored_call: Callable[[clang.cindex.Cursor], bool]):
is_ignored_def: Callable[[clang.cindex.Cursor, clang.cindex.Cursor],
bool], is_ignored_call: Callable[[clang.cindex.Cursor],
bool]):
self._diagnostic_cb = diagnostic_cb
self._is_ignored_top_level = is_ignored_top_level
self._is_ignored_call = is_ignored_call
@@ -312,6 +307,7 @@ class CallAnnotationsValidator:
self._defines: dict[str, str] = {}
self._call_location: Optional[FunctionInfo] = None
self._caller: Optional[FunctionInfo] = None
self._base_func_declarations: dict[str, clang.cindex.Cursor] = {}
self._constructor_context: list[clang.cindex.Cursor] = []
self._level: int = 0
@@ -329,8 +325,7 @@ class CallAnnotationsValidator:
with open(source_file, "r", encoding="utf-8") as file:
for line in file:
line = line.strip()
match = re.fullmatch(
r"^#\s*(define\s+(\w+)(?:\s+(.*))?|include\s+.*)$", line)
match = re.fullmatch(r"^#\s*(define\s+(\w+)(?:\s+(.*))?|include\s+.*)$", line)
if match:
if match.group(1).startswith("define"):
key = match.group(2)
@@ -341,16 +336,14 @@ class CallAnnotationsValidator:
return defs
@staticmethod
def filter_out_unsupported_compiler_args(
args: list[str]) -> tuple[list[str], dict[str, str]]:
def filter_out_unsupported_compiler_args(args: list[str]) -> tuple[list[str], dict[str, str]]:
filtered_args = []
defines = {}
args_iter = iter(args)
try:
while arg := next(args_iter):
# Skip positional arguments (input file name).
if not arg.startswith("-") and (arg.endswith(".cpp")
or arg.endswith(".c")
if not arg.startswith("-") and (arg.endswith(".cpp") or arg.endswith(".c")
or arg.endswith(".h")):
continue
@@ -367,8 +360,7 @@ class CallAnnotationsValidator:
# Preserved options with separate value argument.
if arg in [
"-x"
"-Xclang", "-I", "-isystem", "-iquote", "-include",
"-include-pch"
"-Xclang", "-I", "-isystem", "-iquote", "-include", "-include-pch"
]:
filtered_args += [arg, next(args_iter)]
continue
@@ -406,14 +398,12 @@ class CallAnnotationsValidator:
return (filtered_args, defines)
def compile_and_analyze_file(self, source_file: str,
compiler_args: list[str],
def compile_and_analyze_file(self, source_file: str, compiler_args: list[str],
build_dir: Optional[str]):
filename = os.path.abspath(source_file)
initial_cwd = "."
filtered_args, defines = self.filter_out_unsupported_compiler_args(
compiler_args)
filtered_args, defines = self.filter_out_unsupported_compiler_args(compiler_args)
defines.update(self.parse_initial_defines(source_file))
if build_dir:
@@ -451,8 +441,7 @@ class CallAnnotationsValidator:
self._diagnostic_cb(Diagnostic(target, source, source_ctx, kind))
else:
self._diagnostic_cb(
Diagnostic(FunctionInfo.from_node(target), source, source_ctx,
kind))
Diagnostic(FunctionInfo.from_node(target), source, source_ctx, kind))
def iterate_children(self, children: Iterable[clang.cindex.Cursor],
handler: Callable[[clang.cindex.Cursor], None]):
@@ -465,8 +454,7 @@ class CallAnnotationsValidator:
@staticmethod
def get_referenced_node_info(
node: clang.cindex.Cursor
) -> tuple[bool, Optional[clang.cindex.Cursor], VlAnnotations,
Iterable[clang.cindex.Cursor]]:
) -> tuple[bool, Optional[clang.cindex.Cursor], VlAnnotations, Iterable[clang.cindex.Cursor]]:
if not node.spelling and not node.displayname:
return (False, None, VlAnnotations(), [])
@@ -480,8 +468,7 @@ class CallAnnotationsValidator:
annotations = VlAnnotations.from_nodes_list(children)
return (True, refd, annotations, children)
def check_mt_safe_call(self, node: clang.cindex.Cursor,
refd: clang.cindex.Cursor,
def check_mt_safe_call(self, node: clang.cindex.Cursor, refd: clang.cindex.Cursor,
annotations: VlAnnotations):
is_mt_safe = False
@@ -513,8 +500,7 @@ class CallAnnotationsValidator:
# we are calling local method. It is MT safe
# only if this method is also only calling local methods or
# MT-safe methods
self.iterate_children(refd.get_children(),
self.dispatch_node_inside_definition)
self.iterate_children(refd.get_children(), self.dispatch_node_inside_definition)
is_mt_safe = True
# class/struct member
elif refn and refn.kind == CursorKind.MEMBER_REF_EXPR and refn.referenced:
@@ -525,18 +511,15 @@ class CallAnnotationsValidator:
if self.is_constructor_context() and refn.semantic_parent:
# we are in constructor, so calling local members is MT_SAFE,
# make sure object that we are calling is local to the constructor
constructor_class = self._constructor_context[
-1].semantic_parent
constructor_class = self._constructor_context[-1].semantic_parent
if refn.semantic_parent.spelling == constructor_class.spelling:
if check_class_member_exists(constructor_class, refn):
is_mt_safe = True
else:
# check if this class inherits from some base class
base_class = get_base_class(constructor_class,
refn.semantic_parent)
base_class = get_base_class(constructor_class, refn.semantic_parent)
if base_class:
if check_class_member_exists(
base_class.get_declaration(), refn):
if check_class_member_exists(base_class.get_declaration(), refn):
is_mt_safe = True
# variable
elif refn and refn.kind == CursorKind.DECL_REF_EXPR and refn.referenced:
@@ -567,8 +550,7 @@ class CallAnnotationsValidator:
# Call handling
def process_method_call(self, node: clang.cindex.Cursor,
refd: clang.cindex.Cursor,
def process_method_call(self, node: clang.cindex.Cursor, refd: clang.cindex.Cursor,
annotations: VlAnnotations):
assert self._call_location
ctx = self._call_location.annotations
@@ -576,58 +558,48 @@ class CallAnnotationsValidator:
# MT-safe context
if ctx.is_mt_safe_context():
if not self.check_mt_safe_call(node, refd, annotations):
self.emit_diagnostic(
FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_MT_SAFE_CALL_IN_MT_SAFE_CTX)
self.emit_diagnostic(FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_MT_SAFE_CALL_IN_MT_SAFE_CTX)
# stable tree context
if ctx.is_stabe_tree_context():
if annotations.is_mt_unsafe_call() or not (
annotations.is_stabe_tree_call()
or annotations.is_pure_call()
annotations.is_stabe_tree_call() or annotations.is_pure_call()
or self.check_mt_safe_call(node, refd, annotations)):
self.emit_diagnostic(
FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_STABLE_TREE_CALL_IN_STABLE_TREE_CTX)
self.emit_diagnostic(FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_STABLE_TREE_CALL_IN_STABLE_TREE_CTX)
# pure context
if ctx.is_pure_context():
if not annotations.is_pure_call():
self.emit_diagnostic(
FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_PURE_CALL_IN_PURE_CTX)
self.emit_diagnostic(FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_PURE_CALL_IN_PURE_CTX)
def process_function_call(self, refd: clang.cindex.Cursor,
annotations: VlAnnotations):
def process_function_call(self, refd: clang.cindex.Cursor, annotations: VlAnnotations):
assert self._call_location
ctx = self._call_location.annotations
# MT-safe context
if ctx.is_mt_safe_context():
if not annotations.is_mt_safe_call():
self.emit_diagnostic(
FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_MT_SAFE_CALL_IN_MT_SAFE_CTX)
self.emit_diagnostic(FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_MT_SAFE_CALL_IN_MT_SAFE_CTX)
# stable tree context
if ctx.is_stabe_tree_context():
if annotations.is_mt_unsafe_call() or not (
annotations.is_pure_call()
or annotations.is_mt_safe_call()
or annotations.is_stabe_tree_call()):
self.emit_diagnostic(
FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_STABLE_TREE_CALL_IN_STABLE_TREE_CTX)
if annotations.is_mt_unsafe_call() or not (annotations.is_pure_call()
or annotations.is_mt_safe_call()
or annotations.is_stabe_tree_call()):
self.emit_diagnostic(FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_STABLE_TREE_CALL_IN_STABLE_TREE_CTX)
# pure context
if ctx.is_pure_context():
if not annotations.is_pure_call():
self.emit_diagnostic(
FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_PURE_CALL_IN_PURE_CTX)
self.emit_diagnostic(FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_PURE_CALL_IN_PURE_CTX)
def process_constructor_call(self, refd: clang.cindex.Cursor,
annotations: VlAnnotations):
def process_constructor_call(self, refd: clang.cindex.Cursor, annotations: VlAnnotations):
assert self._call_location
ctx = self._call_location.annotations
@@ -635,31 +607,26 @@ class CallAnnotationsValidator:
# only if they call local methods or MT-safe functions.
if ctx.is_mt_safe_context() or self.is_constructor_context():
self._constructor_context.append(refd)
self.iterate_children(refd.get_children(),
self.dispatch_node_inside_definition)
self.iterate_children(refd.get_children(), self.dispatch_node_inside_definition)
self._constructor_context.pop()
# stable tree context
if ctx.is_stabe_tree_context():
self._constructor_context.append(refd)
self.iterate_children(refd.get_children(),
self.dispatch_node_inside_definition)
self.iterate_children(refd.get_children(), self.dispatch_node_inside_definition)
self._constructor_context.pop()
# pure context
if ctx.is_pure_context():
if not annotations.is_pure_call(
) and not refd.is_default_constructor():
self.emit_diagnostic(
FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_PURE_CALL_IN_PURE_CTX)
if not annotations.is_pure_call() and not refd.is_default_constructor():
self.emit_diagnostic(FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.NON_PURE_CALL_IN_PURE_CTX)
def dispatch_call_node(self, node: clang.cindex.Cursor):
[supported, refd, annotations, _] = self.get_referenced_node_info(node)
if not supported:
self.iterate_children(node.get_children(),
self.dispatch_node_inside_definition)
self.iterate_children(node.get_children(), self.dispatch_node_inside_definition)
return True
assert refd is not None
@@ -676,19 +643,14 @@ class CallAnnotationsValidator:
assert self._call_location is not None
node_file = os.path.abspath(node.location.file.name)
self._call_location = self._call_location.copy(file=node_file,
line=node.location.line)
self._call_location = self._call_location.copy(file=node_file, line=node.location.line)
# Standalone functions and static class methods
if (refd.kind == CursorKind.FUNCTION_DECL
or refd.kind == CursorKind.CXX_METHOD
and refd.is_static_method()):
or refd.kind == CursorKind.CXX_METHOD and refd.is_static_method()):
self.process_function_call(refd, annotations)
# Function pointer
elif refd.kind in [
CursorKind.VAR_DECL, CursorKind.FIELD_DECL,
CursorKind.PARM_DECL
]:
elif refd.kind in [CursorKind.VAR_DECL, CursorKind.FIELD_DECL, CursorKind.PARM_DECL]:
self.process_function_call(refd, annotations)
# Non-static class methods
elif refd.kind == CursorKind.CXX_METHOD:
@@ -726,18 +688,25 @@ class CallAnnotationsValidator:
if self.dispatch_call_node(node) is False:
return None
elif node.is_definition() and node.kind in [
CursorKind.CXX_METHOD, CursorKind.FUNCTION_DECL,
CursorKind.CONSTRUCTOR, CursorKind.CONVERSION_FUNCTION
CursorKind.CXX_METHOD, CursorKind.FUNCTION_DECL, CursorKind.CONSTRUCTOR,
CursorKind.CONVERSION_FUNCTION
]:
self.process_function_definition(node)
return None
return self.iterate_children(node.get_children(),
self.dispatch_node_inside_definition)
return self.iterate_children(node.get_children(), self.dispatch_node_inside_definition)
def process_function_definition(self, node: clang.cindex.Cursor):
[supported, refd, annotations, _] = self.get_referenced_node_info(node)
# Fetch virtual annotations from base class.
# Set refd to virtual definition if present.
signature = node.displayname
if signature in self._base_func_declarations:
refd = self._base_func_declarations[signature]
virtual_annotations = VlAnnotations.from_nodes_list(refd.get_children())
annotations = annotations | virtual_annotations
if refd and self._is_ignored_def(node, refd):
return None
@@ -752,30 +721,29 @@ class CallAnnotationsValidator:
# Implicitly mark definitions in VL_MT_DISABLED_CODE_UNIT .cpp files as
# VL_MT_DISABLED. Existence of the annotation on declarations in .h
# files is verified below.
# Also sets VL_REQUIRES, as this annotation is added together with
# Also sets VL_EXCLUDES, as this annotation is added together with
# explicit VL_MT_DISABLED.
if self.is_mt_disabled_code_unit():
if node.location.file.name == self._main_source_file:
annotations.mt_disabled = True
annotations.requires = True
annotations.excludes = True
if refd.location.file.name == self._main_source_file:
def_annotations.mt_disabled = True
def_annotations.requires = True
def_annotations.excludes = True
if not (def_annotations.is_empty() or def_annotations == annotations):
if def_annotations != annotations:
# Use definition's annotations for the diagnostic
# source (i.e. the definition)
self._caller = FunctionInfo.from_node(node, refd, def_annotations)
self._call_location = self._caller
self.emit_diagnostic(
FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.ANNOTATIONS_DEF_DECL_MISMATCH)
self.emit_diagnostic(FunctionInfo.from_node(refd, refd, annotations),
DiagnosticKind.ANNOTATIONS_DEF_DECL_MISMATCH)
# Use concatenation of definition and declaration annotations
# for calls validation.
self._caller = FunctionInfo.from_node(node, refd,
def_annotations | annotations)
else:
# Use concatenation of definition and declaration annotations
# for calls validation.
self._caller = FunctionInfo.from_node(node, refd, def_annotations | annotations)
prev_call_location = self._call_location
self._call_location = self._caller
@@ -793,8 +761,7 @@ class CallAnnotationsValidator:
if declarations:
del self._external_decls[usr]
self.iterate_children(node_children,
self.dispatch_node_inside_definition)
self.iterate_children(node_children, self.dispatch_node_inside_definition)
self._call_location = prev_call_location
self._caller = prev_call_location
@@ -804,25 +771,37 @@ class CallAnnotationsValidator:
# Nodes not located inside definition
def dispatch_node(self, node: clang.cindex.Cursor):
if node.kind in [
CursorKind.CXX_METHOD, CursorKind.FUNCTION_DECL,
CursorKind.CONSTRUCTOR, CursorKind.CONVERSION_FUNCTION
kind = node.kind
if kind is CursorKind.CXX_BASE_SPECIFIER:
# Get referenced virtual declarations from base class.
for base in node.get_children():
if base.referenced:
for declaration in base.referenced.get_children():
self._base_func_declarations[declaration.displayname] = declaration
elif kind in [
CursorKind.CXX_METHOD, CursorKind.FUNCTION_DECL, CursorKind.CONSTRUCTOR,
CursorKind.CONVERSION_FUNCTION
]:
if node.is_definition():
return self.process_function_definition(node)
# else:
return self.process_function_declaration(node)
return self.iterate_children(node.get_children(), self.dispatch_node)
result = self.iterate_children(node.get_children(), self.dispatch_node)
def process_translation_unit(
self, translation_unit: clang.cindex.TranslationUnit):
# Clean declarations if class declaration processing is finished.
if kind in [
CursorKind.CLASS_DECL, CursorKind.STRUCT_DECL, CursorKind.UNION_DECL,
CursorKind.ENUM_DECL, CursorKind.UNEXPOSED_DECL
]:
self._base_func_declarations = {}
return result
def process_translation_unit(self, translation_unit: clang.cindex.TranslationUnit):
self._level += 1
kv_defines = sorted([f"{k}={v}" for k, v in self._defines.items()])
concat_defines = '\n'.join(kv_defines)
# List of headers already processed in a TU with specified set of defines.
tu_processed_headers = self._processed_headers.setdefault(
concat_defines, set())
tu_processed_headers = self._processed_headers.setdefault(concat_defines, set())
for child in translation_unit.cursor.get_children():
if self._is_ignored_top_level(child):
continue
@@ -833,10 +812,8 @@ class CallAnnotationsValidator:
self.dispatch_node(child)
self._level -= 1
tu_processed_headers.update([
os.path.abspath(str(hdr.source))
for hdr in translation_unit.get_includes()
])
tu_processed_headers.update(
[os.path.abspath(str(hdr.source)) for hdr in translation_unit.get_includes()])
@dataclass
@@ -857,8 +834,7 @@ def get_filter_funcs(verilator_root: str):
filename = os.path.abspath(node.location.file.name)
return not filename.startswith(verilator_root)
def is_ignored_def(node: clang.cindex.Cursor,
refd: clang.cindex.Cursor) -> bool:
def is_ignored_def(node: clang.cindex.Cursor, refd: clang.cindex.Cursor) -> bool:
# __*
if str(refd.spelling).startswith("__"):
return True
@@ -901,8 +877,7 @@ def precompile_header(compile_command: CompileCommand, tmp_dir: str) -> str:
os.chdir(compile_command.directory)
index = Index.create()
translation_unit = index.parse(compile_command.filename,
compile_command.args)
translation_unit = index.parse(compile_command.filename, compile_command.args)
for diag in translation_unit.diagnostics:
if diag.severity >= clang.cindex.Diagnostic.Error:
errors.append(str(diag))
@@ -910,23 +885,20 @@ def precompile_header(compile_command: CompileCommand, tmp_dir: str) -> str:
if len(errors) == 0:
pch_file = os.path.join(
tmp_dir,
f"{compile_command.refid:02}_{os.path.basename(compile_command.filename)}.pch"
)
f"{compile_command.refid:02}_{os.path.basename(compile_command.filename)}.pch")
translation_unit.save(pch_file)
if pch_file:
return pch_file
except (TranslationUnitSaveError, TranslationUnitLoadError,
OSError) as exception:
except (TranslationUnitSaveError, TranslationUnitLoadError, OSError) as exception:
print(f"%Warning: {exception}", file=sys.stderr)
finally:
os.chdir(initial_cwd)
print(
f"%Warning: Precompilation failed, skipping: {compile_command.filename}",
file=sys.stderr)
print(f"%Warning: Precompilation failed, skipping: {compile_command.filename}",
file=sys.stderr)
for error in errors:
print(f" {error}", file=sys.stderr)
return ""
@@ -934,10 +906,8 @@ def precompile_header(compile_command: CompileCommand, tmp_dir: str) -> str:
# Compile and analyze inputs in a single process.
def run_analysis(ccl: Iterable[CompileCommand], pccl: Iterable[CompileCommand],
diagnostic_cb: Callable[[Diagnostic],
None], verilator_root: str):
(is_ignored_top_level, is_ignored_def,
is_ignored_call) = get_filter_funcs(verilator_root)
diagnostic_cb: Callable[[Diagnostic], None], verilator_root: str):
(is_ignored_top_level, is_ignored_def, is_ignored_call) = get_filter_funcs(verilator_root)
prefix = "verilator_clang_check_attributes_"
with tempfile.TemporaryDirectory(prefix=prefix) as tmp_dir:
@@ -947,8 +917,8 @@ def run_analysis(ccl: Iterable[CompileCommand], pccl: Iterable[CompileCommand],
if pch_file:
extra_args += ["-include-pch", pch_file]
cav = CallAnnotationsValidator(diagnostic_cb, is_ignored_top_level,
is_ignored_def, is_ignored_call)
cav = CallAnnotationsValidator(diagnostic_cb, is_ignored_top_level, is_ignored_def,
is_ignored_call)
for compile_command in ccl:
cav.compile_and_analyze_file(compile_command.filename,
extra_args + compile_command.args,
@@ -963,12 +933,11 @@ class ParallelAnalysisProcess:
@staticmethod
def init_data(verilator_root: str, tmp_dir: str):
(is_ignored_top_level, is_ignored_def,
is_ignored_call) = get_filter_funcs(verilator_root)
(is_ignored_top_level, is_ignored_def, is_ignored_call) = get_filter_funcs(verilator_root)
ParallelAnalysisProcess.cav = CallAnnotationsValidator(
ParallelAnalysisProcess._diagnostic_handler, is_ignored_top_level,
is_ignored_def, is_ignored_call)
ParallelAnalysisProcess._diagnostic_handler, is_ignored_top_level, is_ignored_def,
is_ignored_call)
ParallelAnalysisProcess.tmp_dir = tmp_dir
@staticmethod
@@ -979,31 +948,27 @@ class ParallelAnalysisProcess:
def analyze_cpp_file(compile_command: CompileCommand) -> set[Diagnostic]:
ParallelAnalysisProcess.diags = set()
assert ParallelAnalysisProcess.cav is not None
ParallelAnalysisProcess.cav.compile_and_analyze_file(
compile_command.filename, compile_command.args,
compile_command.directory)
ParallelAnalysisProcess.cav.compile_and_analyze_file(compile_command.filename,
compile_command.args,
compile_command.directory)
return ParallelAnalysisProcess.diags
@staticmethod
def precompile_header(compile_command: CompileCommand) -> str:
return precompile_header(compile_command,
ParallelAnalysisProcess.tmp_dir)
return precompile_header(compile_command, ParallelAnalysisProcess.tmp_dir)
# Compile and analyze inputs in multiple processes.
def run_parallel_analysis(ccl: Iterable[CompileCommand],
pccl: Iterable[CompileCommand],
diagnostic_cb: Callable[[Diagnostic], None],
jobs_count: int, verilator_root: str):
def run_parallel_analysis(ccl: Iterable[CompileCommand], pccl: Iterable[CompileCommand],
diagnostic_cb: Callable[[Diagnostic],
None], jobs_count: int, verilator_root: str):
prefix = "verilator_clang_check_attributes_"
with tempfile.TemporaryDirectory(prefix=prefix) as tmp_dir:
with multiprocessing.Pool(
processes=jobs_count,
initializer=ParallelAnalysisProcess.init_data,
initargs=[verilator_root, tmp_dir]) as pool:
with multiprocessing.Pool(processes=jobs_count,
initializer=ParallelAnalysisProcess.init_data,
initargs=[verilator_root, tmp_dir]) as pool:
extra_args = []
for pch_file in pool.imap_unordered(
ParallelAnalysisProcess.precompile_header, pccl):
for pch_file in pool.imap_unordered(ParallelAnalysisProcess.precompile_header, pccl):
if pch_file:
extra_args += ["-include-pch", pch_file]
@@ -1011,8 +976,7 @@ def run_parallel_analysis(ccl: Iterable[CompileCommand],
for compile_command in ccl:
compile_command.args = compile_command.args + extra_args
for diags in pool.imap_unordered(
ParallelAnalysisProcess.analyze_cpp_file, ccl, 1):
for diags in pool.imap_unordered(ParallelAnalysisProcess.analyze_cpp_file, ccl, 1):
for diag in diags:
diagnostic_cb(diag)
@@ -1057,8 +1021,7 @@ class TopDownSummaryPrinter():
row_groups: dict[str, list[list[str]]] = {}
column_widths = [0, 0]
for func in sorted(self._funcs.values(),
key=lambda func:
(func.info.file, func.info.line, func.info.usr)):
key=lambda func: (func.info.file, func.info.line, func.info.usr)):
func_info = func.info
relfile = os.path.relpath(func_info.file, root_dir)
@@ -1082,31 +1045,23 @@ class TopDownSummaryPrinter():
if func.mismatch:
mrelfile = os.path.relpath(func.mismatch.file, root_dir)
row_group.append([
f"{mrelfile}:{func.mismatch.line}:",
f"[{func.mismatch.annotations}]",
f"{mrelfile}:{func.mismatch.line}:", f"[{func.mismatch.annotations}]",
func.mismatch.name + " [declaration]"
])
row_group.append([
f"{relfile}:{func_info.line}:", f"[{func_info.annotations}]",
func_info.name
])
row_group.append(
[f"{relfile}:{func_info.line}:", f"[{func_info.annotations}]", func_info.name])
for callee in sorted(func.calees,
key=lambda func:
(func.file, func.line, func.usr)):
for callee in sorted(func.calees, key=lambda func: (func.file, func.line, func.usr)):
crelfile = os.path.relpath(callee.file, root_dir)
row_group.append([
f"{crelfile}:{callee.line}:", f"[{callee.annotations}]",
" " + callee.name
])
row_group.append(
[f"{crelfile}:{callee.line}:", f"[{callee.annotations}]", " " + callee.name])
row_groups[name] = row_group
for row in row_group:
for row_id, value in enumerate(row[0:-1]):
column_widths[row_id] = max(column_widths[row_id],
len(value))
column_widths[row_id] = max(column_widths[row_id], len(value))
for label, rows in sorted(row_groups.items(), key=lambda kv: kv[0]):
self.begin_group(label)
@@ -1114,21 +1069,17 @@ class TopDownSummaryPrinter():
print(f"{row[0]:<{column_widths[0]}} "
f"{row[1]:<{column_widths[1]}} "
f"{row[2]}")
print(
f"Number of functions reported unsafe: {len(self._unsafe_in_safe)}"
)
print(f"Number of functions reported unsafe: {len(self._unsafe_in_safe)}")
def main():
default_verilator_root = os.path.abspath(
os.path.join(os.path.dirname(__file__), ".."))
default_verilator_root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawDescriptionHelpFormatter,
description="""Check function annotations for correctness""",
epilog=
"""Copyright 2022-2024 by Wilson Snyder. Verilator is free software;
epilog="""Copyright 2022-2024 by Wilson Snyder. Verilator is free software;
you can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Apache License 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Apache-2.0""")
@@ -1142,29 +1093,23 @@ def main():
type=int,
default=0,
help="Number of parallel jobs to use.")
parser.add_argument(
"--compile-commands-dir",
type=str,
default=None,
help="Path to directory containing compile_commands.json.")
parser.add_argument("--compile-commands-dir",
type=str,
default=None,
help="Path to directory containing compile_commands.json.")
parser.add_argument("--cxxflags",
type=str,
default=None,
help="Extra flags passed to clang++.")
parser.add_argument(
"--compilation-root",
type=str,
default=os.getcwd(),
help="Directory used as CWD when compiling source files.")
parser.add_argument(
"-c",
"--precompile",
action="append",
help="Header file to be precompiled and cached at the start.")
parser.add_argument("file",
parser.add_argument("--compilation-root",
type=str,
nargs="+",
help="Source file to analyze.")
default=os.getcwd(),
help="Directory used as CWD when compiling source files.")
parser.add_argument("-c",
"--precompile",
action="append",
help="Header file to be precompiled and cached at the start.")
parser.add_argument("file", type=str, nargs="+", help="Source file to analyze.")
cmdline = parser.parse_args()
@@ -1179,8 +1124,7 @@ def main():
compdb: Optional[CompilationDatabase] = None
if cmdline.compile_commands_dir:
compdb = CompilationDatabase.fromDirectory(
cmdline.compile_commands_dir)
compdb = CompilationDatabase.fromDirectory(cmdline.compile_commands_dir)
if cmdline.cxxflags is not None:
common_cxxflags = shlex.split(cmdline.cxxflags)
@@ -1230,8 +1174,7 @@ def main():
summary_printer.handle_diagnostic, verilator_root)
else:
run_parallel_analysis(compile_commands_list, precompile_commands_list,
summary_printer.handle_diagnostic, cmdline.jobs,
verilator_root)
summary_printer.handle_diagnostic, cmdline.jobs, verilator_root)
summary_printer.print_summary(verilator_root)
+41 -51
View File
@@ -58,15 +58,12 @@ def test():
if not Args.scenarios or re.match('dist', Args.scenarios):
run("make examples VERILATOR_NO_OPT_BUILD=1")
run("make test_regress VERILATOR_NO_OPT_BUILD=1" +
(" SCENARIOS='" + Args.scenarios +
"'" if Args.scenarios else "") +
(" DRIVER_HASHSET='--hashset=" + Args.hashset +
"'" if Args.hashset else "") +
(" SCENARIOS='" + Args.scenarios + "'" if Args.scenarios else "") +
(" DRIVER_HASHSET='--hashset=" + Args.hashset + "'" if Args.hashset else "") +
('' if Args.stop else ' || true'))
else:
for test in Args.tests:
if not os.path.exists(test) and os.path.exists(
"test_regress/t/" + test):
if not os.path.exists(test) and os.path.exists("test_regress/t/" + test):
test = "test_regress/t/" + test
run(test)
ci_fold_end()
@@ -78,8 +75,7 @@ def test():
os.makedirs(cc_dir, exist_ok=True)
os.makedirs(cc_dir + "/info", exist_ok=True)
with subprocess.Popen("find . -print | grep .gcda",
shell=True,
with subprocess.Popen("find . -print | grep .gcda", shell=True,
stdout=subprocess.PIPE) as sp:
datout = sp.stdout.read()
@@ -98,8 +94,7 @@ def test():
del dats[dat]
break
with subprocess.Popen("find . -print | grep .gcno",
shell=True,
with subprocess.Popen("find . -print | grep .gcno", shell=True,
stdout=subprocess.PIPE) as sp:
datout = sp.stdout.read()
@@ -116,8 +111,7 @@ def test():
if gbase in gcnos:
os.symlink(gcnos[gbase], gcno)
else:
print("MISSING .gcno for a .gcda: " + gcno,
file=sys.stderr)
print("MISSING .gcno for a .gcda: " + gcno, file=sys.stderr)
ci_fold_end()
if Args.stage_enabled[5]:
@@ -142,8 +136,7 @@ def test():
if Args.stage_enabled[11]:
ci_fold_start("dirs")
print("Stage 11: Cleanup paths")
cleanup_abs_paths_info(cc_dir, cc_dir + "/app_total.info",
cc_dir + "/app_total.info")
cleanup_abs_paths_info(cc_dir, cc_dir + "/app_total.info", cc_dir + "/app_total.info")
ci_fold_end()
if Args.stage_enabled[12]:
@@ -164,34 +157,38 @@ def test():
inc = "--include " + inc
if exc != '':
exc = "--exclude " + exc
run("cd " + cc_dir + " ; " + RealPath +
"/fastcov.py -C app_total.info " + inc + " " + exc +
" -x --lcov -o app_total_f.info")
run("cd " + cc_dir + " ; " + RealPath + "/fastcov.py -C app_total.info " + inc + " " +
exc + " -x --lcov -o app_total_f.info")
ci_fold_end()
if Args.stage_enabled[17]:
ci_fold_start("report")
print("Stage 17: Create HTML")
run("cd " + cc_dir + " ; genhtml app_total_f.info --demangle-cpp" +
" --rc lcov_branch_coverage=1 --rc genhtml_hi_limit=100 --output-directory html"
)
" --rc lcov_branch_coverage=1 --rc genhtml_hi_limit=100 --output-directory html")
ci_fold_end()
if Args.stage_enabled[18]:
ci_fold_start("upload")
print("Stage 18: Upload")
cmd = "bash <(cat ci/coverage-upload.sh) -f " + cc_dir + "/app_total.info"
print("print: Not running: export CODECOV_TOKEN=<hidden>")
print("print: Not running: " + cmd)
# curl -Os https://cli.codecov.io/latest/linux/codecov ; sudo chmod +x codecov
# --disable-search does not seem to work
# -d with false directory does not seem to work
# So, remove gcno files before calling codecov
upload_dir = "nodist/obj_dir/upload"
os.makedirs(upload_dir, exist_ok=True)
cmd = "ci/codecov -v upload-process -Z" + " -f " + cc_dir + "/app_total.info )"
print("print: Not running:")
print(" export CODECOV_TOKEN=<hidden>")
print(" find . -name '*.gcno' -exec rm {} \\;")
print(" " + cmd)
ci_fold_end()
if Args.stage_enabled[19]:
print("*-* All Finished *-*")
print("")
print("* See report in " + cc_dir + "/html/index.html")
print(
"* Remember to make distclean && ./configure before working on non-coverage"
)
print("* Remember to make distclean && ./configure before working on non-coverage")
def clone_sources(cc_dir):
@@ -200,9 +197,8 @@ def clone_sources(cc_dir):
for globf in Source_Globs:
for infile in glob.glob(globf):
if re.match(r'^/', infile):
sys.exit(
"%Error: source globs should be relative not absolute filenames, "
+ infile)
sys.exit("%Error: source globs should be relative not absolute filenames, " +
infile)
outfile = cc_dir + "/" + infile
outpath = re.sub(r'/[^/]*$', '', outfile, count=1)
os.makedirs(outpath, exist_ok=True)
@@ -243,22 +239,20 @@ def clone_sources(cc_dir):
done = True
ofh.write(line + "\n")
print("Number of source lines automatically LCOV_EXCL_LINE'ed: %d" %
excluded_lines)
print("Number of source lines automatically LCOV_EXCL_BR_LINE'ed: %d" %
excluded_br_lines)
print("Number of source lines automatically LCOV_EXCL_LINE'ed: %d" % excluded_lines)
print("Number of source lines automatically LCOV_EXCL_BR_LINE'ed: %d" % excluded_br_lines)
def cleanup_abs_paths_info(cc_dir, infile, outfile):
lines = []
with open(infile, "r", encoding="utf8") as fh:
for line in fh:
if re.search(r'^SF:', line):
line = re.sub(os.environ['VERILATOR_ROOT'] + '/',
'',
line,
count=1)
if re.search(r'^SF:', line) and not re.search(r'^SF:/usr/', line):
line = re.sub(os.environ['VERILATOR_ROOT'] + '/', '', line, count=1)
line = re.sub(cc_dir + '/', '', line, count=1)
line = re.sub(r'^SF:.*?/include/', 'SF:include/', line, count=1)
line = re.sub(r'^SF:.*?/src/', 'SF:src/', line, count=1)
line = re.sub(r'^SF:.*?/test_regress/', 'SF:test_regress/', line, count=1)
line = re.sub(r'obj_dbg/verilog.y$', 'verilog.y', line)
# print("Remaining SF: "+line)
lines.append(line)
@@ -340,15 +334,13 @@ def ci_fold_end():
parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawDescriptionHelpFormatter,
description=
"""code_coverage builds Verilator with C++ coverage support and runs
description="""code_coverage builds Verilator with C++ coverage support and runs
tests with coverage enabled. This will rebuild the current object
files. Run as:
cd $VERILATOR_ROOT
nodist/code_coverage""",
epilog=
"""Copyright 2019-2024 by Wilson Snyder. This program is free software; you
epilog="""Copyright 2019-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.
@@ -358,22 +350,20 @@ SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
parser.add_argument('--debug', action='store_true', help='enable debug')
parser.add_argument('--hashset',
action='store',
help='pass test hashset onto driver.pl test harness')
help='pass test hashset onto driver.py test harness')
parser.add_argument('--scenarios',
action='store',
help='pass test scenarios onto driver.pl test harness')
parser.add_argument(
'--stages',
action='store',
help='runs a specific stage or range of stages (see the script)')
help='pass test scenarios onto driver.py test harness')
parser.add_argument('--stages',
'--stage',
action='store',
help='runs a specific stage or range of stages (see the script)')
parser.add_argument(
'--tests',
'--test',
action='append',
dest='tests',
default=[],
help=
'Instead of normal regressions, run the specified test(s), may be used multiple times'
)
help='Instead of normal regressions, run the specified test(s), may be used multiple times')
parser.add_argument('--no-stop',
dest='stop',
action='store_false',
+10 -21
View File
@@ -20,8 +20,7 @@ def dotread(filename):
vnum = 0
vertex_re = re.compile(r'^\t([a-zA-Z0-9_]+)\t(.*)$')
edge_re = re.compile(
r'^\t([a-zA-Z0-9_]+)\s+->\s+([a-zA-Z0-9_]+)\s*(.*)$')
edge_re = re.compile(r'^\t([a-zA-Z0-9_]+)\s+->\s+([a-zA-Z0-9_]+)\s*(.*)$')
for line in fh:
vertex_match = re.search(vertex_re, line)
@@ -29,11 +28,7 @@ def dotread(filename):
if vertex_match:
if vertex_match.group(1) != 'nTITLE':
header = False
Vertexes.append({
'num': vnum,
'line': line,
'name': vertex_match.group(1)
})
Vertexes.append({'num': vnum, 'line': line, 'name': vertex_match.group(1)})
vnum += 1
elif edge_match:
fromv = edge_match.group(1)
@@ -65,14 +60,13 @@ def cwrite(filename):
fh.write("void V3GraphTestImport::dotImport() {\n")
fh.write(" auto* gp = &m_graph;\n")
for ver in sorted(Vertexes, key=lambda ver: ver['num']):
fh.write(
" auto* %s = new V3GraphTestVertex{gp, \"%s\"}; if (%s) {}\n"
% (ver['name'], ver['name'], ver['name']))
fh.write(" auto* %s = new V3GraphTestVertex{gp, \"%s\"}; if (%s) {}\n" %
(ver['name'], ver['name'], ver['name']))
fh.write("\n")
for edge in Edges:
fh.write(" new V3GraphEdge{gp, %s, %s, %s, %s};\n" %
(edge['from'], edge['to'], edge['weight'],
"true" if edge['cutable'] else "false"))
fh.write(
" new V3GraphEdge{gp, %s, %s, %s, %s};\n" %
(edge['from'], edge['to'], edge['weight'], "true" if edge['cutable'] else "false"))
fh.write("}\n")
@@ -82,22 +76,17 @@ def cwrite(filename):
parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawDescriptionHelpFormatter,
description=
"""dot_importer takes a graphvis .dot file and converts into .cpp file.
description="""dot_importer takes a graphvis .dot file and converts into .cpp file.
This x.cpp file is then manually included in V3GraphTest.cpp to verify
various xsub-algorithms.""",
epilog=
"""Copyright 2005-2024 by Wilson Snyder. This program is free software; you
epilog="""Copyright 2005-2024 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
parser.add_argument('--debug',
action='store_const',
const=9,
help='enable debug')
parser.add_argument('--debug', action='store_const', const=9, help='enable debug')
parser.add_argument('filename', help='input .dot filename to process')
Args = parser.parse_args()
+374 -49
View File
@@ -18,20 +18,21 @@
$ ./fastcov.py --exclude /usr/include test/ --lcov -o report.info
$ genhtml -o code_coverage report.info
"""
import re
import os
import sys
import glob
import json
import time
import fnmatch
import logging
import argparse
import threading
import subprocess
import multiprocessing
from pathlib import Path
FASTCOV_VERSION = (1,7)
FASTCOV_VERSION = (1,15)
MINIMUM_PYTHON = (3,5)
MINIMUM_GCOV = (9,0,0)
@@ -40,6 +41,10 @@ START_TIME = time.monotonic()
GCOVS_TOTAL = 0
GCOVS_SKIPPED = 0
# Gcov Coverage File Extensions
GCOV_GCNO_EXT = ".gcno" # gcno = "[gc]ov [no]te"
GCOV_GCDA_EXT = ".gcda" # gcda = "[gc]ov [da]ta"
# For when things go wrong...
# Start error codes at 3 because 1-2 are special
# See https://stackoverflow.com/a/1535733/2516916
@@ -49,6 +54,8 @@ EXIT_CODES = {
"python_version": 4,
"unsupported_coverage_format": 5,
"excl_not_found": 6,
"bad_chunk_file": 7,
"missing_json_key": 8,
}
# Disable all logging in case developers are using this as a module
@@ -60,6 +67,132 @@ class FastcovFormatter(logging.Formatter):
log_message = super(FastcovFormatter, self).format(record)
return "[{:.3f}s] {}".format(stopwatch(), log_message)
class DiffParseError(Exception):
pass
class DiffParser(object):
def _refinePaths(self, diff_metadata, diff_base_dir):
diff_metadata.pop('/dev/null', None)
diff_metadata.pop('', None)
for key, value in diff_metadata.copy().items():
diff_metadata.pop(key)
#sources without added lines will be excluded
if value:
newpath = os.path.join(diff_base_dir, key) if diff_base_dir else os.path.abspath(key)
diff_metadata[newpath] = value
def _parseTargetFile(self, line_with_target_file):
#f.e. '+++ b/README.md1' or '+++ b/README.md1 timestamp'
target_source = line_with_target_file[4:].partition('\t')[0].strip()
target_source = target_source[2:] if target_source.startswith('b/') else target_source
return target_source
def _parseHunkBoundaries(self, line_with_hunk_boundaries, line_index):
#f.e. '@@ -121,4 +122,4 @@ Time to process all gcda and parse all gcov:'
# Here ['-121,4', '+122,4']
lines_info = line_with_hunk_boundaries[3:].partition("@@")[0].strip().split(' ')
if len(lines_info) != 2:
raise DiffParseError("Found invalid hunk. Line #{}. {}".format(line_index, line_with_hunk_boundaries))
# Here ['122','4']
target_lines_info = lines_info[1].strip('+').partition(',')
target_line_current = int(target_lines_info[0])
target_lines_count = int(target_lines_info[2]) if target_lines_info[2] else 1
# Here ['121','4']
source_lines_info = lines_info[0].strip('-').partition(',')
source_line_current = int(source_lines_info[0])
source_lines_count = int(source_lines_info[2]) if source_lines_info[2] else 1
return target_line_current, target_lines_count, source_line_current, source_lines_count
def parseDiffFile(self, diff_file, diff_base_dir, fallback_encodings=[]):
diff_metadata = {}
target_source = None
target_hunk = set()
target_line_current = 0
target_line_end = 0
source_line_current = 0
source_line_end = 0
found_hunk = False
for i, line in enumerate(getSourceLines(diff_file, fallback_encodings), 1):
line = line.rstrip()
if not found_hunk:
if line.startswith('+++ '):
# refresh file
target_source = self._parseTargetFile(line)
elif line.startswith('@@ '):
# refresh hunk
target_line_current, target_lines_count, source_line_current, source_lines_count = self._parseHunkBoundaries(line, i)
target_line_end = target_line_current + target_lines_count
source_line_end = source_line_current + source_lines_count
target_hunk = set()
found_hunk = True
continue
if target_line_current > target_line_end or source_line_current > source_line_end:
raise DiffParseError("Hunk longer than expected. Line #{}. {}".format(i, line))
if line.startswith('+'):
#line related to target
target_hunk.add(target_line_current)
target_line_current = target_line_current + 1
elif line.startswith(' ') or line == '':
# line related to both
target_line_current = target_line_current + 1
source_line_current = source_line_current + 1
elif line.startswith('-'):
# line related to source
source_line_current = source_line_current + 1
elif not line.startswith('\\'): # No newline at end of file
# line with newline marker is not included into any boundaries
raise DiffParseError("Found unrecognized hunk line type. Line #{}. {}".format(i, line))
if target_line_current == target_line_end and source_line_current == source_line_end:
# Checked all lines, save data
if target_source in diff_metadata:
diff_metadata[target_source] = target_hunk.union(diff_metadata[target_source])
else:
diff_metadata[target_source] = target_hunk
target_hunk = set()
found_hunk = False
if target_line_current != target_line_end or source_line_current != source_line_end:
raise DiffParseError("Unexpected end of file. Expected hunk with {} target lines, {} source lines".format(
target_line_end - target_line_current, source_line_end - source_line_current))
self._refinePaths(diff_metadata, diff_base_dir)
return diff_metadata
def filterByDiff(self, diff_file, dir_base_dir, fastcov_json, fallback_encodings=[]):
diff_metadata = self.parseDiffFile(diff_file, dir_base_dir, fallback_encodings)
logging.debug("Include only next files: {}".format(diff_metadata.keys()))
excluded_files_count = 0
excluded_lines_count = 0
for source in list(fastcov_json["sources"].keys()):
diff_lines = diff_metadata.get(source, None)
if not diff_lines:
excluded_files_count = excluded_files_count + 1
logging.debug("Exclude {} according to diff file".format(source))
fastcov_json["sources"].pop(source)
continue
for test_name, report_data in fastcov_json["sources"][source].copy().items():
#No info about functions boundaries, removing all
for function in list(report_data["functions"].keys()):
report_data["functions"].pop(function, None)
for line in list(report_data["lines"].keys()):
if line not in diff_lines:
excluded_lines_count = excluded_lines_count + 1
report_data["lines"].pop(line)
for branch_line in list(report_data["branches"].keys()):
if branch_line not in diff_lines:
report_data["branches"].pop(branch_line)
if len(report_data["lines"]) == 0:
fastcov_json["sources"][source].pop(test_name)
if len(fastcov_json["sources"][source]) == 0:
excluded_files_count = excluded_files_count + 1
logging.debug('Exclude {} file as it has no lines due to diff filter'.format(source))
fastcov_json["sources"].pop(source)
logging.info("Excluded {} files and {} lines according to diff file".format(excluded_files_count, excluded_lines_count))
return fastcov_json
def chunks(l, n):
"""Yield successive n-sized chunks from l."""
for i in range(0, len(l), n):
@@ -69,6 +202,10 @@ def setExitCode(key):
global EXIT_CODE
EXIT_CODE = EXIT_CODES[key]
def setExitCodeRaw(code):
global EXIT_CODE
EXIT_CODE = code
def incrementCounters(total, skipped):
global GCOVS_TOTAL
global GCOVS_SKIPPED
@@ -98,10 +235,48 @@ def getGcovVersion(gcov):
p.wait()
return parseVersionFromLine(output.split("\n")[0])
def tryParseNumber(s):
try:
return int(s)
except ValueError:
# Log a warning if not hyphen
if s != "-":
logging.warning("Unsupported numerical value '%s', using 0", s)
# Default to 0 if we can't parse the number (e.g. "-", "NaN", etc.)
return 0
def removeFiles(files):
for file in files:
os.remove(file)
def processPrefix(path, prefix, prefix_strip):
p = Path(path)
if p.exists() or not p.is_absolute():
return path
if prefix_strip > 0:
segments = p.parts
if len(segments) < prefix_strip + 1:
logging.warning("Couldn't strip %i path levels from %s.", prefix_strip, path)
return path
segments = segments[prefix_strip+1:]
p = Path(segments[0])
segments = segments[1:]
for s in segments:
p = p.joinpath(s)
if len(prefix) > 0:
if p.is_absolute():
p = Path(prefix).joinpath(p.relative_to('/'))
else:
p = Path(prefix).joinpath(p)
return str(p)
def getFilteredCoverageFiles(coverage_files, exclude):
def excludeGcda(gcda):
for ex in exclude:
@@ -111,11 +286,16 @@ def getFilteredCoverageFiles(coverage_files, exclude):
return True
return list(filter(excludeGcda, coverage_files))
def globCoverageFiles(cwd, coverage_type):
return glob.glob(os.path.join(os.path.abspath(cwd), "**/*" + coverage_type), recursive=True)
def findCoverageFiles(cwd, coverage_files, use_gcno):
coverage_type = "user provided"
if not coverage_files:
coverage_type = "gcno" if use_gcno else "gcda"
coverage_files = glob.glob(os.path.join(os.path.abspath(cwd), "**/*." + coverage_type), recursive=True)
# gcov strips off extension of whatever you pass it and searches [extensionless name] + .gcno/.gcda
# We should pass either gcno or gcda, but not both - if you pass both it will be processed twice
coverage_type = GCOV_GCNO_EXT if use_gcno else GCOV_GCDA_EXT
coverage_files = globCoverageFiles(cwd, coverage_type)
logging.info("Found {} coverage files ({})".format(len(coverage_files), coverage_type))
logging.debug("Coverage files found:\n %s", "\n ".join(coverage_files))
@@ -125,15 +305,32 @@ def gcovWorker(data_q, metrics_q, args, chunk, gcov_filter_options):
base_report = {"sources": {}}
gcovs_total = 0
gcovs_skipped = 0
error_exit = False
gcov_args = "-it"
gcov_bin = args.gcov
gcov_args = ["--json-format", "--stdout"]
if args.branchcoverage or args.xbranchcoverage:
gcov_args += "b"
gcov_args.append("--branch-probabilities")
p = subprocess.Popen([args.gcov, gcov_args] + chunk, cwd=args.cdirectory, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
for line in iter(p.stdout.readline, b''):
intermediate_json = json.loads(line.decode(sys.stdout.encoding))
intermediate_json_files = processGcovs(args.cdirectory, intermediate_json["files"], gcov_filter_options)
encoding = sys.stdout.encoding if sys.stdout.encoding else 'UTF-8'
workdir = args.cdirectory if args.cdirectory else "."
p = subprocess.Popen([gcov_bin] + gcov_args + chunk, cwd=workdir, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
for i, line in enumerate(iter(p.stdout.readline, b'')):
try:
intermediate_json = json.loads(line.decode(encoding))
except json.decoder.JSONDecodeError as e:
logging.error("Could not process chunk file '{}' ({}/{})".format(chunk[i], i+1, len(chunk)))
logging.error(str(e))
setExitCode("bad_chunk_file")
continue
if "current_working_directory" not in intermediate_json:
logging.error("Missing 'current_working_directory' for data file: {}".format(intermediate_json))
setExitCode("missing_json_key")
continue
intermediate_json_files = processGcovs(args.cdirectory, intermediate_json["files"], intermediate_json["current_working_directory"], gcov_filter_options)
for f in intermediate_json_files:
distillSource(f, base_report["sources"], args.test_name, args.xbranchcoverage)
gcovs_total += len(intermediate_json["files"])
@@ -143,6 +340,8 @@ def gcovWorker(data_q, metrics_q, args, chunk, gcov_filter_options):
data_q.put(base_report)
metrics_q.put((gcovs_total, gcovs_skipped))
sys.exit(EXIT_CODE)
def processGcdas(args, coverage_files, gcov_filter_options):
chunk_size = max(args.minimum_chunk, int(len(coverage_files) / args.jobs) + 1)
@@ -163,6 +362,8 @@ def processGcdas(args, coverage_files, gcov_filter_options):
for p in processes:
p.join()
if p.exitcode != 0:
setExitCodeRaw(p.exitcode)
base_fastcov = fastcov_jsons.pop()
for fj in fastcov_jsons:
@@ -184,6 +385,12 @@ def shouldFilterSource(source, gcov_filter_options):
logging.debug("Filtering coverage for '%s' due to option '--exclude %s'", source, ex)
return True
# Check exclude filter
for ex_glob in gcov_filter_options["exclude_glob"]:
if fnmatch.fnmatch(source, ex_glob):
logging.debug("Filtering coverage for '%s' due to option '--exclude-glob %s'", source, ex_glob)
return True
# Check include filter
if gcov_filter_options["include"]:
included = False
@@ -205,9 +412,12 @@ def filterFastcov(fastcov_json, args):
if shouldFilterSource(source, gcov_filter_options):
del fastcov_json["sources"][source]
def processGcov(cwd, gcov, files, gcov_filter_options):
def processGcov(cwd, gcov, source_base_dir, files, gcov_filter_options):
# Uses cwd if set, else source_base_dir from gcov json. If both are empty, uses "."
base_dir = cwd if cwd else source_base_dir
base_dir = base_dir if base_dir else "."
# Add absolute path
gcov["file_abs"] = os.path.abspath(os.path.join(cwd, gcov["file"]))
gcov["file_abs"] = os.path.abspath(os.path.join(base_dir, gcov["file"]))
if shouldFilterSource(gcov["file_abs"], gcov_filter_options):
return
@@ -215,10 +425,10 @@ def processGcov(cwd, gcov, files, gcov_filter_options):
files.append(gcov)
logging.debug("Accepted coverage for '%s'", gcov["file_abs"])
def processGcovs(cwd, gcov_files, gcov_filter_options):
def processGcovs(cwd, gcov_files, source_base_dir, gcov_filter_options):
files = []
for gcov in gcov_files:
processGcov(cwd, gcov, files, gcov_filter_options)
processGcov(cwd, gcov, source_base_dir, files, gcov_filter_options)
return files
def dumpBranchCoverageToLcovInfo(f, branches):
@@ -288,15 +498,44 @@ def getSourceLines(source, fallback_encodings=[]):
with open(source, errors="ignore") as f:
return f.readlines()
def exclProcessSource(fastcov_sources, source, exclude_branches_sw, include_branches_sw, fallback_encodings):
def containsMarker(markers, strBody):
for marker in markers:
if marker in strBody:
return True
return False
# Returns whether source coverage changed or not
def exclProcessSource(fastcov_sources, source, exclude_branches_sw, include_branches_sw, exclude_line_marker, fallback_encodings, gcov_prefix, gcov_prefix_strip):
source_to_open = processPrefix(source, gcov_prefix, gcov_prefix_strip)
# Before doing any work, check if this file even needs to be processed
if not exclude_branches_sw and not include_branches_sw:
# Ignore unencodable characters
with open(source_to_open, errors="ignore") as f:
if not containsMarker(exclude_line_marker + ["LCOV_EXCL"], f.read()):
return False
# If we've made it this far we have to check every line
start_line = 0
end_line = 0
# Start enumeration at line 1 because the first line of the file is line 1 not 0
for i, line in enumerate(getSourceLines(source, fallback_encodings), 1):
for i, line in enumerate(getSourceLines(source_to_open, fallback_encodings), 1):
# Cycle through test names (likely only 1)
for test_name in fastcov_sources[source]:
fastcov_data = fastcov_sources[source][test_name]
# Check if branch coverage should be deleted based on CLI options
if (exclude_branches_sw or include_branches_sw) and (i in fastcov_data["branches"]):
del_exclude_br = exclude_branches_sw and any(line.lstrip().startswith(e) for e in exclude_branches_sw)
del_include_br = include_branches_sw and all(not line.lstrip().startswith(e) for e in include_branches_sw)
if del_exclude_br or del_include_br:
del fastcov_data["branches"][i]
# Skip to next line as soon as possible
if not containsMarker(exclude_line_marker + ["LCOV_EXCL"], line):
continue
# Build line to function dict so can quickly delete by line number
line_to_func = {}
for f in fastcov_data["functions"].keys():
@@ -305,16 +544,7 @@ def exclProcessSource(fastcov_sources, source, exclude_branches_sw, include_bran
line_to_func[l] = set()
line_to_func[l].add(f)
if i in fastcov_data["branches"]:
del_exclude_br = exclude_branches_sw and any(line.lstrip().startswith(e) for e in exclude_branches_sw)
del_include_br = include_branches_sw and all(not line.lstrip().startswith(e) for e in include_branches_sw)
if del_exclude_br or del_include_br:
del fastcov_data["branches"][i]
if "LCOV_EXCL" not in line:
continue
if "LCOV_EXCL_LINE" in line:
if any(marker in line for marker in exclude_line_marker):
for key in ["lines", "branches"]:
if i in fastcov_data[key]:
del fastcov_data[key][i]
@@ -347,26 +577,56 @@ def exclProcessSource(fastcov_sources, source, exclude_branches_sw, include_bran
if i in fastcov_data["branches"]:
del fastcov_data["branches"][i]
def exclMarkerWorker(fastcov_sources, chunk, exclude_branches_sw, include_branches_sw, fallback_encodings):
# Source coverage changed
return True
def exclMarkerWorker(data_q, fastcov_sources, chunk, exclude_branches_sw, include_branches_sw, exclude_line_marker, fallback_encodings, gcov_prefix, gcov_prefix_strip):
changed_sources = []
for source in chunk:
try:
exclProcessSource(fastcov_sources, source, exclude_branches_sw, include_branches_sw, fallback_encodings)
if exclProcessSource(fastcov_sources, source, exclude_branches_sw, include_branches_sw, exclude_line_marker, fallback_encodings, gcov_prefix, gcov_prefix_strip):
changed_sources.append((source, fastcov_sources[source]))
except FileNotFoundError:
logging.error("Could not find '%s' to scan for exclusion markers...", source)
setExitCode("excl_not_found") # Set exit code because of error
def scanExclusionMarkers(fastcov_json, jobs, exclude_branches_sw, include_branches_sw, min_chunk_size, fallback_encodings):
# Write out changed sources back to main fastcov file
data_q.put(changed_sources)
# Exit current process with appropriate code
sys.exit(EXIT_CODE)
def processExclusionMarkers(fastcov_json, jobs, exclude_branches_sw, include_branches_sw, exclude_line_marker, min_chunk_size, fallback_encodings, gcov_prefix, gcov_prefix_strip):
chunk_size = max(min_chunk_size, int(len(fastcov_json["sources"]) / jobs) + 1)
threads = []
processes = []
data_q = multiprocessing.Queue()
for chunk in chunks(list(fastcov_json["sources"].keys()), chunk_size):
t = threading.Thread(target=exclMarkerWorker, args=(fastcov_json["sources"], chunk, exclude_branches_sw, include_branches_sw, fallback_encodings))
threads.append(t)
t.start()
p = multiprocessing.Process(target=exclMarkerWorker, args=(data_q, fastcov_json["sources"], chunk, exclude_branches_sw, include_branches_sw, exclude_line_marker, fallback_encodings, gcov_prefix, gcov_prefix_strip))
processes.append(p)
p.start()
logging.info("Spawned {} threads each scanning at most {} source files".format(len(threads), chunk_size))
for t in threads:
t.join()
logging.info("Spawned {} exclusion marker scanning processes, each processing at most {} source files".format(len(processes), chunk_size))
changed_sources = []
for p in processes:
changed_sources += data_q.get()
for p in processes:
p.join()
if p.exitcode != 0:
setExitCodeRaw(p.exitcode)
for changed_source in changed_sources:
fastcov_json["sources"][changed_source[0]] = changed_source[1]
def validateSources(fastcov_json, gcov_prefix, gcov_prefix_strip):
logging.info("Checking if all sources exist")
for source in fastcov_json["sources"].keys():
source = processPrefix(source, gcov_prefix, gcov_prefix_strip)
if not os.path.exists(source):
logging.error("Cannot find '{}'".format(source))
def distillFunction(function_raw, functions):
function_name = function_raw["name"]
@@ -413,6 +673,13 @@ def filterExceptionalBranches(branches):
def distillLine(line_raw, lines, branches, include_exceptional_branches):
line_number = int(line_raw["line_number"])
count = int(line_raw["count"])
if count < 0:
if "function_name" in line_raw:
logging.warning("Ignoring negative count found in '%s'.", line_raw["function_name"])
else:
logging.warning("Ignoring negative count.")
count = 0
if line_number not in lines:
lines[line_number] = count
else:
@@ -458,6 +725,7 @@ def getGcovFilterOptions(args):
"sources": set([os.path.abspath(s) for s in args.sources]), #Make paths absolute, use set for fast lookups
"include": args.includepost,
"exclude": args.excludepost,
"exclude_glob":args.excludepost_glob
}
def addDicts(dict1, dict2):
@@ -529,30 +797,30 @@ def parseInfo(path):
current_test_name = line[3:].strip()
elif line.startswith("SF:"):
current_sf = line[3:].strip()
fastcov_json["sources"][current_sf] = {
fastcov_json["sources"].setdefault(current_sf, {
current_test_name: {
"functions": {},
"branches": {},
"lines": {},
}
}
})
current_data = fastcov_json["sources"][current_sf][current_test_name]
elif line.startswith("FN:"):
line_num, function_name = line[3:].strip().split(",")
current_data["functions"][function_name] = {}
current_data["functions"][function_name]["start_line"] = int(line_num)
current_data["functions"][function_name]["start_line"] = tryParseNumber(line_num)
elif line.startswith("FNDA:"):
count, function_name = line[5:].strip().split(",")
current_data["functions"][function_name]["execution_count"] = int(count)
current_data["functions"][function_name]["execution_count"] = tryParseNumber(count)
elif line.startswith("DA:"):
line_num, count = line[3:].strip().split(",")
current_data["lines"][line_num] = int(count)
current_data["lines"][line_num] = tryParseNumber(count)
elif line.startswith("BRDA:"):
branch_tokens = line[5:].strip().split(",")
line_num, count = branch_tokens[0], branch_tokens[-1]
if line_num not in current_data["branches"]:
current_data["branches"][line_num] = []
current_data["branches"][line_num].append(int(count))
current_data["branches"][line_num].append(tryParseNumber(count))
return fastcov_json
@@ -610,9 +878,9 @@ def getGcovCoverage(args):
coverage_files = getFilteredCoverageFiles(coverage_files, args.excludepre)
logging.info("Found {} coverage files after filtering".format(len(coverage_files)))
# We "zero" the "counters" by deleting all gcda files
# We "zero" the "counters" by simply deleting all gcda files
if args.zerocounters:
removeFiles(coverage_files)
removeFiles(globCoverageFiles(args.directory, GCOV_GCDA_EXT))
logging.info("Removed {} .gcda files".format(len(coverage_files)))
sys.exit()
@@ -626,6 +894,37 @@ def getGcovCoverage(args):
return fastcov_json
def formatCoveredItems(covered, total):
coverage = (covered * 100.0) / total if total > 0 else 100.0
coverage = round(coverage, 2)
return "{:.2f}%, {}/{}".format(coverage, covered, total)
def dumpStatistic(fastcov_json):
total_lines = 0
covered_lines = 0
total_functions = 0
covered_functions = 0
total_files = len(fastcov_json["sources"])
covered_files = 0
for source_name, source in fastcov_json["sources"].items():
is_file_covered = False
for test_name, test in source.items():
total_lines += len(test["lines"])
for execution_count in test["lines"].values():
covered_lines += 1 if execution_count > 0 else 0
is_file_covered = is_file_covered or execution_count > 0
total_functions += len(test["functions"])
for function in test["functions"].values():
covered_functions += 1 if function['execution_count'] > 0 else 0
is_file_covered = is_file_covered or function['execution_count'] > 0
if is_file_covered:
covered_files = covered_files + 1
logging.info("Files Coverage: {}".format(formatCoveredItems(covered_files, total_files)))
logging.info("Functions Coverage: {}".format(formatCoveredItems(covered_functions, total_functions)))
logging.info("Lines Coverage: {}".format(formatCoveredItems(covered_lines, total_lines)))
def dumpFile(fastcov_json, args):
if args.lcov:
dumpToLcovInfo(fastcov_json, args.output)
@@ -634,6 +933,9 @@ def dumpFile(fastcov_json, args):
dumpToJson(fastcov_json, args.output)
logging.info("Created fastcov json file '{}'".format(args.output))
if args.dump_statistic:
dumpStatistic(fastcov_json)
def tupleToDotted(tup):
return ".".join(map(str, tup))
@@ -655,15 +957,19 @@ def parseArgs():
# Filtering Options
parser.add_argument('-s', '--source-files', dest='sources', nargs="+", metavar='', default=[], help='Filter: Specify exactly which source files should be included in the final report. Paths must be either absolute or relative to current directory.')
parser.add_argument('-e', '--exclude', dest='excludepost', nargs="+", metavar='', default=[], help='Filter: Exclude source files from final report if they contain one of the provided substrings (i.e. /usr/include test/, etc.)')
parser.add_argument('-eg', '--exclude-glob', dest='excludepost_glob', nargs="+", metavar='', default=[], help='Filter: Exclude source files by glob pattern from final report if they contain one of the provided substrings (i.e. /usr/include test/, etc.)')
parser.add_argument('-i', '--include', dest='includepost', nargs="+", metavar='', default=[], help='Filter: Only include source files in final report that contain one of the provided substrings (i.e. src/ etc.)')
parser.add_argument('-f', '--gcda-files', dest='coverage_files', nargs="+", metavar='', default=[], help='Filter: Specify exactly which gcda or gcno files should be processed. Note that specifying gcno causes both gcno and gcda to be processed.')
parser.add_argument('-E', '--exclude-gcda', dest='excludepre', nargs="+", metavar='', default=[], help='Filter: Exclude gcda or gcno files from being processed via simple find matching (not regex)')
parser.add_argument('-u', '--diff-filter', dest='diff_file', default='', help='Unified diff file with changes which will be included into final report')
parser.add_argument('-ub', '--diff-base-dir', dest='diff_base_dir', default='', help='Base directory for sources in unified diff file, usually repository dir')
parser.add_argument('-ce', '--custom-exclusion-marker', dest='exclude_line_marker', nargs="+", metavar='', default=["LCOV_EXCL_LINE"], help='Filter: Add filter for lines that will be excluded from coverage (same behavior as "LCOV_EXCL_LINE")')
parser.add_argument('-g', '--gcov', dest='gcov', default='gcov', help='Which gcov binary to use')
parser.add_argument('-d', '--search-directory', dest='directory', default=".", help='Base directory to recursively search for gcda files (default: .)')
parser.add_argument('-c', '--compiler-directory', dest='cdirectory', default=".", help='Base directory compiler was invoked from (default: .) \
This needs to be set if invoking fastcov from somewhere other than the base compiler directory.')
parser.add_argument('-c', '--compiler-directory', dest='cdirectory', default="", help='Base directory compiler was invoked from (default: . or read from gcov) \
This needs to be set if invoking fastcov from somewhere other than the base compiler directory. No need to set it if gcc version > 9.1')
parser.add_argument('-j', '--jobs', dest='jobs', type=int, default=multiprocessing.cpu_count(), help='Number of parallel gcov to spawn (default: {}).'.format(multiprocessing.cpu_count()))
parser.add_argument('-m', '--minimum-chunk-size', dest='minimum_chunk', type=int, default=5, help='Minimum number of files a thread should process (default: 5). \
@@ -672,17 +978,23 @@ def parseArgs():
parser.add_argument('-F', '--fallback-encodings', dest='fallback_encodings', nargs="+", metavar='', default=[], help='List of encodings to try if opening a source file with the default fails (i.e. latin1, etc.). This option is not usually needed.')
parser.add_argument('-l', '--lcov', dest='lcov', action="store_true", help='Output in lcov info format instead of fastcov json')
parser.add_argument('-o', '--output', dest='output', default="coverage.json", help='Name of output file (default: coverage.json)')
parser.add_argument('-o', '--output', dest='output', default="", help='Name of output file (default: coverage.json or coverage.info, depends on --lcov option)')
parser.add_argument('-q', '--quiet', dest='quiet', action="store_true", help='Suppress output to stdout')
parser.add_argument('-t', '--test-name', dest='test_name', default="", help='Specify a test name for the coverage. Equivalent to lcov\'s `-t`.')
parser.add_argument('-C', '--add-tracefile', dest='combine', nargs="+", help='Combine multiple coverage files into one. If this flag is specified, fastcov will do a combine operation instead invoking gcov. Equivalent to lcov\'s `-a`.')
parser.add_argument('-V', '--verbose', dest="verbose", action="store_true", help="Print more detailed information about what fastcov is doing")
parser.add_argument('-w', '--validate-sources', dest="validate_sources", action="store_true", help="Check if every source file exists")
parser.add_argument('-p', '--dump-statistic', dest="dump_statistic", action="store_true", help="Dump total statistic at the end")
parser.add_argument('-v', '--version', action="version", version='%(prog)s {version}'.format(version=__version__), help="Show program's version number and exit")
args = parser.parse_args()
parser.add_argument('-gps', '--gcov_prefix_strip', dest="gcov_prefix_strip", action="store", default=0, type=int, help="The number of initial directory names to strip off the absolute paths in the object file.")
parser.add_argument('-gp', '--gcov_prefix', dest="gcov_prefix", action="store", default="", help="The prefix to add to the paths in the object file.")
args = parser.parse_args()
if not args.output:
args.output = 'coverage.info' if args.lcov else 'coverage.json'
return args
def checkPythonVersion(version):
@@ -717,6 +1029,12 @@ def main():
# Setup logging
setupLogging(args.quiet, args.verbose)
if args.gcov_prefix_strip > 0:
os.environ["GCOV_PREFIX_STRIP"] = str(args.gcov_prefix_strip)
if len(args.gcov_prefix) > 0:
os.environ["GCOV_PREFIX"] = args.gcov_prefix
# Get report from appropriate source
if args.combine:
fastcov_json = getCombineCoverage(args)
@@ -727,9 +1045,16 @@ def main():
# Scan for exclusion markers
if not skip_exclusion_markers:
scanExclusionMarkers(fastcov_json, args.jobs, args.exclude_branches_sw, args.include_branches_sw, args.minimum_chunk, args.fallback_encodings)
processExclusionMarkers(fastcov_json, args.jobs, args.exclude_branches_sw, args.include_branches_sw, args.exclude_line_marker, args.minimum_chunk, args.fallback_encodings, args.gcov_prefix, args.gcov_prefix_strip)
logging.info("Scanned {} source files for exclusion markers".format(len(fastcov_json["sources"])))
if args.diff_file:
logging.info("Filtering according to {} file".format(args.diff_file))
DiffParser().filterByDiff(args.diff_file, args.diff_base_dir, fastcov_json, args.fallback_encodings)
if args.validate_sources:
validateSources(fastcov_json, args.gcov_prefix, args.gcov_prefix_strip)
# Dump to desired file format
dumpFile(fastcov_json, args)
+7 -5
View File
@@ -19,9 +19,12 @@ from argparse import ArgumentParser
def interesting(s):
if 'assert' in s: return 1
if 'Assert' in s: return 1
if 'Aborted' in s: return 1
if 'assert' in s:
return 1
if 'Assert' in s:
return 1
if 'Aborted' in s:
return 1
if 'terminate' in s:
if 'unterminated' in s:
return 0
@@ -41,8 +44,7 @@ def main():
for infile in glob(args.dir + '/*'):
# Input filenames are known not to contain spaces or other unusual
# characters, therefore this works.
status, output = getstatusoutput('../../bin/verilator_bin --cc ' +
infile)
status, output = getstatusoutput('../../bin/verilator_bin --cc ' + infile)
if interesting(output):
print(infile)
print(status)
+4 -2
View File
@@ -51,9 +51,11 @@ def write_file(filename, contents):
def parse_line(s):
# str->maybe str
if len(s) == 0: return None
if len(s) == 0:
return None
part = skip_while(lambda x: x != '"', s)
if len(part) == 0 or part[0] != '"': return None
if len(part) == 0 or part[0] != '"':
return None
literal_part = take_while(lambda x: x != '"', part[1:])
return ''.join(filter(lambda x: x != '\\', literal_part))
+12 -19
View File
@@ -31,7 +31,10 @@ def test():
print("== stage 0")
run("/bin/rm -rf " + blddir)
run("/bin/mkdir -p " + blddir)
run("cd " + blddir + " && " + srcdir + "/configure --prefix " + prefix)
# Matches Ubuntu's e.g. /usr/share/pkgconfig/verilator.pc
run("cd " + blddir + " && " + srcdir + "/configure --prefix " + prefix +
" --exec-prefix " + prefix + " --datarootdir " + prefix + "/share" + " --includedir " +
prefix + "/share/verilator/include")
run("cd " + blddir + " && make -j " + str(calc_jobs()))
# Install it under the prefix
@@ -41,8 +44,7 @@ def test():
run("/bin/mkdir -p " + prefix)
run("cd " + blddir + " && make install")
run("test -e " + prefix + "/share/man/man1/verilator.1")
run("test -e " + prefix +
"/share/verilator/examples/make_tracing_c/Makefile")
run("test -e " + prefix + "/share/verilator/examples/make_tracing_c/Makefile")
run("test -e " + prefix + "/share/verilator/include/verilated.h")
run("test -e " + prefix + "/bin/verilator")
run("test -e " + prefix + "/bin/verilator_bin")
@@ -58,10 +60,8 @@ def test():
run("/bin/mkdir -p " + odir)
path = prefix + "/bin" + ":" + prefix + "/share/bin"
write_verilog(odir)
run("cd " + odir + " && PATH=" + path +
":$PATH verilator --cc top.v --exe sim_main.cpp")
run("cd " + odir + "/obj_dir && PATH=" + path +
":$PATH make -f Vtop.mk")
run("cd " + odir + " && PATH=" + path + ":$PATH verilator --cc top.v --exe sim_main.cpp")
run("cd " + odir + "/obj_dir && PATH=" + path + ":$PATH make -f Vtop.mk")
run("cd " + odir + " && PATH=" + path + ":$PATH obj_dir/Vtop")
# run a test using exact path to binary
@@ -72,8 +72,7 @@ def test():
run("/bin/mkdir -p " + odir)
write_verilog(odir)
bin1 = prefix + "/bin"
run("cd " + odir + " && " + bin1 +
"/verilator --cc top.v --exe sim_main.cpp")
run("cd " + odir + " && " + bin1 + "/verilator --cc top.v --exe sim_main.cpp")
run("cd " + odir + "/obj_dir && make -f Vtop.mk")
run("cd " + odir + "/obj_dir && ./Vtop")
@@ -88,8 +87,7 @@ def write_verilog(odir):
def cleanenv():
for var in os.environ:
if var in ('VERILATOR_ROOT', 'VERILATOR_INCLUDE',
'VERILATOR_NO_OPT_BUILD'):
if var in ('VERILATOR_ROOT', 'VERILATOR_INCLUDE', 'VERILATOR_NO_OPT_BUILD'):
print("unset %s # Was '%s'" % (var, os.environ[var]))
del os.environ[var]
@@ -113,21 +111,16 @@ def run(command):
parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawDescriptionHelpFormatter,
description=
"""install_test performs several make-and-install iterations to verify the
description="""install_test performs several make-and-install iterations to verify the
Verilator kit. It isn't part of the normal "make test" due to the number
of builds required.""",
epilog=
"""Copyright 2009-2024 by Wilson Snyder. This program is free software; you
epilog="""Copyright 2009-2024 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
parser.add_argument('--debug',
action='store_const',
const=9,
help='enable debug')
parser.add_argument('--debug', action='store_const', const=9, help='enable debug')
parser.add_argument('--stage',
type=int,
default=0,
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
# pylint: disable=
######################################################################
import argparse
import re
import sys
SUPPRESSES = [
"**********",
"E0602: Undefined variable 'test' (undefined-variable)",
"E0602: Undefined variable 're' (undefined-variable)",
"E0602: Undefined variable 'os' (undefined-variable)",
"E0602: Undefined variable 'glob' (undefined-variable)",
"W0611: Unused import vltest_bootstrap (unused-import)",
]
######################################################################
def process():
anymsg = False
for line in sys.stdin:
line = line.rstrip();
show = True
for msg in SUPPRESSES:
if msg in line:
show = False
continue
if show:
print(line)
anymsg = True
if anymsg:
sys.exit("%Error: See messages above")
#######################################################################
#######################################################################
parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawDescriptionHelpFormatter,
description="""lint_py_test_filter is used to filter
pylint output for expected errors in Verilator test_regress/*.py tests.""",
epilog="""Copyright 2024-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""")
parser.add_argument('--debug', action='store_true', help='enable debug')
Args = parser.parse_args()
process()
######################################################################
# Local Variables:
# compile-command: "cd .. ; make lint-py-pylint-tests"
# End:
+119
View File
@@ -0,0 +1,119 @@
#!/usr/bin/env python3
# pylint: disable=C0114,C0116,C0209,R0912,R0915
######################################################################
import argparse
import os
import re
#from pprint import pprint,pformat
#######################################################################
def message_section(msg):
"""Return sorting-section number for given commit message"""
if re.match(r'^Support', msg):
return 10
if re.match(r'^Add', msg):
return 20
if re.match(r'^Improve', msg):
return 30
if re.match(r'^Fix', msg):
return 40
if re.match(r'^(Internals|CI|Tests)', msg):
return -1
return 0
def process():
cmd = "git log"
msgs = {}
with os.popen(cmd) as fh:
author = ""
lineno = 0
for line in fh:
lineno += 1
line = line.rstrip()
if re.match(r'^Date', line):
continue
if re.match(r'^commit', line):
continue
if re.search(r'Commentary: Changes update', line):
break
am = re.match(r'^Author: (.*) <(.*)>', line)
dm = re.match(r'^ +(.*)', line)
if am:
email = am.group(2)
author = am.group(1)
if re.search(r'antmicro', email):
author += ", Antmicro Ltd."
if re.search(r'github action', author):
author = ""
continue
elif author != "" and dm:
msg = dm.group(1)
if not re.search(r'\.$', msg):
msg += '.'
msg += ' [' + author + ']'
mid = re.search(r'\(#([0-9][0-9][0-9][0-9]+)', line)
if mid:
bug_id = mid.group(1)
else:
bug_id = " %d" % lineno
section = message_section(msg)
if section >= 0:
key = "%06s_%06s_%06d" % (section, bug_id, lineno)
msgs[key] = '* ' + msg
# print("i [%s] %s" % (key, msg))
author = ""
if not msgs:
print("No Changes need to be inserted.")
return
print()
print("Insertion-sort the following lines into 'Changes' file:")
print()
dedup = {}
for key in sorted(msgs.keys()):
if msgs[key] not in dedup:
dedup[msgs[key]] = True
print(msgs[key])
print()
print("You may now want to clean up spelling, and commit:")
print(" (cd docs ; make spelling)")
print(" git ci -am 'Commentary: Changes update'")
print()
#######################################################################
parser = argparse.ArgumentParser(
allow_abbrev=False,
prog="log_changes",
description="Create example entries for 'Changes' from parsing 'git log'",
epilog="""Copyright 2019-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""")
parser.add_argument('--debug', action='store_true', help='enable debug')
Args = parser.parse_args()
process()
######################################################################
# Local Variables:
# compile-command: "cd .. ; nodist/log_changes"
# End:
+9 -7
View File
@@ -47,9 +47,12 @@ class AstseeCmd(gdb.Command):
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"))
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
@@ -58,8 +61,8 @@ class AstseeCmd(gdb.Command):
# 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:
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
@@ -68,8 +71,7 @@ class AstseeCmd(gdb.Command):
astsee_args.newfile = newfile.name
if astsee_args.meta is None:
# pass
gdb.execute(
f'call AstNode::dumpJsonMetaFileGdb("{metafile.name}")')
gdb.execute(f'call AstNode::dumpJsonMetaFileGdb("{metafile.name}")')
astsee_args.meta = metafile.name
try:
astsee.main(astsee_args)
+124 -74
View File
@@ -14,14 +14,23 @@
#
# Utilities
macro (addBuildType sourceConfig newConfig)
macro(addBuildType sourceConfig newConfig)
get_cmake_property(variableNames VARIABLES)
foreach (variableName ${variableNames})
if (variableName MATCHES "^CMAKE_.*_${sourceConfig}(|_.*)$")
string(REPLACE _${sourceConfig} _${newConfig} newVariableName ${variableName})
foreach(variableName ${variableNames})
if(variableName MATCHES "^CMAKE_.*_${sourceConfig}(|_.*)$")
string(
REPLACE
_${sourceConfig}
_${newConfig}
newVariableName
${variableName}
)
set(${newVariableName} ${${variableName}})
mark_as_advanced(${newVariableName})
message(DEBUG " Propagating ${variableName} to ${newVariableName} = ${${newVariableName}}")
message(
DEBUG
" Propagating ${variableName} to ${newVariableName} = ${${newVariableName}}"
)
endif()
endforeach()
endmacro()
@@ -142,6 +151,7 @@ set(HEADERS
V3Randomize.h
V3Reloop.h
V3Rtti.h
V3Sampled.h
V3Sched.h
V3Scope.h
V3Scoreboard.h
@@ -162,7 +172,6 @@ set(HEADERS
V3Table.h
V3Task.h
V3ThreadPool.h
V3ThreadSafety.h
V3Timing.h
V3Trace.h
V3TraceDecl.h
@@ -288,6 +297,7 @@ set(COMMON_SOURCES
V3ProtectLib.cpp
V3Randomize.cpp
V3Reloop.cpp
V3Sampled.cpp
V3Sched.cpp
V3SchedAcyclic.cpp
V3SchedPartition.cpp
@@ -326,15 +336,11 @@ set(COMMON_SOURCES
V3PreProc.cpp
)
SET(COVERAGE_SOURCES
VlcMain.cpp
)
set(COVERAGE_SOURCES VlcMain.cpp)
# Note about tests:
# VlcMain.cpp #includes the following files:
# V3Error.cpp, V3String.cpp, V3Os.cpp and VlcTop.cpp
# V3Number_test.cpp #includes the following files:
# V3FileLine.cpp
#
# Generated sources and headers for the verilator binary
@@ -353,34 +359,49 @@ configure_file(config_package.h.in config_package.h @ONLY)
add_custom_command(
OUTPUT V3Ast__gen_forward_class_decls.h V3Dfg__gen_forward_class_decls.h
DEPENDS ./V3Ast.h ${ASTGEN}
COMMAND ${PYTHON3} ARGS
${ASTGEN} -I "${srcdir}" --astdef V3AstNodeDType.h --astdef V3AstNodeExpr.h --astdef V3AstNodeOther.h --dfgdef V3DfgVertices.h --classes
COMMAND ${PYTHON3}
ARGS
${ASTGEN} -I "${srcdir}" --astdef V3AstNodeDType.h --astdef
V3AstNodeExpr.h --astdef V3AstNodeOther.h --dfgdef V3DfgVertices.h
--classes
)
list(
APPEND
GENERATED_FILES
V3Ast__gen_forward_class_decls.h
V3Dfg__gen_forward_class_decls.h
)
list(APPEND GENERATED_FILES V3Ast__gen_forward_class_decls.h V3Dfg__gen_forward_class_decls.h)
# Output used directly by the `verilator` target
set(verilog_y "${srcdir}/verilog.y" )
set(BISON_V3ParseBison_OUTPUT_HEADER "${CMAKE_CURRENT_BINARY_DIR}/V3ParseBison.h")
set(BISON_V3ParseBison_OUTPUT_SOURCE "${CMAKE_CURRENT_BINARY_DIR}/V3ParseBison.c")
set(verilog_y "${srcdir}/verilog.y")
set(BISON_V3ParseBison_OUTPUT_HEADER
"${CMAKE_CURRENT_BINARY_DIR}/V3ParseBison.h"
)
set(BISON_V3ParseBison_OUTPUT_SOURCE
"${CMAKE_CURRENT_BINARY_DIR}/V3ParseBison.c"
)
add_custom_command(
OUTPUT V3ParseBison.c V3ParseBison.h
MAIN_DEPENDENCY ./verilog.y
DEPENDS ${BISONPRE}
COMMAND ${PYTHON3} ARGS
${BISONPRE} --yacc "${BISON_EXECUTABLE}" -d -v
-o "${BISON_V3ParseBison_OUTPUT_SOURCE}" "${verilog_y}"
COMMAND ${PYTHON3}
ARGS
${BISONPRE} --yacc "${BISON_EXECUTABLE}" -d -v -o
"${BISON_V3ParseBison_OUTPUT_SOURCE}" "${verilog_y}"
)
list(APPEND GENERATED_FILES V3ParseBison.c V3ParseBison.h)
# Output used directly by the `verilator` target
set(verilog_l "${srcdir}/verilog.l")
set(FLEX_V3Lexer_pregen_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/V3Lexer_pregen.yy.cpp")
set(FLEX_V3Lexer_pregen_OUTPUTS
"${CMAKE_CURRENT_BINARY_DIR}/V3Lexer_pregen.yy.cpp"
)
add_custom_command(
OUTPUT V3Lexer_pregen.yy.cpp
MAIN_DEPENDENCY ./verilog.l
DEPENDS ${BISON_V3ParseBison_OUTPUT_HEADER} ${HEADERS}
COMMAND ${FLEX_EXECUTABLE} ARGS
${LFLAGS} -o "${FLEX_V3Lexer_pregen_OUTPUTS}" "${verilog_l}"
COMMAND ${FLEX_EXECUTABLE}
ARGS ${LFLAGS} -o "${FLEX_V3Lexer_pregen_OUTPUTS}" "${verilog_l}"
)
# Output used by another command
@@ -389,19 +410,26 @@ add_custom_command(
OUTPUT V3Lexer.yy.cpp
MAIN_DEPENDENCY ${FLEX_V3Lexer_pregen_OUTPUTS}
DEPENDS ${FLEXFIX}
COMMAND ${PYTHON3} ARGS
${FLEXFIX} V3Lexer < "$<SHELL_PATH:${FLEX_V3Lexer_pregen_OUTPUTS}>" > "$<SHELL_PATH:${FLEX_V3Lexer_OUTPUTS}>"
COMMAND ${PYTHON3}
ARGS
${FLEXFIX} V3Lexer < "$<SHELL_PATH:${FLEX_V3Lexer_pregen_OUTPUTS}>" >
"$<SHELL_PATH:${FLEX_V3Lexer_OUTPUTS}>"
)
add_custom_target(
V3Lexer_yy_cpp${CMAKE_BUILD_TYPE}
DEPENDS ${FLEX_V3Lexer_OUTPUTS}
)
add_custom_target(V3Lexer_yy_cpp${CMAKE_BUILD_TYPE} DEPENDS ${FLEX_V3Lexer_OUTPUTS})
# Output included by another source file
set(FLEX_V3PreLex_pregen_OUTPUTS ${CMAKE_CURRENT_BINARY_DIR}/V3PreLex_pregen.yy.cpp)
set(FLEX_V3PreLex_pregen_OUTPUTS
${CMAKE_CURRENT_BINARY_DIR}/V3PreLex_pregen.yy.cpp
)
add_custom_command(
OUTPUT V3PreLex_pregen.yy.cpp
MAIN_DEPENDENCY ./V3PreLex.l
DEPENDS ${HEADERS}
COMMAND ${FLEX_EXECUTABLE} ARGS
${LFLAGS} -o "${FLEX_V3PreLex_pregen_OUTPUTS}" "${srcdir}/V3PreLex.l"
COMMAND ${FLEX_EXECUTABLE}
ARGS ${LFLAGS} -o "${FLEX_V3PreLex_pregen_OUTPUTS}" "${srcdir}/V3PreLex.l"
)
# Output used by another command
@@ -410,37 +438,45 @@ add_custom_command(
OUTPUT V3PreLex.yy.cpp
MAIN_DEPENDENCY ${FLEX_V3PreLex_pregen_OUTPUTS}
DEPENDS ${FLEXFIX}
COMMAND ${PYTHON3} ARGS
${FLEXFIX} V3PreLex < "$<SHELL_PATH:${FLEX_V3PreLex_pregen_OUTPUTS}>" > "$<SHELL_PATH:${FLEX_V3PreLex_OUTPUTS}>"
COMMAND ${PYTHON3}
ARGS
${FLEXFIX} V3PreLex < "$<SHELL_PATH:${FLEX_V3PreLex_pregen_OUTPUTS}>" >
"$<SHELL_PATH:${FLEX_V3PreLex_OUTPUTS}>"
)
add_custom_target(
V3PreLex_yy_cpp${CMAKE_BUILD_TYPE}
DEPENDS ${FLEX_V3PreLex_OUTPUTS}
)
add_custom_target(V3PreLex_yy_cpp${CMAKE_BUILD_TYPE} DEPENDS ${FLEX_V3PreLex_OUTPUTS})
# Output included by another source file
set(gitHead ${srcdir}/../.git/logs/HEAD)
if (NOT EXISTS ${githead})
if(NOT EXISTS ${githead})
set(gitHead "")
endif()
add_custom_command(
OUTPUT config_rev.h
MAIN_DEPENDENCY ${gitHead}
DEPENDS ${CONFIG_REV}
COMMAND ${PYTHON3} ARGS
${CONFIG_REV} "${srcdir}" > "$<SHELL_PATH:${CMAKE_CURRENT_BINARY_DIR}/config_rev.h>"
COMMAND ${PYTHON3}
ARGS
${CONFIG_REV} "${srcdir}" >
"$<SHELL_PATH:${CMAKE_CURRENT_BINARY_DIR}/config_rev.h>"
)
list(APPEND GENERATED_FILES config_rev.h)
# Output used directly by the `verilator` target
set(ASTGENERATED_NAMES
V3Const
)
set(ASTGENERATED_NAMES V3Const)
foreach(astgen_name ${ASTGENERATED_NAMES})
add_custom_command(
OUTPUT ${astgen_name}__gen.cpp
MAIN_DEPENDENCY ${astgen_name}.cpp
DEPENDS ${ASTGEN} V3Ast.h
COMMAND ${PYTHON3} ARGS
${ASTGEN} -I "${srcdir}" --astdef V3AstNodeDType.h --astdef V3AstNodeExpr.h --astdef V3AstNodeOther.h --dfgdef V3DfgVertices.h ${astgen_name}.cpp
COMMAND ${PYTHON3}
ARGS
${ASTGEN} -I "${srcdir}" --astdef V3AstNodeDType.h --astdef
V3AstNodeExpr.h --astdef V3AstNodeOther.h --dfgdef V3DfgVertices.h
${astgen_name}.cpp
)
list(APPEND GENERATED_FILES ${astgen_name}__gen.cpp)
endforeach()
@@ -448,7 +484,7 @@ endforeach()
#
# Set up the Coverage build type
addBuildType(DEBUG COVERAGE)
addbuildtype(DEBUG COVERAGE)
# This regenerates include/verilated_cov_key.h in the source tree.
# It is a custom_target, not custom_command, because vlcovgen.d is
@@ -457,8 +493,7 @@ add_custom_target(
vlcovgen.d${CMAKE_BUILD_TYPE}
DEPENDS ../include/verilated_cov_key.h ${VLCOVGEN}
COMMENT "Updating include/verilated_cov_key.h"
COMMAND ${PYTHON3}
${VLCOVGEN} --srcdir ${srcdir}
COMMAND ${PYTHON3} ${VLCOVGEN} --srcdir ${srcdir}
)
#
@@ -466,66 +501,81 @@ add_custom_target(
set(verilator verilator${CMAKE_BUILD_TYPE})
add_executable(${verilator}
add_executable(
${verilator}
$<$<NOT:$<CONFIG:COVERAGE>>:${COMMON_SOURCES}>
$<$<NOT:$<CONFIG:COVERAGE>>:${GENERATED_FILES}>
$<$<CONFIG:COVERAGE>:${COVERAGE_SOURCES} config_rev.h>
$<$<CONFIG:COVERAGE>:${COVERAGE_SOURCES}
config_rev.h>
)
set_target_properties(${verilator} PROPERTIES
OUTPUT_NAME_RELEASE verilator_bin
OUTPUT_NAME_DEBUG verilator_bin_dbg
OUTPUT_NAME_COVERAGE verilator_coverage_bin_dbg
#UNITY_BUILD $<IF:$<CONFIG:DEBUG>,FALSE,${CMAKE_UNITY_BUILD}>
MSVC_RUNTIME_LIBRARY MultiThreaded$<IF:$<CONFIG:Release>,,DebugDLL>
#JOB_POOL_LINK one_job # Linking takes lots of resources
INTERPROCEDURAL_OPTIMIZATION_RELEASE $<IF:MINGW,FALSE,TRUE>
INCLUDE_DIRECTORIES ${FLEX_INCLUDE_DIR}
set_target_properties(
${verilator}
PROPERTIES
OUTPUT_NAME_RELEASE verilator_bin
OUTPUT_NAME_DEBUG verilator_bin_dbg
OUTPUT_NAME_COVERAGE verilator_coverage_bin_dbg
#UNITY_BUILD $<IF:$<CONFIG:DEBUG>,FALSE,${CMAKE_UNITY_BUILD}>
MSVC_RUNTIME_LIBRARY MultiThreaded$<IF:$<CONFIG:Release>,,DebugDLL>
#JOB_POOL_LINK one_job # Linking takes lots of resources
INTERPROCEDURAL_OPTIMIZATION_RELEASE $<IF:MINGW,FALSE,TRUE>
INCLUDE_DIRECTORIES ${FLEX_INCLUDE_DIR}
)
add_dependencies(${verilator}
add_dependencies(
${verilator}
V3Lexer_yy_cpp${CMAKE_BUILD_TYPE}
V3PreLex_yy_cpp${CMAKE_BUILD_TYPE}
)
target_link_libraries(${verilator} PRIVATE Threads::Threads)
# verilated_cov_key.h is only regenerated in a single-configuration environment.
# This limitation can be lifted when `add_dependencies` will support generator
# expressions. See https://gitlab.kitware.com/cmake/cmake/issues/19467
if (CMAKE_BUILD_TYPE STREQUAL Coverage)
if(CMAKE_BUILD_TYPE STREQUAL Coverage)
add_dependencies(${verilator} vlcovgen.d${CMAKE_BUILD_TYPE})
endif()
if (NOT MSVC)
if(NOT MSVC)
target_compile_features(${verilator} PRIVATE cxx_std_11)
endif()
target_compile_definitions(${verilator} PRIVATE
YYDEBUG # Required to get nice error messages
$<$<CONFIG:DEBUG>:VL_DEBUG>
$<$<CONFIG:DEBUG>:_GLIBCXX_DEBUG>
)
target_include_directories(${verilator}
target_compile_definitions(
${verilator}
PRIVATE
../include
${WIN_FLEX_BISON}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/../include
${CMAKE_CURRENT_SOURCE_DIR}
YYDEBUG # Required to get nice error messages
$<$<CONFIG:DEBUG>:VL_DEBUG>
$<$<CONFIG:DEBUG>:_GLIBCXX_DEBUG>
)
if (WIN32)
target_include_directories(
${verilator}
PRIVATE
../include
${WIN_FLEX_BISON}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/../include
${CMAKE_CURRENT_SOURCE_DIR}
)
if(WIN32)
if(MINGW)
target_compile_options(${verilator} PRIVATE -Wa,-mbig-obj)
target_link_options(${verilator} PRIVATE -Wl,--stack,10000000 -mconsole -lcomctl32 -DWIN_32_LEAN_AND_MEAN)
target_link_options(
${verilator}
PRIVATE
-Wl,--stack,10000000
-mconsole
-lcomctl32
-DWIN_32_LEAN_AND_MEAN
)
else()
target_compile_options(${verilator} PRIVATE /bigobj)
target_link_options(${verilator} PRIVATE /STACK:10000000)
endif()
target_compile_definitions(${verilator} PRIVATE
YY_NO_UNISTD_H
)
target_compile_definitions(${verilator} PRIVATE YY_NO_UNISTD_H)
target_include_directories(${verilator} PRIVATE ../platform/win32)
target_link_libraries(${verilator} PRIVATE bcrypt psapi)
endif()
+4 -6
View File
@@ -49,7 +49,7 @@ prefix = @prefix@
# Directory in which to install data across multiple architectures
datarootdir = @datarootdir@
# Directory in which to install package specific files
# Directory in which to install package-specific files
# Generally ${prefix}/share/verilator
pkgdatadir = @pkgdatadir@
@@ -210,6 +210,7 @@ RAW_OBJS_PCH_ASTMT = \
V3Options.o \
V3Stats.o \
V3StatsReport.o \
V3VariableOrder.o \
RAW_OBJS_PCH_ASTNOMT = \
V3Active.o \
@@ -284,6 +285,7 @@ RAW_OBJS_PCH_ASTNOMT = \
V3ProtectLib.o \
V3Randomize.o \
V3Reloop.o \
V3Sampled.o \
V3Sched.o \
V3SchedAcyclic.o \
V3SchedPartition.o \
@@ -308,7 +310,6 @@ RAW_OBJS_PCH_ASTNOMT = \
V3Undriven.o \
V3Unknown.o \
V3Unroll.o \
V3VariableOrder.o \
V3Width.o \
V3WidthCommit.o \
V3WidthSel.o \
@@ -354,9 +355,6 @@ $(TGT): $(PREDEP_H) $(OBJS)
@echo " Linking $@..."
${LINK} ${LDFLAGS} -o $@ $(OBJS) $(CCMALLOC) ${LIBS}
V3Number_test: V3Number_test.o
${LINK} ${LDFLAGS} -o $@ $^ ${LIBS}
#### Modules
%__gen.cpp: %.cpp $(ASTGEN) $(AST_DEFS) $(DFG_DEFS)
@@ -365,7 +363,7 @@ V3Number_test: V3Number_test.o
.SECONDARY:
%.gch: %
$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSWALL} ${CFG_CXXFLAGS_PCH} $< -o $@
$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSWALL} ${CFG_CXXFLAGS_PCH} -c $< -o $@
%.o: %.cpp
$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSWALL} -c $< -o $@
%.o: %.c

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