Compare commits

...
210 Commits
Author SHA1 Message Date
Wilson Snyder c8e437c45c Version bump 2018-08-22 18:09:06 -04:00
Wilson Snyder 4627716aa4 Remove extra space in generated func call. 2018-08-21 18:14:32 -04:00
Wilson Snyder 847dbbbaf0 Fix function inlining inside certain while loops, bug1330. 2018-08-21 18:09:40 -04:00
Wilson Snyder d90064eaee Change MODDUP errors to warnings, msg2588. 2018-07-23 18:57:34 -04:00
Wilson Snyder 8e646bc55f configure: Add URL 2018-07-22 19:44:03 -04:00
Wilson Snyder 3a777c2a37 Verilated: Always define VL_RDTSC, though unused; useful for benchmarking. 2018-07-22 11:53:35 -04:00
Wilson Snyder 237f4806bf Fix doxygen old dir refs. 2018-07-20 19:45:58 -04:00
Wilson Snyder dfe66a2b77 Fix whitespace after functions in generated files. 2018-07-18 22:42:05 -04:00
Wilson Snyder a0b09b6450 Remove tabs inside generated files/quotes. 2018-07-18 21:25:21 -04:00
Wilson Snyder 9e3a88c41d Inability to write a file is typically user, not internal error. 2018-07-14 19:22:50 -04:00
John Coiner 736bf75a50 tests: Allow cmdline args to override test args. 2018-07-05 18:52:25 -04:00
Wilson Snyder 129610821f Ignore automake flags passed by Ubuntu builds 2018-07-03 21:34:50 -04:00
Wilson Snyder 4cd0310516 Update error, bug1322. 2018-07-02 09:11:20 -04:00
Wilson Snyder 4f962bddd8 Fix std:: build error, bug1322. 2018-06-28 18:55:36 -04:00
Wilson Snyder 45eddfb335 Warn if using pre-C++11 so find out who needs it. 2018-06-26 07:33:55 -04:00
Wilson Snyder d4b9b5aba6 Fix to ignore Unicode UTF-8 BOM sequences, msg2576. 2018-06-26 07:11:56 -04:00
Wilson Snyder b1bf742544 Internals: rank() public for future optimizers. 2018-06-24 18:47:08 -04:00
Wilson Snyder cdd70ff8fc Commentary 2018-06-24 08:08:34 -04:00
Wilson Snyder 2b56acb39a Add git_untabify utility 2018-06-22 07:09:21 -04:00
Wilson Snyder 35a40b4930 Commentary 2018-06-22 06:35:27 -04:00
Wilson Snyder ae33a1ceb1 Tests: Add t_gate_tree test 2018-06-21 20:27:33 -04:00
Wilson Snyder d225e46e4a Fix define argument stringification, broke since 3.914. 2018-06-21 08:19:59 -04:00
John Coiner 43d07235c9 Tests: Fix sc_main compilation errors.
Signed-off-by: Wilson Snyder <[email protected]>
2018-06-20 19:01:19 -04:00
Wilson Snyder 047a08c999 Internals: Clean some UASSERTs. No functional change. 2018-06-16 18:00:21 -04:00
Wilson Snyder 1d74657bbb Internals: Remove dead code 2018-06-16 17:59:57 -04:00
Wilson Snyder 65bb93a6c5 Add OBJCACHE envvar support to examples and generated Makefiles. 2018-06-15 07:13:18 -04:00
Wilson Snyder 6e7f28785e Internals: Cleanup graph includes. No functional change. 2018-06-15 06:54:03 -04:00
Wilson Snyder 0eb1d0a84e Fix cppcheck warnings. No functional change intended. 2018-06-14 18:59:24 -04:00
Wilson Snyder 5d26bca55c Internals: Remove unneeded returns on asserts. 2018-06-13 18:05:00 -04:00
Wilson Snyder a15e6f68dd devel release 2018-06-12 21:22:01 -04:00
Wilson Snyder 77e7e2bf1c Version bump 2018-06-12 21:20:12 -04:00
Wilson Snyder 1c5c9e2435 cppcheck fixes 2018-06-12 21:14:20 -04:00
James Hutchinson f0ed4346b2 Fix to be in verilog 2005, bug1319.
Signed-off-by: Wilson Snyder <[email protected]>
2018-06-08 08:01:22 -04:00
John Coiner 94c8064798 Fix linear search; this is part of the fix for issue 1316. 2018-06-07 12:43:19 -04:00
Wilson Snyder cf0464c263 Internals: Cleanup V3EmitC common code. No functional change. From threads branch. 2018-05-29 19:55:42 -04:00
Wilson Snyder 6268db643c Commentary 2018-05-25 07:17:38 -04:00
Wilson Snyder fd98d231e4 Tests: Fix determinism of randomization. 2018-05-25 07:15:29 -04:00
Wilson Snyder 92649ba494 includes: Fix VL_RDTSC & misc stuff. 2018-05-24 22:17:44 -04:00
Wilson Snyder 0efe343494 Renamed --profile-cfuncs to --prof-cfuncs. 2018-05-20 09:12:29 -04:00
Wilson Snyder 84335b9580 Verilated: Cleanup command line parsing. Backport from pending v4 change. 2018-05-20 08:36:39 -04:00
Wilson Snyder e8b2c57610 Commentary 2018-05-19 14:50:28 -04:00
Wilson Snyder 5e22ca77ec Tests: Fix misc multithreaded issues, merge from threads branch. 2018-05-19 09:30:54 -04:00
Wilson Snyder b6e8133a4d When tracing, use scalars on single bit arrays to appease vcddiff. 2018-05-19 07:52:07 -04:00
Wilson Snyder 02a22c12ea Internals: Add missing [] to delete call in verilated_vcd_c.cpp, bug1309 2018-05-17 07:08:11 -04:00
Wilson Snyder fe917ba7f4 include: Merge misc thread runtime support. 2018-05-13 19:30:51 -04:00
Wilson Snyder 2c568603f6 Fix latex warning & misc Commentary 2018-05-13 19:21:08 -04:00
Wilson Snyder 51422e3ee8 Fix parsing error on bad missing #, bug1308. 2018-05-09 18:32:12 -04:00
Wilson Snyder 0ef3c10931 Pull some thread include changes from thread branch. 2018-05-08 21:43:32 -04:00
Wilson Snyder 35be80f789 Tests: Use vlt_all for any Verilator test. 2018-05-08 19:39:32 -04:00
Wilson Snyder c29e7619eb Tests: Support multiple scenario testing. 2018-05-07 20:42:28 -04:00
Wilson Snyder a265417727 Tests: Cleanup Perl indentations. No functional change. 2018-05-06 22:39:18 -04:00
Wilson Snyder b69af164f7 Commentary 2018-05-06 20:40:23 -04:00
Wilson Snyder ff61bb509c Tests: Fix race and dead code. 2018-05-05 07:44:52 -04:00
Wilson Snyder c8ba51581f Commentary 2018-04-30 20:34:52 -04:00
Wilson Snyder 29f1a9208e Commentary 2018-04-30 20:00:38 -04:00
Wilson Snyder 8b954dc381 Additional debug prints 2018-04-12 22:00:34 -04:00
John Coiner 767ac2547d Misc clang warning fixes.
Signed-off-by: Wilson Snyder <[email protected]>
2018-04-10 22:05:55 -04:00
Wilson Snyder a46aa2d62b Fix verilator_profcfunc on old gprofs. 2018-04-10 22:05:17 -04:00
Todd Strader 9219ddaece Report interface ports connected to wrong interface, bug1294. 2018-04-04 21:03:43 -04:00
Wilson Snyder c7c99d8553 Fix parsing "output signed" in V2K port list, msg2540. 2018-03-29 20:10:27 -04:00
Wilson Snyder e3354a0191 devel release 2018-03-17 12:01:59 -04:00
Wilson Snyder df3d1a4da9 Version bump 2018-03-17 11:56:37 -04:00
Wilson Snyder 3963fe4384 Fix GCC-8 compile error. 2018-03-17 11:33:47 -04:00
Wilson Snyder 38261ac649 Tests: Ignore history file. 2018-03-17 09:25:38 -04:00
Wilson Snyder e49539fb4c Internals: Put cell assigns near cell. No functional change intended except statement order. 2018-03-17 08:43:19 -04:00
Wilson Snyder 3cd96cf558 Tests: Print error line in summary file. 2018-03-16 19:54:25 -04:00
Wilson Snyder 1bcaaa0f0d Internals: Cleanup V3Inst unused argument. No functional change intended. 2018-03-15 23:19:43 -04:00
Wilson Snyder 7922a1de28 Internals: Misc cleanups related to V3LinkDot. No functional change intended. 2018-03-15 19:46:05 -04:00
John Coiner e897c862f2 Tests: t_foreach now checks that all foreach loops get unrolled and evaluated statically. 2018-03-15 19:06:32 -04:00
John Coiner f55040a38b Fix severe runtime performance bug in certain foreach loops. 2018-03-15 08:59:52 -04:00
Wilson Snyder 2d580e6939 Support IEEE 1800-2017 as default language. 2018-03-12 22:26:34 -04:00
John Coiner fc48008c1c Support 2018-03-12 16:44:01 -04:00
Wilson Snyder 4cf2e4024f verilator_difftree: Better error. 2018-03-11 16:49:40 -04:00
Wilson Snyder 57c7d77af3 Tests: Future reduction or test. 2018-03-11 16:33:38 -04:00
Wilson Snyder c8cf2afb15 Support assert properties, bug785, bug1290. 2018-03-11 10:37:20 -04:00
Wilson Snyder 770045676f Internals: Split some extremely long lines. No functional change. 2018-03-10 16:32:04 -05:00
Wilson Snyder 68cca0e114 Commentary, bug1288 2018-03-10 14:16:37 -05:00
Wilson Snyder 0a1b775ed6 Fix various small node leaks. 2018-03-10 14:10:41 -05:00
Wilson Snyder 54a101acbe Internals: Fix -DLEAK_CHECKS failing due to visitor destructor being too late. 2018-03-10 12:57:50 -05:00
John Coiner db1af07d72 On convergence errors, show activity. 2018-03-10 12:52:11 -05:00
John Coiner ff82f75023 Add --no-debug-leak to reduce memory use under debug. 2018-03-10 12:18:19 -05:00
Wilson Snyder 9ae54786e4 Commentary, bug1288. 2018-03-09 00:04:00 -05:00
Wilson Snyder 22ff760f0b Support calling system functions as tasks, bug1285. 2018-03-08 23:40:19 -05:00
John Coiner 86fe6ac3a8 Fix quoting of quoted arguments.
Signed-off-by: Wilson Snyder <[email protected]>
2018-03-08 22:43:29 -05:00
Tymoteusz Blazejczyk 9f52e23158 Fix verilator_coverage --annotate-min, bug1284. 2018-03-07 19:52:29 -05:00
Wilson Snyder e1410775fb Fix CC warning with flex 2.5.35. 2018-02-28 06:34:03 -05:00
John Coiner a7a790416e Internals: Fix passing bool as int. No functional change.
Signed-off-by: Wilson Snyder <[email protected]>
2018-02-27 07:16:16 -05:00
Patrick Stewart fe5c4df079 Support trig functions (() etc), bug1281.
Signed-off-by: Wilson Snyder <[email protected]>
2018-02-26 04:25:07 -05:00
Wilson Snyder 1376e5de92 Fix pullup/pulldowns on bit selects, bug1274. 2018-02-10 19:08:07 -05:00
Wilson Snyder 7f5b1a402c Internals: Part of last change, spacing. 2018-02-07 20:29:58 -05:00
Wilson Snyder 22573d238b Internals: Fix GCC8 cppcheck warnings. No functional change. 2018-02-07 20:16:53 -05:00
Wilson Snyder 32859d9fc2 Fix GCC 8.0 issues 2018-02-07 18:58:21 -05:00
Wilson Snyder 1b12800b8f devel release 2018-02-01 20:14:40 -05:00
Wilson Snyder 13d11b037a Version bump 2018-02-01 20:09:58 -05:00
Wilson Snyder 0ca0854cac Fix compile error with --public and interface bind, bug1264. 2018-02-01 20:07:46 -05:00
Wilson Snyder 1726c71649 Commentary 2018-02-01 19:20:08 -05:00
Wilson Snyder fd8c29f981 Commentary 2018-02-01 19:18:00 -05:00
Wilson Snyder e07ee559a0 Tests: Fix gcc7.2 warnings. 2018-01-31 19:27:42 -05:00
Wilson Snyder 097107bd0b Support 'assume' similar to 'assert', bug1269. 2018-01-31 07:33:10 -05:00
Wilson Snyder b40b152b87 Fix missing edge type in xml output, msg2480. 2018-01-31 07:29:14 -05:00
Wilson Snyder 3c7fef68c0 Internals: Sort EmitXml visitors. No functional change. 2018-01-31 07:25:10 -05:00
Wilson Snyder b2322ae873 Fix tracing example file output, bug1268. 2018-01-29 19:07:49 -05:00
Wilson Snyder e3f137875b Fix spacing of trace func decls. No functional change. 2018-01-29 19:04:37 -05:00
Wilson Snyder 71fcf45d73 Fix gate optimization out of memory, add --gate-stmts, bug1260. 2018-01-27 15:06:51 -05:00
Wilson Snyder 652b68a5a0 Fix compile error on public real parameters by suppressing, bug1261. 2018-01-24 22:30:30 -05:00
John Coiner 3e0401de1c Misc harmless cleanups from thread branch.
Signed-off-by: Wilson Snyder <[email protected]>
2018-01-24 20:20:26 -05:00
Stefan Wallentowitz c164024f38 Remove c++filt and fix status code of Makefile, bug1265
In the generated Makefile the linker output is piped through c++filt
which was very useful for older linkers. But unfortunately the status
code is lost during the piping. So when the make process is embedded
in a larger setup a failure will not manifest to the outside flow.

As modern linkers do the job of c++filt, this removes it from the
generated Makefile. It will also produce a proper status code then.

Signed-off-by: Wilson Snyder <[email protected]>
2018-01-18 21:25:43 -05:00
Wilson Snyder bd1f1e8699 Fix compile error on public real parameters by suppressing, bug1261. 2018-01-16 19:53:50 -05:00
Wilson Snyder 7ee6efab74 devel release 2018-01-02 18:13:45 -05:00
Wilson Snyder 3788e90644 Version bump 2018-01-02 18:06:05 -05:00
Wilson Snyder 8e65d93d6d Copyright year update. No functional change. 2018-01-02 18:05:06 -05:00
Wilson Snyder 4901668f13 Add INFINITELOOP warning, bug1254. 2017-12-26 21:35:08 -05:00
Wilson Snyder f98940e40a Fix cppcheck warnings. No functional change. 2017-12-17 18:44:35 -05:00
Wilson Snyder 49fe4d081c Support DPI open arrays, bug909, bug1245. 2017-12-17 16:28:58 -05:00
Wilson Snyder 3054b36a8d Internals: Avoid cleaning arrays in prep for openarrays. 2017-12-17 12:53:22 -05:00
Wilson Snyder b888158907 Fix DPI svGetBitselLogic and svPutPartselLogic. 2017-12-17 12:19:40 -05:00
Tymoteusz Blazejczyk 173f71dca6 Fix SystemC 2.3.2 compile error, bug1251.
Signed-off-by: Wilson Snyder <[email protected]>
2017-12-17 08:23:22 -05:00
Wilson Snyder 37a931feb4 Internals: Refactor some V3Task code in prep for openarrays. No functional change intended. 2017-12-16 15:46:21 -05:00
Wilson Snyder 79f5c7fbda Internals: Split verilated_syms.h and rename some methods. No functional change intended. 2017-12-16 10:52:43 -05:00
Wilson Snyder bf3f111ca4 Internals: Move VLVF flags to common function. No functional change. 2017-12-16 10:07:15 -05:00
Wilson Snyder 9a2a5d3155 Internals: Unroll V3Width task processing, in prep for openarrays. No functional change intended. 2017-12-16 09:36:07 -05:00
Wilson Snyder 2a7c61cd6d Commentary 2017-12-16 09:35:28 -05:00
Wilson Snyder 51787d68b9 Add error if always_comb has sensitivity list. 2017-12-13 19:49:37 -05:00
Wilson Snyder 33eb0db6f8 Fix resolving inline nested interface names, bug1250. 2017-12-13 19:42:49 -05:00
Wilson Snyder a0b2727c59 Use power-of-two number of members to align structs 2017-12-11 19:16:49 -05:00
Wilson Snyder d1b8f53711 Support DPI time and svLogicVal.
Note older version incorrectly assumed svBitVal even for logicals.
2017-12-09 20:17:37 -05:00
Wilson Snyder 27b5bfe9b1 DPI: Implement IEEE DPI copy routines. 2017-12-09 17:05:32 -05:00
Wilson Snyder ea91b10086 Internals: Add charIQWN. Proper capitalization. 2017-12-09 14:44:55 -05:00
Wilson Snyder 08da777b33 Tests: Fix illegal dpi return types, and other cleanups 2017-12-09 14:44:25 -05:00
Wilson Snyder 345657ab32 Workaround GCC/clang bug with huge compile times, bug1248. 2017-12-09 11:52:35 -05:00
Wilson Snyder 1b605ade94 Tests: Fix internal run scripts 2017-12-08 19:40:16 -05:00
Wilson Snyder b11fa372b1 Fix constant propagation across DPI imports of inout strings. 2017-12-07 20:10:27 -05:00
Wilson Snyder 662ebece71 Support string len() method. 2017-12-07 19:57:11 -05:00
Wilson Snyder 6b6e8dc83e Use VL_UNCOPYABLE in emitted code. No functional change intended. 2017-12-06 23:26:27 -05:00
Wilson Snyder d215149c7c Fix false ALWCOMBORDER on interface references, bug1247. 2017-12-06 21:29:10 -05:00
Wilson Snyder 895fc0911a Support > 64 bit decimal $display. 2017-12-02 22:10:58 -05:00
Wilson Snyder 754527edfd verilated internals: Add VL_BITRSHIFT_W. No functional change. 2017-12-02 08:17:20 -05:00
John Coiner f0217edef1 Internals: Keep a ptr to _eval in AstNetlist, make it easier to find.
Signed-off-by: Wilson Snyder <[email protected]>
2017-11-30 18:53:57 -05:00
Wilson Snyder 8f1798cc6f Fix modport outputs being treated as inputs, bug1246. 2017-11-28 19:11:41 -05:00
John Coiner 631bda395d Avoid duplicated scans of CFuncs.
Trace into non-entry-point functions (most of them) at their call
sites. We'll trace into entry-point functions (like eval) from their parent
scope. We must trace eval_ to reach the tree of calls beneath it.

Signed-off-by: Wilson Snyder <[email protected]>
2017-11-28 18:38:19 -05:00
John Coiner 791d02a753 Internals: Remove dead code. No functional change.
Signed-off-by: Wilson Snyder <[email protected]>
2017-11-28 18:29:14 -05:00
Wilson Snyder 54b3f92951 Commentary 2017-11-28 18:21:43 -05:00
Wilson Snyder 45de0599d7 Commentary 2017-11-27 20:11:34 -05:00
John Coiner 331ecdc2e7 Commentary
Signed-off-by: Wilson Snyder <[email protected]>
2017-11-27 19:23:55 -05:00
Wilson Snyder 339a7640a8 devel release 2017-11-27 18:50:14 -05:00
Wilson Snyder 0478dbdd1f Version bump 2017-11-25 15:42:11 -05:00
Wilson Snyder 38b0e8a777 Fix some clang-analyzer warnings 2017-11-25 15:41:49 -05:00
Wilson Snyder fe9f1add6f examples: Fix wide signal overflow, and stop on errors. 2017-11-25 15:14:31 -05:00
Wilson Snyder ae9179f412 Fix partial slicing with pattern assignments, bug991. 2017-11-23 14:55:32 -05:00
Wilson Snyder 4c35a76cdb Tests: bug795 2017-11-23 11:38:09 -05:00
Wilson Snyder 8ca3428fb6 Tests: Add split tests, towards bug1244 2017-11-23 11:30:35 -05:00
Wilson Snyder 7369500bb7 Fix cppcheck warnings 2017-11-23 10:43:34 -05:00
Wilson Snyder 45702e319b Support $size/$bits/etc on type references. 2017-11-23 10:17:56 -05:00
Wilson Snyder 813468bfe6 Work around bison 3.0 bug printing wrong debug token names 2017-11-23 09:50:15 -05:00
Wilson Snyder 78192308e1 Tests: Favor make -C over cd+make. No functional change. 2017-11-23 08:56:13 -05:00
John Coiner cb72390b57 Internals: Remove dead loop-related code in V3Order.cpp and V3OrderGraph.h
Signed-off-by: Wilson Snyder <[email protected]>
2017-11-23 08:26:36 -05:00
John Coiner 71b2eeef67 Internals: V3GenClk should scan CFunc internals only at the CCall
Signed-off-by: Wilson Snyder <[email protected]>
2017-11-23 08:21:20 -05:00
Wilson Snyder 57c8590b21 When resolving module names, only use defines if no other choice. 2017-11-22 18:44:19 -05:00
Wilson Snyder f8ad0a0923 Fix false DECLFILENAME on recursive modules. 2017-11-21 22:01:28 -05:00
Wilson Snyder 7c443ab108 Fix error on "unique case" with no cases. 2017-11-21 21:52:37 -05:00
Wilson Snyder 0d645757e7 Less debug verbosity 2017-11-21 21:52:22 -05:00
Wilson Snyder dd37c2ea86 Support $error/$warning in elaboration time blocks. 2017-11-21 21:10:42 -05:00
Wilson Snyder d3032bfc21 Fix flex warning. 2017-11-21 21:10:14 -05:00
Wilson Snyder bd6ecdfa6f Fix mis-showing debug message. 2017-11-21 20:04:29 -05:00
Wilson Snyder 3558e70722 Commentary 2017-11-18 17:52:06 -05:00
Wilson Snyder a579e9273b Support self-recursive modules, bug659. 2017-11-18 17:42:35 -05:00
Wilson Snyder 21369bec95 Internals: Renames in prep for recursion. No functional change. 2017-11-18 17:40:10 -05:00
Wilson Snyder d119d10569 Add BSSPACE and COLONPLUS lint warnings. 2017-11-15 20:19:12 -05:00
Wilson Snyder 38988c005c Fix false unused warning on interfaces, bug1241. 2017-11-14 20:10:25 -05:00
Wilson Snyder 8cc4b588b2 Add error when driving input-only modport. 2017-11-14 19:50:31 -05:00
Wilson Snyder 12607abb33 Remove tabs from --xml output. 2017-11-13 18:24:18 -05:00
Wilson Snyder 562f17ea4b Fix xml tags on typedefs. 2017-11-13 18:04:13 -05:00
Wilson Snyder 0aea9b7709 Update references to coverage.dat, msg2412. 2017-11-13 07:20:36 -05:00
Wilson Snyder c0afe96b80 Fix addition of data types to --xml. 2017-11-09 18:04:16 -05:00
John Coiner 5c919cd0de Fix null dereference crash in width process.
Signed-off-by: Wilson Snyder <[email protected]>
2017-11-09 07:43:30 -05:00
Wilson Snyder f555c93c11 Add data types to --xml. 2017-11-08 21:27:15 -05:00
Wilson Snyder cbb7cd16d0 Detect MSB overflow when under VL_DEBUG, bug1238. 2017-11-05 21:47:55 -05:00
Wilson Snyder 4d074b5414 Commentary 2017-11-05 13:05:50 -05:00
Wilson Snyder dfd22b2b07 Examples: Add +trace flag at runtime 2017-11-05 06:51:29 -05:00
John Coiner 6edaef9598 Internals: Fix debugging with null logicp() graphs.
Signed-off-by: Wilson Snyder <[email protected]>
2017-11-04 18:12:29 -04:00
John Coiner f63e946f04 Internals: Add consts. No functional change.
Signed-off-by: Wilson Snyder <[email protected]>
2017-11-02 18:02:11 -04:00
Wilson Snyder add5cc8b56 Internals: Add VL_UNCOPYABLE to make classes uncopyable. No functional change intended. 2017-11-01 18:51:41 -04:00
John Coiner 2a4e830bee Tests: Fix over sensitive line number.
Signed-off-by: Wilson Snyder <[email protected]>
2017-10-31 21:22:35 -04:00
Wilson Snyder eb87232472 Fix stats critical fast path calculation. 2017-10-30 22:38:47 -04:00
Wilson Snyder 52c3031a82 Internals: Rename selfTest, no functional change. 2017-10-30 19:01:58 -04:00
John Coiner df471e87eb Internals: Break unnecessary dependencies in V3Order.
Signed-off-by: Wilson Snyder <[email protected]>
2017-10-28 13:31:04 -04:00
Wilson Snyder ec6fae5d1a Internals: Add const to same() methods. No functional change. 2017-10-28 10:26:34 -04:00
Wilson Snyder cb422a9a02 Internals: Number astgen from 1 as 0p looks like Op. No functional change. 2017-10-28 08:48:24 -04:00
Wilson Snyder f91bac7b31 Rewrite include libraries to support VL_THREADED towards future threading 2017-10-26 21:51:51 -04:00
Wilson Snyder d542921ff7 Tests: Detect old GCC and skip unsupported tests. 2017-10-26 21:48:45 -04:00
Wilson Snyder ad693d67b2 Mark Verilated functions with multithreaded status. No functional change. 2017-10-26 20:05:42 -04:00
Wilson Snyder 350932e9c0 Fix false failure on clang 3.8 2017-10-26 19:14:05 -04:00
John Coiner 4e98d96755 Internals: Add const's. No functional change intended.
Signed-off-by: Wilson Snyder <[email protected]>
2017-10-26 18:42:50 -04:00
Wilson Snyder c17a9eb5f1 Tests: Fix driver when VERILATOR_ROOT not set. 2017-10-26 07:34:02 -04:00
Wilson Snyder 252ed4c1ae Fix clang warning 2017-10-26 07:27:47 -04:00
Wilson Snyder f9fd634fae Internals: Fix VL_DBG_MSGF va_list corruption in last commit. 2017-10-25 23:01:45 -04:00
Wilson Snyder c17c81254e Internals: Use = delete via a macro for a bit of C++11 forward compatibility 2017-10-25 20:00:38 -04:00
Wilson Snyder 5ead61dc7b Unify format of VL_DEBUG print messages 2017-10-24 22:56:58 -04:00
Wilson Snyder e403db5877 tests: Simplify includes; HARNESS_UPDATE_GOLDEN to whitespace fix 2017-10-24 19:58:52 -04:00
Wilson Snyder 32874fa848 Internals: Misc VCD code cleanups. No functional change. 2017-10-21 17:53:23 -04:00
Wilson Snyder b90f383cfe Add --threads option through to makefiles, unadvertised for now. 2017-10-21 16:41:43 -04:00
Wilson Snyder eb65984368 Tests: Additional display merge tests. No functional change. 2017-10-21 13:50:31 -04:00
Wilson Snyder 10e0d34140 Refactor verilated_vpi.h to move most code to .cpp. No functional change intended. 2017-10-19 21:33:22 -04:00
Wilson Snyder f4b00d3c64 Call VL_PRINTF/vl_stop/vl_finish/vl_fatal through wrappers as hook for future MT use. 2017-10-19 19:40:51 -04:00
Wilson Snyder cc0b780412 Internals: More use of unordered_map/set. No functional change intended. 2017-10-18 18:22:58 -04:00
Wilson Snyder fbbbe4ec87 Commentary 2017-10-18 17:54:39 -04:00
Wilson Snyder 1372d62186 Remove duplicate class forward declarations. 2017-10-18 17:38:10 -04:00
Ahmed El-Mahmoudy a69936de74 Spelling fixes
Signed-off-by: Wilson Snyder <[email protected]>
2017-10-16 21:58:47 -04:00
Wilson Snyder f5dfa1e9c3 Fix MacOS portability, bug1232. 2017-10-15 10:36:50 -04:00
Wilson Snyder 5fb21c2159 devel release 2017-10-14 20:47:25 -04:00
1304 changed files with 25294 additions and 7892 deletions
+1
View File
@@ -23,6 +23,7 @@ dddrun*
doxygen-doc
gdbrun*
gmon.out
ncverilog.history
internals.txt
verilator.txt
verilator_bin*
+134 -2
View File
@@ -2,6 +2,138 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 3.926 2018-08-22
**** Add OBJCACHE envvar support to examples and generated Makefiles.
**** Change MODDUP errors to warnings, msg2588. [Marshal Qiao]
**** Fix define argument stringification (`"), broke since 3.914. [Joe DErrico]
**** Fix to ignore Unicode UTF-8 BOM sequences, msg2576. [HyungKi Jeong]
**** Fix std:: build error, bug1322.
**** Fix function inlining inside certain while loops, bug1330. [Julien Margetts]
* Verilator 3.924 2018-06-12
*** Renamed --profile-cfuncs to --prof-cfuncs.
**** Report interface ports connected to wrong interface, bug1294. [Todd Strader]
**** When tracing, use scalars on single bit arrays to appease vcddiff.
**** Fix parsing "output signed" in V2K port list, msg2540. [James Jung]
**** Fix parsing error on bad missing #, bug1308. [Dan Kirkham]
**** Fix $clog2 to be in verilog 2005, bug1319. [James Hutchinson]
* Verilator 3.922 2018-03-17
** Support IEEE 1800-2017 as default language.
*** Support trig functions ($sin() etc), bug1281. [Patrick Stewart]
*** Support calling system functions as tasks, bug1285. [Joel Holdsworth]
*** Support assert properties, bug785, bug1290. [John Coiner, et al]
*** Support $writememh. [John Coiner]
*** Add --no-debug-leak to reduce memory use under debug. [John Coiner]
**** Fix severe runtime performance bug in certain foreach loops. [John Coiner]
**** On convergence errors, show activity. [John Coiner]
**** Fix GCC 8.0 issues, bug1273.
**** Fix pullup/pulldowns on bit selects, bug1274. [Rob Stoddard]
**** Fix verilator_coverage --annotate-min, bug1284. [Tymoteusz Blazejczyk]
**** Fix quoting of quoted arguments. [John Coiner]
* Verilator 3.920 2018-02-01
** Moving forward, use the git "stable" branch to track the latest release,
and git "v#.###" tags for specific releases.
*** Support 'assume' similar to 'assert', bug1269. [Dan Gisselquist]
**** Fix tracing example file output, bug1268. [Enzo Chi]
**** Fix gate optimization out of memory, add --gate-stmts, bug1260. [Alex Solomatnikov]
**** Fix compile error on public real parameters by suppressing, bug1261. [Alex Solomatnikov]
**** Fix input-only tristate comparisons, bug1267. [Alexis G]
**** Fix missing edge type in xml output, msg2480. [Alexis G]
**** Fix compile error with --public and interface bind, bug1264. [Alexis G]
**** Remove c++filt, bug1265. [Stefan Wallentowitz]
* Verilator 3.918 2018-01-02
*** Workaround GCC/clang bug with huge compile times, bug1248.
*** Support DPI open arrays, bug909, bug1245. [David Pierce, Victor Besyakov]
*** Add INFINITELOOP warning, bug1254. [Alex Solomatnikov]
**** Support > 64 bit decimal $display.
**** Support DPI time and svLogicVal. [Victor Besyakov]
Note older version incorrectly assumed svBitVal even for logicals.
**** Support string len() method. [Victor Besyakov]
**** Add error if always_comb has sensitivity list. [Arjen Roodselaar]
**** Fix SystemC 2.3.2 compile error, bug1251. [Tymoteusz Blazejczyk]
**** Fix modport outputs being treated as inputs, bug1246. [Jeff Bush]
**** Fix false ALWCOMBORDER on interface references, bug1247. [Josh Redford]
**** Fix constant propagation across DPI imports of inout strings. [Victor Besyakov]
**** Fix resolving inline nested interface names, bug1250. [Arjen Roodselaar]
* Verilator 3.916 2017-11-25
*** Support self-recursive modules, bug659. [Sean Moore, et al]
*** Support $error/$warning in elaboration time blocks.
*** Support $size/$bits/etc on type references.
*** Add error when driving input-only modport, bug1110. [Trevor Elbourne]
*** Add BSSPACE and COLONPLUS lint warnings.
**** Detect MSB overflow when under VL_DEBUG, bug1238. [Junyi Xi]
**** Add data types to --xml. [Rui Terra]
**** Fix partial slicing with pattern assignments, bug991. [Johan Bjork]
**** Fix false unused warning on interfaces, bug1241. [Laurens van Dam]
**** Fix error on "unique case" with no cases.
**** Fix MacOS portability, bug1232. [Jeff Bush]
* Verilator 3.914 2017-10-14
** Added new examples/ directory with appropriate examples. This replaces the
@@ -2081,7 +2213,7 @@ Bug fixes:
* Verilator 3.501 2005/11/16 Stable
*** Add --profile-cfuncs for correlating profiles back to Verilog.
*** Add --prof-cfuncs for correlating profiles back to Verilog.
**** Fixed functions where regs are declared before inputs. [Danny Ding]
@@ -2949,7 +3081,7 @@ of input ports exists for tracing.
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
Copyright 2001-2017 by Wilson Snyder. This program is free software; you
Copyright 2001-2018 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.
+4
View File
@@ -16,6 +16,9 @@
/obj_dir/
/obj_dbg/
/obj_opt/
/obj_vlt/
/obj_vltmt/
/obj_dist/
/INCA_libs/
/cov_work/
/logs/
@@ -34,6 +37,7 @@ verilator.pc$
verilator_bin.*
verilator_coverage_bin.*
.vcsmx_rebuild$
ncverilog.history
autom4te\.cache/
nodist/
/simv$
+14 -2
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2018 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.
@@ -92,6 +92,7 @@ datarootdir = @datarootdir@
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
CFG_WITH_THREADED = @CFG_WITH_THREADED@
PACKAGE_VERSION = @PACKAGE_VERSION@
#### End of system configuration section. ####
@@ -213,7 +214,7 @@ test_regress: all_nomsg
examples: all_nomsg
for p in examples/* ; do \
$(MAKE) -C $$p VERILATOR_ROOT=`pwd` ; \
$(MAKE) -C $$p VERILATOR_ROOT=`pwd` || exit 10; \
done
info: $(INFOS)
@@ -429,6 +430,14 @@ cppcheck: $(CPPCHECK_DEP)
%.cppcheck: %.cpp
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) $<
analyzer-src:
-rm -rf src/obj_dbg
scan-build $(MAKE) -k verilator_coverage_bin_dbg verilator_bin_dbg
analyzer-include:
-rm -rf examples/*/obj*
scan-build $(MAKE) -k examples
ftp: info
install-msg:
@@ -505,6 +514,9 @@ dist-file-list:
@echo $(wildcard $(DISTFILES))
@echo "end-dist-file-list:"; # Scripts look for this
print-cfg-with-threaded:
@echo $(CFG_WITH_THREADED)
######################################################################
# Distributions
+1 -1
View File
@@ -11,7 +11,7 @@ This is the Verilator package README file.
http://www.veripool.org/verilator
This package is Copyright 2003-2017 by Wilson Snyder. (Report bugs to
This package is Copyright 2003-2018 by Wilson Snyder. (Report bugs to
L<http://www.veripool.org/>.)
Verilator is free software; you can redistribute it and/or modify it under
+3 -9
View File
@@ -1,6 +1,6 @@
// DESCRIPTION: Verilator: List of To Do issues.
//
// Copyright 2004-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2018 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.
@@ -27,12 +27,10 @@ Long-term Features
* Multithreaded execution
Configure/Make/Install
* Full MSVC++ compilation (does scons support this?) (4.000?)
* Distribute with flex/bison already expanded?
Flex library not needed. Probably too difficult to be worth it.
Testing:
* Move test_c/sp/v/verilated into test_regress format (4.000?)
* Capture all inputs into global "rerun it" file
* Code to make wrapper that sets signals, so can do comparison checks
* New random program generator
@@ -48,20 +46,17 @@ Usability:
* Print version/etc message at runtime. (4.000?)
Include number of lines of code, percent comments, code complexity measurement
<-80chars------------------------------------------------------------------->
Verilator 3.600 - fast, free, open-sourced. Copyright 2001-2013.
Verilator 3.600 - The fast free open-sourced simulator. Copyright 2001-2013.
Verilated #### modules, #### instances, ##### sigs,
#### non-comment lines, ##### ops, ### KB model size
* Default the --l2name to remove extra "v" level of hierarchy (flag to make "top")
Lint:
* CDCRSTLOGIC should allow filtering with paths
"waive CDCRSTLOGIC --from a.b.sig --to a.c.sig --via OR"
Internal Code:
* Eliminate the AstNUser* passed to all visitors; its only needed in V3Width,
and removing it will speed up and simplify all the other code.
* A Visitor class that understands how to traverse data types
* V3Graph should be templated container type, taking in Vertex + Edge types
* Rename V3PreLex etc to match VerilogPerl filenames
* Instead of string, have an VEncodedString/VIdString which contains __DOT__ish
things, to reduce bugs. Also add _20 trailing space to \ encoded names. (4.000)
@@ -114,7 +109,6 @@ Performance:
* 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
* Allow Split of case statements without a $display/$stop
* I-cache packing improvements (what/how?)
* Data cache organization (order of vars in class)
First have clocks,
+257 -149
View File
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
######################################################################
#
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you
# Copyright 2003-2018 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.
@@ -54,18 +54,6 @@ push @ARGV, (split ' ',$ENV{VERILATOR_TEST_FLAGS}||"");
# We sneak a look at the flags so we can do some pre-environment checks
# All flags will hit verilator...
foreach my $sw (@ARGV) {
# Some special treatment for parameters to allow verilog literals for numbers
if ((substr($sw, 0, 2) eq "-G") || (substr($sw, 0, 8) eq "-pvalue+")) {
# If there is a single quote in the parameter put it double quotes ,
# else just put it in double quotes
if ($sw =~ m![\']!) {
$sw = "\"$sw\"";
} else {
$sw = "'$sw'";
}
} else {
$sw = "'$sw'" if $sw =~ m![^---a-zA-Z0-9_/\\:.+]!;
}
push @Opt_Verilator_Sw, $sw;
}
@@ -84,16 +72,30 @@ if (! GetOptions (
pod2usage(-exitstatus=>2, -verbose=>0);
}
# Determine runtime flags and run
if ($opt_gdbbt && !gdb_works()) {
warn "-Info: --gdbbt ignored: gdb doesn't seem to be working\n" if $Debug;
$opt_gdbbt = 0;
}
# Determine runtime flags and run
# Opt_Verilator_Sw is what we want verilator to see on its argc/argv.
# Starting with that, escape all special chars for the shell;
# The shell will undo the escapes and the verilator binary should
# then see exactly the contents of @Opt_Verilator_Sw.
my @quoted_sw = map {sh_escape($_)} @Opt_Verilator_Sw;
if ($opt_gdb) {
# Generic GDB interactive
run (("gdb"||$ENV{VERILATOR_GDB})
." ".verilator_bin()
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
# Note, uncomment to set breakpoints before running:
# ." -ex 'break main'"
# Note, we must use double-quotes ("run <switches>")
# and not single ('run <switches>') below. Bash swallows
# escapes as you would expect in a double-quoted string.
# That's not true for a single-quoted string, where \'
# actually terminates the string -- not what we want!
." -ex \"run ".join(' ', @quoted_sw)."\""
." -ex 'set width 0'"
." -ex 'bt'");
} elsif ($opt_gdbbt && $Debug) {
@@ -101,13 +103,12 @@ if ($opt_gdb) {
run ("gdb"
." ".verilator_bin()
." --batch --quiet --return-child-result"
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
." -ex \"run ".join(' ', @quoted_sw)."\""
." -ex 'set width 0'"
." -ex 'bt'");
} else {
# Normal, non gdb
run (verilator_bin()
." ".join(' ',@Opt_Verilator_Sw));
run (verilator_bin()." ".join(' ',@quoted_sw));
}
#----------------------------------------------------------------------
@@ -196,6 +197,16 @@ sub run {
}
}
sub sh_escape {
my ($arg) = @_;
# This is similar to quotemeta() but less aggressive.
# There's no need to escape hyphens, periods, or forward slashes
# for the shell as these have no special meaning to the shell.
$arg =~ s/([^0-9a-zA-Z_\-\.\/])/\\$1/g;
return $arg;
}
#######################################################################
#######################################################################
package main;
@@ -217,8 +228,8 @@ Verilator - Convert Verilog code to C++/SystemC
=head1 DESCRIPTION
Verilator converts synthesizable (not behavioral) Verilog code, plus some
Synthesis, SystemVerilog and a small subset of Verilog AMS assertions, into
Verilator converts synthesizable (generally not behavioral) Verilog code,
plus some Synthesis, SystemVerilog and a small subset of Verilog AMS into
C++ or SystemC code. It is not a complete simulator, but a compiler.
Verilator is invoked with parameters similar to GCC, Cadence
@@ -238,8 +249,8 @@ To get started, jump down to "EXAMPLE C++ EXECUTION".
=head1 ARGUMENT SUMMARY
This is a short summary of the arguments to Verilator. See the detailed
descriptions in the next sections for more information.
This is a short summary of the arguments to Verilator itself. See the
detailed descriptions in L</"VERILATION ARGUMENTS"> for more information.
{file.v} Verilog package, module and top module filenames
{file.c/cc/cpp} Optional C++ files to compile in
@@ -251,6 +262,7 @@ descriptions in the next sections for more information.
+1800-2005ext+<ext> Use SystemVerilog 2005 with file extension <ext>
+1800-2009ext+<ext> Use SystemVerilog 2009 with file extension <ext>
+1800-2012ext+<ext> Use SystemVerilog 2012 with file extension <ext>
+1800-2017ext+<ext> Use SystemVerilog 2017 with file extension <ext>
--assert Enable all assertions
--autoflush Flush streams after all $displays
--bbox-sys Blackbox unknown $system calls
@@ -270,6 +282,7 @@ descriptions in the next sections for more information.
-D<var>[=<value>] Set preprocessor define
--debug Enable debugging
--debug-check Enable debugging assertions
--no-debug-leak Disable leaking memory in --debug mode
--debugi <level> Enable debugging at a specified level
--debugi-<srcfile> <level> Enable debugging a source file at a level
--default-language <lang> Default language to parse
@@ -289,6 +302,7 @@ descriptions in the next sections for more information.
--getenv <var> Get environment variable with defaults
--help Display this help
-I<dir> Directory to search for includes
--gate-stmts <value> Tune gate optimizer depth
--if-depth <value> Tune IFDEPTH warning
+incdir+<dir> Directory to search for includes
--inhibit-sim Create function to turn off sim
@@ -323,7 +337,7 @@ descriptions in the next sections for more information.
--pins-uint8 Specify types for top level ports
--pipe-filter <command> Filter all input through a script
--prefix <topname> Name of top level class
--profile-cfuncs Name functions for profiling
--prof-cfuncs Name functions for profiling
--private Debugging; see docs
--public Debugging; see docs
-pvalue+<name>=<value> Overwrite toplevel parameter
@@ -335,7 +349,7 @@ descriptions in the next sections for more information.
--stats Create statistics file
--stats-vars Provide statistics on variables
-sv Enable SystemVerilog parsing
+systemverilogext+<ext> Synonym for +1800-2012ext+<ext>
+systemverilogext+<ext> Synonym for +1800-2017ext+<ext>
--top-module <topname> Name of top level input module
--trace Enable waveform creation
--trace-depth <levels> Depth of tracing
@@ -352,6 +366,7 @@ descriptions in the next sections for more information.
-v <filename> Verilog library
+verilog1995ext+<ext> Synonym for +1364-1995ext+<ext>
+verilog2001ext+<ext> Synonym for +1364-2001ext+<ext>
--version Displays program version and exits
--vpi Enable VPI compiles
-Wall Enable all style warnings
-Werror-<message> Convert warnings to errors
@@ -366,7 +381,9 @@ descriptions in the next sections for more information.
-y <dir> Directory to search for modules
=head1 ARGUMENTS
=head1 VERILATION ARGUMENTS
The following are the arguments that may be passed to Verilator itself.
=over 4
@@ -402,6 +419,8 @@ with the --exe option.
=item +1800-2012ext+I<ext>
=item +1800-2017ext+I<ext>
Specifies the language standard to be used with a specific filename
extension, I<ext>.
@@ -433,7 +452,7 @@ Enable all assertions.
=item --autoflush
After every $display or $fdisplay, flush the output stream. This insures
After every $display or $fdisplay, flush the output stream. This ensures
that messages will appear immediately but may reduce performance; for best
performance call "fflush(stdout)" occasionally in the main C loop.
Defaults off, which will buffer output as provided by the normal C stdio
@@ -529,7 +548,7 @@ functions to avoid error C1061.
=back
=item --converge-limit <loops>
=item --converge-limit I<loops>
Rarely needed. Specifies the maximum number of runtime iterations before
creating a model failed to converge error. Defaults to 100.
@@ -547,7 +566,7 @@ Coverage analysis adds statements at each code flow change point, which are
the branches of IF and CASE statements, a super-set of normal Verilog Line
Coverage. At each such branch a unique counter is incremented. At the end
of a test, the counters along with the filename and line number
corresponding to each counter are written into logs/coverage.pl.
corresponding to each counter are written into logs/coverage.dat.
Verilator automatically disables coverage of branches that have a $stop in
them, as it is assumed $stop branches contain an error check that should
@@ -626,9 +645,21 @@ to C<--dump-treei 3>).
Rarely needed. Enable internal debugging assertion checks, without
changing debug verbosity. Enabled automatically when --debug specified.
=item --debugi <level>
=item --no-debug-leak
=item --debugi-<srcfile> <level>
In --debug mode, by default Verilator intentionally leaks AstNode's
instead of freeing them, so that each node pointer is unique in the
resulting tree files and dot files.
This option disables the leak. This may avoid out-of-memory errors
when Verilating large models in --debug mode.
Outside of --debug mode, AstNode's should never be leaked and this option
has no effect.
=item --debugi I<level>
=item --debugi-I<srcfile> I<level>
Rarely needed - for developer use. Set internal debugging level globally
to the specified debug level (1-10) or set the specified Verilator source
@@ -639,7 +670,7 @@ produce more detailed messages.
Select the language to be used by default when first processing each
Verilog file. The language value must be "1364-1995", "1364-2001",
"1364-2005", "1800-2005", "1800-2009" or "1800-2012".
"1364-2005", "1800-2005", "1800-2009", "1800-2012" or "1800-2017".
Any language associated with a particular file extension (see the various
+I<lang>ext+ options) will be used in preference to the language specified
@@ -652,7 +683,7 @@ legacy mixed language designs, the various +I<lang>ext+ options should be
used.
If no language is specified, either by this flag or +I<lang>ext+ options,
then the latest SystemVerilog language (IEEE 1800-2012) is used.
then the latest SystemVerilog language (IEEE 1800-2017) is used.
=item +define+I<var>=I<value>
@@ -670,9 +701,9 @@ the Verilator Internals manual. --dump-tree is enabled automatically with
--debug, so "--debug --no-dump-tree" may be useful if the dump files are
large and not desired.
=item --dump-treei <level>
=item --dump-treei I<level>
=item --dump-treei-<srcfile> <level>
=item --dump-treei-I<srcfile> I<level>
Rarely needed - for developer use. Set internal tree dumping level
globally to a specific dumping level or set the specified Verilator source
@@ -686,7 +717,7 @@ Preprocess the source code, but do not compile, as with 'gcc -E'. Output
is written to standard out. Beware of enabling debugging messages, as they
will also go to standard out.
=item --error-limit <value>
=item --error-limit I<value>
After this number of errors or warnings are encountered, exit. Defaults to
50.
@@ -713,7 +744,7 @@ The file may contain // comments which are ignored to the end of the line.
Any $VAR, $(VAR), or ${VAR} will be replaced with the specified environment
variable.
=item -FI <file>
=item -FI I<file>
Force include of the specified C++ header file. All generated C++ files
will insert a #include of the specified file before any other includes. The
@@ -745,11 +776,16 @@ Double literals must contain a dot (.) and/or an exponent (e).
=item Strings
String must in double quotes ("). On the command line it is required to escape
String must in double quotes (""). On the command line it is required to escape
them properly, e.g. as -GSTR="\"My String\"" or -GSTR='"My String"'.
=back
=item --gate-stmts I<value>
Rarely needed. Set the maximum number of statements that may be present in
an equation for the gate substitution optimization to inline that equation.
=item --gdb
Run Verilator underneath an interactive GDB (or VERILATOR_GDB environment
@@ -866,7 +902,7 @@ otherwise manually create the Mdir before calling Verilator.
Specifies the name to prepend to all lower level classes. Defaults to
the same as --prefix.
=item --no-clk <signal-name>
=item --no-clk I<signal-name>
Prevent the specified signal from being marked as clock. See C<--clk>.
@@ -925,7 +961,7 @@ disables an optimization, an upper case letter enables it. This is
intended for debugging use only; see the source code for version-dependent
mappings of optimizations to -O letters.
=item -o <executable>
=item -o I<executable>
Specify the name for the final executable built if using --exe. Defaults
to the --prefix if not specified.
@@ -1024,7 +1060,7 @@ 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.
=item --profile-cfuncs
=item --prof-cfuncs
Modify the created C++ functions to support profiling. The functions will
be minimized to contain one "basic" statement, generally a single always
@@ -1032,7 +1068,7 @@ block or wire statement. (Note this will slow down the executable by ~5%.)
Furthermore, the function name will be suffixed with the basename of the
Verilog module and line number the statement came from. This allows gprof
or oprofile reports to be correlated with the original Verilog source
statements.
statements. See also L<verilator_profcfunc>.
=item --private
@@ -1113,7 +1149,7 @@ Creates a dump file with statistics on the design in {prefix}__stats.txt.
=item --stats-vars
Creates more detailed statistics including a list of all the variables by
Creates more detailed statistics, including a list of all the variables by
size (plain --stats just gives a count). See --stats, which is implied by
this.
@@ -1125,7 +1161,7 @@ compatibility with other simulators.
=item +systemverilogext+I<ext>
A synonym for C<+1800-2012ext+>I<ext>.
A synonym for C<+1800-2017ext+>I<ext>.
=item --top-module I<topname>
@@ -1140,8 +1176,8 @@ Adds waveform tracing code to the model. Verilator will generate
additional {prefix}__Trace*.cpp files that will need to be compiled. In
addition verilated_vcd_sc.cpp (for SystemC traces) or verilated_vcd_c.cpp
(for both) must be compiled and linked in. If using the Verilator
generated Makefiles, these will be added as source targets for you. If
you're not using the Verilator makefiles, you will need to add these to
generated Makefiles, these files will be added as source targets for you.
If you're not using the Verilator makefiles, you will need to add these to
your Makefile manually.
Having tracing compiled in may result in some small performance losses,
@@ -1219,6 +1255,10 @@ Note -v is fairly standard across Verilog tools.
Synonyms for C<+1364-1995ext+>I<ext> and C<+1364-2001ext+>I<ext> respectively
=item --version
Displays program version and exits.
=item --vpi
Enable use of VPI and linking against the verilated_vpi.cpp files.
@@ -1245,17 +1285,18 @@ supports which the older version does not support.
=item -Wno-I<message>
Disable the specified warning message. This will override any lint_on
directives in the source, i.e. the warning will still not be printed.
Disable the specified warning message, or in some cases where noted here
disable an error. This will override any lint_on directives in the source,
i.e. the warning will still not be printed.
=item -Wno-lint
Disable all lint related warning messages, and all style warnings. This is
equivalent to "-Wno-ALWCOMBORDER -Wno-CASEINCOMPLETE -Wno-CASEOVERLAP
-Wno-CASEX -Wno-CASEWITHX -Wno-CMPCONST -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.
equivalent to "-Wno-ALWCOMBORDER -Wno-BSSPACE -Wno-CASEINCOMPLETE
-Wno-CASEOVERLAP -Wno-CASEX -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.
It is strongly recommended you cleanup your code rather than using this
option, it is only intended to be use when running test-cases of code
@@ -1284,10 +1325,10 @@ 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-CASEINCOMPLETE -Wwarn-CASEOVERLAP -Wwarn-CASEX
-Wwarn-CASEWITHX -Wwarn-CMPCONST -Wwarn-ENDLABEL -Wwarn-IMPLICIT
-Wwarn-LITENDIAN -Wwarn-PINMISSING -Wwarn-REALCVT -Wwarn-UNSIGNED
-Wwarn-WIDTH".
"-Wwarn-ALWCOMBORDER -Wwarn-BSSPACE -Wwarn-CASEINCOMPLETE
-Wwarn-CASEOVERLAP -Wwarn-CASEX -Wwarn-CASEWITHX -Wwarn-CMPCONST
-Wwarn-COLONPLUS -Wwarn-ENDLABEL -Wwarn-IMPLICIT -Wwarn-LITENDIAN
-Wwarn-PINMISSING -Wwarn-REALCVT -Wwarn-UNSIGNED -Wwarn-WIDTH".
=item -Wwarn-style
@@ -1337,7 +1378,7 @@ not otherwise initialized.
--x-initial=unique, the default, initializes variables using a function,
which determines the value to use each initialization. This gives greatest
flexibility and allows finding reset bugs. See L</"Unknown states">
flexibility and allows finding reset bugs. See L</"Unknown states">.
--x-initial=fast, is best for performance, and initializes all variables to
a state Verilator determines is optimal. This may allow further code
@@ -1569,7 +1610,7 @@ fast path, mostly code that is executed every cycle. OPT_SLOW specifies
optimizations for slow-path files (plus tracing), which execute only
rarely, yet take a long time to compile with optimization on. OPT
specifies overall optimization and affects all compiles, including those
OPT_FAST and OPT_SLOW affect. For best results, use OPT="-O2", and link
OPT_FAST and OPT_SLOW control. For best results, use OPT="-O2", and link
with "-static". Nearly the same results can be had with much better
compile times with OPT_FAST="-O1 -fstrict-aliasing". Higher optimization
such as "-O3" may help, but gcc compile times may be excessive under O3 on
@@ -1598,7 +1639,7 @@ code with -DVL_INLINE_OPT=inline. This will inline functions, however this
requires that all cpp files be compiled in a single compiler run.
You may uncover further tuning possibilities by profiling the Verilog code.
Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run
Use Verilator's --prof-cfuncs, then GCC's -g -pg. You can then run
either oprofile or gprof to see where in the C++ code the time is spent.
Run the gprof output through verilator_profcfunc and it will tell you what
Verilog line numbers on which most of the time is being spent.
@@ -1666,8 +1707,8 @@ needed at runtime.
Optionally specifies a caching or distribution program to place in front of
all runs of the C++ Compiler. For example, "objcache --read --write", or
"ccache". If using distcc, it would generally be run under either objcache
or ccache; see the documentation for those programs.
"ccache". If using distcc or icecc/icecream, they would generally be run
under either objcache or ccache; see the documentation for those programs.
=item SYSTEMC
@@ -1734,7 +1775,7 @@ Verilator RPM as the hardcoded value should be correct.
=head1 CONNECTING TO C++
Verilator creates a .h and .cpp file for the top level module and all
modules under it. See the test_c directory in the kit for an example.
modules under it. See the examples directory in the kit for examples.
After the modules are completed, there will be a I<module>.mk file that may
be used with Make to produce a I<module>__ALL.a file with all required
@@ -2188,6 +2229,11 @@ Verilator currently has some support for SystemVerilog synthesis
constructs. As SystemVerilog features enter common usage they are added;
please file a bug if a feature you need is missing.
=head2 SystemVerilog 2017 (IEEE 1800-2017) Support
Verilator supports the 2017 "for" loop constructs, and several minor
cleanups made in 1800-2017.
=head2 Verilog AMS Support
Verilator implements a very small subset of Verilog AMS (Verilog Analog and
@@ -2349,7 +2395,7 @@ Verilator configuration commands.
Switch back to processing Verilog code after a `systemc_... mode switch.
The Verilog code returns to the last language mode specified with
`begin_keywords, or SystemVerilog if none were specified.
`begin_keywords, or SystemVerilog if none was specified.
=item /*verilator clock_enable*/
@@ -2466,6 +2512,13 @@ lint_restore*/. For example:
If SOME_WARNING was on before the lint_off, it will now be restored to on,
and if it was off before the lint_off it will remain off.
=item /*verilator no_inline_module*/
Specifies the module the comment appears in should not be inlined into any
modules that use this module. This is useful especially at the top level
module to reduce the size of the interface class, to aid compile time at a
small performance loss.
=item /*verilator no_inline_task*/
Used in a function or task variable definition section to specify the
@@ -3034,13 +3087,15 @@ Simply use a different register for the flop:
always @* foo[0] = foo_flopped[0];
always @* foo[1] = ...
It is also possible to disable this error when one of the assignments is
inside a public task.
This is not illegal in SystemVerilog, but a violation of good coding
practice. Verilator reports this as an error, because ignoring this warning
may make Verilator simulations differ from other simulators.
It is generally safe to disable this error (with a "// verilator lint_off
BLKANDNBLK" metacomment or the -Wno-BLKANDNBLK option) when one of the
assignments is inside a public task, or when the blocked and non-blocking
assignments have non-overlapping bits and structure members.
=item BLKSEQ
This indicates that a blocking assignment (=) is used in a sequential
@@ -3074,6 +3129,17 @@ generally unrolls small loops. You may want to try increasing
--unroll-count (and occasionally --unroll-stmts) which will raise the small
loop bar to avoid this error.
=item BSSPACE
Warns that a backslash is followed by a space then a newline. Likely the
intent was to have a backslash directly followed by a newline (e.g. when
making a `define) and there's accidentally whitespace at the end of the
line. If the space is not accidental, suggest removing the backslash in
the code as it serves no function.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item CASEINCOMPLETE
Warns that inside a case statement there is a stimulus pattern for which
@@ -3113,6 +3179,15 @@ instead intended is to use a casez with C<?>.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item COLONPLUS
Warns that a :+ is seen. Likely the intent was to use +: to select a range
of bits. If the intent was a range that is explicitly positive, suggest
adding a space, e.g. use ": +".
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item CDCRSTLOGIC
With --cdc only, warns that asynchronous flop reset terms come from other
@@ -3248,6 +3323,18 @@ command line to specify the top include source directories.
Disabled by default as this is a code style warning; it will simulate
correctly.
=item INFINITELOOP
Warns that a while or for statement has a condition that is always true.
and thus result in an infinite loop if the statement ever executes.
This might be unintended behavior if the loop body contains statements that
in other statements that would make time pass, which Verilator is ignoring
due to e.g. STMTDLY warnings being disabled.
Ignoring this warning will only suppress the lint check, it will simulate
correctly (i.e. hang due to the infinite loop).
=item INITIALDLY
Warns that you have a delayed assignment inside of an initial or final
@@ -3274,10 +3361,14 @@ correctly.
=item MODDUP
Error that a module has multiple definitions. Generally this indicates a
Warns that a module has multiple definitions. Generally this indicates a
coding error, or a mistake in a library file and it's good practice to have
one module per file to avoid these issues. For some gate level netlists
duplicates are unavoidable, and this error may be disabled.
one module per file (and only put each file once on the command line) to
avoid these issues. For some gate level netlists duplicates are sometimes
unavoidable, and MODDUP should be disabled.
Ignoring this warning will cause the more recent module definition to be
discarded.
=item MULTIDRIVEN
@@ -3624,7 +3715,7 @@ For example:
will toggle forever and thus the executable will give the didn't converge
error to prevent an infinite loop.
To debug this, run Verilator with --profile-cfuncs. Run make on the
To debug this, run Verilator with --prof-cfuncs. Run make on the
generated files with "OPT=-DVL_DEBUG". Then call Verilated::debug(1) in
your main.cpp.
@@ -3644,24 +3735,24 @@ program above:
=item Does it run under Windows?
Yes, using Cygwin. Verilated output should also compile under Microsoft
Visual C++ Version 7 or newer, but this is not tested by the author.
Yes, using Cygwin. Verilated output also compiles under Microsoft Visual
C++ Version 7 or newer, but this is not tested every release.
=item Can you provide binaries?
Verilator is available as a RPM for SuSE, Fedora, and perhaps other
systems; this is done by porters and may slightly lag the primary
distribution. If there isn't a binary build for your distribution, how
about you set one up? Please contact the authors for assistance.
Verilator is available as a RPM for Debian/Ubuntu, SuSE, Fedora, and
perhaps other systems; this is done by porters and may slightly lag the
primary distribution. If there isn't a binary build for your distribution,
how about you set one up? Please contact the authors for assistance.
Note people sometimes request binaries when they are having problems with
their C++ compiler. Alas, binaries won't help this, as in the end a fully
working C++ compiler is required to compile the output of Verilator.
=item How can it be faster than (name-the-simulator)?
=item How can it be faster than (name-the-commercial-simulator)?
Generally, the implied part of the question is "... with all of their
manpower they can put into it."
Generally, the implied part is of the question is "... with all of the
manpower they can put into developing it."
Most commercial simulators have to be Verilog compliant, meaning event
driven. This prevents them from being able to reorder blocks and make
@@ -3694,17 +3785,18 @@ source code available.
As is standard with Open Source, contributions back to Verilator will be
placed under the Verilator copyright and LGPL/Artistic license. Small test
cases will be released into the public domain so they can be used anywhere,
large tests under the LGPL/Artistic, unless requested otherwise.
and large tests under the LGPL/Artistic, unless requested otherwise.
=item Why is Verilation so slow?
Verilator needs more memory than the resulting simulator will require, as
Verilator creates internally all of the state of the resulting simulator in
order to optimize it. If it takes more than a minute or so (and you're not
using --debug since debug is disk bound), see if your machine is paging;
most likely you need to run it on a machine with more memory. Verilator is
a full 64-bit application and may use more than 4GB, but about 1GB is the
maximum typically needed.
Verilator creates internally all of the state of the resulting generated
simulator in order to optimize it. If it takes more than a minute or so
(and you're not using --debug since debug is disk bound), see if your
machine is paging; most likely you need to run it on a machine with more
memory. Verilator is a full 64-bit application and may use more than 4GB,
but about 1GB is the maximum typically needed, and very large commercial
designs have topped 16GB.
=item How do I generate waveforms (traces) in C++?
@@ -3714,7 +3806,7 @@ Add the --trace switch to Verilator, and in your top level C code, call
Verilated::traceEverOn(true). Then create a VerilatedVcdC object, and
in your main loop call "trace_object->dump(time)" every time step, and
finally call "trace_object->close()". For an example, see below and the
test_c/sim_main.cpp file of the distribution.
examples/tracing_c/sim_main.cpp file of the distribution.
You also need to compile verilated_vcd_c.cpp and add it to your link,
preferably by adding the dependencies in $(VK_GLOBAL_OBJS) to your
@@ -3740,15 +3832,13 @@ trace file if you want all data to land in the same output file.
tfp->close();
}
Also see the examples/tracing_cc directory in the distribution.
=item How do I generate waveforms (traces) in SystemC?
Add the --trace switch to Verilator, and in your top level C sc_main code,
include verilated_vcd_sc.h. Then call Verilated::traceEverOn(true). Then
create a VerilatedVcdSc object as you would create a normal SystemC trace
file. For an example, see the call to VerilatedVcdSc in the
test_sc/sc_main.cpp file of the distribution, and below.
examples/tracing_sc/sc_main.cpp file of the distribution, and below.
Alternatively you may use the C++ trace mechanism described in the previous
question, however the timescale and timeprecision will not inherited from
@@ -3776,8 +3866,6 @@ trace file if you want all data to land in the same output file.
tfp->close();
}
Also see the examples/tracing_cc directory in the distribution.
=item How do I view waveforms (traces)?
Verilator makes standard VCD (Value Change Dump) files. They are viewable
@@ -3796,8 +3884,8 @@ want to trace (such as perhaps library cells). Finally, use the
--trace-depth option to limit the depth of tracing, for example
--trace-depth 1 to see only the top level signals.
Also be sure you write your trace files to a local disk, instead of to a
network disk. Network disks are generally far slower.
Also be sure you write your trace files to a local solid-state disk,
instead of to a network disk. Network disks are generally far slower.
=item How do I do coverage analysis?
@@ -3812,14 +3900,14 @@ At the end of your test, call VerilatedCov::write passing the name of the
coverage data file (typically "logs/coverage.dat").
Run each of your tests in different directories. Each test will create a
logs/coverage.pl file.
logs/coverage.dat file.
After running all of your tests, verilator_coverage is executed.
Verilator_coverage reads the logs/coverage.pl file(s), and creates an
Verilator_coverage reads the logs/coverage.dat file(s), and creates an
annotated source code listing showing code coverage details.
For an example, after running 'make test' in the Verilator distribution,
see the test_sc/logs directory. Grep for lines starting
see the examples/tracing_c/logs directory. Grep for lines starting
with '%' to see what lines Verilator believes need more coverage.
=item Where is the translate_off command? (How do I ignore a construct?)
@@ -3833,6 +3921,8 @@ the "VERILATOR" define for you, so just wrap the code in an ifndef region:
Something_Verilator_Dislikes;
`endif
Most synthesis tools similarly define SYNTHESIS for you.
=item Why do I get "unexpected `do'" or "unexpected `bit'" errors?
Do, bit, ref, return, and other words are now SystemVerilog keywords. You
@@ -3869,7 +3959,7 @@ simulator knows the current time. See the "CONNECTING TO C++" examples.
You need to link your compiled Verilated code against the verilated.cpp
file found in the include directory of the Verilator kit. This is one
target in the $(VK_GLOBAL_OBJS) make variable, which should be part of your
Makefile's link rule.
Makefile's link rule. If you use --exe, this is done for you.
=item Is the PLI supported?
@@ -3891,13 +3981,20 @@ test_regress/t/t_extend_class files show an example of how to do this.
=item How do I get faster build times?
Between GCC 3.0 to 3.3, each compiled progressively slower, thus if you can
use GCC 2.95, or GCC 3.4 you'll have faster builds. Two ways to cheat are
to compile on parallel machines and avoid compilations altogether. See the
--output-split option, and the web for the ccache, distcc and icecream
packages. ccache will skip GCC runs between identical source builds, even
across different users. You can use the OBJCACHE environment variable to
use these CC wrappers.
Use a recent compiler. Newer compilers tend do be faster, with the
now relatively old GCC 3.0 to 3.3 being horrible.
Compile in parallel on many machines and use caching; see the web for the
ccache, distcc and icecream packages. ccache will skip GCC runs between
identical source builds, even across different users. You can use the
OBJCACHE environment variable to use these CC wrappers. Also see the
--output-split option.
To reduce the compile time of classes that use a Verilated module (e.g. a
top CPP file) you may wish to add /*verilator no_inline_module*/ to your
top level module. This will decrease the amount of code in the model's
Verilated class, improving compile times of any instantiating top level C++
code, at a relatively small cost of execution performance.
=item Why do so many files need to recompile when I add a signal?
@@ -4037,7 +4134,7 @@ License.)
In 2001, Wilson Snyder took the kit, and added a SystemC mode, and
called it Verilator2. This was the first packaged public release.
In 2002, Wilson Snyder created Verilator3 by rewriting Verilator from
In 2002, Wilson Snyder created Verilator 3.000 by rewriting Verilator from
scratch in C++. This added many optimizations, yielding about a 2-5x
performance gain.
@@ -4054,7 +4151,7 @@ When possible, please instead report bugs to L<http://www.veripool.org/>.
Wilson Snyder <[email protected]>
Major concepts by Paul Wasson, Duane Galbi and Jie Xu.
Major concepts by Paul Wasson, Duane Galbi, John Coiner and Jie Xu.
=head1 CONTRIBUTORS
@@ -4069,50 +4166,61 @@ Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus Networks Inc.,
and SiCortex Inc.
The people who have contributed major functionality are Byron Bradley,
Jeremy Bennett, Jie Xu, Lane Brooks, Duane Galbi, Paul Wasson, and Wilson
Snyder. Major testers include Jeff Dutton, Jonathon Donaldson, Ralf Karge,
David Hewson, Iztok Jeras, Wim Michiels, Alex Solomatnikov, Sebastien Van
Cauwenberghe, Gene Weber, and Clifford Wolf.
Jeremy Bennett, Jie Xu, Lane Brooks, John Coiner, Duane Galbi, Paul Wasson,
and Wilson Snyder. Major testers included Jeff Dutton, Jonathon Donaldson,
Ralf Karge, David Hewson, Iztok Jeras, Wim Michiels, Alex Solomatnikov,
Sebastien Van Cauwenberghe, Gene Weber, and Clifford Wolf.
Some of the people who have provided ideas and feedback for Verilator
include: Yves Mathieu, David Addison, Nikana Anastasiadis, Hans Van
Antwerpen, Vasu Arasanipalai, Jens Arm, Sharad Bagri, Andrew Bardsley,
Geoff Barrett, J Baxter, Julius Baxter, Jeremy Bennett, Michael Berman,
David Binderman, David Black, Daniel Bone, Gregg Bouchard, Christopher
Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, Charlie Brej, Lane
Brooks, John Brownlee, Jeff Bush, Lawrence Butcher, Ted Campbell, Chris
Candler, Lauren Carlson, Donal Casey, Terry Chen, Robert A. Clark, Allan
Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, Mike Denio,
John Deroo, Philip Derrick, John Dickol, R. Diez, Ruben Diez, Danny Ding,
Ivan Djordjevic, Jonathon Donaldson, Alex Duller, Jeff Dutton, Chandan
Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell, Eugen Fekete,
Fabrizio Ferrandi, Andrea Foletto, Bob Fredieu, Christian Gelinek, Glen
Gibb, Shankar Giri, Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Neil
Hamilton, Junji Hashimoto, Thomas Hawkins, David Hewson, Hiroki Honda, Alex
Hornung, Jae Hossell, Ben Jackson, Krzysztof Jankowski, HyungKi Jeong,
Iztok Jeras, James Johnson, Christophe Joly, Franck Jullien, Mike Kagen,
include: Ahmed El-Mahmoudy, David Addison, Tariq B. Ahmad, Nikana
Anastasiadis, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, Sharad
Bagri, Andrew Bardsley, Matthew Barr, Geoff Barrett, Julius Baxter, Jeremy
Bennett, Michael Berman, Victor Besyakov, David Binderman, Johan Bjork,
David Black, Tymoteusz Blazejczyk, Daniel Bone, Gregg Bouchard, Christopher
Boumenot, Nick Bowler, Byron Bradley, Bryan Brady, Charlie Brej, J Briquet,
Lane Brooks, John Brownlee, Jeff Bush, Lawrence Butcher, Ted Campbell,
Chris Candler, Lauren Carlson, Donal Casey, Terry Chen, Enzo Chi, Robert
A. Clark, Allan Cochrane, John Coiner, Laurens van Dam, Gunter Dannoritzer,
Ashutosh Das, Bernard Deadman, John Demme, Mike Denio, John Deroo, Philip
Derrick, Joe DErrico, John Dickol, Ruben Diez, Danny Ding, Ivan Djordjevic,
Jonathon Donaldson, Sebastian Dressler, Alex Duller, Jeff Dutton, Usuario
Eda, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Trevor Elbourne, Robert
Farrell, Eugen Fekete, Fabrizio Ferrandi, Brian Flachs, Andrea Foletto, Bob
Fredieu, Christian Gelinek, Glen Gibb, Shankar Giri, Dan Gisselquist, Sam
Gladstone, Amir Gonnen, Chitlesh Goorah, Xuan Guo, Neil Hamilton, Jannis
Harder, Junji Hashimoto, Thomas Hawkins, Robert Henry, David Hewson, Jamey
Hicks, Joel Holdsworth, Hiroki Honda, Alex Hornung, David Horton, Jae
Hossell, Alan Hunter, James Hutchinson, Jamie Iles, Ben Jackson, Shareef
Jalloq, Krzysztof Jankowski, HyungKi Jeong, Iztok Jeras, James Johnson,
Christophe Joly, Franck Jullien, James Jung, Mike Kagen, Arthur Kahlich,
Kaalia Kahn, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf
Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Sobhan Klnv, Gernot Koch,
Soon Koh, Steve Kolecki, Brett Koonce, Wojciech Koszek, Varun Koyyalagunta,
David Kravitz, Roland Kruse, Ed Lander, Steve Lang, Stephane Laurent,
Walter Lavino, Christian Leber, Igor Lesik, John Li, Eivind Liland, Charlie
Lind, Andrew Ling, Paul Liu, Derek Lockhart, Arthur Low, Stefan Ludwig, Dan
Lussier, Fred Ma, Duraid Madina, Mark Marshall, Jason McMullan, Wim
Michiels, Wai Sum Mong, Sean Moore, Dennis Muhlestein, John Murphy, Richard
Myers, Dimitris Nalbantis, Bob Newgard, Cong Van Nguyen, Paul Nitza, Pete
Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, Brad Parker, David
Pierce, Dominic Plunkett, David Poole, Rich Porter, Niranjan Prabhu, Usha
Priyadharshini, Mark Jackson Pulver, Prateek Puri, Chris Randall, Frederic
Requin, Alberto Del Rio, Oleg Rodionov, Jan Egil Ruud, John Sanguinetti,
Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Rodney
Sinclair, Steven Slatter, Brian Small, Wilson Snyder, Alex Solomatnikov,
Art Stamness, John Stevenson, Todd Strader, John Stroebel, Emerson
Suguimoto, Gene Sullivan, Renga Sundararajan, Yutetsu Takatsukasa, Peter
Tengstrand, Stefan Thiede, Gary Thomas, Kevin Thompson, Mike Thyer, Steve
Tong, Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters,
Thomas Watts, Eugene Weber, David Welch, Leon Wildman, Gerald Williams,
Trevor Williams, Jeff Winston, Joshua Wise, Clifford Wolf, Johan Wouters,
Ding Xiaoliang, Jie Xu, and Amir Yazdanbakhsh.
Karge, Dan Katz, Sol Katzman, Jonathan Kimmitt, Olof Kindgren, Dan Kirkham,
Sobhan Klnv, Gernot Koch, Soon Koh, Steve Kolecki, Brett Koonce, Wojciech
Koszek, Varun Koyyalagunta, David Kravitz, Roland Kruse, Sergey Kvachonok,
Ed Lander, Steve Lang, Stephane Laurent, Walter Lavino, Christian Leber,
Igor Lesik, John Li, Eivind Liland, Charlie Lind, Andrew Ling, Paul Liu,
Derek Lockhart, Arthur Low, Stefan Ludwig, Dan Lussier, Fred Ma, Duraid
Madina, Mark Marshall, Alfonso Martinez, Yves Mathieu, Patrick Maupin,
Jason McMullan, Elliot Mednick, Wim Michiels, Miodrag Milanovic, Wai Sum
Mong, Sean Moore, Dennis Muhlestein, John Murphy, Richard Myers, Dimitris
Nalbantis, Bob Newgard, Cong Van Nguyen, Paul Nitza, Pete Nixon, Lisa
Noack, Mark Nodine, Andreas Olofsson, James Pallister, Brad Parker, Maciej
Piechotka, David Pierce, Dominic Plunkett, David Poole, Mike Popoloski,
Rich Porter, Niranjan Prabhu, Usha Priyadharshini, Mark Jackson Pulver,
Prateek Puri, Chris Randall, Anton Rapp, Josh Redford, Odd Magne Reitan,
Frederic Requin, Alberto Del Rio, Oleg Rodionov, Paul Rolfe, Arjen
Roodselaar, Jan Egil Ruud, John Sanguinetti, Galen Seitz, Salman Sheikh,
Mike Shinkarovsky, Rafael Shirakawa, Jeffrey Short, Rodney Sinclair, Steven
Slatter, Brian Small, Alex Solomatnikov, Wei Song, Art Stamness, John
Stevenson, Patrick Stewart, Rob Stoddard, Todd Strader, John Stroebel, Sven
Stucki, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Yutetsu
Takatsukasa, Peter Tengstrand, Wesley Terpstra, Rui Terra, Stefan Thiede,
Gary Thomas, Kevin Thompson, Ian Thompson, Mike Thyer, Hans Tichelaar,
Steve Tong, Michael Tresidder, Holger Waechtler, Stefan Wallentowitz, Shawn
Wang, Greg Waters, Thomas Watts, Eugene Weber, David Welch, Thomas J
Whatson, Leon Wildman, Gerald Williams, Trevor Williams, Jeff Winston,
Joshua Wise, Clifford Wolf, Johan Wouters, Junyi Xi, Ding Xiaoliang, Jie
Xu, Mandy Xu, Luke Yang, and Amir Yazdanbakhsh.
Thanks to them, and all those we've missed including above.
@@ -4121,7 +4229,7 @@ Thanks to them, and all those we've missed including above.
The latest version is available from L<http://www.veripool.org/>.
Copyright 2003-2017 by Wilson Snyder. Verilator is free software; you can
Copyright 2003-2018 by Wilson Snyder. Verilator 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.
+3 -3
View File
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
######################################################################
#
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you
# Copyright 2003-2018 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@@ -173,7 +173,7 @@ additional points.
Additional Verilog-standard arguments specify the search paths necessary to
find the source code that the coverage analysis was performed on.
To get correct coverage percentages, you may wish to read logs/coverage.pl
To get correct coverage percentages, you may wish to read logs/coverage.dat
into Emacs and do a M-x keep-lines to include only those statistics of
interest.
@@ -271,7 +271,7 @@ Specifies a module search directory.
The latest version is available from L<http://www.veripool.org/>.
Copyright 2003-2017 by Wilson Snyder. Verilator is free software; you can
Copyright 2003-2018 by Wilson Snyder. Verilator 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.
+3 -2
View File
@@ -85,7 +85,8 @@ sub diff_dir {
diff_file($a,$b);
$any = 1;
}
$any or warn "%Warning: No .tree files found\n";
$any or warn ("%Warning: No .tree files found that have similar base names:\n "
.join("\n ", sort keys %files),"\n");
}
sub diff_file {
@@ -235,7 +236,7 @@ Do not show differences in line numbering.
The latest version is available from L<http://www.veripool.org/verilator>.
Copyright 2005-2017 by Wilson Snyder. This package is free software; you can
Copyright 2005-2018 by Wilson Snyder. This package is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
+1 -1
View File
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
# DESCRIPTION: Print include statements for each ARGV
#
# Copyright 2003-2017 by Wilson Snyder. This package is free software; you can
# Copyright 2003-2018 by Wilson Snyder. This package is free software; you can
# redistribute it and/or modify it under the terms of either the GNU Lesser
# General Public License Version 3 or the Perl Artistic License Version 2.0.
######################################################################
+12 -4
View File
@@ -73,6 +73,14 @@ sub profcfunc {
$funcs{$func}{sec} += $sec;
$funcs{$func}{calls} += $calls;
}
# Older gprofs have no call column for single-call functions
# %time cumesec selfsec {stuff} name
elsif ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$/) {
my $pct=$1; my $sec=$2; my $calls=1; my $func=$3;
$funcs{$func}{pct} += $pct;
$funcs{$func}{sec} += $sec;
$funcs{$func}{calls} += $calls;
}
}
$fh->close;
@@ -191,11 +199,11 @@ __END__
=head1 NAME
verilator_profcfunc - Read gprof report created with --profile-cfuncs
verilator_profcfunc - Read gprof report created with --prof-cfuncs
=head1 SYNOPSIS
verilator --profile-cfuncs ....
verilator --prof-cfuncs ....
gcc --ggdb -pg ....
{run executable}
gprof
@@ -205,7 +213,7 @@ verilator_profcfunc - Read gprof report created with --profile-cfuncs
Verilator_profcfunc reads a profile report created by gprof. The names of
the functions are then transformed, assuming the user used verilator's
--profile-cfuncs, and a report printed showing the percentage of time, etc,
--prof-cfuncs, and a report printed showing the percentage of time, etc,
in each Verilog block.
=head1 ARGUMENTS
@@ -222,7 +230,7 @@ Displays this message and program version and exits.
The latest version is available from L<http://www.veripool.org/>.
Copyright 2007-2017 by Wilson Snyder. Verilator is free software; you can
Copyright 2007-2018 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.
+68 -4
View File
@@ -1,12 +1,13 @@
# DESCRIPTION: Process this file with autoconf to produce a configure script.
#
# Copyright 2003-2017 by Wilson Snyder. Verilator is free software; you can
# Copyright 2003-2018 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.
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[3.914 2017-10-14])
AC_INIT([Verilator],[3.926 2018-08-22],[https://www.veripool.org/verilator],
[verilator],[https://www.veripool.org/verilator])
# When releasing, also update header of Changes file
# and commit using "devel release" or "Version bump" message
@@ -15,6 +16,14 @@ AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk incl
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
# Ignore automake flags passed by Ubuntu builds
AC_ARG_ENABLE([dependency-tracking],
[AS_HELP_STRING([--disable-dependency-tracking], [ignored])])
AC_ARG_ENABLE([maintainer-mode],
[AS_HELP_STRING([--enable-maintainer-mode], [ignored])])
AC_ARG_ENABLE([silent-rules],
[AS_HELP_STRING([--disable-silent-rules], [ignored])])
# Special Substitutions - CFG_WITH_DEFENV
AC_MSG_CHECKING(whether to use hardcoded paths)
AC_ARG_ENABLE([defenv],
@@ -65,6 +74,21 @@ AC_ARG_ENABLE([longtests],
AC_SUBST(CFG_WITH_LONGTESTS)
AC_MSG_RESULT($CFG_WITH_LONGTESTS)
# CFG_WITH_PREC11
AC_MSG_CHECKING(whether allow pre-C++11)
AC_ARG_ENABLE([prec11],
[AS_HELP_STRING([--enable-prec11],
[enable pre-C++11 compilers])],
[case "${enableval}" in
yes) CFG_WITH_PREC11=yes ;;
no) CFG_WITH_PREC11=no ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-prec11]) ;;
esac],
[CFG_WITH_PREC11=no;]
)
AC_SUBST(CFG_WITH_PREC11)
AC_MSG_RESULT($CFG_WITH_PREC11)
# Compiler flags
CFLAGS=-I${includedir}
CPPFLAGS=-I${includedir}
@@ -77,6 +101,8 @@ AC_PROG_CXX
AC_PROG_INSTALL
AC_LANG_PUSH(C++)
cxx_version=$($CXX --version | head -1)
AC_MSG_RESULT([compiler is $CXX --version = $cxx_version])
AC_MSG_CHECKING([that C++ compiler can compile simple program])
AC_RUN_IFELSE(
[AC_LANG_SOURCE([int main() { return 0; }])],
@@ -107,7 +133,7 @@ AC_TYPE_SIZE_T
AC_C_INLINE
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([], [[int* a=new int; delete a; ]])],
[AC_LANG_PROGRAM([#include <new>], [[int* a=new int; delete a; ]])],
[], [AC_MSG_ERROR([$CXX does not seem to successfully compile a simple C++ program])])
AC_DEFUN([_MY_CXX_CHECK_FLAG],
@@ -119,7 +145,7 @@ AC_DEFUN([_MY_CXX_CHECK_FLAG],
CXXFLAGS="$CXXFLAGS $1 -Werror"
AC_MSG_CHECKING([whether $CXX accepts $1])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([], [[int* a=new int; delete a; ]])],
[AC_LANG_PROGRAM([#include <new>], [[int* a=new int; delete a; ]])],
[_my_result=yes
if test -s conftest.err; then
if grep -e "$1" conftest.err >/dev/null; then
@@ -167,9 +193,11 @@ AC_DEFUN([_MY_CXX_CHECK_OPT],
# Macros work such that first option that passes is the one we take
# gnu++14 is the newest that Verilator supports
# std++03 is the oldest that Verilator supports
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++17)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++14)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++11)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++03)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++17)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++14)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++11)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++03)
@@ -179,6 +207,7 @@ AC_SUBST(CFG_CXXFLAGS_STD_NEWEST)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++03)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++11)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++14)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=std++17)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++03)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++11)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++14)
@@ -190,6 +219,7 @@ AC_SUBST(CFG_CXXFLAGS_STD_OLDEST)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wextra)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wfloat-conversion)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wlogical-op)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wthread-safety)
AC_SUBST(CFG_CXXFLAGS_WEXTRA)
# Flags for compiling Verilator internals including parser always
@@ -217,6 +247,7 @@ AC_SUBST(CFG_CXXFLAGS_PARSER)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-faligned-new)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-fbracket-depth=4096)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-bool-operation)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-parentheses-equality)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-sign-compare)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-uninitialized)
@@ -226,6 +257,39 @@ _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-variable)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-shadow)
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
# Set CFG_WITH_THREADED if can support threading
AC_MSG_CHECKING(whether $CXX supports Verilated threads)
ACO_SAVE_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $CFG_CXXFLAGS_STD_NEWEST $CFG_CXXFLAGS_NO_UNUSED"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([#include <thread>], [[ ]])],
[_my_result=yes
if test -s conftest.err; then
if grep -e "$1" conftest.err >/dev/null; then
_my_result=no
fi
fi],
[_my_result=no])
CFG_WITH_THREADED=$_my_result
AC_SUBST(CFG_WITH_THREADED)
AC_MSG_RESULT($CFG_WITH_THREADED)
# Check compiler flag
if test "$CFG_WITH_THREADED" = "no" ; then
if test "$CFG_WITH_PREC11" = "no" ; then
AC_MSG_NOTICE([[]])
AC_MSG_ERROR([[the $CXX compiler appears to not support C++11.
Verilator plans to require a C++11 or newer compiler in a future release,
unless sufficient people report problems. Therefore, if you do not have a
C++11 compiler, please post a message to
https://www.veripool.org/boards/3/topics/2580-Verilator-Requiring-C-11-compiler
indicating your OS and when you think C++11 might be ok, and then rerun
configure with the --enable-prec11 argument. Thanks.]])
fi
fi
# Checks for library functions.
AC_CHECK_MEMBER([struct stat.st_mtim.tv_nsec],
[AC_DEFINE([HAVE_STAT_NSEC],[1],[Defined if struct stat has st_mtim.tv_nsec])],
+1 -5
View File
@@ -630,12 +630,8 @@ WARN_LOGFILE =
# with spaces.
INPUT = doxygen-mainpage \
include \
include \
src \
test_c \
test_regress \
test_sc \
test_v
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+2 -2
View File
@@ -5,7 +5,7 @@
# This calls the object directory makefile. That allows the objects to
# be placed in the "current directory" which simplifies the Makefile.
#
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2018 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@@ -23,7 +23,7 @@ endif
# real project, it is better to start with a more complete example,
# e.g. examples/tracing_c.
# If $VERILATOR_ROOT isn't in the enviornment, we assume it is part of a
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
# package inatall, and verilator is in your path. Otherwise find the
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
ifeq ($(VERILATOR_ROOT),)
+2 -2
View File
@@ -5,7 +5,7 @@
# This calls the object directory makefile. That allows the objects to
# be placed in the "current directory" which simplifies the Makefile.
#
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2018 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@@ -23,7 +23,7 @@ endif
# real project, it is better to start with a more complete example,
# e.g. examples/tracing_sc.
# If $VERILATOR_ROOT isn't in the enviornment, we assume it is part of a
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
# package inatall, and verilator is in your path. Otherwise find the
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
ifeq ($(VERILATOR_ROOT),)
+3 -3
View File
@@ -5,7 +5,7 @@
# This calls the object directory makefile. That allows the objects to
# be placed in the "current directory" which simplifies the Makefile.
#
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2018 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.
@@ -20,7 +20,7 @@ endif
######################################################################
# Set up variables
# If $VERILATOR_ROOT isn't in the enviornment, we assume it is part of a
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
# package inatall, and verilator is in your path. Otherwise find the
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
ifeq ($(VERILATOR_ROOT),)
@@ -73,7 +73,7 @@ run:
@echo
@echo "-- RUN ---------------------"
@mkdir -p logs
obj_dir/Vtop | tee logs/sim.log
obj_dir/Vtop +trace
@echo
@echo "-- COVERAGE ----------------"
+4 -1
View File
@@ -5,7 +5,7 @@
#
# This is executed in the object directory, and called by ../Makefile
#
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2018 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.
@@ -17,6 +17,9 @@ default: Vtop
# Include the rules made by Verilator
include Vtop.mk
# Use OBJCACHE (ccache) if using gmake and its installed
COMPILE.cc = $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
#######################################################################
# Compile flags
+20 -10
View File
@@ -41,14 +41,19 @@ int main(int argc, char** argv, char** env) {
// 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
// If verilator was invoked with --trace, open trace
#if VM_TRACE
Verilated::traceEverOn(true); // Verilator must compute traced signals
VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
VerilatedVcdC* tfp = new VerilatedVcdC;
top->trace(tfp, 99); // Trace 99 levels of hierarchy
mkdir("logs", 0777);
tfp->open("logs/vlt_dump.vcd"); // Open the dump file
// If verilator was invoked with --trace argument,
// and if at run time passed the +trace argument, turn on tracing
VerilatedVcdC* tfp = NULL;
const char* flag = Verilated::commandArgsPlusMatch("trace");
if (flag && 0==strcmp(flag, "+trace")) {
Verilated::traceEverOn(true); // Verilator must compute traced signals
VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
tfp = new VerilatedVcdC;
top->trace(tfp, 99); // Trace 99 levels of hierarchy
mkdir("logs", 0777);
tfp->open("logs/vlt_dump.vcd"); // Open the dump file
}
#endif
// Set some inputs
@@ -57,9 +62,9 @@ int main(int argc, char** argv, char** env) {
top->clk = 0;
top->in_small = 1;
top->in_quad = 0x1234;
top->in_wide[0] = 0x1;
top->in_wide[0] = 0x11111111;
top->in_wide[1] = 0x22222222;
top->in_wide[2] = 0x33333333;
top->in_wide[2] = 0x3;
// Simulate until $finish
while (!Verilated::gotFinish()) {
@@ -85,6 +90,11 @@ int main(int argc, char** argv, char** env) {
// Evaluate model
top->eval();
#if VM_TRACE
// Dump trace data for this cycle
if (tfp) tfp->dump (main_time);
#endif
// Read outputs
VL_PRINTF ("[%" VL_PRI64 "d] clk=%x rstl=%x iquad=%" VL_PRI64 "x"
" -> oquad=%" VL_PRI64"x owide=%x_%08x_%08x\n",
@@ -97,7 +107,7 @@ int main(int argc, char** argv, char** env) {
// Close trace if opened
#if VM_TRACE
if (tfp) { tfp->close(); }
if (tfp) { tfp->close(); tfp = NULL; }
#endif
// Coverage analysis (since test passed)
+3 -3
View File
@@ -5,7 +5,7 @@
# This calls the object directory makefile. That allows the objects to
# be placed in the "current directory" which simplifies the Makefile.
#
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2018 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.
@@ -20,7 +20,7 @@ endif
######################################################################
# Set up variables
# If $VERILATOR_ROOT isn't in the enviornment, we assume it is part of a
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
# package inatall, and verilator is in your path. Otherwise find the
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
ifeq ($(VERILATOR_ROOT),)
@@ -81,7 +81,7 @@ run:
@echo
@echo "-- RUN ---------------------"
@mkdir -p logs
obj_dir/Vtop | tee logs/sim.log
obj_dir/Vtop +trace
@echo
@echo "-- COVERAGE ----------------"
+4 -1
View File
@@ -5,7 +5,7 @@
#
# This is executed in the object directory, and called by ../Makefile
#
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2018 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.
@@ -17,6 +17,9 @@ default: Vtop
# Include the rules made by Verilator
include Vtop.mk
# Use OBJCACHE (ccache) if using gmake and its installed
COMPILE.cc = $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
#######################################################################
# Compile flags
+22 -12
View File
@@ -87,13 +87,18 @@ int sc_main(int argc, char* argv[]) {
sc_start(1);
#endif
// Turn on waves
#if VM_TRACE
cout << "Enabling waves into logs/vlt_dump.vcd...\n";
VerilatedVcdSc* tfp = new VerilatedVcdSc;
top->trace (tfp, 99);
mkdir("logs", 0777);
tfp->open ("logs/vlt_dump.vcd");
// If verilator was invoked with --trace argument,
// and if at run time passed the +trace argument, turn on tracing
VerilatedVcdSc* tfp = NULL;
const char* flag = Verilated::commandArgsPlusMatch("trace");
if (flag && 0==strcmp(flag, "+trace")) {
cout << "Enabling waves into logs/vlt_dump.vcd...\n";
tfp = new VerilatedVcdSc;
top->trace(tfp, 99);
mkdir("logs", 0777);
tfp->open("logs/vlt_dump.vcd");
}
#endif
// Simulate until $finish
@@ -102,13 +107,15 @@ int sc_main(int argc, char* argv[]) {
// Flush the wave files each cycle so we can immediately see the output
// Don't do this in "real" programs, do it in an abort() handler instead
if (tfp) tfp->flush();
#endif
// Apply inputs
if (VL_TIME_Q() > 1 && VL_TIME_Q() < 10) {
reset_l = !1; // Assert reset
} else if (VL_TIME_Q() > 1) {
reset_l = !0; // Deassert reset
}
#endif
// Simulate 1ns
#if (SYSTEMC_VERSION>=20070314)
sc_start(1,SC_NS);
@@ -117,20 +124,23 @@ int sc_main(int argc, char* argv[]) {
#endif
}
// Close Waves
#if VM_TRACE
if (tfp) tfp->close();
#endif
// Final model cleanup
top->final();
// Close trace if opened
#if VM_TRACE
if (tfp) { tfp->close(); tfp = NULL; }
#endif
// Coverage analysis (since test passed)
#if VM_COVERAGE
mkdir("logs", 0777);
VerilatedCov::write("logs/coverage.dat");
#endif
// Destroy model
delete top; top = NULL;
// Fin
return 0;
}
+634 -144
View File
File diff suppressed because it is too large Load Diff
+529 -258
View File
File diff suppressed because it is too large Load Diff
+14 -2
View File
@@ -2,7 +2,7 @@
######################################################################
# DESCRIPTION: Makefile commands for all verilated target files
#
# Copyright 2003-2017 by Wilson Snyder. Verilator is free software; you can
# Copyright 2003-2018 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.
######################################################################
@@ -109,6 +109,16 @@ ifeq ($(VM_SC),1)
endif
endif
#######################################################################
##### Threaded builds
ifneq ($(VM_THREADS),0)
ifneq ($(VM_THREADS),)
# Need C++11 at least, so always default to newest
CPPFLAGS += -DVL_THREADED $(CFG_CXXFLAGS_STD_NEWEST)
endif
endif
#######################################################################
##### Stub
@@ -176,14 +186,16 @@ endif
debug-make::
@echo
@echo CPPFLAGS: $(CPPFLAGS)
@echo VM_PREFIX: $(VM_PREFIX)
@echo VM_PARALLEL_BUILDS: $(VM_PARALLEL_BUILDS)
@echo VM_CLASSES_FAST: $(VM_CLASSES_FAST)
@echo VM_CLASSES_SLOW: $(VM_CLASSES_SLOW)
@echo VM_SUPPORT_FAST: $(VM_SUPPORT_FAST)
@echo VM_SUPPORT_SLOW: $(VM_SUPPORT_SLOW)
@echo VM_GLOBAL_FAST: $(VM_GLOBAL_FAST)
@echo VM_GLOBAL_SLOW: $(VM_GLOBAL_SLOW)
@echo CPPFLAGS: $(CPPFLAGS)
@echo VK_OBJS: $(VK_OBJS)
@echo
######################################################################
+1 -1
View File
@@ -4,7 +4,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
+64 -48
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
// Copyright 2001-2018 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.
//
@@ -96,13 +96,14 @@ private:
private:
// MEMBERS
ValueIndexMap m_valueIndexes; ///< For each key/value a unique arbitrary index value
IndexValueMap m_indexValues; ///< For each key/value a unique arbitrary index value
ItemList m_items; ///< List of all items
VerilatedMutex m_mutex; ///< Protects all members, when VL_THREADED. Wrapper deals with setting it.
ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
IndexValueMap m_indexValues VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
ItemList m_items VL_GUARDED_BY(m_mutex); ///< List of all items
VerilatedCovImpItem* m_insertp; ///< Item about to insert
const char* m_insertFilenamep; ///< Filename about to insert
int m_insertLineno; ///< Line number about to insert
VerilatedCovImpItem* m_insertp VL_GUARDED_BY(m_mutex); ///< Item about to insert
const char* m_insertFilenamep VL_GUARDED_BY(m_mutex); ///< Filename about to insert
int m_insertLineno VL_GUARDED_BY(m_mutex); ///< Line number about to insert
// CONSTRUCTORS
VerilatedCovImp() {
@@ -110,16 +111,17 @@ private:
m_insertFilenamep = NULL;
m_insertLineno = 0;
}
VL_UNCOPYABLE(VerilatedCovImp);
public:
~VerilatedCovImp() { clear(); }
static VerilatedCovImp& imp() {
~VerilatedCovImp() { clearGuts(); }
static VerilatedCovImp& imp() VL_MT_SAFE {
static VerilatedCovImp s_singleton;
return s_singleton;
}
private:
// PRIVATE METHODS
int valueIndex(const std::string& value) {
int valueIndex(const std::string& value) VL_REQUIRES(m_mutex) {
static int nextIndex = KEY_UNDEF+1;
ValueIndexMap::iterator iter = m_valueIndexes.find(value);
if (iter != m_valueIndexes.end()) return iter->second;
@@ -128,7 +130,7 @@ private:
m_indexValues.insert(std::make_pair(nextIndex, value));
return nextIndex;
}
static std::string dequote(const std::string& text) {
static std::string dequote(const std::string& text) VL_PURE {
// Quote any special characters
std::string rtn;
for (const char* pos = text.c_str(); *pos; ++pos) {
@@ -141,7 +143,7 @@ private:
}
return rtn;
}
static bool legalKey(const std::string& key) {
static bool legalKey(const std::string& key) VL_PURE {
// Because we compress long keys to a single letter, and
// don't want applications to either get confused if they use
// a letter differently, nor want them to rely on our compression...
@@ -150,7 +152,7 @@ private:
if (key.length()==2 && isdigit(key[1])) return false;
return true;
}
static std::string keyValueFormatter (const std::string& key, const std::string& value) {
static std::string keyValueFormatter(const std::string& key, const std::string& value) VL_PURE {
std::string name;
if (key.length()==1 && isalpha(key[0])) {
name += std::string("\001")+key;
@@ -160,7 +162,7 @@ private:
name += std::string("\002")+dequote(value);
return name;
}
static std::string combineHier (const std::string& old, const std::string& add) {
static std::string combineHier(const std::string& old, const std::string& add) VL_PURE {
// (foo.a.x, foo.b.x) => foo.*.x
// (foo.a.x, foo.b.y) => foo.*
// (foo.a.x, foo.b) => foo.*
@@ -194,7 +196,7 @@ private:
//cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add<<"\nch o="<<out<<endl;
return out;
}
bool itemMatchesString(VerilatedCovImpItem* itemp, const std::string& match) {
bool itemMatchesString(VerilatedCovImpItem* itemp, const std::string& match) VL_REQUIRES(m_mutex) {
for (int i=0; i<MAX_KEYS; ++i) {
if (itemp->m_keys[i] != KEY_UNDEF) {
// We don't compare keys, only values
@@ -206,21 +208,18 @@ private:
}
return false;
}
static void selftest() {
static void selftest() VL_MT_SAFE {
// Little selftest
if (combineHier ("a.b.c","a.b.c") !="a.b.c") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("a.b.c","a.b") !="a.b*") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("a.x.c","a.y.c") !="a.*.c") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("a.z.z.z.c","a.b.c") !="a.*.c") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("z","a") !="*") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("q.a","q.b") !="q.*") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("q.za","q.zb") !="q.z*") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("1.2.3.a","9.8.7.a") !="*.a") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("a.b.c","a.b.c") !="a.b.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("a.b.c","a.b") !="a.b*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("a.x.c","a.y.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("a.z.z.z.c","a.b.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("z","a") !="*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("q.a","q.b") !="q.*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("q.za","q.zb") !="q.z*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier ("1.2.3.a","9.8.7.a") !="*.a") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
}
public:
// PUBLIC METHODS
void clear() {
void clearGuts() VL_REQUIRES(m_mutex) {
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
VerilatedCovImpItem* itemp = *(it);
delete itemp;
@@ -229,7 +228,17 @@ public:
m_indexValues.clear();
m_valueIndexes.clear();
}
void clearNonMatch (const char* matchp) {
public:
// PUBLIC METHODS
void clear() VL_EXCLUDES(m_mutex) {
Verilated::quiesce();
VerilatedLockGuard lock(m_mutex);
clearGuts();
}
void clearNonMatch(const char* matchp) VL_EXCLUDES(m_mutex) {
Verilated::quiesce();
VerilatedLockGuard lock(m_mutex);
if (matchp && matchp[0]) {
ItemList newlist;
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
@@ -243,23 +252,28 @@ public:
m_items = newlist;
}
}
void zero() {
void zero() VL_EXCLUDES(m_mutex) {
Verilated::quiesce();
VerilatedLockGuard lock(m_mutex);
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
(*it)->zero();
}
}
// We assume there's always call to i/f/p in that order
void inserti (VerilatedCovImpItem* itemp) {
void inserti (VerilatedCovImpItem* itemp) VL_EXCLUDES(m_mutex) {
VerilatedLockGuard lock(m_mutex);
assert(!m_insertp);
m_insertp = itemp;
}
void insertf (const char* filenamep, int lineno) {
void insertf (const char* filenamep, int lineno) VL_EXCLUDES(m_mutex) {
VerilatedLockGuard lock(m_mutex);
m_insertFilenamep = filenamep;
m_insertLineno = lineno;
}
void insertp (const char* ckeyps[MAX_KEYS],
const char* valps[MAX_KEYS]) {
const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) {
VerilatedLockGuard lock(m_mutex);
assert(m_insertp);
// First two key/vals are filename
ckeyps[0]="filename"; valps[0]=m_insertFilenamep;
@@ -303,7 +317,7 @@ public:
addKeynum++;
if (!legalKey(key)) {
std::string msg = "%Error: Coverage keys of one character, or letter+digit are illegal: "+key;
vl_fatal("",0,"",msg.c_str());
VL_FATAL_MT("",0,"",msg.c_str());
}
}
}
@@ -312,16 +326,18 @@ public:
m_insertp = NULL;
}
void write (const char* filename) {
void write(const char* filename) VL_EXCLUDES(m_mutex) {
Verilated::quiesce();
VerilatedLockGuard lock(m_mutex);
#ifndef VM_COVERAGE
vl_fatal("",0,"","%Error: Called VerilatedCov::write when VM_COVERAGE disabled\n");
VL_FATAL_MT("",0,"","%Error: Called VerilatedCov::write when VM_COVERAGE disabled\n");
#endif
selftest();
std::ofstream os (filename);
if (os.fail()) {
std::string msg = std::string("%Error: Can't write '")+filename+"'";
vl_fatal("",0,"",msg.c_str());
VL_FATAL_MT("",0,"",msg.c_str());
return;
}
os << "# SystemC::Coverage-3\n";
@@ -385,25 +401,25 @@ public:
//=============================================================================
// VerilatedCov
void VerilatedCov::clear() {
void VerilatedCov::clear() VL_MT_SAFE {
VerilatedCovImp::imp().clear();
}
void VerilatedCov::clearNonMatch (const char* matchp) {
void VerilatedCov::clearNonMatch(const char* matchp) VL_MT_SAFE {
VerilatedCovImp::imp().clearNonMatch(matchp);
}
void VerilatedCov::zero() {
void VerilatedCov::zero() VL_MT_SAFE {
VerilatedCovImp::imp().zero();
}
void VerilatedCov::write (const char* filenamep) {
void VerilatedCov::write(const char* filenamep) VL_MT_SAFE {
VerilatedCovImp::imp().write(filenamep);
}
void VerilatedCov::_inserti (vluint32_t* itemp) {
void VerilatedCov::_inserti(vluint32_t* itemp) VL_MT_SAFE {
VerilatedCovImp::imp().inserti(new VerilatedCoverItemSpec<vluint32_t>(itemp));
}
void VerilatedCov::_inserti (vluint64_t* itemp) {
void VerilatedCov::_inserti(vluint64_t* itemp) VL_MT_SAFE {
VerilatedCovImp::imp().inserti(new VerilatedCoverItemSpec<vluint64_t>(itemp));
}
void VerilatedCov::_insertf (const char* filename, int lineno) {
void VerilatedCov::_insertf(const char* filename, int lineno) VL_MT_SAFE {
VerilatedCovImp::imp().insertf(filename,lineno);
}
@@ -413,7 +429,7 @@ void VerilatedCov::_insertf (const char* filename, int lineno) {
#define N(n) "","" // Null argument list
void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19),
A(20),A(21),A(22),A(23),A(24),A(25),A(26),A(27),A(28),A(29)) {
A(20),A(21),A(22),A(23),A(24),A(25),A(26),A(27),A(28),A(29)) VL_MT_SAFE {
const char* keyps[VerilatedCovImpBase::MAX_KEYS]
= {NULL,NULL,NULL, // filename,lineno,page
key0,key1,key2,key3,key4,key5,key6,key7,key8,key9,
@@ -428,20 +444,20 @@ void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
}
// And versions with fewer arguments (oh for a language with named parameters!)
void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)) {
void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)) VL_MT_SAFE {
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
}
void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)) {
A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)) VL_MT_SAFE {
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
C(10),C(11),C(12),C(13),C(14),C(15),C(16),C(17),C(18),C(19),
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
}
// Backward compatibility for Verilator
void VerilatedCov::_insertp (A(0), A(1), K(2),int val2, K(3),int val3,
K(4),const std::string& val4, A(5),A(6)) {
K(4),const std::string& val4, A(5),A(6)) VL_MT_SAFE {
std::string val2str = vlCovCvtToStr(val2);
std::string val3str = vlCovCvtToStr(val3);
_insertp(C(0),C(1),
+12 -10
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
// Copyright 2001-2018 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.
//
@@ -73,7 +73,7 @@
//=============================================================================
/// Convert VL_COVER_INSERT value arguments to strings
template< class T> std::string vlCovCvtToStr (const T& t) {
template< class T> std::string vlCovCvtToStr (const T& t) VL_PURE {
std::ostringstream os; os<<t; return os.str();
}
@@ -82,23 +82,25 @@ template< class T> std::string vlCovCvtToStr (const T& t) {
/// Verilator coverage global class
////
/// Global class with methods affecting all coverage data.
/// All public methods in this class are thread safe.
class VerilatedCov {
VL_UNCOPYABLE(VerilatedCov);
public:
// GLOBAL METHODS
/// Return default filename
static const char* defaultFilename() { return "coverage.dat"; }
static const char* defaultFilename() VL_PURE { return "coverage.dat"; }
/// Write all coverage data to a file
static void write (const char* filenamep = defaultFilename());
static void write (const char* filenamep = defaultFilename()) VL_MT_SAFE;
/// Insert a coverage item
/// We accept from 1-30 key/value pairs, all as strings.
/// Call _insert1, followed by _insert2 and _insert3
/// Do not call directly; use VL_COVER_INSERT or higher level macros instead
// _insert1: Remember item pointer with count. (Not const, as may add zeroing function)
static void _inserti (vluint32_t* itemp);
static void _inserti (vluint64_t* itemp);
static void _inserti (vluint32_t* itemp) VL_MT_SAFE;
static void _inserti (vluint64_t* itemp) VL_MT_SAFE;
// _insert2: Set default filename and line number
static void _insertf (const char* filename, int lineno);
static void _insertf (const char* filename, int lineno) VL_MT_SAFE;
// _insert3: Set parameters
// We could have just the maximum argument version, but this compiles
// much slower (nearly 2x) than having smaller versions also. However
@@ -120,11 +122,11 @@ public:
#undef A
#undef D
/// Clear coverage points (and call delete on all items)
static void clear();
static void clear() VL_MT_SAFE;
/// Clear items not matching the provided string
static void clearNonMatch (const char* matchp);
static void clearNonMatch (const char* matchp) VL_MT_SAFE;
/// Zero coverage points
static void zero();
static void zero() VL_MT_SAFE;
};
#endif // guard
+40 -41
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
// Copyright 2001-2018 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.
//
@@ -63,12 +63,6 @@ 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'")
//=============================================================================
// VerilatedCovKey
/// Verilator coverage global class
////
/// Global class with methods affecting all coverage data.
// VLCOVGEN_CIK_AUTO_EDIT_BEGIN
#define VL_CIK_COL0 "c0"
#define VL_CIK_COL0_NAME "C0"
@@ -102,42 +96,47 @@ VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr
#define VL_CIK_WEIGHT "w"
// VLCOVGEN_CIK_AUTO_EDIT_END
//=============================================================================
// VerilatedCovKey
/// Verilator coverage global class.
/// This class is thread safe.
class VerilatedCovKey {
public:
static std::string shortKey(const std::string& key) {
// 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 == "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;
// VLCOVGEN_SHORT_AUTO_EDIT_END
return key;
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 == "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;
// VLCOVGEN_SHORT_AUTO_EDIT_END
return key;
}
};
+563 -101
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2018 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.
@@ -16,8 +16,8 @@
/// \file
/// \brief Verilator: DPI implementation code
///
/// This file must be compiled and linked against all objects
/// created from Verilator or called by Verilator that use the DPI.
/// This file must be compiled and linked against all objects
/// created from Verilator or called by Verilator that use the DPI.
///
/// Code available from: http://www.veripool.org/verilator
///
@@ -42,11 +42,14 @@
// Not supported yet
#define _VL_SVDPI_UNIMP() \
vl_fatal(__FILE__,__LINE__,"",(std::string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str())
VL_FATAL_MT(__FILE__,__LINE__,"",(std::string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str())
#define _VL_SVDPI_WARN(message...) \
VL_PRINTF_MT(message)
// Function requires a "context" in the import declaration
#define _VL_SVDPI_CONTEXT_WARN() \
VL_PRINTF("%%Warning: DPI C Function called by Verilog DPI import with missing 'context' keyword.\n");
_VL_SVDPI_WARN("%%Warning: DPI C Function called by Verilog DPI import with missing 'context' keyword.\n");
//======================================================================
//======================================================================
@@ -61,196 +64,655 @@ const char* svDpiVersion() {
// Bit-select utility functions.
svBit svGetBitselBit(const svBitVecVal* sp, int bit) {
return VL_BITISSET_W(sp,bit);
return VL_BITRSHIFT_W(sp,bit) & 1;
}
svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) {
_VL_SVDPI_UNIMP(); return 0;
// Not VL_BITRSHIFT_W as sp is a different structure type
// Verilator doesn't support X/Z so only aval
return (((sp[VL_BITWORD_I(bit)].aval >> VL_BITBIT_I(bit)) & 1)
| (((sp[VL_BITWORD_I(bit)].bval >> VL_BITBIT_I(bit)) & 1)<<1));
}
void svPutBitselBit(svBitVecVal* dp, int bit, svBit s) {
VL_ASSIGNBIT_WI(32, bit, dp, s);
}
void svPutBitselLogic(svLogicVecVal* dp, int bit, svLogic s) {
_VL_SVDPI_UNIMP();
// Verilator doesn't support X/Z so only aval
dp[VL_BITWORD_I(bit)].aval
= ((dp[VL_BITWORD_I(bit)].aval & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
| ((s&1)<<VL_BITBIT_I(bit)));
dp[VL_BITWORD_I(bit)].bval
= ((dp[VL_BITWORD_I(bit)].bval & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
| ((s&2)>>1<<VL_BITBIT_I(bit)));
}
void svGetPartselBit(svBitVecVal* dp, const svBitVecVal* sp, int i, int w) {
_VL_SVDPI_UNIMP();
void svGetPartselBit(svBitVecVal* dp, const svBitVecVal* sp, int lsb, int width) {
// See also VL_SEL_WWI
int msb = lsb+width-1;
int word_shift = VL_BITWORD_I(lsb);
if (VL_BITBIT_I(lsb)==0) {
// Just a word extract
for (int i=0; i<VL_WORDS_I(width); ++i) dp[i] = sp[i+word_shift];
} else {
int loffset = lsb & VL_SIZEBITS_I;
int nbitsfromlow = 32-loffset; // bits that end up in lword (know loffset!=0)
// Middle words
int words = VL_WORDS_I(msb-lsb+1);
for (int i=0; i<words; ++i) {
dp[i] = sp[i+word_shift]>>loffset;
int upperword = i+word_shift+1;
if (upperword <= static_cast<int>(VL_BITWORD_I(msb))) {
dp[i] |= sp[upperword] << nbitsfromlow;
}
}
}
// Clean result
dp[VL_WORDS_I(width)-1] &= VL_MASK_I(width);
}
void svGetPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int i, int w) {
_VL_SVDPI_UNIMP();
void svGetPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int lsb, int width) {
int msb = lsb+width-1;
int word_shift = VL_BITWORD_I(lsb);
if (VL_BITBIT_I(lsb)==0) {
// Just a word extract
for (int i=0; i<VL_WORDS_I(width); ++i) dp[i] = sp[i+word_shift];
} else {
int loffset = lsb & VL_SIZEBITS_I;
int nbitsfromlow = 32-loffset; // bits that end up in lword (know loffset!=0)
// Middle words
int words = VL_WORDS_I(msb-lsb+1);
for (int i=0; i<words; ++i) {
dp[i].aval = sp[i+word_shift].aval >> loffset;
dp[i].bval = sp[i+word_shift].bval >> loffset;
int upperword = i+word_shift+1;
if (upperword <= static_cast<int>(VL_BITWORD_I(msb))) {
dp[i].aval |= sp[upperword].aval << nbitsfromlow;
dp[i].bval |= sp[upperword].bval << nbitsfromlow;
}
}
}
// Clean result
dp[VL_WORDS_I(width)-1].aval &= VL_MASK_I(width);
dp[VL_WORDS_I(width)-1].bval &= VL_MASK_I(width);
}
void svPutPartselBit(svBitVecVal* dp, const svBitVecVal s, int lbit, int width) {
// See also _VL_INSERT_WI
int hbit = lbit+width-1;
int hoffset = VL_BITBIT_I(hbit);
int loffset = VL_BITBIT_I(lbit);
if (hoffset==VL_SIZEBITS_I && loffset==0) {
// Fast and common case, word based insertion
dp[VL_BITWORD_I(lbit)] = s;
}
else {
int hword = VL_BITWORD_I(hbit);
int lword = VL_BITWORD_I(lbit);
if (hword==lword) { // know < 32 bits because above checks it
IData insmask = (VL_MASK_I(hoffset-loffset+1))<<loffset;
dp[lword] = (dp[lword] & ~insmask) | ((s<<loffset) & insmask);
} else {
IData hinsmask = (VL_MASK_I(hoffset-0+1))<<0;
IData linsmask = (VL_MASK_I(31-loffset+1))<<loffset;
int nbitsonright = 32-loffset; // bits that end up in lword
dp[lword] = (dp[lword] & ~linsmask) | ((s<<loffset) & linsmask);
dp[hword] = (dp[hword] & ~hinsmask) | ((s>>nbitsonright) & hinsmask);
}
}
}
// cppcheck-suppress passedByValue
void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal s, int lbit, int width) {
int hbit = lbit+width-1;
int hoffset = VL_BITBIT_I(hbit);
int loffset = VL_BITBIT_I(lbit);
if (hoffset==VL_SIZEBITS_I && loffset==0) {
// Fast and common case, word based insertion
dp[VL_BITWORD_I(lbit)].aval = s.aval;
dp[VL_BITWORD_I(lbit)].bval = s.bval;
}
else {
int hword = VL_BITWORD_I(hbit);
int lword = VL_BITWORD_I(lbit);
if (hword==lword) { // know < 32 bits because above checks it
IData insmask = (VL_MASK_I(hoffset-loffset+1))<<loffset;
dp[lword].aval = (dp[lword].aval & ~insmask) | ((s.aval<<loffset) & insmask);
dp[lword].bval = (dp[lword].bval & ~insmask) | ((s.bval<<loffset) & insmask);
} else {
IData hinsmask = (VL_MASK_I(hoffset-0+1))<<0;
IData linsmask = (VL_MASK_I(31-loffset+1))<<loffset;
int nbitsonright = 32-loffset; // bits that end up in lword
dp[lword].aval = (dp[lword].aval & ~linsmask) | ((s.aval<<loffset) & linsmask);
dp[lword].bval = (dp[lword].bval & ~linsmask) | ((s.bval<<loffset) & linsmask);
dp[hword].aval = (dp[hword].aval & ~hinsmask) | ((s.aval>>nbitsonright) & hinsmask);
dp[hword].bval = (dp[hword].bval & ~hinsmask) | ((s.bval>>nbitsonright) & hinsmask);
}
}
}
void svPutPartselBit(svBitVecVal* dp, const svBitVecVal s, int i, int w) {
_VL_SVDPI_UNIMP();
}
void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int i, int w) {
_VL_SVDPI_UNIMP();
//======================================================================
// Open array internals
static inline const VerilatedDpiOpenVar* _vl_openhandle_varp(const svOpenArrayHandle h) {
if (VL_UNLIKELY(!h)) {
VL_FATAL_MT(__FILE__, __LINE__, "",
"%%Error: DPI svOpenArrayHandle function called with NULL handle");
}
const VerilatedDpiOpenVar* varp = reinterpret_cast<const VerilatedDpiOpenVar*>(h);
if (VL_UNLIKELY(!varp->magicOk())) {
VL_FATAL_MT(__FILE__, __LINE__, "",
"%%Error: DPI svOpenArrayHandle function called with non-Verilator handle");
}
return varp;
}
//======================================================================
// Open array querying functions
int svLeft(const svOpenArrayHandle h, int d) {
_VL_SVDPI_UNIMP(); return 0;
return _vl_openhandle_varp(h)->left(d);
}
int svRight(const svOpenArrayHandle h, int d) {
_VL_SVDPI_UNIMP(); return 0;
return _vl_openhandle_varp(h)->right(d);
}
int svLow(const svOpenArrayHandle h, int d) {
_VL_SVDPI_UNIMP(); return 0;
return _vl_openhandle_varp(h)->low(d);
}
int svHigh(const svOpenArrayHandle h, int d) {
_VL_SVDPI_UNIMP(); return 0;
return _vl_openhandle_varp(h)->high(d);
}
int svIncrement(const svOpenArrayHandle h, int d) {
_VL_SVDPI_UNIMP(); return 0;
return _vl_openhandle_varp(h)->increment(d);
}
int svSize(const svOpenArrayHandle h, int d) {
return _vl_openhandle_varp(h)->elements(d);
}
int svDimensions(const svOpenArrayHandle h) {
_VL_SVDPI_UNIMP(); return 0;
return _vl_openhandle_varp(h)->udims();
}
void *svGetArrayPtr(const svOpenArrayHandle) {
_VL_SVDPI_UNIMP(); return NULL;
/// Return pointer to open array data, or NULL if not in IEEE standard C layout
void* svGetArrayPtr(const svOpenArrayHandle h) {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
if (VL_UNLIKELY(!varp->isDpiStdLayout())) return NULL;
return varp->datap();
}
int svSizeOfArray(const svOpenArrayHandle) {
_VL_SVDPI_UNIMP(); return 0;
}
void *svGetArrElemPtr(const svOpenArrayHandle, int indx1, ...) {
_VL_SVDPI_UNIMP(); return NULL;
}
void *svGetArrElemPtr1(const svOpenArrayHandle, int indx1) {
_VL_SVDPI_UNIMP(); return NULL;
}
void *svGetArrElemPtr2(const svOpenArrayHandle, int indx1, int indx2) {
_VL_SVDPI_UNIMP(); return NULL;
}
void *svGetArrElemPtr3(const svOpenArrayHandle, int indx1, int indx2, int indx3) {
_VL_SVDPI_UNIMP(); return NULL;
/// Return size of open array, or 0 if not in IEEE standard C layout
int svSizeOfArray(const svOpenArrayHandle h) {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
if (VL_UNLIKELY(!varp->isDpiStdLayout())) return 0;
// Truncate 64 bits to int; DPI is limited to 4GB
return static_cast<int>(varp->totalSize());
}
//======================================================================
// s=source, d=destination
// From user space into simulator storage
// Open array access internals
static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp,
int nargs, int indx1, int indx2, int indx3) {
void* datap = varp->datap();
if (VL_UNLIKELY(nargs != varp->udims())) {
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function called on"
" %d dimensional array using %d dimensional function.\n",
varp->udims(), nargs);
return NULL;
}
if (nargs>=1) {
datap = varp->datapAdjustIndex(datap, 1, indx1);
if (VL_UNLIKELY(!datap)) {
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 1 out of bounds; %d outside [%d:%d].\n",
indx1, varp->left(1), varp->right(1));
return NULL;
}
}
if (nargs>=2) {
datap = varp->datapAdjustIndex(datap, 2, indx2);
if (VL_UNLIKELY(!datap)) {
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 2 out of bounds; %d outside [%d:%d].\n",
indx2, varp->left(2), varp->right(2));
return NULL;
}
}
if (nargs>=3) {
datap = varp->datapAdjustIndex(datap, 3, indx3);
if (VL_UNLIKELY(!datap)) {
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 3 out of bounds; %d outside [%d:%d].\n",
indx1, varp->left(3), varp->right(3));
return NULL;
}
}
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 NULL if outside range
static void* _vl_svGetArrElemPtr(const svOpenArrayHandle h,
int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
if (VL_UNLIKELY(!varp->isDpiStdLayout())) return NULL;
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
return datap;
}
/// Copy to user bit array from simulator open array
static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s,
int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE {
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()) {
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;
case VLVT_UINT64: {
WData lwp[2]; VL_SET_WQ(lwp, *(reinterpret_cast<QData*>(datap)));
d[0] = lwp[0]; d[1] = lwp[1];
break;
}
case VLVT_WDATA: {
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
for (int i=0; i<VL_WORDS_I(varp->packed().elements()); ++i) d[i] = wdatap[i];
return;
}
default:
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
return;
}
}
/// Copy to user logic array from simulator open array
static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s,
int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE {
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()) {
case VLVT_UINT8: d[0].aval = *(reinterpret_cast<CData*>(datap)); d[0].bval=0; return;
case VLVT_UINT16: d[0].aval = *(reinterpret_cast<SData*>(datap)); d[0].bval=0; return;
case VLVT_UINT32: d[0].aval = *(reinterpret_cast<IData*>(datap)); d[0].bval=0; return;
case VLVT_UINT64: {
WData lwp[2]; VL_SET_WQ(lwp, *(reinterpret_cast<QData*>(datap)));
d[0].aval = lwp[0]; d[0].bval=0;
d[1].aval = lwp[1]; d[0].bval=0;
break;
}
case VLVT_WDATA: {
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
for (int i=0; i<VL_WORDS_I(varp->packed().elements()); ++i) {
d[i].aval = wdatap[i]; d[i].bval = 0;
}
return;
}
default:
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
return;
}
}
/// Copy to simulator open array from from user bit array
static void _vl_svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s,
int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE {
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()) {
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;
case VLVT_UINT64: *(reinterpret_cast<QData*>(datap)) = _VL_SET_QII(s[1], s[0]); break;
case VLVT_WDATA: {
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
for (int i=0; i<VL_WORDS_I(varp->packed().elements()); ++i) wdatap[i] = s[i];
return;
}
default:
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
return;
}
}
/// Copy to simulator open array from from user logic array
static void _vl_svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE {
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()) {
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;
case VLVT_UINT64: *(reinterpret_cast<QData*>(datap)) = _VL_SET_QII(s[1].aval, s[0].aval); break;
case VLVT_WDATA: {
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
for (int i=0; i<VL_WORDS_I(varp->packed().elements()); ++i) wdatap[i] = s[i].aval;
return;
}
default:
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
return;
}
}
/// Return bit from simulator open array
static svBit _vl_svGetBitArrElem(const svOpenArrayHandle s,
int nargs, int indx1, int indx2, 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;
}
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)) & VL_ULL(1);
case VLVT_WDATA: {
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
return VL_BITRSHIFT_W(wdatap, lsb) & 1;
}
default:
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
return 0;
}
}
/// Update simulator open array from bit
static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value,
int nargs, int indx1, int indx2, int indx3, int indx4) VL_MT_SAFE {
// 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;
}
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:
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
return;
}
}
//======================================================================
// DPI accessors that simply call above functions
void* svGetArrElemPtr(const svOpenArrayHandle h, int indx1, ...) {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
void* datap;
va_list ap;
va_start(ap, indx1);
// va_arg is a macro, so need temporaries as used below
switch (varp->udims()) {
case 1: datap = _vl_svGetArrElemPtr(h, 1, indx1, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
datap = _vl_svGetArrElemPtr(h, 2, indx1, indx2, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
datap = _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3); break; }
default: datap = _vl_svGetArrElemPtr(h, -1, 0, 0, 0); break; // Will error
}
va_end(ap);
return datap;
}
void* svGetArrElemPtr1(const svOpenArrayHandle h, int indx1) {
return _vl_svGetArrElemPtr(h, 1, indx1, 0, 0);
}
void* svGetArrElemPtr2(const svOpenArrayHandle h, int indx1, int indx2) {
return _vl_svGetArrElemPtr(h, 2, indx1, indx2, 0);
}
void* svGetArrElemPtr3(const svOpenArrayHandle h, int indx1, int indx2, int indx3) {
return _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3);
}
void svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s,
int indx1, ...) {
_VL_SVDPI_UNIMP();
int indx1, ...) {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
va_list ap;
va_start(ap, indx1);
switch (varp->udims()) {
case 1: _vl_svPutBitArrElemVecVal(d, s, 1, indx1, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
_vl_svPutBitArrElemVecVal(d, s, 2, indx1, indx2, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
_vl_svPutBitArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; }
default: _vl_svPutBitArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
}
va_end(ap);
}
void svPutBitArrElem1VecVal(const svOpenArrayHandle d, const svBitVecVal* s,
int indx1) {
_VL_SVDPI_UNIMP();
int indx1) {
_vl_svPutBitArrElemVecVal(d, s, 1, indx1, 0, 0);
}
void svPutBitArrElem2VecVal(const svOpenArrayHandle d, const svBitVecVal* s,
int indx1, int indx2) {
_VL_SVDPI_UNIMP();
int indx1, int indx2) {
_vl_svPutBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
}
void svPutBitArrElem3VecVal(const svOpenArrayHandle d, const svBitVecVal* s,
int indx1, int indx2, int indx3) {
_VL_SVDPI_UNIMP();
int indx1, int indx2, int indx3) {
_vl_svPutBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
}
void svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
int indx1, ...) {
_VL_SVDPI_UNIMP();
int indx1, ...) {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
va_list ap;
va_start(ap, indx1);
switch (varp->udims()) {
case 1: _vl_svPutLogicArrElemVecVal(d, s, 1, indx1, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
_vl_svPutLogicArrElemVecVal(d, s, 2, indx1, indx2, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
_vl_svPutLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; }
default: _vl_svPutLogicArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
}
va_end(ap);
}
void svPutLogicArrElem1VecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
int indx1) {
_VL_SVDPI_UNIMP();
int indx1) {
_vl_svPutLogicArrElemVecVal(d, s, 1, indx1, 0, 0);
}
void svPutLogicArrElem2VecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
int indx1, int indx2) {
_VL_SVDPI_UNIMP();
int indx1, int indx2) {
_vl_svPutLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
}
void svPutLogicArrElem3VecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
int indx1, int indx2, int indx3) {
_VL_SVDPI_UNIMP();
int indx1, int indx2, int indx3) {
_vl_svPutLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
}
//======================================================================
// From simulator storage into user space
void svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s,
int indx1, ...) {
_VL_SVDPI_UNIMP();
int indx1, ...) {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
va_list ap;
va_start(ap, indx1);
switch (varp->udims()) {
case 1: _vl_svGetBitArrElemVecVal(d, s, 1, indx1, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
_vl_svGetBitArrElemVecVal(d, s, 2, indx1, indx2, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
_vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; }
default: _vl_svGetBitArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
}
va_end(ap);
}
void svGetBitArrElem1VecVal(svBitVecVal* d, const svOpenArrayHandle s,
int indx1) {
_VL_SVDPI_UNIMP();
int indx1) {
_vl_svGetBitArrElemVecVal(d, s, 1, indx1, 0, 0);
}
void svGetBitArrElem2VecVal(svBitVecVal* d, const svOpenArrayHandle s,
int indx1, int indx2) {
_VL_SVDPI_UNIMP();
int indx1, int indx2) {
_vl_svGetBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
}
void svGetBitArrElem3VecVal(svBitVecVal* d, const svOpenArrayHandle s,
int indx1, int indx2, int indx3) {
_VL_SVDPI_UNIMP();
int indx1, int indx2, int indx3) {
_vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
}
void svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s,
int indx1, ...) {
_VL_SVDPI_UNIMP();
int indx1, ...) {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
va_list ap;
va_start(ap, indx1);
switch (varp->udims()) {
case 1: _vl_svGetLogicArrElemVecVal(d, s, 1, indx1, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
_vl_svGetLogicArrElemVecVal(d, s, 2, indx1, indx2, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
_vl_svGetLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; }
default: _vl_svGetLogicArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
}
va_end(ap);
}
void svGetLogicArrElem1VecVal(svLogicVecVal* d, const svOpenArrayHandle s,
int indx1) {
_VL_SVDPI_UNIMP();
int indx1) {
_vl_svGetLogicArrElemVecVal(d, s, 1, indx1, 0, 0);
}
void svGetLogicArrElem2VecVal(svLogicVecVal* d, const svOpenArrayHandle s,
int indx1, int indx2) {
_VL_SVDPI_UNIMP();
int indx1, int indx2) {
_vl_svGetLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
}
void svGetLogicArrElem3VecVal(svLogicVecVal* d, const svOpenArrayHandle s,
int indx1, int indx2, int indx3) {
_VL_SVDPI_UNIMP();
int indx1, int indx2, int indx3) {
_vl_svGetLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
}
svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...) {
_VL_SVDPI_UNIMP(); return 0;
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
svBit out;
va_list ap;
va_start(ap, indx1);
switch (varp->udims()) {
case 1: out = _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
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);
return out;
}
svBit svGetBitArrElem1(const svOpenArrayHandle s, int indx1) {
_VL_SVDPI_UNIMP(); return 0;
return _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0);
}
svBit svGetBitArrElem2(const svOpenArrayHandle s, int indx1, int indx2) {
_VL_SVDPI_UNIMP(); return 0;
return _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0);
}
svBit svGetBitArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3) {
_VL_SVDPI_UNIMP(); return 0;
return _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
}
svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...) {
_VL_SVDPI_UNIMP(); return sv_x;
// Verilator doesn't support X/Z so can just call Bit version
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
svBit out;
va_list ap;
va_start(ap, indx1);
switch (varp->udims()) {
case 1: out = _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
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);
return out;
}
svLogic svGetLogicArrElem1(const svOpenArrayHandle s, int indx1) {
_VL_SVDPI_UNIMP(); return sv_x;
// Verilator doesn't support X/Z so can just call Bit version
return svGetBitArrElem1(s, indx1);
}
svLogic svGetLogicArrElem2(const svOpenArrayHandle s, int indx1, int indx2) {
_VL_SVDPI_UNIMP(); return sv_x;
// Verilator doesn't support X/Z so can just call Bit version
return svGetBitArrElem2(s, indx1, indx2);
}
svLogic svGetLogicArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3) {
_VL_SVDPI_UNIMP(); return sv_x;
}
void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1, ...) {
_VL_SVDPI_UNIMP();
}
void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1) {
_VL_SVDPI_UNIMP();
}
void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1, int indx2) {
_VL_SVDPI_UNIMP();
}
void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1, int indx2, int indx3) {
_VL_SVDPI_UNIMP();
// Verilator doesn't support X/Z so can just call Bit version
return svGetBitArrElem3(s, indx1, indx2, indx3);
}
void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...) {
_VL_SVDPI_UNIMP();
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
va_list ap;
va_start(ap, indx1);
switch (varp->udims()) {
case 1: _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
_vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
_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);
}
void svPutBitArrElem1(const svOpenArrayHandle d, svBit value, int indx1) {
_VL_SVDPI_UNIMP();
_vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0);
}
void svPutBitArrElem2(const svOpenArrayHandle d, svBit value, int indx1, int indx2) {
_VL_SVDPI_UNIMP();
_vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0);
}
void svPutBitArrElem3(const svOpenArrayHandle d, svBit value, int indx1, int indx2, int indx3) {
_VL_SVDPI_UNIMP();
_vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
}
void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1, ...) {
// Verilator doesn't support X/Z so can just call Bit version
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
va_list ap;
va_start(ap, indx1);
switch (varp->udims()) {
case 1: _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
_vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
_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);
}
void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1) {
// Verilator doesn't support X/Z so can just call Bit version
svPutBitArrElem1(d, value, indx1);
}
void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1, int indx2) {
// Verilator doesn't support X/Z so can just call Bit version
svPutBitArrElem2(d, value, indx1, indx2);
}
void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1, int indx2, int indx3) {
// Verilator doesn't support X/Z so can just call Bit version
svPutBitArrElem3(d, value, indx1, indx2, indx3);
}
//======================================================================
@@ -277,7 +739,7 @@ svScope svGetScopeFromName(const char* scopeName) {
return (svScope)VerilatedImp::scopeFind(scopeName);
}
int svPutUserData(const svScope scope, void *userKey, void* userData) {
int svPutUserData(const svScope scope, void* userKey, void* userData) {
VerilatedImp::userInsert(scope,userKey,userData);
return 0;
}
+29 -12
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -28,36 +28,53 @@
#ifndef _VERILATED_DPI_H_
#define _VERILATED_DPI_H_ 1 ///< Header Guard
#include "verilated.h" // Presumed done by caller
#include "verilated.h" // Also presumably included by caller
#include "verilated_sym_props.h"
#include "svdpi.h"
//===================================================================
// SETTING OPERATORS
/// Return WData from svBitVecVal
static inline void VL_SET_W_SVBV(int obits, WDataOutP owp, const svBitVecVal* lwp) VL_MT_SAFE {
int words = VL_WORDS_I(obits);
for (int i=0; i<words-1; ++i) owp[i]=lwp[i];
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
}
/// Return svBitVecVal from WData
static inline void VL_SET_W_SVBV(int obits, WDataOutP owp, svBitVecVal* lwp) {
static inline void VL_SET_SVBV_W(int obits, svBitVecVal* owp, WDataInP lwp) VL_MT_SAFE {
int words = VL_WORDS_I(obits);
for (int i=0; i<words-1; ++i) owp[i]=lwp[i];
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
}
static inline void VL_SET_SVBV_W(int obits, svBitVecVal* owp, WDataInP lwp) {
int words = VL_WORDS_I(obits);
for (int i=0; i<words-1; ++i) owp[i]=lwp[i];
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
}
static inline void VL_SET_W_SVLV(int obits, WDataOutP owp, svLogicVecVal* lwp) {
// Note we ignore X/Z in svLogicVecVal
/// Convert svLogicVecVal to/from WData
/// Note these functions ignore X/Z in svLogicVecVal
static inline void VL_SET_W_SVLV(int obits, WDataOutP owp, const svLogicVecVal* lwp) VL_MT_SAFE {
int words = VL_WORDS_I(obits);
for (int i=0; i<words-1; ++i) owp[i]=lwp[i].aval;
owp[words-1] = lwp[words-1].aval & VL_MASK_I(obits);
}
static inline void VL_SET_SVLV_W(int obits, svLogicVecVal* owp, WDataInP lwp) {
// Note we don't create X/Z in svLogicVecVal
static inline QData VL_SET_Q_SVLV(const svLogicVecVal* lwp) VL_MT_SAFE {
return _VL_SET_QII(lwp[1].aval, lwp[0].aval);
}
static inline IData VL_SET_I_SVLV(const svLogicVecVal* lwp) VL_MT_SAFE {
return lwp[0].aval;
}
static inline void VL_SET_SVLV_W(int obits, svLogicVecVal* owp, WDataInP lwp) VL_MT_SAFE {
int words = VL_WORDS_I(obits);
for (int i=0; i<words; ++i) owp[i].bval=0;
for (int i=0; i<words-1; ++i) owp[i].aval=lwp[i];
owp[words-1].aval = lwp[words-1] & VL_MASK_I(obits);
}
static inline void VL_SET_SVLV_I(int, svLogicVecVal* owp, IData ld) VL_MT_SAFE {
owp[0].aval=ld; owp[0].bval=0;
}
static inline void VL_SET_SVLV_Q(int, svLogicVecVal* owp, QData ld) VL_MT_SAFE {
WData lwp[2]; VL_SET_WQ(lwp,ld);
owp[0].aval=lwp[0]; owp[0].bval=0;
owp[1].aval=lwp[1]; owp[1].bval=0;
}
//======================================================================
+25 -18
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2010-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2010-2018 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.
@@ -36,49 +36,56 @@
//======================================================================
// Conversion functions
extern std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp);
inline std::string VL_CVT_PACK_STR_NQ(QData lhs) {
extern std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) VL_MT_SAFE;
inline std::string VL_CVT_PACK_STR_NQ(QData lhs) VL_PURE {
WData lw[2]; VL_SET_WQ(lw, lhs);
return VL_CVT_PACK_STR_NW(2, lw);
}
inline std::string VL_CVT_PACK_STR_NN(const std::string& lhs) {
inline std::string VL_CVT_PACK_STR_NN(const std::string& lhs) VL_PURE {
return lhs;
}
inline std::string VL_CVT_PACK_STR_NI(IData lhs) {
inline std::string VL_CVT_PACK_STR_NI(IData lhs) VL_PURE {
WData lw[1]; lw[0] = lhs;
return VL_CVT_PACK_STR_NW(1, lw);
}
inline std::string VL_CONCATN_NNN(const std::string& lhs, const std::string& rhs) {
inline std::string VL_CONCATN_NNN(const std::string& lhs, const std::string& rhs) VL_PURE {
return lhs+rhs;
}
inline std::string VL_REPLICATEN_NNQ(int,int,int, const std::string& lhs, IData rep) {
inline std::string VL_REPLICATEN_NNQ(int,int,int, const std::string& lhs, IData rep) VL_PURE {
std::string out; out.reserve(lhs.length() * rep);
for (unsigned times=0; times<rep; ++times) out += lhs;
return out;
}
inline std::string VL_REPLICATEN_NNI(int obits,int lbits,int rbits, const std::string& lhs, IData rep) {
inline std::string VL_REPLICATEN_NNI(int obits,int lbits,int rbits,
const std::string& lhs, IData rep) VL_PURE {
return VL_REPLICATEN_NNQ(obits,lbits,rbits,lhs,rep);
}
extern IData VL_FOPEN_NI(const std::string& filename, IData mode);
extern void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
const std::string& ofilename, void* memp, IData start, IData end);
extern IData VL_SSCANF_INX(int lbits, const std::string& ld, const char* formatp, ...);
extern void VL_SFORMAT_X(int obits_ignored, std::string &output, const char* formatp, ...);
extern std::string VL_SFORMATF_NX(const char* formatp, ...);
extern IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rdp);
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, IData& rdr) {
inline IData VL_LEN_IN(const std::string& ld) { return ld.length(); }
extern IData VL_FOPEN_NI(const std::string& filename, IData mode) VL_MT_SAFE;
extern void VL_READMEM_N(bool hex, int width, int depth, int array_lsb,
const std::string& ofilename,
void* memp, IData start, IData end) VL_MT_SAFE;
extern void VL_WRITEMEM_N(bool hex, int width, int depth, int array_lsb,
const std::string& ofilename,
const void* memp, IData start, IData end) VL_MT_SAFE;
extern IData VL_SSCANF_INX(int lbits, const std::string& ld, const char* formatp, ...) VL_MT_SAFE;
extern void VL_SFORMAT_X(int obits_ignored, std::string& output, const char* formatp, ...) VL_MT_SAFE;
extern std::string VL_SFORMATF_NX(const char* formatp, ...) VL_MT_SAFE;
extern IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rdp) VL_MT_SAFE;
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, IData& rdr) VL_MT_SAFE {
WData rwp[2]; // WData must always be at least 2
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
if (got) rdr = rwp[0];
return got;
}
inline IData VL_VALUEPLUSARGS_INQ(int rbits, const std::string& ld, QData& rdr) {
inline IData VL_VALUEPLUSARGS_INQ(int rbits, const std::string& ld, QData& rdr) VL_MT_SAFE {
WData rwp[2];
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
if (got) rdr = VL_SET_QW(rwp);
return got;
}
extern IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr);
extern IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr) VL_MT_SAFE;
#endif // Guard
+201 -59
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2018 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,14 +34,138 @@
#include "verilated_syms.h"
#include <map>
#include <set>
#include <vector>
#include <deque>
#include <string>
#ifdef VL_THREADED
# include <functional>
# include <queue>
#endif
class VerilatedScope;
//======================================================================
// Types
// Threaded message passing
#ifdef VL_THREADED
/// Message, enqueued on an mtask, and consumed on the main eval thread
class VerilatedMsg {
public:
// TYPES
struct Cmp {
bool operator() (const VerilatedMsg& a, const VerilatedMsg& b) const {
return a.mtaskId() < b.mtaskId(); }
};
private:
// MEMBERS
vluint32_t m_mtaskId; ///< MTask that did enqueue
std::function<void()> m_cb; ///< Lambda to execute when message received
public:
// CONSTRUCTORS
VerilatedMsg(const std::function<void()>& cb)
: m_mtaskId(Verilated::mtaskId()), m_cb(cb) {}
~VerilatedMsg() {}
// METHODS
vluint32_t mtaskId() const { return m_mtaskId; }
/// Execute the lambda function
void run() const { m_cb(); }
};
/// Each thread has a queue it pushes to
/// This assumes no thread starts pushing the next tick until the previous has drained.
/// If more aggressiveness is needed, a double-buffered scheme might work well.
class VerilatedEvalMsgQueue {
typedef std::multiset<VerilatedMsg, VerilatedMsg::Cmp> VerilatedThreadQueue;
std::atomic<vluint64_t> m_depth; ///< Current depth of queue (see comments below)
VerilatedMutex m_mutex; ///< Mutex protecting queue
VerilatedThreadQueue m_queue VL_GUARDED_BY(m_mutex); ///< Message queue
public:
// CONSTRUCTORS
VerilatedEvalMsgQueue() : m_depth(0) {
assert(atomic_is_lock_free(&m_depth));
}
~VerilatedEvalMsgQueue() { }
private:
VL_UNCOPYABLE(VerilatedEvalMsgQueue);
public:
// METHODS
//// Add message to queue (called by producer)
void post(const VerilatedMsg& msg) VL_EXCLUDES(m_mutex) {
VerilatedLockGuard lock(m_mutex);
m_queue.insert(msg); // Pass by value to copy the message into queue
++m_depth;
}
/// Service queue until completion (called by consumer)
void process() VL_EXCLUDES(m_mutex) {
// Tracking m_depth is redundant to e.g. getting the mutex and looking at queue size,
// but on the reader side it's 4x faster to test an atomic then getting a mutex
while (m_depth) {
// Wait for a message to be added to the queue
// We don't use unique_lock as want to unlock with the message copy still in scope
m_mutex.lock();
assert(!m_queue.empty()); // Otherwise m_depth is wrong
// Unfortunately to release the lock we need to copy the message
// (Or have the message be a pointer, but then new/delete cost on each message)
// We assume messages are small, so copy
auto it = m_queue.begin();
const VerilatedMsg msg = *(it);
m_queue.erase(it);
m_mutex.unlock();
m_depth--; // Ok if outside critical section as only this code checks the value
{
VL_DEBUG_IF(VL_DBG_MSGF("Executing callback from mtaskId=%d\n", msg.mtaskId()););
msg.run();
}
}
}
};
/// Each thread has a local queue to build up messages until the end of the eval() call
class VerilatedThreadMsgQueue {
std::queue<VerilatedMsg> m_queue;
public:
// CONSTRUCTORS
VerilatedThreadMsgQueue() { }
~VerilatedThreadMsgQueue() {
// The only call of this with a non-empty queue is a fatal error.
// So this does not flush the queue, as the destination queue is not known to this class.
}
private:
VL_UNCOPYABLE(VerilatedThreadMsgQueue);
// METHODS
static VerilatedThreadMsgQueue& threadton() {
static VL_THREAD_LOCAL VerilatedThreadMsgQueue t_s;
return t_s;
}
public:
/// Add message to queue, called by producer
static void post(const VerilatedMsg& msg) VL_MT_SAFE {
// Handle calls to threaded routines outside
// of any mtask -- if an initial block calls $finish, say.
if (Verilated::mtaskId() == 0) {
// No queueing, just do the action immediately
msg.run();
} else {
Verilated::endOfEvalReqdInc();
threadton().m_queue.push(msg); // Pass by value to copy the message into queue
}
}
/// Push all messages to the eval's queue
static void flush(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
while (!threadton().m_queue.empty()) {
evalMsgQp->post(threadton().m_queue.front());
threadton().m_queue.pop();
Verilated::endOfEvalReqdDec();
}
}
};
#endif // VL_THREADED
//======================================================================
// VerilatedImp
class VerilatedImp {
// Whole class is internal use only - Global information shared between verilated*.cpp files.
@@ -56,58 +180,55 @@ class VerilatedImp {
// Nothing here is save-restored; users expected to re-register appropriately
ArgVec m_argVec; ///< Argument list (NOT save-restored, may want different results)
bool m_argVecLoaded; ///< Ever loaded argument list
UserMap m_userMap; ///< Map of <(scope,userkey), userData>
VerilatedScopeNameMap m_nameMap; ///< Map of <scope_name, scope pointer>
VerilatedMutex m_argMutex; ///< Protect m_argVec, m_argVecLoaded
ArgVec m_argVec VL_GUARDED_BY(m_argMutex); ///< Argument list (NOT save-restored, may want different results)
bool m_argVecLoaded VL_GUARDED_BY(m_argMutex); ///< Ever loaded argument list
VerilatedMutex m_userMapMutex; ///< Protect m_userMap
UserMap m_userMap VL_GUARDED_BY(m_userMapMutex); ///< Map of <(scope,userkey), userData>
VerilatedMutex m_nameMutex; ///< Protect m_nameMap
VerilatedScopeNameMap m_nameMap VL_GUARDED_BY(m_nameMutex); ///< Map of <scope_name, scope pointer>
// Slow - somewhat static:
ExportNameMap m_exportMap; ///< Map of <export_func_proto, func number>
int m_exportNext; ///< Next export funcnum
VerilatedMutex m_exportMutex; ///< Protect m_nameMap
ExportNameMap m_exportMap VL_GUARDED_BY(m_exportMutex); ///< Map of <export_func_proto, func number>
int m_exportNext VL_GUARDED_BY(m_exportMutex); ///< Next export funcnum
// File I/O
std::vector<FILE*> m_fdps; ///< File descriptors
std::deque<IData> m_fdFree; ///< List of free descriptors (SLOW - FOPEN/CLOSE only)
VerilatedMutex m_fdMutex; ///< Protect m_fdps, m_fdFree
std::vector<FILE*> m_fdps VL_GUARDED_BY(m_fdMutex); ///< File descriptors
std::deque<IData> m_fdFree VL_GUARDED_BY(m_fdMutex); ///< List of free descriptors (SLOW - FOPEN/CLOSE only)
public: // But only for verilated*.cpp
// CONSTRUCTORS
VerilatedImp() : m_argVecLoaded(false), m_exportNext(0) {
VerilatedImp()
: m_argVecLoaded(false), m_exportNext(0) {
m_fdps.resize(3);
m_fdps[0] = stdin;
m_fdps[1] = stdout;
m_fdps[2] = stderr;
}
~VerilatedImp() {}
static void internalsDump() {
VL_PRINTF("internalsDump:\n");
VL_PRINTF(" Argv:");
for (ArgVec::const_iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
VL_PRINTF(" %s",it->c_str());
}
VL_PRINTF("\n");
VL_PRINTF(" Version: %s %s\n", Verilated::productName(), Verilated::productVersion());
scopesDump();
exportsDump();
userDump();
}
private:
VL_UNCOPYABLE(VerilatedImp);
public:
// METHODS - debug
static void internalsDump() VL_MT_SAFE;
static void versionDump() VL_MT_SAFE;
// METHODS - arguments
static void commandArgs(int argc, const char** argv) {
s_s.m_argVec.clear(); // Always clear
commandArgsAdd(argc, argv);
}
static void commandArgsAdd(int argc, const char** argv) {
if (!s_s.m_argVecLoaded) s_s.m_argVec.clear();
for (int i=0; i<argc; ++i) s_s.m_argVec.push_back(argv[i]);
s_s.m_argVecLoaded = true; // Can't just test later for empty vector, no arguments is ok
}
static std::string argPlusMatch(const char* prefixp) {
public:
static void commandArgs(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex);
static void commandArgsAdd(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex);
static std::string argPlusMatch(const char* prefixp) VL_EXCLUDES(s_s.m_argMutex) {
VerilatedLockGuard lock(s_s.m_argMutex);
// Note prefixp does not include the leading "+"
size_t len = strlen(prefixp);
if (VL_UNLIKELY(!s_s.m_argVecLoaded)) {
s_s.m_argVecLoaded = true; // Complain only once
vl_fatal("unknown",0,"",
"%Error: Verilog called $test$plusargs or $value$plusargs without"
" testbench C first calling Verilated::commandArgs(argc,argv).");
VL_FATAL_MT("unknown",0,"",
"%Error: Verilog called $test$plusargs or $value$plusargs without"
" testbench C first calling Verilated::commandArgs(argc,argv).");
}
for (ArgVec::const_iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
if ((*it)[0]=='+') {
@@ -116,26 +237,32 @@ public: // But only for verilated*.cpp
}
return "";
}
private:
static void commandArgsAddGuts(int argc, const char** argv) VL_REQUIRES(s_s.m_argMutex);
public:
// METHODS - user scope tracking
// We implement this as a single large map instead of one map per scope
// There's often many more scopes than userdata's and thus having a ~48byte
// per map overhead * N scopes would take much more space and cache thrashing.
static inline void userInsert(const void* scopep, void* userKey, void* userData) {
static inline void userInsert(const void* scopep, void* userKey, void* userData) VL_MT_SAFE {
VerilatedLockGuard lock(s_s.m_userMapMutex);
UserMap::iterator it=s_s.m_userMap.find(std::make_pair(scopep,userKey));
if (it != s_s.m_userMap.end()) it->second = userData;
// When we support VL_THREADs, we need a lock around this insert, as it's runtime
else s_s.m_userMap.insert(it, std::make_pair(std::make_pair(scopep,userKey),userData));
}
static inline void* userFind(const void* scopep, void* userKey) {
static inline void* userFind(const void* scopep, void* userKey) VL_MT_SAFE {
VerilatedLockGuard lock(s_s.m_userMapMutex);
UserMap::const_iterator it=s_s.m_userMap.find(std::make_pair(scopep,userKey));
if (VL_LIKELY(it != s_s.m_userMap.end())) return it->second;
else return NULL;
}
private:
/// Symbol table destruction cleans up the entries for each scope.
static void userEraseScope(const VerilatedScope* scopep) {
static void userEraseScope(const VerilatedScope* scopep) VL_MT_SAFE {
// Slow ok - called once/scope on destruction, so we simply iterate.
VerilatedLockGuard lock(s_s.m_userMapMutex);
for (UserMap::iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ) {
if (it->first.first == scopep) {
s_s.m_userMap.erase(it++);
@@ -144,44 +271,50 @@ private:
}
}
}
static void userDump() {
static void userDump() VL_MT_SAFE {
VerilatedLockGuard lock(s_s.m_userMapMutex); // Avoid it changing in middle of dump
bool first = true;
for (UserMap::const_iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) {
if (first) { VL_PRINTF(" userDump:\n"); first=false; }
VL_PRINTF(" DPI_USER_DATA scope %p key %p: %p\n",
if (first) { VL_PRINTF_MT(" userDump:\n"); first=false; }
VL_PRINTF_MT(" DPI_USER_DATA scope %p key %p: %p\n",
it->first.first, it->first.second, it->second);
}
}
public: // But only for verilated*.cpp
// METHODS - scope name
static void scopeInsert(const VerilatedScope* scopep) {
static void scopeInsert(const VerilatedScope* scopep) VL_MT_SAFE {
// Slow ok - called once/scope at construction
VerilatedLockGuard lock(s_s.m_nameMutex);
VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
if (it == s_s.m_nameMap.end()) {
s_s.m_nameMap.insert(it, std::make_pair(scopep->name(),scopep));
}
}
static inline const VerilatedScope* scopeFind(const char* namep) {
static inline const VerilatedScope* scopeFind(const char* namep) VL_MT_SAFE {
VerilatedLockGuard lock(s_s.m_nameMutex); // If too slow, can assume this is only VL_MT_SAFE_POSINIT
VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.find(namep);
if (VL_LIKELY(it != s_s.m_nameMap.end())) return it->second;
else return NULL;
}
static void scopeErase(const VerilatedScope* scopep) {
static void scopeErase(const VerilatedScope* scopep) VL_MT_SAFE {
// Slow ok - called once/scope at destruction
VerilatedLockGuard lock(s_s.m_nameMutex);
userEraseScope(scopep);
VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
if (it != s_s.m_nameMap.end()) s_s.m_nameMap.erase(it);
}
static void scopesDump() {
VL_PRINTF(" scopesDump:\n");
static void scopesDump() VL_MT_SAFE {
VerilatedLockGuard lock(s_s.m_nameMutex);
VL_PRINTF_MT(" scopesDump:\n");
for (VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) {
const VerilatedScope* scopep = it->second;
scopep->scopeDump();
}
VL_PRINTF("\n");
VL_PRINTF_MT("\n");
}
static const VerilatedScopeNameMap* scopeNameMap() {
static const VerilatedScopeNameMap* scopeNameMap() VL_MT_SAFE_POSTINIT {
// Thread save only assuming this is called only after model construction completed
return &s_s.m_nameMap;
}
@@ -194,8 +327,9 @@ public: // But only for verilated*.cpp
// in the design that also happen to have our same callback function.
// Rather than a 2D map, the integer scheme saves 500ish ns on a likely
// miss at the cost of a multiply, and all lookups move to slowpath.
static int exportInsert(const char* namep) {
static int exportInsert(const char* namep) VL_MT_SAFE {
// Slow ok - called once/function at creation
VerilatedLockGuard lock(s_s.m_exportMutex);
ExportNameMap::iterator it=s_s.m_exportMap.find(namep);
if (it == s_s.m_exportMap.end()) {
s_s.m_exportMap.insert(it, std::make_pair(namep, s_s.m_exportNext++));
@@ -204,26 +338,29 @@ public: // But only for verilated*.cpp
return it->second;
}
}
static int exportFind(const char* namep) {
static int exportFind(const char* namep) VL_MT_SAFE {
VerilatedLockGuard lock(s_s.m_exportMutex);
ExportNameMap::const_iterator it=s_s.m_exportMap.find(namep);
if (VL_LIKELY(it != s_s.m_exportMap.end())) return it->second;
std::string msg = (std::string("%Error: Testbench C called ")+namep
+" but no such DPI export function name exists in ANY model");
vl_fatal("unknown",0,"", msg.c_str());
VL_FATAL_MT("unknown",0,"", msg.c_str());
return -1;
}
static const char* exportName(int funcnum) {
static const char* exportName(int funcnum) VL_MT_SAFE {
// Slowpath; find name for given export; errors only so no map to reverse-map it
VerilatedLockGuard lock(s_s.m_exportMutex);
for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
if (it->second == funcnum) return it->first;
}
return "*UNKNOWN*";
}
static void exportsDump() {
static void exportsDump() VL_MT_SAFE {
VerilatedLockGuard lock(s_s.m_exportMutex);
bool first = true;
for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
if (first) { VL_PRINTF(" exportDump:\n"); first=false; }
VL_PRINTF(" DPI_EXPORT_NAME %05d: %s\n", it->second, it->first);
if (first) { VL_PRINTF_MT(" exportDump:\n"); first=false; }
VL_PRINTF_MT(" DPI_EXPORT_NAME %05d: %s\n", it->second, it->first);
}
}
// We don't free up m_exportMap until the end, because we can't be sure
@@ -231,9 +368,10 @@ public: // But only for verilated*.cpp
public: // But only for verilated*.cpp
// METHODS - file IO
static IData fdNew(FILE* fp) {
static IData fdNew(FILE* fp) VL_MT_SAFE {
if (VL_UNLIKELY(!fp)) return 0;
// Bit 31 indicates it's a descriptor not a MCD
VerilatedLockGuard lock(s_s.m_fdMutex);
if (s_s.m_fdFree.empty()) {
// Need to create more space in m_fdps and m_fdFree
size_t start = s_s.m_fdps.size();
@@ -244,18 +382,22 @@ public: // But only for verilated*.cpp
s_s.m_fdps[idx] = fp;
return (idx | (1UL<<31)); // bit 31 indicates not MCD
}
static void fdDelete(IData fdi) {
static void fdDelete(IData fdi) VL_MT_SAFE {
IData idx = VL_MASK_I(31) & fdi;
VerilatedLockGuard lock(s_s.m_fdMutex);
if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return;
if (VL_UNLIKELY(!s_s.m_fdps[idx])) return; // Already free
s_s.m_fdps[idx] = NULL;
s_s.m_fdFree.push_back(idx);
}
static inline FILE* fdToFp(IData fdi) {
static inline FILE* fdToFp(IData fdi) VL_MT_SAFE {
IData idx = VL_MASK_I(31) & fdi;
VerilatedLockGuard lock(s_s.m_fdMutex); // This might get slow, if it does we can cache it
if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return NULL;
return s_s.m_fdps[idx];
}
};
//======================================================================
#endif // Guard
+24 -20
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
// Copyright 2001-2018 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.
//
@@ -48,7 +48,7 @@ static const char* const VLTSAVE_TRAILER_STR = "vltsaved"; ///< Value of last by
//=============================================================================
// Searalization
bool VerilatedDeserialize::readDiffers (const void* __restrict datap, size_t size) {
bool VerilatedDeserialize::readDiffers (const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
bufferCheck();
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
vluint8_t miss = 0;
@@ -58,17 +58,17 @@ bool VerilatedDeserialize::readDiffers (const void* __restrict datap, size_t siz
return (miss!=0);
}
VerilatedDeserialize& VerilatedDeserialize::readAssert (const void* __restrict datap, size_t size) {
VerilatedDeserialize& VerilatedDeserialize::readAssert (const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
if (VL_UNLIKELY(readDiffers(datap,size))) {
std::string fn = filename();
std::string msg = std::string("Can't deserialize save-restore file as was made from different model");
vl_fatal(fn.c_str(), 0, "", msg.c_str());
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
close();
}
return *this; // For function chaining
}
void VerilatedSerialize::header() {
void VerilatedSerialize::header() VL_MT_UNSAFE_ONE {
VerilatedSerialize& os = *this; // So can cut and paste standard << code below
assert((strlen(VLTSAVE_HEADER_STR) & 7) == 0); // Keep aligned
os.write(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR));
@@ -78,29 +78,29 @@ void VerilatedSerialize::header() {
os.write(Verilated::serializedPtr(), Verilated::serializedSize());
}
void VerilatedDeserialize::header() {
void VerilatedDeserialize::header() VL_MT_UNSAFE_ONE {
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR)))) {
std::string fn = filename();
std::string msg = std::string("Can't deserialize; file has wrong header signature");
vl_fatal(fn.c_str(), 0, "", msg.c_str());
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
close();
}
os.read(Verilated::serializedPtr(), Verilated::serializedSize());
}
void VerilatedSerialize::trailer() {
void VerilatedSerialize::trailer() VL_MT_UNSAFE_ONE {
VerilatedSerialize& os = *this; // So can cut and paste standard << code below
assert((strlen(VLTSAVE_TRAILER_STR) & 7) == 0); // Keep aligned
os.write(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR));
}
void VerilatedDeserialize::trailer() {
void VerilatedDeserialize::trailer() VL_MT_UNSAFE_ONE {
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR)))) {
std::string fn = filename();
std::string msg = std::string("Can't deserialize; file has wrong end-of-file signature");
vl_fatal(fn.c_str(), 0, "", msg.c_str());
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
close();
}
}
@@ -110,9 +110,10 @@ void VerilatedDeserialize::trailer() {
//=============================================================================
// Opening/Closing
void VerilatedSave::open (const char* filenamep) {
void VerilatedSave::open(const char* filenamep) VL_MT_UNSAFE_ONE {
m_assertOne.check();
if (isOpen()) return;
VL_DEBUG_IF(VL_PRINTF("-vltSave: opening save file %s\n",filenamep););
VL_DEBUG_IF(VL_DBG_MSGF("- save: opening save file %s\n",filenamep););
if (filenamep[0]=='|') {
assert(0); // Not supported yet.
@@ -132,9 +133,10 @@ void VerilatedSave::open (const char* filenamep) {
header();
}
void VerilatedRestore::open (const char* filenamep) {
void VerilatedRestore::open(const char* filenamep) VL_MT_UNSAFE_ONE {
m_assertOne.check();
if (isOpen()) return;
VL_DEBUG_IF(VL_PRINTF("-vltRestore: opening restore file %s\n",filenamep););
VL_DEBUG_IF(VL_DBG_MSGF("- restore: opening restore file %s\n",filenamep););
if (filenamep[0]=='|') {
assert(0); // Not supported yet.
@@ -155,7 +157,7 @@ void VerilatedRestore::open (const char* filenamep) {
header();
}
void VerilatedSave::close () {
void VerilatedSave::close() VL_MT_UNSAFE_ONE {
if (!isOpen()) return;
trailer();
flush();
@@ -163,7 +165,7 @@ void VerilatedSave::close () {
::close(m_fd); // May get error, just ignore it
}
void VerilatedRestore::close () {
void VerilatedRestore::close() VL_MT_UNSAFE_ONE {
if (!isOpen()) return;
trailer();
flush();
@@ -174,7 +176,8 @@ void VerilatedRestore::close () {
//=============================================================================
// Buffer management
void VerilatedSave::flush() {
void VerilatedSave::flush() VL_MT_UNSAFE_ONE {
m_assertOne.check();
if (VL_UNLIKELY(!isOpen())) return;
vluint8_t* wp = m_bufp;
while (1) {
@@ -188,7 +191,7 @@ void VerilatedSave::flush() {
if (errno != EAGAIN && errno != EINTR) {
// write failed, presume error (perhaps out of disk space)
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
vl_fatal("",0,"",msg.c_str());
VL_FATAL_MT("",0,"",msg.c_str());
close();
break;
}
@@ -197,7 +200,8 @@ void VerilatedSave::flush() {
m_cp = m_bufp; // Reset buffer
}
void VerilatedRestore::fill() {
void VerilatedRestore::fill() VL_MT_UNSAFE_ONE {
m_assertOne.check();
if (VL_UNLIKELY(!isOpen())) return;
// Move remaining characters down to start of buffer. (No memcpy, overlaps allowed)
vluint8_t* rp = m_bufp;
@@ -216,7 +220,7 @@ void VerilatedRestore::fill() {
if (errno != EAGAIN && errno != EINTR) {
// write failed, presume error (perhaps out of disk space)
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
vl_fatal("",0,"",msg.c_str());
VL_FATAL_MT("",0,"",msg.c_str());
close();
break;
}
+40 -31
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2012-2017 by Wilson Snyder. This program is free software;
// Copyright 2012-2018 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.
//
@@ -28,6 +28,7 @@
//=============================================================================
// VerilatedSerialize - convert structures to a stream representation
// This class is not thread safe, it must be called by a single thread
class VerilatedSerialize {
protected:
@@ -37,14 +38,17 @@ protected:
vluint8_t* m_bufp; ///< Output buffer
bool m_isOpen; ///< True indicates open file/stream
std::string m_filename; ///< Filename, for error messages
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
inline static size_t bufferInsertSize() { return 16*1024; }
void header();
void trailer();
void header() VL_MT_UNSAFE_ONE;
void trailer() VL_MT_UNSAFE_ONE;
// CONSTRUCTORS
VL_UNCOPYABLE(VerilatedSerialize);
public:
// CREATORS
VerilatedSerialize() {
m_isOpen = false;
m_bufp = new vluint8_t [bufferSize()];
@@ -57,9 +61,9 @@ public:
// METHODS
bool isOpen() const { return m_isOpen; }
std::string filename() const { return m_filename; }
virtual void close() { flush(); }
virtual void flush() {}
inline VerilatedSerialize& write (const void* __restrict datap, size_t size) {
virtual void close() VL_MT_UNSAFE_ONE { flush(); }
virtual void flush() VL_MT_UNSAFE_ONE {}
inline VerilatedSerialize& write(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
while (size) {
bufferCheck();
@@ -71,8 +75,7 @@ public:
return *this; // For function chaining
}
private:
VerilatedSerialize(const VerilatedSerialize& ); ///< N/A, no copy constructor
VerilatedSerialize& bufferCheck() {
VerilatedSerialize& bufferCheck() VL_MT_UNSAFE_ONE {
// 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_cp > (m_bufp+(bufferSize()-bufferInsertSize())))) {
@@ -84,6 +87,7 @@ private:
//=============================================================================
// VerilatedDeserial - load structures from a stream representation
// This class is not thread safe, it must be called by a single thread
class VerilatedDeserialize {
protected:
@@ -94,15 +98,18 @@ protected:
vluint8_t* m_endp; ///< Last valid byte in m_bufp buffer
bool m_isOpen; ///< True indicates open file/stream
std::string m_filename; ///< Filename, for error messages
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
inline static size_t bufferInsertSize() { return 16*1024; }
virtual void fill() = 0;
void header();
void trailer();
void header() VL_MT_UNSAFE_ONE;
void trailer() VL_MT_UNSAFE_ONE;
// CONSTRUCTORS
VL_UNCOPYABLE(VerilatedDeserialize);
public:
// CREATORS
VerilatedDeserialize() {
m_isOpen = false;
m_bufp = new vluint8_t [bufferSize()];
@@ -116,9 +123,9 @@ public:
// METHODS
bool isOpen() const { return m_isOpen; }
std::string filename() const { return m_filename; }
virtual void close() { flush(); }
virtual void flush() {}
inline VerilatedDeserialize& read (void* __restrict datap, size_t size) {
virtual void close() VL_MT_UNSAFE_ONE { flush(); }
virtual void flush() VL_MT_UNSAFE_ONE {}
inline VerilatedDeserialize& read(void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
vluint8_t* __restrict dp = (vluint8_t* __restrict)datap;
while (size) {
bufferCheck();
@@ -130,12 +137,12 @@ public:
return *this; // For function chaining
}
// Read a datum and compare with expected value
bool readDiffers (const void* __restrict datap, size_t size);
VerilatedDeserialize& readAssert (const void* __restrict datap, size_t size);
VerilatedDeserialize& readAssert (vluint64_t data) { return readAssert(&data, sizeof(data)); }
VerilatedDeserialize& readAssert(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
VerilatedDeserialize& readAssert(vluint64_t data) VL_MT_UNSAFE_ONE {
return readAssert(&data, sizeof(data)); }
private:
VerilatedDeserialize(const VerilatedDeserialize& ); ///< N/A, no copy constructor
VerilatedDeserialize& bufferCheck() {
bool readDiffers(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
VerilatedDeserialize& bufferCheck() VL_MT_UNSAFE_ONE {
// 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_cp+bufferInsertSize()) > m_endp)) {
@@ -147,40 +154,42 @@ private:
//=============================================================================
// VerilatedSave - serialize to a file
// This class is not thread safe, it must be called by a single thread
class VerilatedSave : public VerilatedSerialize {
private:
int m_fd; ///< File descriptor we're writing to
public:
// CREATORS
// CONSTRUCTORS
VerilatedSave() { m_fd=-1; }
virtual ~VerilatedSave() { close(); }
// METHODS
void open(const char* filenamep); ///< Open the file; call isOpen() to see if errors
void open(const std::string& filename) { open(filename.c_str()); }
virtual void close();
virtual void flush();
void open(const char* filenamep) VL_MT_UNSAFE_ONE; ///< Open the file; call isOpen() to see if errors
void open(const std::string& filename) VL_MT_UNSAFE_ONE { open(filename.c_str()); }
virtual void close() VL_MT_UNSAFE_ONE;
virtual void flush() VL_MT_UNSAFE_ONE;
};
//=============================================================================
// VerilatedRestore - deserialize from a file
// This class is not thread safe, it must be called by a single thread
class VerilatedRestore : public VerilatedDeserialize {
private:
int m_fd; ///< File descriptor we're writing to
public:
// CREATORS
// CONSTRUCTORS
VerilatedRestore() { m_fd=-1; }
virtual ~VerilatedRestore() { close(); }
// METHODS
void open(const char* filenamep); ///< Open the file; call isOpen() to see if errors
void open(const std::string& filename) { open(filename.c_str()); }
virtual void close();
virtual void flush() {}
virtual void fill();
void open(const char* filenamep) VL_MT_UNSAFE_ONE; ///< Open the file; call isOpen() to see if errors
void open(const std::string& filename) VL_MT_UNSAFE_ONE { open(filename.c_str()); }
virtual void close() VL_MT_UNSAFE_ONE;
virtual void flush() VL_MT_UNSAFE_ONE {}
virtual void fill() VL_MT_UNSAFE_ONE;
};
//=============================================================================
+3 -2
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2018 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,12 @@
// We want to get a pointer to m_data in the sc_bv_base class,
// but it is protected. So make an exposing class, then use
// cast magic to get at it. Saves patching get_datap in SystemC.
// This class is thread safe (though most of SystemC is not).
#define VL_SC_BV_DATAP(bv) (VlScBvExposer::sp_datap(bv))
class VlScBvExposer : public sc_bv_base {
public:
static const vluint32_t* sp_datap(const sc_bv_base& base) {
static const vluint32_t* sp_datap(const sc_bv_base& base) VL_MT_SAFE {
return static_cast<const VlScBvExposer*>(&base)->sp_datatp(); }
const vluint32_t* sp_datatp() const { return reinterpret_cast<vluint32_t*>(m_data); }
// Above reads this protected element in sc_bv_base:
+224
View File
@@ -0,0 +1,224 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2018 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
///
/// \file
/// \brief Verilator: Include to provide information about symbol inspection
///
/// This file is for inclusion by internal files that need to inspect
/// specific symbols.
///
/// User routines wanting to inspect the symbol table should use
/// verilated_syms.h instead.
///
/// These classes are thread safe, and read only.
///
/// Code available from: http://www.veripool.org/verilator
///
//*************************************************************************
#ifndef _VERILATED_SYM_PROPS_H_
#define _VERILATED_SYM_PROPS_H_ 1 ///< Header Guard
//===========================================================================
/// Verilator range
/// Thread safety: Assume is constructed only with model, then any number of readers
// See also V3Ast::VNumRange
class VerilatedRange {
int m_left;
int m_right;
protected:
friend class VerilatedVarProps;
friend class VerilatedScope;
VerilatedRange() : m_left(0), m_right(0) {}
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() const { return m_left; }
int right() const { return m_right; }
int low() const { return (m_left < m_right) ? m_left : m_right; }
int high() const { return (m_left > m_right) ? m_left : m_right; }
int elements() const {
return (VL_LIKELY(m_left>=m_right) ? (m_left-m_right+1) : (m_right-m_left+1)); }
int increment() const { return (m_left >= m_right) ? 1 : -1; }
};
//===========================================================================
/// Verilator variable
/// Thread safety: Assume is constructed only with model, then any number of readers
class VerilatedVarProps {
// TYPES
enum { MAGIC = 0xddc4f829 };
// MEMBERS
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
VerilatedRange m_packed; // Packed array range
VerilatedRange m_unpacked[3]; // Unpacked array range
// CONSTRUCTORS
protected:
friend class VerilatedScope;
VerilatedVarProps(VerilatedVarType vltype, VerilatedVarFlags vlflags,
int pdims, int udims)
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(vlflags), m_pdims(pdims), m_udims(udims) {}
public:
class Unpacked {};
// Without packed
VerilatedVarProps(VerilatedVarType vltype, int vlflags)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(0) { }
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Unpacked, int u0l, int u0r)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(1) {
m_unpacked[0].init(u0l, u0r); }
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Unpacked, int u0l, int u0r, int u1l, int u1r)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(2) {
m_unpacked[0].init(u0l, u0r); m_unpacked[1].init(u1l, u1r); }
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Unpacked, int u0l, int u0r, int u1l, int u1r, int u2l, int u2r)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(3) {
m_unpacked[0].init(u0l, u0r); m_unpacked[1].init(u1l, u1r); m_unpacked[2].init(u2l, u2r); }
// With packed
class Packed {};
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Packed, int pl, int pr)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(0), m_packed(pl,pr) { }
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Packed, int pl, int pr,
Unpacked, int u0l, int u0r)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(1), m_packed(pl,pr) {
m_unpacked[0].init(u0l, u0r); }
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Packed, int pl, int pr,
Unpacked, int u0l, int u0r, int u1l, int u1r)
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(VerilatedVarFlags(vlflags)),
m_pdims(1), m_udims(2), m_packed(pl,pr) {
m_unpacked[0].init(u0l, u0r); m_unpacked[1].init(u1l, u1r); }
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Packed, int pl, int pr,
Unpacked, int u0l, int u0r, int u1l, int u1r, int u2l, int u2r)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(3), m_packed(pl,pr) {
m_unpacked[0].init(u0l, u0r); m_unpacked[1].init(u1l, u1r); m_unpacked[2].init(u2l, u2r); }
public:
~VerilatedVarProps() {}
// METHODS
bool magicOk() const { return m_magic==MAGIC; }
VerilatedVarType vltype() const { return m_vltype; }
VerilatedVarFlags vldir() const {
return static_cast<VerilatedVarFlags>(static_cast<int>(m_vlflags) & VLVF_MASK_DIR); }
vluint32_t entSize() const;
bool isPublicRW() const { return ((m_vlflags & VLVF_PUB_RW) != 0); }
/// DPI compatible C standard layout
bool isDpiCLayout() const { return ((m_vlflags & VLVF_DPI_CLAY) != 0); }
int udims() const { return m_udims; }
int dims() const { return m_pdims + m_udims; }
const VerilatedRange& packed() const { return m_packed; }
const VerilatedRange& unpacked() const { return m_unpacked[0]; }
// DPI accessors
int left(int dim) const {
return dim==0 ? m_packed.left() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].left() : 0;
}
int right(int dim) const {
return dim==0 ? m_packed.right() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].right() : 0;
}
int low(int dim) const {
return dim==0 ? m_packed.low() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].low() : 0;
}
int high(int dim) const {
return dim==0 ? m_packed.high() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].high() : 0;
}
int increment(int dim) const {
return dim==0 ? m_packed.increment() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].increment() : 0;
}
int elements(int dim) const {
return dim==0 ? m_packed.elements() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].elements() : 0;
}
/// Total size in bytes (note DPI limited to 4GB)
size_t totalSize() const;
/// Adjust a data pointer to access a given array element, NuLL if something goes bad
void* datapAdjustIndex(void* datap, int dim, int indx) const;
};
//===========================================================================
/// Verilator DPI open array variable
class VerilatedDpiOpenVar {
// MEMBERS
const VerilatedVarProps* m_propsp; // Variable properties
void* m_datap; // Location of data (local to thread always, so safe)
public:
// CONSTRUCTORS
VerilatedDpiOpenVar(const VerilatedVarProps* propsp, void* datap)
: m_propsp(propsp), m_datap(datap) {}
VerilatedDpiOpenVar(const VerilatedVarProps* propsp, const void* datap)
: m_propsp(propsp), m_datap(const_cast<void*>(datap)) {}
~VerilatedDpiOpenVar() {}
// METHODS
void* datap() const { return m_datap; }
// METHODS - from VerilatedVarProps
bool magicOk() const { return m_propsp->magicOk(); }
VerilatedVarType vltype() const { return m_propsp->vltype(); }
bool isDpiStdLayout() const { return m_propsp->isDpiCLayout(); }
const VerilatedRange& packed() const { return m_propsp->packed(); }
const VerilatedRange& unpacked() const { return m_propsp->unpacked(); }
int udims() const { return m_propsp->udims(); }
int left(int dim) const { return m_propsp->left(dim); }
int right(int dim) const { return m_propsp->right(dim); }
int low(int dim) const { return m_propsp->low(dim); }
int high(int dim) const { return m_propsp->high(dim); }
int increment(int dim) const { return m_propsp->increment(dim); }
int elements(int dim) const { return m_propsp->elements(dim); }
size_t totalSize() const { return m_propsp->totalSize(); }
void* datapAdjustIndex(void* datap, int dim, int indx) const {
return m_propsp->datapAdjustIndex(datap, dim, indx); }
};
//===========================================================================
/// Verilator variable
/// Thread safety: Assume is constructed only with model, then any number of readers
class VerilatedVar : public VerilatedVarProps {
// MEMBERS
void* m_datap; // Location of data
const char* m_namep; // Name - slowpath
protected:
friend class VerilatedScope;
// CONSTRUCTORS
VerilatedVar(const char* namep, void* datap,
VerilatedVarType vltype, VerilatedVarFlags vlflags, int dims)
: VerilatedVarProps(vltype, vlflags, (dims>0?1:0), ((dims>1)?dims-1:0))
, m_datap(datap), m_namep(namep) {}
public:
~VerilatedVar() {}
// ACCESSORS
void* datap() const { return m_datap; }
const VerilatedRange& range() const { return packed(); } // Deprecated
const VerilatedRange& array() const { return unpacked(); } // Deprecated
const char* name() const { return m_namep; }
};
#endif // Guard
+13 -55
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -16,9 +16,12 @@
/// \file
/// \brief Verilator: Include to allow symbol inspection
///
/// This file is for inclusion by files that need to inspect
/// the symbol table. It is not included in verilated.h
/// as it requires some heavyweight C++ classes.
/// This file is for inclusion by files that need to inspect the symbol
/// table. It is not included in verilated.h (instead see
/// verilated_sym_props.h) as it requires some heavyweight C++ classes.
///
/// These classes are thread safe and read only. It is constructed only
/// when a model is built (from the main thread).
///
/// Code available from: http://www.veripool.org/verilator
///
@@ -28,68 +31,22 @@
#ifndef _VERILATED_SYMS_H_
#define _VERILATED_SYMS_H_ 1 ///< Header Guard
#include "verilated_sym_props.h"
#include "verilated_heavy.h"
#include <map>
//===========================================================================
/// Verilator range
// See also V3Ast::VNumRange
class VerilatedRange {
int m_left;
int m_right;
protected:
friend class VerilatedVar;
friend class VerilatedScope;
VerilatedRange() : m_left(0), m_right(0) {}
void sets(int left, int right) { m_left=left; m_right=right; }
public:
~VerilatedRange() {}
int left() const { return m_left; }
int right() const { return m_right; }
int elements() const { return (VL_LIKELY(m_left>=m_right)?(m_left-m_right+1):(m_right-m_left+1)); }
};
//===========================================================================
/// Verilator variable
class VerilatedVar {
void* m_datap; // Location of data
VerilatedVarType m_vltype; // Data type
VerilatedVarFlags m_vlflags; // Direction
VerilatedRange m_range; // First range
VerilatedRange m_array; // Array
int m_dims; // Dimensions
const char* m_namep; // Name - slowpath
protected:
friend class VerilatedScope;
VerilatedVar(const char* namep, void* datap,
VerilatedVarType vltype, VerilatedVarFlags vlflags, int dims)
: m_datap(datap), m_vltype(vltype), m_vlflags(vlflags), m_dims(dims), m_namep(namep) {}
public:
~VerilatedVar() {}
void* datap() const { return m_datap; }
VerilatedVarType vltype() const { return m_vltype; }
VerilatedVarFlags vldir() const { return static_cast<VerilatedVarFlags>(static_cast<int>(m_vlflags) & VLVF_MASK_DIR); }
vluint32_t entSize() const;
bool isPublicRW() const { return ((m_vlflags & VLVF_PUB_RW) != 0); }
const VerilatedRange& range() const { return m_range; }
const VerilatedRange& array() const { return m_array; }
const char* name() const { return m_namep; }
int dims() const { return m_dims; }
};
//======================================================================
/// Types
/// Class to sort maps keyed by const char*'s
struct VerilatedCStrCmp {
/// Ordering maps keyed by const char*'s
bool operator() (const char *a, const char *b) const {
return std::strcmp(a, b) < 0;
return std::strcmp(a, b) < 0;
}
};
/// Map of sorted scope names to find associated scope class
class VerilatedScopeNameMap
: public std::map<const char*, const VerilatedScope*, VerilatedCStrCmp> {
public:
@@ -97,6 +54,7 @@ public:
~VerilatedScopeNameMap() {}
};
/// Map of sorted variable names to find associated variable class
class VerilatedVarNameMap
: public std::map<const char*, VerilatedVar, VerilatedCStrCmp> {
public:
+46 -29
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
// Copyright 2001-2018 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.
//
@@ -55,18 +55,24 @@ class VerilatedVcdSingleton {
private:
typedef std::vector<VerilatedVcd*> VcdVec;
struct Singleton {
VcdVec s_vcdVecp; ///< List of all created traces
VerilatedMutex s_vcdMutex; ///< Protect the singleton
VcdVec s_vcdVecp VL_GUARDED_BY(s_vcdMutex); ///< List of all created traces
};
static Singleton& singleton() { static Singleton s; return s; }
public:
static void pushVcd(VerilatedVcd* vcdp) {
static void pushVcd(VerilatedVcd* vcdp) VL_EXCLUDES(singleton().s_vcdMutex) {
VerilatedLockGuard lock(singleton().s_vcdMutex);
singleton().s_vcdVecp.push_back(vcdp);
}
static void removeVcd(const VerilatedVcd* vcdp) {
static void removeVcd(const VerilatedVcd* vcdp) VL_EXCLUDES(singleton().s_vcdMutex) {
VerilatedLockGuard lock(singleton().s_vcdMutex);
VcdVec::iterator pos = find(singleton().s_vcdVecp.begin(), singleton().s_vcdVecp.end(), vcdp);
if (pos != singleton().s_vcdVecp.end()) { singleton().s_vcdVecp.erase(pos); }
}
static void flush_all() {
static void flush_all() VL_EXCLUDES(singleton().s_vcdMutex) VL_MT_UNSAFE_ONE {
// Thread safety: Although this function is protected by a mutex so perhaps
// in the future we can allow tracing in separate threads, vcdp->flush() assumes call from single thread
VerilatedLockGuard lock(singleton().s_vcdMutex);
for (VcdVec::const_iterator it=singleton().s_vcdVecp.begin(); it!=singleton().s_vcdVecp.end(); ++it) {
VerilatedVcd* vcdp = *it;
vcdp->flush();
@@ -90,7 +96,7 @@ protected:
VerilatedVcdCallback_t m_changecb; ///< Incremental Dumping Callback function
void* m_userthis; ///< Fake "this" for caller
vluint32_t m_code; ///< Starting code number
// CREATORS
// CONSTRUCTORS
VerilatedVcdCallInfo (VerilatedVcdCallback_t icb, VerilatedVcdCallback_t fcb,
VerilatedVcdCallback_t changecb,
void* ut, vluint32_t code)
@@ -103,16 +109,16 @@ protected:
//=============================================================================
// VerilatedVcdFile
bool VerilatedVcdFile::open(const std::string& name) {
bool VerilatedVcdFile::open(const std::string& name) VL_MT_UNSAFE {
m_fd = ::open(name.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK, 0666);
return (m_fd>=0);
}
void VerilatedVcdFile::close() {
void VerilatedVcdFile::close() VL_MT_UNSAFE {
::close(m_fd);
}
ssize_t VerilatedVcdFile::write(const char* bufp, ssize_t len) {
ssize_t VerilatedVcdFile::write(const char* bufp, ssize_t len) VL_MT_UNSAFE {
return ::write(m_fd, bufp, len);
}
@@ -141,6 +147,7 @@ VerilatedVcd::VerilatedVcd(VerilatedVcdFile* filep)
}
void VerilatedVcd::open (const char* filename) {
m_assertOne.check();
if (isOpen()) return;
// Set member variables
@@ -171,6 +178,7 @@ void VerilatedVcd::open (const char* filename) {
void VerilatedVcd::openNext (bool incFilename) {
// Open next filename in concat sequence, mangle filename if
// incFilename is true.
m_assertOne.check();
closePrev(); // Close existing
if (incFilename) {
// Find _0000.{ext} in filename
@@ -219,7 +227,7 @@ void VerilatedVcd::makeNameMap() {
m_namemapp = new NameMap;
for (vluint32_t ent = 0; ent< m_callbacks.size(); ent++) {
VerilatedVcdCallInfo *cip = m_callbacks[ent];
cip->m_code = nextCode();
cip->m_code = m_nextCode;
(cip->m_initcb) (this, cip->m_userthis, cip->m_code);
}
@@ -265,6 +273,7 @@ VerilatedVcd::~VerilatedVcd() {
}
void VerilatedVcd::closePrev () {
// This function is on the flush() call path
if (!isOpen()) return;
bufferFlush();
@@ -273,6 +282,7 @@ void VerilatedVcd::closePrev () {
}
void VerilatedVcd::closeErr () {
// This function is on the flush() call path
// Close due to an error. We might abort before even getting here,
// depending on the definition of vl_fatal.
if (!isOpen()) return;
@@ -283,6 +293,8 @@ void VerilatedVcd::closeErr () {
}
void VerilatedVcd::close() {
// This function is on the flush() call path
m_assertOne.check();
if (!isOpen()) return;
if (m_evcd) {
printStr("$vcdclose ");
@@ -311,10 +323,10 @@ void VerilatedVcd::printTime (vluint64_t timeui) {
// Dinotrace doesn't mind, but Cadence vvision seems to choke
if (VL_UNLIKELY(timeui < m_timeLastDump)) {
timeui = m_timeLastDump;
static bool backTime = false;
static VL_THREAD_LOCAL bool backTime = false;
if (!backTime) {
backTime = true;
VL_PRINTF("VCD time is moving backwards, wave file may be incorrect.\n");
VL_PRINTF_MT("%%Warning: VCD time is moving backwards, wave file may be incorrect.\n");
}
}
m_timeLastDump = timeui;
@@ -331,14 +343,16 @@ void VerilatedVcd::bufferResize(vluint64_t minsize) {
memcpy(m_wrBufp, oldbufp, m_writep - oldbufp);
m_writep = m_wrBufp + (m_writep - oldbufp);
m_wrFlushp = m_wrBufp + m_wrChunkSize * 6;
delete oldbufp; oldbufp=NULL;
delete [] oldbufp; oldbufp=NULL;
}
}
void VerilatedVcd::bufferFlush () {
void VerilatedVcd::bufferFlush () VL_MT_UNSAFE_ONE {
// This function is on the flush() call path
// We add output data to m_writep.
// When it gets nearly full we dump it using this routine which calls write()
// This is much faster than using buffered I/O
m_assertOne.check();
if (VL_UNLIKELY(!isOpen())) return;
char* wp = m_wrBufp;
while (1) {
@@ -353,7 +367,7 @@ void VerilatedVcd::bufferFlush () {
if (errno != EAGAIN && errno != EINTR) {
// write failed, presume error (perhaps out of disk space)
std::string msg = std::string("VerilatedVcd::bufferFlush: ")+strerror(errno);
vl_fatal("",0,"",msg.c_str());
VL_FATAL_MT("",0,"",msg.c_str());
closeErr();
break;
}
@@ -368,12 +382,14 @@ void VerilatedVcd::bufferFlush () {
// Simple methods
void VerilatedVcd::set_time_unit (const char* unitp) {
//cout<<" set_time_unit ("<<unitp<<") == "<<timescaleToDouble(unitp)<<" == "<<doubleToTimescale(timescaleToDouble(unitp))<<endl;
//cout<<" set_time_unit ("<<unitp<<") == "<<timescaleToDouble(unitp)
// <<" == "<<doubleToTimescale(timescaleToDouble(unitp))<<endl;
m_timeUnit = timescaleToDouble(unitp);
}
void VerilatedVcd::set_time_resolution (const char* unitp) {
//cout<<"set_time_resolution ("<<unitp<<") == "<<timescaleToDouble(unitp)<<" == "<<doubleToTimescale(timescaleToDouble(unitp))<<endl;
//cout<<"set_time_resolution ("<<unitp<<") == "<<timescaleToDouble(unitp)
// <<" == "<<doubleToTimescale(timescaleToDouble(unitp))<<endl;
m_timeRes = timescaleToDouble(unitp);
}
@@ -499,19 +515,20 @@ void VerilatedVcd::dumpHeader () {
}
void VerilatedVcd::module (const std::string& name) {
m_assertOne.check();
m_modName = name;
}
void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep,
int arraynum, bool tri, bool bussed, int msb, int lsb) {
if (!code) { vl_fatal(__FILE__,__LINE__,"","Internal: internal trace problem, code 0 is illegal"); }
if (!code) { VL_FATAL_MT(__FILE__,__LINE__,"","Internal: internal trace problem, code 0 is illegal"); }
int bits = ((msb>lsb)?(msb-lsb):(lsb-msb))+1;
int codesNeeded = 1+int(bits/32);
if (tri) codesNeeded *= 2; // Space in change array for __en signals
// Make sure array is large enough
m_nextCode = std::max(nextCode(), code+codesNeeded);
m_nextCode = std::max(m_nextCode, code+codesNeeded);
if (m_sigs.capacity() <= m_nextCode) {
m_sigs.reserve(m_nextCode*2); // Power-of-2 allocation speeds things up
}
@@ -552,7 +569,7 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
sprintf(buf, " %2d ", bits);
decl += buf;
if (m_evcd) {
sprintf(buf, "<%d", code);
sprintf(buf, "<%u", code);
decl += buf;
} else {
decl += stringCode(code);
@@ -617,15 +634,16 @@ void VerilatedVcd::fullFloat (vluint32_t code, const float newval) {
//=============================================================================
// Callbacks
void VerilatedVcd::addCallback (
void VerilatedVcd::addCallback VL_MT_UNSAFE_ONE (
VerilatedVcdCallback_t initcb, VerilatedVcdCallback_t fullcb, VerilatedVcdCallback_t changecb,
void* userthis)
{
m_assertOne.check();
if (VL_UNLIKELY(isOpen())) {
std::string msg = std::string("Internal: ")+__FILE__+"::"+__FUNCTION__+" called with already open file";
vl_fatal(__FILE__,__LINE__,"",msg.c_str());
VL_FATAL_MT(__FILE__,__LINE__,"",msg.c_str());
}
VerilatedVcdCallInfo* vci = new VerilatedVcdCallInfo(initcb, fullcb, changecb, userthis, nextCode());
VerilatedVcdCallInfo* vci = new VerilatedVcdCallInfo(initcb, fullcb, changecb, userthis, m_nextCode);
m_callbacks.push_back(vci);
}
@@ -633,15 +651,17 @@ void VerilatedVcd::addCallback (
// Dumping
void VerilatedVcd::dumpFull (vluint64_t timeui) {
m_assertOne.check();
dumpPrep (timeui);
Verilated::quiesce();
for (vluint32_t ent = 0; ent< m_callbacks.size(); ent++) {
VerilatedVcdCallInfo *cip = m_callbacks[ent];
(cip->m_fullcb) (this, cip->m_userthis, cip->m_code);
}
dumpDone ();
}
void VerilatedVcd::dump (vluint64_t timeui) {
m_assertOne.check();
if (!isOpen()) return;
if (VL_UNLIKELY(m_fullDump)) {
m_fullDump = false; // No need for more full dumps
@@ -653,11 +673,11 @@ void VerilatedVcd::dump (vluint64_t timeui) {
if (!isOpen()) return;
}
dumpPrep (timeui);
Verilated::quiesce();
for (vluint32_t ent = 0; ent< m_callbacks.size(); ent++) {
VerilatedVcdCallInfo *cip = m_callbacks[ent];
(cip->m_changecb) (this, cip->m_userthis, cip->m_code);
}
dumpDone();
}
void VerilatedVcd::dumpPrep (vluint64_t timeui) {
@@ -666,13 +686,10 @@ void VerilatedVcd::dumpPrep (vluint64_t timeui) {
printStr("\n");
}
void VerilatedVcd::dumpDone () {
}
//======================================================================
// Static members
void VerilatedVcd::flush_all() {
void VerilatedVcd::flush_all() VL_MT_UNSAFE_ONE {
VerilatedVcdSingleton::flush_all();
}
+32 -25
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
// Copyright 2001-2018 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,6 +24,7 @@
#define _VERILATED_VCD_C_H_ 1
#include "verilatedos.h"
#include "verilated.h"
#include <string>
#include <vector>
@@ -44,9 +45,9 @@ public:
// METHODS
VerilatedVcdFile() : m_fd(0) {}
virtual ~VerilatedVcdFile() {}
virtual bool open(const std::string& name);
virtual void close();
virtual ssize_t write(const char* bufp, ssize_t len);
virtual bool open(const std::string& name) VL_MT_UNSAFE;
virtual void close() VL_MT_UNSAFE;
virtual ssize_t write(const char* bufp, ssize_t len) VL_MT_UNSAFE;
};
//=============================================================================
@@ -104,8 +105,10 @@ private:
typedef std::map<std::string,std::string> NameMap;
NameMap* m_namemapp; ///< List of names for the header
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
void bufferResize(vluint64_t minsize);
void bufferFlush();
void bufferFlush() VL_MT_UNSAFE_ONE;
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
@@ -136,7 +139,7 @@ private:
if (code>=(94)) *m_writep++ = static_cast<char>((code/94)%94+33);
*m_writep++ = static_cast<char>((code)%94+33);
}
static std::string stringCode (vluint32_t code) {
static std::string stringCode (vluint32_t code) VL_PURE {
std::string out;
if (code>=(94*94*94)) out += static_cast<char>((code/94/94/94)%94+33);
if (code>=(94*94)) out += static_cast<char>((code/94/94)%94+33);
@@ -144,20 +147,13 @@ private:
return out + static_cast<char>((code)%94+33);
}
VerilatedVcd(const VerilatedVcd& ); ///< N/A, no copy constructor
protected:
// METHODS
void evcd(bool flag) { m_evcd = flag; }
// CONSTRUCTORS
VL_UNCOPYABLE(VerilatedVcd);
public:
// CREATORS
explicit VerilatedVcd(VerilatedVcdFile* filep=NULL);
~VerilatedVcd();
// ACCESSORS
/// Inside dumping routines, return next VCD signal code
vluint32_t nextCode() const {return m_nextCode;}
/// Set size in megabytes after which new file should be created
void rolloverMB(vluint64_t rolloverMB) { m_rolloverMB=rolloverMB; };
/// Is file open?
@@ -168,11 +164,13 @@ public:
inline bool isScopeEscape(char c) { return isspace(c) || c==m_scopeEscape; }
// METHODS
void open (const char* filename); ///< Open the file; call isOpen() to see if errors
void open(const char* filename) VL_MT_UNSAFE_ONE; ///< Open the file; call isOpen() to see if errors
void openNext (bool incFilename); ///< Open next data-only file
void flush() { bufferFlush(); } ///< Flush any remaining data
static void flush_all(); ///< Flush any remaining data from all files
void close (); ///< Close the file
void close() VL_MT_UNSAFE_ONE; ///< Close the file
/// Flush any remaining data to this file
void flush() VL_MT_UNSAFE_ONE { bufferFlush(); }
/// Flush any remaining data from all files
static void flush_all() VL_MT_UNSAFE_ONE;
void set_time_unit (const char* unit); ///< Set time units (s/ms, defaults to ns)
void set_time_unit (const std::string& unit) { set_time_unit(unit.c_str()); }
@@ -191,7 +189,7 @@ public:
/// Inside dumping routines, declare callbacks for tracings
void addCallback (VerilatedVcdCallback_t init, VerilatedVcdCallback_t full,
VerilatedVcdCallback_t change,
void* userthis);
void* userthis) VL_MT_UNSAFE_ONE;
/// Inside dumping routines, declare a module
void module (const std::string& name);
@@ -393,18 +391,27 @@ public:
fullFloat (code, newval);
}
}
protected:
// METHODS
void evcd(bool flag) { m_evcd = flag; }
};
//=============================================================================
// VerilatedVcdC
/// Create a VCD dump file in C standalone (no SystemC) simulations.
/// Also derived for use in SystemC simulations.
/// Thread safety: Unless otherwise indicated, every function is VL_MT_UNSAFE_ONE
class VerilatedVcdC {
VerilatedVcd m_sptrace; ///< Trace file being created
public:
// CONSTRUCTORS
VL_UNCOPYABLE(VerilatedVcdC);
public:
explicit VerilatedVcdC(VerilatedVcdFile* filep=NULL) : m_sptrace(filep) {}
~VerilatedVcdC() {}
public:
// ACCESSORS
/// Is file open?
bool isOpen() const { return m_sptrace.isOpen(); }
@@ -412,17 +419,17 @@ public:
/// Open a new VCD file
/// This includes a complete header dump each time it is called,
/// just as if this object was deleted and reconstructed.
void open (const char* filename) { m_sptrace.open(filename); }
void open(const char* filename) VL_MT_UNSAFE_ONE { m_sptrace.open(filename); }
/// Continue a VCD dump by rotating to a new file name
/// The header is only in the first file created, this allows
/// "cat" to be used to combine the header plus any number of data files.
void openNext (bool incFilename=true) { m_sptrace.openNext(incFilename); }
void openNext(bool incFilename=true) VL_MT_UNSAFE_ONE { m_sptrace.openNext(incFilename); }
/// Set size in megabytes after which new file should be created
void rolloverMB(size_t rolloverMB) { m_sptrace.rolloverMB(rolloverMB); };
/// Close dump
void close() { m_sptrace.close(); }
void close() VL_MT_UNSAFE_ONE { m_sptrace.close(); }
/// Flush dump
void flush() { m_sptrace.flush(); }
void flush() VL_MT_UNSAFE_ONE { m_sptrace.flush(); }
/// Write one cycle of dump data
void dump (vluint64_t timeui) { m_sptrace.dump(timeui); }
/// Write one cycle of dump data - backward compatible and to reduce
+6 -1
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
// Copyright 2001-2018 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,11 @@ void VerilatedVcdSc::trace (const unsigned int &, const std::string &, const cha
# define DECL_TRACE_METHOD_B(tp) \
void VerilatedVcdSc::trace( const tp& object, const std::string& name, int width ) {}
#if (SYSTEMC_VERSION>=20171012)
DECL_TRACE_METHOD_A( sc_event )
DECL_TRACE_METHOD_A( sc_time )
#endif
DECL_TRACE_METHOD_A( bool )
DECL_TRACE_METHOD_A( sc_dt::sc_bit )
DECL_TRACE_METHOD_A( sc_dt::sc_logic )
+12 -2
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
// Copyright 2001-2018 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.
//
@@ -17,6 +17,8 @@
/// \file
/// \brief Verilator tracing in VCD format
///
/// This class is not threadsafe, as the SystemC kernel is not threadsafe.
///
//=============================================================================
// SPDIFF_OFF
@@ -37,6 +39,8 @@ class VerilatedVcdSc
: sc_trace_file
, public VerilatedVcdC
{
// CONSTRUCTORS
VL_UNCOPYABLE(VerilatedVcdSc);
public:
VerilatedVcdSc() {
sc_get_curr_simcontext()->add_trace_file(this);
@@ -56,8 +60,9 @@ public:
spTrace()->set_time_resolution(sc_get_time_resolution().to_string());
# endif
}
virtual ~VerilatedVcdSc() {}
// METHODS
/// Called by SystemC simulate()
virtual void cycle (bool delta_cycle) {
# if (SYSTEMC_VERSION>20011000)
@@ -91,6 +96,11 @@ private:
virtual void write_comment (const std::string &);
virtual void trace (const unsigned int &, const std::string &, const char **);
#if (SYSTEMC_VERSION>=20171012)
DECL_TRACE_METHOD_A( sc_event )
DECL_TRACE_METHOD_A( sc_time )
#endif
DECL_TRACE_METHOD_A( bool )
DECL_TRACE_METHOD_A( sc_dt::sc_bit )
DECL_TRACE_METHOD_A( sc_dt::sc_logic )
+610 -75
View File
File diff suppressed because it is too large Load Diff
+11 -459
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2018 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.
@@ -16,8 +16,8 @@
/// \file
/// \brief Verilator: VPI implementation code
///
/// This file must be compiled and linked against all objects
/// created from Verilator or called by Verilator that use the VPI.
/// This file must be compiled and linked against all objects
/// created from Verilator or called by Verilator that use the VPI.
///
/// Code available from: http://www.veripool.org/verilator
///
@@ -29,472 +29,24 @@
#include "verilated.h"
#include "verilated_syms.h"
#include <list>
#include <set>
#include <map>
//======================================================================
// From IEEE 1800-2009 annex K
#include "vltstd/vpi_user.h"
//======================================================================
// Internal constants
#define VL_DEBUG_IF_PLI VL_DEBUG_IF
#define VL_VPI_LINE_SIZE 8192
//======================================================================
// Internal macros
#define _VL_VPI_INTERNAL VerilatedVpi::error_info()->setMessage(vpiInternal)->setMessage
#define _VL_VPI_SYSTEM VerilatedVpi::error_info()->setMessage(vpiSystem )->setMessage
#define _VL_VPI_ERROR VerilatedVpi::error_info()->setMessage(vpiError )->setMessage
#define _VL_VPI_WARNING VerilatedVpi::error_info()->setMessage(vpiWarning )->setMessage
#define _VL_VPI_NOTICE VerilatedVpi::error_info()->setMessage(vpiNotice )->setMessage
#define _VL_VPI_ERROR_RESET VerilatedVpi::error_info()->resetError
// Not supported yet
#define _VL_VPI_UNIMP() \
_VL_VPI_ERROR(__FILE__,__LINE__,Verilated::catName("Unsupported VPI function: ",VL_FUNC));
//======================================================================
// Implementation
// Base VPI handled object
class VerilatedVpio {
// MEM MANGLEMENT
static vluint8_t* s_freeHead;
public:
// CONSTRUCTORS
VerilatedVpio() {}
virtual ~VerilatedVpio() {}
inline static void* operator new(size_t size) {
// We new and delete tons of vpi structures, so keep them around
// To simplify our free list, we use a size large enough for all derived types
// We reserve word zero for the next pointer, as that's safer in case a
// dangling reference to the original remains around.
static size_t chunk = 96;
if (VL_UNLIKELY(size>chunk)) vl_fatal(__FILE__,__LINE__,"", "increase chunk");
if (VL_LIKELY(s_freeHead)) {
vluint8_t* newp = s_freeHead;
s_freeHead = *((vluint8_t**)newp);
return newp+8;
} else {
// +8: 8 bytes for next
vluint8_t* newp = reinterpret_cast<vluint8_t*>(::operator new(chunk+8));
return newp+8;
}
}
inline static void operator delete(void* obj, size_t size) {
vluint8_t* oldp = ((vluint8_t*)obj)-8;
*((void**)oldp) = s_freeHead;
s_freeHead = oldp;
}
// MEMBERS
static inline VerilatedVpio* castp(vpiHandle h) { return dynamic_cast<VerilatedVpio*>((VerilatedVpio*)h); }
inline vpiHandle castVpiHandle() { return reinterpret_cast<vpiHandle>(this); }
// ACCESSORS
virtual const char* name() const { return "<null>"; }
virtual const char* fullname() const { return "<null>"; }
virtual const char* defname() const { return "<null>"; }
virtual vluint32_t type() const { return 0; }
virtual vluint32_t size() const { return 0; }
virtual const VerilatedRange* rangep() const { return NULL; }
virtual vpiHandle dovpi_scan() { return 0; }
};
typedef PLI_INT32 (*VerilatedPliCb)(struct t_cb_data *);
class VerilatedVpioCb : public VerilatedVpio {
t_cb_data m_cbData;
s_vpi_value m_value;
QData m_time;
public:
// cppcheck-suppress uninitVar // m_value
VerilatedVpioCb(const t_cb_data* cbDatap, QData time)
: m_cbData(*cbDatap), m_time(time) {
m_value.format = cbDatap->value ? cbDatap->value->format : vpiSuppressVal;
m_cbData.value = &m_value;
}
virtual ~VerilatedVpioCb() {}
static inline VerilatedVpioCb* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioCb*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { 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; }
};
class VerilatedVpioConst : public VerilatedVpio {
vlsint32_t m_num;
public:
explicit VerilatedVpioConst(vlsint32_t num) : m_num(num) {}
virtual ~VerilatedVpioConst() {}
static inline VerilatedVpioConst* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioConst*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { return vpiUndefined; }
vlsint32_t num() const { return m_num; }
};
class VerilatedVpioRange : public VerilatedVpio {
const VerilatedRange* m_range;
vlsint32_t m_iteration;
public:
explicit VerilatedVpioRange(const VerilatedRange* range) : m_range(range), m_iteration(0) {}
virtual ~VerilatedVpioRange() {}
static inline VerilatedVpioRange* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioRange*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { return vpiRange; }
virtual vluint32_t size() const { return m_range->elements(); }
virtual const VerilatedRange* rangep() const { return m_range; }
int iteration() const { return m_iteration; }
void iterationInc() { ++m_iteration; }
virtual vpiHandle dovpi_scan() {
if (!iteration()) {
VerilatedVpioRange* nextp = new VerilatedVpioRange(*this);
nextp->iterationInc();
return ((nextp)->castVpiHandle());
} else {
return 0; // End of list - only one deep
}
}
};
class VerilatedVpioScope : public VerilatedVpio {
const VerilatedScope* m_scopep;
public:
explicit VerilatedVpioScope(const VerilatedScope* scopep)
: m_scopep(scopep) {}
virtual ~VerilatedVpioScope() {}
static inline VerilatedVpioScope* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioScope*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { return vpiScope; }
const VerilatedScope* scopep() const { return m_scopep; }
virtual const char* name() const { return m_scopep->name(); }
virtual const char* fullname() const { return m_scopep->name(); }
};
class VerilatedVpioVar : public VerilatedVpio {
const VerilatedVar* m_varp;
const VerilatedScope* m_scopep;
vluint8_t* m_prevDatap; // 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
protected:
void* m_varDatap; // varp()->datap() adjusted for array entries
vlsint32_t m_index;
const VerilatedRange& get_range() const {
// Determine number of dimensions and return outermost
return (m_varp->dims()>1) ? m_varp->array() : m_varp->range();
}
public:
VerilatedVpioVar(const VerilatedVar* varp, const VerilatedScope* scopep)
: m_varp(varp), m_scopep(scopep), m_index(0) {
m_prevDatap = NULL;
m_mask.u32 = VL_MASK_I(varp->range().elements());
m_entSize = varp->entSize();
m_varDatap = varp->datap();
}
virtual ~VerilatedVpioVar() {
if (m_prevDatap) { delete [] m_prevDatap; m_prevDatap = NULL; }
}
static inline VerilatedVpioVar* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVar*>((VerilatedVpio*)h); }
const VerilatedVar* varp() const { return m_varp; }
const VerilatedScope* scopep() const { return m_scopep; }
vluint32_t mask() const { return m_mask.u32; }
vluint8_t mask_byte(int idx) { return m_mask.u8[idx & 3]; }
vluint32_t entSize() const { return m_entSize; }
vluint32_t index() { return m_index; }
virtual vluint32_t type() const {
if (varp()->vldir() != vpiNoDirection) return vpiPort;
return (varp()->dims()>1) ? vpiMemory : vpiReg; /* but might be wire, logic */
}
virtual vluint32_t size() const { return get_range().elements(); }
virtual const VerilatedRange* rangep() const { return &get_range(); }
virtual const char* name() const { return m_varp->name(); }
virtual const char* fullname() const {
static VL_THREAD_LOCAL std::string out;
out = std::string(m_scopep->name())+"."+name();
return out.c_str();
}
void* prevDatap() const { return m_prevDatap; }
void* varDatap() const { return m_varDatap; }
void createPrevDatap() {
if (VL_UNLIKELY(!m_prevDatap)) {
m_prevDatap = new vluint8_t [entSize()];
memcpy(prevDatap(), varp()->datap(), entSize());
}
}
};
class VerilatedVpioMemoryWord : public VerilatedVpioVar {
public:
VerilatedVpioMemoryWord(const VerilatedVar* varp, const VerilatedScope* scopep,
vlsint32_t index, int offset)
: VerilatedVpioVar(varp, scopep) {
m_index = index;
m_varDatap = ((vluint8_t*)varp->datap()) + entSize()*offset;
}
virtual ~VerilatedVpioMemoryWord() {}
static inline VerilatedVpioMemoryWord* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioMemoryWord*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { return vpiMemoryWord; }
virtual vluint32_t size() const { return varp()->range().elements(); }
virtual const VerilatedRange* rangep() const { return &(varp()->range()); }
virtual const char* fullname() const {
static VL_THREAD_LOCAL std::string out;
char num[20]; sprintf(num,"%d",m_index);
out = std::string(scopep()->name())+"."+name()+"["+num+"]";
return out.c_str();
}
};
class VerilatedVpioVarIter : public VerilatedVpio {
const VerilatedScope* m_scopep;
VerilatedVarNameMap::const_iterator m_it;
bool m_started;
public:
explicit VerilatedVpioVarIter(const VerilatedScope* scopep)
: m_scopep(scopep), m_started(false) { }
virtual ~VerilatedVpioVarIter() {}
static inline VerilatedVpioVarIter* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVarIter*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { return vpiIterator; }
virtual vpiHandle dovpi_scan() {
if (VL_LIKELY(m_scopep->varsp())) {
VerilatedVarNameMap* varsp = m_scopep->varsp();
if (VL_UNLIKELY(!m_started)) { m_it = varsp->begin(); m_started=true; }
else if (VL_UNLIKELY(m_it == varsp->end())) return 0;
else ++m_it;
if (m_it == varsp->end()) return 0;
return ((new VerilatedVpioVar(&(m_it->second), m_scopep))
->castVpiHandle());
} else {
return 0; // End of list - only one deep
}
}
};
class VerilatedVpioMemoryWordIter : public VerilatedVpio {
const vpiHandle m_handle;
const VerilatedVar* m_varp;
vlsint32_t m_iteration;
vlsint32_t m_direction;
bool m_done;
public:
VerilatedVpioMemoryWordIter(const vpiHandle handle, const VerilatedVar* varp)
: m_handle(handle), m_varp(varp), m_iteration(varp->array().right()), m_direction(VL_LIKELY(varp->array().left()>varp->array().right())?1:-1), m_done(false) { }
virtual ~VerilatedVpioMemoryWordIter() {}
static inline VerilatedVpioMemoryWordIter* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioMemoryWordIter*>((VerilatedVpio*)h); }
virtual vluint32_t type() const { return vpiIterator; }
void iterationInc() {
if (!(m_done = (m_iteration == m_varp->array().left()))) m_iteration+=m_direction;
}
virtual vpiHandle dovpi_scan() {
vpiHandle result;
if (m_done) return 0;
result = vpi_handle_by_index(m_handle, m_iteration);
iterationInc();
return result;
}
};
//======================================================================
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 {
if (a.first < b.first) return 1;
if (a.first > b.first) return 0;
return a.second < b.second;
}
};
class VerilatedVpiError;
class VerilatedVpi {
enum { CB_ENUM_MAX_VALUE = cbAtEndOfSimTime+1 }; // Maxium callback reason
typedef std::list<VerilatedVpioCb*> VpioCbList;
typedef std::set<std::pair<QData,VerilatedVpioCb*>,VerilatedVpiTimedCbsCmp > VpioTimedCbs;
struct product_info {
PLI_BYTE8* product;
};
VpioCbList m_cbObjLists[CB_ENUM_MAX_VALUE]; // Callbacks for each supported reason
VpioTimedCbs m_timedCbs; // Time based callbacks
VerilatedVpiError* m_errorInfop; // Container for vpi error info
static VerilatedVpi s_s; // Singleton
public:
VerilatedVpi() { m_errorInfop=NULL; }
~VerilatedVpi() {}
static void cbReasonAdd(VerilatedVpioCb* vop) {
if (vop->reason() == cbValueChange) {
if (VerilatedVpioVar* varop = VerilatedVpioVar::castp(vop->cb_datap()->obj)) {
varop->createPrevDatap();
}
}
if (VL_UNLIKELY(vop->reason() >= CB_ENUM_MAX_VALUE)) vl_fatal(__FILE__,__LINE__,"", "vpi bb reason too large");
s_s.m_cbObjLists[vop->reason()].push_back(vop);
}
static void cbTimedAdd(VerilatedVpioCb* vop) {
s_s.m_timedCbs.insert(std::make_pair(vop->time(), vop));
}
static void cbReasonRemove(VerilatedVpioCb* cbp) {
VpioCbList& cbObjList = s_s.m_cbObjLists[cbp->reason()];
// We do not remove it now as we may be iterating the list,
// instead set to NULL and will cleanup later
for (VpioCbList::iterator it=cbObjList.begin(); it!=cbObjList.end(); ++it) {
if (*it == cbp) *it = NULL;
}
}
static void cbTimedRemove(VerilatedVpioCb* cbp) {
VpioTimedCbs::iterator 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 callTimedCbs() {
QData time = VL_TIME_Q();
for (VpioTimedCbs::iterator it=s_s.m_timedCbs.begin(); it!=s_s.m_timedCbs.end(); ) {
if (VL_UNLIKELY(it->first <= time)) {
VerilatedVpioCb* vop = it->second;
++it; // iterator may be deleted by callback
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: timed_callback %p\n",vop););
(vop->cb_rtnp()) (vop->cb_datap());
}
else { ++it; }
}
}
static QData cbNextDeadline() {
VpioTimedCbs::const_iterator it=s_s.m_timedCbs.begin();
if (VL_LIKELY(it!=s_s.m_timedCbs.end())) {
return it->first;
} else {
return ~VL_ULL(0); // maxquad
}
}
static void callCbs(vluint32_t reason) {
VpioCbList& cbObjList = s_s.m_cbObjLists[reason];
for (VpioCbList::iterator it=cbObjList.begin(); it!=cbObjList.end();) {
if (VL_UNLIKELY(!*it)) { // Deleted earlier, cleanup
it = cbObjList.erase(it);
continue;
}
VerilatedVpioCb* vop = *it++;
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: reason_callback %d %p\n",reason,vop););
(vop->cb_rtnp()) (vop->cb_datap());
}
}
static void callValueCbs() {
VpioCbList& cbObjList = s_s.m_cbObjLists[cbValueChange];
typedef std::set<VerilatedVpioVar*> VpioVarSet;
VpioVarSet update; // set of objects to update after callbacks
for (VpioCbList::iterator it=cbObjList.begin(); it!=cbObjList.end();) {
if (VL_UNLIKELY(!*it)) { // Deleted earlier, cleanup
it = cbObjList.erase(it);
continue;
}
VerilatedVpioCb* vop = *it++;
if (VerilatedVpioVar* varop = VerilatedVpioVar::castp(vop->cb_datap()->obj)) {
void* newDatap = varop->varDatap();
void* prevDatap = varop->prevDatap(); // Was malloced when we added the callback
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: value_test %s v[0]=%d/%d %p %p\n",
varop->fullname(), *((CData*)newDatap), *((CData*)prevDatap),
newDatap, prevDatap););
if (memcmp(prevDatap, newDatap, varop->entSize())) {
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: value_callback %p %s v[0]=%d\n",
vop,varop->fullname(), *((CData*)newDatap)););
update.insert(varop);
vpi_get_value(vop->cb_datap()->obj, vop->cb_datap()->value);
(vop->cb_rtnp()) (vop->cb_datap());
}
}
}
for (VpioVarSet::const_iterator it=update.begin(); it!=update.end(); ++it) {
memcpy((*it)->prevDatap(), (*it)->varDatap(), (*it)->entSize());
}
}
static VerilatedVpiError* error_info(); // getter for vpi error info
/// Call timed callbacks
/// Users should call this from their main loops
static void callTimedCbs() VL_MT_UNSAFE_ONE;
/// Call value based callbacks
/// Users should call this from their main loops
static void callValueCbs() VL_MT_UNSAFE_ONE;
/// Self test, for internal use only
static void selfTest() VL_MT_UNSAFE_ONE;
};
#define _VL_VPI_ERROR_SET \
do { \
va_list args; \
va_start(args, message); \
VL_VSNPRINTF(m_buff, sizeof(m_buff), message.c_str(), args); \
va_end(args); \
} while (0)
class VerilatedVpiError {
//// Container for vpi error info
t_vpi_error_info m_errorInfo;
bool m_flag;
char m_buff[VL_VPI_LINE_SIZE];
void setError(PLI_BYTE8 *message, PLI_BYTE8 *code, PLI_BYTE8 *file, PLI_INT32 line) {
m_errorInfo.message = message;
m_errorInfo.file = file;
m_errorInfo.line = line;
m_errorInfo.code = code;
do_callbacks();
}
void do_callbacks() {
if (getError()->level >= vpiError && Verilated::fatalOnVpiError()) {
// Stop on vpi error/unsupported
vpi_unsupported();
}
// We need to run above code first because in the case that the callback executes further vpi
// functions we will loose the error as it will be overwritten.
VerilatedVpi::callCbs(cbPLIError);
}
public:
VerilatedVpiError() : m_flag(false) {
m_buff[0] = '\0';
m_errorInfo.product = (PLI_BYTE8*)Verilated::productName();
}
~VerilatedVpiError() {}
static void selfTest();
VerilatedVpiError* setMessage(PLI_INT32 level) {
m_flag=true;
m_errorInfo.level = level;
return this;
}
void setMessage(std::string file, PLI_INT32 line, std::string message, ...) {
static VL_THREAD_LOCAL std::string filehold;
_VL_VPI_ERROR_SET;
m_errorInfo.state = vpiPLI;
filehold = file;
setError((PLI_BYTE8*)m_buff, NULL, (PLI_BYTE8*)filehold.c_str(), line);
}
p_vpi_error_info getError() {
if (m_flag) return &m_errorInfo;
return NULL;
}
void resetError() {
m_flag=false;
}
static void vpi_unsupported() {
// Not supported yet
p_vpi_error_info error_info_p = VerilatedVpi::error_info()->getError();
if (error_info_p) {
vl_fatal(error_info_p->file, error_info_p->line, "", error_info_p->message);
return;
}
vl_fatal(__FILE__, __LINE__, "", "vpi_unsupported called without error info set");
}
static const char* strFromVpiVal(PLI_INT32 vpiVal);
static const char* strFromVpiObjType(PLI_INT32 vpiVal);
static const char* strFromVpiMethod(PLI_INT32 vpiVal);
static const char* strFromVpiCallbackReason(PLI_INT32 vpiVal);
static const char* strFromVpiProp(PLI_INT32 vpiVal);
};
//======================================================================
#endif // Guard
+116 -17
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@@ -42,43 +42,84 @@
# else
# define VL_ATTR_PRINTF(fmtArgNum) __attribute__ ((format (printf, fmtArgNum, fmtArgNum+1)))
# endif
# define VL_ATTR_PURE __attribute__ ((pure))
# define VL_ATTR_UNUSED __attribute__ ((unused))
# define VL_FUNC __func__
# if defined(__clang__) && defined(VL_THREADED)
# define VL_ACQUIRE(...) __attribute__ ((acquire_capability(__VA_ARGS__)))
# define VL_ACQUIRE_SHARED(...) __attribute__ ((acquire_shared_capability(__VA_ARGS__)))
# define VL_RELEASE(...) __attribute__ ((release_capability(__VA_ARGS__)))
# define VL_RELEASE_SHARED(...) __attribute__ ((release_shared_capability(__VA_ARGS__)))
# define VL_TRY_ACQUIRE(...) __attribute__ ((try_acquire_capability(__VA_ARGS__)))
# define VL_TRY_ACQUIRE_SHARED(...) __attribute__ ((try_acquire_shared_capability(__VA_ARGS__)))
# define VL_CAPABILITY(x) __attribute__ ((capability(x)))
# define VL_REQUIRES(x) __attribute__ ((requires_capability(x)))
# define VL_GUARDED_BY(x) __attribute__ ((guarded_by(x)))
# define VL_EXCLUDES(x) __attribute__ ((locks_excluded(x)))
# define VL_SCOPED_CAPABILITY __attribute__ ((scoped_lockable))
# endif
# define VL_LIKELY(x) __builtin_expect(!!(x), 1)
# define VL_UNLIKELY(x) __builtin_expect(!!(x), 0)
# define VL_UNREACHABLE __builtin_unreachable();
# define VL_PREFETCH_RD(p) __builtin_prefetch((p),0)
# define VL_PREFETCH_RW(p) __builtin_prefetch((p),1)
#elif defined(_MSC_VER)
# define VL_ATTR_ALIGNED(alignment)
# define VL_ATTR_ALWINLINE
# define VL_ATTR_NORETURN
# define VL_ATTR_PRINTF(fmtArgNum)
# define VL_ATTR_UNUSED
# define VL_FUNC __FUNCTION__
# define VL_LIKELY(x) (!!(x))
# define VL_UNLIKELY(x) (!!(x))
# define VL_UNREACHABLE
# define VL_PREFETCH_RD(p)
# define VL_PREFETCH_RW(p)
#else
#endif
// Defaults for unsupported compiler features
#ifndef VL_ATTR_ALIGNED
# define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment
#endif
#ifndef VL_ATTR_ALWINLINE
# define VL_ATTR_ALWINLINE ///< Inline, even when not optimizing
#endif
#ifndef VL_ATTR_NORETURN
# define VL_ATTR_NORETURN ///< Function does not ever return
#endif
#ifndef VL_ATTR_PRINTF
# define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking
#endif
#ifndef VL_ATTR_PURE
# define VL_ATTR_PURE ///< Function is pure (and thus also VL_MT_SAFE)
#endif
#ifndef VL_ATTR_UNUSED
# define VL_ATTR_UNUSED ///< Function that may be never used
#endif
#ifndef VL_FUNC
# define VL_FUNC "__func__" ///< Name of current function for error macros
#endif
#ifndef VL_CAPABILITY
# define VL_ACQUIRE(...) ///< Function requires a capability/lock (-fthread-safety)
# define VL_ACQUIRE_SHARED(...) ///< Function aquires a shared capability/lock (-fthread-safety)
# define VL_RELEASE(...) ///< Function releases a capability/lock (-fthread-safety)
# define VL_RELEASE_SHARED(...) ///< Function releases a shared capability/lock (-fthread-safety)
# define VL_TRY_ACQUIRE(...) ///< Function returns bool if aquired a capability (-fthread-safety)
# define VL_TRY_ACQUIRE_SHARED(...) ///< Function returns bool if aquired a shared capability (-fthread-safety)
# define VL_REQUIRES(x) ///< Function requires a capability inbound (-fthread-safety)
# define VL_EXCLUDES(x) ///< Function requires not having a capability inbound (-fthread-safety)
# define VL_CAPABILITY(x) ///< Name of capability/lock (-fthread-safety)
# define VL_GUARDED_BY(x) ///< Name of mutex protecting this variable (-fthread-safety)
# define VL_SCOPED_CAPABILITY ///< Scoped threaded capability/lock (-fthread-safety)
#endif
#ifndef VL_LIKELY
# define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true than false
# define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false than true
#endif
#ifndef VL_UNREACHABLE
# define VL_UNREACHABLE ///< Point that may never be reached
#endif
#ifndef VL_PREFETCH_RD
# define VL_PREFETCH_RD(p) ///< Prefetch data with read intent
#endif
#ifndef VL_PREFETCH_RW
# define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent
#endif
#ifdef VL_THREADED
# ifdef __GNUC__
# if (__cplusplus < 201103L) && !defined(VL_THREADED_NO_C11_WARNING)
# error "VL_THREADED support plans to move to C++-11 and later only; use newer --std to be ready"
# error "VL_THREADED/--threads support requires C++-11 or newer only; use newer compiler"
# endif
# else
# error "Unsupported compiler for VL_THREADED: No thread-local declarator"
@@ -90,6 +131,12 @@
#define VL_THREAD ///< Deprecated
#define VL_STATIC_OR_THREAD static ///< Deprecated
#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
#define VL_MT_SAFE_POSTINIT ///< Comment tag that function is threadsafe when VL_THREADED, only during normal operation (post-init)
#define VL_MT_UNSAFE ///< Comment tag that function is not threadsafe when VL_THREADED
#define VL_MT_UNSAFE_ONE ///< Comment tag that function is not threadsafe when VL_THREADED, protected to make sure single-caller
#ifdef _MSC_VER
# define VL_ULL(c) (c##ui64) ///< Add appropriate suffix to 64-bit constant
#else
@@ -109,15 +156,22 @@
// C++-2011
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define VL_EQ_DELETE = delete
# define VL_HAS_UNIQUE_PTR
# define VL_HAS_UNORDERED_MAP
# define VL_UNIQUE_PTR std::unique_ptr
# define VL_UNORDERED_MAP std::unordered_map
# define VL_HAS_UNORDERED_SET
# 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>
#else
# define VL_UNIQUE_PTR std::auto_ptr
# define VL_UNORDERED_MAP std::map
# define VL_EQ_DELETE
# define vl_unique_ptr std::auto_ptr
# define vl_unordered_map std::map
# define vl_unordered_set std::set
# define VL_INCLUDE_UNORDERED_MAP <map>
# define VL_INCLUDE_UNORDERED_SET <set>
#endif
//=========================================================================
@@ -257,6 +311,14 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
/// Words this number of bits needs (1 bit=1 word)
#define VL_WORDS_I(nbits) (((nbits)+(VL_WORDSIZE-1))/VL_WORDSIZE)
//=========================================================================
// Class definition helpers
// Used to declare a class as uncopyable; put after a private:
#define VL_UNCOPYABLE(Type) \
Type(const Type& other) VL_EQ_DELETE; \
Type& operator= (const Type&) VL_EQ_DELETE
//=========================================================================
// Verilated function size macros
@@ -291,6 +353,43 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
# define VL_ROUND(n) round(n)
#endif
//=========================================================================
// Performance counters
/// The vluint64_t argument is loaded with a high-performance counter for profiling
/// or 0x0 if not implemeted on this platform
#if defined(__i386__) || defined(__x86_64__)
# define VL_RDTSC(val) { \
vluint32_t hi, lo; \
asm volatile("rdtsc" : "=a" (lo), "=d" (hi)); \
(val) = ((vluint64_t)lo) | (((vluint64_t)hi)<<32); \
}
#elif defined(__aarch64__)
# define VL_RDTSC(val) asm volatile("mrs %[rt],PMCCNTR_EL0" : [rt] "=r" (val));
#else
// We just silently ignore unknown OSes, as only leads to missing statistics
# define VL_RDTSC(val) (val) = 0;
#endif
//=========================================================================
// Threading related OS-specific functions
#if VL_THREADED
# if defined(__i386__) || defined(__x86_64__)
/// 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")
# elif defined(__ia64__)
# define VL_CPU_RELAX() asm volatile("hint @pause" ::: "memory")
# elif defined(__aarch64__)
# define VL_CPU_RELAX() asm volatile("yield" ::: "memory")
# elif defined(__powerpc64__)
# define VL_CPU_RELAX() asm volatile("or 1, 1, 1; or 2, 2, 2;" ::: "memory")
# else
# error "Missing VL_CPU_RELAX() definition. Or, don't use VL_THREADED"
# endif
#endif
//=========================================================================
#endif /*guard*/
+22 -22
View File
@@ -7,7 +7,7 @@
* This file contains the constant definitions, structure definitions,
* and routine declarations used by SystemVerilog DPI.
*
* This file is from the SystemVerilog IEEE 1800-2012 Annex I.
* This file is from the SystemVerilog IEEE 1800-2017 Annex I.
*/
#ifndef INCLUDED_SVDPI
@@ -117,7 +117,7 @@ typedef uint32_t svBitVecVal;
/*
* Return implementation version information string ("1800-2005" or "SV3.1a").
*/
XXTERN const char* svDpiVersion();
XXTERN const char* svDpiVersion( void );
/* a handle to a scope (an instance of a module or interface) */
XXTERN typedef void* svScope;
@@ -155,7 +155,7 @@ XXTERN void svGetPartselBit(svBitVecVal* d, const svBitVecVal* s, int i, int w);
XXTERN void svGetPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w);
XXTERN void svPutPartselBit(svBitVecVal* d, const svBitVecVal s, int i, int w);
XXTERN void svPutPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w);
XXTERN void svPutPartselLogic(svLogicVecVal* d, const svLogicVecVal s, int i, int w);
/*
* Open array querying functions
@@ -241,28 +241,28 @@ XXTERN void svGetLogicArrElem2VecVal(svLogicVecVal* d, const svOpenArrayHandle s
XXTERN void svGetLogicArrElem3VecVal(svLogicVecVal* d, const svOpenArrayHandle s,
int indx1, int indx2, int indx3);
XXTERN svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...);
XXTERN svBit svGetBitArrElem1(const svOpenArrayHandle s, int indx1);
XXTERN svBit svGetBitArrElem2(const svOpenArrayHandle s, int indx1, int indx2);
XXTERN svBit svGetBitArrElem3(const svOpenArrayHandle s, int indx1, int indx2,
XXTERN svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...);
XXTERN svBit svGetBitArrElem1(const svOpenArrayHandle s, int indx1);
XXTERN svBit svGetBitArrElem2(const svOpenArrayHandle s, int indx1, int indx2);
XXTERN svBit svGetBitArrElem3(const svOpenArrayHandle s, int indx1, int indx2,
int indx3);
XXTERN svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...);
XXTERN svLogic svGetLogicArrElem1(const svOpenArrayHandle s, int indx1);
XXTERN svLogic svGetLogicArrElem2(const svOpenArrayHandle s, int indx1, int indx2);
XXTERN svLogic svGetLogicArrElem3(const svOpenArrayHandle s, int indx1, int indx2,
XXTERN svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...);
XXTERN svLogic svGetLogicArrElem1(const svOpenArrayHandle s, int indx1);
XXTERN svLogic svGetLogicArrElem2(const svOpenArrayHandle s, int indx1, int indx2);
XXTERN svLogic svGetLogicArrElem3(const svOpenArrayHandle s, int indx1, int indx2,
int indx3);
XXTERN void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1,
XXTERN void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1,
...);
XXTERN void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1);
XXTERN void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1,
XXTERN void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1);
XXTERN void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1,
int indx2);
XXTERN void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1,
XXTERN void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1,
int indx2, int indx3);
XXTERN void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...);
XXTERN void svPutBitArrElem1(const svOpenArrayHandle d, svBit value, int indx1);
XXTERN void svPutBitArrElem2(const svOpenArrayHandle d, svBit value, int indx1,
XXTERN void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...);
XXTERN void svPutBitArrElem1(const svOpenArrayHandle d, svBit value, int indx1);
XXTERN void svPutBitArrElem2(const svOpenArrayHandle d, svBit value, int indx1,
int indx2);
XXTERN void svPutBitArrElem3(const svOpenArrayHandle d, svBit value, int indx1,
XXTERN void svPutBitArrElem3(const svOpenArrayHandle d, svBit value, int indx1,
int indx2, int indx3);
/* Functions for working with DPI context */
@@ -273,7 +273,7 @@ XXTERN void svPutBitArrElem3(const svOpenArrayHandle d, svBit value, int indx1
* is the scope of the function's declaration site, not call site.
* Returns NULL if called from C code that is *not* an imported function.
*/
XXTERN svScope svGetScope();
XXTERN svScope svGetScope( void );
/*
* Set context for subsequent export function execution.
@@ -337,7 +337,7 @@ XXTERN int svGetCallerInfo(const char** fileName, int *lineNumber);
* Returns 1 if the current execution thread is in the disabled state.
* Disable protocol must be adhered to if in the disabled state.
*/
XXTERN int svIsDisabledState();
XXTERN int svIsDisabledState( void );
/*
* Imported functions call this API function during disable processing to
@@ -345,7 +345,7 @@ XXTERN int svIsDisabledState();
* This function must be called before returning from an imported function that is
* in the disabled state.
*/
XXTERN void svAckDisabledState();
XXTERN void svAckDisabledState( void );
/*
**********************************************************
+3 -3
View File
@@ -1,7 +1,7 @@
/*******************************************************************************
* vpi_user.h
*
* IEEE Std 1800-2012 Programming Language Interface (PLI)
* IEEE Std 1800-2017 Programming Language Interface (PLI)
*
* This file contains the constant definitions, structure definitions, and
* routine declarations used by the SystemVerilog Verification Procedural
@@ -251,7 +251,7 @@ typedef PLI_UINT32 *vpiHandle;
#define vpiModPathOut 96 /* output terminal of a module path */
#define vpiOperand 97 /* operand of expression */
#define vpiPortInst 98 /* connected port instance */
#define vpiProcess 99 /* process in module */
#define vpiProcess 99 /* process in module, program or interface */
#define vpiVariables 100 /* variables in module */
#define vpiUse 101 /* usage */
@@ -978,7 +978,7 @@ XXTERN vpiHandle vpi_handle_by_multi_index PROTO_PARAMS((vpiHandle obj,
/****************************** GLOBAL VARIABLES ******************************/
PLI_VEXTERN PLI_DLLESPEC void (*vlog_startup_routines[])();
PLI_VEXTERN PLI_DLLESPEC void (*vlog_startup_routines[])( void );
/* array of function pointers, last pointer should be null */
+2 -2
View File
@@ -749,7 +749,7 @@ File a bug (if there isn't already) so others know what you're working on.
=item 2.
Make a testcase in the test_regress/t/t_EXAMPLE format, see L<TESTING>.
Make a testcase in the test_regress/t/t_EXAMPLE format, see L</TESTING>.
=item 3.
@@ -785,7 +785,7 @@ in C<src/Makefile_obj.in> and reconfigure.
The latest version is available from L<http://www.veripool.org/>.
Copyright 2008-2017 by Wilson Snyder. Verilator is free software; you can
Copyright 2008-2018 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
######################################################################
#
# Copyright 2007-2017 by Wilson Snyder. This package is free software; you
# Copyright 2007-2018 by Wilson Snyder. This package is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
######################################################################
#
# Copyright 2007-2017 by Wilson Snyder. This package is free software; you
# Copyright 2007-2018 by Wilson Snyder. This package is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
+1 -1
View File
@@ -143,7 +143,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION
Copyright 2005-2017 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2018 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
+1 -1
View File
@@ -184,7 +184,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION
Copyright 2005-2017 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2018 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
######################################################################
#
# Copyright 2007-2017 by Wilson Snyder. This package is free software; you
# Copyright 2007-2018 by Wilson Snyder. This package is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
+177
View File
@@ -0,0 +1,177 @@
#!/usr/bin/perl -w
# See copyright, etc in below POD section.
######################################################################
use Getopt::Long;
#use Data::Dumper; $Data::Dumper::Indent=1; $Data::Dumper::Sortkeys=1; #Debug
use IO::File;
use IO::Dir;
use Pod::Usage;
use strict;
use vars qw ($Debug);
our $VERSION = '0.001';
#======================================================================
# main
autoflush STDOUT 1;
autoflush STDERR 1;
Getopt::Long::config ("no_auto_abbrev");
if (! GetOptions (
"debug" => sub { $Debug = 1; },
"help" => sub { print "Version $VERSION\n";
pod2usage(-verbose=>2, -exitval => 2, output=>\*STDOUT, -noperldoc=>1); },
"version" => sub { print "Version $VERSION\n"; exit(0); },
"<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; },
)) {
die "%Error: Bad usage, try 'git_untabify --help'\n";
}
read_patch();
#######################################################################
sub read_patch {
my $filename = undef;
my $lineno = 0;
my $editlines = {};
while (defined(my $line = <STDIN>)) {
if ($line =~ m!^\+\+\+ b/(.*)!) {
edit_file($filename, $editlines);
$filename = $1;
$lineno = 0;
$editlines = {};
print "FILE $filename\n" if $Debug;
}
elsif ($line =~ m!^@@ -?[0-9]+,?[0-9]* \+?([0-9]+)!) {
$lineno = $1 - 1;
print " LINE $1 $line" if $Debug;
}
elsif ($line =~ m!^ !) {
++$lineno;
}
elsif ($line =~ m!^\+!) {
++$lineno;
if ($line =~ m!\t!) {
print " $lineno: $line" if $Debug;
$editlines->{$lineno} = 1;
}
}
}
edit_file($filename, $editlines);
}
sub edit_file {
my $filename = shift;
my $editlines = shift;
return if (scalar keys(%$editlines) < 1);
if (ignore($filename)) {
print "%Warning: Ignoring $filename\n";
return;
}
print "Edit $filename ",join(",",sort(keys %$editlines)),"\n";
my $lineno = 0;
my @out;
{
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
while (defined(my $line = $fh->getline)) {
++$lineno;
if ($editlines->{$lineno}) {
print $line;
push @out, untabify($line);
} else {
push @out, $line;
}
}
$fh->close;
}
{
my $fh = IO::File->new(">${filename}.untab") or die "%Error: $! ${filename}.untab,";
$fh->print(join('',@out));
$fh->close;
my ($dev,$ino,$mode) = stat($filename);
chmod $mode, "${filename}.untab";
}
rename("${filename}.untab", $filename) or die "%Error: $! ${filename}.untab,";
}
sub ignore {
my $filename = shift;
return 1 if ($filename =~ /(Makefile|\.mk)/);
return 1 if ($filename =~ /\.(y|l|out|vcd)$/);
#
return 0 if ($filename =~ /\.(sv|v|vh|svh|h|vc|cpp|pl)$/);
return 0;
}
sub untabify {
my $line = shift;
my $out = "";
my $col = 0;
foreach my $c (split //, $line) {
if ($c eq "\t") {
my $destcol = int(($col+8)/8)*8;
while ($col < $destcol) { ++$col; $out .= " "; }
} else {
$out .= $c;
$col++;
}
}
return $out;
}
#######################################################################
__END__
=pod
=head1 NAME
git_untabify - Pipe a git diff report and untabify differences
=head1 SYNOPSIS
git diff a..b | git_untabify
=head1 DESCRIPTION
Take a patch file, and edit the files in the destination patch list to
untabify the related patch lines.
=head1 ARGUMENTS
=over 4
=item --help
Displays this message and program version and exits.
=item --version
Displays program version and exits.
=back
=head1 DISTRIBUTION
Copyright 2005-2018 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.
=head1 AUTHORS
Wilson Snyder <[email protected]>
=head1 SEE ALSO
=cut
######################################################################
### Local Variables:
### compile-command: "./git_untabify "
### End:
+4 -4
View File
@@ -100,14 +100,14 @@ sub write_verilog {
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('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(' top->eval();' ,"\n");
$fh->print(' main_time++;' ,"\n");
$fh->print(' }' ,"\n");
$fh->print(' top->final();' ,"\n");
$fh->print('}' ,"\n");
@@ -184,7 +184,7 @@ Runs a specific test stage (see the script).
=head1 DISTRIBUTION
Copyright 2009-2017 by Wilson Snyder. This package is free software; you
Copyright 2009-2018 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+1 -1
View File
@@ -28,7 +28,7 @@ invoke_atsim - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2005-2017 by Wilson Snyder. This package is free software; you
Copyright 2005-2018 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+1 -1
View File
@@ -28,7 +28,7 @@ invoke_iccr - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2007-2017 by Wilson Snyder. This package is free software; you
Copyright 2007-2018 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+2 -2
View File
@@ -8,7 +8,7 @@ use strict;
#======================================================================
# main
eval `modulecmd perl add cds-ius`;
eval `modulecmd perl add cds-ius/latest`;
exec('ncverilog',@ARGV);
#######################################################################
@@ -28,7 +28,7 @@ invoke_ncverilog - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2005-2017 by Wilson Snyder. This package is free software; you
Copyright 2005-2018 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+2 -2
View File
@@ -8,7 +8,7 @@ use strict;
#======================================================================
# main
eval `modulecmd perl add synopsys-sim`;
eval `modulecmd perl add synopsys-sim/latest`;
exec('vcs',@ARGV);
#######################################################################
@@ -28,7 +28,7 @@ invoke_vcs - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2005-2017 by Wilson Snyder. This package is free software; you
Copyright 2005-2018 by Wilson Snyder. This package is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+1 -1
View File
@@ -331,7 +331,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION
Copyright 2005-2017 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2018 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License Version 3 or the Perl Artistic License Version 2.0.
+1 -1
View File
@@ -1,6 +1,6 @@
# DESCRIPTION: Verilator: GDB startup file with useful defines
#
# Copyright 2012-2017 by Wilson Snyder. This program is free software; you can
# Copyright 2012-2018 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
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2018 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 -1
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2018 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.
@@ -104,6 +104,7 @@ CPPFLAGS += -W -Wall $(CFG_CXXFLAGS_WEXTRA) $(CFG_CXXFLAGS_SRC) -Werror
else
CPPFLAGS += $(CFG_CXXFLAGS_SRC)
endif
CPPFLAGSWALL = $(CPPFLAGS)
CPPFLAGSPARSER = $(CPPFLAGS) $(CFG_CXXFLAGS_PARSER)
+8 -4
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -174,11 +174,13 @@ private:
// Convert to a non-delayed assignment
UINFO(5," ASSIGNDLY "<<nodep<<endl);
if (m_check == CT_INITIAL) {
nodep->v3warn(INITIALDLY,"Delayed assignments (<=) in initial or final block; suggest blocking assignments (=).");
nodep->v3warn(INITIALDLY, "Delayed assignments (<=) in initial"
" or final block; suggest blocking assignments (=).");
} else if (m_check == CT_LATCH) {
// Suppress. Shouldn't matter that the interior of the latch races
} else {
nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=).");
nodep->v3warn(COMBDLY, "Delayed assignments (<=) in non-clocked"
" (non flop or latch) block; suggest blocking assignments (=).");
}
AstNode* newp = new AstAssign (nodep->fileline(),
nodep->lhsp()->unlinkFrBack(),
@@ -437,6 +439,8 @@ public:
void V3Active::activeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ActiveVisitor visitor (nodep);
{
ActiveVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("active", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
+4 -2
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -159,6 +159,8 @@ public:
void V3ActiveTop::activeTopAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ActiveTopVisitor visitor (nodep);
{
ActiveTopVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("activetop", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+42 -11
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2005-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2018 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -67,7 +67,7 @@ private:
timesp->unlinkFrBackWithNext();
timenewp->addNext(timesp);
}
nodep->fmtp()->exprsp(timenewp);
nodep->fmtp()->addExprsp(timenewp);
if (!nodep->fmtp()->scopeNamep() && nodep->fmtp()->formatScopeTracking()) {
nodep->fmtp()->scopeNamep(new AstScopeName(nodep->fileline()));
}
@@ -88,11 +88,17 @@ private:
return newp;
}
AstNode* newFireAssert(AstNode* nodep, const string& message) {
AstNode* newFireAssertUnchecked(AstNode* nodep, const string& message) {
// Like newFireAssert() but omits the asserts-on check
AstDisplay* dispp = new AstDisplay (nodep->fileline(), AstDisplayType::DT_ERROR, message, NULL, NULL);
AstNode* bodysp = dispp;
replaceDisplay(dispp, "%%Error"); // Convert to standard DISPLAY format
bodysp->addNext(new AstStop (nodep->fileline()));
return bodysp;
}
AstNode* newFireAssert(AstNode* nodep, const string& message) {
AstNode* bodysp = newFireAssertUnchecked(nodep, message);
bodysp = newIfAssertOn(bodysp);
return bodysp;
}
@@ -105,7 +111,9 @@ private:
//
AstNode* bodysp = NULL;
bool selfDestruct = false;
AstIf* ifp = NULL;
if (AstPslCover* snodep = nodep->castPslCover()) {
++m_statAsCover;
if (!v3Global.opt.coverageUser()) {
selfDestruct = true;
} else {
@@ -116,14 +124,30 @@ private:
if (message!="") covincp->declp()->comment(message);
bodysp = covincp;
}
if (bodysp && stmtsp) bodysp = bodysp->addNext(stmtsp);
ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL);
bodysp = ifp;
} else if (nodep->castPslAssert()) {
++m_statAsPsl;
// Insert an automatic error message and $stop after
// any user-supplied statements.
AstNode* autoMsgp = newFireAssertUnchecked(nodep, "'assert property' failed.");
if (stmtsp) {
stmtsp->addNext(autoMsgp);
} else {
stmtsp = autoMsgp;
}
ifp = new AstIf(nodep->fileline(), propp, NULL, stmtsp);
// It's more LIKELY that we'll take the NULL if clause
// than the sim-killing else clause:
ifp->branchPred(AstBranchPred::BP_LIKELY);
bodysp = newIfAssertOn(ifp);
} else {
nodep->v3fatalSrc("Unknown node type");
}
if (bodysp && stmtsp) bodysp = bodysp->addNext(stmtsp);
AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL);
bodysp = ifp;
if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
//
AstNode* newp = new AstAlways (nodep->fileline(),
VAlwaysKwd::ALWAYS,
sentreep,
@@ -202,6 +226,9 @@ private:
AstNode *newifp = nodep->cloneTree(false);
bool allow_none = nodep->unique0Pragma();
// Empty case means no property
if (!propp) propp = new AstConst(nodep->fileline(), AstConst::LogicFalse());
// Note: if this ends with an 'else', then we don't need to validate that one of the
// predicates evaluates to true.
AstNode* ohot = ((allow_none || hasDefaultElse)
@@ -259,6 +286,9 @@ private:
else propp = onep;
}
}
// Empty case means no property
if (!propp) propp = new AstConst(nodep->fileline(), AstConst::LogicFalse());
bool allow_none = has_default || nodep->unique0Pragma();
AstNode* ohot = (allow_none
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
@@ -288,12 +318,11 @@ private:
}
}
virtual void visit(AstPslCover* nodep) {
virtual void visit(AstNodePslCoverOrAssert* nodep) {
nodep->iterateChildren(*this);
if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name());
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
nodep->stmtsp(), nodep->name()); VL_DANGLING(nodep);
++m_statAsCover;
}
virtual void visit(AstVAssert* nodep) {
nodep->iterateChildren(*this);
@@ -343,6 +372,8 @@ public:
void V3Assert::assertAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
AssertVisitor visitor (nodep);
{
AssertVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("assert", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2005-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2018 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 -3
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2005-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2018 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.
@@ -86,7 +86,7 @@ private:
pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstPslCover* nodep) {
virtual void visit(AstNodePslCoverOrAssert* nodep) {
if (nodep->sentreep()) return; // Already processed
clearAssertInfo();
nodep->iterateChildren(*this);
@@ -136,6 +136,8 @@ public:
void V3AssertPre::assertPreAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
AssertPreVisitor visitor (nodep);
{
AssertPreVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("assertpre", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2005-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2018 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.
+33 -22
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -229,7 +229,8 @@ inline void AstNode::debugTreeChange(const char* prefix, int lineno, bool next)
// Called on all major tree changers.
// Only for use for those really nasty bugs relating to internals
// Note this may be null.
//if (debug()) cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<": "<<(void*)this<<" <e"<<AstNode::s_editCntGbl<<">"<<endl;
//if (debug()) cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "
// <<prefix<<": "<<(void*)this<<" <e"<<AstNode::s_editCntGbl<<">"<<endl;
//if (debug()) {
// cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<endl;
// // Commenting out the section below may crash, as the tree state
@@ -290,8 +291,8 @@ void AstNode::addNextHere(AstNode* newp) {
// This could be at head, tail, or both (single)
// New could be head of single node, or list
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
UASSERT(newp,"Null item passed to addNext");
UASSERT(newp->backp()==NULL,"New node (back) already assigned?");
UASSERT(newp, "Null item passed to addNext");
UASSERT(!newp->backp(), "New node (back) already assigned?");
this->debugTreeChange("-addHereThs: ", __LINE__, false);
newp->debugTreeChange("-addHereNew: ", __LINE__, true);
newp->editCountInc();
@@ -334,7 +335,7 @@ void AstNode::addNextHere(AstNode* newp) {
}
void AstNode::setOp1p(AstNode* newp) {
UASSERT(newp,"Null item passed to setOp1p\n");
UASSERT(newp, "Null item passed to setOp1p");
UDEBUGONLY(if (m_op1p) this->v3fatalSrc("Adding to non-empty, non-list op1"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op1"););
@@ -347,7 +348,7 @@ void AstNode::setOp1p(AstNode* newp) {
}
void AstNode::setOp2p(AstNode* newp) {
UASSERT(newp,"Null item passed to setOp2p\n");
UASSERT(newp, "Null item passed to setOp2p");
UDEBUGONLY(if (m_op2p) this->v3fatalSrc("Adding to non-empty, non-list op2"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op2"););
@@ -360,7 +361,7 @@ void AstNode::setOp2p(AstNode* newp) {
}
void AstNode::setOp3p(AstNode* newp) {
UASSERT(newp,"Null item passed to setOp3p\n");
UASSERT(newp, "Null item passed to setOp3p");
UDEBUGONLY(if (m_op3p) this->v3fatalSrc("Adding to non-empty, non-list op3"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op3"););
@@ -373,7 +374,7 @@ void AstNode::setOp3p(AstNode* newp) {
}
void AstNode::setOp4p(AstNode* newp) {
UASSERT(newp,"Null item passed to setOp4p\n");
UASSERT(newp, "Null item passed to setOp4p");
UDEBUGONLY(if (m_op4p) this->v3fatalSrc("Adding to non-empty, non-list op4"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op4"););
@@ -386,25 +387,25 @@ void AstNode::setOp4p(AstNode* newp) {
}
void AstNode::addOp1p(AstNode* newp) {
UASSERT(newp,"Null item passed to addOp1p\n");
UASSERT(newp, "Null item passed to addOp1p");
if (!m_op1p) { op1p(newp); }
else { m_op1p->addNext(newp); }
}
void AstNode::addOp2p(AstNode* newp) {
UASSERT(newp,"Null item passed to addOp2p\n");
UASSERT(newp, "Null item passed to addOp2p");
if (!m_op2p) { op2p(newp); }
else { m_op2p->addNext(newp); }
}
void AstNode::addOp3p(AstNode* newp) {
UASSERT(newp,"Null item passed to addOp3p\n");
UASSERT(newp, "Null item passed to addOp3p");
if (!m_op3p) { op3p(newp); }
else { m_op3p->addNext(newp); }
}
void AstNode::addOp4p(AstNode* newp) {
UASSERT(newp,"Null item passed to addOp4p\n");
UASSERT(newp, "Null item passed to addOp4p");
if (!m_op4p) { op4p(newp); }
else { m_op4p->addNext(newp); }
}
@@ -430,7 +431,7 @@ void AstNRelinker::dump(ostream& str) const {
AstNode* AstNode::unlinkFrBackWithNext(AstNRelinker* linkerp) {
this->debugTreeChange("-unlinkWNextThs: ", __LINE__, true);
AstNode* oldp = this;
UASSERT(oldp->m_backp,"Node has no back, already unlinked?\n");
UASSERT(oldp->m_backp, "Node has no back, already unlinked?");
oldp->editCountInc();
AstNode* backp = oldp->m_backp;
if (linkerp) {
@@ -478,7 +479,7 @@ AstNode* AstNode::unlinkFrBackWithNext(AstNRelinker* linkerp) {
AstNode* AstNode::unlinkFrBack(AstNRelinker* linkerp) {
this->debugTreeChange("-unlinkFrBkThs: ", __LINE__, true);
AstNode* oldp = this;
UASSERT(oldp->m_backp,"Node has no back, already unlinked?\n");
UASSERT(oldp->m_backp, "Node has no back, already unlinked?");
oldp->editCountInc();
AstNode* backp = oldp->m_backp;
if (linkerp) {
@@ -530,8 +531,8 @@ AstNode* AstNode::unlinkFrBack(AstNRelinker* linkerp) {
void AstNode::relink(AstNRelinker* linkerp) {
if (debug()>8) { UINFO(0," EDIT: relink: "); dumpPtrs(); }
AstNode* newp = this;
UASSERT(linkerp && linkerp->m_backp, "Need non-empty linker\n");
UASSERT(newp->backp()==NULL, "New node already linked?\n");
UASSERT(linkerp && linkerp->m_backp, "Need non-empty linker");
UASSERT(!newp->backp(), "New node already linked?");
newp->editCountInc();
if (debug()>8) { linkerp->dump(cout); cout<<endl; }
@@ -667,7 +668,7 @@ AstNode* AstNode::cloneTree(bool cloneNextLink) {
void AstNode::deleteNode() {
// private: Delete single node. Publicly call deleteTree() instead.
UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n");
UASSERT(!m_backp, "Delete called on node with backlink still set");
editCountInc();
// Change links of old node so we coredump if used
this->m_nextp = (AstNode*)1;
@@ -677,9 +678,17 @@ void AstNode::deleteNode() {
this->m_op2p = (AstNode*)1;
this->m_op3p = (AstNode*)1;
this->m_op4p = (AstNode*)1;
if (
#if !defined(VL_DEBUG) || defined(VL_LEAK_CHECKS)
delete this; // Leak massively, so each pointer is unique and we can debug easier
1
#else
!v3Global.opt.debugLeak()
#endif
) {
delete this;
}
// Else leak massively, so each pointer is unique
// and we can debug easier.
}
AstNode::~AstNode() {
@@ -704,7 +713,7 @@ void AstNode::deleteTreeIter() {
void AstNode::deleteTree() {
// deleteTree always deletes the next link, because you must have called
// unlinkFromBack or unlinkFromBackWithNext as appropriate before calling this.
UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n");
UASSERT(!m_backp, "Delete called on node with backlink still set");
this->debugTreeChange("-delTree: ", __LINE__, true);
this->editCountInc();
// MUST be depth first!
@@ -779,7 +788,9 @@ void AstNode::iterateAndNext(AstNVisitor& v) {
niterp->m_iterpp = &niterp;
niterp->accept(v);
// accept may do a replaceNode and change niterp on us...
//if (niterp != nodep) UINFO(1,"iterateAndNext edited "<<(void*)nodep<<" now into "<<(void*)niterp<<endl); // niterp maybe NULL, so need cast
// niterp maybe NULL, so need cast if printing
//if (niterp != nodep) UINFO(1,"iterateAndNext edited "<<(void*)nodep
// <<" now into "<<(void*)niterp<<endl);
if (!niterp) return; // Perhaps node deleted inside accept
niterp->m_iterpp = NULL;
if (VL_UNLIKELY(niterp!=nodep)) { // Edited node inside accept
@@ -1037,8 +1048,8 @@ void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
if (doDump) {
{ // Write log & close
UINFO(2,"Dumping "<<filename<<endl);
const VL_UNIQUE_PTR<ofstream> logsp (V3File::new_ofstream(filename, append));
if (logsp->fail()) v3fatalSrc("Can't write "<<filename);
const vl_unique_ptr<std::ofstream> logsp (V3File::new_ofstream(filename, append));
if (logsp->fail()) v3fatal("Can't write "<<filename);
*logsp<<"Verilator Tree Dump (format 0x3900) from <e"<<dec<<editCountLast()<<">";
*logsp<<" to <e"<<dec<<editCountGbl()<<">"<<endl;
if (editCountGbl()==editCountLast()
+158 -69
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -167,7 +167,7 @@ class AstEdgeType {
public:
// REMEMBER to edit the strings below too
enum en {
// These must be in general -> most specific order, as we sort by it in V3Const::visit AstSenTre
// These must be in general -> most specific order, as we sort by it in V3Const::visit AstSenTree
ET_ILLEGAL,
// Involving a variable
ET_ANYEDGE, // Default for sensitivities; rip them out
@@ -208,14 +208,37 @@ public:
"COMBO","INITIAL","SETTLE","NEVER"
};
return names[m_e];
};
}
const char* verilogKwd() const {
static const char* const names[] = {
"%E-edge", "[any]", "edge", "posedge", "negedge", "[high]","[low]",
"*","[initial]","[settle]","[never]"
};
return names[m_e];
};
}
// Return true iff this and the other have mutually exclusive transitions
bool exclusiveEdge(const AstEdgeType& other) const {
switch (m_e) {
case AstEdgeType::ET_POSEDGE:
switch (other.m_e) {
case AstEdgeType::ET_NEGEDGE: // FALLTHRU
case AstEdgeType::ET_LOWEDGE:
return true;
default: {}
}
break;
case AstEdgeType::ET_NEGEDGE:
switch (other.m_e) {
case AstEdgeType::ET_POSEDGE: // FALLTHRU
case AstEdgeType::ET_HIGHEDGE:
return true;
default: {}
}
break;
default: {}
}
return false;
}
inline AstEdgeType () : m_e(ET_ILLEGAL) {}
// cppcheck-suppress noExplicitConstructor
inline AstEdgeType (en _e) : m_e(_e) {}
@@ -340,9 +363,9 @@ public:
};
return names[m_e];
};
static void test() {
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).ascii()," MAX"),"Enum array mismatch");
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).dpiType()," MAX"),"Enum array mismatch");
static void selfTest() {
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).ascii()," MAX"), "SelfTest: Enum mismatch");
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).dpiType()," MAX"),"SelfTest: Enum mismatch");
}
inline AstBasicDTypeKwd () : m_e(UNKNOWN) {}
// cppcheck-suppress noExplicitConstructor
@@ -395,11 +418,21 @@ public:
bool isBitLogic() const { // Bit/logic vector types; can form a packed array
return (m_e==LOGIC || m_e==BIT);
}
bool isDpiUnsupported() const {
return (m_e==TIME);
bool isDpiBitVal() const { // DPI uses svBitVecVal
return m_e==BIT;
}
bool isDpiLogicVal() const { // DPI uses svLogicVecVal
return m_e==INTEGER || m_e==LOGIC || m_e==LOGIC_IMPLICIT || m_e==TIME;
}
bool isDpiUnreturnable() const { // Not legal as DPI function return
return isDpiLogicVal();
}
bool isDpiUnsignable() const { // Can add "unsigned" to DPI
return (m_e==BYTE || m_e==SHORTINT || m_e==INT || m_e==LONGINT || m_e==INTEGER);
return (m_e==BYTE || m_e==SHORTINT || m_e==INT || m_e==LONGINT || m_e==INTEGER);
}
bool isDpiCLayout() const { // Uses standard C layout, for DPI runtime access
return (m_e==BIT || m_e==BYTE || m_e==CHANDLE || m_e==INT
|| m_e==LONGINT || m_e==DOUBLE || m_e==SHORTINT || m_e==UINT32 || m_e==UINT64);
}
bool isOpaque() const { // IE not a simple number we can bit optimize
return (m_e==STRING || m_e==SCOPEPTR || m_e==CHARPTR || m_e==DOUBLE || m_e==FLOAT);
@@ -658,10 +691,14 @@ struct VNumRange {
return false;
}
//
class LeftRight {};
VNumRange() : m_hi(0), m_lo(0), mu_flags(0) {}
VNumRange(int hi, int lo, bool littleEndian)
: m_hi(0), m_lo(0), mu_flags(0)
{ init(hi,lo,littleEndian); }
VNumRange(LeftRight, int left, int right)
: m_hi(0), m_lo(0), mu_flags(0)
{ init((right>left)?right:left, (right>left)?left:right, (right>left)); }
~VNumRange() {}
// MEMBERS
void init(int hi, int lo, bool littleEndian) {
@@ -854,14 +891,18 @@ public:
class AstNVisitor {
private:
vector<AstNode*> m_deleteps; // Nodes to delete when we are finished
vector<AstNode*> m_deleteps; // Nodes to delete when doDeletes() called
protected:
friend class AstNode;
public:
// Cleaning
/// At the end of the visitor (or doDeletes()), delete this pushed node
/// along with all children and next(s). This is often better to use
/// than an immediate deleteTree, as any pointers into this node will
/// persist for the lifetime of the visitor
void pushDeletep(AstNode* nodep) {
m_deleteps.push_back(nodep);
}
/// Call deleteTree on all previously pushDeletep()'ed nodes
void doDeletes();
public:
virtual ~AstNVisitor() {
@@ -919,7 +960,7 @@ public:
inline bool operator== (const V3Hash& rh) const { return m_both==rh.m_both; }
inline bool operator!= (const V3Hash& rh) const { return m_both!=rh.m_both; }
inline bool operator< (const V3Hash& rh) const { return m_both<rh.m_both; }
// CREATORS
// CONSTRUCTORS
class Illegal {}; // for creator type-overload selection
class FullValue {}; // for creator type-overload selection
explicit V3Hash(Illegal) { m_both=0; }
@@ -1060,7 +1101,8 @@ public:
AstNode* op4p() const { return m_op4p; }
AstNodeDType* dtypep() const { return m_dtypep; }
AstNode* clonep() const { return ((m_cloneCnt==s_cloneCntGbl)?m_clonep:NULL); }
AstNode* firstAbovep() const { return ((backp() && backp()->nextp()!=this) ? backp() : NULL); } // Returns NULL when second or later in list
AstNode* firstAbovep() const { // Returns NULL when second or later in list
return ((backp() && backp()->nextp()!=this) ? backp() : NULL); }
bool brokeExists() const;
bool brokeExistsAbove() const;
@@ -1246,12 +1288,13 @@ public:
static AstNode* addNextNull(AstNode* nodep, AstNode* newp); // Returns nodep, adds newp (maybe NULL) to end of nodep's list
inline AstNode* addNext(AstNode* newp) { return addNext(this, newp); }
inline AstNode* addNextNull(AstNode* newp) { return addNextNull(this, newp); }
void addNextHere(AstNode* newp); // Adds after speced node
void addNextHere(AstNode* newp); // Insert newp at this->nextp
void addPrev(AstNode* newp) { replaceWith(newp); newp->addNext(this); }
void addHereThisAsNext(AstNode* newp); // Adds at old place of this, this becomes next
void replaceWith(AstNode* newp); // Replace current node in tree with new node
AstNode* unlinkFrBack(AstNRelinker* linkerp=NULL); // Unlink this from whoever points to it.
AstNode* unlinkFrBackWithNext(AstNRelinker* linkerp=NULL); // Unlink this from whoever points to it, keep entire next list with unlinked node
// Unlink this from whoever points to it, keep entire next list with unlinked node
AstNode* unlinkFrBackWithNext(AstNRelinker* linkerp=NULL);
void swapWith(AstNode* bp);
void relink(AstNRelinker* linkerp); // Generally use linker->relink() instead
void cloneRelinkNode() { cloneRelink(); }
@@ -1280,17 +1323,20 @@ public:
virtual bool isPure() const { return true; } // Else a $display, etc, that must be ordered with other displays
virtual bool isBrancher() const { return false; } // Changes control flow, disable some optimizations
virtual bool isGateOptimizable() const { return true; } // Else a AstTime etc that can't be pushed out
virtual bool isGateDedupable() const { return isGateOptimizable(); } // GateDedupable is a slightly larger superset of GateOptimzable (eg, AstNodeIf)
// GateDedupable is a slightly larger superset of GateOptimzable (eg, AstNodeIf)
virtual bool isGateDedupable() const { return isGateOptimizable(); }
virtual bool isSubstOptimizable() const { return true; } // Else a AstTime etc that can't be substituted out
virtual bool isPredictOptimizable() const { return true; } // Else a AstTime etc which output can't be predicted from input
virtual bool isOutputter() const { return false; } // Else creates output or exits, etc, not unconsumed
virtual bool isUnlikely() const { return false; } // Else $stop or similar statement which means an above IF statement is unlikely to be taken
// isUnlikely handles $stop or similar statement which means an above IF statement is unlikely to be taken
virtual bool isUnlikely() const { return false; }
virtual int instrCount() const { return 0; }
virtual V3Hash sameHash() const { return V3Hash(V3Hash::Illegal()); } // Not a node that supports it
virtual bool same(AstNode* otherp) const { return true; }
virtual bool same(const AstNode*) const { return true; }
virtual bool hasDType() const { return false; } // Iff has a data type; dtype() must be non null
virtual AstNodeDType* getChildDTypep() const { return NULL; } // Iff has a non-null childDTypep(), as generic node function
virtual bool maybePointedTo() const { return false; } // Another AstNode* may have a pointer into this node, other then normal front/back/etc.
// Another AstNode* may have a pointer into this node, other then normal front/back/etc.
virtual bool maybePointedTo() const { return false; }
virtual const char* broken() const { return NULL; }
// INVOKERS
@@ -1369,7 +1415,7 @@ public:
virtual bool stringFlavor() const { return false; } // N flavor of nodes with both flavors?
virtual int instrCount() const { return widthInstrs(); }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode*) const { return true; }
virtual bool same(const AstNode*) const { return true; }
};
class AstNodeBiop : public AstNodeMath {
@@ -1396,7 +1442,7 @@ public:
virtual bool stringFlavor() const { return false; } // N flavor of nodes with both flavors?
virtual int instrCount() const { return widthInstrs(); }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode*) const { return true; }
virtual bool same(const AstNode*) const { return true; }
};
class AstNodeTriop : public AstNodeMath {
@@ -1413,7 +1459,9 @@ public:
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
void thsp(AstNode* nodep) { return setOp3p(nodep); }
// METHODS
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, const V3Number& ths) = 0; // Set out to evaluation of a AstConst'ed
// Set out to evaluation of a AstConst'ed
virtual void numberOperate(V3Number& out, const V3Number& lhs,
const V3Number& rhs, const V3Number& ths) = 0;
virtual bool cleanLhs() = 0; // True if LHS must have extra upper bits zero
virtual bool cleanRhs() = 0; // True if RHS must have extra upper bits zero
virtual bool cleanThs() = 0; // True if THS must have extra upper bits zero
@@ -1422,7 +1470,7 @@ public:
virtual bool sizeMattersThs() = 0; // True if output result depends on ths size
virtual int instrCount() const { return widthInstrs(); }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode*) const { return true; }
virtual bool same(const AstNode*) const { return true; }
};
class AstNodeBiCom : public AstNodeBiop {
@@ -1482,7 +1530,7 @@ public:
void attrp(AstAttrOf* nodep) { return setOp4p((AstNode*)nodep); }
// METHODS
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode*) const { return true; }
virtual bool same(const AstNode*) const { return true; }
};
class AstNodeStmt : public AstNode {
@@ -1514,7 +1562,7 @@ public:
virtual bool cleanRhs() { return true; }
virtual int instrCount() const { return widthInstrs(); }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode*) const { return true; }
virtual bool same(const AstNode*) const { return true; }
virtual string verilogKwd() const { return "="; }
virtual bool brokeLhsMustBeLvalue() const = 0;
};
@@ -1534,7 +1582,7 @@ public:
virtual bool isGateOptimizable() const { return false; }
virtual int instrCount() const { return instrCountBranch(); }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
virtual bool same(const AstNode* samep) const { return true; }
};
class AstNodeIf : public AstNodeStmt {
@@ -1556,7 +1604,7 @@ public:
virtual bool isGateDedupable() const { return true; }
virtual int instrCount() const { return instrCountBranch(); }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
virtual bool same(const AstNode* samep) const { return true; }
void branchPred(AstBranchPred flag) { m_branchPred = flag; }
AstBranchPred branchPred() const { return m_branchPred; }
};
@@ -1648,8 +1696,9 @@ public:
ASTNODE_BASE_FUNCS(NodeText)
virtual void dump(ostream& str=cout);
virtual V3Hash sameHash() const { return V3Hash(text()); }
virtual bool same(AstNode* samep) const {
return text()==samep->castNodeText()->text(); }
virtual bool same(const AstNode* samep) const {
const AstNodeText* asamep = static_cast<const AstNodeText*>(samep);
return text() == asamep->text(); }
const string& text() const { return m_text; }
};
@@ -1684,6 +1733,8 @@ public:
virtual AstNodeDType* virtRefDTypep() const { return NULL; } // Iff has a non-null refDTypep(), as generic node function
virtual void virtRefDTypep(AstNodeDType* nodep) { } // Iff has refDTypep(), set as generic node function
virtual bool similarDType(AstNodeDType* samep) const = 0; // Assignable equivalence. Call skipRefp() on this and samep before calling
virtual AstNodeDType* subDTypep() const { return NULL; } // Iff has a non-null subDTypep(), as generic node function
virtual bool isFourstate() const;
//
// Changing the width may confuse the data type resolution, so must clear TypeTable cache after use.
void widthForce(int width, int sized) { m_width=width; m_widthMin=sized; }
@@ -1696,7 +1747,8 @@ public:
bool isNosign() const { return m_numeric.isNosign(); }
AstNumeric numeric() const { return m_numeric; }
int widthWords() const { return VL_WORDS_I(width()); }
int widthMin() const { return m_widthMin?m_widthMin:m_width; } // If sized, the size, if unsized the min digits to represent it
int widthMin() const { // If sized, the size, if unsized the min digits to represent it
return m_widthMin?m_widthMin:m_width; }
int widthPow2() const;
void widthMinFromWidth() { m_widthMin = m_width; }
bool widthSized() const { return !m_widthMin || m_widthMin==m_width; }
@@ -1706,6 +1758,7 @@ public:
pair<uint32_t,uint32_t> dimensions(bool includeBasic);
uint32_t arrayUnpackedElements(); // 1, or total multiplication of all dimensions
static int uniqueNumInc() { return ++s_uniqueNum; }
const char* charIQWN() const { return (isString() ? "N" : isWide() ? "W" : isQuad() ? "Q" : "I"); }
};
class AstNodeClassDType : public AstNodeDType {
@@ -1714,19 +1767,23 @@ private:
typedef map<string,AstMemberDType*> MemberNameMap;
// MEMBERS
bool m_packed;
bool m_isFourstate;
MemberNameMap m_members;
public:
AstNodeClassDType(FileLine* fl, AstNumeric numericUnpack)
: AstNodeDType(fl) {
// AstNumeric::NOSIGN overloaded to indicate not packed
m_packed = (numericUnpack != AstNumeric::NOSIGN);
m_isFourstate = false; // V3Width computes
numeric(numericUnpack.isSigned() ? AstNumeric::SIGNED : AstNumeric::UNSIGNED);
}
ASTNODE_BASE_FUNCS(NodeClassDType)
virtual const char* broken() const;
virtual void dump(ostream& str);
// For basicp() we reuse the size to indicate a "fake" basic type of same size
virtual AstBasicDType* basicp() const { return findLogicDType(width(),width(),numeric())->castBasicDType(); }
virtual AstBasicDType* basicp() const {
return (isFourstate() ? findLogicDType(width(),width(),numeric())->castBasicDType()
: findBitDType(width(),width(),numeric())->castBasicDType()); }
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
@@ -1740,6 +1797,8 @@ public:
void addMembersp(AstNode* nodep) { addNOp1p(nodep); }
bool packed() const { return m_packed; }
bool packedUnsup() const { return true; } // packed() but as don't support unpacked, presently all structs
void isFourstate(bool flag) { m_isFourstate = flag; }
virtual bool isFourstate() const { return m_isFourstate; }
void clearCache() { m_members.clear(); }
void repairMemberCache();
AstMemberDType* findMember(const string& name) const {
@@ -1770,24 +1829,24 @@ public:
virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) {
m_refDTypep = m_refDTypep->clonep();
}}
virtual bool same(AstNode* samep) const {
AstNodeArrayDType* sp = samep->castNodeArrayDType();
return (msb()==sp->msb()
&& subDTypep()==sp->subDTypep()
&& rangenp()->sameTree(sp->rangenp())); } // HashedDT doesn't recurse, so need to check children
virtual bool same(const AstNode* samep) const {
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep);
return (msb()==asamep->msb()
&& subDTypep()==asamep->subDTypep()
&& rangenp()->sameTree(asamep->rangenp())); } // HashedDT doesn't recurse, so need to check children
virtual bool similarDType(AstNodeDType* samep) const {
AstNodeArrayDType* sp = samep->castNodeArrayDType();
return (sp
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep);
return (asamep
&& type() == samep->type()
&& msb() == sp->msb()
&& rangenp()->sameTree(sp->rangenp())
&& subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp()));
&& msb() == asamep->msb()
&& rangenp()->sameTree(asamep->rangenp())
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
}
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(msb()),V3Hash(lsb())); }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); }
virtual AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); }
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; }
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
@@ -1838,21 +1897,24 @@ class AstNodeFTask : public AstNode {
private:
string m_name; // Name of task
string m_cname; // Name of task if DPI import
uint64_t m_dpiOpenParent; // DPI import open array, if !=0, how many callees
bool m_taskPublic:1; // Public task
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
bool m_prototype:1; // Just a prototype
bool m_dpiExport:1; // DPI exported
bool m_dpiImport:1; // DPI imported
bool m_dpiContext:1; // DPI import context
bool m_dpiOpenChild:1; // DPI import open array child wrapper
bool m_dpiTask:1; // DPI import task (vs. void function)
bool m_pure:1; // DPI import pure
public:
AstNodeFTask(FileLine* fileline, const string& name, AstNode* stmtsp)
: AstNode(fileline)
, m_name(name), m_taskPublic(false)
, m_name(name)
, m_dpiOpenParent(0), m_taskPublic(false)
, m_attrIsolateAssign(false), m_prototype(false)
, m_dpiExport(false), m_dpiImport(false), m_dpiContext(false)
, m_dpiTask(false), m_pure(false) {
, m_dpiOpenChild(false), m_dpiTask(false), m_pure(false) {
addNOp3p(stmtsp);
cname(name); // Might be overridden by dpi import/export
}
@@ -1874,23 +1936,29 @@ public:
void addStmtsp(AstNode* nodep) { addNOp3p(nodep); }
// op4 = scope name
AstScopeName* scopeNamep() const { return op4p()->castScopeName(); }
void scopeNamep(AstNode* nodep) { setNOp4p(nodep); }
void taskPublic(bool flag) { m_taskPublic=flag; }
bool taskPublic() const { return m_taskPublic; }
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
void prototype(bool flag) { m_prototype = flag; }
bool prototype() const { return m_prototype; }
void dpiExport(bool flag) { m_dpiExport = flag; }
bool dpiExport() const { return m_dpiExport; }
void dpiImport(bool flag) { m_dpiImport = flag; }
bool dpiImport() const { return m_dpiImport; }
void dpiContext(bool flag) { m_dpiContext = flag; }
bool dpiContext() const { return m_dpiContext; }
void dpiTask(bool flag) { m_dpiTask = flag; }
bool dpiTask() const { return m_dpiTask; }
void pure(bool flag) { m_pure = flag; }
bool pure() const { return m_pure; }
// MORE ACCESSORS
void dpiOpenParentInc() { ++m_dpiOpenParent; }
void dpiOpenParentClear() { m_dpiOpenParent=0; }
uint64_t dpiOpenParent() const { return m_dpiOpenParent; }
void scopeNamep(AstNode* nodep) { setNOp4p(nodep); }
void taskPublic(bool flag) { m_taskPublic=flag; }
bool taskPublic() const { return m_taskPublic; }
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
void prototype(bool flag) { m_prototype = flag; }
bool prototype() const { return m_prototype; }
void dpiExport(bool flag) { m_dpiExport = flag; }
bool dpiExport() const { return m_dpiExport; }
void dpiImport(bool flag) { m_dpiImport = flag; }
bool dpiImport() const { return m_dpiImport; }
void dpiContext(bool flag) { m_dpiContext = flag; }
bool dpiContext() const { return m_dpiContext; }
void dpiOpenChild(bool flag) { m_dpiOpenChild = flag; }
bool dpiOpenChild() const { return m_dpiOpenChild; }
void dpiTask(bool flag) { m_dpiTask = flag; }
bool dpiTask() const { return m_dpiTask; }
void pure(bool flag) { m_pure = flag; }
bool pure() const { return m_pure; }
};
class AstNodeFTaskRef : public AstNode {
@@ -1898,7 +1966,7 @@ class AstNodeFTaskRef : public AstNode {
private:
AstNodeFTask* m_taskp; // [AfterLink] Pointer to task referenced
string m_name; // Name of variable
string m_dotted; // Dotted part of scope to task or ""
string m_dotted; // Dotted part of scope the name()ed task/func is under or ""
string m_inlinedDots; // Dotted hierarchy flattened out
AstPackage* m_packagep; // Package hierarchy
public:
@@ -1952,6 +2020,8 @@ private:
bool m_inLibrary:1; // From a library, no error if not used, never top level
bool m_dead:1; // LinkDot believes is dead; will remove in Dead visitors
bool m_internal:1; // Internally created
bool m_recursive:1; // Recursive module
bool m_recursiveClone:1; // If recursive, what module it clones, otherwise NULL
int m_level; // 1=top module, 2=cell off top module, ...
int m_varNum; // Incrementing variable number
int m_typeNum; // Incrementing implicit type number
@@ -1959,7 +2029,8 @@ public:
AstNodeModule(FileLine* fl, const string& name)
: AstNode (fl)
,m_name(name), m_origName(name)
,m_modPublic(false), m_modTrace(false), m_inLibrary(false), m_dead(false), m_internal(false)
,m_modPublic(false), m_modTrace(false), m_inLibrary(false), m_dead(false)
,m_internal(false), m_recursive(false), m_recursiveClone(false)
,m_level(0), m_varNum(0), m_typeNum(0) { }
ASTNODE_BASE_FUNCS(NodeModule)
virtual void dump(ostream& str);
@@ -1989,6 +2060,17 @@ public:
bool dead() const { return m_dead; }
void internal(bool flag) { m_internal = flag; }
bool internal() const { return m_internal; }
void recursive(bool flag) { m_recursive = flag; }
bool recursive() const { return m_recursive; }
void recursiveClone(bool flag) { m_recursiveClone = flag; }
bool recursiveClone() const { return m_recursiveClone; }
};
class AstNodeRange : public AstNode {
// A range, sized or unsized
public:
explicit AstNodeRange(FileLine* fl) : AstNode (fl) { }
ASTNODE_BASE_FUNCS(NodeRange)
};
//######################################################################
@@ -2004,11 +2086,16 @@ public:
inline int AstNode::width() const { return dtypep() ? dtypep()->width() : 0; }
inline int AstNode::widthMin() const { return dtypep() ? dtypep()->widthMin() : 0; }
inline bool AstNode::width1() const { return dtypep() && dtypep()->width()==1; } // V3Const uses to know it can optimize
inline int AstNode::widthInstrs() const { return (!dtypep() ? 1 : (dtypep()->isWide() ? dtypep()->widthWords() : 1)); }
inline bool AstNode::isDouble() const { return dtypep() && dtypep()->castBasicDType() && dtypep()->castBasicDType()->isDouble(); }
inline bool AstNode::isString() const { return dtypep() && dtypep()->basicp() && dtypep()->basicp()->isString(); }
inline bool AstNode::isSigned() const { return dtypep() && dtypep()->isSigned(); }
inline bool AstNode::width1() const { // V3Const uses to know it can optimize
return dtypep() && dtypep()->width()==1; }
inline int AstNode::widthInstrs() const {
return (!dtypep() ? 1 : (dtypep()->isWide() ? dtypep()->widthWords() : 1)); }
inline bool AstNode::isDouble() const {
return dtypep() && dtypep()->castBasicDType() && dtypep()->castBasicDType()->isDouble(); }
inline bool AstNode::isString() const {
return dtypep() && dtypep()->basicp() && dtypep()->basicp()->isString(); }
inline bool AstNode::isSigned() const {
return dtypep() && dtypep()->isSigned(); }
inline bool AstNode::isZero() { return (this->castConst() && this->castConst()->num().isEqZero()); }
inline bool AstNode::isNeqZero() { return (this->castConst() && this->castConst()->num().isNeqZero()); }
@@ -2020,6 +2107,8 @@ inline bool AstNode::sameGateTree(AstNode* node2p) { return sameTreeIter(this, n
inline void AstNodeVarRef::init() { if (m_varp) dtypep(m_varp->dtypep()); }
inline bool AstNodeDType::isFourstate() const { return basicp()->isFourstate(); }
inline void AstNodeArrayDType::rangep(AstRange* nodep) { setOp2p(nodep); }
inline int AstNodeArrayDType::msb() const { return rangep()->msbConst(); }
inline int AstNodeArrayDType::lsb() const { return rangep()->lsbConst(); }
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
+96 -20
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -26,6 +26,7 @@
#include <iomanip>
#include <vector>
#include <algorithm>
#include VL_INCLUDE_UNORDERED_SET
#include "V3Ast.h"
#include "V3File.h"
@@ -63,13 +64,14 @@ int AstNodeSel::bitConst() const {
void AstNodeClassDType::repairMemberCache() {
clearCache();
for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
if (m_members.find(itemp->name())!=m_members.end()) { itemp->v3error("Duplicate declaration of member name: "<<itemp->prettyName()); }
if (m_members.find(itemp->name())!=m_members.end()) {
itemp->v3error("Duplicate declaration of member name: "<<itemp->prettyName()); }
else m_members.insert(make_pair(itemp->name(), itemp));
}
}
const char* AstNodeClassDType::broken() const {
set<AstMemberDType*> exists;
vl_unordered_set<AstMemberDType*> exists;
for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
exists.insert(itemp);
}
@@ -238,11 +240,20 @@ string AstVar::vlArgType(bool named, bool forReturn, bool forFunc) const {
} else if (isWide()) {
arg += "WData"; // []'s added later
}
if (isWide() && !strtype) {
arg += " (& "+name();
arg += ")["+cvtToStr(widthWords())+"]";
if (isDpiOpenArray() || (isWide() && !strtype)) {
arg += " (& "+name()+")";
for (AstNodeDType* dtp=dtypep(); dtp; ) {
dtp = dtp->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstUnpackArrayDType* adtypep = dtp->castUnpackArrayDType()) {
arg += "["+cvtToStr(adtypep->declRange().elements())+"]";
dtp = adtypep->subDTypep();
} else break;
}
if (isWide() && !strtype) {
arg += "["+cvtToStr(widthWords())+"]";
}
} else {
if (forFunc && (isOutput() || (strtype && isInput()))) arg += "&";
if (forFunc && (isOutput() || (strtype && isInput()))) arg += "&";
if (named) arg += " "+name();
}
return arg;
@@ -274,15 +285,48 @@ string AstVar::vlEnumType() const {
}
string AstVar::vlEnumDir() const {
string out;
if (isInout()) {
return "VLVD_INOUT";
out = "VLVD_INOUT";
} else if (isInOnly()) {
return "VLVD_IN";
out = "VLVD_IN";
} else if (isOutOnly()) {
return "VLVD_OUT";
out = "VLVD_OUT";
} else {
return "VLVD_NODIR";
out = "VLVD_NODIR";
}
//
if (isSigUserRWPublic()) out += "|VLVF_PUB_RW";
else if (isSigUserRdPublic()) out += "|VLVF_PUB_RD";
//
if (AstBasicDType* bdtypep = basicp()) {
if (bdtypep->keyword().isDpiCLayout()) out += "|VLVF_DPI_CLAY";
}
return out;
}
string AstVar::vlPropInit() const {
string out;
out = vlEnumType(); // VLVT_UINT32 etc
out += ", "+vlEnumDir(); // VLVD_IN etc
if (AstBasicDType* bdtypep = basicp()) {
out += ", VerilatedVarProps::Packed()";
out += ", "+cvtToStr(bdtypep->left())+", "+cvtToStr(bdtypep->right());
}
bool first = true;
for (AstNodeDType* dtp=dtypep(); dtp; ) {
dtp = dtp->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstNodeArrayDType* adtypep = dtp->castNodeArrayDType()) {
if (first) {
out += ", VerilatedVarProps::Unpacked()";
first = false;
}
out += ", "+cvtToStr(adtypep->declRange().left())+", "+cvtToStr(adtypep->declRange().right());
dtp = adtypep->subDTypep();
}
else break; // AstBasicDType - nothing below
}
return out;
}
string AstVar::cPubArgType(bool named, bool forReturn) const {
@@ -312,8 +356,11 @@ string AstVar::cPubArgType(bool named, bool forReturn) const {
string AstVar::dpiArgType(bool named, bool forReturn) const {
if (forReturn) named=false;
string arg;
if (!basicp()) arg = "UNKNOWN";
if (basicp()->isBitLogic()) {
if (isDpiOpenArray()) {
arg = "const svOpenArrayHandle";
} else if (!basicp()) {
arg = "UNKNOWN";
} else if (basicp()->keyword().isDpiBitVal()) {
if (widthMin() == 1) {
arg = "unsigned char";
if (!forReturn && isOutput()) arg += "*";
@@ -326,6 +373,19 @@ string AstVar::dpiArgType(bool named, bool forReturn) const {
arg = "svBitVecVal*";
}
}
} else if (basicp()->keyword().isDpiLogicVal()) {
if (widthMin() == 1) {
arg = "unsigned char";
if (!forReturn && isOutput()) arg += "*";
} else {
if (forReturn) {
arg = "svLogicVecVal";
} else if (isInOnly()) {
arg = "const svLogicVecVal*";
} else {
arg = "svLogicVecVal*";
}
}
} else {
arg = basicp()->keyword().dpiType();
if (basicp()->keyword().isDpiUnsignable() && !basicp()->isSigned()) {
@@ -548,28 +608,28 @@ string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
return out;
}
bool AstSenTree::hasClocked() {
bool AstSenTree::hasClocked() const {
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
if (senp->isClocked()) return true;
}
return false;
}
bool AstSenTree::hasSettle() {
bool AstSenTree::hasSettle() const {
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
if (senp->isSettle()) return true;
}
return false;
}
bool AstSenTree::hasInitial() {
bool AstSenTree::hasInitial() const {
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
if (senp->isInitial()) return true;
}
return false;
}
bool AstSenTree::hasCombo() {
bool AstSenTree::hasCombo() const {
if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
if (senp->isCombo()) return true;
@@ -778,6 +838,7 @@ void AstCCast::dump(ostream& str) {
}
void AstCell::dump(ostream& str) {
this->AstNode::dump(str);
if (recursive()) str<<" [RECURSIVE]";
if (modp()) { str<<" -> "; modp()->dump(str); }
else { str<<" ->UNLINKED:"<<modName(); }
}
@@ -849,6 +910,7 @@ void AstRefDType::dump(ostream& str) {
void AstNodeClassDType::dump(ostream& str) {
this->AstNode::dump(str);
if (packed()) str<<" [PACKED]";
if (isFourstate()) str<<" [4STATE]";
}
void AstNodeDType::dump(ostream& str) {
this->AstNode::dump(str);
@@ -886,6 +948,8 @@ void AstNodeModule::dump(ostream& str) {
if (modPublic()) str<<" [P]";
if (inLibrary()) str<<" [LIB]";
if (dead()) str<<" [DEAD]";
if (recursiveClone()) str<<" [RECURSIVE-CLONE]";
else if (recursive()) str<<" [RECURSIVE]";
}
void AstPackageExport::dump(ostream& str) {
this->AstNode::dump(str);
@@ -902,6 +966,12 @@ void AstSel::dump(ostream& str) {
if (declElWidth()!=1) str<<"/"<<declElWidth();
}
}
void AstSliceSel::dump(ostream& str) {
this->AstNode::dump(str);
if (declRange().ranged()) {
str<<" decl"<<declRange();
}
}
void AstTypeTable::dump(ostream& str) {
this->AstNode::dump(str);
for (int i=0; i<(int)(AstBasicDTypeKwd::_ENUM_MAX); ++i) {
@@ -939,7 +1009,10 @@ void AstTypeTable::dump(ostream& str) {
}
// Note get newline from caller too.
}
void AstUnsizedArrayDType::dumpSmall(ostream& str) {
this->AstNodeDType::dumpSmall(str);
str<<"[]";
}
void AstVarScope::dump(ostream& str) {
this->AstNode::dump(str);
if (isCircular()) str<<" [CIRC]";
@@ -951,7 +1024,7 @@ void AstVarXRef::dump(ostream& str) {
if (packagep()) { str<<" pkg="<<(void*)packagep(); }
if (lvalue()) str<<" [LV] => ";
else str<<" [RV] <- ";
str<<dotted()<<". - ";
str<<".="<<dotted()<<" ";
if (inlinedDots()!="") str<<" inline.="<<inlinedDots()<<" - ";
if (varScopep()) { varScopep()->dump(str); }
else if (varp()) { varp()->dump(str); }
@@ -986,6 +1059,7 @@ void AstVar::dump(ostream& str) {
if (attrFileDescr()) str<<" [aFD]";
if (isFuncReturn()) str<<" [FUNCRTN]";
else if (isFuncLocal()) str<<" [FUNC]";
if (isDpiOpenArray()) str<<" [DPIOPENA]";
if (!attrClocker().unknown()) str<<" ["<<attrClocker().ascii()<<"] ";
str<<" "<<varType();
}
@@ -1021,7 +1095,7 @@ void AstNodeFTaskRef::dump(ostream& str) {
this->AstNode::dump(str);
if (packagep()) { str<<" pkg="<<(void*)packagep(); }
str<<" -> ";
if (dotted()!="") { str<<dotted()<<". - "; }
if (dotted()!="") { str<<".="<<dotted()<<" "; }
if (taskp()) { taskp()->dump(str); }
else { str<<"UNLINKED"; }
}
@@ -1031,6 +1105,8 @@ void AstNodeFTask::dump(ostream& str) {
if (prototype()) str<<" [PROTOTYPE]";
if (dpiImport()) str<<" [DPII]";
if (dpiExport()) str<<" [DPIX]";
if (dpiOpenChild()) str<<" [DPIOPENCHILD]";
if (dpiOpenParent()) str<<" [DPIOPENPARENT]";
if ((dpiImport() || dpiExport()) && cname()!=name()) str<<" [c="<<cname()<<"]";
}
void AstBegin::dump(ostream& str) {
+566 -234
View File
File diff suppressed because it is too large Load Diff
+8 -6
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -291,10 +291,12 @@ public:
void V3Begin::debeginAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
BeginState state;
{ BeginVisitor bvisitor (nodep,&state); }
if (state.anyFuncInBegin()) {
BeginRelinkVisitor brvisitor (nodep,&state);
}
{
BeginState state;
{ BeginVisitor bvisitor (nodep,&state); }
if (state.anyFuncInBegin()) {
BeginRelinkVisitor brvisitor (nodep,&state);
}
} // Destruct before checking
V3Global::dumpCheckGlobalTree("begin", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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,7 +29,7 @@
class V3Branch {
public:
// CREATORS
// CONSTRUCTORS
static void branchAll(AstNetlist* rootp);
};
+7 -4
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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 @@ class BrokenTable : public AstNVisitor {
private:
// MEMBERS
// For each node, we keep if it exists or not.
typedef VL_UNORDERED_MAP<const AstNode*,int> NodeMap; // Performance matters (when --debug)
typedef vl_unordered_map<const AstNode*,int> NodeMap; // Performance matters (when --debug)
static NodeMap s_nodes; // Set of all nodes that exist
// BITMASK
enum { FLAG_ALLOCATED = 0x01 }; // new() and not delete()ed
@@ -224,8 +224,11 @@ private:
nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo): "<<whyp);
}
if (nodep->dtypep()) {
if (!nodep->dtypep()->brokeExists()) { nodep->v3fatalSrc("Broken link in node->dtypep() to "<<(void*)nodep->dtypep()); }
else if (!nodep->dtypep()->castNodeDType()) { nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "<<(void*)nodep->dtypep()); }
if (!nodep->dtypep()->brokeExists()) {
nodep->v3fatalSrc("Broken link in node->dtypep() to "<<(void*)nodep->dtypep());
} else if (!nodep->dtypep()->castNodeDType()) {
nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "<<(void*)nodep->dtypep());
}
}
if (v3Global.assertDTypesResolved()) {
if (nodep->hasDType()) {
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
+49 -5
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -23,6 +23,8 @@
// for all AstCoverDecl, move the declaration into a _configure_coverage AstCFunc.
// For each variable that needs reset, add a AstCReset node.
//
// For primary inputs, add _eval_debug_assertions.
//
// This transformation honors outputSplitCFuncs.
//*************************************************************************
#include "config_build.h"
@@ -75,7 +77,8 @@ public:
m_numStmts += 1;
}
V3CCtorsVisitor(AstNodeModule* nodep, string basename, string argsp="", string callargsp="",
V3CCtorsVisitor(AstNodeModule* nodep, const string& basename,
const string& argsp="", const string& callargsp="",
const string& stmt="") {
m_basename = basename;
m_argsp = argsp;
@@ -96,27 +99,68 @@ public:
}
~V3CCtorsVisitor() {}
private:
explicit V3CCtorsVisitor(const V3CCtorsVisitor&); ///< N/A, no copy constructor
VL_UNCOPYABLE(V3CCtorsVisitor);
};
//######################################################################
void V3CCtors::evalAsserts() {
AstNodeModule* modp = v3Global.rootp()->modulesp(); // Top module
AstCFunc* funcp = new AstCFunc(modp->fileline(), "_eval_debug_assertions", NULL, "void");
funcp->declPrivate(true);
funcp->isStatic(false);
funcp->slow(false);
funcp->ifdef("VL_DEBUG");
modp->addStmtp(funcp);
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
if (AstVar* varp = np->castVar()) {
if (varp->isPrimaryIn() && !varp->isSc()) {
if (AstBasicDType* basicp = varp->dtypeSkipRefp()->castBasicDType()) {
int storedWidth = basicp->widthAlignBytes() * 8;
int lastWordWidth = varp->width() % storedWidth;
if (lastWordWidth != 0) {
// if (signal & CONST(upper_non_clean_mask)) { fail; }
AstNode* newp = new AstVarRef(varp->fileline(), varp, false);
if (varp->isWide()) {
newp = new AstWordSel(varp->fileline(), newp,
new AstConst(varp->fileline(), varp->widthWords()-1));
}
uint64_t value = VL_MASK_Q(storedWidth) & ~VL_MASK_Q(lastWordWidth);
V3Number num (varp->fileline(), storedWidth, value);
newp = new AstAnd(varp->fileline(), newp,
new AstConst(varp->fileline(), num));
AstNodeIf* ifp = new AstIf(varp->fileline(), newp,
new AstCStmt(varp->fileline(),
"Verilated::overWidthError(\""+varp->prettyName()+"\");"));
ifp->branchPred(AstBranchPred::BP_UNLIKELY);
newp = ifp;
funcp->addStmtsp(newp);
}
}
}
}
}
}
void V3CCtors::cctorsAll() {
UINFO(2,__FUNCTION__<<": "<<endl);
evalAsserts();
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castNodeModule()) {
// Process each module in turn
{
V3CCtorsVisitor var_reset (modp, "_ctor_var_reset");
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
if (AstVar* varp = np->castVar()) {
var_reset.add(new AstCReset(varp->fileline(), new AstVarRef(varp->fileline(), varp, true)));
if (!varp->isIfaceParent() && !varp->isIfaceRef()) {
var_reset.add(new AstCReset(varp->fileline(), new AstVarRef(varp->fileline(), varp, true)));
}
}
}
}
if (v3Global.opt.coverage()) {
V3CCtorsVisitor configure_coverage
(modp, "_configure_coverage", EmitCBaseVisitor::symClassVar()+ ", bool first", "vlSymsp, first",
"if (0 && vlSymsp && first) {} // Prevent unused\n");
"if (0 && vlSymsp && first) {} // Prevent unused\n");
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
if (AstCoverDecl* coverp = np->castCoverDecl()) {
AstNode* backp = coverp->backp();
+3 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -30,6 +30,8 @@
class V3CCtors {
public:
static void cctorsAll();
private:
static void evalAsserts();
};
+9 -7
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -166,7 +166,7 @@ private:
}
UINFO(8,"Simple case statement: "<<nodep<<endl);
// Zero list of items for each value
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) m_valueItem[i] = NULL;
for (uint32_t i=0; i<(1UL<<m_caseWidth); ++i) m_valueItem[i] = NULL;
// Now pick up the values for each assignment
// We can cheat and use uint32_t's because we only support narrow case's
bool bitched = false;
@@ -184,7 +184,7 @@ private:
V3Number numval (itemp->fileline(), iconstp->width());
numval.opBitsOne(iconstp->num());
uint32_t val = numval.toUInt();
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
for (uint32_t i=0; i<(1UL<<m_caseWidth); ++i) {
if ((i & mask) == val) {
if (!m_valueItem[i]) {
m_valueItem[i] = itemp;
@@ -199,12 +199,12 @@ private:
}
// Defaults were moved to last in the caseitem list by V3LinkDot
if (itemp->isDefault()) { // Case statement's default... Fill the table
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
for (uint32_t i=0; i<(1UL<<m_caseWidth); ++i) {
if (!m_valueItem[i]) m_valueItem[i] = itemp;
}
}
}
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
for (uint32_t i=0; i<(1UL<<m_caseWidth); ++i) {
if (!m_valueItem[i]) {
nodep->v3warn(CASEINCOMPLETE,"Case values incompletely covered (example pattern 0x"<<hex<<i<<")");
m_caseNoOverlapsAllCovered = false;
@@ -278,7 +278,7 @@ private:
AstNode* cexprp = nodep->exprp()->unlinkFrBack();
if (debug()>=9) {
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
for (uint32_t i=0; i<(1UL<<m_caseWidth); ++i) {
if (AstNode* itemp = m_valueItem[i]) {
UINFO(9,"Value "<<hex<<i<<" "<<itemp<<endl);
}
@@ -488,7 +488,9 @@ public:
void V3Case::caseAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CaseVisitor visitor (nodep);
{
CaseVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("case", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Case::caseLint(AstNodeCase* nodep) {
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
+4 -2
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2004-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2018 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.
@@ -187,6 +187,8 @@ public:
void V3Cast::castAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CastVisitor visitor (nodep);
{
CastVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("cast", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2004-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2018 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.
+7 -7
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -76,7 +76,7 @@ public:
, m_srcDomainSet(false), m_dstDomainSet(false)
, m_asyncPath(false) {}
virtual ~CdcEitherVertex() {}
// Accessors
// ACCESSORS
AstScope* scopep() const { return m_scopep; }
AstNode* nodep() const { return m_nodep; }
AstSenTree* srcDomainp() const { return m_srcDomainp; }
@@ -99,7 +99,7 @@ public:
CdcVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
: CdcEitherVertex(graphp, scopep, varScp), m_varScp(varScp), m_cntAsyncRst(0), m_fromFlop(false) {}
virtual ~CdcVarVertex() {}
// Accessors
// ACCESSORS
AstVarScope* varScp() const { return m_varScp; }
virtual string name() const { return (cvtToStr((void*)m_varScp)+" "+varScp()->name()); }
virtual string dotColor() const { return fromFlop() ? "green" : cntAsyncRst() ? "red" : "blue"; }
@@ -118,7 +118,7 @@ public:
, m_hazard(false), m_isFlop(false)
{ srcDomainp(sensenodep); dstDomainp(sensenodep); }
virtual ~CdcLogicVertex() {}
// Accessors
// ACCESSORS
virtual string name() const { return (cvtToStr((void*)nodep())+"@"+scopep()->prettyName()); }
virtual string dotColor() const { return hazard() ? "black" : "yellow"; }
bool hazard() const { return m_hazard; }
@@ -496,8 +496,8 @@ private:
}
string filename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__cdc_edges.txt";
const VL_UNIQUE_PTR<ofstream> ofp (V3File::new_ofstream(filename));
if (ofp->fail()) v3fatalSrc("Can't write "<<filename);
const vl_unique_ptr<std::ofstream> ofp (V3File::new_ofstream(filename));
if (ofp->fail()) v3fatal("Can't write "<<filename);
*ofp<<"Edge Report for "<<v3Global.opt.prefix()<<endl;
deque<string> report; // Sort output by name
@@ -739,7 +739,7 @@ public:
// Make report of all signal names and what clock edges they have
string filename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__cdc.txt";
m_ofp = V3File::new_ofstream(filename);
if (m_ofp->fail()) v3fatalSrc("Can't write "<<filename);
if (m_ofp->fail()) v3fatal("Can't write "<<filename);
m_ofFilename = filename;
*m_ofp<<"CDC Report for "<<v3Global.opt.prefix()<<endl;
*m_ofp<<"Each dump below traces logic from inputs/source flops to destination flop(s).\n";
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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 -5
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -175,13 +175,17 @@ private:
newChangeDet();
} else {
if (debug()) nodep->dumpTree(cout,"-DETECTARRAY-class-");
m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<<m_vscp->varp()->prettyName());
m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable"
" (probably with UNOPTFLAT warning suppressed): "
<<m_vscp->varp()->prettyName());
}
}
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
if (debug()) nodep->dumpTree(cout,"-DETECTARRAY-general-");
m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<<m_vscp->varp()->prettyName());
m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable"
" (probably with UNOPTFLAT warning suppressed): "
<<m_vscp->varp()->prettyName());
}
public:
// CONSTUCTORS
@@ -300,7 +304,9 @@ public:
void V3Changed::changedAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ChangedState state;
ChangedVisitor visitor (nodep, &state);
{
ChangedState state;
ChangedVisitor visitor (nodep, &state);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("changed", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
+6 -3
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -90,7 +90,8 @@ private:
}
void computeCppWidth (AstNode* nodep) {
if (!nodep->user2() && nodep->hasDType()) {
if (nodep->castVar() || nodep->castNodeDType()) { // Don't want to change variable widths!
if (nodep->castVar() || nodep->castNodeDType() // Don't want to change variable widths!
|| nodep->dtypep()->skipRefp()->castUnpackArrayDType()) { // Or arrays
} else {
setCppWidth(nodep);
}
@@ -296,6 +297,8 @@ public:
void V3Clean::cleanAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CleanVisitor visitor (nodep);
{
CleanVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("clean", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
+7 -5
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2008-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2008-2018 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.
@@ -373,7 +373,7 @@ class GaterVisitor : public GaterBaseVisitor {
}
void scoreboardPli(AstNode* nodep) {
// Order all PLI statements with other PLI statements
// This insures $display's and such remain in proper order
// This ensures $display's and such remain in proper order
// We don't prevent splitting out other non-pli statements, however,
// because it is common to have $uasserts sprinkled about.
if (!m_pliVertexp) {
@@ -621,7 +621,7 @@ class GaterVisitor : public GaterBaseVisitor {
}
// Top level we could choose to make multiple gaters, or ORs under the gater
// Right now we'll put OR lower down and let other optimizations deal
if (nodep) nodep = new AstOr(eqnp->fileline(),nodep,eqnp);
if (nodep) nodep = new AstOr(nodep->fileline(), nodep, eqnp);
else nodep = eqnp;
//if (debug()>=9) nodep->dumpTree(cout," followExpr: ");
}
@@ -912,8 +912,10 @@ public:
void V3ClkGater::clkGaterAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
// While the gater does well at some modules, it seems to slow down many others
UINFO(5,"ClkGater is disabled due to performance issues\n");
{
// While the gater does well at some modules, it seems to slow down many others
UINFO(5,"ClkGater is disabled due to performance issues\n");
} // Destruct before checking
//GaterVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("clkgater", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
+16 -17
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -62,15 +62,12 @@ private:
AstNodeModule* m_modp; // Current module
AstTopScope* m_topScopep; // Current top scope
AstScope* m_scopep; // Current scope
AstActive* m_activep; // Current block
AstUntilStable* m_untilp; // Current until
AstCFunc* m_evalFuncp; // Top eval function we are creating
AstCFunc* m_initFuncp; // Top initial function we are creating
AstCFunc* m_finalFuncp; // Top final function we are creating
AstCFunc* m_settleFuncp; // Top settlement function we are creating
AstSenTree* m_lastSenp; // Last sensitivity match, so we can detect duplicates.
AstIf* m_lastIfp; // Last sensitivity if active to add more under
int m_stableNum; // Number of each untilstable
// METHODS
static int debug() {
@@ -252,7 +249,6 @@ private:
virtual void visit(AstNodeModule* nodep) {
//UINFO(4," MOD "<<nodep<<endl);
m_modp = nodep;
m_stableNum = 0;
nodep->iterateChildren(*this);
m_modp= NULL;
}
@@ -330,16 +326,13 @@ private:
pushDeletep(nodep);
}
void addToEvalLoop(AstNode* stmtsp) {
if (m_untilp) m_untilp->addBodysp(stmtsp); // In a until loop, add to body
else m_evalFuncp->addStmtsp(stmtsp); // else add to top level function
m_evalFuncp->addStmtsp(stmtsp); // add to top level function
}
void addToSettleLoop(AstNode* stmtsp) {
if (m_untilp) m_untilp->addBodysp(stmtsp); // In a until loop, add to body
else m_settleFuncp->addStmtsp(stmtsp); // else add to top level function
m_settleFuncp->addStmtsp(stmtsp); // add to top level function
}
void addToInitial(AstNode* stmtsp) {
if (m_untilp) m_untilp->addBodysp(stmtsp); // In a until loop, add to body
else m_initFuncp->addStmtsp(stmtsp); // else add to top level function
m_initFuncp->addStmtsp(stmtsp); // add to top level function
}
virtual void visit(AstActive* nodep) {
// Careful if adding variables here, ACTIVES can be under other ACTIVES
@@ -393,16 +386,20 @@ private:
public:
// CONSTUCTORS
explicit ClockVisitor(AstNetlist* nodep) {
m_modp=NULL; m_activep=NULL;
m_modp = NULL;
m_evalFuncp = NULL;
m_topScopep=NULL;
m_lastSenp=NULL;
m_initFuncp = NULL;
m_finalFuncp = NULL;
m_settleFuncp = NULL;
m_topScopep = NULL;
m_lastSenp = NULL;
m_lastIfp = NULL;
m_scopep = NULL;
m_stableNum = 0;
m_untilp = NULL;
//
nodep->accept(*this);
// Allow downstream modules to find _eval()
// easily without iterating through the tree.
nodep->evalp(m_evalFuncp);
}
virtual ~ClockVisitor() {}
};
@@ -412,6 +409,8 @@ public:
void V3Clock::clockAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ClockVisitor visitor (nodep);
{
ClockVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("clock", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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 -2
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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.
@@ -402,6 +402,7 @@ private:
UINFO(4," MOD "<<nodep<<endl);
m_modp = nodep;
m_modNFuncs = 0;
m_walkLast2p = NULL;
m_hashed.clear();
// Compute hash of all statement trees in the function
m_state = STATE_HASH;
@@ -473,6 +474,8 @@ public:
void V3Combine::combineAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CombineVisitor visitor (nodep);
{
CombineVisitor visitor (nodep);
} // Destruct before checking
V3Global::dumpCheckGlobalTree("combine", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2018 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