Compare commits

...
237 Commits
Author SHA1 Message Date
Wilson Snyder 17b75c6428 Version bump 2021-02-25 21:43:33 -05:00
Wilson Snyder ce78d6e438 Fix flexfix to directly run with python. 2021-02-25 21:19:37 -05:00
Wilson Snyder dad86b9a84 Tests: Fix leak found by previous commit 2021-02-25 20:38:38 -05:00
Wilson Snyder e1a48dcb07 Fix spacing 2021-02-25 20:13:13 -05:00
Wilson Snyder 0b501df959 Tests: Rename 2021-02-25 20:05:54 -05:00
Wilson Snyder 57d1404f40 Tests: Cleanup to return instead of exit 2021-02-25 19:26:36 -05:00
Wilson Snyder 2f8fa75691 Tests: On format make tests executable 2021-02-25 19:24:41 -05:00
Wilson Snyder 00c3bafe7d Tests: With --gdbsim build with ggdb 2021-02-25 19:20:11 -05:00
Wilson Snyder 206bd416aa Internals: Cleanup some RANDOM functions. 2021-02-24 22:13:24 -05:00
Wilson Snyder 30c34e4975 Internals: Avoid extra typedef. No functional change. 2021-02-24 21:13:00 -05:00
Wilson Snyder 1a5f599626 Commentary 2021-02-24 18:32:21 -05:00
Wilson Snyder c95e606c0a Fix range inheritance on port without data type (#2753). 2021-02-24 18:21:13 -05:00
Wilson Snyder a886f28c85 Internals: Use static_assert 2021-02-23 19:02:04 -05:00
Wilson Snyder 8c2ee6c5ab With -DVL_NO_LEGACY hide all outdated API routines 2021-02-22 22:59:23 -05:00
Wilson Snyder 6ada513fa5 Internal: Don't serialize debug, turn on each run. 2021-02-22 22:39:57 -05:00
Wilson Snyder 9f381f7617 Remove old SP_AUTO_COVER3 define 2021-02-22 22:27:33 -05:00
Wilson Snyder 48986ccdeb Remove VL_TIME_I, rarely/never used and too little precision. 2021-02-21 21:56:43 -05:00
Wilson Snyder 0f8e494c76 Tests: Add t_verilated_legacy 2021-02-21 21:49:55 -05:00
Wilson Snyder 9650aefa42 Internals: Cleanup unneeded {}. No functional change 2021-02-21 21:25:21 -05:00
Wilson Snyder 3ae75926e4 Inline old VL_CTOR macros. 2021-02-21 12:12:11 -05:00
Wilson Snyder 18f3df438e For generated --main, use unique_ptr. No functional change intended. 2021-02-21 11:02:02 -05:00
Andreas Kuster 99c02419c0 Commentary - contributors. (#2801) 2021-02-21 08:22:52 -05:00
bb5384bc50 Optimize bit op tree #2186, #2632, and #2633 (#2751)
* Tests:Add some more signals to t_const_opt_red.v

* Optimize bit op trees such as ~a[2] & a[1] & ~a[0] to 3'b010 == (3'111 & a)

* Update src/V3Const.cpp

Co-authored-by: Wilson Snyder <[email protected]>

* Update src/V3Const.cpp

Co-authored-by: Wilson Snyder <[email protected]>

* Update src/V3Const.cpp

Co-authored-by: Wilson Snyder <[email protected]>

* Apply clang-format

* Don't edit and-or tree.

* Call matchBitOpTree() after V3Expand does its job.

* Internals: Rename newNodep -> newp. No functional change is intended.

* Internals: Remove m_sels. No functional change is intended.

* Internals: Remove stringstream. No functional change is intended.

* Internals: Use V3Number::bitIs1(). No functional change is intended.

* Internals: Use V3Number instead of std::map. Resolved laek. Result should be same.

* Internals: Resolve overload of setPolarity. No functional change is intended.

* Internals: Pass failure reason. No functional change is intended.

* Internals: Add VNUser::toPtr(). No functional change is intended.

* Internals: Use user4 instead of std::map. No functional change is intended.

* Catch up with the AST style aftre V3Expand

* Internals: Rename Context to VarInfo. No functional change is intended.

* Add some more test case

* tests:Add stats to tests
Update stats in t_merge_cond.pl as matchBitopTree does some of them.

* insert CCast if necessary

* small optimization to remove redundant bit mask

* No quick exit even when unoptimizable node is found.

* Simplify removing redundant And

* simplify

* Revert "Internals: Add VNUser::toPtr(). No functional change is intended."

This reverts commit f98dce10db.

* Consider AstWordSel and cleanup

* Update test

* Update src/V3Const.cpp

Co-authored-by: Wilson Snyder <[email protected]>

* Update src/V3Const.cpp

Co-authored-by: Wilson Snyder <[email protected]>

* Update src/V3Const.cpp

Co-authored-by: Wilson Snyder <[email protected]>

* Update src/V3Const.cpp

Co-authored-by: Wilson Snyder <[email protected]>

* Update src/V3Const.cpp

Co-authored-by: Wilson Snyder <[email protected]>

* Update src/V3Const.cpp

Co-authored-by: Wilson Snyder <[email protected]>

* Apply clang-format

* Internals: rename variables. No functional change is intended.

Co-authored-by: Wilson Snyder <[email protected]>
Co-authored-by: github action <[email protected]>
2021-02-21 18:11:33 +09:00
Wilson Snyder fd6edd90bc Fix little endian interface pin swizzling (#2475). 2021-02-20 22:11:20 -05:00
Wilson Snyder 191f76dd90 Increase LINE_TOKEN_MAX (#2752). 2021-02-20 20:55:38 -05:00
Wilson Snyder 975c1b39a9 Fix little endian packed array pattern assignment (#2795). 2021-02-20 20:29:28 -05:00
Yutetsu TAKATSUKASA 62e877ebf0 Add transformation of '^(const ^ a)' -> '(^const) ^ (^a)' (#2800)
* Add transformation of '^(const ^ a)' -> '(^const) ^ (^a)'

* Use TREEOP instead of TREEOPC
2021-02-20 23:16:55 +09:00
Wilson Snyder aa99833580 Tests: Show (non-)per-instance coverage 2021-02-18 19:20:53 -05:00
Yutetsu TAKATSUKASA 120322df3e Remove redundant AND with 1 (#2791) 2021-02-18 19:28:49 +09:00
Yutetsu TAKATSUKASA c1b6faff6d Add more patterns to t_const_opt_red.v (#2792) 2021-02-18 19:28:30 +09:00
Wilson Snyder 22e299e78e Support concat selection (#2721). 2021-02-17 23:03:47 -05:00
Wilson Snyder d559190e9e Tests for future concat select (#2721) 2021-02-17 22:57:52 -05:00
Wilson Snyder c5e5be8e99 Commentary 2021-02-16 22:40:21 -05:00
Wilson Snyder 2b2fe13e79 Tests: Add unsupported test for interface typedef (#2783) 2021-02-16 22:31:30 -05:00
Wilson Snyder 64887bd92d Commentary 2021-02-16 20:40:16 -05:00
Wilson Snyder 95b0e9eef2 Tests: Add missing sc_time_stamp calls. 2021-02-16 20:34:44 -05:00
Wilson Snyder e44563fddc Tests: Use vl_time_stamp64 where reasonable 2021-02-16 20:14:30 -05:00
Yutetsu TAKATSUKASA f2a7f30b09 Commentary: In docs remove +I (#2789) 2021-02-15 08:40:49 -05:00
Wilson Snyder 43cf5693d1 Fix shifts by > 32 bit values (#2785). 2021-02-14 11:15:12 -05:00
Wilson Snyder 20b3f0efa0 Fix class extends with VM_PARALLEL_BUILDS (#2775). 2021-02-13 17:29:34 -05:00
Wilson Snyder 2b72218dd8 Fix examples not flushing vcd (#2787). 2021-02-13 17:06:53 -05:00
Wilson Snyder 36eb952b60 Tests: Fix mising init 2021-02-03 19:43:29 -05:00
Wilson Snyder 99afffa949 Tests: Add some verbose statements. 2021-02-03 19:38:44 -05:00
Wilson Snyder ae311200bf Tests: Pass tool to allow ifdefs in VPI C code. 2021-02-03 19:29:24 -05:00
Wilson Snyder 828fa80afa Tests: Add common use_libvpi for multiple simulators 2021-02-03 18:59:27 -05:00
Wilson Snyder fe0a42eaa8 Tests: Cleanup some unused functions. 2021-02-03 18:50:23 -05:00
Wilson Snyder 153335ff35 Tests: Cleanup some DPI warnings. 2021-02-03 18:30:39 -05:00
github action 7bce15b065 Apply clang-format 2021-02-03 22:39:03 +00:00
Wilson Snyder 2225acd3ec Tests: Avoid C++11 requirement in TestVpi.h 2021-02-03 17:37:31 -05:00
github action af5fc4f1ad Apply clang-format 2021-02-03 19:41:25 +00:00
Àlex Torregrosa e77e4e1fe6 Improve struct scopes when dumping structs to VCD (#2776) 2021-02-03 14:40:21 -05:00
Morten Borup Petersen 843ae2955e Commentary on incorrectly specified debug level (#2777)
As seen at https://github.com/verilator/verilator/blob/master/src/V3Options.cpp#L1202
setting --debug enables a debug level of 3.
2021-02-03 14:38:34 -05:00
Samuel Riedel 483516ce4e Fix build to execute vlcovgen with python3. (#2773) 2021-01-28 15:01:33 -05:00
Wilson Snyder 05bb24df6c Fix $fread extra semicolon inside statements. 2021-01-26 22:20:16 -05:00
Wilson Snyder 31223d4058 Fix $ in filenames (#2768). 2021-01-26 20:10:38 -05:00
Paul Wright d891e5ac3a Fix to exclude strings from toggle coverage (#2766) (#2767) 2021-01-25 07:33:38 -05:00
Wilson Snyder 3c79e00d24 Commentary (#2764) 2021-01-24 20:24:23 -05:00
github action 555269f791 Apply clang-format 2021-01-23 15:32:52 +00:00
Wilson Snyder 64941538b7 Fix TIMESCALE warnings on primitives (#2763). 2021-01-23 10:31:41 -05:00
James Hanlon fadc6776ec For --flatten, override inlining of public and no_inline modules (#2761) 2021-01-18 08:03:18 -05:00
Yutetsu TAKATSUKASA 878a252437 Internals: Add TREEOPC() that executes only when m_doCpp==true (#2759) 2021-01-17 13:53:49 +09:00
Wilson Snyder 5cadabeb2d Fix argparse difference on ubuntu 18.04 2021-01-16 14:14:39 -05:00
Wilson Snyder 2517bfd0af Fix argparse difference on ubuntu 18.04 2021-01-16 13:57:56 -05:00
Wilson Snyder 1f105edf69 Internals: Convert astgen to python. 2021-01-16 13:24:14 -05:00
Yutetsu TAKATSUKASA b82085fbc6 Internals: Use size_t to compare with vector::capacity(). No functional change intended. (#2758) 2021-01-16 09:47:27 -05:00
Yutetsu TAKATSUKASA cea8b65f8c Internals: Make some accessors in V3Number public (#2756). No functional change. 2021-01-16 09:47:04 -05:00
Wilson Snyder 22260c6b85 Internals: Rename V3Const TREEOPC to TREEOPA. 2021-01-15 22:13:06 -05:00
Pierre-Henri Horrein 3c849d7ce0 Generate SELRANGE instead of errors for potentially unreachable code (#2625) (#2754)
When using a "if" statement inside an always block, part of the code may
be unreachable. This can be used to avoid errors, but it generated an
error, this commit demotes this to a warning. Partly fixes #2625.
2021-01-15 07:31:48 -05:00
Wilson Snyder fb2c243fc7 Build cmake examples with -j 2021-01-13 20:02:21 -05:00
Wilson Snyder 3bb8fbe73b Internal coverage improvements 2021-01-13 20:01:10 -05:00
Wilson Snyder ab5d4bd51d Tests: Abstract out common test comparison 2021-01-12 18:31:23 -05:00
Wilson Snyder bcf9abf490 Internals: Var rename. No functional change. 2021-01-11 22:42:14 -05:00
Philipp Wagner b7c26dbea9 Fix to include limits header for std::numeric_limits (#2747)
Code using `std::numeric_limits` wasn't including the limits header,
leading to a compilation error in Fedora Rawhide (GCC 11.0).
2021-01-11 11:23:54 -05:00
github action 4f1867a4f8 Apply clang-format 2021-01-11 03:55:27 +00:00
Wilson Snyder bd551a7444 Internals: Convert bisonpre to python3 2021-01-10 22:53:59 -05:00
Wilson Snyder d4d9e12b66 CI: Fix coverage action (install systemc) 2021-01-10 19:45:43 -05:00
Wilson Snyder 6060acc73d CI: Fix coverage action 2021-01-10 19:15:39 -05:00
Wilson Snyder e972668169 CI: Fix coverage action 2021-01-10 18:55:56 -05:00
Wilson Snyder 945496d6d9 devel release 2021-01-10 13:36:46 -05:00
Wilson Snyder 484b76e5b3 Version bump 2021-01-10 13:34:59 -05:00
Wilson Snyder 801d850724 Commentary 2021-01-10 13:14:25 -05:00
Paul Wright 769c0fa318 Fix to ignore coverage on real ports (#2741) (#2745) 2021-01-10 12:40:03 -05:00
Julien Margetts a11700271f Add LATCH and NOLATCH warnings (#1609) (#2740). 2021-01-05 14:26:01 -05:00
Wilson Snyder 6d80e8f856 Test update 2021-01-05 09:04:31 -05:00
Wilson Snyder f57c72e5db clang-format 2021-01-03 12:01:14 -05:00
Wilson Snyder 7eeb930c72 examples: Use unique_ptr 2021-01-03 11:54:43 -05:00
Yutetsu TAKATSUKASA 5b280c1911 Fix hierarchical verilation with explicit setting of default parameter value (#2738)
* Test hierarchical block that is explicitly set its default parameter value.

* Fix hierarchical verilation when a hierarchical block is instantiated with explicit setting of the default value.

Parameterized hierarchical block must have mangled name even when all parameters have default value,
otherwise the parameterized module will be hidden by protect-lib wrapper.

* rename variable names. No functional change is intended.
2021-01-03 12:19:37 +09:00
Wilson Snyder 1a073fbf5e Fix vpiLeftRange on little-endian memories (#2696). 2021-01-02 22:00:13 -05:00
Wilson Snyder 83d978c2cd Fix generate for unrolling to be signed (#2730). 2021-01-02 21:43:13 -05:00
Wilson Snyder a17e2375b3 CI: Need flexlexer for internal coverage testrun 2021-01-02 21:42:41 -05:00
Yutetsu TAKATSUKASA c0a6858c42 Refactor V3Param (#2736)
* Use unique_ptr to manage lifetime. Slightly changed variable name. No functional change is intended.

* Let ParameterizedHierBlocks::areSame() public. No functional change is intended.
2021-01-03 07:21:45 +09:00
Yutetsu TAKATSUKASAandWilson Snyder 7a18adc716 Emit timescale in hierarchical block only when timescale is specified (#2735)
* Add a test for hierarchical verilation without timescale

* Emit timeunit in hierarchical wrapper only when it is specified in the input design or command line option.

* Update src/V3AstNodes.h

Co-authored-by: Wilson Snyder <[email protected]>

Co-authored-by: Wilson Snyder <[email protected]>
2021-01-02 08:31:27 +09:00
Wilson Snyder bd602d0e2d Copyright year update 2021-01-01 10:29:54 -05:00
Wilson Snyder 72b2df30f8 Fix tracing empty sc module (#2729). 2020-12-28 11:13:58 -05:00
Wilson Snyder d6c5d31dcd docker: Use sed to avoid perl 2020-12-23 19:23:23 -05:00
Wilson Snyder 84c323188e Internals: yapf reformat vlcovgen. No functional change. 2020-12-23 19:17:46 -05:00
Wilson Snyder cbd1bd5dad Tests: Fix some VPI coverage holes 2020-12-23 19:15:00 -05:00
Wilson Snyder 97255dc835 Tests: Test future if condition optimization (#2726) 2020-12-23 18:23:47 -05:00
Wilson Snyder 9f8b17230a Cleanup extra space on 'VlWide<...>>' 2020-12-23 18:09:12 -05:00
Wilson Snyder 93476a7372 Internals: Convert vlcovgen to python3. No functional change. 2020-12-23 16:54:05 -05:00
Wilson Snyder b8b9170f9d Remove Unix::Processors dependency 2020-12-23 16:07:14 -05:00
Wilson Snyder 575539996b Fix manifest for src/config_rev in last commit 2020-12-23 16:07:04 -05:00
Wilson Snyder 922eab5f93 Internals: Convert config_rev, cppcheck_filtered, flexfix to python3 2020-12-23 15:41:14 -05:00
Wilson Snyder b7a533109d Fix cppcheck warnings. No functional change intended. 2020-12-23 15:22:02 -05:00
Wilson Snyder 941e5c659a Fix cppcheck parse error 2020-12-23 15:22:02 -05:00
Unai Martinez-Corral e37a93bffb CI: (fix) check that CCACHE_DIR is set, before execing mkdir 2020-12-23 19:52:37 +01:00
Unai Martinez-CorralandWilson Snyder 6e3de7bfd1 CI: exploit concurrency (#2687)
Co-authored-by: Wilson Snyder <[email protected]>
2020-12-23 18:53:05 +01:00
Nandu Raj 1124829500 Fix $urandom_range maximum value (#2723) 2020-12-22 07:52:38 -05:00
Yutetsu TAKATSUKASA 4096dee598 Use files from gtkwave3-gtk3, not from gtkwave3 (#2718) 2020-12-21 07:06:03 +09:00
HyungKi Jeong 36f41e08a5 Fix to allow inheriting 'VerilatedVcdFile' class. (#2720) 2020-12-20 12:18:09 -05:00
Wilson Snyder 28ff71b1bf Internals: Misc refactoring from dcache branch. No functional change. 2020-12-19 20:46:10 -05:00
Wilson Snyder db276946b4 Internals: Convert internal code_coverage to python3. 2020-12-19 20:29:09 -05:00
Wilson Snyder beb03be731 Internals: convert install_test and dot_importer to python3. 2020-12-19 12:48:22 -05:00
Wilson Snyder b93e409f0e Optimize additional display statements (#2702). 2020-12-19 11:12:47 -05:00
Yutetsu TAKATSUKASA 788de3ad24 CI: Enable address sanitizer for vlt tests. (#2715) 2020-12-19 11:12:15 -05:00
Yutetsu TAKATSUKASA cb4ddd3213 Update files from GTKWave f119b35816e605e753fc1a24ae121a3787615b26 (#2716) 2020-12-19 09:13:18 -05:00
Wilson Snyder 7e94b3a4fa Examples: Explicitly refer to PYTHON3 not PYTHON 2020-12-18 23:07:21 -05:00
Wilson Snyder ca9bdc6e70 Tests: Ignore github action commits 2020-12-18 23:06:42 -05:00
github action 37ebc6e634 Apply clang-format 2020-12-19 03:55:46 +00:00
Wilson Snyder 457e926168 Use yapf3 and add to CI 2020-12-18 22:54:06 -05:00
Wilson Snyder ec4e408b2b Add yapf and reformat python code 2020-12-18 22:34:14 -05:00
Wilson Snyder a16ebaf79c Remove some stale and unsupported maintainer utilities 2020-12-18 21:57:48 -05:00
Wilson Snyder 1e34ae31d2 Fix vpi_release_handle to be called implicitly per IEEE (#2706). 2020-12-18 21:16:57 -05:00
Wilson Snyder 43811821d6 Backout GTKwave update 7deac509c6 2020-12-18 21:03:02 -05:00
Wilson Snyder 3797b5bca1 Check for vpi_release_handle even when no VL_DEBUG 2020-12-18 20:46:43 -05:00
Wilson Snyder 7deac509c6 GTKwave updates from upstream. 2020-12-18 19:33:57 -05:00
Wilson Snyder c39a8b439a Internals: Use emplace instead of insert(make_pair(...)). No functional change intended. 2020-12-18 18:24:47 -05:00
Wilson Snyder d0c4aee7b5 Tests: clang-format 2020-12-17 22:44:50 -05:00
Todd Strader a88965a124 Fix scope map for multiple construction (#2710) 2020-12-17 12:21:40 -05:00
James HanlonandJames Hanlon c18cbca813 Add support for package imports preceeding parameters in interfaces (#2714)
Co-authored-by: James Hanlon <[email protected]>
2020-12-17 11:26:53 -05:00
Yutetsu TAKATSUKASA e4eab56495 Add a workflow that calls clang-format and commit. (#2713)
* Add a workflow that calls clang-format and commit.
2020-12-17 23:41:10 +09:00
Wilson Snyder deb5531e54 Tests: Make explicit some IEEE-mandated freeing of VPI handles 2020-12-16 20:57:02 -05:00
Wilson Snyder 9bb353c577 Tests: Make explicit some IEEE-mandated freeing of VPI handles 2020-12-16 20:36:04 -05:00
Wilson Snyder a816c2b75e Tests: Fix hardcoded path in last test 2020-12-16 19:38:35 -05:00
Wilson Snyder ff702174d8 Report double calls to vpi_release_handle when using VL_DEBUG 2020-12-16 19:10:17 -05:00
Wilson Snyder d5d6598d75 Internals: spacing 2020-12-16 19:08:10 -05:00
Wilson Snyder 0abf18f618 Fix supporting begin_keywords 1364-2001-noconfig 2020-12-16 18:40:45 -05:00
Wilson Snyder 6adda241c9 Fix $urandom_range with no second argument 2020-12-16 18:34:49 -05:00
Yutetsu TAKATSUKASA ce9293fcb3 Fix memory leaks found in trace related tests (#2708)
* Fix memory leak of t_trace_cat and t_trace_cat_renew

* Fix memory leak of t_trace_c_api

* Fix memory leak in t_trace_public_func and t_trace_public_func_vlt

* Fix memory leaks in t_flat_build (and probably more).

* Use unique_ptr in testcases
2020-12-17 08:31:47 +09:00
Wilson Snyder d6168f654e Update contributor URL (#2711) 2020-12-16 18:02:54 -05:00
Yutetsu TAKATSUKASA 738ee3d4eb Fix memory leaks when using shared protect-lib (#2707)
* Guarantee mechanism to initialize just once is now in VerilatedInitializer. No functional change is intended.

* Make sure to initialize Verilated::NonInitialized just once. Fixes
memory leak in t_prot_lib_shared and t_hier_block_prot_lib_shared.

* Call setup() and teardown() of Verilated::NonSerialized.
2020-12-16 12:30:58 -05:00
Todd Strader b75901b3eb Fix VPI module tree (#2704) 2020-12-16 11:46:57 -05:00
Yutetsu TAKATSUKASA f98782c061 Tests: Fix use-after-free in fst testcases (#2709) 2020-12-16 10:00:13 -05:00
Wilson Snyder 3039735648 Tests: Fix various test leaks (#2703). 2020-12-15 23:12:13 -05:00
Wilson Snyder c00c26c705 Remove some comments emitted in output.
* Comments were disabling some optimizations.
* Suspect rarely referred to.
* Sometimes incorrectly placed due to other optimizations.
2020-12-15 22:55:17 -05:00
Wilson Snyder 084ba6711b Tests: Fix various test leaks (#2703). 2020-12-15 22:09:40 -05:00
Wilson Snyder c54360485e Fix over-iterating dpi dimensions (#2703). 2020-12-15 22:09:24 -05:00
Yutetsu TAKATSUKASA d9ef4ac435 Rename --asan to --sanitize (#2705) 2020-12-15 21:07:27 -05:00
Yutetsu TAKATSUKASAandWilson Snyder 176cc5a196 Add --asan option that enables address sanitizer to the test driver (#2700)
* Experimentally add --vltasan which enables address sanitizer

Co-authored-by: Wilson Snyder <[email protected]>
2020-12-16 07:33:26 +09:00
Yutetsu TAKATSUKASA 7821da6ad5 Fix DPI-C and protect-lib if port is implicit logic (#2699) 2020-12-15 09:51:14 -05:00
Wilson Snyder 5ee30e271e When combine functions, favor keeping non-slow name. 2020-12-13 21:53:55 -05:00
Wilson Snyder 4ce48788c5 Always use verilated_heavy (#2701).
On test suite adds ~7% runtime but will simplify logic and enable some
future changes.

Most large designs I saw were already using verilated_heavy as were using
strings, queues, associative arrays, classes, $readmem, $writemem, or
$valueplusargs.
2020-12-13 19:40:05 -05:00
Wilson Snyder 3590f7e206 Remove unused VL_DISABLE_INTRINSICS, use VL_PORTABLE_ONLY instead 2020-12-13 19:14:09 -05:00
Wilson Snyder 882b310897 Fix little endian packed array counting (#2499). 2020-12-13 16:23:59 -05:00
Wilson Snyder 82fc142c1c Add error on real to non-real output pins (#2690). 2020-12-13 13:33:48 -05:00
Wilson Snyder 5898c22b3b Internals: Cleanup variables for pin interconnection 2020-12-13 13:22:42 -05:00
Yutetsu TAKATSUKASA 13e88106da Internals:Cleanup dpiTypesToStringConverter. No functional change is intended. (#2698) 2020-12-13 16:05:06 +09:00
Marlon James 457d1a66f2 Fix VPI memory word indexing (#2695)
* Test that indexing into memory word fails

* VPI: don't index into memory word

Memory and memory words share a VerilatedVar, so check for memory word before attempting to index.
2020-12-12 22:47:47 -05:00
Wilson Snyder b04a1caeac In warnings, rename cells to instances to match IEEE 2020-12-12 22:43:55 -05:00
Wilson Snyder 53c4c7d540 Fix error format (#2095). 2020-12-12 22:26:50 -05:00
Wilson Snyder fb689bbb19 Fix clang warning, recent change 2020-12-12 22:16:10 -05:00
Wilson Snyder e2e3cc8463 Better error on inside on unpacked, queues, etc (#2566) 2020-12-12 21:20:42 -05:00
Wilson Snyder 6061744c4d Tests: Add t_dynarray_unpacked (#2314) 2020-12-12 20:56:35 -05:00
Wilson Snyder 8e25d2c61d Commentary (#2095). 2020-12-12 20:26:50 -05:00
Wilson Snyder 18f8c8a14f Fix error when dotted refers to missing module (#2095). 2020-12-12 20:25:00 -05:00
Wilson Snyder 44765e03a3 Internals: clang-format 2020-12-12 20:22:28 -05:00
Wilson Snyder 3f119f5647 Fix --no-decoration to turn off DPI import/export locations 2020-12-12 19:33:18 -05:00
Wilson Snyder 517fdb7587 Support queue of arrays 2020-12-12 19:19:32 -05:00
Wilson Snyder 0ca72f8098 For debug build, mv to prevent text busy error durring regression 2020-12-12 19:19:32 -05:00
Yutetsu TAKATSUKASA 28d139149a Test: Add unpacked array of 1 bit wire to DPI tests (#2694) 2020-12-13 07:28:37 +09:00
Wilson Snyder 81ce2cbc05 Internals: Params cleanups in prep for dedot. 2020-12-12 15:48:10 -05:00
Wilson Snyder d7af6436a2 Fix genblk naming to match IEEE (#2686). 2020-12-12 12:57:11 -05:00
Yutetsu TAKATSUKASA c80ca8d03e Test: Use non-blocking assignment as DRIVE macro does in t_prot_lib (#2693) 2020-12-12 23:07:12 +09:00
Wilson Snyder 93304f3b82 Internals: Reorder library code. No functional change. 2020-12-12 08:58:03 -05:00
Marlon James 30546afdab Fix VPI range iterator null return (#2691)
* Test that range iterator exhausts after 1 dimension

* Separate range iterator from range object

Range iterators should return NULL after all ranges have been returned
2020-12-12 08:11:08 -05:00
Wilson Snyder 82d8fe0c27 Internal coverage fixes 2020-12-10 22:01:56 -05:00
Wilson Snyder 4db673b2ff ci: Fix Ubuntu-18.04/16.04 runs 2020-12-10 20:22:00 -05:00
Wilson Snyder a5fa468343 Fix cast from packed structs, broke with $cast (#2684) 2020-12-10 18:36:06 -05:00
Wilson Snyder 2df1b72ce2 CI: Add separate contributors action (#2689) 2020-12-10 18:12:26 -05:00
Unai Martinez-Corral 2998890647 CI: remove unused 'ci-ccache-size.bash' (#2688) 2020-12-10 15:59:31 -05:00
Unai Martinez-Corral 8e178ca4a9 CI: Misc style cleanups (#2683) 2020-12-10 12:33:26 -05:00
Unai Martinez-Corral d94a8a28fa Fix Windows msys2, define WEXITSTATUS (#2685) 2020-12-10 12:20:54 -05:00
Unai Martinez-Corral 9a32158b5e CI: Cleanup ci/coverage to use a matrix to define coverage jobs (#2682)
* contributors: add Unai Martinez-Corral

* ci/coverage: use a matrix to define coverage jobs
2020-12-10 11:15:30 -05:00
Wilson Snyder b15dd3f898 Commentary 2020-12-10 09:06:01 -05:00
Wilson Snyder af0e535015 Internals: Remove Xnor node type.
Convert to Not(Xor(x)) up front, to help code coverage and optimize out extra nots sooner.
2020-12-10 00:04:10 -05:00
Wilson Snyder 5b2844e1be Fix instability in last commit from dangling deletes. 2020-12-09 23:57:40 -05:00
Wilson Snyder 53ce708294 Fix showing reference locations for BLKANDNBLK (#2170). 2020-12-09 23:07:11 -05:00
Wilson Snyder a1322635fd Internal coverage improvements 2020-12-09 22:32:09 -05:00
Wilson Snyder ab4ad9965c Fix DPI open array handling issues, and do internal coverage (#2350). 2020-12-09 22:15:34 -05:00
Wilson Snyder 2273fa62d9 CI: coverage action parallelism 2020-12-09 22:12:04 -05:00
Wilson Snyder cca874dc83 CI: coverage action parallelism 2020-12-09 21:35:48 -05:00
Wilson Snyder 274475aefd CI: coverage action parallelism 2020-12-09 21:33:22 -05:00
Wilson Snyder a91cf18d09 CI: coverage action parallelism 2020-12-09 21:30:31 -05:00
Wilson Snyder a7723ee9a5 CI: coverage action parallelism 2020-12-09 21:13:09 -05:00
Wilson Snyder 28ee80c310 CI: coverage action parallelism 2020-12-09 21:10:34 -05:00
Wilson Snyder 26da90ffce CI: coverage action parallelism 2020-12-09 20:57:17 -05:00
Wilson Snyder 9eb211a8d4 CI: coverage action parallelism 2020-12-09 20:55:01 -05:00
Wilson Snyder 75c2884fea CI: coverage action parallelism 2020-12-09 20:54:06 -05:00
Wilson Snyder f49f86c7ce CI: coverage action parallelism 2020-12-09 20:47:02 -05:00
Wilson Snyder a1989161d8 CI: coverage action parallelism 2020-12-09 20:38:41 -05:00
Wilson Snyder f11fa61ecf CI: coverage action parallelism 2020-12-09 20:37:11 -05:00
Wilson Snyder 9a904b97b2 CI: coverage action parallelism 2020-12-09 20:30:18 -05:00
Wilson Snyder 7d05be802d Misc internal coverage hole and related bug fixes 2020-12-09 19:18:12 -05:00
Krzysztof Bieganski 5e7b0d526d Support 'randc' as alias to 'rand' (#2680)
* Add alias 'randc' to 'rand'

* Make the 'RANDC' warning; add tests
2020-12-09 19:17:30 -05:00
Yutetsu TAKATSUKASA ff3d35ca61 Support unpacked array port in protect-lib and hierarchical verilation (#2672)
* Add a test to use unpacked array port in hierarchical verilation and protect-lib.

* V3EmitV supports unpacked array variables

* Can Emit local unpacked array properly

* Update golden of t_debug_emitv

* Support unpacked array port in protect-lib

* Remove t_prot_lib_unpacked_bad test as unpacked array is supported now.
2020-12-09 08:29:45 +09:00
Wilson Snyder c23de458ed Misc internal coverage cleanups 2020-12-08 08:40:22 -05:00
Wilson Snyder 90e0c9bdcd CI: internal coverage updates 2020-12-08 08:00:24 -05:00
Wilson Snyder 7892c5af13 Tests: Fix fstrobe instability 2020-12-08 07:49:48 -05:00
Wilson Snyder 0a0e4dce09 Internal coverage: default VERILATOR_ROOT setting. 2020-12-08 07:12:57 -05:00
Wilson Snyder 8e06b1e925 Misc internal coverage cleanups 2020-12-07 23:15:29 -05:00
Wilson Snyder a15540dfdd Tests: Add coverage github action 2020-12-07 21:57:10 -05:00
Wilson Snyder 3c680ddf22 Tests: Test some warnings without tests. 2020-12-07 20:30:16 -05:00
Wilson Snyder 47eeef485d Report UNUSED on parameters, localparam and genvars (#2627). 2020-12-07 19:49:50 -05:00
Wilson Snyder 251812638d Internals: Rename accessor. No functional change. 2020-12-07 18:50:31 -05:00
Krzysztof Bieganski cf7ea06b5d Support randomize() class method and rand 2020-12-07 17:55:22 -05:00
Wilson Snyder cd248f6bd7 Internals: Make consistent left/right/lo/hi accessors to ranges.
Change order of Range to store always left:right.
XML output changes to now show left:right (previously info was lost), no other change intended.
2020-12-06 21:13:56 -05:00
Wilson Snyder b32d530000 Error message cleanup 2020-12-06 20:33:08 -05:00
Wilson Snyder 570631380b Internal: Misc cleanups. No functional change intended. 2020-12-06 13:49:44 -05:00
Wilson Snyder d5f88cbf78 Tests: Rename some tests. 2020-12-06 11:37:56 -05:00
Wilson Snyder 74ef35d3b3 Support $cast and new CASTCONST warning. 2020-12-05 22:58:36 -05:00
Wilson Snyder 8b8ebb0e43 Internals: Use restorer. No functional change. 2020-12-05 22:21:30 -05:00
Yutetsu TAKATSUKASA 301b4ff1ad Internals: Introduce TaskDpiUtils in V3Task (#2670)
* Internals:Simplify V3Task.cpp. no functional change intended

* Internals:Introduce TaskDpiUtils in V3Task.cpp. No functional change intended
2020-12-06 12:09:48 +09:00
Yutetsu TAKATSUKASA 5476ff93e2 Ignore some files generated by modelsim (#2669) 2020-12-05 21:55:56 -05:00
Yutetsu TAKATSUKASA 375ea169b9 Internals: Apply verilog-mode. No functional change is intended. (#2671) 2020-12-05 21:55:06 -05:00
Wilson Snyder 9c2785b49b Internals: Swap lhs/rhs $cast args. 2020-12-05 17:11:00 -05:00
Wilson Snyder 8582aed66a Add --top option as alias of --top-module. 2020-12-05 16:58:17 -05:00
Wilson Snyder 9bd5cd4ef3 Internals: Track null separately from '0 2020-12-05 16:49:10 -05:00
Wilson Snyder f858dd44ac Fix :: references to forward classes 2020-12-05 16:23:20 -05:00
Wilson Snyder e69736124f Debug: Less verbose link. 2020-12-05 16:16:37 -05:00
Wilson Snyder f0e691a1b8 Handle unsupported parameters through link phase 2020-12-05 11:30:14 -05:00
Wilson Snyder 5fb834e41e Fix passing parameter type instantiations by position number. 2020-12-05 11:00:30 -05:00
Yutetsu TAKATSUKASA 7f6d4ac359 Use both gcc and clang in CI (#2667)
* Remove remaining TRAVIS_ variable

* Use both gcc and clang.
2020-12-05 12:36:04 +09:00
Wilson Snyder 666d0ab552 Standard YAML spacing is 2 spaces. 2020-12-04 17:39:53 -05:00
Wilson Snyder b9f2400d17 Rename workflow to appease badges 2020-12-04 17:11:00 -05:00
Wilson Snyder 85b2c6b6c7 Github actions badge fix 2020-12-04 17:06:18 -05:00
Yutetsu TAKATSUKASAandWilson Snyder 73a7595335 Add the initial version of CI using GitHub Actions (#2665)
* Add the initial version of CI using GitHub Actions

* Update .github/workflows/check_pr.yml

Co-authored-by: Wilson Snyder <[email protected]>

* remove setting for travis

* rename travis-*.bash to ci-*.bash

* Rename TRAVIS_ variables to CI_

* install ccache and libsystemc(-dev) in ci-install.bash

* Use CI_ variables and Ubuntu-20.04 that provides SystemC

* call ccache maintenance

Co-authored-by: Wilson Snyder <[email protected]>
2020-12-05 00:30:46 +09:00
Wilson Snyder 38c6085f54 devel release 2020-12-02 20:19:04 -05:00
703 changed files with 14354 additions and 9013 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
---
name: Bug report
about: Something isn't working as expected, and it isn't "Unsupported." (Note our contributor agreement at https://github.com/verilator/verilator/.github/blob/master/CONTRIBUTING.adoc)
about: Something isn't working as expected, and it isn't "Unsupported." (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.adoc)
title: ''
labels: new
assignees: ''
+1 -1
View File
@@ -1,6 +1,6 @@
---
name: Feature Request
about: Request something should be supported, or a new feature added. (Note our contributor agreement at https://github.com/verilator/verilator/.github/blob/master/CONTRIBUTING.adoc)
about: Request something should be supported, or a new feature added. (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.adoc)
title: ''
labels: new
assignees: ''
+1 -1
View File
@@ -1,6 +1,6 @@
---
name: Q and A, or Other
about: Ask a question, not related to a specific bug or feature request. (Note our contributor agreement at https://github.com/verilator/verilator/.github/blob/master/CONTRIBUTING.adoc)
about: Ask a question, not related to a specific bug or feature request. (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.adoc)
title: ''
labels: new
assignees: ''
+137
View File
@@ -0,0 +1,137 @@
# DESCRIPTION: Github actions config
# This name is key to badges in README.adoc, so we use the name build
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
name: build
on:
push:
pull_request:
workflow_dispatch:
schedule:
- cron: '0 0 * * 0' # weekly
env:
CI_OS_NAME: linux
CI_COMMIT: ${{ github.sha }}
CCACHE_COMPRESS: 1
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_MAXSIZE: 2Gi # 2GiB for clang and gcc, 4GiB in total
jobs:
Matrix:
runs-on: ubuntu-latest
name: Generate Build matrix
outputs:
matrix: ${{ steps.generate.outputs.matrix }}
steps:
- uses: actions/checkout@v2
- id: generate
name: Run 'generate_matrix.sh'
run: |
if [ '${{ github.event_name}}' = 'pull_request' ]; then
matrix='[ "ubuntu-20.04" ]'
else
matrix='[ "ubuntu-16.04", "ubuntu-18.04", "ubuntu-20.04" ]'
fi
echo "::set-output name=matrix::$matrix"
Build:
needs: Matrix
strategy:
fail-fast: false
matrix:
os: ${{ fromJson(needs.Matrix.outputs.matrix) }}
debug: [ opt, dbg ]
compiler:
- { cc: clang, cxx: clang++ }
- { cc: gcc, cxx: g++ }
runs-on: ${{ matrix.os }}
name: Build | ${{ matrix.os }} | ${{ matrix.compiler.cc }} | ${{ matrix.debug }}
env:
CI_BUILD_STAGE_NAME: build
CI_RUNS_ON: ${{ matrix.os }}
CI_MAKE_SRC_TARGET: ${{ matrix.debug }}
CC: ${{ matrix.compiler.cc }}
CXX: ${{ matrix.compiler.cxx }}
CACHE_KEY: ${{ matrix.os }}-${{ matrix.compiler.cc }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Cache
uses: actions/cache@v2
env:
cache-name: ccache
with:
path: ${{ github.workspace }}/.ccache
key: ${{ env.CACHE_KEY }}-${{ env.cache-name }}-${{ github.sha }}
restore-keys: ${{ env.CACHE_KEY }}-${{ env.cache-name }}
- name: Install packages for build
run: ./ci/ci-install.bash
- name: Build
run: |
./ci/ci-script.bash
tar cvzf verilator-${{ matrix.os}}-${CI_COMMIT}-${{ matrix.compiler.cc }}-${{ matrix.debug }}.tgz ./bin
- uses: actions/upload-artifact@v2
with:
path: verilator-${{ matrix.os}}-${{ env.CI_COMMIT }}-${{ matrix.compiler.cc }}-${{ matrix.debug }}.tgz
Test:
needs: [ Matrix, Build ]
strategy:
fail-fast: false
max-parallel: 8
matrix:
os: ${{ fromJson(needs.Matrix.outputs.matrix) }}
compiler:
- { cc: clang, cxx: clang++ }
- { cc: gcc, cxx: g++ }
suite:
- dist-vlt-0
- dist-vlt-1
- vltmt-0
- vltmt-1
runs-on: ${{ matrix.os }}
name: Test | ${{ matrix.os }} | ${{ matrix.compiler.cc }} | ${{ matrix.suite }}
env:
CI_BUILD_STAGE_NAME: test
CI_RUNS_ON: ${{ matrix.os }}
CC: ${{ matrix.compiler.cc }}
CXX: ${{ matrix.compiler.cxx }}
CACHE_KEY: ${{ matrix.os }}-${{ matrix.compiler.cc }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Cache
uses: actions/cache@v2
env:
cache-name: ccache
with:
path: ${{ github.workspace }}/.ccache
key: ${{ env.CACHE_KEY }}-${{ env.cache-name }}-${{ github.sha }}
restore-keys: ${{ env.CACHE_KEY }}-${{ env.cache-name }}
- uses: actions/download-artifact@v2
- name: Install Verilator and test dependencies
run: |
tar xvzf artifact/verilator-${{ matrix.os}}-${CI_COMMIT}-${{ matrix.compiler.cc }}-opt.tgz
tar xvzf artifact/verilator-${{ matrix.os}}-${CI_COMMIT}-${{ matrix.compiler.cc }}-dbg.tgz
rm -rf artifact
./ci/ci-install.bash
- name: Test
env:
TESTS: ${{ matrix.suite }}
run: ./ci/ci-script.bash
+44
View File
@@ -0,0 +1,44 @@
# DESCRIPTION: Github actions config
# This name is key to badges in README.adoc, so we use the name build
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
name: clang-format
on:
push:
pull_request_target:
workflow_dispatch:
jobs:
format:
runs-on: ubuntu-20.04
name: Ubuntu 20.04 | format
env:
CI_OS_NAME: linux
CI_RUNS_ON: ubuntu-20.04
CI_COMMIT: ${{ github.sha }}
steps:
- name: Checkout
uses: actions/checkout@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Install packages for build
env:
CI_BUILD_STAGE_NAME: build
run: |
bash ci/ci-install.bash &&
sudo apt-get install clang-10 yapf3 &&
git config --global user.email "[email protected]" &&
git config --global user.name "github action"
- name: Format code
run: |
autoconf &&
./configure &&
make -j 2 format CLANGFORMAT=clang-format-10 &&
git status
- name: Push
run: |
if [ -n "$(git status --porcelain)" ]; then
git commit . -m "Apply clang-format" &&
git push origin
fi
+17
View File
@@ -0,0 +1,17 @@
# 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-20.04
steps:
- uses: actions/checkout@v2
- run: test_regress/t/t_dist_contributors.pl
+100
View File
@@ -0,0 +1,100 @@
# DESCRIPTION: Github actions config
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
name: coverage
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 0' # weekly
env:
CI_OS_NAME: linux
CI_COMMIT: ${{ github.sha }}
CCACHE_COMPRESS: 1
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_MAXSIZE: 2Gi # 2GiB for clang and gcc, 4GiB in total
COVERAGE: 1
jobs:
Build:
runs-on: ubuntu-20.04
env:
CI_BUILD_STAGE_NAME: build
CI_RUNS_ON: ${{ matrix.os }}
CACHE_KEY: ${{ matrix.os }}-${{ matrix.compiler.cc }}-coverage
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v2
env:
cache-name: ccache
with:
path: ${{ github.workspace }}/.ccache
key: ${{ env.CACHE_KEY }}-${{ env.cache-name }}-${{ github.sha }}
restore-keys: coverage-${{ env.cache-name }}
- name: Install dependencies for build
env:
CI_BUILD_STAGE_NAME: build
run: ./ci/ci-install.bash
- name: Build Verilator
run: |
./ci/ci-script.bash
tar cvzf verilator-${CI_COMMIT}-coverage.tgz bin src/obj*/*.o src/obj*/*.gcno
- uses: actions/upload-artifact@v2
with:
path: verilator-${{ env.CI_COMMIT }}-coverage.tgz
Test:
needs: Build
strategy:
fail-fast: false
matrix:
test:
- vlt-
- vltmt-
num:
- 0
- 1
- 2
- 3
include:
- { test: dist, num: '' }
name: test-${{ matrix.test }}${{ matrix.num }}
runs-on: ubuntu-20.04
env:
CI_BUILD_STAGE_NAME: test
CI_RUNS_ON: ${{ matrix.os }}
CACHE_KEY: ${{ matrix.os }}-${{ matrix.compiler.cc }}-coverage
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v2
env:
cache-name: ccache
with:
path: ${{ github.workspace }}/.ccache
key: ${{ env.CACHE_KEY }}-${{ env.cache-name }}-${{ github.sha }}
restore-keys: coverage-${{ env.cache-name }}
- uses: actions/download-artifact@v2
- name: Install Verilator and test dependencies
run: |
tar xvzf artifact/verilator-${CI_COMMIT}-coverage.tgz
touch src/obj*/*.o src/obj*/*.gcno
./ci/ci-install.bash
- name: Test
env:
TESTS: coverage-${{ matrix.test }}${{ matrix.num }}
run: ./ci/ci-script.bash
+2
View File
@@ -15,6 +15,8 @@
*.tex
*.pdf
/Makefile
/.ccache
/artifact/
README
TAGS
autom4te.cache
-149
View File
@@ -1,149 +0,0 @@
# DESCRIPTION: Travis-CI config
#
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
version: ~> 1.0
language: cpp
cache:
directories:
- $HOME/.ccache
env:
global:
- VERILATOR_ROOT=$TRAVIS_BUILD_DIR
# The list and order of build stages
stages:
- build # Build Verilator
- test # Run tests
# Dump info about the environment for debugging
before_install:
# To dump the script that Travis itself is executing, add 'cat $0' here
- cd "$TRAVIS_BUILD_DIR" # Skipping the git clone in later stages requires this
- export CCACHE_MAXSIZE=$(ci/travis-ccache-size.bash) # Set here after the 'cd'
- env | sort
- ls -lA .
- ls -lA bin
- g++ -E -dM -c -x c++ /dev/null | sort
- clang++ -E -dM -c -x c++ /dev/null | sort
# Install all dependencies
# We run twice to attempt on failure to recover from temp network problems
install:
- ./ci/travis-install.bash || ./ci/travis-install.bash
before_script:
# ccache maintenance
- ./ci/travis-ccache-maint.bash
# Don't produce core dumps (esp. on FreeBSD)
- ulimit -c 0
# On Focal, set the SystemC installation location
- |
if [ "$TRAVIS_DIST" = "focal" ] && [ "$M32" != "1" ]; then
export SYSTEMC_INCLUDE=/usr/include
export SYSTEMC_LIBDIR=/usr/lib/x86_64-linux-gnu
fi
# Override compiler for M32
- |
if [ "$M32" = "1" ]; then
export CC="$CC -m32"
export CXX="$CXX -m32"
unset M32 # verilated.mk actually references $(M32) so unset
fi
before_cache:
- ccache -s -z
# All jobs run the same script
script: ./ci/travis-script.bash
# Enumerate all the jobs
jobs:
include:
############################################################################
# Jobs in the 'build' stage
############################################################################
# GCC builds
- {stage: build, if: type = cron, os: linux, dist: trusty, compiler: gcc, workspaces: {create: {name: trusty-gcc, paths: .}}}
- {stage: build, if: type = cron, os: linux, dist: xenial, compiler: gcc, workspaces: {create: {name: xenial-gcc, paths: .}}}
- {stage: build, if: type = cron, os: linux, dist: bionic, compiler: gcc, workspaces: {create: {name: bionic-gcc, paths: .}}}
- {stage: build, os: linux, dist: focal, compiler: gcc, workspaces: {create: {name: focal-gcc, paths: .}}}
# Clang builds
- {stage: build, if: type = cron, os: linux, dist: xenial, compiler: clang, workspaces: {create: {name: xenial-clang, paths: .}}}
- {stage: build, os: linux, dist: focal, compiler: clang, workspaces: {create: {name: focal-clang, paths: .}}}
# Coverage build
- {stage: build, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {create: {name: coverage, paths: .}}, env: COVERAGE=1}
# 32-bit build
- {stage: build, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {create: {name: focal-gcc-m32, paths: .}}, env: M32=1}
# OS X build
- {stage: build, if: type = cron, os: osx, osx_image: xcode11.6, compiler: clang, workspaces: {create: {name: osx-xcode11.6, paths: .}}}
# FreeBSD build
#- {stage: build, if: type = cron, os: freebsd, compiler: clang, workspaces: {create: {name: freebsd, paths: .}}}
############################################################################
# Jobs in the 'test' stage
############################################################################
# GCC tests
- {stage: test, if: type = cron, os: linux, dist: trusty, compiler: gcc, workspaces: {use: trusty-gcc}, git: {clone: false}, env: TESTS=dist-vlt-0}
- {stage: test, if: type = cron, os: linux, dist: trusty, compiler: gcc, workspaces: {use: trusty-gcc}, git: {clone: false}, env: TESTS=dist-vlt-1}
- {stage: test, if: type = cron, os: linux, dist: trusty, compiler: gcc, workspaces: {use: trusty-gcc}, git: {clone: false}, env: TESTS=vltmt-0}
- {stage: test, if: type = cron, os: linux, dist: trusty, compiler: gcc, workspaces: {use: trusty-gcc}, git: {clone: false}, env: TESTS=vltmt-1}
- {stage: test, if: type = cron, os: linux, dist: xenial, compiler: gcc, workspaces: {use: xenial-gcc}, git: {clone: false}, env: TESTS=dist-vlt-0}
- {stage: test, if: type = cron, os: linux, dist: xenial, compiler: gcc, workspaces: {use: xenial-gcc}, git: {clone: false}, env: TESTS=dist-vlt-1}
- {stage: test, if: type = cron, os: linux, dist: xenial, compiler: gcc, workspaces: {use: xenial-gcc}, git: {clone: false}, env: TESTS=vltmt-0}
- {stage: test, if: type = cron, os: linux, dist: xenial, compiler: gcc, workspaces: {use: xenial-gcc}, git: {clone: false}, env: TESTS=vltmt-1}
- {stage: test, if: type = cron, os: linux, dist: bionic, compiler: gcc, workspaces: {use: bionic-gcc}, git: {clone: false}, env: TESTS=dist-vlt-0}
- {stage: test, if: type = cron, os: linux, dist: bionic, compiler: gcc, workspaces: {use: bionic-gcc}, git: {clone: false}, env: TESTS=dist-vlt-1}
- {stage: test, if: type = cron, os: linux, dist: bionic, compiler: gcc, workspaces: {use: bionic-gcc}, git: {clone: false}, env: TESTS=vltmt-0}
- {stage: test, if: type = cron, os: linux, dist: bionic, compiler: gcc, workspaces: {use: bionic-gcc}, git: {clone: false}, env: TESTS=vltmt-1}
- {stage: test, if: type != cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: focal-gcc}, git: {clone: false}, env: TESTS=dist-vlt-0}
- {stage: test, if: type != cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: focal-gcc}, git: {clone: false}, env: TESTS=dist-vlt-1}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: focal-gcc}, git: {clone: false}, env: TESTS=vltmt-0}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: focal-gcc}, git: {clone: false}, env: TESTS=vltmt-1}
# Clang tests
- {stage: test, if: type = cron, os: linux, dist: xenial, compiler: clang, workspaces: {use: xenial-clang}, git: {clone: false}, env: TESTS=dist-vlt-0}
- {stage: test, if: type = cron, os: linux, dist: xenial, compiler: clang, workspaces: {use: xenial-clang}, git: {clone: false}, env: TESTS=dist-vlt-1}
- {stage: test, if: type = cron, os: linux, dist: xenial, compiler: clang, workspaces: {use: xenial-clang}, git: {clone: false}, env: TESTS=vltmt-0}
- {stage: test, if: type = cron, os: linux, dist: xenial, compiler: clang, workspaces: {use: xenial-clang}, git: {clone: false}, env: TESTS=vltmt-1}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: clang, workspaces: {use: focal-clang}, git: {clone: false}, env: TESTS=dist-vlt-0}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: clang, workspaces: {use: focal-clang}, git: {clone: false}, env: TESTS=dist-vlt-1}
- {stage: test, if: type != cron, os: linux, dist: focal, compiler: clang, workspaces: {use: focal-clang}, git: {clone: false}, env: TESTS=vltmt-0}
- {stage: test, if: type != cron, os: linux, dist: focal, compiler: clang, workspaces: {use: focal-clang}, git: {clone: false}, env: TESTS=vltmt-1}
# Coverage tests
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-dist}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vlt-0}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vlt-1}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vlt-2}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vlt-3}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vltmt-0}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vltmt-1}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vltmt-2}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: coverage}, git: {clone: false}, env: TESTS=coverage-vltmt-3}
# 32-bit tests
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: focal-gcc-m32}, git: {clone: false}, env: [M32=1, TESTS=dist-vlt-0]}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: focal-gcc-m32}, git: {clone: false}, env: [M32=1, TESTS=dist-vlt-1]}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: focal-gcc-m32}, git: {clone: false}, env: [M32=1, TESTS=vltmt-0]}
- {stage: test, if: type = cron, os: linux, dist: focal, compiler: gcc, workspaces: {use: focal-gcc-m32}, git: {clone: false}, env: [M32=1, TESTS=vltmt-1]}
# OS X tests
- {stage: test, if: type = cron, os: osx, osx_image: xcode11.6, compiler: clang, workspaces: {use: osx-xcode11.6}, git: {clone: false}, env: TESTS=dist-vlt-0}
- {stage: test, if: type = cron, os: osx, osx_image: xcode11.6, compiler: clang, workspaces: {use: osx-xcode11.6}, git: {clone: false}, env: TESTS=dist-vlt-1}
- {stage: test, if: type = cron, os: osx, osx_image: xcode11.6, compiler: clang, workspaces: {use: osx-xcode11.6}, git: {clone: false}, env: TESTS=vltmt-0}
- {stage: test, if: type = cron, os: osx, osx_image: xcode11.6, compiler: clang, workspaces: {use: osx-xcode11.6}, git: {clone: false}, env: TESTS=vltmt-1}
# FreeBSD tests
#- {stage: test, if: type = cron, os: freebsd, compiler: clang, workspaces: {use: freebsd}, git: {clone: false}, env: TESTS=dist-vlt-0}
#- {stage: test, if: type = cron, os: freebsd, compiler: clang, workspaces: {use: freebsd}, git: {clone: false}, env: TESTS=dist-vlt-1}
#- {stage: test, if: type = cron, os: freebsd, compiler: clang, workspaces: {use: freebsd}, git: {clone: false}, env: TESTS=vltmt-0}
#- {stage: test, if: type = cron, os: freebsd, compiler: clang, workspaces: {use: freebsd}, git: {clone: false}, env: TESTS=vltmt-1}
notifications:
email:
if: repo = verilator/verilator
recipients:
- [email protected]
- [email protected]
+88 -1
View File
@@ -3,6 +3,93 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 4.110 2021-02-25
*** Optimize bit operations and others (#2186) (#2632) (#2633) (#2751) (#2800) [Yutetsu TAKATSUKASA]
**** Support concat selection (#2721).
**** Support struct scopes when dumping structs to VCD (#2776) [Alex Torregrosa]
**** Generate SELRANGE for potentially unreachable code (#2625) (#2754) [Pierre-Henri Horrein]
**** For --flatten, override inlining of public and no_inline modules (#2761) [James Hanlon]
**** Fix little endian interface pin swizzling (#2475). [Don Owen]
**** Fix range inheritance on port without data type (#2753). [Embedded Go]
**** Fix TIMESCALE warnings on primitives (#2763). [Xuanqi]
**** Fix to exclude strings from toggle coverage (#2766) (#2767) [Paul Wright]
**** Fix $fread extra semicolon inside statements. [Leendert van Doorn]
**** Fix class extends with VM_PARALLEL_BUILDS (#2775). [Iru Cai]
**** Fix shifts by > 32 bit values (#2785). [qrq992]
**** Fix examples not flushing vcd (#2787). [Richard E George]
**** Fix little endian packed array pattern assignment (#2795). [Alex Torregrosa]
* Verilator 4.108 2021-01-10
** Many VPI changes for IEEE compatibility, which may alter behavior from previous releases.
** Support randomize() class method and rand (#2607). [Krzysztof Bieganski]
*** Support $cast and new CASTCONST warning.
*** Add --top option as alias of --top-module.
*** Add LATCH and NOLATCH warnings (#1609) (#2740). [Julien Margetts]
**** Remove Unix::Processors internal test dependency.
**** Report UNUSED on parameters, localparam and genvars (#2627). [Charles Eric LaForest]
**** Add error on real to non-real output pins (#2690). [Peter Monsson]
**** Support package imports before parameters in interfaces (#2714). [James Hanlon]
**** Support --sanitize in internal tests (#2705). [Yutetsu TAKATSUKASA]
**** Fix passing parameter type instantiations by position number.
**** Fix DPI open array handling issues.
**** Fix error when dotted refers to missing module (#2095). [Alexander Grobman]
**** Fix little endian packed array counting (#2499). [phantom-killua]
**** Fix showing reference locations for BLKANDNBLK (#2170). [Yuri Victorovich]
**** Fix genblk naming to match IEEE (#2686). [tinshark]
**** Fix VPI memory word indexing (#2695). [Marlon James]
**** Fix vpiLeftRange on little-endian memories (#2696). [Marlon James]
**** Fix VPI module tree (#2704). [Todd Strader]
**** Fix vpi_release_handle to be called implicitly per IEEE (#2706).
**** Fix to allow inheriting 'VerilatedVcdFile' class. (#2720) [HyungKi Jeong]
**** Fix $urandom_range maximum value (#2723). [Nandu Raj]
**** Fix tracing empty sc module (#2729).
**** Fix generate for unrolling to be signed (#2730). [yanx21]
**** Fix to emit timescale in hierarchical blocks (#2735). [Yutetsu TAKATSUKASA]
**** Fix to ignore coverage on real ports (#2741) (#2745). [Paul Wright]
* Verilator 4.106 2020-12-02
** Change -sv option to select 1800-2017 instead of 1800-2005.
@@ -3835,7 +3922,7 @@ of input ports exists for tracing.
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
Copyright 2001-2020 by Wilson Snyder. This program is free software; you
Copyright 2001-2021 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+3
View File
@@ -1,3 +1,4 @@
\.ccache/
\.clang-format
\.clang-tidy
\.git/
@@ -23,6 +24,7 @@
/obj_dir/
/obj_dist/
/obj_iv/
/obj_ms/
/obj_nc/
/obj_opt/
/obj_vcs/
@@ -45,6 +47,7 @@ src/Makefile$
src/Makefile_obj$
include/verilated.mk$
test_regress/.gdbinit$
test_regress/transcript
codecov.yml
config.cache$
config.status$
+33 -4
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you
# Copyright 2003-2021 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.
@@ -153,6 +153,7 @@ DISTFILES_INC = $(INFOS) .gitignore \
.*attributes */.*attributes */*/.*attributes \
src/.*ignore src/*.in src/*.cpp src/*.[chly] \
src/astgen src/bisonpre src/*fix src/cppcheck_filtered \
src/config_rev \
src/vlcovgen src/mkinstalldirs \
src/.gdbinit \
src/*.pl src/*.pod \
@@ -219,7 +220,7 @@ all_nomsg: verilator_exe $(VL_INST_MAN_FILES)
verilator_exe verilator_bin verilator_bin_dbg verilator_coverage_bin_dbg:
@echo ------------------------------------------------------------
@echo "making verilator in src"
$(MAKE) -C src $(OBJCACHE_JOBS)
$(MAKE) -C src $(OBJCACHE_JOBS) $(CI_MAKE_SRC_TARGET)
.PHONY:msg_test
msg_test: all_nomsg
@@ -421,6 +422,7 @@ endif
# Use --xml flag to see the cppcheck code to use for suppression
CPPCHECK_CPP = $(wildcard \
$(srcdir)/examples/*/*.cpp \
$(srcdir)/include/*.cpp \
$(srcdir)/src/*.cpp )
CPPCHECK_H = $(wildcard \
@@ -429,7 +431,7 @@ CPPCHECK_H = $(wildcard \
CPPCHECK_YL = $(wildcard \
$(srcdir)/src/*.y \
$(srcdir)/src/*.l )
CPPCHECK = src/cppcheck_filtered
CPPCHECK = src/cppcheck_filtered cppcheck
CPPCHECK_FLAGS = --enable=all --inline-suppr \
--suppress=unusedScopedObject --suppress=cstyleCast --suppress=useInitializationList \
--suppress=nullPointerRedundantCheck
@@ -461,15 +463,42 @@ analyzer-include:
-rm -rf examples/*/obj*
scan-build $(MAKE) -k examples
format: clang-format yapf format-pl-exec
CLANGFORMAT = clang-format
CLANGFORMAT_FLAGS = -i
CLANGFORMAT_FILES = $(CPPCHECK_CPP) $(CPPCHECK_H) $(CPPCHECK_YL) test_regress/t/*.c*
CLANGFORMAT_FILES = $(CPPCHECK_CPP) $(CPPCHECK_H) $(CPPCHECK_YL) test_regress/t/*.c* test_regress/t/*.h
clang-format:
@$(CLANGFORMAT) --version | egrep 10.0 > /dev/null \
|| echo "*** You are not using clang-format 10.0, indents may differ from master's ***"
$(CLANGFORMAT) $(CLANGFORMAT_FLAGS) $(CLANGFORMAT_FILES)
YAPF = yapf3
YAPF_FLAGS = -i
YAPF_FILES = \
examples/xml_py/vl_file_copy \
examples/xml_py/vl_hier_graph \
src/astgen \
src/bisonpre \
src/config_rev \
src/cppcheck_filtered \
src/flexfix \
src/vlcovgen \
nodist/code_coverage \
nodist/code_coverage.dat \
nodist/dot_importer \
nodist/fuzzer/actual_fail \
nodist/fuzzer/generate_dictionary \
nodist/install_test \
yapf:
$(YAPF) $(YAPF_FLAGS) $(YAPF_FILES)
format-pl-exec:
-chmod a+x test_regress/t/*.pl
ftp: info
install-msg:
+2 -2
View File
@@ -6,7 +6,7 @@ image:https://img.shields.io/badge/License-LGPL%20v3-blue.svg[license LGPLv3,lin
image:https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg[license Artistic-2.0,link=https://opensource.org/licenses/Artistic-2.0]
image:https://api.codacy.com/project/badge/Grade/fa78caa433c84a4ab9049c43e9debc6f[Code Quality,link=https://www.codacy.com/gh/verilator/verilator]
image:https://codecov.io/gh/verilator/verilator/branch/master/graph/badge.svg[Coverage,link=https://codecov.io/gh/verilator/verilator]
image:https://travis-ci.com/verilator/verilator.svg?branch=master[Build Status (Travis CI),link=https://travis-ci.com/verilator/verilator]
image:https://github.com/verilator/verilator/workflows/build/badge.svg[Build Status (GitHub),link=https://github.com/verilator/verilator/actions?query=workflow%3Abuild]
endif::[]
ifdef::env-github[]
@@ -145,7 +145,7 @@ perhaps Icarus may.
== Open License
Verilator is Copyright 2003-2020 by Wilson Snyder. (Report bugs to
Verilator is Copyright 2003-2021 by Wilson Snyder. (Report bugs to
https://verilator.org/issues[Verilator Issues].)
Verilator is free software; you can redistribute it and/or modify it under
+130 -73
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
######################################################################
#
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you
# Copyright 2003-2021 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.
@@ -409,6 +409,7 @@ arguments.
--threads-max-mtasks <mtasks> Tune maximum mtask partitioning
--timescale <timescale> Sets default timescale
--timescale-override <timescale> Overrides all timescales
--top <topname> Alias of --top-module
--top-module <topname> Name of top level input module
--trace Enable waveform creation
--trace-coverage Enable tracing of coverage
@@ -454,11 +455,11 @@ ARGUMENTS"> for the detailed description of these arguments.
+verilator+debug Enable debugging
+verilator+debugi+<value> Enable debugging at a level
+verilator+help Display help
+verilator+prof+threads+file+I<filename> Set profile filename
+verilator+prof+threads+start+I<value> Set profile starting point
+verilator+prof+threads+window+I<value> Set profile duration
+verilator+rand+reset+I<value> Set random reset technique
+verilator+seed+I<value> Set random seed
+verilator+prof+threads+file+<filename> Set profile filename
+verilator+prof+threads+start+<value> Set profile starting point
+verilator+prof+threads+window+<value> Set profile duration
+verilator+rand+reset+<value> Set random reset technique
+verilator+seed+<value> Set random seed
+verilator+noassert Disable assert checking
+verilator+V Verbose version and config
+verilator+version Show version and exit
@@ -755,7 +756,7 @@ is fairly standard across Verilog tools while -D is similar to GCC.
Select the debug executable of Verilator (if available), and enable more
internal assertions (equivalent to C<--debug-check>), debugging messages
(equivalent to C<--debugi 4>), and intermediate form dump files (equivalent
(equivalent to C<--debugi 3>), and intermediate form dump files (equivalent
to C<--dump-treei 3>).
=item --debug-check
@@ -1260,8 +1261,8 @@ With -E, show comments in preprocessor output.
=item --prefix I<topname>
Specifies the name of the top level class and makefile. Defaults to V
prepended to the name of the --top-module switch, or V prepended to the
first Verilog filename passed on the command line.
prepended to the name of the --top switch, or V prepended to the first
Verilog filename passed on the command line.
=item --prof-cfuncs
@@ -1523,6 +1524,8 @@ sc_set_time_resolution, or the C++ code instantiating the Verilated module.
As 1fs is the finest time precision it may be desirable to always use a
precision of 1fs.
=item --top I<topname>
=item --top-module I<topname>
When the input Verilog contains more than one top level module, specifies
@@ -1636,8 +1639,8 @@ into Verilator. (Similar to perl -V.) See also --getenv.
=item -v I<filename>
Read the filename as a Verilog library. Any modules in the file may be
used to resolve cell instantiations in the top level module, else ignored.
Note -v is fairly standard across Verilog tools.
used to resolve instances in the top level module, else ignored. Note -v
is fairly standard across Verilog tools.
=item --no-verilate
@@ -1714,7 +1717,7 @@ than using this option.
Disable all lint related warning messages, and all style warnings. This is
equivalent to "-Wno-ALWCOMBORDER -Wno-BSSPACE -Wno-CASEINCOMPLETE
-Wno-CASEOVERLAP -Wno-CASEX -Wno-CASEWITHX -Wno-CMPCONST -Wno-COLONPLUS
-Wno-CASEOVERLAP -Wno-CASEX -Wno-CASTCONST -Wno-CASEWITHX -Wno-CMPCONST -Wno-COLONPLUS
-Wno-ENDLABEL -Wno-IMPLICIT -Wno-LITENDIAN -Wno-PINCONNECTEMPTY
-Wno-PINMISSING -Wno-SYNCASYNCNET -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED
-Wno-WIDTH" plus the list shown for Wno-style.
@@ -1746,7 +1749,7 @@ Enables the specified warning message.
Enable all lint related warning messages (note by default they are already
enabled), but do not affect style messages. This is equivalent to
"-Wwarn-ALWCOMBORDER -Wwarn-BSSPACE -Wwarn-CASEINCOMPLETE
-Wwarn-CASEOVERLAP -Wwarn-CASEX -Wwarn-CASEWITHX -Wwarn-CMPCONST
-Wwarn-CASEOVERLAP -Wwarn-CASEX -Wwarn-CASTCONST -Wwarn-CASEWITHX -Wwarn-CMPCONST
-Wwarn-COLONPLUS -Wwarn-ENDLABEL -Wwarn-IMPLICIT -Wwarn-LITENDIAN
-Wwarn-PINMISSING -Wwarn-REALCVT -Wwarn-UNSIGNED -Wwarn-WIDTH".
@@ -2543,6 +2546,27 @@ called from Verilog by querying the scope of that function. See the
sections on DPI Context Functions and DPI Header Isolation below and the
comments within the svdpi.h header for more information.
=head2 DPI Imports that access signals
If a DPI import accesses a signal through the VPI Verilator will not be
able to know what variables are accessed and may schedule the code
inappropriately. Ideally pass the values as inputs/outputs so the VPI is
not required. Alternatively a workaround is to use a non-inlined task as a
wrapper:
logic din;
// This DPI function will read "din"
import "DPI-C" context function void dpi_that_accesses_din();
always @ (...)
dpi_din_args(din);
task dpi_din_args(input din);
/* verilator no_inline_task */
dpi_that_accesses_din();
endtask
=head2 DPI Display Functions
Verilator allows writing $display like functions using this syntax:
@@ -3101,8 +3125,8 @@ Enable/disable waveform tracing for all future signals declared in the
specified filename (or wildcard with '*' or '?', or all files if omitted)
and range of line numbers (or all lines if omitted).
For tracing_off, cells below any module in the files/ranges specified will
also not be traced.
For tracing_off, instances below any module in the files/ranges specified
will also not be traced.
=item clock_enable -module "<modulename>" -var "<signame>"
@@ -3774,13 +3798,13 @@ for use by downstream applications.
=item /*verilator tracing_off*/
Disable waveform tracing for all future signals that are declared in this
module, or cells below this module. Often this is placed just after a
primitive's module statement, so that the entire module and cells below it
are not traced.
module, or instances below this module. Often this is placed just after a
primitive's module statement, so that the entire module and instances below
it are not traced.
=item /*verilator tracing_on*/
Re-enable waveform tracing for all future signals or cells that are
Re-enable waveform tracing for all future signals or instances that are
declared.
=back
@@ -3834,8 +3858,8 @@ for example a[2].b is acceptable, while a[x].b is generally not.
References into generated and arrayed instances use the instance names
specified in the Verilog standard; arrayed instances are named
{cellName}[{instanceNumber}] in Verilog, which becomes
{cellname}__BRA__{instanceNumber}__KET__ inside the generated C++ code.
{instanceName}[{instanceNumber}] in Verilog, which becomes
{instanceName}__BRA__{instanceNumber}__KET__ inside the generated C++ code.
=head2 Latches
@@ -4314,15 +4338,6 @@ not overlap.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item CASEX
Warns that it is simply better style to use casez, and C<?> in place of
C<x>'s. See
L<http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf>
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item CASEWITHX
Warns that a case statement contains a constant with a C<x>. Verilator is
@@ -4333,6 +4348,25 @@ instead intended is to use a casez with C<?>.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item CASEX
Warns that it is simply better style to use casez, and C<?> in place of
C<x>'s. See
L<http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf>
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item CASTCONST
Warns that a dynamic cast ($cast) is unnecessary as the $cast will always
succeed or fail. If it will always fail, the $cast is useless. If it will
always succeed a static cast may be preferred.
Ignoring this warning will only suppress the lint check, it will simulate
correctly. On other simulators, not fixing CASTCONST may result in
decreased performance.
=item CDCRSTLOGIC
With --cdc only, warns that asynchronous flop reset terms come from other
@@ -4510,9 +4544,9 @@ top module statement is processed.
Warns that a wire is being implicitly declared (it is a single bit wide
output from a sub-module.) While legal in Verilog, implicit declarations
only work for single bit wide signals (not buses), do not allow using a
signal before it is implicitly declared by a cell, and can lead to dangling
nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for
Emacs, available from L<https://www.veripool.org/verilog-mode>
signal before it is implicitly declared by an instance, and can lead to
dangling nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode
for Emacs, available from L<https://www.veripool.org/verilog-mode>
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
@@ -4578,6 +4612,16 @@ exposed is acceptable.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item LATCH
Warns that a signal is not assigned in all control paths of a combinational
always block, resulting in the inference of a latch. For intentional
latches, consider using the always_latch (SystemVerilog) keyword instead.
The warning may be disabled with a lint_off pragma around the always block.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item LITENDIAN
Warns that a packed vector is declared with little endian bit numbering
@@ -4585,10 +4629,10 @@ Warns that a packed vector is declared with little endian bit numbering
and little numbering is now thus often due to simple oversight instead of
intent.
Also warns that a cell is declared with little endian range (i.e. [0:7] or
[7]) and is connected to a N-wide signal. Based on IEEE the bits will
likely be backwards from what you expect (i.e. cell [0] will connect to
signal bit [N-1] not bit [0]).
Also warns that an instance is declared with little endian range
(i.e. [0:7] or [7]) and is connected to a N-wide signal. Based on IEEE the
bits will likely be backwards from what you expect (i.e. instance [0] will
connect to signal bit [N-1] not bit [0]).
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
@@ -4620,18 +4664,18 @@ instantiated by any other module, and both modules were put on the command
line (not in a library). Three likely cases:
1. A single module is intended to be the top. This warning then occurs
because some low level cell is being read in, but is not really needed as
part of the design. The best solution for this situation is to ensure that
only the top module is put on the command line without any flags, and all
remaining library files are read in as libraries with -v, or are
because some low level instance is being read in, but is not really needed
as part of the design. The best solution for this situation is to ensure
that only the top module is put on the command line without any flags, and
all remaining library files are read in as libraries with -v, or are
automatically resolved by having filenames that match the module names.
2. A single module is intended to be the top, the name of it is known, and
all other modules should be ignored if not part of the design. The best
solution is to use the --top-module option to specify the top module's
name. All other modules that are not part of the design will be for the
most part ignored (they must be clean in syntax and their contents will be
removed as part of the Verilog module elaboration process.)
solution is to use the --top option to specify the top module's name. All
other modules that are not part of the design will be for the most part
ignored (they must be clean in syntax and their contents will be removed as
part of the Verilog module elaboration process.)
3. Multiple modules are intended to be design tops, e.g. when linting a
library file. As multiple modules are desired, disable the MULTITOP
@@ -4641,29 +4685,37 @@ based on the top module name followed by __02E (a Verilator-encoded ASCII
".'). This renaming is done even if the two modules' signals seem
identical, e.g. multiple modules with a "clk" input.
=item NOLATCH
Warns that no latch was detected in an always_latch block. The warning may
be disabled with a lint_off pragma around the always block, but recoding
using a regular always may be more appropriate.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item PINCONNECTEMPTY
Warns that a cell instantiation has a pin which is connected to
.pin_name(), e.g. not another signal, but with an explicit mention of the
pin. It may be desirable to disable PINCONNECTEMPTY, as this indicates
intention to have a no-connect.
Warns that an instance has a pin which is connected to .pin_name(),
e.g. not another signal, but with an explicit mention of the pin. It may
be desirable to disable PINCONNECTEMPTY, as this indicates intention to
have a no-connect.
Disabled by default as this is a code style warning; it will simulate
correctly.
=item PINMISSING
Warns that a module has a pin which is not mentioned in a cell
instantiation. If a pin is not missing it should still be specified on the
cell declaration with a empty connection, using "(.pin_name())".
Warns that a module has a pin which is not mentioned in an instance. If a
pin is not missing it should still be specified on the instance declaration
with a empty connection, using "(.pin_name())".
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item PINNOCONNECT
Warns that a cell instantiation has a pin which is not connected to another
signal.
Warns that an instance has a pin which is not connected to another signal.
Disabled by default as this is a code style warning; it will simulate
correctly.
@@ -4679,6 +4731,11 @@ declared before being used.
Error that a procedural assignment is setting a wire. According to IEEE, a
var/reg must be used as the target of procedural assignments.
=item RANDC
Warns that the 'randc' keyword is currently unsupported, and that it is
being converted to 'rand'.
=item REALCVT
Warns that a real number is being implicitly rounded to an integer, with
@@ -4782,12 +4839,12 @@ correctly.
=item TASKNSVAR
Error when a call to a task or function has a output from that task tied to
Error when a call to a task or function has an inout from that task tied to
a non-simple signal. Instead connect the task output to a temporary signal
of the appropriate width, and use that signal to set the appropriate
expression as the next statement. For example:
task foo; output sig; ... endtask
task foo(inout sig); ... endtask
always @* begin
foo(bus_we_select_from[2]); // Will get TASKNSVAR error
end
@@ -4901,7 +4958,7 @@ potentially resolving the conflict. If you run with --report-unoptflat
Verilator will suggest possible candidates for C<split_var>.
The UNOPTFLAT warning may also be due to clock enables, identified from the
reported path going through a clock gating cell. To fix these, use the
reported path going through a clock gating instance. To fix these, use the
clock_enable meta comment described above.
The UNOPTFLAT warning may also occur where outputs from a block of logic
@@ -4960,10 +5017,10 @@ design simulate incorrectly; see the details under --bbox-unsup.
=item UNUSED
Warns that the specified signal is never used/consumed. Verilator is
fairly liberal in the usage calculations; making a signal public, a signal
matching --unused-regexp ("*unused*") or accessing only a single array
element marks the entire signal as used.
Warns that the specified signal or parameter is never used/consumed.
Verilator is fairly liberal in the usage calculations; making a signal
public, a signal matching --unused-regexp ("*unused*") or accessing only a
single array element marks the entire signal as used.
Disabled by default as this is a code style warning; it will simulate
correctly.
@@ -5193,7 +5250,7 @@ want all data to land in the same output file.
topp->trace(tfp, 99); // Trace 99 levels of hierarchy
tfp->open("obj_dir/t_trace_ena_cc/simx.vcd");
...
while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {
while (vl_time_stamp64() < sim_time && !Verilated::gotFinish()) {
main_time += #;
tfp->dump(main_time);
}
@@ -5476,21 +5533,21 @@ by your code or you'll get strange results.
=item Should a module be in Verilog or SystemC?
Sometimes there is a block that just interconnects cells, and have a choice
as to if you write it in Verilog or SystemC. Everything else being equal,
best performance is when Verilator sees all of the design. So, look at the
hierarchy of your design, labeling cells as to if they are SystemC or
Verilog. Then:
Sometimes there is a block that just interconnects instances, and have a
choice as to if you write it in Verilog or SystemC. Everything else being
equal, best performance is when Verilator sees all of the design. So, look
at the hierarchy of your design, labeling instances as to if they are
SystemC or Verilog. Then:
A module with only SystemC cells below must be SystemC.
A module with only SystemC instances below must be SystemC.
A module with a mix of Verilog and SystemC cells below must be SystemC. (As
Verilator cannot connect to lower-level SystemC cells.)
A module with a mix of Verilog and SystemC instances below must be
SystemC. (As Verilator cannot connect to lower-level SystemC instances.)
A module with only Verilog cells below can be either, but for best
A module with only Verilog instances below can be either, but for best
performance should be Verilog. (The exception is if you have a design that
is instantiated many times; in this case Verilating one of the lower
modules and instantiating that Verilated cells multiple times into a
modules and instantiating that Verilated instances multiple times into a
SystemC module *may* be faster.)
=back
@@ -5679,7 +5736,7 @@ remain anonymous.
The latest version is available from L<https://verilator.org>.
Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
redistribute it and/or modify the Verilator internals under the terms of
either the GNU Lesser General Public License Version 3 or the Perl Artistic
License Version 2.0.
+2 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
######################################################################
#
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you
# Copyright 2003-2021 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.
@@ -278,7 +278,7 @@ Specifies a module search directory.
The latest version is available from L<https://verilator.org>.
Copyright 2003-2020 by Wilson Snyder. This program is free software; you
Copyright 2003-2021 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify the Verilator internals under the terms
of either the GNU Lesser General Public License Version 3 or the Perl
Artistic License Version 2.0.
+1 -1
View File
@@ -208,7 +208,7 @@ Do not show differences in line numbering.
The latest version is available from L<https://verilator.org>.
Copyright 2005-2020 by Wilson Snyder. This program is free software; you
Copyright 2005-2021 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+1 -1
View File
@@ -617,7 +617,7 @@ verilator_gantt.vcd.
The latest version is available from L<https://verilator.org>.
Copyright 2018-2020 by Wilson Snyder. This program is free software; you
Copyright 2018-2021 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
# DESCRIPTION: Print include statements for each ARGV
#
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
+1 -1
View File
@@ -228,7 +228,7 @@ Displays this message and program version and exits.
The latest version is available from L<https://verilator.org>.
Copyright 2007-2020 by Wilson Snyder. This program is free software; you
Copyright 2007-2021 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# DESCRIPTION: Verilator: Travis CI ccache maintenance
# DESCRIPTION: Verilator: CI ccache maintenance
#
# Copyright 2020 by Geza Lore. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
@@ -19,8 +19,8 @@ set -x
ccache --version
# Flush ccache if requested in commit message
COMMIT="${TRAVIS_PULL_REQUEST_SHA:-$TRAVIS_COMMIT}"
if git log --format=%B -n 1 "$COMMIT" | grep -q -i '\[travis\s\+ccache\s\+clear\]'; then
COMMIT="${CI_PULL_REQUEST_SHA:-$CI_COMMIT}"
if git log --format=%B -n 1 "$COMMIT" | grep -q -i '\[CI\s\+ccache\s\+clear\]'; then
echo "Flushing ccache due to commit message"
ccache -C
fi
+36 -28
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# DESCRIPTION: Verilator: Travis CI dependency install script
# DESCRIPTION: Verilator: CI dependency install script
#
# Copyright 2020 by Geza Lore. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
@@ -14,25 +14,23 @@
# required by the particular build stage.
################################################################################
# Note that Travis runs "apt-get update" when "apt-get install" is used in the
# .travis.yml file directly, but since we invoke it via this script, we need to
# run it manually where requried, otherwise some packages cannot be found.
set -e
set -x
cd $(dirname "$0")/..
fatal() {
echo "ERROR: $(basename "$0"): $1" >&2; exit 1;
}
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
if [ "$CI_OS_NAME" = "linux" ]; then
MAKE=make
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
elif [ "$CI_OS_NAME" = "osx" ]; then
MAKE=make
elif [ "$TRAVIS_OS_NAME" = "freebsd" ]; then
elif [ "$CI_OS_NAME" = "freebsd" ]; then
MAKE=gmake
else
fatal "Unknown os: '$TRAVIS_OS_NAME'"
fatal "Unknown os: '$CI_OS_NAME'"
fi
install-vcddiff() {
@@ -43,61 +41,71 @@ install-vcddiff() {
sudo cp "${TMP_DIR}/vcddiff" /usr/local/bin
}
if [ "$TRAVIS_BUILD_STAGE_NAME" = "build" ]; then
if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
##############################################################################
# Dependencies of jobs in the 'build' stage, i.e.: packages required to
# build Verilator
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
if [ "$CI_OS_NAME" = "linux" ]; then
sudo apt-get update
sudo apt-get install libfl-dev
sudo apt-get install libgoogle-perftools-dev
sudo apt-get install libfl-dev libgoogle-perftools-dev ccache
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ]; then
sudo apt-get install libsystemc libsystemc-dev
fi
if [ "$COVERAGE" = 1 ]; then
yes yes | sudo cpan -fi Unix::Processors Parallel::Forker
yes yes | sudo cpan -fi Parallel::Forker
fi
if [ "$M32" = 1 ]; then
sudo apt-get install gcc-multilib g++-multilib
fi
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
elif [ "$CI_OS_NAME" = "osx" ]; then
brew update
brew install ccache perl gperftools
elif [ "$TRAVIS_OS_NAME" = "freebsd" ]; then
elif [ "$CI_OS_NAME" = "freebsd" ]; then
sudo pkg install -y autoconf bison ccache gmake perl5
else
fatal "Unknown os: '$TRAVIS_OS_NAME'"
fatal "Unknown os: '$CI_OS_NAME'"
fi
elif [ "$TRAVIS_BUILD_STAGE_NAME" = "test" ]; then
if [ -n "$CCACHE_DIR" ]; then
mkdir -p "$CCACHE_DIR" && ./ci/ci-ccache-maint.bash
fi
elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
##############################################################################
# Dependencies of jobs in the 'test' stage, i.e.: packages required to
# run the tests
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
if [ "$CI_OS_NAME" = "linux" ]; then
sudo apt-get update
sudo apt-get install gdb gtkwave lcov
if [ "$TRAVIS_DIST" = "focal" ]; then
# libfl-dev needed for internal coverage's test runs
sudo apt-get install gdb gtkwave lcov libfl-dev ccache
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ]; then
sudo apt-get install libsystemc-dev
fi
if [ "$M32" = 1 ]; then
sudo apt-get install lib32z1-dev gcc-multilib g++-multilib
fi
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
elif [ "$CI_OS_NAME" = "osx" ]; then
brew update
# brew cask install gtkwave # fst2vcd hangs at launch, so don't bother
brew install ccache perl
elif [ "$TRAVIS_OS_NAME" = "freebsd" ]; then
elif [ "$CI_OS_NAME" = "freebsd" ]; then
# fst2vcd fails with "Could not open '<input file>', exiting."
sudo pkg install -y ccache gmake perl5 python3
else
fatal "Unknown os: '$TRAVIS_OS_NAME'"
fatal "Unknown os: '$CI_OS_NAME'"
fi
# Common installs
if [ "$TRAVIS_DIST" != "trusty" ]; then
TRAVIS_CPAN_REPO=https://cpan.org
if [ "$CI_RUNS_ON" != "ubuntu-14.04" ]; then
CI_CPAN_REPO=https://cpan.org
fi
yes yes | sudo cpan -M $TRAVIS_CPAN_REPO -fi Unix::Processors Parallel::Forker
yes yes | sudo cpan -M $CI_CPAN_REPO -fi Parallel::Forker
install-vcddiff
autoconf
./configure --enable-longtests --enable-ccwarn
else
##############################################################################
# Unknown build stage
fatal "Unknown build stage: '$TRAVIS_BUILD_STAGE_NAME'"
fatal "Unknown build stage: '$CI_BUILD_STAGE_NAME'"
fi
+36 -29
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# DESCRIPTION: Verilator: Travis CI main job script
# DESCRIPTION: Verilator: CI main job script
#
# Copyright 2020 by Geza Lore. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
@@ -10,9 +10,8 @@
################################################################################
# This is the main script executed in the 'script' phase by all jobs. We use a
# single script to keep the .travis.yml spec simple. We pass job parameters via
# environment variables using 'env' keys. Having different 'env' keys in jobs
# ensures they use different Travis build caches.
# single script to keep the CI setting simple. We pass job parameters via
# environment variables using 'env' keys.
################################################################################
set -e
@@ -22,20 +21,20 @@ fatal() {
echo "ERROR: $(basename "$0"): $1" >&2; exit 1;
}
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
if [ "$CI_OS_NAME" = "linux" ]; then
export MAKE=make
NPROC=$(nproc)
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
elif [ "$CI_OS_NAME" = "osx" ]; then
export MAKE=make
NPROC=$(sysctl -n hw.logicalcpu)
elif [ "$TRAVIS_OS_NAME" = "freebsd" ]; then
elif [ "$CI_OS_NAME" = "freebsd" ]; then
export MAKE=gmake
NPROC=$(sysctl -n hw.ncpu)
else
fatal "Unknown os: '$TRAVIS_OS_NAME'"
fatal "Unknown os: '$CI_OS_NAME'"
fi
if [ "$TRAVIS_BUILD_STAGE_NAME" = "build" ]; then
if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
##############################################################################
# Build verilator
@@ -43,7 +42,7 @@ if [ "$TRAVIS_BUILD_STAGE_NAME" = "build" ]; then
autoconf
./configure --enable-longtests --enable-ccwarn
"$MAKE" -j "$NPROC" -k
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
if [ "$CI_OS_NAME" = "osx" ]; then
file bin/verilator_bin
file bin/verilator_bin_dbg
md5 bin/verilator_bin
@@ -52,15 +51,17 @@ if [ "$TRAVIS_BUILD_STAGE_NAME" = "build" ]; then
stat bin/verilator_bin_dbg
fi
else
nodist/code_coverage --stages 1-2
nodist/code_coverage --stages 0-2
fi
elif [ "$TRAVIS_BUILD_STAGE_NAME" = "test" ]; then
elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
##############################################################################
# Run tests
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
export VERILATOR_TEST_NO_GDB=1 # Pain to get GDB to work on OS X
export VERILATOR_TEST_NO_GPROF=1 # Apple Clang has no -pg
export VERILATOR_TEST_NO_CONTRIBUTORS=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
export VERILATOR_TEST_NO_GPROF=1 # Apple Clang has no -pg
# export PATH="/Applications/gtkwave.app/Contents/Resources/bin:$PATH" # fst2vcd
file bin/verilator_bin
file bin/verilator_bin_dbg
@@ -70,21 +71,24 @@ elif [ "$TRAVIS_BUILD_STAGE_NAME" = "test" ]; then
stat bin/verilator_bin_dbg
# For some reason, the dbg exe is corrupted by this point ('file' reports
# it as data rather than a Mach-O). Unclear if this is an OS X issue or
# one for Travis. Remove the file and re-link...
# CI's. Remove the file and re-link...
rm bin/verilator_bin_dbg
"$MAKE" -j "$NPROC" -k
elif [ "$TRAVIS_OS_NAME" = "freebsd" ]; then
elif [ "$CI_OS_NAME" = "freebsd" ]; then
export VERILATOR_TEST_NO_GDB=1 # Disable for now, ideally should run
export VERILATOR_TEST_NO_GPROF=1 # gprof is a bit different on FreeBSD, disable
fi
# Run sanitize on Ubuntu 20.04 only
[ "$CI_RUNS_ON" = 'ubuntu-20.04' ] && sanitize='--sanitize' || sanitize=''
# Run the specified test
case $TESTS in
dist-vlt-0)
"$MAKE" -C test_regress SCENARIOS="--dist --vlt" DRIVER_HASHSET=--hashset=0/2
"$MAKE" -C test_regress SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=0/2
;;
dist-vlt-1)
"$MAKE" -C test_regress SCENARIOS="--dist --vlt" DRIVER_HASHSET=--hashset=1/2
"$MAKE" -C test_regress SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=1/2
;;
vltmt-0)
"$MAKE" -C test_regress SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=0/2
@@ -92,32 +96,35 @@ elif [ "$TRAVIS_BUILD_STAGE_NAME" = "test" ]; then
vltmt-1)
"$MAKE" -C test_regress SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=1/2
;;
coverage-all)
nodist/code_coverage --stages 1-
;;
coverage-dist)
nodist/code_coverage --stages 3- --scenarios=--dist
nodist/code_coverage --stages 1- --scenarios=--dist
;;
coverage-vlt-0)
nodist/code_coverage --stages 3- --scenarios=--vlt --hashset=0/4
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=0/4
;;
coverage-vlt-1)
nodist/code_coverage --stages 3- --scenarios=--vlt --hashset=1/4
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=1/4
;;
coverage-vlt-2)
nodist/code_coverage --stages 3- --scenarios=--vlt --hashset=2/4
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=2/4
;;
coverage-vlt-3)
nodist/code_coverage --stages 3- --scenarios=--vlt --hashset=3/4
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=3/4
;;
coverage-vltmt-0)
nodist/code_coverage --stages 3- --scenarios=--vltmt --hashset=0/4
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=0/4
;;
coverage-vltmt-1)
nodist/code_coverage --stages 3- --scenarios=--vltmt --hashset=1/4
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=1/4
;;
coverage-vltmt-2)
nodist/code_coverage --stages 3- --scenarios=--vltmt --hashset=2/4
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=2/4
;;
coverage-vltmt-3)
nodist/code_coverage --stages 3- --scenarios=--vltmt --hashset=3/4
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=3/4
;;
*)
fatal "Unknown test: $TESTS"
@@ -130,5 +137,5 @@ elif [ "$TRAVIS_BUILD_STAGE_NAME" = "test" ]; then
else
##############################################################################
# Unknown build stage
fatal "Unknown build stage: '$TRAVIS_BUILD_STAGE_NAME'"
fatal "Unknown build stage: '$CI_BUILD_STAGE_NAME'"
fi
+1 -1
View File
@@ -40,7 +40,7 @@ RUN apt-get update \
WORKDIR /tmp
RUN cpan install -fi Unix::Processors Parallel::Forker
RUN cpan install -fi Parallel::Forker
RUN git clone https://github.com/veripool/vcddiff.git && \
make -C vcddiff && \
+1 -1
View File
@@ -27,5 +27,5 @@ if [ -e ${obj_dir} ]; then
cp -r /usr/local/share/verilator/bin ${obj_dir}/vlt
cp -r /usr/local/share/verilator/include ${obj_dir}/vlt
# Point Makefile to that folder
perl -i -pe 's/VERILATOR_ROOT = \/usr\/local\/share\/verilator/VERILATOR_ROOT = vlt/g' ${obj_dir}/*.mk
sed -i 's/VERILATOR_ROOT = \/usr\/local\/share\/verilator/VERILATOR_ROOT = vlt/g' ${obj_dir}/*.mk
fi
-37
View File
@@ -1,37 +0,0 @@
#!/usr/bin/env bash
# DESCRIPTION: Verilator: Travis CI ccache sizer
#
# Copyright 2020 by Geza Lore. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
################################################################################
# This script computes the size of the ccache to be used for a job. We want the
# ccache to be just big enough to be able to hold a whole build so a re-build
# of the same does not miss in the cache due to capacity, but we don't want the
# ccache too big as pulling it down from the network takes time, and it is
# unlikely objects from much earlier builds would be useful.
################################################################################
fatal() {
echo "ERROR: $(basename "$0"): $1" >&2; exit 1;
}
if [ "$TRAVIS_BUILD_STAGE_NAME" = "build" ]; then
if [ "$COVERAGE" == 1 ]; then
echo "1024M"
else
echo "768M"
fi
elif [ "$TRAVIS_BUILD_STAGE_NAME" = "test" ]; then
if [[ $TESTS == coverage-* ]]; then
echo "1536M"
else
echo "256M"
fi
else
fatal "Unknown build stage: '$TRAVIS_BUILD_STAGE_NAME'"
fi
+2 -2
View File
@@ -1,6 +1,6 @@
# DESCRIPTION: codecov.io config
#
# Copyright 2020-2020 by Wilson Snyder. This program is free software; you
# Copyright 2020-2021 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@@ -15,7 +15,7 @@ codecov:
coverage:
precision: 2
round: down
range: "70...100"
range: "50...100"
ignore:
- "ci"
- "docs"
+7 -2
View File
@@ -1,13 +1,13 @@
# DESCRIPTION: Process this file with autoconf to produce a configure script.
#
# Copyright 2003-2020 by Wilson Snyder. Verilator is free software; you
# Copyright 2003-2021 by Wilson Snyder. Verilator is free software; you
# can redistribute it and/or modify it under the terms of either the GNU Lesser
# General Public License Version 3 or the Perl Artistic License Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[4.106 2020-12-02],
AC_INIT([Verilator],[4.110 2021-02-25],
[https://verilator.org],
[verilator],[https://verilator.org])
# When releasing, also update header of Changes file
@@ -139,6 +139,11 @@ if test "x$PERL" = "x" ; then
AC_MSG_ERROR([Cannot find "perl" in your PATH, please install it])
fi
AC_PATH_PROG(PYTHON3,python3)
if test "x$PYTHON3" = "x" ; then
AC_MSG_ERROR([Cannot find "python3" in your PATH, please install it])
fi
AC_PATH_PROG(LEX,flex)
if test "x$LEX" = "x" ; then
AC_MSG_ERROR([Cannot find "flex" in your PATH, please install it])
+2 -2
View File
@@ -27,8 +27,8 @@ contributions flow more efficiently.
* You may attach a patch to the issue, or (preferred) may request a GitHub
pull request.
** Verilator uses Travis CI to provide continuous integration. You may
want to setup Travis CI on your GitHub branch to ensure your changes
** Verilator uses GitHub Actions to provide continuous integration. You may
want to enable Actions on your GitHub branch to ensure your changes
keep the tests passing. See link:internals.adoc[docs/internals].
* Your source-code contributions must be certified as open source, under
+9
View File
@@ -5,6 +5,8 @@ Please see the Verilator manual for 200+ additional contributors. Thanks to all.
Ahmed El-Mahmoudy
Alex Chadwick
Àlex Torregrosa
Andreas Kuster
Chris Randall
Conor McCullough
Dan Petrisko
@@ -49,18 +51,23 @@ Marshal Qiao
Matthew Ballance
Michael Killough
Mike Popoloski
Morten Borup Petersen
Nandu Raj
Nathan Kohagen
Nathan Myers
Patrick Stewart
Paul Wright
Peter Horvath
Peter Monsson
Philipp Wagner
Pierre-Henri Horrein
Pieter Kapsenberg
Piotr Binkowski
Qingyao Sun
Rafal Kapuscik
Richard Myers
Rupert Swarbrick
Samuel Riedel
Sean Cross
Sebastien Van Cauwenberghe
Sergi Granell
@@ -72,6 +79,7 @@ Tobias Wölfel
Todd Strader
Tomasz Gorochowik
Tymoteusz Blazejczyk
Unai Martinez-Corral
Victor Besyakov
Vassilis Papaefstathiou
Veripool API Bot
@@ -80,3 +88,4 @@ Yossi Nivin
Yuri Victorovich
Yutetsu TAKATSUKASA
Yves Mathieu
HyungKi Jeong
+1 -1
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you
# Copyright 2003-2021 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.
+2 -4
View File
@@ -1,6 +1,6 @@
// DESCRIPTION: Verilator: List of To Do issues.
//
// Copyright 2004-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2021 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.
@@ -84,7 +84,7 @@
"if (a) { ... b=2; } else { ... b=2;}" -> "b=2; if ..."
Careful though, as b could appear in the statement or multiple times in statement
(Could just require exatly two 'b's in statement)
** Simplify XOR/XNOR/AND/OR bit selection trees
** Simplify XOR/AND/OR bit selection trees
Foo = A[1] ^ A[2] ^ A[3] etc are better as ^ ( A & 32'b...1110 )
** Combine variables into wider elements
Parallel statements on different bits should become single signal
@@ -96,8 +96,6 @@
Don't merge if any combining would form circ logic (out goes back to in)
** Multiple assignments each bit can become single assign with concat
Make sure a SEL of a CONCAT can get the single bit back.
** Usually blocks/values
Enable only after certain time, so VL_TIME_I(32) > 0x1e gets eliminated out
** Better ordering of a<=b, b<=c, put all refs to 'b' next to each other to optimize caching
** I-cache packing improvements (what/how?)
** Data cache organization (order of vars in class)
+1 -2
View File
@@ -100,7 +100,6 @@ Those developing Verilator itself may also want these (see internals.adoc):
sudo apt-get install gdb asciidoctor graphviz cmake clang clang-format gprof lcov
cpan install Pod::Perldoc
cpan install Unix::Processors
cpan install Parallel::Forker
==== Install SystemC
@@ -298,7 +297,7 @@ or https://verilator.org/verilator_doc.pdf[Verilator manual (PDF)].
== License
Copyright 2008-2020 by Wilson Snyder. Verilator is free software; you can
Copyright 2008-2021 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
+14 -16
View File
@@ -409,8 +409,9 @@ style indentation; the `c-set-style` undoes that.)
* Comment every member variable.
Indentation is automatically maintained with "make clang-format" (using
clang-format version 10.0.0). For those manually formatting:
Indentation is automatically maintained with "make format" using
clang-format version 10.0.0, and yapf for python, and is automatically
corrected in the CI actions. For those manually formatting C++ code:
* Use 4 spaces per level, and no tabs.
@@ -696,7 +697,7 @@ Verilator problem.
When enabling the long tests, some additional PERL modules are needed,
which you can install using cpan.
cpan install Unix::Processors
cpan install Parallel::Forker
There are some traps to avoid when running regression tests
@@ -728,20 +729,17 @@ test, run the following command.
=== Continuous Integration
Verilator has a https://travis-ci.com/verilator/verilator[Travis CI environment]
which automatically tests the master branch for test failures on new commits. It
also runs a daily cron job to validate all of the tests against different OS and
compiler versions.
Verilator uses GitHub Actions which automatically tests the master branch
for test failures on new commits. It also runs a daily cron job to validate
all of the tests against different OS and compiler versions.
Developers can connect Travis CI to their GitHub account so that the CI
environment can check their branches too by doing the following:
Developers can enable Actions on their GitHub repository so that the CI
environment can check their branches too by enabling the build workflow:
* Go to https://github.com/marketplace/travis-ci and follow the prompts
* Only the Open Source (FREE) version of Travis CI is required
* Under a Travis CI project click More options > Settings in order to set up a
cron job on a particular branch
* On GitHub, navigate to the main page of the repository.
* Under your repository name, click Actions.
* In the left sidebar, click the workflow you want to enable ("build").
* Click Enable workflow.
=== Fuzzing
@@ -1026,7 +1024,7 @@ IEEE 1800-2017 33 Config:: Little/no tool support or industry use.
== Distribution
Copyright 2008-2020 by Wilson Snyder. Verilator is free software; you can
Copyright 2008-2021 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
+1 -1
View File
@@ -66,7 +66,7 @@ elements in the `<module>` elements using the `dtype_id` attribute.
== Distribution
Copyright 2020-2020 by Wilson Snyder. Verilator is free software; you can
Copyright 2020-2021 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
+1 -1
View File
@@ -54,7 +54,7 @@ run:
@echo
@echo "-- BUILD -------------------"
cmake --build build
cmake --build build -j
@echo
@echo "-- RUN ---------------------"
+1 -1
View File
@@ -90,7 +90,7 @@ run:
@echo
@echo "-- BUILD -------------------"
cmake --build build
cmake --build build -j
@echo
@echo "-- RUN ---------------------"
+1 -1
View File
@@ -54,7 +54,7 @@ run:
@echo
@echo "-- BUILD -------------------"
cmake --build build
cmake --build build -j
@echo
@echo "-- RUN ---------------------"
+1 -1
View File
@@ -54,7 +54,7 @@ run:
@echo
@echo "-- BUILD -------------------"
cmake --build build
cmake --build build -j
@echo
@echo "-- RUN ---------------------"
+1 -1
View File
@@ -90,7 +90,7 @@ run:
@echo
@echo "-- BUILD -------------------"
cmake --build build
cmake --build build -j
@echo
@echo "-- RUN ---------------------"
+2 -2
View File
@@ -37,6 +37,6 @@ int main(int argc, char** argv, char** env) {
// Destroy model
delete top;
// Fin
exit(0);
// Return good completion status
return 0;
}
+2 -1
View File
@@ -33,12 +33,13 @@ int sc_main(int argc, char* argv[]) {
// Simulate until $finish
while (!Verilated::gotFinish()) {
// Simulate 1ns
sc_start(1, SC_NS);
}
// Final model cleanup
top->final();
// Fin
// Return good completion status
return 0;
}
+4 -3
View File
@@ -13,7 +13,7 @@
#include "Vtop.h"
#if VM_TRACE
# include <verilated_vcd_c.h>
#include <verilated_vcd_c.h>
#endif
vluint64_t main_time = 0;
@@ -70,6 +70,7 @@ int main(int argc, char** argv, char** env) {
delete top;
top = nullptr;
// Fin
exit(0);
// Return good completion status
// Don't use exit() or destructor won't get called
return 0;
}
+8 -7
View File
@@ -5,6 +5,9 @@
// SPDX-License-Identifier: CC0-1.0
//======================================================================
// For std::unique_ptr
#include <memory>
// Include common routines
#include <verilated.h>
@@ -43,7 +46,8 @@ int main(int argc, char** argv, char** env) {
Verilated::mkdir("logs");
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
Vtop* top = new Vtop; // Or use a const unique_ptr, or the VL_UNIQUE_PTR wrapper
// Using unique_ptr is similar to "Vtop* top = new Vtop" then deleting at end
const std::unique_ptr<Vtop> top{new Vtop};
// Set some inputs
top->reset_l = !0;
@@ -97,10 +101,7 @@ int main(int argc, char** argv, char** env) {
VerilatedCov::write("logs/coverage.dat");
#endif
// Destroy model
delete top;
top = nullptr;
// Fin
exit(0);
// Return good completion status
// Don't use exit() or destructor won't get called
return 0;
}
+11 -10
View File
@@ -6,6 +6,9 @@
// SPDX-License-Identifier: CC0-1.0
//======================================================================
// For std::unique_ptr
#include <memory>
// SystemC global header
#include <systemc.h>
@@ -45,20 +48,22 @@ int sc_main(int argc, char* argv[]) {
ios::sync_with_stdio();
// Define clocks
sc_clock clk("clk", 10, SC_NS, 0.5, 3, SC_NS, true);
sc_clock fastclk("fastclk", 2, SC_NS, 0.5, 2, SC_NS, true);
sc_clock clk{"clk", 10, SC_NS, 0.5, 3, SC_NS, true};
sc_clock fastclk{"fastclk", 2, SC_NS, 0.5, 2, SC_NS, true};
// Define interconnect
sc_signal<bool> reset_l;
sc_signal<vluint32_t> in_small;
sc_signal<vluint64_t> in_quad;
sc_signal<sc_bv<70> > in_wide;
sc_signal<sc_bv<70>> in_wide;
sc_signal<vluint32_t> out_small;
sc_signal<vluint64_t> out_quad;
sc_signal<sc_bv<70> > out_wide;
sc_signal<sc_bv<70>> out_wide;
// Construct the Verilated model, from inside Vtop.h
Vtop* top = new Vtop("top");
// Using unique_ptr is similar to "Vtop* top = new Vtop" then deleting at end
const std::unique_ptr<Vtop> top{new Vtop{"top"}};
// Attach signals to the model
top->clk(clk);
top->fastclk(fastclk);
@@ -129,10 +134,6 @@ int sc_main(int argc, char* argv[]) {
VerilatedCov::write("logs/coverage.dat");
#endif
// Destroy model
delete top;
top = nullptr;
// Fin
// Return good completion status
return 0;
}
+4 -4
View File
@@ -22,9 +22,9 @@ VERILATOR = $(VERILATOR_ROOT)/bin/verilator
endif
DOT = dot
PYTHON = python3
PYTHON3 = python3
PYTHON_VERSION := $(shell ${PYTHON} --version 2>&1)
PYTHON_VERSION := $(shell ${PYTHON3} --version 2>&1)
PYTHON_VERSION_FULL := $(wordlist 2,4,$(subst ., ,${PYTHON_VERSION}))
PYTHON_VERSION_MAJOR := $(word 1,${PYTHON_VERSION_FULL})
PYTHON_VERSION_MINOR := $(word 2,${PYTHON_VERSION_FULL})
@@ -45,13 +45,13 @@ test: \
test-vl_file_copy:
@echo "-- vl_file_copy example"
$(PYTHON) vl_file_copy -odir copied top.v
$(PYTHON3) vl_file_copy -odir copied top.v
@cmp copied/top.v top.v
@cmp copied/sub.v sub.v
test-vl_hier_graph:
@echo "-- vl_hier_graph example"
$(PYTHON) vl_hier_graph -o graph.dot top.v
$(PYTHON3) vl_hier_graph -o graph.dot top.v
@echo "Manually run: " $(DOT) -Tpdf -o graph.pdf graph.dot
######################################################################
+35 -25
View File
@@ -10,24 +10,29 @@ import sys
import tempfile
import xml.etree.ElementTree as ET
from shutil import copy2
from pprint import pprint,pformat
from pprint import pprint, pformat
#######################################################################
class VlFileCopy:
def __init__(self,
verilator_args, # presently all verilator options are passed-thru
# ideally this script would check against options mentioned in help
debug=0,
output_dir='copied'): # directory name we output file uses
def __init__(
self,
verilator_args, # presently all verilator options are passed-thru
# ideally this script would check against options mentioned in help
debug=0,
output_dir='copied'): # directory name we output file uses
self.debug = debug
xml_temp = tempfile.NamedTemporaryFile()
args = ['--xml-output', xml_temp.name,
'--bbox-sys', # Parse some stuff can't translate
'--bbox-unsup',
'--prefix vlxml'] # So we know name of .xml output
args = [
'--xml-output',
xml_temp.name,
'--bbox-sys', # Parse some stuff can't translate
'--bbox-unsup',
'--prefix vlxml'
] # So we know name of .xml output
args += verilator_args
self.run_verilator(args)
self.tree = ET.parse(xml_temp.name)
@@ -55,16 +60,18 @@ class VlFileCopy:
print("\t%s " % command)
status = subprocess.call(command, shell=True)
if status != 0:
raise Exception("Command failed running Verilator with '"+command+"', stopped")
raise Exception("Command failed running Verilator with '" +
command + "', stopped")
#######################################################################
if __name__=='__main__':
if __name__ == '__main__':
parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawTextHelpFormatter,
description=
"""Example of using Verilator XML output to copy a list of files to an
"""Example of using Verilator XML 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.
@@ -72,8 +79,7 @@ Example usage:
vl_file_copy -f input.vc top.v -odir mycopy
# This will make at least mycopy/top.v
""",
epilog=
"""All other arguments are pass-thru to Verilator: e.g.:
epilog="""All other arguments are pass-thru to Verilator: e.g.:
+define+<var>=<value> Set preprocessor define
-F <file> Parse options from a file, relatively
@@ -87,26 +93,30 @@ Example usage:
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,
""")
parser.add_argument('-debug',
'--debug',
action='store_const',
const=9,
help='enable debug')
parser.add_argument('-odir', '--odir',
action='store', metavar='directory', required=True,
parser.add_argument('-odir',
'--odir',
action='store',
metavar='directory',
required=True,
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)
# 3. "make install" will not install this.
# 4. This has not had production-worthy validation.
fc = VlFileCopy(output_dir = args.odir,
debug = args.debug,
verilator_args = rem)
fc = VlFileCopy(output_dir=args.odir, debug=args.debug, verilator_args=rem)
######################################################################
### Local Variables:
+43 -30
View File
@@ -10,26 +10,31 @@ import sys
import tempfile
import xml.etree.ElementTree as ET
from shutil import copy2
from pprint import pprint,pformat
from pprint import pprint, pformat
#######################################################################
class VlHierGraph:
def __init__(self,
verilator_args, # presently all verilator options are passed-thru
# ideally this script would check against options mentioned in help
debug=0,
output_filename='graph.dot'): # output filename
def __init__(
self,
verilator_args, # presently all verilator options are passed-thru
# ideally this script would check against options mentioned in help
debug=0,
output_filename='graph.dot'): # output filename
self.debug = debug
self.next_vertex_number = 0
self.name_to_number = {}
xml_temp = tempfile.NamedTemporaryFile()
args = ['--xml-output', xml_temp.name,
'--bbox-sys', # Parse some stuff can't translate
'--bbox-unsup',
'--prefix vlxml'] # So we know name of .xml output
args = [
'--xml-output',
xml_temp.name,
'--bbox-sys', # Parse some stuff can't translate
'--bbox-unsup',
'--prefix vlxml'
] # So we know name of .xml output
args += verilator_args
self.run_verilator(args)
self.tree = ET.parse(xml_temp.name)
@@ -39,7 +44,9 @@ 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
root = self.tree.getroot()
@@ -48,8 +55,7 @@ class VlHierGraph:
# origNames are before parameterization, name if after
mod_name = module.get('name')
mod_number = self.name_to_vertex_number(mod_name)
fh.write(" n%d [label=\"%s\""
% (mod_number, mod_name))
fh.write(" n%d [label=\"%s\"" % (mod_number, mod_name))
if module.get('topModule'):
fh.write(" color=\"red\" rank=1")
fh.write("];\n")
@@ -58,8 +64,8 @@ class VlHierGraph:
inst_name = instance.get('name')
def_name = instance.get('defName')
def_number = self.name_to_vertex_number(def_name)
fh.write(" n%d->n%d [label=\"%s\"];\n"
% (mod_number, def_number, inst_name));
fh.write(" n%d->n%d [label=\"%s\"];\n" %
(mod_number, def_number, inst_name))
fh.write("}\n")
@@ -80,24 +86,25 @@ class VlHierGraph:
print("\t%s " % command)
status = subprocess.call(command, shell=True)
if status != 0:
raise Exception("Command failed running Verilator with '"+command+"', stopped")
raise Exception("Command failed running Verilator with '" +
command + "', stopped")
#######################################################################
if __name__=='__main__':
if __name__ == '__main__':
parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawTextHelpFormatter,
description=
"""Example of using Verilator XML output to create a .dot file showing the
"""Example of using Verilator XML output to create a .dot file showing the
design module hierarchy.
Example usage:
vl_hier_graph -f input.vc top.v -o graph.dot
dot -Tpdf -o graph.pdf graph.dot
""",
epilog=
"""All other arguments are pass-thru to Verilator: e.g.:
epilog="""All other arguments are pass-thru to Verilator: e.g.:
+define+<var>=<value> Set preprocessor define
-F <file> Parse options from a file, relatively
@@ -111,26 +118,32 @@ Example usage:
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,
""")
parser.add_argument('-debug',
'--debug',
action='store_const',
const=9,
help='enable debug')
parser.add_argument('-o', '--o',
action='store', metavar='filename', required=True,
parser.add_argument('-o',
'--o',
action='store',
metavar='filename',
required=True,
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 -2
View File
@@ -1806,6 +1806,7 @@ xc->already_in_flush = 0;
static void *fstWriterFlushContextPrivate1(void *ctx)
{
struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
struct fstWriterContext *xc_parent;
pthread_mutex_lock(&(xc->xc_parent->mutex));
fstWriterFlushContextPrivate2(xc);
@@ -1816,10 +1817,11 @@ free(xc->curval_mem);
free(xc->valpos_mem);
free(xc->vchg_mem);
tmpfile_close(&xc->tchn_handle, &xc->tchn_handle_nam);
xc_parent = xc->xc_parent;
free(xc);
xc->xc_parent->in_pthread = 0;
pthread_mutex_unlock(&(xc->xc_parent->mutex));
xc_parent->in_pthread = 0;
pthread_mutex_unlock(&(xc_parent->mutex));
return(NULL);
}
+66 -71
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2021 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.
@@ -32,6 +32,7 @@
#include <sstream>
#include <sys/stat.h> // mkdir
#include <list>
#include <limits>
#include <utility>
// clang-format off
@@ -44,18 +45,12 @@
constexpr unsigned VL_VALUE_STRING_MAX_WIDTH = 8192;
//===========================================================================
// Static sanity checks (when get C++11 can use static_assert)
// Static sanity checks
typedef union {
// cppcheck-suppress unusedStructMember // Unused as is assertion
char vluint8_incorrect[(sizeof(vluint8_t) == 1) ? 1 : -1];
// cppcheck-suppress unusedStructMember // Unused as is assertion
char vluint16_incorrect[(sizeof(vluint16_t) == 2) ? 1 : -1];
// cppcheck-suppress unusedStructMember // Unused as is assertion
char vluint32_incorrect[(sizeof(vluint32_t) == 4) ? 1 : -1];
// cppcheck-suppress unusedStructMember // Unused as is assertion
char vluint64_incorrect[(sizeof(vluint64_t) == 8) ? 1 : -1];
} vl_static_checks_t;
static_assert(sizeof(vluint8_t) == 1, "vluint8_t is missized");
static_assert(sizeof(vluint16_t) == 2, "vluint8_t is missized");
static_assert(sizeof(vluint32_t) == 4, "vluint8_t is missized");
static_assert(sizeof(vluint64_t) == 8, "vluint8_t is missized");
//===========================================================================
// Global variables
@@ -72,10 +67,27 @@ Verilated::CommandArgValues Verilated::s_args;
VerilatedImp::VerilatedImpU VerilatedImp::s_s;
struct VerilatedImpInitializer {
VerilatedImpInitializer() { VerilatedImp::setup(); }
~VerilatedImpInitializer() { VerilatedImp::teardown(); }
} s_VerilatedImpInitializer;
// Guarantees to call setup() and teardown() just once.
struct VerilatedInitializer {
VerilatedInitializer() { setup(); }
~VerilatedInitializer() { teardown(); }
void setup() {
static bool done = false;
if (!done) {
VerilatedImp::setup();
Verilated::s_ns.setup();
done = true;
}
}
void teardown() {
static bool done = false;
if (!done) {
VerilatedImp::teardown();
Verilated::s_ns.teardown();
done = true;
}
}
} s_VerilatedInitializer;
//===========================================================================
// User definable functions
@@ -247,7 +259,6 @@ void VL_PRINTF_MT(const char* formatp, ...) VL_MT_SAFE {
// Overall class init
Verilated::Serialized::Serialized() {
s_debug = 0;
s_calcUnusedSigs = false;
s_gotFinish = false;
s_assertOn = true;
@@ -261,10 +272,8 @@ Verilated::Serialized::Serialized() {
s_timeprecision = VL_TIME_PRECISION; // Initial value until overriden by _Vconfigure
}
Verilated::NonSerialized::NonSerialized() {
s_profThreadsFilenamep = strdup("profile_threads.dat");
}
Verilated::NonSerialized::~NonSerialized() {
void Verilated::NonSerialized::setup() { s_profThreadsFilenamep = strdup("profile_threads.dat"); }
void Verilated::NonSerialized::teardown() {
if (s_profThreadsFilenamep) {
VL_DO_CLEAR(free(const_cast<char*>(s_profThreadsFilenamep)),
s_profThreadsFilenamep = nullptr);
@@ -312,19 +321,16 @@ vluint64_t vl_rand64() VL_MT_SAFE {
return result;
}
#ifndef VL_NO_LEGACY
// VL_RANDOM_W currently unused as $random always 32 bits, left for backwards compatibility
// LCOV_EXCL_START
WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) VL_MT_SAFE {
for (int i = 0; i < VL_WORDS_I(obits); ++i) {
if (i < (VL_WORDS_I(obits) - 1)) {
outwp[i] = vl_rand64();
} else {
outwp[i] = vl_rand64() & VL_MASK_E(obits);
}
}
for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = vl_rand64();
outwp[VL_WORDS_I(obits) - 1] = vl_rand64() & VL_MASK_E(obits);
return outwp;
}
// LCOV_EXCL_STOP
#endif
IData VL_RANDOM_SEEDED_II(int obits, IData seed) VL_MT_SAFE {
Verilated::randSeed(static_cast<int>(seed));
@@ -350,13 +356,8 @@ QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE {
return data;
}
WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE {
for (int i = 0; i < VL_WORDS_I(obits); ++i) {
if (i < (VL_WORDS_I(obits) - 1)) {
outwp[i] = VL_RAND_RESET_I(32);
} else {
outwp[i] = VL_RAND_RESET_I(32) & VL_MASK_E(obits);
}
}
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;
}
@@ -1327,8 +1328,6 @@ void VL_FCLOSE_I(IData fdi) VL_MT_SAFE {
VerilatedImp::fdClose(fdi);
}
void VL_FFLUSH_ALL() VL_MT_SAFE { fflush(stdout); }
void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) VL_MT_SAFE {
static VL_THREAD_LOCAL std::string t_output; // static only for speed
t_output = "";
@@ -1496,19 +1495,19 @@ IData VL_FREAD_I(int width, int array_lsb, int array_size, void* memp, IData fpi
IData entry = read_elements + start - array_lsb;
if (width <= 8) {
CData* datap = &(reinterpret_cast<CData*>(memp))[entry];
if (shift == start_shift) { *datap = 0; }
if (shift == start_shift) *datap = 0;
*datap |= (c << shift) & VL_MASK_I(width);
} else if (width <= 16) {
SData* datap = &(reinterpret_cast<SData*>(memp))[entry];
if (shift == start_shift) { *datap = 0; }
if (shift == start_shift) *datap = 0;
*datap |= (c << shift) & VL_MASK_I(width);
} else if (width <= VL_IDATASIZE) {
IData* datap = &(reinterpret_cast<IData*>(memp))[entry];
if (shift == start_shift) { *datap = 0; }
if (shift == start_shift) *datap = 0;
*datap |= (c << shift) & VL_MASK_I(width);
} else if (width <= VL_QUADSIZE) {
QData* datap = &(reinterpret_cast<QData*>(memp))[entry];
if (shift == start_shift) { *datap = 0; }
if (shift == start_shift) *datap = 0;
*datap |= ((static_cast<QData>(c) << static_cast<QData>(shift)) & VL_MASK_Q(width));
} else {
WDataOutP datap = &(reinterpret_cast<WDataOutP>(memp))[entry * VL_WORDS_I(width)];
@@ -1895,19 +1894,19 @@ void VlReadMem::setData(void* valuep, const std::string& rhs) {
int value = (c >= 'a' ? (c == 'x' ? VL_RAND_RESET_I(4) : (c - 'a' + 10)) : (c - '0'));
if (m_bits <= 8) {
CData* datap = reinterpret_cast<CData*>(valuep);
if (!innum) { *datap = 0; }
if (!innum) *datap = 0;
*datap = ((*datap << shift) + value) & VL_MASK_I(m_bits);
} else if (m_bits <= 16) {
SData* datap = reinterpret_cast<SData*>(valuep);
if (!innum) { *datap = 0; }
if (!innum) *datap = 0;
*datap = ((*datap << shift) + value) & VL_MASK_I(m_bits);
} else if (m_bits <= VL_IDATASIZE) {
IData* datap = reinterpret_cast<IData*>(valuep);
if (!innum) { *datap = 0; }
if (!innum) *datap = 0;
*datap = ((*datap << shift) + value) & VL_MASK_I(m_bits);
} else if (m_bits <= VL_QUADSIZE) {
QData* datap = reinterpret_cast<QData*>(valuep);
if (!innum) { *datap = 0; }
if (!innum) *datap = 0;
*datap = ((*datap << static_cast<QData>(shift)) + static_cast<QData>(value))
& VL_MASK_Q(m_bits);
} else {
@@ -2107,7 +2106,7 @@ void VL_WRITEMEM_N(bool hex, // Hex format, else binary
// Helper function for conversion of timescale strings
// Converts (1|10|100)(s|ms|us|ns|ps|fs) to power of then
int VL_TIME_STR_CONVERT(const char* strp) {
int VL_TIME_STR_CONVERT(const char* strp) VL_PURE {
int scale = 0;
if (!strp) return 0;
if (*strp++ != '1') return 0;
@@ -2128,14 +2127,14 @@ int VL_TIME_STR_CONVERT(const char* strp) {
if (*strp) return 0;
return scale;
}
static const char* vl_time_str(int scale) {
static const char* vl_time_str(int scale) VL_PURE {
static const char* const names[]
= {"100s", "10s", "1s", "100ms", "10ms", "1ms", "100us", "10us", "1us",
"100ns", "10ns", "1ns", "100ps", "10ps", "1ps", "100fs", "10fs", "1fs"};
if (VL_UNLIKELY(scale > 2 || scale < -15)) scale = 0;
return names[2 - scale];
}
double vl_time_multiplier(int scale) {
double vl_time_multiplier(int scale) VL_PURE {
// Return timescale multipler -18 to +18
// For speed, this does not check for illegal values
if (scale < 0) {
@@ -2202,7 +2201,7 @@ void VL_TIMEFORMAT_IINI(int units, int precision, const std::string& suffix,
void Verilated::debug(int level) VL_MT_SAFE {
const VerilatedLockGuard lock(s_mutex);
s_s.s_debug = level;
s_ns.s_debug = level;
if (level) {
#ifdef VL_DEBUG
VL_DEBUG_IF(VL_DBG_MSGF("- Verilated::debug is on."
@@ -2352,7 +2351,7 @@ static void removeCb(Verilated::VoidPCb cb, void* datap, VoidPCbList& cbs) {
std::pair<Verilated::VoidPCb, void*> pair(cb, datap);
cbs.remove(pair);
}
static void runCallbacks(VoidPCbList& cbs) VL_MT_SAFE {
static void runCallbacks(const VoidPCbList& cbs) VL_MT_SAFE {
for (const auto& i : cbs) i.first(i.second);
}
@@ -2458,7 +2457,11 @@ void Verilated::endOfThreadMTaskGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAF
VerilatedThreadMsgQueue::flush(evalMsgQp);
}
void Verilated::endOfEvalGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
void Verilated::endOfEval(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
// It doesn't work to set endOfEvalReqd on the threadpool thread
// and then check it on the eval thread since it's thread local.
// It should be ok to call into endOfEvalGuts, it returns immediately
// if there are no transactions.
VL_DEBUG_IF(VL_DBG_MSGF("End-of-eval cleanup\n"););
evalMsgQp->process();
}
@@ -2468,32 +2471,20 @@ void Verilated::endOfEvalGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
// VerilatedImp:: Constructors
// verilated.o may exist both in protect-lib and main module.
// Both the main module and the protec-lib refer the same instance of
// Both the main module and the protect-lib refer the same instance of
// static variables such as Verilated or VerilatedImplData.
// This is important to share the state such as Verilated::gotFinish.
// But the sharing may cause double-free error when shutting down because destructors
// are called twice.
// 1st time:From protec-lib shared object on the way of unloading after exitting main()
// 1st time:From protect-lib shared object on the way of unloading after exiting main()
// 2nd time:From main executable.
//
// To avoid the trouble, all member variables are enclosed in VerilatedImpU union.
// ctor nor dtor of members are not called automatically.
// VerilatedImp::setup() and teardown() guarantees to initialize/destruct just once.
// VerilatedInitializer::setup() and teardown() guarantees to initialize/destruct just once.
void VerilatedImp::setup() {
static bool done = false;
if (!done) {
new (&VerilatedImp::s_s) VerilatedImpData();
done = true;
}
}
void VerilatedImp::teardown() {
static bool done = false;
if (!done) {
VerilatedImp::s_s.~VerilatedImpU();
done = true;
}
}
void VerilatedImp::setup() { new (&VerilatedImp::s_s) VerilatedImpData(); }
void VerilatedImp::teardown() { VerilatedImp::s_s.~VerilatedImpU(); }
//===========================================================================
// VerilatedImp:: Methods
@@ -2640,7 +2631,7 @@ vluint32_t VerilatedVarProps::entSize() const {
size_t VerilatedVarProps::totalSize() const {
size_t size = entSize();
for (int udim = 0; udim <= udims(); ++udim) size *= m_unpacked[udim].elements();
for (int udim = 0; udim < udims(); ++udim) size *= m_unpacked[udim].elements();
return size;
}
@@ -2692,7 +2683,7 @@ void VerilatedScope::exportInsert(int finalize, const char* namep, void* cb) VL_
if (!finalize) {
// Need two passes so we know array size to create
// Alternative is to dynamically stretch the array, which is more code, and slower.
if (funcnum >= m_funcnumMax) { m_funcnumMax = funcnum + 1; }
if (funcnum >= m_funcnumMax) m_funcnumMax = funcnum + 1;
} else {
if (VL_UNCOVERABLE(funcnum >= m_funcnumMax)) {
VL_FATAL_MT(__FILE__, __LINE__, "", // LCOV_EXCL_LINE
@@ -2737,7 +2728,7 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap, boo
}
va_end(ap);
m_varsp->insert(std::make_pair(namep, var));
m_varsp->emplace(namep, var);
}
// cppcheck-suppress unusedFunction // Used by applications
@@ -2784,6 +2775,10 @@ void VerilatedHierarchy::add(VerilatedScope* fromp, VerilatedScope* top) {
VerilatedImp::hierarchyAdd(fromp, top);
}
void VerilatedHierarchy::remove(VerilatedScope* fromp, VerilatedScope* top) {
VerilatedImp::hierarchyRemove(fromp, top);
}
//===========================================================================
// VerilatedOneThreaded:: Methods
+69 -64
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2021 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.
@@ -265,24 +265,12 @@ public:
#define VL_OUT(name, msb, lsb) IData name ///< Declare output signal, 17-32 bits
#define VL_OUTW(name, msb, lsb, words) WData name[words] ///< Declare output signal, 65+ bits
#define VL_PIN_NOP(instname, pin, port) ///< Connect a pin, ala SP_PIN
#define VL_CELL(instname, type) ///< Declare a cell, ala SP_CELL
/// Declare a module, ala SC_MODULE
#define VL_MODULE(modname) class modname VL_NOT_FINAL : public VerilatedModule
// Not class final in VL_MODULE, as users might be abstracting our models (--hierarchical)
/// Constructor, ala SC_CTOR
#define VL_CTOR(modname) modname(const char* __VCname = "")
/// Constructor declaration for C++, ala SP_CTOR_IMPL
#define VL_CTOR_IMP(modname) \
modname::modname(const char* __VCname) \
: VerilatedModule(__VCname)
/// Constructor declaration for SystemC, ala SP_CTOR_IMPL
#define VL_SC_CTOR_IMP(modname) modname::modname(sc_module_name)
//=========================================================================
// Functions overridable by user defines
// (Internals however must use VL_PRINTF_MT, which calls these.)
@@ -363,6 +351,7 @@ public: // But internals only - called from VerilatedModule's
class VerilatedHierarchy final {
public:
static void add(VerilatedScope* fromp, VerilatedScope* top);
static void remove(VerilatedScope* fromp, VerilatedScope* top);
};
//===========================================================================
@@ -375,7 +364,6 @@ class Verilated final {
static struct Serialized { // All these members serialized/deserialized
// Fast path
int s_debug; ///< See accessors... only when VL_DEBUG set
bool s_calcUnusedSigs; ///< Waves file on, need all signals calculated
bool s_gotFinish; ///< A $finish statement executed
bool s_assertOn; ///< Assertions are enabled
@@ -395,12 +383,13 @@ class Verilated final {
static struct NonSerialized { // Non-serialized information
// These are reloaded from on command-line settings, so do not need to persist
// Fast path
int s_debug = 0; ///< See accessors... only when VL_DEBUG set
vluint64_t s_profThreadsStart = 1; ///< +prof+threads starting time
vluint32_t s_profThreadsWindow = 2; ///< +prof+threads window size
// Slow path
const char* s_profThreadsFilenamep; ///< +prof+threads filename
NonSerialized();
~NonSerialized();
void setup();
void teardown();
} s_ns;
// no need to be save-restored (serialized) the
@@ -429,12 +418,26 @@ class Verilated final {
} t_s;
private:
friend struct VerilatedInitializer;
// CONSTRUCTORS
VL_UNCOPYABLE(Verilated);
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
/// changing the level (no mutex)
static inline int debug() VL_MT_SAFE { return s_ns.s_debug; }
#else
/// Return constant 0 debug level, so C++'s optimizer rips up
static constexpr int debug() VL_PURE { return 0; }
#endif
/// Select initial value of otherwise uninitialized signals.
////
/// 0 = Set to zeros
@@ -448,17 +451,6 @@ public:
/// Random seed extended to 64 bits, and defaulted if user seed==0
static vluint64_t randSeedDefault64() VL_MT_SAFE;
/// 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
/// changing the level (no mutex)
static inline int debug() VL_MT_SAFE { return s_s.s_debug; }
#else
/// Return constant 0 debug level, so C++'s optimizer rips up
static constexpr int debug() VL_PURE { return 0; }
#endif
/// Enable calculation of unused signals
static void calcUnusedSigs(bool flag) VL_MT_SAFE;
static bool calcUnusedSigs() VL_MT_SAFE { ///< Return calcUnusedSigs value
@@ -476,7 +468,7 @@ public:
static bool gotFinish() VL_MT_SAFE { return s_s.s_gotFinish; } ///< Return if got a $finish
/// Allow traces to at some point be enabled (disables some optimizations)
static void traceEverOn(bool flag) VL_MT_SAFE {
if (flag) { calcUnusedSigs(flag); }
if (flag) calcUnusedSigs(flag);
}
/// Enable/disable assertions
static void assertOn(bool flag) VL_MT_SAFE;
@@ -504,7 +496,9 @@ public:
static void addFlushCb(VoidPCb cb, void* datap) VL_MT_SAFE;
static void removeFlushCb(VoidPCb cb, void* datap) VL_MT_SAFE;
static void runFlushCallbacks() VL_MT_SAFE;
#ifndef VL_NO_LEGACY
static void flushCall() VL_MT_SAFE { runFlushCallbacks(); } // Deprecated
#endif
/// Callbacks to run prior to termination
static void addExitCb(VoidPCb cb, void* datap) VL_MT_SAFE;
static void removeExitCb(VoidPCb cb, void* datap) VL_MT_SAFE;
@@ -572,35 +566,29 @@ public:
static int dpiLineno() VL_MT_SAFE { return t_s.t_dpiLineno; }
static int exportFuncNum(const char* namep) VL_MT_SAFE;
// Internal: Serialization setup
static constexpr size_t serialized1Size() VL_PURE { return sizeof(s_s); }
static constexpr void* serialized1Ptr() VL_MT_UNSAFE { return &s_s; } // For Serialize only
static size_t serialized2Size() VL_PURE;
static void* serialized2Ptr() VL_MT_UNSAFE;
#ifdef VL_THREADED
/// Set the mtaskId, called when an mtask starts
/// Internal: Set the mtaskId, called when an mtask starts
static void mtaskId(vluint32_t id) VL_MT_SAFE { t_s.t_mtaskId = id; }
static vluint32_t mtaskId() VL_MT_SAFE { return t_s.t_mtaskId; }
static void endOfEvalReqdInc() VL_MT_SAFE { ++t_s.t_endOfEvalReqd; }
static void endOfEvalReqdDec() VL_MT_SAFE { --t_s.t_endOfEvalReqd; }
/// Called at end of each thread mtask, before finishing eval
/// Internal: Called at end of each thread mtask, before finishing eval
static void endOfThreadMTask(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
if (VL_UNLIKELY(t_s.t_endOfEvalReqd)) { endOfThreadMTaskGuts(evalMsgQp); }
}
/// Called at end of eval loop
static void endOfEval(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
// It doesn't work to set endOfEvalReqd on the threadpool thread
// and then check it on the eval thread since it's thread local.
// It should be ok to call into endOfEvalGuts, it returns immediately
// if there are no transactions.
endOfEvalGuts(evalMsgQp);
if (VL_UNLIKELY(t_s.t_endOfEvalReqd)) endOfThreadMTaskGuts(evalMsgQp);
}
/// Internal: Called at end of eval loop
static void endOfEval(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE;
#endif
private:
#ifdef VL_THREADED
static void endOfThreadMTaskGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE;
static void endOfEvalGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE;
#endif
};
@@ -652,15 +640,17 @@ extern void VL_DBG_MSGF(const char* formatp, ...) VL_ATTR_PRINTF(1) VL_MT_SAFE;
extern vluint64_t vl_rand64() VL_MT_SAFE;
inline IData VL_RANDOM_I(int obits) VL_MT_SAFE { return vl_rand64() & VL_MASK_I(obits); }
inline QData VL_RANDOM_Q(int obits) VL_MT_SAFE { return vl_rand64() & VL_MASK_Q(obits); }
#ifndef VL_NO_LEGACY
extern WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp); ///< Randomize a signal
#endif
extern IData VL_RANDOM_SEEDED_II(int obits, IData seed) VL_MT_SAFE;
inline IData VL_URANDOM_RANGE_I(IData hi, IData lo) {
vluint64_t rnd = vl_rand64();
if (VL_LIKELY(hi > lo)) {
// Modulus isn't very fast but it's common that hi-low is power-of-two
return (rnd % (hi - lo)) + lo;
return (rnd % (hi - lo + 1)) + lo;
} else {
return (rnd % (lo - hi)) + hi;
return (rnd % (lo - hi + 1)) + hi;
}
}
@@ -864,7 +854,6 @@ inline vluint64_t vl_time_stamp64() { return static_cast<vluint64_t>(sc_time_sta
# endif
#endif
#define VL_TIME_I() (static_cast<IData>(vl_time_stamp64()))
#define VL_TIME_Q() (static_cast<QData>(vl_time_stamp64()))
#define VL_TIME_D() (static_cast<double>(vl_time_stamp64()))
@@ -873,8 +862,9 @@ inline vluint64_t vl_time_stamp64() { return static_cast<vluint64_t>(sc_time_sta
// Can't use multiply in Q flavor, as might lose precision
#define VL_TIME_UNITED_Q(scale) (VL_TIME_Q() / static_cast<QData>(scale))
#define VL_TIME_UNITED_D(scale) (VL_TIME_D() / static_cast<double>(scale))
/// Time imported from units to time precision
double vl_time_multiplier(int scale);
double vl_time_multiplier(int scale) VL_PURE;
/// Evaluate expression if debug enabled
#ifdef VL_DEBUG
@@ -887,10 +877,6 @@ double vl_time_multiplier(int scale);
# define VL_DEBUG_IF(text) do {} while (false)
#endif
/// Collect coverage analysis for this line
#ifndef SP_AUTO_COVER3
# define SP_AUTO_COVER3(what,file,line)
#endif
// clang-format on
//=========================================================================
@@ -1265,7 +1251,7 @@ static inline IData VL_COUNTBITS_W(int lbits, int words, WDataInP lwp, IData ctr
EData r = 0;
IData wordLbits = 32;
for (int i = 0; i < words; ++i) {
if (i == words - 1) { wordLbits = lbits % 32; }
if (i == words - 1) wordLbits = lbits % 32;
r += VL_COUNTBITS_E(wordLbits, lwp[i], ctrl0, ctrl1, ctrl2);
}
return r;
@@ -1338,7 +1324,7 @@ static inline IData VL_MOSTSETBITP1_W(int words, WDataInP lwp) VL_MT_SAFE {
for (int i = words - 1; i >= 0; --i) {
if (VL_UNLIKELY(lwp[i])) { // Shorter worst case if predict not taken
for (int bit = VL_EDATASIZE - 1; bit >= 0; --bit) {
if (VL_UNLIKELY(VL_BITISSET_E(lwp[i], bit))) { return i * VL_EDATASIZE + bit + 1; }
if (VL_UNLIKELY(VL_BITISSET_E(lwp[i], bit))) return i * VL_EDATASIZE + bit + 1;
}
// Can't get here - one bit must be set
}
@@ -1370,12 +1356,6 @@ static inline WDataOutP VL_XOR_W(int words, WDataOutP owp, WDataInP lwp, WDataIn
for (int i = 0; (i < words); ++i) owp[i] = (lwp[i] ^ rwp[i]);
return owp;
}
// EMIT_RULE: VL_XNOR: oclean=dirty; obits=lbits; lbits==rbits;
static inline WDataOutP VL_XNOR_W(int words, WDataOutP owp, WDataInP lwp,
WDataInP rwp) VL_MT_SAFE {
for (int i = 0; (i < words); ++i) owp[i] = (lwp[i] ^ ~rwp[i]);
return owp;
}
// EMIT_RULE: VL_NOT: oclean=dirty; obits=lbits;
static inline WDataOutP VL_NOT_W(int words, WDataOutP owp, WDataInP lwp) VL_MT_SAFE {
for (int i = 0; i < words; ++i) owp[i] = ~(lwp[i]);
@@ -1641,8 +1621,8 @@ static inline WDataOutP VL_DIVS_WWW(int lbits, WDataOutP owp, WDataInP lwp,
WData rwstore[VL_MULS_MAX_WORDS];
WDataInP ltup = lwp;
WDataInP rtup = rwp;
if (lsign) { ltup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), lwstore, lwp)); }
if (rsign) { rtup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), rwstore, rwp)); }
if (lsign) ltup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), lwstore, lwp));
if (rsign) rtup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), rwstore, rwp));
if ((lsign && !rsign) || (!lsign && rsign)) {
WData qNoSign[VL_MULS_MAX_WORDS];
VL_DIV_WWW(lbits, qNoSign, ltup, rtup);
@@ -1663,8 +1643,8 @@ static inline WDataOutP VL_MODDIVS_WWW(int lbits, WDataOutP owp, WDataInP lwp,
WData rwstore[VL_MULS_MAX_WORDS];
WDataInP ltup = lwp;
WDataInP rtup = rwp;
if (lsign) { ltup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), lwstore, lwp)); }
if (rsign) { rtup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), rwstore, rwp)); }
if (lsign) ltup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), lwstore, lwp));
if (rsign) rtup = _VL_CLEAN_INPLACE_W(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), rwstore, rwp));
if (lsign) { // Only dividend sign matters for modulus
WData qNoSign[VL_MULS_MAX_WORDS];
VL_MODDIV_WWW(lbits, qNoSign, ltup, rtup);
@@ -2148,6 +2128,12 @@ static inline WDataOutP VL_SHIFTL_WWW(int obits, int lbits, int rbits, WDataOutP
}
return VL_SHIFTL_WWI(obits, lbits, 32, owp, lwp, rwp[0]);
}
static inline WDataOutP VL_SHIFTL_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp,
QData rd) VL_MT_SAFE {
WData rwp[VL_WQ_WORDS_E];
VL_SET_WQ(rwp, rd);
return VL_SHIFTL_WWW(obits, lbits, rbits, owp, lwp, rwp);
}
static inline IData VL_SHIFTL_IIW(int obits, int, int rbits, IData lhs, WDataInP rwp) VL_MT_SAFE {
for (int i = 1; i < VL_WORDS_I(rbits); ++i) {
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
@@ -2156,6 +2142,11 @@ static inline IData VL_SHIFTL_IIW(int obits, int, int rbits, IData lhs, WDataInP
}
return VL_CLEAN_II(obits, obits, lhs << rwp[0]);
}
static inline IData VL_SHIFTL_IIQ(int obits, int lbits, int rbits, IData lhs,
QData rhs) VL_MT_SAFE {
if (VL_UNLIKELY(rhs >= VL_IDATASIZE)) return 0;
return VL_CLEAN_II(obits, obits, lhs << rhs);
}
static inline QData VL_SHIFTL_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp) VL_MT_SAFE {
for (int i = 1; i < VL_WORDS_I(rbits); ++i) {
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
@@ -2165,6 +2156,11 @@ static inline QData VL_SHIFTL_QQW(int obits, int, int rbits, QData lhs, WDataInP
// Above checks rwp[1]==0 so not needed in below shift
return VL_CLEAN_QQ(obits, obits, lhs << (static_cast<QData>(rwp[0])));
}
static inline QData VL_SHIFTL_QQQ(int obits, int lbits, int rbits, QData lhs,
QData rhs) VL_MT_SAFE {
if (VL_UNLIKELY(rhs >= VL_QUADSIZE)) return 0;
return VL_CLEAN_QQ(obits, obits, lhs << rhs);
}
// EMIT_RULE: VL_SHIFTR: oclean=lclean; rclean==clean;
// Important: Unlike most other funcs, the shift might well be a computed
@@ -2226,6 +2222,14 @@ static inline QData VL_SHIFTR_QQW(int obits, int, int rbits, QData lhs, WDataInP
// Above checks rwp[1]==0 so not needed in below shift
return VL_CLEAN_QQ(obits, obits, lhs >> (static_cast<QData>(rwp[0])));
}
static inline IData VL_SHIFTR_IIQ(int obits, int, int rbits, IData lhs, QData rhs) VL_MT_SAFE {
if (VL_UNLIKELY(rhs >= VL_IDATASIZE)) return 0;
return VL_CLEAN_QQ(obits, obits, lhs >> rhs);
}
static inline QData VL_SHIFTR_QQQ(int obits, int, int rbits, QData lhs, QData rhs) VL_MT_SAFE {
if (VL_UNLIKELY(rhs >= VL_QUADSIZE)) return 0;
return VL_CLEAN_QQ(obits, obits, lhs >> rhs);
}
// EMIT_RULE: VL_SHIFTRS: oclean=false; lclean=clean, rclean==clean;
static inline IData VL_SHIFTRS_III(int obits, int lbits, int, IData lhs, IData rhs) VL_PURE {
@@ -2280,7 +2284,7 @@ static inline WDataOutP VL_SHIFTRS_WWW(int obits, int lbits, int rbits, WDataOut
WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
EData overshift = 0; // Huge shift 1>>32 or more
for (int i = 1; i < VL_WORDS_I(rbits); ++i) overshift |= rwp[i];
if (VL_UNLIKELY(overshift)) {
if (VL_UNLIKELY(overshift || rwp[0] >= obits)) {
int lmsw = VL_WORDS_I(obits) - 1;
EData sign = VL_SIGNONES_E(lbits, lwp[lmsw]);
for (int j = 0; j <= lmsw; ++j) owp[j] = sign;
@@ -2299,7 +2303,7 @@ static inline IData VL_SHIFTRS_IIW(int obits, int lbits, int rbits, IData lhs,
WDataInP rwp) VL_MT_SAFE {
EData overshift = 0; // Huge shift 1>>32 or more
for (int i = 1; i < VL_WORDS_I(rbits); ++i) overshift |= rwp[i];
if (VL_UNLIKELY(overshift)) {
if (VL_UNLIKELY(overshift || rwp[0] >= obits)) {
IData sign = -(lhs >> (lbits - 1)); // ffff_ffff if negative
return VL_CLEAN_II(obits, obits, sign);
}
@@ -2309,13 +2313,14 @@ static inline QData VL_SHIFTRS_QQW(int obits, int lbits, int rbits, QData lhs,
WDataInP rwp) VL_MT_SAFE {
EData overshift = 0; // Huge shift 1>>32 or more
for (int i = 1; i < VL_WORDS_I(rbits); ++i) overshift |= rwp[i];
if (VL_UNLIKELY(overshift)) {
if (VL_UNLIKELY(overshift || rwp[0] >= obits)) {
QData sign = -(lhs >> (lbits - 1)); // ffff_ffff if negative
return VL_CLEAN_QQ(obits, obits, sign);
}
return VL_SHIFTRS_QQI(obits, lbits, 32, lhs, rwp[0]);
}
static inline IData VL_SHIFTRS_IIQ(int obits, int lbits, int rbits, IData lhs, QData rhs) VL_PURE {
static inline IData VL_SHIFTRS_IIQ(int obits, int lbits, int rbits, IData lhs,
QData rhs) VL_MT_SAFE {
WData rwp[VL_WQ_WORDS_E];
VL_SET_WQ(rwp, rhs);
return VL_SHIFTRS_IIW(obits, lbits, rbits, lhs, rwp);
+1 -1
View File
@@ -2,7 +2,7 @@
######################################################################
# DESCRIPTION: Makefile commands for all verilated target files
#
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
+1 -1
View File
@@ -4,7 +4,7 @@
//
//*************************************************************************
//
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2021 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.
+5 -5
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2020 by Wilson Snyder. This program is free software; you
// Copyright 2001-2021 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.
@@ -123,8 +123,8 @@ private:
if (iter != m_valueIndexes.end()) return iter->second;
m_nextIndex++;
assert(m_nextIndex > 0); // Didn't rollover
m_valueIndexes.insert(std::make_pair(value, m_nextIndex));
m_indexValues.insert(std::make_pair(m_nextIndex, value));
m_valueIndexes.emplace(value, m_nextIndex);
m_indexValues.emplace(m_nextIndex, value);
return m_nextIndex;
}
static std::string dequote(const std::string& text) VL_PURE {
@@ -298,7 +298,7 @@ public:
// Keys -> strings
std::string keys[MAX_KEYS];
for (int i = 0; i < MAX_KEYS; ++i) {
if (ckeyps[i] && ckeyps[i][0]) { keys[i] = ckeyps[i]; }
if (ckeyps[i] && ckeyps[i][0]) keys[i] = ckeyps[i];
}
// Ignore empty keys
for (int i = 0; i < MAX_KEYS; ++i) {
@@ -390,7 +390,7 @@ public:
cit->second.second += itemp->count();
cit->second.first = combineHier(oldhier, hier);
} else {
eventCounts.insert(std::make_pair(name, make_pair(hier, itemp->count())));
eventCounts.emplace(name, make_pair(hier, itemp->count()));
}
}
+1 -1
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2020 by Wilson Snyder. This program is free software; you
// Copyright 2001-2021 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.
+11 -74
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2020 by Wilson Snyder. This program is free software; you
// Copyright 2001-2021 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.
@@ -29,69 +29,27 @@
#define VLCOVGEN_ITEM(string_parsed_by_vlcovgen)
// clang-format off
VLCOVGEN_ITEM("name=>'col0_name', short=>'C0', group=>1, default=>undef, descr=>'The column title for the header line of this column'")
VLCOVGEN_ITEM("name=>'col1_name', short=>'C1', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'col2_name', short=>'C2', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'col3_name', short=>'C3', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'column', short=>'n', group=>1, default=>0, descr=>'Column number for the item. Used to disambiguate multiple coverage points on the same line number'")
VLCOVGEN_ITEM("name=>'filename', short=>'f', group=>1, default=>undef, descr=>'Filename of the item'")
VLCOVGEN_ITEM("name=>'groupdesc', short=>'d', group=>1, default=>'', descr=>'Description of the covergroup this item belongs to'")
VLCOVGEN_ITEM("name=>'groupname', short=>'g', group=>1, default=>'', descr=>'Group name of the covergroup this item belongs to'")
VLCOVGEN_ITEM("name=>'groupcmt', short=>'O', group=>1, default=>'', ")
VLCOVGEN_ITEM("name=>'linescov', short=>'S', group=>1, default=>'', descr=>'List of comma-separated lines covered'")
VLCOVGEN_ITEM("name=>'per_instance',short=>'P', group=>1, default=>0, descr=>'True if every hierarchy is independently counted; otherwise all hierarchies will be combined into a single count'")
VLCOVGEN_ITEM("name=>'row0_name', short=>'R0', group=>1, default=>undef, descr=>'The row title for the header line of this row'")
VLCOVGEN_ITEM("name=>'row1_name', short=>'R1', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'row2_name', short=>'R2', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'row3_name', short=>'R3', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'table', short=>'T', group=>1, default=>undef, descr=>'The name of the table for automatically generated tables'")
VLCOVGEN_ITEM("name=>'thresh', short=>'s', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'type', short=>'t', group=>1, default=>'', descr=>'Type of coverage (block, line, fsm, etc)'")
VLCOVGEN_ITEM("'name':'column', 'short':'n', 'group':1, 'default':0, 'descr':'Column number for the item. Used to disambiguate multiple coverage points on the same line number'")
VLCOVGEN_ITEM("'name':'filename', 'short':'f', 'group':1, 'default':None, 'descr':'Filename of the item'")
VLCOVGEN_ITEM("'name':'linescov', 'short':'S', 'group':1, 'default':'', 'descr':'List of comma-separated lines covered'")
VLCOVGEN_ITEM("'name':'per_instance','short':'P', 'group':1, 'default':0, 'descr':'True if every hierarchy is independently counted; otherwise all hierarchies will be combined into a single count'")
VLCOVGEN_ITEM("'name':'thresh', 'short':'s', 'group':1, 'default':None, 'descr':'Number of hits to consider covered (aka at_least)'")
VLCOVGEN_ITEM("'name':'type', 'short':'t', 'group':1, 'default':'', 'descr':'Type of coverage (block, line, fsm, etc)'")
// Bin attributes
VLCOVGEN_ITEM("name=>'col0', short=>'c0', group=>0, default=>undef, descr=>'The (enumeration) value name for this column in a table cross' ")
VLCOVGEN_ITEM("name=>'col1', short=>'c1', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'col2', short=>'c2', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'col3', short=>'c3', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'comment', short=>'o', group=>0, default=>'', descr=>'Textual description for the item'")
VLCOVGEN_ITEM("name=>'hier', short=>'h', group=>0, default=>'', descr=>'Hierarchy path name for the item'")
VLCOVGEN_ITEM("name=>'limit', short=>'L', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'lineno', short=>'l', group=>0, default=>0, descr=>'Line number for the item'")
VLCOVGEN_ITEM("name=>'row0', short=>'r0', group=>0, default=>undef, descr=>'The (enumeration) value name for this row in a table cross'")
VLCOVGEN_ITEM("name=>'row1', short=>'r1', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'row2', short=>'r2', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'row3', short=>'r3', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr=>'For totaling items, weight of this item'")
VLCOVGEN_ITEM("'name':'comment', 'short':'o', 'group':0, 'default':'', 'descr':'Textual description for the item'")
VLCOVGEN_ITEM("'name':'hier', 'short':'h', 'group':0, 'default':'', 'descr':'Hierarchy path name for the item'")
VLCOVGEN_ITEM("'name':'lineno', 'short':'l', 'group':0, 'default':0, 'descr':'Line number for the item'")
VLCOVGEN_ITEM("'name':'weight', 'short':'w', 'group':0, 'default':None, 'descr':'For totaling items, weight of this item'")
// clang-format on
// VLCOVGEN_CIK_AUTO_EDIT_BEGIN
#define VL_CIK_COL0 "c0"
#define VL_CIK_COL0_NAME "C0"
#define VL_CIK_COL1 "c1"
#define VL_CIK_COL1_NAME "C1"
#define VL_CIK_COL2 "c2"
#define VL_CIK_COL2_NAME "C2"
#define VL_CIK_COL3 "c3"
#define VL_CIK_COL3_NAME "C3"
#define VL_CIK_COLUMN "n"
#define VL_CIK_COMMENT "o"
#define VL_CIK_FILENAME "f"
#define VL_CIK_GROUPCMT "O"
#define VL_CIK_GROUPDESC "d"
#define VL_CIK_GROUPNAME "g"
#define VL_CIK_HIER "h"
#define VL_CIK_LIMIT "L"
#define VL_CIK_LINENO "l"
#define VL_CIK_LINESCOV "S"
#define VL_CIK_PER_INSTANCE "P"
#define VL_CIK_ROW0 "r0"
#define VL_CIK_ROW0_NAME "R0"
#define VL_CIK_ROW1 "r1"
#define VL_CIK_ROW1_NAME "R1"
#define VL_CIK_ROW2 "r2"
#define VL_CIK_ROW2_NAME "R2"
#define VL_CIK_ROW3 "r3"
#define VL_CIK_ROW3_NAME "R3"
#define VL_CIK_TABLE "T"
#define VL_CIK_THRESH "s"
#define VL_CIK_TYPE "t"
#define VL_CIK_WEIGHT "w"
@@ -106,34 +64,13 @@ class VerilatedCovKey final {
public:
static std::string shortKey(const std::string& key) VL_PURE {
// VLCOVGEN_SHORT_AUTO_EDIT_BEGIN
if (key == "col0") return VL_CIK_COL0;
if (key == "col0_name") return VL_CIK_COL0_NAME;
if (key == "col1") return VL_CIK_COL1;
if (key == "col1_name") return VL_CIK_COL1_NAME;
if (key == "col2") return VL_CIK_COL2;
if (key == "col2_name") return VL_CIK_COL2_NAME;
if (key == "col3") return VL_CIK_COL3;
if (key == "col3_name") return VL_CIK_COL3_NAME;
if (key == "column") return VL_CIK_COLUMN;
if (key == "comment") return VL_CIK_COMMENT;
if (key == "filename") return VL_CIK_FILENAME;
if (key == "groupcmt") return VL_CIK_GROUPCMT;
if (key == "groupdesc") return VL_CIK_GROUPDESC;
if (key == "groupname") return VL_CIK_GROUPNAME;
if (key == "hier") return VL_CIK_HIER;
if (key == "limit") return VL_CIK_LIMIT;
if (key == "lineno") return VL_CIK_LINENO;
if (key == "linescov") return VL_CIK_LINESCOV;
if (key == "per_instance") return VL_CIK_PER_INSTANCE;
if (key == "row0") return VL_CIK_ROW0;
if (key == "row0_name") return VL_CIK_ROW0_NAME;
if (key == "row1") return VL_CIK_ROW1;
if (key == "row1_name") return VL_CIK_ROW1_NAME;
if (key == "row2") return VL_CIK_ROW2;
if (key == "row2_name") return VL_CIK_ROW2_NAME;
if (key == "row3") return VL_CIK_ROW3;
if (key == "row3_name") return VL_CIK_ROW3_NAME;
if (key == "table") return VL_CIK_TABLE;
if (key == "thresh") return VL_CIK_THRESH;
if (key == "type") return VL_CIK_TYPE;
if (key == "weight") return VL_CIK_WEIGHT;
+24 -97
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2021 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.
@@ -37,11 +37,6 @@
//======================================================================
// Internal macros
// Not supported yet
#define _VL_SVDPI_UNIMP() \
VL_FATAL_MT(__FILE__, __LINE__, "", \
(std::string("%%Error: Unsupported DPI function: ") + VL_FUNC).c_str())
#define _VL_SVDPI_WARN(...) VL_PRINTF_MT(__VA_ARGS__)
// Function requires a "context" in the import declaration
@@ -258,16 +253,6 @@ static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp, int nargs, i
return datap;
}
static int _vl_sv_adjusted_bit(const VerilatedDpiOpenVar* varp, int indx) {
if (VL_UNLIKELY(indx < varp->low(0) || indx > varp->high(0))) {
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function packed index out of bounds; %d "
"outside [%d:%d].\n",
indx, varp->left(0), varp->right(0));
return 0;
}
return indx - varp->low(0);
}
/// Return pointer to simulator open array element, or nullptr if outside range
static void* _vl_svGetArrElemPtr(const svOpenArrayHandle h, int nargs, int indx1, int indx2,
int indx3) VL_MT_SAFE {
@@ -283,7 +268,7 @@ static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s,
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
if (VL_UNLIKELY(!datap)) return;
switch (varp->vltype()) {
switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
case VLVT_UINT8: d[0] = *(reinterpret_cast<CData*>(datap)); return;
case VLVT_UINT16: d[0] = *(reinterpret_cast<SData*>(datap)); return;
case VLVT_UINT32: d[0] = *(reinterpret_cast<IData*>(datap)); return;
@@ -299,10 +284,10 @@ static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s,
for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) d[i] = wdatap[i];
return;
}
default:
default: // LCOV_EXCL_START // Errored earlier
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return;
return; // LCOV_EXCL_STOP
}
}
/// Copy to user logic array from simulator open array
@@ -311,7 +296,7 @@ static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandl
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
if (VL_UNLIKELY(!datap)) return;
switch (varp->vltype()) {
switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
case VLVT_UINT8:
d[0].aval = *(reinterpret_cast<CData*>(datap));
d[0].bval = 0;
@@ -330,7 +315,7 @@ static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandl
d[0].aval = lwp[0];
d[0].bval = 0;
d[1].aval = lwp[1];
d[0].bval = 0;
d[1].bval = 0;
break;
}
case VLVT_WDATA: {
@@ -341,10 +326,10 @@ static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandl
}
return;
}
default:
default: // LCOV_EXCL_START // Errored earlier
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return;
return; // LCOV_EXCL_STOP
}
}
@@ -354,7 +339,7 @@ static void _vl_svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecV
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
if (VL_UNLIKELY(!datap)) return;
switch (varp->vltype()) {
switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = s[0]; return;
case VLVT_UINT16: *(reinterpret_cast<SData*>(datap)) = s[0]; return;
case VLVT_UINT32: *(reinterpret_cast<IData*>(datap)) = s[0]; return;
@@ -364,10 +349,10 @@ static void _vl_svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecV
for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) wdatap[i] = s[i];
return;
}
default:
default: // LCOV_EXCL_START // Errored earlier
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return;
return; // LCOV_EXCL_STOP
}
}
/// Copy to simulator open array from from user logic array
@@ -376,7 +361,7 @@ static void _vl_svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogic
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
if (VL_UNLIKELY(!datap)) return;
switch (varp->vltype()) {
switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = s[0].aval; return;
case VLVT_UINT16: *(reinterpret_cast<SData*>(datap)) = s[0].aval; return;
case VLVT_UINT32: *(reinterpret_cast<IData*>(datap)) = s[0].aval; return;
@@ -388,10 +373,10 @@ static void _vl_svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogic
for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) wdatap[i] = s[i].aval;
return;
}
default:
default: // LCOV_EXCL_START // Errored earlier
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return;
return; // LCOV_EXCL_STOP
}
}
@@ -400,31 +385,14 @@ static svBit _vl_svGetBitArrElem(const svOpenArrayHandle s, int nargs, int indx1
int indx3, int indx4) VL_MT_SAFE {
// One extra index supported, as need bit number
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
void* datap;
int lsb;
if (varp->packed().elements()) {
datap = _vl_sv_adjusted_datap(varp, nargs - 1, indx1, indx2, indx3);
lsb = _vl_sv_adjusted_bit(
varp, ((nargs == 1) ? indx1 : (nargs == 2) ? indx2 : (nargs == 3) ? indx3 : indx4));
} else {
datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
lsb = 0;
}
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
if (VL_UNLIKELY(!datap)) return 0;
switch (varp->vltype()) {
case VLVT_UINT8: return (*(reinterpret_cast<CData*>(datap)) >> lsb) & 1;
case VLVT_UINT16: return (*(reinterpret_cast<SData*>(datap)) >> lsb) & 1;
case VLVT_UINT32: return (*(reinterpret_cast<IData*>(datap)) >> lsb) & 1;
case VLVT_UINT64:
return (*(reinterpret_cast<QData*>(datap)) >> static_cast<QData>(lsb)) & 1ULL;
case VLVT_WDATA: {
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
return VL_BITRSHIFT_W(wdatap, lsb) & 1;
}
default:
switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
case VLVT_UINT8: return (*(reinterpret_cast<CData*>(datap))) & 1;
default: // LCOV_EXCL_START // Errored earlier
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return 0;
return 0; // LCOV_EXCL_STOP
}
}
/// Update simulator open array from bit
@@ -433,27 +401,14 @@ static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value, int narg
// One extra index supported, as need bit number
value &= 1; // Make sure clean
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
void* datap;
int lsb;
if (varp->packed().elements()) {
datap = _vl_sv_adjusted_datap(varp, nargs - 1, indx1, indx2, indx3);
lsb = _vl_sv_adjusted_bit(
varp, ((nargs == 1) ? indx1 : (nargs == 2) ? indx2 : (nargs == 3) ? indx3 : indx4));
} else {
datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
lsb = 0;
}
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
if (VL_UNLIKELY(!datap)) return;
switch (varp->vltype()) {
case VLVT_UINT8: VL_ASSIGNBIT_II(-1, lsb, *(reinterpret_cast<CData*>(datap)), value); return;
case VLVT_UINT16: VL_ASSIGNBIT_II(-1, lsb, *(reinterpret_cast<SData*>(datap)), value); return;
case VLVT_UINT32: VL_ASSIGNBIT_II(-1, lsb, *(reinterpret_cast<IData*>(datap)), value); return;
case VLVT_UINT64: VL_ASSIGNBIT_QI(-1, lsb, *(reinterpret_cast<QData*>(datap)), value); return;
case VLVT_WDATA: VL_ASSIGNBIT_WI(-1, lsb, (reinterpret_cast<WDataOutP>(datap)), value); return;
default:
switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = value; return;
default: // LCOV_EXCL_START // Errored earlier
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return;
return; // LCOV_EXCL_STOP
}
}
@@ -643,13 +598,6 @@ svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...) {
out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
break;
}
case 4: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
int indx4 = va_arg(ap, int);
out = _vl_svGetBitArrElem(s, 4, indx1, indx2, indx3, indx4);
break;
}
default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break; // Will error
}
va_end(ap);
@@ -683,13 +631,6 @@ svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...) {
out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
break;
}
case 4: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
int indx4 = va_arg(ap, int);
out = _vl_svGetBitArrElem(s, 4, indx1, indx2, indx3, indx4);
break;
}
default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break; // Will error
}
va_end(ap);
@@ -725,13 +666,6 @@ void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...) {
_vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
break;
}
case 4: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
int indx4 = va_arg(ap, int);
_vl_svPutBitArrElem(d, value, 4, indx1, indx2, indx3, indx4);
break;
}
default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break; // Will error
}
va_end(ap);
@@ -763,13 +697,6 @@ void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1, ...)
_vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
break;
}
case 4: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
int indx4 = va_arg(ap, int);
_vl_svPutBitArrElem(d, value, 4, indx1, indx2, indx3, indx4);
break;
}
default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break; // Will error
}
va_end(ap);
+1 -1
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2021 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.
+2 -2
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2020 by Wilson Snyder. This program is free software; you
// Copyright 2001-2021 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.
@@ -94,7 +94,7 @@ void VerilatedFst::open(const char* filename) VL_MT_UNSAFE {
m_code2symbol.clear();
// Allocate string buffer for arrays
if (!m_strbuf) { m_strbuf = new char[maxBits() + 32]; }
if (!m_strbuf) m_strbuf = new char[maxBits() + 32];
}
void VerilatedFst::close() {
+1 -1
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2020 by Wilson Snyder. This program is free software; you
// Copyright 2001-2021 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.
+93 -42
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2010-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2010-2021 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.
@@ -87,6 +87,51 @@ public:
void print(QData addr, bool addrstamp, const void* valuep);
};
//===================================================================
// Verilog wide-number-in-array container
// Similar to std::array<WData, N>, but lighter weight, only methods needed
// by Verilator, to help compile time.
//
// This is only used when we need an upper-level container and so can't
// simply use a C style array (which is just a pointer).
template <std::size_t T_Words> class VlWide final {
EData m_storage[T_Words];
public:
// cppcheck-suppress uninitVar
VlWide() = default;
~VlWide() = default;
VlWide(const VlWide&) = default;
VlWide(VlWide&&) = default;
// OPERATOR METHODS
VlWide& operator=(const VlWide&) = default;
VlWide& operator=(VlWide&&) = default;
const EData& operator[](size_t index) const { return m_storage[index]; };
EData& operator[](size_t index) { return m_storage[index]; };
operator WDataOutP() { return &m_storage[0]; }
// METHODS
const EData& at(size_t index) const { return m_storage[index]; }
EData& at(size_t index) { return m_storage[index]; }
WData* data() { return &m_storage[0]; }
const WData* data() const { return &m_storage[0]; }
bool operator<(const VlWide<T_Words>& rhs) const {
return VL_LT_W(T_Words, data(), rhs.data());
}
};
// Convert a C array to std::array reference by pointer magic, without copy.
// Data type (second argument) is so the function template can automatically generate.
template <std::size_t T_Words> VlWide<T_Words>& VL_CVT_W_A(WDataInP inp, const VlWide<T_Words>&) {
return *((VlWide<T_Words>*)inp);
}
template <std::size_t T_Words> std::string VL_TO_STRING(const VlWide<T_Words>& obj) {
return VL_TO_STRING_W(T_Words, obj.data());
}
//===================================================================
// Verilog queue and dynamic array container
// There are no multithreaded locks on this; the base variable must
@@ -444,45 +489,6 @@ template <class T_Value> std::string VL_TO_STRING(const VlQueue<T_Value>& obj) {
return obj.to_string();
}
//===================================================================
// Verilog array container
// Similar to std::array<WData, N>, but lighter weight, only methods needed
// by Verilator, to help compile time.
//
// This is only used when we need an upper-level container and so can't
// simply use a C style array (which is just a pointer).
template <std::size_t T_Words> class VlWide final {
WData m_storage[T_Words];
public:
// cppcheck-suppress uninitVar
VlWide() = default;
~VlWide() = default;
VlWide(const VlWide&) = default;
VlWide(VlWide&&) = default;
VlWide& operator=(const VlWide&) = default;
VlWide& operator=(VlWide&&) = default;
// METHODS
const WData& at(size_t index) const { return m_storage[index]; }
WData& at(size_t index) { return m_storage[index]; }
WData* data() { return &m_storage[0]; }
const WData* data() const { return &m_storage[0]; }
bool operator<(const VlWide<T_Words>& rhs) const {
return VL_LT_W(T_Words, data(), rhs.data());
}
};
// Convert a C array to std::array reference by pointer magic, without copy.
// Data type (second argument) is so the function template can automatically generate.
template <std::size_t T_Words> VlWide<T_Words>& VL_CVT_W_A(WDataInP inp, const VlWide<T_Words>&) {
return *((VlWide<T_Words>*)inp);
}
template <std::size_t T_Words> std::string VL_TO_STRING(const VlWide<T_Words>& obj) {
return VL_TO_STRING_W(T_Words, obj.data());
}
//===================================================================
// Verilog associative array container
// There are no multithreaded locks on this; the base variable must
@@ -560,8 +566,7 @@ public:
T_Value& at(const T_Key& index) {
const auto it = m_map.find(index);
if (it == m_map.end()) {
std::pair<typename Map::iterator, bool> pit
= m_map.insert(std::make_pair(index, m_defaultValue));
std::pair<typename Map::iterator, bool> pit = m_map.emplace(index, m_defaultValue);
return pit.first->second;
}
return it->second;
@@ -788,6 +793,41 @@ void VL_WRITEMEM_N(bool hex, int bits, const std::string& filename,
}
}
//===================================================================
// Verilog packed array container
// For when a standard C++[] array is not sufficient, e.g. an
// array under a queue, or methods operating on the array
template <class T_Value, std::size_t T_Depth> class VlUnpacked final {
private:
// TYPES
typedef std::array<T_Value, T_Depth> Array;
public:
typedef typename Array::const_iterator const_iterator;
private:
// MEMBERS
Array m_array; // State of the assoc array
public:
// CONSTRUCTORS
VlUnpacked() = default;
~VlUnpacked() = default;
VlUnpacked(const VlUnpacked&) = default;
VlUnpacked(VlUnpacked&&) = default;
VlUnpacked& operator=(const VlUnpacked&) = default;
VlUnpacked& operator=(VlUnpacked&&) = default;
// METHODS
// Raw access
WData* data() { return &m_array[0]; }
const WData* data() const { return &m_array[0]; }
T_Value& operator[](size_t index) { return m_array[index]; };
const T_Value& operator[](size_t index) const { return m_array[index]; };
};
//===================================================================
// Verilog class reference container
// There are no multithreaded locks on this; the base variable must
@@ -802,6 +842,17 @@ inline T VL_NULL_CHECK(T t, const char* filename, int linenum) {
return t;
}
template <typename T, typename U>
static inline bool VL_CAST_DYNAMIC(VlClassRef<T> in, VlClassRef<U>& outr) {
VlClassRef<U> casted = std::dynamic_pointer_cast<U>(in);
if (VL_LIKELY(casted)) {
outr = casted;
return true;
} else {
return false;
}
}
//======================================================================
// Conversion functions
+17 -9
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2021 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.
@@ -61,7 +61,7 @@ private:
std::function<void()> m_cb; ///< Lambda to execute when message received
public:
// CONSTRUCTORS
VerilatedMsg(const std::function<void()>& cb)
explicit VerilatedMsg(const std::function<void()>& cb)
: m_mtaskId{Verilated::mtaskId()}
, m_cb{cb} {}
~VerilatedMsg() = default;
@@ -235,7 +235,7 @@ protected:
VerilatedScopeNameMap m_nameMap VL_GUARDED_BY(m_nameMutex);
VerilatedMutex m_hierMapMutex; ///< Protect m_hierMap
/// Map the represents scope hierarchy
/// Map that represents scope hierarchy
VerilatedHierarchyMap m_hierMap VL_GUARDED_BY(m_hierMapMutex);
// Slow - somewhat static:
@@ -331,7 +331,7 @@ public:
if (it != s_s.v.m_userMap.end()) {
it->second = userData;
} else {
s_s.v.m_userMap.insert(it, std::make_pair(std::make_pair(scopep, userKey), userData));
s_s.v.m_userMap.emplace(std::make_pair(scopep, userKey), userData);
}
}
static inline void* userFind(const void* scopep, void* userKey) VL_MT_SAFE {
@@ -374,9 +374,7 @@ public: // But only for verilated*.cpp
// Slow ok - called once/scope at construction
const VerilatedLockGuard lock(s_s.v.m_nameMutex);
const auto it = s_s.v.m_nameMap.find(scopep->name());
if (it == s_s.v.m_nameMap.end()) {
s_s.v.m_nameMap.insert(it, std::make_pair(scopep->name(), scopep));
}
if (it == s_s.v.m_nameMap.end()) s_s.v.m_nameMap.emplace(scopep->name(), scopep);
}
static inline const VerilatedScope* scopeFind(const char* namep) VL_MT_SAFE {
const VerilatedLockGuard lock(s_s.v.m_nameMutex);
@@ -413,6 +411,16 @@ public: // But only for verilated*.cpp
const VerilatedLockGuard lock(s_s.v.m_hierMapMutex);
s_s.v.m_hierMap[fromp].push_back(top);
}
static void hierarchyRemove(const VerilatedScope* fromp,
const VerilatedScope* top) VL_MT_SAFE {
// Slow ok - called at destruction for VPI accessible elements
const VerilatedLockGuard lock(s_s.v.m_hierMapMutex);
VerilatedHierarchyMap& map = s_s.v.m_hierMap;
if (map.find(fromp) == map.end()) return;
auto& scopes = map[fromp];
const auto it = find(scopes.begin(), scopes.end(), top);
if (it != scopes.end()) scopes.erase(it);
}
static const VerilatedHierarchyMap* hierarchyMap() VL_MT_SAFE_POSTINIT {
// Thread save only assuming this is called only after model construction completed
return &s_s.v.m_hierMap;
@@ -432,7 +440,7 @@ public: // But only for verilated*.cpp
const VerilatedLockGuard lock(s_s.v.m_exportMutex);
const auto it = s_s.v.m_exportMap.find(namep);
if (it == s_s.v.m_exportMap.end()) {
s_s.v.m_exportMap.insert(it, std::make_pair(namep, s_s.v.m_exportNext++));
s_s.v.m_exportMap.emplace(namep, s_s.v.m_exportNext++);
return s_s.v.m_exportNext++;
} else {
return it->second;
@@ -587,7 +595,7 @@ private:
}
} else {
// MCD Case
for (int i = 0; (fdi != 0) && (i < fp.capacity()); ++i, fdi >>= 1) {
for (size_t i = 0; (fdi != 0) && (i < fp.capacity()); ++i, fdi >>= 1) {
if (fdi & VL_MASK_I(1)) fp.push_back(s_s.v.m_fdps[i]);
}
}
+3 -3
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -24,8 +24,8 @@
// clang-format off
// Use VL_DISABLE_INTRINSICS to disable all intrinsics based optimization
#if !defined(VL_DISABLE_INTRINSICS) && !defined(VL_PORTABLE_ONLY)
// Use VL_PORTABLE_ONLY to disable all intrinsics based optimization
#ifndef VL_PORTABLE_ONLY
# if defined(__SSE2__) && !defined(VL_DISABLE_SSE2)
# define VL_HAVE_SSE2 1
# include <emmintrin.h>
+1 -1
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2020 by Wilson Snyder. This program is free software; you
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
// can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2000-2020 by Wilson Snyder. This program is free software; you
// Copyright 2000-2021 by Wilson Snyder. This program is free software; you
// can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2021 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.
+9 -9
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2021 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.
@@ -44,15 +44,15 @@ protected:
friend class VerilatedVarProps;
friend class VerilatedScope;
VerilatedRange() = default;
VerilatedRange(int left, int right)
: m_left{left}
, m_right{right} {}
void init(int left, int right) {
m_left = left;
m_right = right;
}
public:
VerilatedRange(int left, int right)
: m_left{left}
, m_right{right} {}
~VerilatedRange() = default;
int left() const { return m_left; }
int right() const { return m_right; }
@@ -75,15 +75,15 @@ class VerilatedVarProps VL_NOT_FINAL {
const vluint32_t m_magic; // Magic number
const VerilatedVarType m_vltype; // Data type
const VerilatedVarFlags m_vlflags; // Direction
const int m_pdims; // Packed dimensions
const int m_udims; // Unpacked dimensions
const int m_pdims; // Packed dimensions, 0 = none
const int m_udims; // Unpacked dimensions, 0 = none
VerilatedRange m_packed; // Packed array range
std::vector<VerilatedRange> m_unpacked; // Unpacked array ranges
void initUnpacked(const int* ulims) {
for (int i = 0; i < m_udims; ++i) {
const int left = ulims ? ulims[2 * i + 0] : 0;
const int right = ulims ? ulims[2 * i + 1] : 0;
m_unpacked.push_back(VerilatedRange(left, right));
const int uleft = ulims ? ulims[2 * i + 0] : 0;
const int uright = ulims ? ulims[2 * i + 1] : 0;
m_unpacked.emplace_back(uleft, uright);
}
}
// CONSTRUCTORS
+6 -4
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2021 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.
@@ -43,6 +43,7 @@ struct VerilatedCStrCmp {
};
/// Map of sorted scope names to find associated scope class
// This is a class instead of typedef/using to allow forward declaration in verilated.h
class VerilatedScopeNameMap final
: public std::map<const char*, const VerilatedScope*, VerilatedCStrCmp> {
public:
@@ -51,16 +52,17 @@ public:
};
/// Map of sorted variable names to find associated variable class
// This is a class instead of typedef/using to allow forward declaration in verilated.h
class VerilatedVarNameMap final : public std::map<const char*, VerilatedVar, VerilatedCStrCmp> {
public:
VerilatedVarNameMap() = default;
~VerilatedVarNameMap() = default;
};
typedef std::vector<const VerilatedScope*> VerilatedScopeVector;
/// Map of parent scope to vector of children scopes
// This is a class instead of typedef/using to allow forward declaration in verilated.h
class VerilatedHierarchyMap final
: public std::unordered_map<const VerilatedScope*, VerilatedScopeVector> {
: public std::unordered_map<const VerilatedScope*, std::vector<const VerilatedScope*>> {
public:
VerilatedHierarchyMap() = default;
~VerilatedHierarchyMap() = default;
+1 -1
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//=============================================================================
//
// Copyright 2012-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2012-2021 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2012-2020 by Wilson Snyder. This program is free software; you
// Copyright 2012-2021 by Wilson Snyder. This program is free software; you
// can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+3 -4
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2020 by Wilson Snyder. This program is free software; you
// Copyright 2001-2021 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.
@@ -74,7 +74,7 @@ public:
// Non blocking get
bool tryGet(T& result) {
const VerilatedLockGuard lockGuard(m_mutex);
if (m_queue.empty()) { return false; }
if (m_queue.empty()) return false;
result = m_queue.front();
m_queue.pop_front();
return true;
@@ -216,14 +216,13 @@ protected:
double timeRes() const { return m_timeRes; }
double timeUnit() const { return m_timeUnit; }
std::string timeResStr() const;
std::string timeUnitStr() const;
void traceInit() VL_MT_UNSAFE;
void declCode(vluint32_t code, vluint32_t bits, bool tri);
/// Is this an escape?
bool isScopeEscape(char c) { return isspace(c) || c == m_scopeEscape; }
bool isScopeEscape(char c) { return c != '\f' && (isspace(c) || c == m_scopeEscape); }
/// Character that splits scopes. Note whitespace are ALWAYS escapes.
char scopeEscape() { return m_scopeEscape; }
+38 -7
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2020 by Wilson Snyder. This program is free software; you
// Copyright 2001-2021 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.
@@ -47,7 +47,7 @@ static double timescaleToDouble(const char* unitp) {
unitp = endp;
for (; *unitp && isspace(*unitp); unitp++) {}
switch (*unitp) {
case 's': value *= 1e1; break;
case 's': value *= 1e0; break;
case 'm': value *= 1e-3; break;
case 'u': value *= 1e-6; break;
case 'n': value *= 1e-9; break;
@@ -70,7 +70,7 @@ static std::string doubleToTimescale(double value) {
else if (value >= 1e-18) { suffixp = "as"; value *= 1e18; }
// clang-format on
char valuestr[100];
sprintf(valuestr, "%3.0f%s", value, suffixp);
sprintf(valuestr, "%0.0f%s", value, suffixp);
return valuestr; // Gets converted to string, so no ref to stack
}
@@ -374,10 +374,6 @@ template <> std::string VerilatedTrace<VL_DERIVED_T>::timeResStr() const {
return doubleToTimescale(m_timeRes);
}
template <> std::string VerilatedTrace<VL_DERIVED_T>::timeUnitStr() const {
return doubleToTimescale(m_timeUnit);
}
//=========================================================================
// External interface to client code
@@ -643,4 +639,39 @@ static inline void cvtQDataToStr(char* dstp, QData value) {
#define cvtEDataToStr cvtIDataToStr
//=============================================================================
#ifdef VERILATED_VCD_TEST
void verilated_trace_imp_selftest() {
#define SELF_CHECK(got, exp) \
do { \
if ((got) != (exp)) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: selftest\n"); \
} while (0)
#define SELF_CHECK_TS(scale) \
SELF_CHECK(doubleToTimescale(timescaleToDouble(scale)), std::string{scale});
SELF_CHECK_TS("1s");
SELF_CHECK_TS("100ms");
SELF_CHECK_TS("10ms");
SELF_CHECK_TS("1ms");
SELF_CHECK_TS("100us");
SELF_CHECK_TS("10us");
SELF_CHECK_TS("1us");
SELF_CHECK_TS("100ns");
SELF_CHECK_TS("10ns");
SELF_CHECK_TS("1ns");
SELF_CHECK_TS("100ps");
SELF_CHECK_TS("10ps");
SELF_CHECK_TS("1ps");
SELF_CHECK_TS("100fs");
SELF_CHECK_TS("10fs");
SELF_CHECK_TS("1fs");
SELF_CHECK_TS("100as");
SELF_CHECK_TS("10as");
SELF_CHECK_TS("1as");
}
#endif
#endif // VL_CPPCHECK
+23 -7
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2020 by Wilson Snyder. This program is free software; you
// Copyright 2001-2021 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.
@@ -138,7 +138,9 @@ void VerilatedVcd::openNext(bool incFilename) {
name[pos - 2] = '0';
if ((++(name[pos - 3])) > '9') {
name[pos - 3] = '0';
if ((++(name[pos - 4])) > '9') { name[pos - 4] = '0'; }
if ((++(name[pos - 4])) > '9') { //
name[pos - 4] = '0';
}
}
}
}
@@ -164,7 +166,7 @@ void VerilatedVcd::openNext(bool incFilename) {
}
bool VerilatedVcd::preChangeDump() {
if (VL_UNLIKELY(m_rolloverMB && m_wroteBytes > m_rolloverMB)) { openNext(true); }
if (VL_UNLIKELY(m_rolloverMB && m_wroteBytes > m_rolloverMB)) openNext(true);
return isOpen();
}
@@ -198,7 +200,7 @@ void VerilatedVcd::makeNameMap() {
std::string newname = std::string("top");
if (hiername[0] != '\t') newname += ' ';
newname += hiername;
newmapp->insert(std::make_pair(newname, decl));
newmapp->emplace(newname, decl);
}
deleteNameMap();
m_namemapp = newmapp;
@@ -401,13 +403,22 @@ void VerilatedVcd::dumpHeader() {
if (*np == ' ') np++;
if (*np == '\t') break; // tab means signal name starts
printIndent(1);
printStr("$scope module ");
// Find character after name end
const char* sp = np;
while (*sp && *sp != ' ' && *sp != '\t' && *sp != '\f') sp++;
if (*sp == '\f') {
printStr("$scope struct ");
} else {
printStr("$scope module ");
}
for (; *np && *np != ' ' && *np != '\t'; np++) {
if (*np == '[') {
printStr("(");
} else if (*np == ']') {
printStr(")");
} else {
} else if (*np != '\f') {
*m_writep++ = *np;
}
}
@@ -511,7 +522,7 @@ void VerilatedVcd::declare(vluint32_t code, const char* name, const char* wirep,
decl += buf;
}
decl += " $end\n";
m_namemapp->insert(std::make_pair(hiername, decl));
m_namemapp->emplace(hiername, decl);
}
void VerilatedVcd::declBit(vluint32_t code, const char* name, bool array, int arraynum) {
@@ -777,6 +788,8 @@ void VerilatedVcd::fullDouble(vluint32_t code, const double newval) {
#ifdef VERILATED_VCD_TEST
#include <iostream>
extern void verilated_trace_imp_selftest();
vluint32_t v1, v2, s1, s2[3];
vluint32_t tri96[3];
vluint32_t tri96__tri[3];
@@ -843,6 +856,8 @@ void vcdChange(void*, VerilatedVcd* vcdp) {
// clang-format off
void vcdTestMain(const char* filenamep) {
verilated_trace_imp_selftest();
v1 = v2 = s1 = 0;
s2[0] = s2[1] = s2[2] = 0;
tri96[2] = tri96[1] = tri96[0] = 0;
@@ -889,6 +904,7 @@ void vcdTestMain(const char* filenamep) {
}
# endif
vcdp->close();
VL_DO_CLEAR(delete vcdp, vcdp = nullptr);
}
}
#endif
+3 -3
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2020 by Wilson Snyder. This program is free software; you
// Copyright 2001-2021 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.
@@ -34,7 +34,7 @@ class VerilatedVcd;
// VerilatedFile
/// File handling routines, which can be overrode for e.g. socket I/O
class VerilatedVcdFile final {
class VerilatedVcdFile VL_NOT_FINAL {
private:
int m_fd = 0; ///< File descriptor we're writing to
public:
@@ -84,7 +84,7 @@ private:
inline void bufferCheck() {
// Flush the write buffer if there's not enough space left for new information
// We only call this once per vector, so we need enough slop for a very wide "b###" line
if (VL_UNLIKELY(m_writep > m_wrFlushp)) { bufferFlush(); }
if (VL_UNLIKELY(m_writep > m_wrFlushp)) bufferFlush();
}
void closePrev();
void closeErr();
+1 -1
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2020 by Wilson Snyder. This program is free software; you
// Copyright 2001-2021 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.
+2 -2
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//=============================================================================
//
// Copyright 2001-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -53,7 +53,7 @@ public:
// METHODS
/// Called by SystemC simulate()
virtual void cycle(bool delta_cycle) {
if (!delta_cycle) { this->dump(sc_time_stamp().to_double()); }
if (!delta_cycle) this->dump(sc_time_stamp().to_double());
}
private:
+222 -100
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2021 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.
@@ -56,6 +56,11 @@ constexpr unsigned VL_VPI_LINE_SIZE = 8192;
// Base VPI handled object
class VerilatedVpio VL_NOT_FINAL {
// CONSTANTS
/// Magic value stored in front of object to detect double free etc
/// Must be odd, as aligned pointer can never be odd
static constexpr vluint32_t activeMagic() { return 0xfeed100f; }
// MEM MANGLEMENT
static VL_THREAD_LOCAL vluint8_t* t_freeHead;
@@ -73,16 +78,27 @@ public:
if (VL_LIKELY(t_freeHead)) {
vluint8_t* newp = t_freeHead;
t_freeHead = *(reinterpret_cast<vluint8_t**>(newp));
*(reinterpret_cast<vluint32_t*>(newp)) = activeMagic();
return newp + 8;
}
// +8: 8 bytes for next
vluint8_t* newp = reinterpret_cast<vluint8_t*>(::operator new(chunk + 8));
*(reinterpret_cast<vluint32_t*>(newp)) = activeMagic();
return newp + 8;
}
static void operator delete(void* obj, size_t /*size*/)VL_MT_SAFE {
vluint8_t* oldp = (static_cast<vluint8_t*>(obj)) - 8;
if (VL_UNLIKELY(*(reinterpret_cast<vluint32_t*>(oldp)) != activeMagic())) {
VL_FATAL_MT(__FILE__, __LINE__, "",
"vpi_release_handle() called on same object twice, or on non-Verilator "
"VPI object");
}
#ifdef VL_VPI_IMMEDIATE_FREE // Define to aid in finding leaky handles
::operator delete(oldp);
#else
*(reinterpret_cast<void**>(oldp)) = t_freeHead;
t_freeHead = oldp;
#endif
}
// MEMBERS
static VerilatedVpio* castp(vpiHandle h) {
@@ -97,32 +113,44 @@ public:
virtual vluint32_t size() const { return 0; }
virtual const VerilatedRange* rangep() const { return nullptr; }
virtual vpiHandle dovpi_scan() { return nullptr; }
virtual PLI_INT32 dovpi_remove_cb() { return 0; }
};
typedef PLI_INT32 (*VerilatedPliCb)(struct t_cb_data*);
class VerilatedVpioCb final : public VerilatedVpio {
t_cb_data m_cbData;
s_vpi_value m_value;
class VerilatedVpioTimedCb final : public VerilatedVpio {
// A handle to a timed callback created with vpi_register_cb
// User can call vpi_remove_cb or vpi_release_handle on it
vluint64_t m_id; // Unique id/sequence number to find schedule's event
QData m_time;
public:
// cppcheck-suppress uninitVar // m_value
VerilatedVpioCb(const t_cb_data* cbDatap, QData time)
: m_cbData(*cbDatap)
, m_time(time) { // Need () or GCC 4.8 false warning
m_value.format = cbDatap->value ? cbDatap->value->format : vpiSuppressVal;
m_cbData.value = &m_value;
}
virtual ~VerilatedVpioCb() override = default;
static VerilatedVpioCb* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioCb*>(reinterpret_cast<VerilatedVpio*>(h));
VerilatedVpioTimedCb(vluint64_t id, QData time)
: m_id(id)
, m_time{time} {}
virtual ~VerilatedVpioTimedCb() override = default;
static VerilatedVpioTimedCb* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioTimedCb*>(reinterpret_cast<VerilatedVpioTimedCb*>(h));
}
virtual vluint32_t type() const override { return vpiCallback; }
vluint32_t reason() const { return m_cbData.reason; }
VerilatedPliCb cb_rtnp() const { return m_cbData.cb_rtn; }
t_cb_data* cb_datap() { return &(m_cbData); }
QData time() const { return m_time; }
virtual PLI_INT32 dovpi_remove_cb() override;
};
class VerilatedVpioReasonCb final : public VerilatedVpio {
// A handle to a non-timed callback created with vpi_register_cb
// User can call vpi_remove_cb or vpi_release_handle on it
vluint64_t m_id; // Unique id/sequence number to find schedule's event
PLI_INT32 m_reason; // VPI callback reason code
public:
// cppcheck-suppress uninitVar // m_value
VerilatedVpioReasonCb(vluint64_t id, PLI_INT32 reason)
: m_id(id)
, m_reason{reason} {}
virtual ~VerilatedVpioReasonCb() override = default;
static VerilatedVpioReasonCb* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioReasonCb*>(reinterpret_cast<VerilatedVpioReasonCb*>(h));
}
virtual vluint32_t type() const override { return vpiCallback; }
virtual PLI_INT32 dovpi_remove_cb() override;
};
class VerilatedVpioConst final : public VerilatedVpio {
@@ -147,7 +175,6 @@ public:
VerilatedVpioParam(const VerilatedVar* varp, const VerilatedScope* scopep)
: m_varp{varp}
, m_scopep{scopep} {}
virtual ~VerilatedVpioParam() override = default;
static VerilatedVpioParam* castp(vpiHandle h) {
@@ -167,7 +194,6 @@ public:
class VerilatedVpioRange final : public VerilatedVpio {
const VerilatedRange* m_range;
vlsint32_t m_iteration = 0;
public:
explicit VerilatedVpioRange(const VerilatedRange* range)
@@ -179,15 +205,28 @@ public:
virtual vluint32_t type() const override { return vpiRange; }
virtual vluint32_t size() const override { return m_range->elements(); }
virtual const VerilatedRange* rangep() const override { return m_range; }
int iteration() const { return m_iteration; }
void iterationInc() { ++m_iteration; }
};
class VerilatedVpioRangeIter final : public VerilatedVpio {
// Only supports 1 dimension
const VerilatedRange* m_range;
bool m_done = false;
public:
explicit VerilatedVpioRangeIter(const VerilatedRange* range)
: m_range{range} {}
virtual ~VerilatedVpioRangeIter() override = default;
static VerilatedVpioRangeIter* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioRangeIter*>(reinterpret_cast<VerilatedVpio*>(h));
}
virtual vluint32_t type() const override { return vpiIterator; }
virtual vpiHandle dovpi_scan() override {
if (!iteration()) {
VerilatedVpioRange* nextp = new VerilatedVpioRange(*this);
nextp->iterationInc();
return ((nextp)->castVpiHandle());
if (VL_UNLIKELY(m_done)) {
delete this; // IEEE 37.2.2 vpi_scan at end does a vpi_release_handle
return nullptr;
}
return nullptr; // End of list - only one deep
m_done = true;
return ((new VerilatedVpioRange(m_range))->castVpiHandle());
}
};
@@ -209,16 +248,16 @@ public:
};
class VerilatedVpioVar VL_NOT_FINAL : public VerilatedVpio {
const VerilatedVar* m_varp;
const VerilatedScope* m_scopep;
const VerilatedVar* m_varp = nullptr;
const VerilatedScope* m_scopep = nullptr;
vluint8_t* m_prevDatap = nullptr; // Previous value of data, for cbValueChange
union {
vluint8_t u8[4];
vluint32_t u32;
} m_mask; // memoized variable mask
vluint32_t m_entSize; // memoized variable size
vluint32_t m_entSize = 0; // memoized variable size
protected:
void* m_varDatap; // varp()->datap() adjusted for array entries
void* m_varDatap = nullptr; // varp()->datap() adjusted for array entries
vlsint32_t m_index = 0;
const VerilatedRange& get_range() const {
// Determine number of dimensions and return outermost
@@ -233,6 +272,19 @@ public:
m_entSize = varp->entSize();
m_varDatap = varp->datap();
}
explicit VerilatedVpioVar(const VerilatedVpioVar* varp) {
if (varp) {
m_varp = varp->m_varp;
m_scopep = varp->m_scopep;
m_mask.u32 = varp->m_mask.u32;
m_entSize = varp->m_entSize;
m_varDatap = varp->m_varDatap;
m_index = varp->m_index;
// Not copying m_prevDatap, must be nullptr
} else {
m_mask.u32 = 0;
}
}
virtual ~VerilatedVpioVar() override {
if (m_prevDatap) VL_DO_CLEAR(delete[] m_prevDatap, m_prevDatap = nullptr);
}
@@ -310,13 +362,18 @@ public:
m_it = varsp->begin();
m_started = true;
} else if (VL_UNLIKELY(m_it == varsp->end())) {
delete this; // IEEE 37.2.2 vpi_scan at end does a vpi_release_handle
return nullptr;
} else {
++m_it;
}
if (m_it == varsp->end()) return nullptr;
if (VL_UNLIKELY(m_it == varsp->end())) {
delete this; // IEEE 37.2.2 vpi_scan at end does a vpi_release_handle
return nullptr;
}
return ((new VerilatedVpioVar(&(m_it->second), m_scopep))->castVpiHandle());
}
delete this; // IEEE 37.2.2 vpi_scan at end does a vpi_release_handle
return nullptr; // End of list - only one deep
}
};
@@ -343,9 +400,11 @@ public:
if (!(m_done = (m_iteration == m_varp->unpacked().left()))) m_iteration += m_direction;
}
virtual vpiHandle dovpi_scan() override {
vpiHandle result;
if (m_done) return nullptr;
result = vpi_handle_by_index(m_handle, m_iteration);
if (VL_UNLIKELY(m_done)) {
delete this; // IEEE 37.2.2 vpi_scan at end does a vpi_release_handle
return nullptr;
}
vpiHandle result = vpi_handle_by_index(m_handle, m_iteration);
iterationInc();
return result;
}
@@ -385,7 +444,10 @@ public:
}
virtual vluint32_t type() const override { return vpiIterator; }
virtual vpiHandle dovpi_scan() override {
if (m_it == m_vec->end()) return nullptr;
if (m_it == m_vec->end()) {
delete this; // IEEE 37.2.2 vpi_scan at end does a vpi_release_handle
return nullptr;
}
const VerilatedScope* modp = *m_it++;
return (new VerilatedVpioModule(modp))->castVpiHandle();
}
@@ -393,10 +455,42 @@ public:
//======================================================================
typedef PLI_INT32 (*VerilatedPliCb)(struct t_cb_data*);
class VerilatedVpiCbHolder final {
// Holds information needed to call a callback
vluint64_t m_id;
s_cb_data m_cbData;
s_vpi_value m_value;
VerilatedVpioVar m_varo; // If a cbValueChange callback, the object we will return
public:
// cppcheck-suppress uninitVar // m_value
VerilatedVpiCbHolder(vluint64_t id, const s_cb_data* cbDatap, const VerilatedVpioVar* varop)
: m_id(id)
, m_cbData(*cbDatap)
, m_varo(varop) {
m_value.format = cbDatap->value ? cbDatap->value->format : vpiSuppressVal;
m_cbData.value = &m_value;
if (varop) {
m_cbData.obj = m_varo.castVpiHandle();
m_varo.createPrevDatap();
} else {
m_cbData.obj = NULL;
}
}
~VerilatedVpiCbHolder() = default;
VerilatedPliCb cb_rtnp() const { return m_cbData.cb_rtn; }
s_cb_data* cb_datap() { return &m_cbData; }
vluint64_t id() const { return m_id; }
bool invalid() const { return !m_id; }
void invalidate() { m_id = 0; }
};
struct VerilatedVpiTimedCbsCmp {
/// Ordering sets keyed by time, then callback descriptor
bool operator()(const std::pair<QData, VerilatedVpioCb*>& a,
const std::pair<QData, VerilatedVpioCb*>& b) const {
/// Ordering sets keyed by time, then callback unique id
bool operator()(const std::pair<QData, vluint64_t>& a,
const std::pair<QData, vluint64_t>& b) const {
if (a.first < b.first) return true;
if (a.first > b.first) return false;
return a.second < b.second;
@@ -407,57 +501,70 @@ class VerilatedVpiError;
class VerilatedVpiImp final {
enum { CB_ENUM_MAX_VALUE = cbAtEndOfSimTime + 1 }; // Maxium callback reason
typedef std::list<VerilatedVpioCb*> VpioCbList;
typedef std::set<std::pair<QData, VerilatedVpioCb*>, VerilatedVpiTimedCbsCmp> VpioTimedCbs;
typedef std::list<VerilatedVpiCbHolder> VpioCbList;
typedef std::map<std::pair<QData, vluint64_t>, VerilatedVpiCbHolder> VpioTimedCbs;
VpioCbList m_cbObjLists[CB_ENUM_MAX_VALUE]; // Callbacks for each supported reason
VpioTimedCbs m_timedCbs; // Time based callbacks
VerilatedVpiError* m_errorInfop = nullptr; // Container for vpi error info
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
vluint64_t m_nextCallbackId = 1; // Id to identify callback
static VerilatedVpiImp s_s; // Singleton
public:
VerilatedVpiImp() = default;
~VerilatedVpiImp() = default;
static void assertOneCheck() { s_s.m_assertOne.check(); }
static void cbReasonAdd(VerilatedVpioCb* vop) {
if (vop->reason() == cbValueChange) {
if (VerilatedVpioVar* varop = VerilatedVpioVar::castp(vop->cb_datap()->obj)) {
varop->createPrevDatap();
}
}
if (VL_UNCOVERABLE(vop->reason() >= CB_ENUM_MAX_VALUE)) {
static vluint64_t nextCallbackId() { return ++s_s.m_nextCallbackId; }
static void cbReasonAdd(vluint64_t id, const s_cb_data* cb_data_p) {
// The passed cb_data_p was property of the user, so need to recreate
if (VL_UNCOVERABLE(cb_data_p->reason >= CB_ENUM_MAX_VALUE)) {
VL_FATAL_MT(__FILE__, __LINE__, "", "vpi bb reason too large");
}
s_s.m_cbObjLists[vop->reason()].push_back(vop);
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_register_cb reason=%d id=%" VL_PRI64 "d obj=%p\n",
cb_data_p->reason, id, cb_data_p->obj););
VerilatedVpioVar* varop = nullptr;
if (cb_data_p->reason == cbValueChange) varop = VerilatedVpioVar::castp(cb_data_p->obj);
s_s.m_cbObjLists[cb_data_p->reason].emplace_back(id, cb_data_p, varop);
}
static void cbTimedAdd(VerilatedVpioCb* vop) {
s_s.m_timedCbs.insert(std::make_pair(vop->time(), vop));
static void cbTimedAdd(vluint64_t id, const s_cb_data* cb_data_p, QData time) {
// The passed cb_data_p was property of the user, so need to recreate
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_register_cb reason=%d id=%" VL_PRI64
"d delay=%" VL_PRI64 "u\n",
cb_data_p->reason, id, time););
s_s.m_timedCbs.emplace(std::piecewise_construct,
std::forward_as_tuple(std::make_pair(time, id)),
std::forward_as_tuple(id, cb_data_p, nullptr));
}
static void cbReasonRemove(VerilatedVpioCb* cbp) {
VpioCbList& cbObjList = s_s.m_cbObjLists[cbp->reason()];
static void cbReasonRemove(vluint64_t id, vluint32_t reason) {
// Id might no longer exist, if already removed due to call after event, or teardown
VpioCbList& cbObjList = s_s.m_cbObjLists[reason];
// We do not remove it now as we may be iterating the list,
// instead set to nullptr and will cleanup later
for (auto& ir : cbObjList) {
if (ir == cbp) ir = nullptr;
if (ir.id() == id) ir.invalidate();
}
}
static void cbTimedRemove(VerilatedVpioCb* cbp) {
const auto it = s_s.m_timedCbs.find(std::make_pair(cbp->time(), cbp));
if (VL_LIKELY(it != s_s.m_timedCbs.end())) s_s.m_timedCbs.erase(it);
static void cbTimedRemove(vluint64_t id, QData time) {
// Id might no longer exist, if already removed due to call after event, or teardown
const auto it = s_s.m_timedCbs.find(std::make_pair(time, id));
if (VL_LIKELY(it != s_s.m_timedCbs.end())) it->second.invalidate();
}
static void callTimedCbs() VL_MT_UNSAFE_ONE {
assertOneCheck();
QData time = VL_TIME_Q();
for (auto it = s_s.m_timedCbs.begin(); it != s_s.m_timedCbs.end();) {
if (VL_UNLIKELY(it->first <= time)) {
VerilatedVpioCb* vop = it->second;
if (VL_UNLIKELY(it->first.first <= time)) {
VerilatedVpiCbHolder& ho = it->second;
const auto last_it = it;
++it; // Timed callbacks are one-shot
++it;
if (VL_UNLIKELY(!ho.invalid())) {
VL_DEBUG_IF_PLI(
VL_DBG_MSGF("- vpi: timed_callback id=%" VL_PRI64 "d\n", ho.id()););
ho.invalidate(); // Timed callbacks are one-shot
(ho.cb_rtnp())(ho.cb_datap());
}
s_s.m_timedCbs.erase(last_it);
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: timed_callback %p\n", vop););
(vop->cb_rtnp())(vop->cb_datap());
} else {
++it;
}
@@ -465,7 +572,7 @@ public:
}
static QData cbNextDeadline() {
const auto it = s_s.m_timedCbs.cbegin();
if (VL_LIKELY(it != s_s.m_timedCbs.cend())) return it->first;
if (VL_LIKELY(it != s_s.m_timedCbs.cend())) return it->first.first;
return ~0ULL; // maxquad
}
static bool callCbs(vluint32_t reason) VL_MT_UNSAFE_ONE {
@@ -476,16 +583,18 @@ public:
for (auto it = cbObjList.begin(); true;) {
// cbReasonRemove sets to nullptr, so we know on removal the old end() will still exist
bool was_last = it == last;
if (VL_UNLIKELY(!*it)) { // Deleted earlier, cleanup
if (VL_UNLIKELY(it->invalid())) { // Deleted earlier, cleanup
it = cbObjList.erase(it);
if (was_last) break;
continue;
}
VerilatedVpioCb* vop = *it++;
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: reason_callback %d %p\n", reason, vop););
(vop->cb_rtnp())(vop->cb_datap());
VerilatedVpiCbHolder& ho = *it;
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: reason_callback reason=%d id=%" VL_PRI64 "d\n",
reason, ho.id()););
(ho.cb_rtnp())(ho.cb_datap());
called = true;
if (was_last) break;
++it;
}
return called;
}
@@ -500,24 +609,25 @@ public:
for (auto it = cbObjList.begin(); true;) {
// cbReasonRemove sets to nullptr, so we know on removal the old end() will still exist
bool was_last = it == last;
if (VL_UNLIKELY(!*it)) { // Deleted earlier, cleanup
if (VL_UNLIKELY(it->invalid())) { // Deleted earlier, cleanup
it = cbObjList.erase(it);
if (was_last) break;
continue;
}
VerilatedVpioCb* vop = *it++;
if (VerilatedVpioVar* varop = VerilatedVpioVar::castp(vop->cb_datap()->obj)) {
VerilatedVpiCbHolder& ho = *it++;
if (VerilatedVpioVar* varop = VerilatedVpioVar::castp(ho.cb_datap()->obj)) {
void* newDatap = varop->varDatap();
void* prevDatap = varop->prevDatap(); // Was malloced when we added the callback
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: value_test %s v[0]=%d/%d %p %p\n",
varop->fullname(), *((CData*)newDatap),
*((CData*)prevDatap), newDatap, prevDatap););
if (memcmp(prevDatap, newDatap, varop->entSize()) != 0) {
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: value_callback %p %s v[0]=%d\n", vop,
varop->fullname(), *((CData*)newDatap)););
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: value_callback %" VL_PRI64
"d %s v[0]=%d\n",
ho.id(), varop->fullname(), *((CData*)newDatap)););
update.insert(varop);
vpi_get_value(vop->cb_datap()->obj, vop->cb_datap()->value);
(vop->cb_rtnp())(vop->cb_datap());
vpi_get_value(ho.cb_datap()->obj, ho.cb_datap()->value);
(ho.cb_rtnp())(ho.cb_datap());
called = true;
}
}
@@ -616,12 +726,23 @@ bool VerilatedVpi::callCbs(vluint32_t reason) VL_MT_UNSAFE_ONE {
QData VerilatedVpi::cbNextDeadline() VL_MT_UNSAFE_ONE { return VerilatedVpiImp::cbNextDeadline(); }
PLI_INT32 VerilatedVpioTimedCb::dovpi_remove_cb() {
VerilatedVpiImp::cbTimedRemove(m_id, m_time);
delete this; // IEEE 37.2.2 a vpi_remove_cb does a vpi_release_handle
return 1;
}
PLI_INT32 VerilatedVpioReasonCb::dovpi_remove_cb() {
VerilatedVpiImp::cbReasonRemove(m_id, m_reason);
delete this; // IEEE 37.2.2 a vpi_remove_cb does a vpi_release_handle
return 1;
}
//======================================================================
// VerilatedVpiImp implementation
VerilatedVpiError* VerilatedVpiImp::error_info() VL_MT_UNSAFE_ONE {
VerilatedVpiImp::assertOneCheck();
if (VL_UNLIKELY(!s_s.m_errorInfop)) { s_s.m_errorInfop = new VerilatedVpiError(); }
if (VL_UNLIKELY(!s_s.m_errorInfop)) s_s.m_errorInfop = new VerilatedVpiError();
return s_s.m_errorInfop;
}
@@ -1018,6 +1139,9 @@ void VerilatedVpiError::selfTest() VL_MT_UNSAFE_ONE {
// callback related
vpiHandle vpi_register_cb(p_cb_data cb_data_p) {
// Returns handle so user can remove the callback, user must vpi_release_handle it
// Don't confuse with the callback-activated t_cb_data object handle
// which is the object causing the callback rather than the callback itself
VerilatedVpiImp::assertOneCheck();
_VL_VPI_ERROR_RESET();
// cppcheck-suppress nullPointer
@@ -1029,10 +1153,10 @@ vpiHandle vpi_register_cb(p_cb_data cb_data_p) {
case cbAfterDelay: {
QData time = 0;
if (cb_data_p->time) time = _VL_SET_QII(cb_data_p->time->high, cb_data_p->time->low);
VerilatedVpioCb* vop = new VerilatedVpioCb(cb_data_p, VL_TIME_Q() + time);
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_register_cb %d %p delay=%" VL_PRI64 "u\n",
cb_data_p->reason, vop, time););
VerilatedVpiImp::cbTimedAdd(vop);
QData abstime = VL_TIME_Q() + time;
vluint64_t id = VerilatedVpiImp::nextCallbackId();
VerilatedVpioTimedCb* vop = new VerilatedVpioTimedCb{id, abstime};
VerilatedVpiImp::cbTimedAdd(id, cb_data_p, abstime);
return vop->castVpiHandle();
}
case cbReadWriteSynch: // FALLTHRU // Supported via vlt_main.cpp
@@ -1045,9 +1169,9 @@ vpiHandle vpi_register_cb(p_cb_data cb_data_p) {
case cbEnterInteractive: // FALLTHRU // NOP, but need to return handle, so make object
case cbExitInteractive: // FALLTHRU // NOP, but need to return handle, so make object
case cbInteractiveScopeChange: { // FALLTHRU // NOP, but need to return handle, so make object
VerilatedVpioCb* vop = new VerilatedVpioCb(cb_data_p, 0);
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_register_cb %d %p\n", cb_data_p->reason, vop););
VerilatedVpiImp::cbReasonAdd(vop);
vluint64_t id = VerilatedVpiImp::nextCallbackId();
VerilatedVpioReasonCb* vop = new VerilatedVpioReasonCb{id, cb_data_p->reason};
VerilatedVpiImp::cbReasonAdd(id, cb_data_p);
return vop->castVpiHandle();
}
default:
@@ -1060,15 +1184,10 @@ vpiHandle vpi_register_cb(p_cb_data cb_data_p) {
PLI_INT32 vpi_remove_cb(vpiHandle cb_obj) {
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_remove_cb %p\n", cb_obj););
VerilatedVpiImp::assertOneCheck();
VerilatedVpioCb* vop = VerilatedVpioCb::castp(cb_obj);
_VL_VPI_ERROR_RESET();
VerilatedVpio* vop = VerilatedVpio::castp(cb_obj);
if (VL_UNLIKELY(!vop)) return 0;
if (vop->cb_datap()->reason == cbAfterDelay) {
VerilatedVpiImp::cbTimedRemove(vop);
} else {
VerilatedVpiImp::cbReasonRemove(vop);
}
return 1;
return vop->dovpi_remove_cb();
}
void vpi_get_cb_info(vpiHandle /*object*/, p_cb_data /*cb_data_p*/) { _VL_VPI_UNIMP(); }
@@ -1116,7 +1235,7 @@ vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
if (scopename.find('.') == std::string::npos) {
// This is a toplevel, hence search in our TOP ports first.
scopep = Verilated::scopeFind("TOP");
if (scopep) { varp = scopep->varFind(baseNamep); }
if (scopep) varp = scopep->varFind(baseNamep);
}
if (!varp) {
scopep = Verilated::scopeFind(scopename.c_str());
@@ -1137,8 +1256,11 @@ vpiHandle vpi_handle_by_index(vpiHandle object, PLI_INT32 indx) {
// Used to get array entries
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_handle_by_index %p %d\n", object, indx););
VerilatedVpiImp::assertOneCheck();
VerilatedVpioVar* varop = VerilatedVpioVar::castp(object);
_VL_VPI_ERROR_RESET();
// Memory words are not indexable
VerilatedVpioMemoryWord* vop = VerilatedVpioMemoryWord::castp(object);
if (VL_UNLIKELY(vop)) return nullptr;
VerilatedVpioVar* varop = VerilatedVpioVar::castp(object);
if (VL_LIKELY(varop)) {
if (varop->varp()->dims() < 2) return nullptr;
if (VL_LIKELY(varop->varp()->unpacked().left() >= varop->varp()->unpacked().right())) {
@@ -1249,7 +1371,7 @@ vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle object) {
VerilatedVpiError::strFromVpiMethod(type), vop->fullname(),
vop->varp()->dims());
}
return ((new VerilatedVpioRange(vop->rangep()))->castVpiHandle());
return ((new VerilatedVpioRangeIter(vop->rangep()))->castVpiHandle());
}
case vpiReg: {
VerilatedVpioScope* vop = VerilatedVpioScope::castp(object);
@@ -1990,11 +2112,12 @@ PLI_INT32 vpi_chk_error(p_vpi_error_info error_info_p) {
return _error_info_p->level; // return error severity level
}
#ifndef VL_NO_LEGACY
PLI_INT32 vpi_free_object(vpiHandle object) {
VerilatedVpiImp::assertOneCheck();
_VL_VPI_ERROR_RESET();
return vpi_release_handle(object); // Deprecated
// vpi_free_object is IEEE deprecated, use vpi_release_handle
return vpi_release_handle(object);
}
#endif
PLI_INT32 vpi_release_handle(vpiHandle object) {
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_release_handle %p\n", object););
@@ -2002,7 +2125,6 @@ PLI_INT32 vpi_release_handle(vpiHandle object) {
VerilatedVpio* vop = VerilatedVpio::castp(object);
_VL_VPI_ERROR_RESET();
if (VL_UNLIKELY(!vop)) return 0;
vpi_remove_cb(object); // May not be a callback, but that's ok
VL_DO_DANGLING(delete vop, vop);
return 1;
}
+1 -1
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2021 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.
+29 -16
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2021 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.
@@ -39,6 +39,7 @@
# define VL_ATTR_PRINTF(fmtArgNum) __attribute__((format(printf, (fmtArgNum), (fmtArgNum) + 1)))
# define VL_ATTR_PURE __attribute__((pure))
# define VL_ATTR_UNUSED __attribute__((unused))
# define VL_ATTR_WEAK __attribute__((weak))
# define VL_FUNC __func__
# if defined(__clang__) && defined(VL_THREADED)
# define VL_ACQUIRE(...) __attribute__((acquire_capability(__VA_ARGS__)))
@@ -87,6 +88,9 @@
#ifndef VL_ATTR_UNUSED
# define VL_ATTR_UNUSED ///< Function that may be never used
#endif
#ifndef VL_ATTR_WEAK
# define VL_ATTR_WEAK ///< Function external that is optionally defined
#endif
#ifndef VL_FUNC
# define VL_FUNC "__func__" ///< Name of current function for error macros
#endif
@@ -118,7 +122,7 @@
# define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent
#endif
#ifdef VL_THREADED
#if defined(VL_THREADED) && !defined(VL_CPPCHECK)
# if defined(_MSC_VER) && _MSC_VER >= 1900
# define VL_THREAD_LOCAL thread_local
# elif defined(__GNUC__)
@@ -133,8 +137,10 @@
# define VL_THREAD_LOCAL ///< Use new C++ static local thread
#endif
#define VL_THREAD ///< Deprecated
#define VL_STATIC_OR_THREAD static ///< Deprecated
#ifndef VL_NO_LEGACY
# define VL_THREAD ///< Deprecated
# define VL_STATIC_OR_THREAD static ///< Deprecated
#endif
#define VL_PURE ///< Comment tag that Function is pure (and thus also VL_MT_SAFE)
#define VL_MT_SAFE ///< Comment tag that function is threadsafe when VL_THREADED
@@ -144,7 +150,9 @@
#define VL_MT_UNSAFE_ONE ///< Comment tag that function is not threadsafe when VL_THREADED,
///< protected to make sure single-caller
#define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant (deprecated)
#ifndef VL_NO_LEGACY
# define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant (deprecated)
#endif
// This is not necessarily the same as #UL, depending on what the IData typedef is.
#define VL_UL(c) (static_cast<IData>(c##UL)) ///< Add appropriate suffix to 32-bit constant
@@ -184,16 +192,18 @@
// C++-2011
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(VL_CPPCHECK)
# ifndef VL_NO_LEGACY
// These are deprecated historical defines. We leave them in case users referenced them.
# define VL_EQ_DELETE = delete
# define vl_unique_ptr std::unique_ptr
# define vl_unordered_map std::unordered_map
# define vl_unordered_set std::unordered_set
# define VL_INCLUDE_UNORDERED_MAP <unordered_map>
# define VL_INCLUDE_UNORDERED_SET <unordered_set>
# define VL_FINAL final
# define VL_MUTABLE mutable
# define VL_OVERRIDE override
# define VL_EQ_DELETE = delete
# define vl_unique_ptr std::unique_ptr
# define vl_unordered_map std::unordered_map
# define vl_unordered_set std::unordered_set
# define VL_INCLUDE_UNORDERED_MAP <unordered_map>
# define VL_INCLUDE_UNORDERED_SET <unordered_set>
# define VL_FINAL final
# define VL_MUTABLE mutable
# define VL_OVERRIDE override
# endif
#else
# error "Verilator requires a C++11 or newer compiler"
#endif
@@ -358,12 +368,15 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
#define VL_BYTESIZE 8 ///< Bits in a CData / byte
#define VL_SHORTSIZE 16 ///< Bits in a SData / short
#define VL_IDATASIZE 32 ///< Bits in a IData / word
#define VL_WORDSIZE VL_IDATASIZE ///< Legacy define
#define VL_QUADSIZE 64 ///< Bits in a QData / quadword
#define VL_EDATASIZE 32 ///< Bits in a EData (WData entry)
#define VL_EDATASIZE_LOG2 5 ///< log2(VL_EDATASIZE)
#define VL_CACHE_LINE_BYTES 64 ///< Bytes in a cache line (for alignment)
#ifndef VL_NO_LEGACY
# define VL_WORDSIZE VL_IDATASIZE ///< Legacy define
#endif
/// Bytes this number of bits needs (1 bit=1 byte)
#define VL_BYTES_I(nbits) (((nbits) + (VL_BYTESIZE - 1)) / VL_BYTESIZE)
/// Words/EDatas this number of bits needs (1 bit=1 word)
@@ -450,7 +463,7 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
# define NOMINMAX
# include "Windows.h"
# define VL_CPU_RELAX() YieldProcessor()
# elif defined(__i386__) || defined(__x86_64__)
# elif defined(__i386__) || defined(__x86_64__) || defined(VL_CPPCHECK)
/// For more efficient busy waiting on SMT CPUs, let the processor know
/// we're just waiting so it can let another thread run
# define VL_CPU_RELAX() asm volatile("rep; nop" ::: "memory")
+1 -1
View File
@@ -102,7 +102,7 @@ typedef uint32_t svBitVecVal;
* Because the contents of the unused bits is undetermined,
* the following macros can be handy.
*/
#define SV_MASK(N) (~(-1 << (N)))
#define SV_MASK(N) (~(0xffffffffU << (N)))
#define SV_GET_UNSIGNED_BITS(VALUE, N) \
((N) == 32 ? (VALUE) : ((VALUE) & SV_MASK(N)))
-82
View File
@@ -1,82 +0,0 @@
#!/usr/bin/env perl
######################################################################
#
# Copyright 2007-2020 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
#
######################################################################
# DESCRIPTION: Diff bison files
use warnings;
use Getopt::Long;
use IO::File;
use strict;
our $Debug;
our $Opt_Unsup;
if (! GetOptions (
#"help" => \&usage,
"debug" => sub { $Debug = 1; },
"unsup!" => \$Opt_Unsup, # Ignore unsupported
)) {
die "usage();"
}
diff($ARGV[0],$ARGV[1]);
sub diff {
my $a=shift;
my $b=shift;
my $ta = "/tmp/bisondiff.$$.a";
my $tb = "/tmp/bisondiff.$$.b";
prep($a,$ta);
prep($b,$tb);
system("diff -u -w $ta $tb");
}
sub prep {
my $filename = shift;
my $wfilename = shift;
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename";
my $fho = IO::File->new(">$wfilename") or die "%Error: $! writing $wfilename";
my %declared;
my %used;
my $body = 0;
my $rule = "";
my $skip = 1;
while (defined(my $line = $fh->getline)) {
if ($skip == 1) {
next if $line !~ /%token/;
$skip = 2;
}
if ($Opt_Unsup) {
$line =~ s!//UNSUP!|!g;
$line =~ s!(\s+)\|(\s+)!$1$2!g; # As "UNSUP" often replaces "|"
}
# %type<foo>
$line =~ s/^(%\S+)<(\S+)>/$1/;
# rule<foo>
$line =~ s/^([a-zA-Z0-9_]+)<\S+>:/$1:/;
# Productions
$line =~ s/[ \t]{[^}]*?}/\t{}/g;
$fho->print($line);
}
}
# Local Variables:
# compile-command: "./bisondiff --unsup $VP/Parser/VParseBison.y ../src/verilog.y"
# End:
+356 -456
View File
@@ -1,509 +1,409 @@
#!/usr/bin/env perl
# See copyright, etc in below POD section.
#!/usr/bin/env python3
######################################################################
use warnings;
use Cwd;
use File::Copy qw(cp);
use File::Path qw(mkpath);
use File::Spec;
use FindBin qw($RealBin);
use Getopt::Long;
use Parallel::Forker;
use Unix::Processors;
use IO::File;
use Pod::Usage;
use strict;
use vars qw($Debug);
import argparse
import glob
import multiprocessing
import os
import re
import subprocess
our $Opt_Stop = 1;
our $Opt_Fastcov = 1;
our $Exclude_Branch_Regexp;
our $Exclude_Line_Regexp;
our $Remove_Gcda_Regexp;
RealPath = os.path.dirname(os.path.realpath(__file__))
Exclude_Branch_Regexps = []
Exclude_Line_Regexps = []
Remove_Gcda_Regexps = []
Remove_Sources = []
Source_Globs = []
our @Remove_Sources;
our @Source_Globs;
if 'VERILATOR_ROOT' not in os.environ:
os.environ['VERILATOR_ROOT'] = os.getcwd()
our $Fork = new Parallel::Forker(use_sig_child => 1, poll_interval => 10*1000);
$Fork->max_proc(Unix::Processors->new->max_online * 1.5);
$SIG{CHLD} = sub { Parallel::Forker::sig_child($Fork); };
$SIG{TERM} = sub { $Fork->kill_tree_all('TERM') if $Fork && $Fork->in_parent; die "Quitting...\n"; };
######################################################################
#======================================================================
# main
our $Opt_Hashset;
our $opt_stages = '';
our $Opt_Scenarios;
our %Opt_Stages;
our @Opt_Tests;
def test():
if not os.path.exists("nodist/code_coverage.dat"):
sys.exit("%Error: Run code_coverage from the top of the verilator kit")
exec(open("./nodist/code_coverage.dat").read())
autoflush STDOUT 1;
autoflush STDERR 1;
Getopt::Long::config("no_auto_abbrev");
if (! GetOptions(
"debug" => sub { $Debug = 1; },
"hashset=s" => \$Opt_Hashset, # driver.pl hashset
"<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; },
"fastcov!" => \$Opt_Fastcov, # use fastcov, not documented, for debug
"scenarios=s" => \$Opt_Scenarios, # driver.pl scenarios
"stage=s" => \$opt_stages, # starting stage number
"stages=s" => \$opt_stages, # starting stage number
"stop!" => \$Opt_Stop, # stop/do not stop on error in tests
"test=s@" => \@Opt_Tests, # test name
)) {
die "%Error: Bad usage, try 'code_coverage --help'\n";
}
if Args.stage_enabled[0]:
ci_fold_start("distclean")
print("Stage 0: distclean")
run("make distclean || true")
ci_fold_end()
{
my $start = 0;
my $end = 99;
if ($opt_stages && $opt_stages =~ /^(\d+)$/) {
$start = $end = $1;
} elsif ($opt_stages && $opt_stages =~ /^(\d+)-(\d+$)$/) {
$start = $1; $end = $2;
} elsif ($opt_stages && $opt_stages =~ /^-(\d+$)$/) {
$end = $1;
} elsif ($opt_stages && $opt_stages =~ /^(\d+)-$/) {
$start = $1;
} elsif ($opt_stages) {
die "%Error: --stages not understood: $opt_stages,";
}
for (my $n = $start; $n <= $end; ++$n) { $Opt_Stages{$n} = 1; }
}
test();
exit(0);
#######################################################################
sub test {
-r "nodist/code_coverage.dat" or die "%Error: Run from the top of the verilator kit,";
require "./nodist/code_coverage.dat";
if ($Opt_Stages{1}) {
ci_fold_start("configure");
print "Stage 1: configure (coverage on)\n";
run("make distclean || true");
run("autoconf");
if Args.stage_enabled[1]:
ci_fold_start("configure")
print("Stage 1: configure (coverage on)")
run("autoconf")
# Exceptions can pollute the branch coverage data
run("./configure --enable-longtests CXX='g++ --coverage -fno-exceptions -DVL_GCOV'");
ci_fold_end();
}
run("./configure --enable-longtests CXX='g++ --coverage -fno-exceptions -DVL_GCOV'"
)
ci_fold_end()
if ($Opt_Stages{2}) {
ci_fold_start("build");
print "Stage 2: build\n";
my $nproc = Unix::Processors->new->max_online;
run("make -k -j $nproc VERILATOR_NO_OPT_BUILD=1");
if Args.stage_enabled[2]:
ci_fold_start("build")
print("Stage 2: build")
nproc = multiprocessing.cpu_count()
run("make -k -j " + str(nproc) + " VERILATOR_NO_OPT_BUILD=1")
# The optimized versions will not collect good coverage, overwrite them
run("cp bin/verilator_bin_dbg bin/verilator_bin");
run("cp bin/verilator_coverage_bin_dbg bin/verilator_coverage_bin");
ci_fold_end();
}
run("cp bin/verilator_bin_dbg bin/verilator_bin")
run("cp bin/verilator_coverage_bin_dbg bin/verilator_coverage_bin")
ci_fold_end()
if ($Opt_Stages{3}) {
ci_fold_start("test");
print "Stage 3: make tests (with coverage on)\n";
if ($#Opt_Tests < 0) {
run("make examples VERILATOR_NO_OPT_BUILD=1")
if !$Opt_Scenarios || $Opt_Scenarios =~ /dist/i;
run("make test_regress VERILATOR_NO_OPT_BUILD=1"
. ($Opt_Scenarios ? " SCENARIOS='".$Opt_Scenarios."'" : "")
. ($Opt_Hashset ? " DRIVER_HASHSET='--hashset=".$Opt_Hashset."'" : "")
. ($Opt_Stop ? '' : ' || true'));
} else {
foreach my $test (@Opt_Tests) {
if (! -f $test && -f "test_regress/t/${test}") {
$test = "test_regress/t/${test}";
}
run($test);
}
}
ci_fold_end();
}
if Args.stage_enabled[3]:
ci_fold_start("test")
print("Stage 3: make tests (with coverage on)")
if not Args.tests:
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 "") +
('' 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):
test = "test_regress/t/" + test
run(test)
ci_fold_end()
my $cc_dir = "nodist/obj_dir/coverage";
if ($Opt_Stages{4}) {
ci_fold_start("gcno");
print "Stage 4: Create gcno files under $cc_dir\n";
mkpath($cc_dir);
mkpath("$cc_dir/info");
my $dats = `find . -print | grep .gcda`;
my %dats;
foreach my $dat (split '\n', $dats) {
$dats{$dat} = 1;
}
foreach my $dat (sort keys %dats) {
(my $gcno = $dat) =~ s!\.gcda$!.gcno!;
if ($dat =~ /$Remove_Gcda_Regexp/) {
# Remove .gcda/.gcno for files we don't care about before we slowly
# read them
unlink $dat;
unlink $gcno;
delete $dats{$dat};
next;
}
}
$dats = `find . -print | grep .gcno`;
my %gcnos;
foreach my $gcno (split '\n', $dats) {
(my $gbase = $gcno) =~ s!.*/!!;
$gcnos{$gbase} = File::Spec->rel2abs($gcno);
}
cc_dir = "nodist/obj_dir/coverage"
if Args.stage_enabled[4]:
ci_fold_start("gcno")
print("Stage 4: Create gcno files under " + cc_dir)
os.makedirs(cc_dir, exist_ok=True)
os.makedirs(cc_dir + "/info", exist_ok=True)
sp = subprocess.Popen("find . -print | grep .gcda",
shell=True,
stdout=subprocess.PIPE)
datout = sp.stdout.read()
dats = {}
for dat in datout.splitlines():
dat = dat.decode('utf-8')
dats[dat] = 1
for dat in sorted(dats.keys()):
gcno = re.sub(r'\.gcda$', '.gcno', dat)
for regexp in Remove_Gcda_Regexps:
if re.search(regexp, dat):
# Remove .gcda/.gcno for files we don't care about before we slowly
# read them
unlink_ok(dat)
unlink_ok(gcno)
del dats[dat]
break
sp = subprocess.Popen("find . -print | grep .gcno",
shell=True,
stdout=subprocess.PIPE)
datout = sp.stdout.read()
gcnos = {}
for gcno in datout.splitlines():
gcno = gcno.decode('utf-8')
gbase = re.sub(r'.*/', '', gcno, count=1)
gcnos[gbase] = os.path.abspath(gcno)
# We need a matching .gcno for every .gcda, try to find a matching file elsewhere
foreach my $dat (sort keys %dats) {
(my $gcno = $dat) =~ s!\.gcda$!.gcno!;
(my $gbase = $gcno) =~ s!.*/!!;
if (!-r $gcno) {
if ($gcnos{$gbase}) {
symlink($gcnos{$gbase}, $gcno)
or die "%Error: can't ln -s $gcnos{$gbase} $gcno,";
} else {
warn "MISSING .gcno for a .gcda: $gcno\n";
}
}
}
ci_fold_end();
}
for dat in sorted(dats):
gcno = re.sub(r'\.gcda$', '.gcno', dat)
gbase = re.sub(r'.*/', '', gcno, count=1)
if not os.path.exists(gcno):
if gbase in gcnos:
os.symlink(gcnos[gbase], gcno)
else:
print("MISSING .gcno for a .gcda: " + gcno,
file=sys.stderr)
ci_fold_end()
if ($Opt_Stages{5} && $Opt_Fastcov) {
ci_fold_start("fastcov");
if Args.stage_enabled[5]:
ci_fold_start("fastcov")
# Must run in root directory to find all files
mkpath($cc_dir);
#run("${RealBin}/fastcov.py -b -c src/obj_dbg -X".
# " --exclude /usr --exclude test_regress"
# ." -o ${cc_dir}/app_total.json");
run("${RealBin}/fastcov.py -b -c src/obj_dbg -X --lcov".
" --exclude /usr --exclude test_regress"
." -o ${cc_dir}/app_total.info");
ci_fold_end();
}
os.makedirs(cc_dir, exist_ok=True)
run(RealPath + "/fastcov.py -b -c src/obj_dbg -X --lcov" +
" --exclude /usr --exclude test_regress" + " -o " + cc_dir +
"/app_total.info")
ci_fold_end()
if ($Opt_Stages{5} && !$Opt_Fastcov) {
ci_fold_start("infos");
print "Stage 5: make infos\n";
my $dats = `find . -print | grep .gcda`;
my %dirs;
foreach my $dat (split '\n', $dats) {
(my $dir = $dat) =~ s!/[^/]+$!!;
$dirs{$dir} = 1;
}
foreach my $dir (sort keys %dirs) {
(my $outname = $dir) =~ s![^a-zA-Z0-9]+!_!g;
$Fork->schedule(run_on_start => sub {
# .info may be empty, so ignore errors (unfortunately)
run("cd $cc_dir/info ; lcov -c -d ../../../../$dir --exclude /usr -o app_test_${outname}.info || true");
})->run;
}
$Fork->wait_all;
ci_fold_end();
}
if ($Opt_Stages{6}) {
ci_fold_start("clone");
if Args.stage_enabled[6]:
ci_fold_start("clone")
# No control file to override single lines, so replicate the sources
# Also lets us see the insertion markers in the HTML source res
print "Stage 6: Clone sources under $cc_dir\n";
clone_sources($cc_dir);
ci_fold_end();
}
print("Stage 6: Clone sources under " + cc_dir)
clone_sources(cc_dir)
ci_fold_end()
if ($Opt_Stages{8} && !$Opt_Fastcov) {
ci_fold_start("copy");
print "Stage 8: Copy .gcno files\n";
my $dats = `find . -print | grep .gcno`;
foreach my $dat (sort (split '\n', $dats)) {
next if $dat =~ /$cc_dir/;
my $outdat = $cc_dir."/".$dat;
#print "cp $dat, $outdat);\n";
cp($dat, $outdat);
}
ci_fold_end();
}
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")
ci_fold_end()
if ($Opt_Stages{10} && !$Opt_Fastcov) {
ci_fold_start("combine");
print "Stage 10: Combine data files\n";
{
run("cd $cc_dir ; lcov -c -i -d src/obj_dbg -o app_base.info");
run("cd $cc_dir ; lcov -a app_base.info -o app_total.info");
my $infos = `cd $cc_dir ; find info -print | grep .info`;
my $comb = "";
my @infos = (sort (split /\n/, $infos));
foreach my $info (@infos) {
$comb .= " -a $info";
# Need to batch them to avoid overrunning shell command length limit
if (length($comb) > 10000 || $info eq $infos[$#infos]) {
# .info may be empty, so ignore errors (unfortunately)
run("cd $cc_dir ; lcov -a app_total.info $comb -o app_total.info || true");
$comb = "";
}
}
}
ci_fold_end();
}
if ($Opt_Stages{11}) {
ci_fold_start("dirs");
print "Stage 11: Cleanup paths\n";
if ($Opt_Fastcov) {
cleanup_abs_paths_info($cc_dir, "$cc_dir/app_total.info", "$cc_dir/app_total.info");
#cleanup_abs_paths_json($cc_dir, "$cc_dir/app_total.json", "$cc_dir/app_total.json");
} else {
cleanup_abs_paths_info($cc_dir, "$cc_dir/app_total.info", "$cc_dir/app_total.info");
}
ci_fold_end();
}
if ($Opt_Stages{12}) {
ci_fold_start("filter");
print "Stage 12: Filter processed source files\n";
my $inc = '';
foreach my $glob (@Source_Globs) {
foreach my $infile (glob $glob) {
$inc .= " '$infile'";
}
}
my $exc = '';
foreach my $glob (@Remove_Sources) {
if Args.stage_enabled[12]:
ci_fold_start("filter")
print("Stage 12: Filter processed source files")
inc = ''
for globf in Source_Globs:
for infile in glob.glob(globf):
inc += " '" + infile + "'"
exc = ''
for globf in Remove_Sources:
# Fastcov does exact match not globbing at present
# Lcov requires whole path match so needs the glob
$glob =~ s!^\*!! if $Opt_Fastcov;
$glob =~ s!\*$!! if $Opt_Fastcov;
$exc .= " '$glob'";
}
if ($Opt_Fastcov) {
$inc = "--include ".$inc if $inc ne '';
$exc = "--exclude ".$exc if $exc ne '';
run("cd $cc_dir ; ${RealBin}/fastcov.py -C app_total.info ${inc} ${exc} -x --lcov -o app_total_f.info");
} else {
run("cd $cc_dir ; lcov --remove app_total.info $exc -o app_total_f.info");
}
ci_fold_end();
}
globf = re.sub(r'^\*', '', globf)
globf = re.sub(r'\*$', '', globf)
exc += " '" + globf + "'"
if inc != '':
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")
ci_fold_end()
if ($Opt_Stages{17}) {
ci_fold_start("report");
print "Stage 17: Create HTML\n";
run("cd $cc_dir ; genhtml app_total_f.info --demangle-cpp"
." --rc lcov_branch_coverage=1 --rc genhtml_hi_limit=100 --output-directory html");
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"
)
ci_fold_end()
if ($Opt_Stages{18}) {
ci_fold_start("upload");
print "Stage 18: Upload\n";
my $cmd = "bash <(curl -s https://codecov.io/bash) -f $cc_dir/app_total.info";
print "print: Not running: export CODECOV_TOKEN=<hidden>\n";
print "print: Not running: $cmd\n";
ci_fold_end();
}
if Args.stage_enabled[18]:
ci_fold_start("upload")
print("Stage 18: Upload")
cmd = "bash <(curl -s https://codecov.io/bash) -f " + cc_dir + "/app_total.info"
print("print: Not running: export CODECOV_TOKEN=<hidden>")
print("print: Not running: " + cmd)
ci_fold_end()
if ($Opt_Stages{19}) {
print "*-* All Finished *-*\n";
print "\n";
print "* See report in ${cc_dir}/html/index.html\n";
print "* Remember to make distclean && ./configure before working on non-coverage\n";
}
}
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"
)
sub clone_sources {
my $cc_dir = shift;
my $excluded_lines = 0;
my $excluded_br_lines = 0;
foreach my $glob (@Source_Globs) {
foreach my $infile (glob $glob) {
$infile !~ m!^/!
or die "%Error: source globs should be relative not absolute filenames,";
my $outfile = $cc_dir."/".$infile;
(my $outpath = $outfile) =~ s!/[^/]*$!!;
mkpath($outpath);
my $fh = IO::File->new("<$infile") or die "%Error: $! $infile,";
my $ofh = IO::File->new(">$outfile") or die "%Error: $! $outfile,";
my $lineno = 0;
while (defined(my $line = $fh->getline)) {
$lineno++;
chomp $line;
if ($line =~ /LCOV_EXCL_LINE/) {
$line .= " LCOV_EXCL_BR_LINE";
}
elsif ($line =~ /LCOV_EXCL_START/) {
$line .= " LCOV_EXCL_BR_START";
}
elsif ($line =~ /LCOV_EXCL_STOP/) {
$line .= " LCOV_EXCL_BR_STOP";
}
elsif ($line =~ /$Exclude_Line_Regexp/) {
$line .= " //code_coverage: // LCOV_EXCL_LINE LCOV_EXCL_BR_LINE";
$excluded_lines++;
$excluded_br_lines++;
#print "$infile:$lineno: $line";
}
elsif ($line =~ /$Exclude_Branch_Regexp/) {
$line .= " //code_coverage: // LCOV_EXCL_BR_LINE";
$excluded_br_lines++;
#print "$infile:$lineno: $line";
}
$ofh->print("$line\n");
}
}
}
print "Number of source lines automatically LCOV_EXCL_LINE'ed: $excluded_lines\n";
print "Number of source lines automatically LCOV_EXCL_BR_LINE'ed: $excluded_br_lines\n";
}
sub cleanup_abs_paths_info {
my $cc_dir = shift;
my $infile = shift;
my $outfile = shift;
my $fh = IO::File->new("<$infile") or die "%Error: $! $infile,";
my @lines;
while (defined(my $line = $fh->getline)) {
if ($line =~ m!^SF:!) {
$line =~ s!$ENV{VERILATOR_ROOT}/!!;
$line =~ s!$cc_dir/!!;
$line =~ s!obj_dbg/verilog.y$!verilog.y!;
#print "Remaining SF: ",$line;
}
push @lines, $line;
}
my $ofh = IO::File->new(">$outfile") or die "%Error: $! $outfile,";
$ofh->print(@lines);
}
def clone_sources(cc_dir):
excluded_lines = 0
excluded_br_lines = 0
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)
outfile = cc_dir + "/" + infile
outpath = re.sub(r'/[^/]*$', '', outfile, count=1)
os.makedirs(outpath, exist_ok=True)
with open(infile) as fh:
with open(outfile, "w") as ofh:
lineno = 0
for line in fh:
lineno += 1
line = line.rstrip()
done = False
if re.search(r'LCOV_EXCL_LINE', line):
line += " LCOV_EXCL_BR_LINE"
done = True
elif re.search(r'LCOV_EXCL_START', line):
line += " LCOV_EXCL_BR_START"
done = True
elif re.search(r'LCOV_EXCL_STOP', line):
line += " LCOV_EXCL_BR_STOP"
done = True
sub cleanup_abs_paths_json {
my $cc_dir = shift;
my $infile = shift;
my $outfile = shift;
# Handcrafted cleanup, alternative would be to deserialize/serialize JSON
# But JSON::Parse not installed by default
# JSON::PP more likely to be installed, but slower
my $fh = IO::File->new("<$infile") or die "%Error: $! $infile,";
my @lines;
while (defined(my $line = $fh->getline)) {
$line =~ s!"$ENV{VERILATOR_ROOT}/!"!g;
$line =~ s!"$cc_dir/!"!g;
$line =~ s!obj_dbg/verilog.y$!verilog.y!g;
push @lines, $line;
}
my $ofh = IO::File->new(">$outfile") or die "%Error: $! $outfile,";
$ofh->print(@lines);
}
for regexp in Exclude_Line_Regexps:
if done:
break
if re.search(regexp, line):
#print("%s:%d: %s" % (infile, lineno, line)
line += " //code_coverage: // LCOV_EXCL_LINE LCOV_EXCL_BR_LINE"
excluded_lines += 1
excluded_br_lines += 1
done = True
#######################################################################
for regexp in Exclude_Branch_Regexps:
if done:
break
if re.search(regexp, line):
#print("%s:%d: %s" % (infile, lineno, line)
line += " //code_coverage: // LCOV_EXCL_BR_LINE"
excluded_br_lines += 1
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)
def cleanup_abs_paths_info(cc_dir, infile, outfile):
lines = []
with open(infile) as fh:
for line in fh:
if re.search(r'^SF:', line):
line = re.sub(os.environ['VERILATOR_ROOT'] + '/',
'',
line,
count=1)
line = re.sub(cc_dir + '/', '', line, count=1)
line = re.sub(r'obj_dbg/verilog.y$', 'verilog.y', line)
#print("Remaining SF: "+line)
lines.append(line)
with open(outfile, "w") as ofh:
for line in lines:
ofh.write(line)
def cleanup_abs_paths_json(cc_dir, infile, outfile):
# Handcrafted cleanup, alternative would be to deserialize/serialize JSON,
# but this is much faster
lines = []
with open(infile) as fh:
for line in fh:
line = re.sub('"' + os.environ['VERILATOR_ROOT'] + '/', '"', line)
line = re.sub('"' + cc_dir + '/', '"', line)
line = re.sub(r'obj_dbg/verilog.y$', 'verilog.y', line)
lines.append(line)
with open(outfile, "w") as ofh:
for line in lines:
ofh.write(line)
######################################################################
# .dat file callbacks
sub exclude_branch_regexp {
$Exclude_Branch_Regexp = shift;
}
sub exclude_line_regexp {
$Exclude_Line_Regexp = shift;
}
sub remove_gcda_regexp {
$Remove_Gcda_Regexp = shift;
}
sub remove_source {
my @srcs = @_;
push @Remove_Sources, @srcs;
}
sub source_globs {
my @dirs = @_;
push @Source_Globs, @dirs;
}
def exclude_branch_regexp(*regexps):
Exclude_Branch_Regexps.extend(regexps)
def exclude_line_regexp(*regexps):
Exclude_Line_Regexps.extend(regexps)
def remove_gcda_regexp(*regexps):
Remove_Gcda_Regexps.extend(regexps)
def remove_source(*sources):
Remove_Sources.extend(sources)
def source_globs(*dirs):
Source_Globs.extend(dirs)
#######################################################################
sub run {
# Run a system command, check errors
my $command = shift;
print "\t$command\n";
system "$command";
my $status = $?;
($status == 0) or die "%Error: Command Failed $command, $status, stopped";
}
our $_Ci_Action;
sub ci_fold_start {
$_Ci_Action = shift;
print "travis_fold:start:$_Ci_Action\n";
}
sub ci_fold_end {
print "travis_fold:end:$_Ci_Action\n";
}
def run(command):
# run a system command, check errors
print("\t%s" % command)
status = subprocess.call(command, shell=True)
if status < 0:
raise Exception("%Error: Command failed " + command + ", stopped")
def unlink_ok(filename):
try:
os.unlink(filename)
except OSError:
pass
def ci_fold_start(action):
print("::group::" + action, flush=True)
def ci_fold_end():
print("::endgroup::\n", flush=True)
#######################################################################
__END__
#######################################################################
=pod
=head1 NAME
code_coverage - Build and collect Verilator coverage
=head1 SYNOPSIS
parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawDescriptionHelpFormatter,
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
=head1 DESCRIPTION
code_coverage builds Verilator with C++ coverage support and runs tests
with coverage enabled.
This will rebuild the current object files.
=head1 ARGUMENTS
=over 4
=item --hashset I<hashset>
Pass test hashset onto driver.pl test harness.
=item --help
Displays this message and program version and exits.
=item --scenarios I<scenarios>
Pass test scenarios onto driver.pl test harness.
=item --stages I<stage>
Runs a specific stage or range of stages (see the script).
=item --no-stop
Do not stop collecting data if tests fail.
=item --test I<test_regress_test_name>
Instead of normal regressions, run the specified test. May be specified
multiple times for multiple tests.
=back
=head1 DISTRIBUTION
Copyright 2019-2020 by Wilson Snyder. This program is free software; you
nodist/code_coverage""",
epilog=
"""Copyright 2019-2021 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
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
=head1 AUTHORS
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')
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)')
parser.add_argument(
'--test',
action='append',
dest='tests',
default=[],
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',
help='do not stop collecting data if tests fail')
Wilson Snyder <[email protected]>
parser.set_defaults(stop=True)
Args = parser.parse_args()
=head1 SEE ALSO
if True:
start = 0
end = 99
Args.stage_enabled = {}
if Args.stages:
match_one = re.match(r'^(\d+)$', Args.stages)
match_range = re.match(r'^(\d+)-(\d+)$', Args.stages)
match_to = re.match(r'^-(\d+)$', Args.stages)
match_from = re.match(r'^(\d+)-$', Args.stages)
if match_one:
start = end = int(match_one.group(1))
elif match_range:
start = int(match_range.group(1))
end = int(match_range.group(2))
elif match_to:
end = int(match_to.group(1))
elif match_from:
start = int(match_from.group(1))
else:
os.exit("%Error: --stages not understood: " + Args.stages)
for n in range(0, 100):
Args.stage_enabled[n] = False
for n in range(start, end + 1):
Args.stage_enabled[n] = True
C<lcov>
=cut
test()
######################################################################
### Local Variables:
+43 -44
View File
@@ -1,63 +1,62 @@
# -*- Perl -*-
# -*- Python -*-
# DESCRIPTION: Verilator: Internal C++ code lcov control file
#
# Copyright 2019-2020 by Wilson Snyder. This program is free software; you
# Copyright 2019-2021 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
source_globs("src/*.cpp",
"src/*.h",
"src/*.l",
"src/*.y",
"src/obj_dbg/*.h",
"src/obj_dbg/*.cpp",
"include/*.c",
"include/*.cpp",
"include/*.h",
"include/*/*.h",
"include/*/*.cpp",
"include/*/*.c",
);
source_globs("src/*.cpp")
source_globs("src/*.h")
source_globs("src/*.l")
source_globs("src/*.y")
source_globs("src/obj_dbg/*.h")
source_globs("src/obj_dbg/*.cpp")
source_globs("include/*.c")
source_globs("include/*.cpp")
source_globs("include/*.h")
source_globs("include/*/*.h")
source_globs("include/*/*.cpp")
source_globs("include/*/*.c")
# Note *'s are removed when using fastcov
remove_source("/usr/*");
remove_source("*/include/sysc/*");
remove_source("*/V3ClkGater.cpp");
remove_source("*/V3ClkGater.h");
remove_source("*/V3GraphDfa.cpp");
remove_source("*/V3GraphDfa.h");
remove_source("*/V3Lexer_pregen.yy.cpp");
remove_source("*/V3PreLex_pregen.yy.cpp");
remove_source("*/verilog.c");
remove_source("*include/gtkwave/*");
remove_source("/usr/*")
remove_source("*/include/sysc/*")
remove_source("*/V3ClkGater.cpp")
remove_source("*/V3ClkGater.h")
remove_source("*/V3GraphDfa.cpp")
remove_source("*/V3GraphDfa.h")
remove_source("*/V3Lexer_pregen.yy.cpp")
remove_source("*/V3PreLex_pregen.yy.cpp")
remove_source("*/verilog.c")
remove_source("*include/gtkwave/*")
# Something wrong in generation, unfortunately as would like this
#genhtml: ERROR: cannot read /svaha/wsnyder/SandBox/homecvs/v4/verilator/src/obj_dbg/verilog.y
#remove_source("*/src/obj_dbg/verilog.y");
remove_source("*test_regress/*");
remove_source("*examples/*");
#remove_source("*/src/obj_dbg/verilog.y")
remove_source("*test_regress/*")
remove_source("*examples/*")
# Remove collected coverage on each little test main file
# Would just be removed with remove_source in later step
remove_gcda_regexp(qr!test_regress/.*/(Vt_|Vtop_).*\.gcda!);
remove_gcda_regexp(r'test_regress/.*/(Vt_|Vtop_).*\.gcda')
# Exclude line entirely, also excludes from function and branch coverage
exclude_line_regexp(qr/(\bv3fatalSrc\b
|\bfatalSrc\b
|\bVL_UNCOVERABLE\b
|\bVL_UNREACHABLE\b
|\bVL_FATAL
|\bUASSERT
|\bNUM_ASSERT
|\bERROR_RSVD_WORD
|\bV3ERROR_NA
|\bUINFO\b)/x);
exclude_line_regexp(r'\bv3fatalSrc\b')
exclude_line_regexp(r'\bfatalSrc\b')
exclude_line_regexp(r'\bVL_UNCOVERABLE\b')
exclude_line_regexp(r'\bVL_UNREACHABLE\b')
exclude_line_regexp(r'\bVL_FATAL')
exclude_line_regexp(r'\bUASSERT')
exclude_line_regexp(r'\bNUM_ASSERT')
exclude_line_regexp(r'\bERROR_RSVD_WORD')
exclude_line_regexp(r'\bV3ERROR_NA')
exclude_line_regexp(r'\bUINFO\b')
# Exclude for branch coverage only
exclude_branch_regexp(qr/(\bdebug\(\)
|\bassert\(
|\bBROKEN_RTK\(
|\bSELF_CHECK)/x);
exclude_branch_regexp(r'\bdebug\(\)')
exclude_branch_regexp(r'\bassert\(')
exclude_branch_regexp(r'\bBROKEN_RTK\(')
exclude_branch_regexp(r'\bSELF_CHECK')
1;
True
+92 -147
View File
@@ -1,164 +1,109 @@
#!/usr/bin/env perl
# See copyright, etc in below POD section.
#!/usr/bin/env python3
######################################################################
use warnings;
use Getopt::Long;
use IO::File;
use Pod::Usage;
use Data::Dumper; $Data::Dumper::Indent=1;
use strict;
use vars qw($Debug);
import argparse
import re
#======================================================================
######################################################################
our @Header;
our %Vertexes;
our @Edges;
our %Edges;
Header = []
Vertexes = []
Edges = []
#======================================================================
#######################################################################
def dotread(filename):
with open(filename) as fh:
header = True
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*(.*)$')
for line in fh:
vertex_match = re.search(vertex_re, line)
edge_match = re.search(edge_re, line)
if vertex_match:
if vertex_match.group(1) != 'nTITLE':
header = False
Vertexes.append({
'num': vnum,
'line': line,
'name': vertex_match.group(1)
})
vnum += 1
elif edge_match:
fromv = edge_match.group(1)
tov = edge_match.group(2)
w = re.match(r'weight=(\d+)', line)
weight = w.group(1) if w else 1
w = re.match(r'style=(\S+)', line)
cutable = w.group(1) if w else None
edge = {
'num': vnum,
'line': line,
'weight': weight,
'cutable': cutable,
'from': fromv,
'to': tov
}
vnum += 1
Edges.append(edge)
elif header:
Header.append(line)
print("IGNORE: " + line)
#######################################################################
def cwrite(filename):
with open(filename, "w") as fh:
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("\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("}\n")
######################################################################
# main
$Debug = 0;
my $opt_filename;
autoflush STDOUT 1;
autoflush STDERR 1;
if (! GetOptions(
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
)) {
usage();
}
dotread($opt_filename);
cwrite("graph_export.cpp");
#----------------------------------------------------------------------
sub usage {
pod2usage(-verbose=>2, -exitval=>0, -output=>\*STDOUT);
exit(1); # Unreachable
}
sub debug {
$Debug = 1;
}
sub parameter {
my $param = shift;
if (!$opt_filename) {
$opt_filename = $param;
} else {
die "%Error: Unknown parameter: $param\n";
}
}
#######################################################################
sub dotread {
my $filename = shift;
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
my $header = 1;
my $vnum = 0;
while (defined (my $line = $fh->getline)) {
if ($line =~ /^\t([a-zA-Z0-9_]+)\t(.*)$/) {
next if $1 eq 'nTITLE';
$header = 0;
$Vertexes{$1} = {num => $vnum++,
line => $line,
name => $1,};
}
elsif ($line =~ /^\t([a-zA-Z0-9_]+)\s+->\s+([a-zA-Z0-9_]+)\s+(.*)$/) {
my $from=$1; my $to=$2;
my $weight = 1; $weight = $1 if $line =~ /weight=(\d+)/;
my $cutable = undef; $cutable = $1 if $line =~ /style=(\S+)/;
my $edge = {num => $vnum++,
line => $line,
weight => $weight,
cutable => $cutable,
from => $from,
to => $to,};
push @Edges, $edge;
$Edges{$from}{$to} = $edge;
}
elsif ($header) {
push @Header, $line;
print "IGNORE: $line";
}
}
}
#######################################################################
sub cwrite {
my $filename = shift;
my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,";
$fh->print("void V3GraphTestImport::dotImport() {\n");
$fh->print(" DfaGraph* gp = &m_graph;\n");
foreach my $ver (sort {$a->{num} <=> $b->{num}} (values %Vertexes)) {
$fh->printf(" V3GraphTestVertex* %s = new V3GraphTestVertex(gp, \"%s\"); if (%s) {}\n",
$ver->{name}, $ver->{name}, $ver->{name});
}
$fh->print("\n");
foreach my $edge (@Edges) {
$fh->printf(" new V3GraphEdge(gp, %s, %s, %s, %s);\n",
$edge->{from}, $edge->{to},
$edge->{weight}, $edge->{cutable}?"true":"false");
}
$fh->print("}\n");
}
#######################################################################
__END__
=pod
=head1 NAME
dot_importer - Take graph .dot file and convert into .cpp file
=head1 SYNOPSIS
dot_importer a.dot
=head1 DESCRIPTION
Dot_importer takes a graphvis .dot file and converts into .cpp file. This
.cpp file is then manually included in V3GraphTest.cpp to verify various
sub-algorithms.
=head1 ARGUMENTS
=over 4
=item --help
Displays this message and program version and exits.
=back
=head1 DISTRIBUTION
Copyright 2005-2020 by Wilson Snyder. This program is free software; you
parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawDescriptionHelpFormatter,
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-2021 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
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
=head1 AUTHORS
parser.add_argument('--debug',
action='store_const',
const=9,
help='enable debug')
parser.add_argument('filename', help='input .dot filename to process')
Wilson Snyder <[email protected]>
=head1 SEE ALSO
=cut
Args = parser.parse_args()
dotread(Args.filename)
cwrite("graph_export.cpp")
######################################################################
### Local Variables:
### compile-command: "./dot_importer | tee ~/d/a.dot"
### compile-command: "./dot_importer ../test_regress/obj_vlt/t_EXAMPLE/*orderg_o*.dot && cat graph_export.cpp"
### End:
-205
View File
@@ -1,205 +0,0 @@
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
use warnings;
use Getopt::Long;
use IO::File;
use Pod::Usage;
use Data::Dumper; $Data::Dumper::Indent=1;
use strict;
use vars qw($Debug);
#======================================================================
our @Header;
our %Vertexes;
our %Edges;
our %User;
our %User2;
#======================================================================
# main
$Debug = 0;
my $opt_filename;
my $opt_circle;
autoflush STDOUT 1;
autoflush STDERR 1;
if (! GetOptions(
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
"circle=s" => \$opt_circle,
)) {
usage();
}
dotread($opt_filename);
circle($opt_circle) if $opt_circle;
simplify();
dotwrite();
#----------------------------------------------------------------------
sub usage {
pod2usage(-verbose=>2, -exitval=>0, -output=>\*STDOUT);
exit(1); # Unreachable
}
sub debug {
$Debug = 1;
}
sub parameter {
my $param = shift;
if (!$opt_filename) {
$opt_filename = $param;
} else {
die "%Error: Unknown parameter: $param\n";
}
}
#######################################################################
sub dotread {
my $filename = shift;
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
my $header = 1;
while (defined (my $line = $fh->getline)) {
if ($line =~ /^\t([a-zA-Z0-9_]+)\t(.*)$/) {
$header = 0;
$Vertexes{$1} = $2;
}
elsif ($line =~ /^\t([a-zA-Z0-9_]+)\s+->\s+([a-zA-Z0-9_]+)\s+(.*)$/) {
$Edges{$1}{$2} = $3;
}
elsif ($header) {
push @Header, $line;
}
}
}
######################################################################
sub simplify {
foreach my $ver (sort (keys %Vertexes)) {
$Vertexes{$ver} = _simplify($Vertexes{$ver});
}
foreach my $v1 (sort (keys %Edges)) {
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
$Edges{$v1}{$v2} = _simplify($Edges{$v1}{$v2});
}
}
}
sub _simplify {
my $text = shift;
$text =~ s/__DOT__/./g;
return $text;
}
sub dotwrite {
foreach my $line (@Header) {
print "$line";
}
foreach my $ver (sort (keys %Vertexes)) {
print "\t$ver\t$Vertexes{$ver}\n";
}
foreach my $v1 (sort (keys %Edges)) {
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
print "\t$v1 -> $v2\t$Edges{$v1}{$v2}\n";
}
}
print "}\n";
}
######################################################################
sub circle {
my $node = shift;
%User = ();
%User2 = ();
_circle_recurse($node, 1);
foreach my $ver (keys %Vertexes) {
if (!$User{$ver}) {
delete $Vertexes{$ver};
delete $Edges{$ver};
}
}
foreach my $v1 (sort (keys %Edges)) {
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
if (!$Vertexes{$v2}) { delete $Edges{$v1}{$v2}; }
}
}
}
sub _circle_recurse {
my $node = $_[0];
my $level = $_[1];
$Vertexes{$node} or warn "%Warning: Can't find ref node $node\n";
$User{$node} = 1 if (($User2{$node}||0)==1);
return $User{$node} if $User2{$node};
$User2{$node} = 1;
my $r = 0;
foreach my $v2 (keys %{$Edges{$node}}) {
$r |= _circle_recurse($v2,$level++)||0;
}
$User{$node} = 1 if $r;
$User2{$node} = 2;
return $r;
}
#######################################################################
__END__
=pod
=head1 NAME
dot_pruner -
=head1 SYNOPSIS
dot_pruner *.log
=head1 DESCRIPTION
dd
=head1 ARGUMENTS
=over 4
=item --help
Displays this message and program version and exits.
=back
=head1 DISTRIBUTION
Copyright 2005-2020 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
=head1 AUTHORS
Wilson Snyder <[email protected]>
=head1 SEE ALSO
=cut
######################################################################
### Local Variables:
### compile-command: "./dot_pruner | tee ~/d/a.dot"
### End:
-61
View File
@@ -1,61 +0,0 @@
#!/usr/bin/env perl
######################################################################
#
# Copyright 2007-2020 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
#
######################################################################
# DESCRIPTION: Diff flex files
use warnings;
use IO::File;
use strict;
my $Debug;
diff($ARGV[0],$ARGV[1]);
sub diff {
my $a=shift;
my $b=shift;
my $ta = "/tmp/flexdiff.$$.a";
my $tb = "/tmp/flexdiff.$$.b";
prep($a,$ta);
prep($b,$tb);
system("diff -u -w $ta $tb");
}
sub prep {
my $filename = shift;
my $wfilename = shift;
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename";
my $fho = IO::File->new(">$wfilename") or die "%Error: $! writing $wfilename";
my %declared;
my %used;
my @lines;
while (defined(my $line = $fh->getline)) {
# Productions
#$line =~ s/[ \t]{[^}]*?}/\t{}/g;
$line =~ s/StashPrefix;//g;
$line =~ s/VALTEXT;//g;
$line =~ s/CALLBACK\([^)]*\);//g;
push @lines, $line;
}
#@lines = sort @lines;
$fho->print(@lines);
}
# Local Variables:
# compile-command: "./flexdiff $VP/Parser/VParseLex.l ../src/verilog.l"
# End:
+7 -4
View File
@@ -16,6 +16,7 @@ from glob import glob
from subprocess import getstatusoutput
from argparse import ArgumentParser
def interesting(s):
if 'assert' in s: return 1
if 'Assert' in s: return 1
@@ -33,17 +34,19 @@ def interesting(s):
def main():
p = ArgumentParser()
p.add_argument('--dir',default='out1/queue')
p.add_argument('--dir', default='out1/queue')
args = p.parse_args()
for infile in glob(args.dir+'/*'):
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)
print(output)
if __name__=='__main__':
if __name__ == '__main__':
main()
+25 -18
View File
@@ -15,7 +15,8 @@
from subprocess import getstatusoutput
from os import system
def take_while(f,a):
def take_while(f, a):
# any(a) => (a->bool)->[a]->[a]
# Does the same think as Haskell's takewhile.
out = []
@@ -26,44 +27,50 @@ def take_while(f,a):
return out
return out
def skip_while(f,a):
def skip_while(f, a):
# any(a) => (a->bool)->[a]->[a]
# Basically, the opposite thing from skipwhile
while len(a) and f(a[0]):
a = a[1:]
return a
def print_lines(a):
# printable(a) => [a]->void
for elem in a:
print(elem)
def write_file(filename,contents):
def write_file(filename, contents):
# str->str->void
f = open(filename,'w')
f = open(filename, 'w')
f.write(contents)
def parse_line(s):
# str->maybe str
if len(s)==0: return
part = skip_while(lambda x: x!='"',s)
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))
if len(s) == 0: return
part = skip_while(lambda x: x != '"', s)
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))
def main():
status,output = getstatusoutput('flex -T ../../src/verilog.l')
assert status==0
status, output = getstatusoutput('flex -T ../../src/verilog.l')
assert status == 0
lines = output.splitlines()
lines = take_while(lambda x: 'beginning dump of nfa' not in x,lines)
tokens = set(filter(lambda x: x,map(parse_line,lines)))
lines = take_while(lambda x: 'beginning dump of nfa' not in x, lines)
tokens = set(filter(lambda x: x, map(parse_line, lines)))
dirname = 'dictionary'
r = system('mkdir -p '+dirname)
assert(r==0)
for i,token in enumerate(tokens):
write_file(dirname+'/'+str(i),token)
r = system('mkdir -p ' + dirname)
assert (r == 0)
for i, token in enumerate(tokens):
write_file(dirname + '/' + str(i), token)
if __name__=='__main__':
if __name__ == '__main__':
main()
+111 -182
View File
@@ -1,211 +1,140 @@
#!/usr/bin/env perl
# See copyright, etc in below POD section.
#!/usr/bin/env python3
######################################################################
use warnings;
use Getopt::Long;
use Cwd;
use IO::File;
use Pod::Usage;
use strict;
use vars qw($Debug);
import argparse
import multiprocessing
import os
import shutil
import subprocess
#======================================================================
# main
######################################################################
our $Opt_Stage = 0;
our $Opt_Jobs = calc_jobs();
autoflush STDOUT 1;
autoflush STDERR 1;
Getopt::Long::config("no_auto_abbrev");
if (! GetOptions(
"debug" => sub { $Debug = 1; },
"<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; },
"stage=i" => \$Opt_Stage,
"j=i" => \$Opt_Jobs,
)) {
die "%Error: Bad usage, try 'install_test --help'\n";
}
def test():
if not os.path.exists("nodist/install_test"):
sys.exit("%Error: Run from the top of the verilator kit")
test();
exit(0);
#######################################################################
sub test {
-r "nodist/install_test" or die "%Error: Run from the top of the verilator kit,";
cleanenv();
run("make distclean") if -r "Makefile";
cleanenv()
if os.path.exists("Makefile"):
run("make distclean")
# Try building from a scratch area
my $srcdir = getcwd();
my $blddir = $srcdir."/test_regress/obj_dir/install_test_bld";
my $prefix = $srcdir."/test_regress/obj_dir/install_test_prefix";
my $testdirp= $srcdir."/test_regress/obj_dir/install_test_testp";
my $testdirn= $srcdir."/test_regress/obj_dir/install_test_testn";
srcdir = os.getcwd()
blddir = srcdir + "/test_regress/obj_dir/install_test_bld"
prefix = srcdir + "/test_regress/obj_dir/install_test_prefix"
testdirp = srcdir + "/test_regress/obj_dir/install_test_testp"
testdirn = srcdir + "/test_regress/obj_dir/install_test_testn"
if ($Opt_Stage <= 0) {
run("/bin/rm -rf $blddir");
run("/bin/mkdir -p $blddir");
run("cd $blddir && $srcdir/configure --prefix $prefix");
run("cd $blddir && make -j $Opt_Jobs");
}
if Args.stage <= 0:
print("== stage 0")
run("/bin/rm -rf " + blddir)
run("/bin/mkdir -p " + blddir)
run("cd " + blddir + " && " + srcdir + "/configure --prefix " + prefix)
run("cd " + blddir + " && make -j " + str(calc_jobs()))
# Install it under the prefix
if ($Opt_Stage <= 1) {
run("/bin/rm -rf $prefix");
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/include/verilated.h");
run("test -e $prefix/bin/verilator");
run("test -e $prefix/bin/verilator_bin");
run("test -e $prefix/bin/verilator_bin_dbg");
run("test -e $prefix/bin/verilator_gantt");
run("test -e $prefix/bin/verilator_profcfunc");
}
if Args.stage <= 1:
print("== stage 1")
run("/bin/rm -rf " + prefix)
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/include/verilated.h")
run("test -e " + prefix + "/bin/verilator")
run("test -e " + prefix + "/bin/verilator_bin")
run("test -e " + prefix + "/bin/verilator_bin_dbg")
run("test -e " + prefix + "/bin/verilator_gantt")
run("test -e " + prefix + "/bin/verilator_profcfunc")
# Run a test using just the path
if ($Opt_Stage <= 2) {
my $dir = $testdirp;
run("/bin/rm -rf $dir");
run("/bin/mkdir -p $dir");
my $bin1 = $prefix."/bin";
my $bin2 = $prefix."/share/bin";
write_verilog($dir);
run("cd $dir && PATH=$bin1:$bin2:\$PATH verilator --cc foo.v --exe foo.cpp");
run("cd $dir/obj_dir && PATH=$bin1:$bin2:\$PATH make -f Vfoo.mk");
run("cd $dir && PATH=$bin1:$bin2:\$PATH obj_dir/Vfoo");
}
# run a test using just the path
if Args.stage <= 2:
print("== stage 2")
dir = testdirp
run("/bin/rm -rf " + dir)
run("/bin/mkdir -p " + dir)
path = prefix + "/bin" + ":" + prefix + "/share/bin"
write_verilog(dir)
run("cd " + dir + " && PATH=" + path +
":$PATH verilator --cc top.v --exe sim_main.cpp")
run("cd " + dir + "/obj_dir && PATH=" + path +
":$PATH make -f Vtop.mk")
run("cd " + dir + " && PATH=" + path + ":$PATH obj_dir/Vtop")
# Run a test using exact path to binary
if ($Opt_Stage <= 3) {
my $dir = $testdirn;
run("/bin/rm -rf $dir");
run("/bin/mkdir -p $dir");
write_verilog($dir);
my $bin1 = $prefix."/bin";
my $bin2 = $prefix."/share/bin";
run("cd $dir && $bin1/verilator --cc foo.v --exe foo.cpp");
run("cd $dir/obj_dir && make -f Vfoo.mk");
run("cd $dir/obj_dir && ./Vfoo");
}
# run a test using exact path to binary
if Args.stage <= 3:
print("== stage 3")
dir = testdirn
run("/bin/rm -rf " + dir)
run("/bin/mkdir -p " + dir)
write_verilog(dir)
bin1 = prefix + "/bin"
run("cd " + dir + " && " + bin1 +
"/verilator --cc top.v --exe sim_main.cpp")
run("cd " + dir + "/obj_dir && make -f Vtop.mk")
run("cd " + dir + "/obj_dir && ./Vtop")
if ($Opt_Stage <= 9) {
print "*-* All Finished *-*\n";
}
}
if Args.stage <= 9:
print("*-* All Finished *-*")
sub write_verilog {
my $dir = shift;
IO::File->new(">$dir/foo.v")->print('module t; initial begin $display("HELLO WORLD"); $finish; end endmodule'."\n");
my $fh = IO::File->new(">$dir/foo.cpp");
$fh->print('#include "Vfoo.h"' ,"\n");
$fh->print('unsigned int main_time = 0;' ,"\n");
$fh->print('double sc_time_stamp() {' ,"\n");
$fh->print(' return main_time;' ,"\n");
$fh->print('}' ,"\n");
$fh->print('int main() {' ,"\n");
$fh->print(' Vfoo *top = new Vfoo;' ,"\n");
$fh->print(' while (!Verilated::gotFinish()) {',"\n");
$fh->print(' top->eval();' ,"\n");
$fh->print(' main_time++;' ,"\n");
$fh->print(' }' ,"\n");
$fh->print(' top->final();' ,"\n");
$fh->print('}' ,"\n");
}
sub cleanenv {
foreach my $var (keys %ENV) {
if ($var eq "VERILATOR_ROOT"
|| $var eq "VERILATOR_INCLUDE"
|| $var eq "VERILATOR_NO_OPT_BUILD") {
print "unset $var # Was '$ENV{$var}'\n";
delete $ENV{$var}
}
}
}
def write_verilog(dir):
shutil.copy2("examples/make_hello_c/top.v", dir + "/top.v")
shutil.copy2("examples/make_hello_c/sim_main.cpp", dir + "/sim_main.cpp")
def cleanenv():
for var in os.environ:
if (var == "VERILATOR_ROOT" or var == "VERILATOR_INCLUDE"
or var == "VERILATOR_NO_OPT_BUILD"):
print("unset %s # Was '%s'" % (var, os.environ[var]))
del os.environ[var]
def calc_jobs():
return multiprocessing.cpu_count() + 1
def run(command):
# run a system command, check errors
print("\t%s" % command)
os.system(command)
status = subprocess.call(command, shell=True)
if status < 0:
raise Exception("%Error: Command failed " + command + ", stopped")
#######################################################################
sub calc_jobs {
my $ok = eval "
use Unix::Processors;
return Unix::Processors->new->max_online;
";
$ok && !$@ or return 1;
print "driver.pl: Found $ok cores, using -j ",$ok+1,"\n" if $Debug;
return $ok + 1;
}
sub run {
# Run a system command, check errors
my $command = shift;
print "\t$command\n";
system "$command";
my $status = $?;
($status == 0) or die "%Error: Command Failed $command, $status, stopped";
}
#######################################################################
__END__
=pod
=head1 NAME
install_test - Build and install Verilator several ways
=head1 SYNOPSIS
install_test
=head1 DESCRIPTION
install_test performs several make-and-install iterations to verify the
kit. It isn't part of the normal "make test" due to the number of builds
required.
=head1 ARGUMENTS
=over 4
=item --help
Displays this message and program version and exits.
=item -j I<jobs>
Specify make -j flag. Defaults to number of cores + 1 if Perl's
Unix::Processors is installed, else 1.
=item -stage I<stage>
Runs a specific test stage (see the script).
=back
=head1 DISTRIBUTION
Copyright 2009-2020 by Wilson Snyder. This program is free software; you
parser = argparse.ArgumentParser(
allow_abbrev=False,
formatter_class=argparse.RawDescriptionHelpFormatter,
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-2021 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
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('--stage',
type=int,
default=0,
help='run a specific test stage (see the script)')
=head1 AUTHORS
Wilson Snyder <[email protected]>
=head1 SEE ALSO
=cut
Args = parser.parse_args()
test()
######################################################################
### Local Variables:
### compile-command: "cd .. ; nodist/install_test "
### compile-command: "cd .. ; nodist/install_test"
### End:
-49
View File
@@ -1,49 +0,0 @@
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
use warnings;
use strict;
#======================================================================
# main
eval `modulecmd perl add axiom-athdl`;
exec('atsim', @ARGV);
#######################################################################
__END__
=pod
=head1 NAME
invoke_atsim - Invoke tool under "modules" command
=head1 SYNOPSIS
invoke_atsim {arguments}
=head1 DESCRIPTION
=head1 DISTRIBUTION
Copyright 2005-2020 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
=head1 AUTHORS
Wilson Snyder <[email protected]>
=head1 SEE ALSO
=cut
######################################################################
### Local Variables:
### compile-command: "./invoke_atsim -help"
### End:
-49
View File
@@ -1,49 +0,0 @@
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
use warnings;
use strict;
#======================================================================
# main
eval `modulecmd perl add cds-ius`;
exec('iccr', @ARGV);
#######################################################################
__END__
=pod
=head1 NAME
invoke_iccr - Invoke tool under "modules" command
=head1 SYNOPSIS
invoke_iccr {arguments}
=head1 DESCRIPTION
=head1 DISTRIBUTION
Copyright 2007-2020 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
=head1 AUTHORS
Wilson Snyder <[email protected]>
=head1 SEE ALSO
=cut
######################################################################
### Local Variables:
### compile-command: "./invoke_iccr -help"
### End:
-49
View File
@@ -1,49 +0,0 @@
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
use warnings;
use strict;
#======================================================================
# main
eval `modulecmd perl add cds-ius/latest`;
exec('ncverilog', @ARGV);
#######################################################################
__END__
=pod
=head1 NAME
invoke_ncverilog - Invoke tool under "modules" command
=head1 SYNOPSIS
invoke_ncverilog {arguments}
=head1 DESCRIPTION
=head1 DISTRIBUTION
Copyright 2005-2020 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
=head1 AUTHORS
Wilson Snyder <[email protected]>
=head1 SEE ALSO
=cut
######################################################################
### Local Variables:
### compile-command: "./invoke_ncverilog -help"
### End:
-49
View File
@@ -1,49 +0,0 @@
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
use warnings;
use strict;
#======================================================================
# main
eval `modulecmd perl add synopsys-sim/latest`;
exec('vcs', @ARGV);
#######################################################################
__END__
=pod
=head1 NAME
invoke_vcs - Invoke tool under "modules" command
=head1 SYNOPSIS
invoke_vcs {arguments}
=head1 DESCRIPTION
=head1 DISTRIBUTION
Copyright 2005-2020 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
=head1 AUTHORS
Wilson Snyder <[email protected]>
=head1 SEE ALSO
=cut
######################################################################
### Local Variables:
### compile-command: "./invoke_vcs -help"
### End:
-352
View File
@@ -1,352 +0,0 @@
#!/usr/bin/env perl
# See copyright, etc in below POD section.
######################################################################
use warnings;
use Getopt::Long;
use IO::File;
use Pod::Usage;
use Data::Dumper; $Data::Dumper::Indent=1;
use strict;
use vars qw($Debug);
#======================================================================
our $Tree;
our %OpMap;
gentree();
#======================================================================
# main
$Debug = 0;
my $opt_filename;
autoflush STDOUT 1;
autoflush STDERR 1;
if (! GetOptions(
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
)) {
usage();
}
vread($opt_filename);
#print Dumper($Tree);
vwrite();
print '(query-replace-regexp "(\\([0-9a-z_]+\\))" "\\1" nil nil nil)',"\n";
#----------------------------------------------------------------------
sub usage {
pod2usage(-verbose=>2, -exitval=>0, -output=>\*STDOUT);
exit(1); # Unreachable
}
sub debug {
$Debug = 1;
}
sub parameter {
my $param = shift;
if (!$opt_filename) {
$opt_filename = $param;
} else {
die "%Error: Unknown parameter: $param\n";
}
}
#######################################################################
sub vread {
my $filename = shift;
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
my $lasthier="";
$Tree = {
op => 'NETLIST',
t => [[],[],[],[],[],],
};
my @stack;
$stack[1] = $Tree;
while (defined (my $line = $fh->getline)) {
if ($line =~ /^\s+(\S+):\s+(\S+)\s+0x\S+\s+{(\d+)}\s+w(\d+)\s+(.*)$/) {
my $hier = $1;
my $op = $2;
my $lineno = $3;
my $width = $4;
my $etc = $5;
$etc =~ s/__DOT__/./g;
$etc =~ s/__PVT__//g;
my $self = {
op => $op,
#width => $width,
#lineno => $lineno,
#line => $line,
etc => $etc,
args => [split(/[ \t]+/,$etc)],
t => [[],[],[],[],[],],
};
my @hiers = (1,split(/:/,$hier));
my $depth = $#hiers+1;
my $newchild = $hiers[$#hiers];
#print "DD $depth $newchild $op\n";
push @{$stack[$depth-1]->{t}[$newchild]}, $self;
$stack[$depth] = $self;
$lasthier = $hier;
#print " $lasthier\n";
#print Dumper($Tree);
}
}
}
######################################################################
our $Indent = 0;
use vars qw($Code_Self);
use vars qw($Avoid_Hex);
sub vwrite {
$Indent = 0;
print vwrite_rec($Tree);
}
sub vwrite_rec {
my $self = shift;
#print "/*$self->{op}*/";
my $code = $OpMap{$self->{op}} or die "%Error: No map for $self->{op},";
local $Code_Self = $self;
#print Dumper($self->{t}[3]),"\n";
&$code;
}
######################################################################
# Tree functions
sub p { print join("",@_); }
sub exists1 { return defined $Code_Self->{t}[1][0]; }
sub exists2 { return defined $Code_Self->{t}[2][0]; }
sub exists3 { return defined $Code_Self->{t}[3][0]; }
sub exists4 { return defined $Code_Self->{t}[4][0]; }
sub exists5 { return defined $Code_Self->{t}[5][0]; }
sub t1 { foreach my $r (@{$Code_Self->{t}[1]}) { vwrite_rec($r); } }
sub t2 { foreach my $r (@{$Code_Self->{t}[2]}) { vwrite_rec($r); } }
sub t3 { foreach my $r (@{$Code_Self->{t}[3]}) { vwrite_rec($r); } }
sub t4 { foreach my $r (@{$Code_Self->{t}[4]}) { vwrite_rec($r); } }
sub t5 { foreach my $r (@{$Code_Self->{t}[5]}) { vwrite_rec($r); } }
sub p1 { p "("; t1; p ")";}
sub p2 { p "("; t2; p ")";}
sub p3 { p "("; t3; p ")";}
sub p4 { p "("; t4; p ")";}
sub p5 { p "("; t5; p ")";}
sub a1 { p $Code_Self->{args}[0]; }
sub a2 { p $Code_Self->{args}[1]; }
sub a3 { p $Code_Self->{args}[2]; }
sub a4 { p $Code_Self->{args}[3]; }
sub a5 { p $Code_Self->{args}[4]; }
sub a6 { p $Code_Self->{args}[5]; }
sub a7 { p $Code_Self->{args}[6]; }
sub indentInc { $Indent+=2; }
sub indentDec { $Indent-=2; }
sub nl { p "\n"," "x$Indent; }
######################################################################
# nl is a newline
# p# indicates to add parens
# t# indicates tree reference
# a# indicates info from dump where n1 is the width.
sub gentree {
%OpMap = (
'NULLNODE' => sub { "" },
'NETLIST' => sub { nl;t1;t2;t3;t4;t5; },
'ACTIVE' => sub { p "always_act @(";t1;p ") begin";indentInc;nl;t2;t3;t4;t5;indentDec;p "end";nl; },
'ADD' => sub { p1;p " + ";p2; },
'ALWAYS' => sub { p "always @(";t1;p ") begin";indentInc;nl;t2;t3;t4;t5;indentDec;p "end";nl; },
'ALWAYSPOST' => sub { p "ALWAYSPOST what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'AND' => sub { p1;p " & ";p2; },
'ARRAYSEL' => sub { t1;p "[";t2;p "]"; },
'ASSIGN' => sub { t2;p " = ";t1;p ";";nl; },
'ASSIGNDLY' => sub { t2;p " <= ";t1;p ";";nl; },
'ASSIGNPOST' => sub { p "ASSIGNPOST what{";t1;p " = ";t2;p ";";nl; },
'ASSIGNPRE' => sub { p "ASSIGNPRE what{";t1;p " = ";t2;p ";";nl; },
'ASSIGNW' => sub { p "assign ";t2;p " = ";t1;p ";";nl; },
'ATTROF' => sub { p "ATTROF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'BEGIN' => sub { p "begin";indentInc;nl;t1;t2;t3;t4;t5;indentDec;p "end";nl; },
'BITSEL' => sub { t1;local $Avoid_Hex=1; p "[";t2;p "]"; },
'CASE' => sub { p "CASE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CASEITEM' => sub { p "CASEITEM what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CAST' => sub { p "CAST what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CCALL' => sub { p "CCALL what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CELL' => sub { a1;p " ";a7;p " (/*CELL*/);"; nl; },
'CFUNC' => sub { p "CFUNC what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CHANGEDET' => sub { p "CHANGEDET what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CINCLUDE' => sub { p "CINCLUDE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'COMMENT' => sub { p "//COMMENT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl;nl; },
'CONCAT' => sub { p "{";p1;p ",";p2;p "}"; },
'CONDITIONAL' => sub { p1;p " ? ";p2;p " : ";p3; },
'CONST' => sub { p_const(); },
'COVER' => sub { p "COVER what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CRETURN' => sub { p "CRETURN what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CSTMT' => sub { p "CSTMT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'DEFPARAM' => sub { p "defparam ";p1;p " = ";p2;p ";";nl; },
'DISPLAY' => sub { p '$write("';p1;p "\",";p2;p3;p4;p5;p ");";nl; },
'DIV' => sub { p1;p " / ";p2; },
'EQ' => sub { p1;p " == ";p2; },
'EQCASE' => sub { p1;p " === ";p2; },
'EXTEND' => sub { t1; },
'EXTRACT' => sub { t1;local $Avoid_Hex=1; p "[";t2;p ":";t3;p "]"; },
'FINISH' => sub { p '$finish;';nl },
'FOR' => sub { p "for (";p1;p ",";p2;p ",";p3;p ") begin";indentInc;nl;p4;p5;indentDec;p "end";nl; },
'FUNC' => sub { p "FUNC what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'FUNCREF' => sub { p "FUNCREF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'GT' => sub { p1;p " > ";p2; },
'GTE' => sub { p1;p " >= ";p2; },
'IF' => sub { p "if (";p1;p ") begin";indentInc;nl;t2;indentDec;if (exists3) {p "end else begin";indentInc;nl;t3;indentDec;} p "end"; nl; },
'INITARRAY' => sub { p "INITARRAY what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'INITIAL' => sub { p "initial begin";indentInc;nl;t1;t2;t3;t4;t5;indentDec;p "end";nl; },
'LOGAND' => sub { p1;p " && ";p2; },
'LOGNOT' => sub { p1;p " || ";p2; },
'LOGOR' => sub { p "!";p1; },
'LT' => sub { p1;p " < ";p2; },
'LTE' => sub { p1;p " <= ";p2; },
'MODDIV' => sub { p1;p " % ";p2; },
'MODULE' => sub { p "module ";a1;p " (/*AUTOARG*/);";indentInc;nl;t1;t2;t3;t4;t5;indentDec;nl;p "endmodule";nl; },
'MUL' => sub { p1;p " * ";p2; },
'NEQ' => sub { p1;p " != ";p2; },
'NEQCASE' => sub { p1;p " !== ";p2; },
'NOT' => sub { p " ~";p1; },
'OR' => sub { p1;p " | ";p2; },
'PIN' => sub { p ";p ";p1;p " (";p2;p "),";nl; },
'PORT' => sub { p ""; },
'PRAGMA' => sub { p "PRAGMA what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'RAND' => sub { p '$rand'; },
'RANGE' => sub { t1; local $Avoid_Hex=1; p "[";t2;p ":";t3;p "]"; },
'REDAND' => sub { p "&(";p1;p ")"; },
'REDOR' => sub { p "|(";p1;p ")"; },
'REDXNOR' => sub { p "~|(";p1;p ")"; },
'REDXOR' => sub { p "~^(";p1;p ")"; },
'REPLICATE' => sub { p "{";p1;p "{";p2;p "}}"; },
'SCCTOR' => sub { p "SCCTOR what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'SCHDR' => sub { p "SCHDR what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'SCIMP' => sub { p "SCIMP what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'SCINT' => sub { p "SCINT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'SCOPE' => sub { t1;t2;t3;t4;t5; },
'SENITEM' => sub { a1;p " ";t1; },
'SENTREE' => sub { t1;t2;t3;t4;t5; },
'SHIFTL' => sub { p1;p " << ";p2; },
'SHIFTR' => sub { p1;p " >> ";p2; },
'STOP' => sub { p '$stop;';nl; },
'SUB' => sub { p1;p " - ";p2; },
'TASK' => sub { p "TASK what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'TASKREF' => sub { p "TASKREF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'TEXT' => sub { p "TEXT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'TIME' => sub { p '$time'; },
'TOPSCOPE' => sub { t1;t2;t3;t4;t5; },
'TRACE' => sub { p "TRACE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'UCFUNC' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ")"; },
'UCSTMT' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ");";nl; },
'NEGATE' => sub { p " -";p1; },
'VAR' => sub { p_var(); },
'VARPIN' => sub { p "VARPIN what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'VARREF' => sub { a1; },
'VARSCOPE' => sub { },
'WHILE' => sub { t1; p "while (";t2;p ") begin";indentInc;nl;t3;t4;indentDec;p "end";nl; },
'WORDSEL' => sub { p1;p "[";p2;p ":";p3;p "]"; },
'XNOR' => sub { p1;p " ~^ ";p2; },
'XOR' => sub { p1;p " ^";p2; },
);
}
sub p_var {
my $self = $Code_Self;
if ($self->{etc} =~ /\[I\]/) {
print "input";
} elsif ($self->{etc} =~ /\[O\]/) {
print "output";
} else {
print "reg";
}
p "\t";
{
local $Avoid_Hex=1;
t1;
}
p "\t";
a1;
if (exists2()) {
p " = ";
t2;
}
p ";";
nl;
}
sub p_const {
my $v = $Code_Self->{args}[0];
if ($v =~ /\?32\?h(.*)$/
|| ($Avoid_Hex && $v =~ /^[0-9?]*h(.*)$/)) {
print hex $1;
} else {
print $v;
}
}
#######################################################################
__END__
=pod
=head1 NAME
vtree_importer -
=head1 SYNOPSIS
vtree_importer *.log
=head1 DESCRIPTION
dd
=head1 ARGUMENTS
=over 4
=item --help
Displays this message and program version and exits.
=back
=head1 DISTRIBUTION
Copyright 2005-2020 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
=head1 AUTHORS
Wilson Snyder <[email protected]>
=head1 SEE ALSO
=cut
######################################################################
### Local Variables:
### compile-command: "./vtree_importer "
### End:
+1 -1
View File
@@ -1,6 +1,6 @@
# DESCRIPTION: Verilator: GDB startup file with useful defines
#
# Copyright 2012-2020 by Wilson Snyder. This program is free software; you
# Copyright 2012-2021 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.
+9 -7
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you
# Copyright 2003-2021 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.
@@ -18,7 +18,7 @@
#### Start of system configuration section. ####
srcdir = @srcdir@
PERL = @PERL@
PYTHON3 = @PYTHON3@
EXEEXT = @EXEEXT@
# VPATH only does sources; fix install_test's not creating ../bin
vpath %.h @srcdir@
@@ -52,8 +52,8 @@ obj_dbg:
opt: ../bin/verilator_bin
ifeq ($(VERILATOR_NO_OPT_BUILD),1) # Faster laptop development... One build
../bin/verilator_bin: ../bin/verilator_bin_dbg
-rm -rf $@ $@.exe
-cp -p $<$(EXEEXT) $@$(EXEEXT)
-cp -p $<$(EXEEXT) $@$(EXEEXT).tmp
-mv -f $@$(EXEEXT).tmp $@$(EXEEXT)
else
../bin/verilator_bin: obj_opt ../bin prefiles
$(MAKE) -C obj_opt -j 1 TGT=../$@ -f ../Makefile_obj serial
@@ -78,17 +78,19 @@ endif
prefiles::
prefiles:: config_rev.h
# This output goes into srcdir if locally configured, as we need to distribute it as part of the kit.
config_rev.h: ${srcdir}/config_rev.pl $(GIT_CHANGE_DEP)
$(PERL) ${srcdir}/config_rev.pl ${srcdir} >$@
config_rev.h: ${srcdir}/config_rev $(GIT_CHANGE_DEP)
$(PYTHON3) ${srcdir}/config_rev ${srcdir} >$@
# Human convenience
format:
$(MAKE) -C .. $@
clang-format:
$(MAKE) -C .. $@
maintainer-copy::
clean mostlyclean distclean maintainer-clean::
-rm -rf obj_* *.log *.dmp *.vpd core
-rm -f *.o *.d perlxsi.c *_gen_*
-rm -f *.o *.d *_gen_*
-rm -f *__gen* obj_*
-rm -f .objcache*
+10 -8
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2020 by Wilson Snyder. This program is free software; you
# Copyright 2003-2021 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.
@@ -41,6 +41,7 @@ LINK = @CXX@
LEX = @LEX@
LFLAGS = -d
PERL = @PERL@
PYTHON3 = @PYTHON3@
YACC = @YACC@
OBJCACHE ?= @OBJCACHE@
@@ -138,7 +139,7 @@ make_info:
@echo " Compile flags: " $(CXX) ${CFLAGS} ${CXXFLAGS} ${CPPFLAGS}
clean mostlyclean distclean maintainer-clean::
-rm -f *.o *.d perlxsi.c *_gen_*
-rm -f *.o *.d *_gen_*
-rm -f *__gen*
-rm -f obj_* .objcache*
@@ -228,6 +229,7 @@ RAW_OBJS = \
V3PreShell.o \
V3Premit.o \
V3ProtectLib.o \
V3Randomize.o \
V3Reloop.o \
V3Scope.o \
V3Scoreboard.o \
@@ -286,7 +288,7 @@ V3Number_test: V3Number_test.o
#### Modules
%__gen.cpp: %.cpp $(ASTGEN) V3Ast.h V3AstNodes.h
$(PERL) $(ASTGEN) -I$(srcdir) $*.cpp
$(PYTHON3) $(ASTGEN) -I $(srcdir) $*.cpp
%.o: %.cpp
$(OBJCACHE) ${CXX} ${CXXFLAGS} ${CPPFLAGSWALL} -c $< -o $@
@@ -313,32 +315,32 @@ serial:: V3Ast__gen_classes.h V3ParseBison.c
serial_vlcov:: vlcovgen.d
vlcovgen.d: $(VLCOVGEN) $(srcdir)/../include/verilated_cov_key.h
$(PERL) $(VLCOVGEN) --srcdir $(srcdir)
$(PYTHON3) $(VLCOVGEN) --srcdir $(srcdir)
touch $@
V3Ast__gen_classes.h : $(ASTGEN) V3Ast.h V3AstNodes.h
$(PERL) $(ASTGEN) -I$(srcdir) --classes
$(PYTHON3) $(ASTGEN) -I $(srcdir) --classes
V3ParseBison.h: V3ParseBison.c
# Have only one output file in this rule to prevent parallel make issues
V3ParseBison.c: verilog.y $(BISONPRE)
@echo "If you get errors from verilog.y below, try upgrading bison to version 1.875 or newer."
$(PERL) $(BISONPRE) --yacc ${YACC} -d -v -o V3ParseBison.c $<
$(PYTHON3) $(BISONPRE) --yacc ${YACC} -d -v -o V3ParseBison.c $<
V3Lexer_pregen.yy.cpp: verilog.l V3ParseBison.h $(HEADERS)
${LEX} --version
${LEX} ${LFLAGS} -o$@ $<
V3Lexer.yy.cpp: V3Lexer_pregen.yy.cpp $(FLEXFIX)
$(PERL) $(FLEXFIX) V3Lexer <$< >$@
$(PYTHON3) $(FLEXFIX) V3Lexer <$< >$@
V3PreLex_pregen.yy.cpp: V3PreLex.l $(HEADERS)
${LEX} --version
${LEX} ${LFLAGS} -o$@ $<
V3PreLex.yy.cpp: V3PreLex_pregen.yy.cpp $(FLEXFIX)
$(PERL) $(FLEXFIX) V3PreLex <$< >$@
$(PYTHON3) $(FLEXFIX) V3PreLex <$< >$@
.SUFFIXES:
+206 -5
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you
// Copyright 2003-2021 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.
@@ -35,11 +35,168 @@
#include "V3EmitCBase.h"
#include "V3Const.h"
#include "V3SenTree.h" // for SenTreeSet
#include "V3Graph.h"
#include <unordered_map>
//***** See below for main transformation engine
//######################################################################
// Extend V3GraphVertex class for use in latch detection graph
class LatchDetectGraphVertex final : public V3GraphVertex {
public:
enum VertexType : uint8_t { VT_BLOCK, VT_BRANCH, VT_OUTPUT };
private:
string m_name; // Only used for .dot file generation
VertexType m_type; // Vertex type (BLOCK/BRANCH/OUTPUT)
string typestr() const { // "
switch (m_type) {
case VT_BLOCK: return "(||)"; // basic block node
case VT_BRANCH: return "(&&)"; // if/else branch mode
case VT_OUTPUT: return "(out)"; // var assignment
default: return "??"; // unknown
}
}
public:
LatchDetectGraphVertex(V3Graph* graphp, const string& name, VertexType type = VT_BLOCK)
: V3GraphVertex(graphp)
, m_name(name)
, m_type(type) {}
virtual string name() const { return m_name + " " + typestr(); }
virtual string dotColor() const { return user() ? "green" : "black"; }
virtual int type() const { return m_type; }
};
//######################################################################
// Extend V3Graph class for use as a latch detection graph
class LatchDetectGraph final : public V3Graph {
protected:
typedef std::vector<AstVarRef*> VarRefVec;
LatchDetectGraphVertex* m_curVertexp; // Current latch detection graph vertex
VarRefVec m_outputs; // Vector of lvalues encountered on this pass
VL_DEBUG_FUNC; // Declare debug()
static LatchDetectGraphVertex* castVertexp(void* vertexp) {
return reinterpret_cast<LatchDetectGraphVertex*>(vertexp);
}
// Recursively traverse the graph to determine whether every control 'BLOCK' has an assignment
// to the output we are currently analysing (the output whose 'user() is set), if so return
// true. Where a BLOCK contains a BRANCH, both the if and else sides of the branch must return
// true for the BRANCH to evalute to true. A BLOCK however needs only a single one of its
// siblings to evaluate true in order to evaluate true itself. On output vertex only evaluates
// true if it is the vertex we are analyzing on this check
bool latchCheckInternal(LatchDetectGraphVertex* vertexp) {
bool result = false;
switch (vertexp->type()) {
case LatchDetectGraphVertex::VT_OUTPUT: // Base case
result = vertexp->user();
break;
case LatchDetectGraphVertex::VT_BLOCK: // (OR of potentially many siblings)
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
if (latchCheckInternal(castVertexp(edgep->top()))) {
result = true;
break;
}
}
break;
case LatchDetectGraphVertex::VT_BRANCH: // (AND of both sibling)
// A BRANCH vertex always has exactly 2 siblings
LatchDetectGraphVertex* ifp = castVertexp(vertexp->outBeginp()->top());
LatchDetectGraphVertex* elsp = castVertexp(vertexp->outBeginp()->outNextp()->top());
result = latchCheckInternal(ifp) && latchCheckInternal(elsp);
break;
}
vertexp->user(result);
return result;
}
public:
LatchDetectGraph() { clear(); }
~LatchDetectGraph() { clear(); }
// ACCESSORS
LatchDetectGraphVertex* currentp() { return m_curVertexp; }
void currentp(LatchDetectGraphVertex* vertex) { m_curVertexp = vertex; }
// METHODS
void begin() {
// Start a new if/else tracking graph
// See NODE STATE comment in ActiveLatchCheckVisitor
AstNode::user1ClearTree();
m_curVertexp = new LatchDetectGraphVertex(this, "ROOT");
}
// Clear out userp field of referenced outputs on destruction
// (occurs at the end of each combinational always block)
void clear() {
m_outputs.clear();
// Calling base class clear will unlink & delete all edges & vertices
V3Graph::clear();
m_curVertexp = nullptr;
}
// Add a new control path and connect it to its parent
LatchDetectGraphVertex* addPathVertex(LatchDetectGraphVertex* parent, const string& name,
bool branch = false) {
m_curVertexp = new LatchDetectGraphVertex(this, name,
branch ? LatchDetectGraphVertex::VT_BRANCH
: LatchDetectGraphVertex::VT_BLOCK);
new V3GraphEdge(this, parent, m_curVertexp, 1);
return m_curVertexp;
}
// Add a new output variable vertex and store a pointer to it in the user1 field of the
// variables AstNode
LatchDetectGraphVertex* addOutputVertex(AstVarRef* nodep) {
LatchDetectGraphVertex* outVertexp
= new LatchDetectGraphVertex(this, nodep->name(), LatchDetectGraphVertex::VT_OUTPUT);
nodep->varp()->user1p(outVertexp);
m_outputs.push_back(nodep);
return outVertexp;
}
// Connect an output assignment to its parent control block
void addAssignment(AstVarRef* nodep) {
LatchDetectGraphVertex* outVertexp;
if (!nodep->varp()->user1p()) { // Not seen this output before
outVertexp = addOutputVertex(nodep);
} else
outVertexp = castVertexp(nodep->varp()->user1p());
new V3GraphEdge(this, m_curVertexp, outVertexp, 1);
}
// Run latchCheckInternal on each variable assigned by the always block to see if all control
// paths make an assignment. Detected latches are flagged in the variables AstVar
void latchCheck(AstNode* nodep, bool latch_expected) {
bool latch_detected = false;
for (const auto& vrp : m_outputs) {
LatchDetectGraphVertex* vertp = castVertexp(vrp->varp()->user1p());
vertp->user(true); // Identify the output vertex we are checking paths _to_
if (!latchCheckInternal(castVertexp(verticesBeginp()))) latch_detected = true;
if (latch_detected && !latch_expected) {
nodep->v3warn(
LATCH,
"Latch inferred for signal "
<< vrp->prettyNameQ()
<< " (not all control paths of combinational always assign a value)\n"
<< nodep->warnMore()
<< "... Suggest use of always_latch for intentional latches");
if (debug() >= 9) dumpDotFilePrefixed("latch_" + vrp->name());
}
vertp->user(false); // Clear again (see above)
vrp->varp()->isLatched(latch_detected);
}
// Should _all_ variables assigned in always_latch be latches? Probably, but this only
// warns if none of them are
if (latch_expected && !latch_detected)
nodep->v3warn(NOLATCH, "No latches detected in always_latch block");
}
};
//######################################################################
// Collect existing active names
@@ -135,6 +292,48 @@ public:
void main(AstScope* nodep) { iterate(nodep); }
};
//######################################################################
// Latch checking visitor
class ActiveLatchCheckVisitor final : public ActiveBaseVisitor {
private:
// NODE STATE
// Input:
// AstVar::user1p // V2LatchGraphVertex* The vertex handling this node
AstUser1InUse m_inuser1;
// STATE
LatchDetectGraph m_graph; // Graph used to detect latches in combo always
// VISITORS
virtual void visit(AstVarRef* nodep) {
AstVar* varp = nodep->varp();
if (nodep->access().isWriteOrRW() && varp->isSignal() && !varp->isUsedLoopIdx()) {
m_graph.addAssignment(nodep);
}
}
virtual void visit(AstNodeIf* nodep) {
LatchDetectGraphVertex* parentp = m_graph.currentp();
LatchDetectGraphVertex* branchp = m_graph.addPathVertex(parentp, "BRANCH", true);
m_graph.addPathVertex(branchp, "IF");
iterateAndNextNull(nodep->ifsp());
m_graph.addPathVertex(branchp, "ELSE");
iterateAndNextNull(nodep->elsesp());
m_graph.currentp(parentp);
}
// Empty visitors, speed things up
virtual void visit(AstNodeMath* nodep) {}
//--------------------
virtual void visit(AstNode* nodep) { iterateChildren(nodep); }
public:
// CONSTRUCTORS
ActiveLatchCheckVisitor(AstNode* nodep, VAlwaysKwd kwd) {
m_graph.begin();
iterate(nodep);
m_graph.latchCheck(nodep, kwd == VAlwaysKwd::ALWAYS_LATCH);
}
virtual ~ActiveLatchCheckVisitor() {}
};
//######################################################################
// Active AssignDly replacement functions
@@ -157,11 +356,14 @@ private:
<< "... Suggest blocking assignments (=)");
} else if (m_check == CT_LATCH) {
// Suppress. Shouldn't matter that the interior of the latch races
} else {
} else if (!(VN_IS(nodep->lhsp(), VarRef)
&& VN_CAST(nodep->lhsp(), VarRef)->varp()->isLatched())) {
nodep->v3warn(COMBDLY, "Delayed assignments (<=) in non-clocked"
" (non flop or latch) block\n"
<< nodep->warnMore()
<< "... Suggest blocking assignments (=)");
// Conversely, we could also suggest latches use delayed assignments, as
// recommended by Cliff Cummings?
}
AstNode* newp = new AstAssign(nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
nodep->rhsp()->unlinkFrBack());
@@ -171,10 +373,9 @@ private:
}
virtual void visit(AstAssign* nodep) override {
if (m_check == CT_SEQ) {
AstNode* las = m_assignp;
VL_RESTORER(m_assignp);
m_assignp = nodep;
iterateAndNextNull(nodep->lhsp());
m_assignp = las;
}
}
virtual void visit(AstVarRef* nodep) override {
@@ -284,7 +485,6 @@ private:
m_namer.scopep()->addActivep(m_scopeFinalp);
}
nodep->unlinkFrBack();
m_scopeFinalp->addStmtsp(new AstComment(nodep->fileline(), nodep->typeName(), true));
m_scopeFinalp->addStmtsp(nodep->bodysp()->unlinkFrBackWithNext());
VL_DO_DANGLING(nodep->deleteTree(), nodep);
}
@@ -343,6 +543,7 @@ private:
// Warn and/or convert any delayed assignments
if (combo && !sequent) {
ActiveLatchCheckVisitor latchvisitor(nodep, kwd);
if (kwd == VAlwaysKwd::ALWAYS_LATCH) {
ActiveDlyVisitor dlyvisitor(nodep, ActiveDlyVisitor::CT_LATCH);
} else {
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you
// can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2020 by Wilson Snyder. This program is free software; you
// Copyright 2003-2021 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.

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