Compare commits

...
642 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
Wilson Snyder 132f61e900 Fix version 2017-10-14 16:20:17 -04:00
Wilson Snyder 0e9be8eea0 Version bump 2017-10-14 16:15:07 -04:00
Wilson Snyder 96f5f66c26 Move generated objects into bin/ to match --prefix installations 2017-10-14 16:09:02 -04:00
Wilson Snyder bbed4d50ab Fix clang and cppcheck warnings. 2017-10-14 14:51:57 -04:00
Wilson Snyder 4b7ee8267b Slicing: Fix off-by-one error earlier this version. 2017-10-14 14:04:15 -04:00
Wilson Snyder f6a745a4c2 Fix clang warnings. 2017-10-14 14:03:12 -04:00
Wilson Snyder a23a5505c4 configure: Check compiler works. 2017-10-14 13:20:58 -04:00
Wilson Snyder 21030f0a4f Internals: C++ style casts. No functional change intended. 2017-10-14 13:00:42 -04:00
Wilson Snyder d21824cbae Internals: Refactor verilated_vcd to move singleton into only .cpp. No functional change intended. 2017-10-14 13:00:25 -04:00
Wilson Snyder 124786ad1b Tests: Require newest compiler with thread test. 2017-10-14 12:57:42 -04:00
Wilson Snyder f81daac9c0 Fix MacOS portability, bug1231. 2017-10-14 12:56:16 -04:00
Wilson Snyder db8e8392fa Fix MacOS portability, bug1230. 2017-10-14 09:00:39 -04:00
Wilson Snyder 5bc2f87d3e Fix --skip-identical to handle closer timestamps looking at ctime. 2017-10-13 20:34:36 -04:00
Wilson Snyder de35c90847 Fix float-conversion warning, bug1229. 2017-10-11 19:01:37 -04:00
Wilson Snyder bc813fddcc tests: Fix examples when VERILATOR_ROOT not set 2017-10-11 19:01:02 -04:00
Wilson Snyder 13c91f5fce Internals: Refactor VerilatorSerialize to remove intermediate class. No functional change intended. 2017-10-11 18:55:31 -04:00
Wilson Snyder ac4690d74b Internals: Add const's. No functional change 2017-10-10 22:22:17 -04:00
Wilson Snyder a1a8f17617 Internals: Add const's. No functional change 2017-10-10 20:24:10 -04:00
Wilson Snyder 12be852a43 Fix ` expansion of defines, bug1227, bug1228. 2017-10-10 18:44:10 -04:00
Wilson Snyder 440fbef79b Untabify examples. No functional change. 2017-10-10 07:18:01 -04:00
Wilson Snyder e1c221a4d5 Tests: Add t_dist_tabs.pl 2017-10-09 22:08:22 -04:00
Wilson Snyder e1f1c82d4e Fix -E duplicating output, bug1226. 2017-10-09 21:08:50 -04:00
Wilson Snyder 3c1b82255e Change VL_THREADED to use C++11, and compute and test related GCC flags automatically 2017-10-07 21:29:57 -04:00
Wilson Snyder 6bd47b54df Tests: Add t_include_all. Fix GCC warning when DPI with VPI. 2017-10-07 21:21:12 -04:00
Wilson Snyder 3261a45ec1 configure: Add new _MY_CXX_CHECK_SET. No functional change. 2017-10-07 15:25:23 -04:00
Wilson Snyder 0ac116bb4e Internals: Favor C++ cast style. No functional change intended. 2017-10-07 15:01:19 -04:00
Wilson Snyder 221e4ff6fe Fix ` expansion of empty defines, bug1225. 2017-10-07 14:09:33 -04:00
Wilson Snyder fe80499f9c Internals: Move preproc DEV expansion when in ifndef, cleanup prep for bug1225. 2017-10-07 14:09:31 -04:00
Wilson Snyder d3d1f3ab60 Internals: Cleanup preproc in prep for bug1225. No functional change. 2017-10-07 14:09:17 -04:00
Chris Randall 264b888ef2 Add /*verilator tag*/ for XML extraction applications.
Signed-off-by: Wilson Snyder <[email protected]>
2017-10-06 07:33:52 -04:00
John Coiner ba270e09a4 Add --no-relative-cfuncs and related default optimization, bug1224.
Signed-off-by: Wilson Snyder <[email protected]>
2017-10-05 18:18:11 -04:00
Wilson Snyder 8281ee1520 Optimize arrayed if assignments 2017-10-04 22:10:44 -04:00
Wilson Snyder 75aab4e9d2 Fix conditional slices and add related optimizations. 2017-10-04 21:27:34 -04:00
Wilson Snyder b532a47e4a Internals: Prep for V3Slice rewrite. No functional change intended. 2017-10-04 21:15:19 -04:00
Wilson Snyder 77a3d683e3 Fix unnecessary Vdly variables, bug1224 partial. 2017-10-03 21:26:42 -04:00
Wilson Snyder c132d0e1fe Fix extra duplicate multiclk blocks when dtypes differ 2017-10-02 22:58:34 -04:00
Wilson Snyder 1a6348f113 Optimize display+display statements. 2017-10-02 20:25:10 -04:00
Wilson Snyder 89ac6ab594 Fix memory leak in VerilatedVcd dumps, bug1222 partial. 2017-10-02 18:49:00 -04:00
Wilson Snyder 3d1012b73b Allow disabling BLKLOOPINIT (Intentionally undocumented), part of last commit 2017-10-01 23:36:19 -04:00
Wilson Snyder c98ad79e68 Allow disabling BLKLOOPINIT (Intentionally undocumented) 2017-10-01 23:23:02 -04:00
Wilson Snyder 82460b0da3 Commentary 2017-10-01 23:06:16 -04:00
Wilson Snyder 0bdc57a14a Fix lost .tree debug file extensions in recent commit. 2017-10-01 22:17:37 -04:00
Wilson Snyder 33780a09df Add --x-initial option 2017-10-01 21:31:40 -04:00
John Coiner a9c9d5ca4b Fix over-aggressive inlining, bug1223.
Signed-off-by: Wilson Snyder <[email protected]>
2017-10-01 18:02:58 -04:00
Wilson Snyder ab07dbdb9d Fix over-aggressive inlining, bug1223. 2017-10-01 18:00:27 -04:00
Wilson Snyder 6dd6750985 Remove empty _configure_coverage in emitted code. 2017-10-01 16:44:53 -04:00
John Coiner 59aa0f43d5 Tests: In t_dist_whitespace, indicate what line has errant whitespace
Signed-off-by: Wilson Snyder <[email protected]>
2017-10-01 16:09:56 -04:00
Wilson Snyder 04ca6a4307 Fix compiler warning when WIDTH warning ignored on large compare. 2017-10-01 10:21:27 -04:00
John Coiner c7cbe11ba4 Fix Ubuntu 17.10 issues, bug1223 partial.
Signed-off-by: Wilson Snyder <[email protected]>
2017-09-30 13:33:14 -04:00
Wilson Snyder 4794093aba Replaced test_c/test_sc with new examples/ directory. 2017-09-23 21:18:07 -04:00
Wilson Snyder 46e300b2c5 Add --getenv option. 2017-09-23 18:03:39 -04:00
Wilson Snyder c693e52f6c Fix false unused warning on line coverage objects 2017-09-23 18:00:44 -04:00
Wilson Snyder 4e2ec09f9a Tests: The internal test_verilated test directory is moved to be part of test_regress. 2017-09-23 10:49:29 -04:00
Wilson Snyder cdbae456d5 devel release 2017-09-23 10:11:06 -04:00
Wilson Snyder 379177d2f4 Version bump 2017-09-23 10:04:52 -04:00
Wilson Snyder fb193d6172 Internals: Ignore gmon.out 2017-09-23 09:52:06 -04:00
Wilson Snyder 16234bb713 Tests: Call driver's run instead of private _run. 2017-09-23 08:50:39 -04:00
Wilson Snyder 3f14e649b5 Internals: Use singleton in place of global 2017-09-23 07:44:52 -04:00
Wilson Snyder c2e8062f84 Verilated headers no longer "use namespace std;" 2017-09-23 07:32:37 -04:00
Wilson Snyder 5d3fef21b0 Cleanup misc spacing and unneeded stuff in emitted headers. 2017-09-22 22:27:03 -04:00
Wilson Snyder b64e1b4a49 Fix inverted sync/async message. 2017-09-22 18:57:53 -04:00
Wilson Snyder 89f414b185 Less verbosity for IEEE warnings in earlier commit this rev. 2017-09-21 22:07:49 -04:00
Wilson Snyder 47e13cfdf4 Optimize concat/replicate+replicate. 2017-09-21 21:05:42 -04:00
Wilson Snyder 48d3ce46d8 Commenary 2017-09-21 18:39:23 -04:00
Wilson Snyder 89c8449ec0 Support package export, bug1217. 2017-09-20 21:04:59 -04:00
Xavier Delacour 331fcb633e Update .gitconfig 2017-09-20 07:57:09 -04:00
Wilson Snyder bffc2233a0 Commentary about IMPERFECTSCH. Add test. 2017-09-19 21:01:03 -04:00
Wilson Snyder 393b5d48b2 Better optimize Shift-And constructs. 2017-09-19 20:56:17 -04:00
Wilson Snyder 6006cdff2c Fix wide array indices causing compile error. 2017-09-19 20:04:45 -04:00
Wilson Snyder d6b10465f3 Improve more errors to note IEEE 2017-09-18 23:06:31 -04:00
Wilson Snyder b3cf5c4f5f Improve error to note common :: package errors 2017-09-18 22:54:54 -04:00
Wilson Snyder 3862f2f022 Note IEEE in 32 bit decimal oversized 2017-09-18 22:50:26 -04:00
Wilson Snyder 38ab22bf1d Simplify VL_CONST_W macro generation for faster compiles. 2017-09-18 21:36:18 -04:00
Wilson Snyder ce16f7689d Fix clang 3.8 warnings 2017-09-18 20:05:56 -04:00
Wilson Snyder b06a329466 Fix GCC 4.4 false warning 2017-09-18 08:30:04 -04:00
Wilson Snyder c5b24f3850 Internals: Remove dead code, bug1215. 2017-09-18 07:13:58 -04:00
Wilson Snyder 103b956581 Default to -O2 for Verilator itself, for 20%+ 2017-09-17 23:25:20 -04:00
Wilson Snyder 63361fc56e Add performance information to --stats file. 2017-09-17 22:52:57 -04:00
Wilson Snyder 1e9e334929 Internals: Name cleanup. No functional change. 2017-09-16 11:06:35 -04:00
Wilson Snyder f30d71b0c5 Internals: Better prefetching for ~5%. 2017-09-16 07:55:48 -04:00
Wilson Snyder fee4aba9ec Internals: Fix GCC constant warnings. 2017-09-15 18:26:09 -04:00
Wilson Snyder f1960273a0 Internals: Fix over-aggressive debug 2017-09-15 18:25:52 -04:00
Wilson Snyder 778564e63b Compling: Turn on -Wextra when using --enable-ccwarn 2017-09-14 23:28:02 -04:00
Wilson Snyder cf6a69da27 Internals: Fix some cast and fallthrough warnings. No functional change 2017-09-14 23:27:06 -04:00
Wilson Snyder 960b2ed023 Internals: Fix some shadow and other warnings. No functional change 2017-09-14 23:26:23 -04:00
Mike Popoloski 74420550e6 Fix .name connections on interfaces, bug1214.
Signed-off-by: Wilson Snyder <[email protected]>
2017-09-14 21:24:13 -04:00
Mike Popoloski cb5887b376 Support module port parameters without defaults, bug 1213.
Signed-off-by: Wilson Snyder <[email protected]>
2017-09-14 21:20:20 -04:00
Wilson Snyder 41b40157d8 Fix non-colon array of interface modports, bug1212. 2017-09-14 21:15:56 -04:00
Wilson Snyder b11b693c08 Fix constant function default parameters, bug1211. 2017-09-13 19:47:11 -04:00
Wilson Snyder 256eb4bba0 Support or/and/xor array intrinsic methods, bug1210. 2017-09-13 19:37:47 -04:00
Wilson Snyder 77804b4d38 Fix GCC noreturn compile error, bug1209. 2017-09-13 19:27:59 -04:00
Wilson Snyder 8c9ca7a1b3 Fix LITENDIAN warning on arrayed cells, bug1202. 2017-09-13 19:09:49 -04:00
Wilson Snyder 9d055f8c13 Fix ordering of arrayed cell wide connections, bug1202 partial. 2017-09-12 19:34:10 -04:00
Wilson Snyder 3dacd87dfb Fix enum ranges without colons, bug1204. 2017-09-12 18:53:57 -04:00
Wilson Snyder 691fbb0c42 Tests: Support newer VCS. 2017-09-12 18:42:58 -04:00
Wilson Snyder c28a6eef3b Fix whitespace issues, bug1203. 2017-09-11 19:18:58 -04:00
Wilson Snyder 17fed3fedd devel release 2017-09-07 21:15:48 -04:00
Wilson Snyder 1448cc56fc Version bump 2017-09-07 21:10:22 -04:00
Wilson Snyder 074689b5de SystemPerl mode (-sp-deprecated) has been removed. 2017-09-07 21:08:49 -04:00
Wilson Snyder 8dd612a0a0 Commentary, bug1198. 2017-09-06 20:45:21 -04:00
Wilson Snyder 22fdbba0b5 Update keywords for C++11 etc, msg2325 2017-09-02 21:01:50 -04:00
Wilson Snyder 39b787670b Update keywords for C++11 etc, msg2325 2017-09-02 20:59:03 -04:00
Wilson Snyder a221278c05 Commentary 2017-08-31 19:45:53 -04:00
Wilson Snyder 5f26b9ec66 Internals: Remove dead putAlign, bug1093. 2017-08-28 23:01:19 -04:00
Wilson Snyder 48778d0a77 devel release 2017-08-28 22:51:53 -04:00
Wilson Snyder 42d2cbad41 Version bump 2017-08-28 22:46:43 -04:00
Wilson Snyder cb82c42e35 Test for bug1191. 2017-08-28 22:41:38 -04:00
Wilson Snyder f13fb330ed Reenable -Wchar-subscripts and sort flag list 2017-08-14 20:15:24 -04:00
Wilson Snyder d4bae48ca2 Fix GCC7.1 warning on new alignment 2017-08-14 19:59:21 -04:00
Wilson Snyder 590ad964b1 Add assertion on bad formed lvalues, used to debug bug1187. 2017-08-13 18:08:44 -04:00
Wilson Snyder d4595df8a4 Fix internal error on unconnected inouts, bug1187. 2017-08-13 18:08:24 -04:00
Wilson Snyder 7b642bcbb4 Support packed struct DPI imports, bug1190. 2017-08-11 19:07:47 -04:00
Wilson Snyder ca26596695 Fix undefined VL_POW_WWI. 2017-07-12 20:08:32 -04:00
Wilson Snyder 88cf5e5d98 Fix realloc leak on out-of-memory 2017-07-12 18:54:27 -04:00
Wilson Snyder 13f790360d Fix compile error on unused VL_VALUEPLUSARGS_IW, bug1181. 2017-07-07 07:50:45 -04:00
Wilson Snyder 70daadf987 Fix cpp-check warnings; support XML format 2 2017-07-06 20:25:59 -04:00
Wilson Snyder 9d5004db1c Fix GCC 7 warnings. 2017-07-06 19:49:34 -04:00
Wilson Snyder ea82bfcced Fix GCC 6 warnings. 2017-07-06 19:07:23 -04:00
Wilson Snyder 00a502942e Fix valueplus exceeding array bounds. 2017-07-06 19:01:35 -04:00
Wilson Snyder 2031bc7fc4 Commentary 2017-07-05 19:06:22 -04:00
Wilson Snyder 3adb22e971 Support x in , 2017-07-05 18:51:06 -04:00
Wilson Snyder 331ea5116f devel release 2017-06-22 18:36:29 -04:00
Wilson Snyder 1da5a33f88 Version bump 2017-06-22 18:31:22 -04:00
Wilson Snyder 6c87724af8 Support set_time_unit/set_time_precision in C traces, msg2261. 2017-06-20 19:33:58 -04:00
Wilson Snyder c7a5ff5e82 Tests: Fix broken vgen test, commentary. 2017-06-20 19:10:18 -04:00
Wilson Snyder abf2fcf820 Fix .* on interface pins, bug1176. 2017-06-20 18:40:18 -04:00
Wilson Snyder 644c22b08f Fix extract of packed array with non-zero LSB, bug1172. 2017-06-06 20:06:23 -04:00
Wilson Snyder c54024a5e6 Fix constant shifts by more than 32-bit numbers, bug1174 continued. 2017-06-05 21:15:31 -04:00
Wilson Snyder 97093fdf81 Fix power operator on wide constants, bug761. 2017-06-05 20:30:01 -04:00
Wilson Snyder 50c4f60c68 Internals: Favor preincrement. No functional change. 2017-06-05 20:16:51 -04:00
Wilson Snyder f0fb3b78d1 Internals: New VL_ZERO_W for faster inline. Prefer WData for wide. No functional change intended. 2017-06-05 20:04:09 -04:00
Wilson Snyder 9b06178f35 Fix shifts by more than 32-bit numbers, bug1174. 2017-06-05 07:56:59 -04:00
Wilson Snyder a01c96140b devel release 2017-05-30 22:04:58 -04:00
Wilson Snyder 02530172e7 Version bump 2017-05-30 22:01:21 -04:00
Wilson Snyder 447d803800 Fix internal clang warnings. 2017-05-24 23:51:15 -04:00
Wilson Snyder 6b04901c4d Fix testplusargs false width warning, bug1165. 2017-05-19 07:20:41 -04:00
Wilson Snyder 7fb29621c3 Fix interface functions returning wrong parameters, bug996. 2017-05-18 22:49:17 -04:00
Wilson Snyder b032fce962 Support $value$plusargs with variables, bug1165. 2017-05-18 22:41:43 -04:00
Wilson Snyder ce879122bb Fix --assert with complex case statements, bug1164. 2017-05-17 20:15:40 -04:00
Todd Strader 2fa16708b7 Fix non-arrayed cells with interface arrays, bug1153.
Signed-off-by: Wilson Snyder <[email protected]>
2017-05-10 19:05:42 -04:00
Todd Strader 54bc8608e3 Add stack trace when can't optimize function, bug1158.
Signed-off-by: Wilson Snyder <[email protected]>
2017-05-09 18:54:15 -04:00
Todd Strader 706a7802cc Fix non-cutable ordering loops on clock arrays, bug1009.
Signed-off-by: Wilson Snyder <[email protected]>
2017-05-09 08:05:21 -04:00
Wilson Snyder 9dc01cf540 Support arrayed parameter overrides, bug1153. 2017-05-02 19:16:54 -04:00
Wilson Snyder 8943ad5966 internals: Remove extra newlines on v3fatalSrc. No functional change. 2017-04-28 20:09:27 -04:00
Wilson Snyder deb7a1c9c0 Fix non-arrayed cells with interface arrays, bug1153. 2017-04-28 20:03:38 -04:00
Wilson Snyder 96a5445d44 Support ports of array of reals, bug1154. 2017-04-28 06:10:14 -04:00
Wilson Snyder d693065afb Fix backwards array interface error message 2017-04-27 06:36:14 -04:00
Wilson Snyder bdeee35669 Add warning on mis-sized literal, bug1156. 2017-04-26 18:34:01 -04:00
Wilson Snyder 62b3deb90d Tests: Improve vams to attach wire. 2017-04-04 19:15:15 -04:00
Wilson Snyder 9df9ff59e0 Commentary 2017-04-03 20:02:19 -04:00
Wilson Snyder 23a3271c06 devel release 2017-04-02 08:49:31 -04:00
Wilson Snyder f4a5aa2e94 Version bump 2017-04-02 08:43:53 -04:00
Wilson Snyder bdd54eed1c Commentary 2017-04-02 08:39:33 -04:00
Wilson Snyder c6a20a72f2 Turn off parser debug in optimized build, msg2203 2017-03-31 17:46:15 -04:00
Wilson Snyder d7a54b3632 Fix nested structure parameter selects, bug1150. 2017-03-30 19:05:55 -04:00
Wilson Snyder be6a3d0f10 Fix wreal not handling continuous assign, bug1150. 2017-03-30 18:32:37 -04:00
Wilson Snyder e9125a3a22 Fix error on parameters with dotted references, bug1146. 2017-03-28 19:55:20 -04:00
Wilson Snyder c27a60658f Add error on duplicate pattern assignments, bug1145. 2017-03-23 18:15:03 -04:00
Wilson Snyder 8f2bc6e028 Patch to fix for bug1135. 2017-03-22 17:34:47 -04:00
Wilson Snyder a6b78cbbee Fix error on improperly widthed default function, bug984. 2017-03-21 19:27:42 -04:00
Wilson Snyder 182a7076fd Fix missing error on interface size mismatch, bug1143. 2017-03-21 19:19:28 -04:00
Wilson Snyder 17a9b22dce Fix cell ranges without colons. 2017-03-21 19:17:15 -04:00
Wilson Snyder f190d12802 Internals: Avoid coredump debugging bug1135. 2017-03-21 18:22:32 -04:00
Wilson Snyder b12dd526f9 Fix calling sformatf to display, and elab , bug1139. 2017-03-17 18:40:16 -04:00
Wilson Snyder 473d555dc1 Fix ugly interface-to-non-interface errors, bug1112. 2017-03-17 18:35:53 -04:00
Wilson Snyder fa9208ccdd Fix ugly interface-to-non-interface errors, bug1112. 2017-03-17 18:33:49 -04:00
Wilson Snyder 4aa088eb2f Fix realpath compile issue on MSVC++, bug1141. 2017-03-15 20:08:19 -04:00
Wilson Snyder 8f8147d646 Fix internal error on interface arrays, bug1135. 2017-03-15 20:03:53 -04:00
Wilson Snyder e637dd2390 Fix internal error on initializing parameter array, bug1131. 2017-03-06 07:20:30 -05:00
Wilson Snyder c90960fc88 Fix LDFLAGS and CFLAGS not preserving order, bug1130. 2017-02-13 18:11:40 -05:00
Wilson Snyder da86a1c9f2 Fix previous commit warning 2017-02-13 18:11:22 -05:00
Wilson Snyder 0adb789238 Add --relative-includes. 2017-02-09 18:33:18 -05:00
Wilson Snyder 15082a178b Add -FI option to force includes,msg2146. 2017-02-09 07:44:36 -05:00
Wilson Snyder 4a0db26c36 Commentary 2017-02-04 13:53:08 -05:00
Wilson Snyder ad3ea636d5 Fix 2009 localparam syntax, msg2139. 2017-01-26 22:41:32 -05:00
Wilson Snyder 6a238b0514 devel release 2017-01-26 22:41:05 -05:00
Wilson Snyder e6d7e7e329 Version bump 2017-01-15 12:13:13 -05:00
Wilson Snyder f942aba855 Support old-style (), bug467. 2017-01-09 19:19:21 -05:00
Wilson Snyder 2f34132275 Fix bad code when tracing array of structs, bug1122. 2017-01-06 18:44:37 -05:00
Wilson Snyder 663b2be065 Tests: bug1104, unsupported. 2016-12-21 21:00:40 -05:00
Wilson Snyder a1e4d676c3 Fix parsing sensitivity with &&, bug934. 2016-12-21 18:23:14 -05:00
Wilson Snyder 6f28d21207 With --bbox-unsup, suppress desassign and mixed edges, bug1120. 2016-12-21 17:43:19 -05:00
Wilson Snyder 9f115e056e Commentary 2016-12-21 17:21:44 -05:00
Wilson Snyder 8352ba4af4 Commentary, bug1116 2016-12-03 15:01:55 -05:00
Wilson Snyder 9b06310cbe Fix internal error on unique casez with --assert, bug1117. 2016-12-03 14:49:51 -05:00
Wilson Snyder 77fe33e57f Fix internal error on double-for loop unrolling, bug1044. 2016-11-29 20:40:58 -05:00
Wilson Snyder df58eb9bc7 Commentary 2016-11-27 16:37:51 -05:00
Wilson Snyder 2d0084308d Internals: Convert AstNUser to non-pointer to avoid NULL call. No functional change intended. 2016-11-27 09:40:12 -05:00
Wilson Snyder 7efa40966a Internals: Remove second argument to visitors. No functional change intended. 2016-11-27 08:11:38 -05:00
Wilson Snyder 6d644dc764 Internals: V3Width now iterates like others, replacing arg passing. No functional change intended. 2016-11-25 16:48:36 -05:00
Wilson Snyder b0de0b1176 devel release 2016-11-25 10:55:28 -05:00
Wilson Snyder c72d473e96 Version bump 2016-11-25 10:35:45 -05:00
Wilson Snyder c8a91bd46f Commentary 2016-11-18 21:42:06 -05:00
Wilson Snyder 498f19a6a1 Use VERILATOR_INCLUDE in generated files to allow relocation. 2016-11-18 21:13:56 -05:00
Wilson Snyder c7a2138ece Commentary 2016-11-18 20:31:41 -05:00
Wilson Snyder 4078902543 Compiling: Fix flexfix adding new warning back in flex 2.5.35 2016-11-18 19:40:39 -05:00
Wilson Snyder 9e38ed9a39 configure: Better prune unknwon gcc -Wno- flags. 2016-11-18 19:27:29 -05:00
Wilson Snyder 183cabc77d Internals: Have cloning return node's type to avoid casts. No functional change. 2016-11-08 21:16:22 -05:00
Wilson Snyder b582e481c6 Commentary in Makefile.in 2016-11-08 18:12:05 -05:00
Wilson Snyder ad39931e87 Internals: Cleanup uses of accept in V3Width. No functional change. 2016-11-07 19:14:45 -05:00
Wilson Snyder 1ae22e1365 Internals: Cleanup some casts. No functional change. 2016-11-06 11:39:09 -05:00
Wilson Snyder b748ddfe06 Fix flex 2.6.2 bug, bug1103. 2016-11-06 08:14:05 -05:00
Wilson Snyder e52f5f1b63 Internals: Remove extraneous castNode() calls. No functional change. 2016-11-05 10:06:43 -04:00
Wilson Snyder bda4b326ab Internals: Use mixed case for AstType enums. No functional change. 2016-11-05 09:47:56 -04:00
Wilson Snyder 70ddf32719 Fix error on referencing variable in parent, bug1099. 2016-11-05 08:37:18 -04:00
Stefan Wallentowitz 3edba7b662 Fix type parameters with low optimization, bug1101.
Signed-off-by: Wilson Snyder <[email protected]>
2016-11-04 22:58:21 -04:00
Wilson Snyder f74ef650ac Honor --output-split on coverage constructors, bug1098. 2016-10-23 14:27:57 -04:00
Wilson Snyder f093c3d78b Fix error on bad interface name, bug1097. 2016-10-22 08:05:27 -04:00
Wilson Snyder d933f33bdb devel release 2016-10-14 19:51:30 -04:00
Wilson Snyder 813d62005d Version bump 2016-10-14 19:42:18 -04:00
Wilson Snyder 411de9bddf Commentary. 2016-09-30 18:16:56 -04:00
Wilson Snyder bd28945374 Untabify 2016-09-30 18:14:42 -04:00
Wilson Snyder 1e4c3751e1 Support foreach, bug1078. 2016-09-19 22:00:13 -04:00
Wilson Snyder 5b6f47cd0f If VM_PARALLEL_BUILDS=1, use OPT_FAST and OPT_SLOW. 2016-09-19 19:31:09 -04:00
Wilson Snyder bec8c5bf4c Commentary 2016-09-19 17:55:43 -04:00
Johan Bjork 15495bb200 Improve Verilation performance on trace duplicates, msg2017.
Signed-off-by: Wilson Snyder <[email protected]>
2016-09-19 17:54:42 -04:00
Wilson Snyder 999f278971 Fix concats with wide width, bug1088 continued. 2016-09-16 18:54:28 -04:00
Wilson Snyder 7ca1d35a4e New test. 2016-09-16 18:15:32 -04:00
Wilson Snyder 2117fe414e Fix error on wide numbers that represent shifts, bug1088. 2016-09-14 20:27:20 -04:00
Wilson Snyder 7d8c51181d With --no-decoration also shrink output code indents. 2016-09-13 22:53:09 -04:00
Wilson Snyder c30211cb27 Add --no-decoration to remove output comments, msg2015. 2016-09-13 22:28:07 -04:00
Johan Bjork 901da118e5 Internals: Move prettyName invocation to after option checks in trace and coverage
Signed-off-by: Wilson Snyder <[email protected]>
2016-09-12 21:52:40 -04:00
Wilson Snyder f11757e43a Fix error on wide shift, msg2005. 2016-09-12 18:31:45 -04:00
Wilson Snyder 3f143317a6 Add error on DPI functions > 32 bits, msg1995. 2016-09-10 08:14:17 -04:00
Wilson Snyder 45d7312dfc Improve Verilation performance on internal strings, msg1975. 2016-09-08 22:04:14 -04:00
Wilson Snyder 26774eb045 Fix error on wide numbers that represent small msb/lsb, msg1991. 2016-09-08 21:30:35 -04:00
Wilson Snyder 6789d247e2 Fix SystemC compiles with VPI, bug1081. 2016-08-23 18:05:29 -04:00
Johan Bjork 462bc3d707 Clean up disabled tests for bugs already fixed.
Signed-off-by: Wilson Snyder <[email protected]>
2016-08-23 06:45:25 -04:00
Wilson Snyder e1755ea6a8 devel release 2016-07-30 10:18:52 -04:00
Wilson Snyder b4a7e4697e Version bump 2016-07-30 10:10:35 -04:00
Wilson Snyder cd61b1d045 Usage check. 2016-07-30 10:05:55 -04:00
Wilson Snyder 24dc36ba4c Fix comparison of unpacked arrays, bug1071. 2016-07-23 16:58:30 -04:00
Wilson Snyder e8e4f1777d Internals: Add cloneType method. Unused - for next checkin. 2016-07-23 16:54:36 -04:00
Wilson Snyder ae38a26af3 Internals: Cleanup some slice code. No functional change. 2016-07-21 23:07:22 -04:00
Wilson Snyder 8ee94dd7aa Tests: Smaller verilated test. 2016-07-21 23:03:54 -04:00
Wilson Snyder e741a29d36 Commentary 2016-07-13 22:51:40 -04:00
Wilson Snyder be1d275151 Fix Ubuntu 16.04 test failures. 2016-07-12 21:43:16 -04:00
David Horton 31c9e26e2e Fix compiler warning in GCC 6.
Signed-off-by: Wilson Snyder <[email protected]>
2016-07-09 04:09:34 -04:00
Wilson Snyder 20ed1ada03 Spelling fixes. 2016-07-09 03:31:22 -04:00
Wilson Snyder 891214fa72 Fix enum values of 11-16 bits wide using .next/.prev, bug1062. 2016-06-15 22:46:34 -04:00
Wilson Snyder e819e285e2 Fix false warnings on non-power-2 enums using .next/.prev. 2016-06-15 20:13:52 -04:00
Wilson Snyder 171c175e54 devel release 2016-05-18 21:15:33 -04:00
Wilson Snyder 675cbce8cb Version bump 2016-05-18 21:10:56 -04:00
Wilson Snyder 4f1398f773 Add commandArgsAdd, msg1890. 2016-05-16 22:04:21 -04:00
Wilson Snyder ae89e399a3 Fix to string, msg1890. 2016-05-16 21:57:49 -04:00
Wilson Snyder 2c9716c64c Try 2. Fix core dump on Arch Linux/GCC 6.1.1, bug1058. 2016-05-16 21:40:49 -04:00
Wilson Snyder bc58245abf Fix core dump on Arch Linux/GCC 6.1.1, bug1058. 2016-05-14 17:56:04 -04:00
Johan Bjork 8c4aa8517e Fix --output-split of constructors, bug1035.
Signed-off-by: Wilson Snyder <[email protected]>
2016-05-12 07:19:02 -04:00
Johan Bjork c0b7a54bb9 Fix removal of empty packages, modules and cells, bug1034.
Signed-off-by: Wilson Snyder <[email protected]>
2016-05-11 21:44:55 -04:00
Wilson Snyder 6b32bb635d Change --l2-name default to remove 'v' naming. 2016-05-07 14:10:33 -04:00
Wilson Snyder 691de22ae3 Add --l2-name option for controlling 'v' naming, bug1050. 2016-05-07 14:01:02 -04:00
Wilson Snyder e64b2d3372 Internals: user#inc now has optional increment value. 2016-05-06 22:26:15 -04:00
Johan Bjork e190af9d87 Avoid extra clean ANDs after CCalls.
Signed-off-by: Wilson Snyder <[email protected]>
2016-05-06 21:18:48 -04:00
Johan Bjork 8d14463b18 Fix emitting public enumerations.
Signed-off-by: Wilson Snyder <[email protected]>
2016-05-05 22:48:53 -04:00
Wilson Snyder 04977ef721 Internals: Show clocker in debug dumps. Part of bug1009. 2016-05-05 22:40:19 -04:00
Wilson Snyder d84e6875c5 Test case 2016-04-06 19:18:59 -04:00
Wilson Snyder 80678ae7bc Fix clang 3.8.0 warnings. 2016-03-31 22:26:49 -04:00
Stefan Wallentowitz 482bdab0e0 Support command-line -G/+pvalue param overrides, bug1045.
Signed-off-by: Wilson Snyder <[email protected]>
2016-03-24 19:14:15 -04:00
Stefan Wallentowitz b2623b9841 Internals: Add success parameter to parseDouble. No functional change intended.
Signed-off-by: Wilson Snyder <[email protected]>
2016-03-23 07:48:32 -04:00
Wilson Snyder 9ae40d64f0 Support parameter type, bug376. 2016-03-14 21:51:31 -04:00
Wilson Snyder cef097b7b7 Internals: Refactoring prep for parameter type branch. No functional change intended. 2016-03-12 20:54:52 -05:00
Wilson Snyder b840334ad2 devel release 2016-03-01 19:14:04 -05:00
Wilson Snyder acff683e8e Version bump 2016-03-01 19:12:14 -05:00
Stefan Wallentowitz c5332de86d Support SV strings to readmemh, bug1040.
Signed-off-by: Wilson Snyder <[email protected]>
2016-03-01 18:57:15 -05:00
Wilson Snyder 90ecf14a0a Fix pattern assignment width propagation, bug1037. 2016-02-21 23:00:21 -05:00
Wilson Snyder 4945282369 Fix slicing mix of big and little-endian, bug1033. 2016-02-09 22:16:12 -05:00
Wilson Snyder ca532d23f0 Suppress null compares to avoid compile errors until bug1030 fixed 2016-02-08 22:16:05 -05:00
Wilson Snyder a509b6a21c Internals: Fix compares to null, ongoing part of bug1030. No functional change intended. 2016-02-08 22:15:44 -05:00
Wilson Snyder 46229473cb Fix crash on very deep function trees, bug1028. 2016-02-04 20:47:55 -05:00
Johan Bjork 65be2448dc Fix elaboration-time display warnings, bug1032.
Signed-off-by: Wilson Snyder <[email protected]>
2016-02-04 18:38:59 -05:00
Johan Bjork be74806044 Fix read-after-free error detected by valgrind, bug1031.
Signed-off-by: Wilson Snyder <[email protected]>
2016-02-04 18:34:08 -05:00
Wilson Snyder b488666c1e Fix cppcheck 1.71 issues. No functional change intended. 2016-02-04 18:30:21 -05:00
Wilson Snyder d1acaea611 Internals: Fix compares to null, ongoing part of bug1030. No functional change intended. 2016-02-03 20:44:31 -05:00
Wilson Snyder db6e5ce7cf Internals: Misc code cleanups. No functional change. 2016-02-03 20:43:05 -05:00
Wilson Snyder d56179df17 Internals: Fix compares to null, part of bug1030. No functional change intended. 2016-02-02 21:02:00 -05:00
Wilson Snyder 850100c9c2 Fix compares to null, part of bug1030. 2016-02-02 19:35:44 -05:00
Wilson Snyder 0725999f0a flexfix: Match Verilog-perl fix for new gcc. 2016-02-02 19:32:17 -05:00
Johan Bjork cb2d8259f2 Fix stats and debug print, bug1029
Signed-off-by: Wilson Snyder <[email protected]>
2016-01-28 22:20:31 -05:00
Johan Bjork 61a1f3d817 Support inlining interfaces, bug1018.
Signed-off-by: Wilson Snyder <[email protected]>
2016-01-21 19:11:53 -05:00
Johan Bjork 63f111b7f3 Fix unrolling complicated for-loop bounds, bug677.
Signed-off-by: Wilson Snyder <[email protected]>
2016-01-21 19:00:19 -05:00
Wilson Snyder e061eb3003 Fix using short parameter names on negative params, bug1022. 2016-01-20 22:09:11 -05:00
Johan Bjork 29daa58222 Fix stats file containing multiple unroll entries, bug1020.
Signed-off-by: Wilson Snyder <[email protected]>
2016-01-06 20:53:48 -05:00
Johan Bjork 340cc02171 Avoid dynamic_cast for classes with no children, bug1021.
Signed-off-by: Wilson Snyder <[email protected]>
2016-01-06 20:47:44 -05:00
Wilson Snyder b738d1960a Copyright year update 2016-01-06 20:36:41 -05:00
Wilson Snyder 38f5b780d7 devel release 2016-01-06 20:33:25 -05:00
Wilson Snyder fa9dac29e8 Version bump 2015-12-19 10:26:14 -05:00
Wilson Snyder afc432042f Fix ternary operation with unpacked array, bug1017. 2015-12-18 18:02:25 -05:00
Wilson Snyder 21cb29baf0 Fix arrayed instances to unpacked of same size, bug1015. Fix slices of unpacked arrays with non-zero LSBs. 2015-12-15 22:37:49 -05:00
Wilson Snyder e8b5001cfe Fix model restore crash, bug1013. 2015-12-14 19:58:22 -05:00
Wilson Snyder 849c1e46a2 Fix constant propagation, bug1012. 2015-12-08 22:22:42 -05:00
Wilson Snyder ebad6cde36 Fix error instead of warning on large concat, msg1768. 2015-12-08 21:25:43 -05:00
Johan Bjork f920b3945e Fix dotted generated array error, bug1005.
Signed-off-by: Wilson Snyder <[email protected]>
2015-12-05 19:58:58 -05:00
Wilson Snyder 178028a70a Commentary; part of last commit 2015-12-05 19:45:45 -05:00
Todd Strader 5e54d3e41a Fix interface inside generate, bug1001, bug1003.
Signed-off-by: Wilson Snyder <[email protected]>
2015-12-05 19:39:40 -05:00
Wilson Snyder f0af8726e3 Internals: Fix some spacing. No functional change. 2015-12-05 17:12:03 -05:00
Todd Strader 57f2fe77ea Fix cell [#] to mean # cells.
Signed-off-by: Wilson Snyder <[email protected]>
2015-12-01 18:23:11 -05:00
Todd Strader d56ca25089 Tests: Fix false hidden module warning.
Signed-off-by: Wilson Snyder <[email protected]>
2015-12-01 18:17:26 -05:00
Wilson Snyder d39ce17dea Makefiles: Turn off make built-in suffixes. 2015-11-28 17:33:01 -05:00
Johan Bjork 373a68ec8b Fix dtype indexing into arrays, bug1007.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-24 21:34:07 -05:00
Johan Bjork 5613758ee3 Fix array slicing of non-const indexes, bug1006.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-24 21:28:04 -05:00
Johan Bjork 2102f86909 Fix genvar constant propagation, bug1003.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-22 21:16:13 -05:00
Wilson Snyder d5ea785de7 Commentary; last commit was bug1004 2015-11-22 21:13:16 -05:00
Johan Bjork 9edd28d2ed Fix genvar constant propagation from package, bug1003.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-22 20:46:26 -05:00
Wilson Snyder 7698af5178 Tests 2015-11-14 20:53:36 -05:00
Wilson Snyder 52ae451f5c Fix interface inside generate, bug998. 2015-11-14 09:06:09 -05:00
Wilson Snyder 9254443cd4 Fix casts under generates, bug999. 2015-11-12 22:29:42 -05:00
Johan Bjork 4e4bc7b90f Fix constant function assigned to packed structs, bug997.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-11 20:49:45 -05:00
Johan Bjork c7e0f2e196 Fix function calls on arrayed interface, bug994.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-11 20:40:24 -05:00
Wilson Snyder acabaab6ac Internals: Avoid tristate coredump. 2015-11-11 20:37:52 -05:00
Wilson Snyder b0a249f338 Fix display %u, %v, %p, %z, bug989. 2015-11-10 21:12:15 -05:00
Wilson Snyder 0cb5d5cc5a Internals: Upgrade some C strings to C++ 2015-11-10 18:59:48 -05:00
Wilson Snyder 9208c87f91 Tests: Better upper-case display formats. 2015-11-10 07:09:53 -05:00
Johan Bjork 0081ce4a75 Fix size-changing cast on packed struct, bug993.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-06 19:12:17 -05:00
Todd Strader 7850f49963 Fix t_scope_map --verbose test, bug955.
Signed-off-by: Wilson Snyder <[email protected]>
2015-11-06 18:58:48 -05:00
Wilson Snyder c72ee41142 Add z to param values to avoid conflicts. 2015-11-05 07:00:04 -05:00
Wilson Snyder bf5dee955d Fix real parameters causing bad module names, bug992. 2015-11-04 22:01:21 -05:00
Wilson Snyder 3df23a148a devel release 2015-11-01 08:20:17 -05:00
Wilson Snyder 0a1b55c296 Version bump 2015-11-01 08:18:54 -05:00
Wilson Snyder 14b8efe4bb Version bump 2015-11-01 08:14:44 -05:00
Wilson Snyder 64162efebd Fix commit 379bfd06, crash in commandArgsPlusMatch 2015-11-01 08:14:18 -05:00
Wilson Snyder faf5e1de51 Internals: Remove some unneeded c_str() calls. No functional change. 2015-10-29 22:19:51 -04:00
Wilson Snyder 0d7b1a7dc7 Remove VlCovCvtToCStr to avoid scary scope issues. 2015-10-29 21:58:00 -04:00
Wilson Snyder fa63bc6b78 Fix error message on missing interface, bug985. 2015-10-29 21:44:02 -04:00
Wilson Snyder 379bfd062f Fix crash in commandArgsPlusMatch, bug987. 2015-10-29 21:07:49 -04:00
Jamey Hicks 49108c23f0 Support with non-format arguments, bug467.
Signed-off-by: Wilson Snyder <[email protected]>
2015-10-27 20:58:31 -04:00
Wilson Snyder 4475060268 Ignore %l in , bug983. 2015-10-27 20:37:52 -04:00
Wilson Snyder 4f269e336d With --bbox-ignore, don't warn about always order. 2015-10-24 07:24:53 -04:00
Wilson Snyder 4464b13163 Fix dot indexing into arrayed inferfaces, bug978. 2015-10-23 23:06:24 -04:00
Wilson Snyder 215d5f68b0 Fix struct.enum.name method calls, bug855. 2015-10-23 22:57:15 -04:00
Wilson Snyder 281f4e04ee Fix $fwrite to constant stderr/stdout, bug961. 2015-10-23 21:53:16 -04:00
Wilson Snyder 17a3f9691d Fix package:scope.scope variable references. 2015-10-23 21:03:35 -04:00
Wilson Snyder 4fde6ee7af Support elaboration assertions, bug973. 2015-10-23 18:13:25 -04:00
Wilson Snyder 040b1b06d5 Support genvar indexes into arrayed cells, bug517. 2015-10-22 20:13:49 -04:00
Wilson Snyder b16ea8b719 Tests: With --benchmark, don't time directory change. 2015-10-21 06:54:03 -04:00
Wilson Snyder cc22847bc3 For --xml, decrease block indent to 2 spaces. 2015-10-20 21:22:00 -04:00
Johan Bjork 3702e17b2e Backout bug978 fix as is incomplete.
Signed-off-by: Wilson Snyder <[email protected]>
2015-10-10 07:54:45 -04:00
Wilson Snyder 7abc220fb3 Fix C++ 2014 compile warnings. No functional change. 2015-10-04 13:41:45 -04:00
Wilson Snyder 4fc9a906f6 Internals: Fix cppcheck warnings; add VL_DANGLING. No functional change. 2015-10-04 13:16:35 -04:00
Wilson Snyder 5de83c9805 Internals: Fix cppcheck warnings. No functional change. 2015-10-04 13:11:32 -04:00
Johan Bjork f71d904a9b Fix internal error on interface array, bug978.
Signed-off-by: Wilson Snyder <[email protected]>
2015-10-04 11:17:58 -04:00
Wilson Snyder 318ded4198 Internals: Cleanup cppcheck warnings. 2015-10-03 22:33:06 -04:00
Wilson Snyder f1874b211f Support , bug977. 2015-10-03 07:12:56 -04:00
Wilson Snyder c60ffd7fd9 Fix enum constant propagation, bug970. 2015-10-01 21:15:01 -04:00
Todd Strader dc57282168 Internal: Fix setBit from earlier commit, bug971.
Signed-off-by: Wilson Snyder <[email protected]>
2015-09-30 07:02:39 -04:00
Todd Strader 3c336e179f Fix structure parameter constant propagation, bug968.
Signed-off-by: Wilson Snyder <[email protected]>
2015-09-29 21:02:33 -04:00
Todd Strader 6bda57da5d Internals: Fix setBit not clearing X mask.
Signed-off-by: Wilson Snyder <[email protected]>
2015-09-29 20:59:17 -04:00
Wilson Snyder 9a16001e51 Add --vpi flag, and fix VPI linkage, bug969. 2015-09-25 22:57:28 -04:00
Todd Strader 34870e899f Add VerilatedScopeNameMap for introspection, bug966.
Signed-off-by: Wilson Snyder <[email protected]>
2015-09-24 21:08:58 -04:00
Wilson Snyder d0653f72e2 Fix very long module names, bug937. 2015-09-19 20:12:35 -04:00
Wilson Snyder 64748b7b1d Internals: Replace FNV hashes with SHA1 2015-09-19 18:49:54 -04:00
Wilson Snyder 7163c8d048 Fix internal error on dotted refs into generates, bug958. 2015-09-18 20:57:27 -04:00
Wilson Snyder d0ec991bb2 Fix mis-optimizing public DPI functions, bug963. 2015-09-18 19:06:15 -04:00
Wilson Snyder d458af4454 Commentary, bug965. 2015-09-11 20:18:41 -04:00
Wilson Snyder 9e9e7c33ae Install commentary, msg1678. 2015-09-03 21:20:19 -04:00
Wilson Snyder ce7de5ed30 Commentary, bug951 2015-08-16 11:48:05 -04:00
Wilson Snyder 776d8edf52 devel release 2015-08-12 21:42:08 -04:00
Wilson Snyder 5f21385e41 Version bump - commentary fix 2015-08-12 21:40:55 -04:00
Wilson Snyder 94fed93f54 Version bump 2015-08-12 21:34:59 -04:00
Wilson Snyder a950e4816d Support extraction of enum bits, bug951. 2015-08-12 21:33:40 -04:00
Wilson Snyder c87c66efb1 Fix size casts as second argument of cast item, bug950. 2015-08-12 19:37:25 -04:00
Jie Xu 5a5a0006fe Fix parameters with function parameter arguments, bug952.
Signed-off-by: Wilson Snyder <[email protected]>
2015-08-12 19:29:06 -04:00
Wilson Snyder 60b48a6830 Fix coverage documentation, bug954. 2015-08-12 19:18:58 -04:00
Wilson Snyder 5e41350588 Fix makefile with --coverage, bug953. 2015-08-12 19:06:15 -04:00
Wilson Snyder ff9f5b62ac bug951 testcase 2015-08-12 08:36:23 -04:00
Wilson Snyder 882913f0ca Add tracing_on, etc to vlt files, bug932. 2015-07-22 20:14:58 -04:00
Wilson Snyder 2062f7e97b Fix hashed error with typedef inside block, bug948. 2015-07-22 19:52:11 -04:00
Wilson Snyder 445c83a60d Fix with SV string, bug947. 2015-07-21 18:36:27 -04:00
Wilson Snyder 1891cfd79a Fix rounding in trace , bug946. 2015-07-21 13:22:08 -04:00
Wilson Snyder 06d5a7b2bf Internals: Allow hashing nulls; misc cleanup 2015-07-06 19:37:20 -04:00
Wilson Snyder 5af8a8aa4c Internals: Hash nulls 2015-07-05 20:31:30 -04:00
Wilson Snyder dc6b085d8b Fix MinGW compiler error, bug927. 2015-06-21 21:01:02 -04:00
Wilson Snyder 00759f777e Fix dpi imports inside generates. 2015-06-16 19:27:18 -04:00
Wilson Snyder 95ac0e61b2 Fix MinGW compiler error, bug927. 2015-06-16 07:13:45 -04:00
Wilson Snyder 6c5884853f Fix string-to-int space conversion, bug931. 2015-06-12 07:28:44 -04:00
Wilson Snyder 7578ef889f Fix .c files to be treated as .cpp, bug930. 2015-06-09 07:28:51 -04:00
Wilson Snyder da254af8d5 Fix MinGW compiler error, bug929. 2015-06-08 07:24:04 -04:00
Wilson Snyder 98123dc422 Verison fix 2015-06-06 14:02:06 -04:00
Wilson Snyder 466909b3d9 devel release 2015-06-06 14:00:23 -04:00
Wilson Snyder 0d4305192a Version bump 2015-06-06 13:58:26 -04:00
Wilson Snyder 9e61b9f696 Fix width propagation on sized casts, bug925. 2015-06-06 13:43:14 -04:00
Wilson Snyder 491539ff32 Fix MSVC++ compiler error, bug927. 2015-06-04 19:37:03 -04:00
Wilson Snyder 4c29a13a6e Fix include, part of bug919. 2015-05-16 18:08:20 -04:00
Wilson Snyder b66e1bdb9e Fix Ubuntu 15.04 compile warning. 2015-05-15 20:03:29 -04:00
Wilson Snyder 7312de6bc2 Fix sign extension in large localparams, bug910. 2015-05-14 21:46:07 -04:00
Wilson Snyder 1d6bcda014 Add pkg-config .pc file, bug919. 2015-05-13 21:21:29 -04:00
Wilson Snyder 5a747bad7d Fix width extension on mis-width ports, bug918. 2015-05-13 20:59:13 -04:00
Wilson Snyder 9542783a7e Internals: Refactor V3Inst static class. No functional change. 2015-05-13 20:56:16 -04:00
Wilson Snyder a59639413d Fix part-select in constant function, bug916. 2015-05-09 14:01:54 -04:00
Wilson Snyder d5eb92a071 Fix preprocessing stringified newline escapes, bug915. 2015-05-07 21:41:54 -04:00
Wilson Snyder 994cde57af Fix Cygwin uint32 compile, bug914. 2015-05-07 20:41:53 -04:00
Wilson Snyder 238a5809bf Fix truncation warning with -pins-bv, bug912. 2015-04-28 21:31:25 -04:00
Wilson Snyder 49fa65c0dd Match Verilog-Perl: Fix Preproc loop under Perl-Tk, bug913. 2015-04-28 15:54:34 -04:00
Wilson Snyder 49123f169c Fix core dump in sync-async warnings, bug911. 2015-04-27 06:47:29 -04:00
Wilson Snyder 4dc64c387f Part of prev commit, fix installing missing manpages, bug908. 2015-04-27 06:47:15 -04:00
Wilson Snyder 98a63711dd Fix installing missing manpages, bug908. 2015-04-09 19:03:01 -04:00
Wilson Snyder cb95cf4745 devel release 2015-04-09 19:00:02 -04:00
Wilson Snyder acd48fa61d Commentary, bug907. 2015-04-09 18:58:01 -04:00
Wilson Snyder cb7abcbaea Commentary 2015-04-09 18:57:25 -04:00
Wilson Snyder 793c974480 Version bump 2015-04-05 10:56:20 -04:00
Wilson Snyder 78a321925f Add Parser useProtected argument to aid runtime, Verilog-Perl bug899. 2015-04-05 10:54:56 -04:00
Wilson Snyder 643572595e Fix compile warning, msg1613. 2015-03-16 10:08:59 -04:00
Wilson Snyder fb4d462325 Rename readme for github. Commentary. 2015-03-14 13:45:00 -04:00
Wilson Snyder c0df07c86f Commentary: Update contributor list 2015-03-13 07:38:17 -04:00
Wilson Snyder e918d945f2 Fix order of C style arrays. 2015-03-13 07:06:06 -04:00
Wilson Snyder 0ee5743853 Add --dump-treei-<srcfile>, bug894. 2015-03-12 19:48:04 -04:00
Wilson Snyder 486d69da5f Add --clk and related optimizations, msg1533. 2015-03-12 19:20:46 -04:00
Wilson Snyder 005b4b7609 Updated - add VerilatedVcdFile to allow real-time waveforms, bug890. 2015-03-05 20:21:48 -05:00
Wilson Snyder a0fd065dcf Add VerilatedVcdFile to allow real-time waveforms, bug890. 2015-03-05 08:54:57 -05:00
Wilson Snyder 751384cb5c Fix compile error on MinGW, bug887. 2015-02-26 20:40:45 -05:00
Wilson Snyder 6ac672b4a3 Fix SystemC arrayed bit vectors, bug886. 2015-02-25 21:09:55 -05:00
Wilson Snyder a89502be9f Fix comma-separated instantiations with parameters, bug884. 2015-02-22 11:41:10 -05:00
Wilson Snyder 04e7b3bd4d devel release 2015-02-12 20:39:20 -05:00
Wilson Snyder 9ebb37b6a5 Version bump 2015-02-12 20:37:44 -05:00
Wilson Snyder 052a7e3deb Fix sign extension of pattern members, bug882. 2015-02-12 07:47:45 -05:00
Wilson Snyder 108c0f6bb8 Fix configure selecting switches that give warnings. 2015-02-11 21:24:01 -05:00
Wilson Snyder 6ed89b6ca5 New test for bug882. 2015-02-11 19:46:19 -05:00
Wilson Snyder 27ccaffb37 Fix mis-optimizing gate assignments in unopt blocks, bug881. 2015-02-11 19:36:34 -05:00
Wilson Snyder a001babad2 Fix executable bit on driver.pl from recent change. 2015-02-11 18:14:08 -05:00
Wilson Snyder 32a76c5255 Fix clang warnings. 2015-02-10 22:38:05 -05:00
Wilson Snyder 099f797975 Fix slice connections of arrays to ports, bug880. 2015-02-10 20:24:21 -05:00
Wilson Snyder b7df3e24b4 Tests: Support -ms for modelsim testing, bug878 2015-02-10 20:16:03 -05:00
Wilson Snyder 8323092a0c Fix cppcheck warnings. No functional change. 2015-02-09 21:05:27 -05:00
Wilson Snyder e5af46d3fb Add warning on slice selection out of bounds, bug875. 2015-01-25 16:32:46 -05:00
Wilson Snyder a6743588b6 Fix UNOPTFLAT change detect on multidim arrays, bug872. 2015-01-21 20:43:21 -05:00
Wilson Snyder 90cbcd2dfd Fix non-ANSI modport instantiations, bug868. 2015-01-17 15:35:45 -05:00
Wilson Snyder a36b7afba5 Fix VM_PARALLEL_BUILDS broke in 3.868, bug870. 2015-01-17 13:31:27 -05:00
Wilson Snyder 4c91ade61d Copyright year update 2015-01-07 18:25:53 -05:00
Wilson Snyder f2a17b9b70 Fix $sccanf from string, bug866. 2014-12-24 21:50:38 -05:00
Wilson Snyder b71b9ccb57 Fix member select error broke in 3.868, bug867. 2014-12-24 19:27:46 -05:00
Wilson Snyder 8b0af19351 Support cast operator with expression size, bug865. 2014-12-23 22:11:31 -05:00
Wilson Snyder 9f7c473376 Suppress COMBDLY when inside always_latch, bug854. 2014-12-23 21:42:33 -05:00
Wilson Snyder 0206767478 devel release 2014-12-20 16:49:42 -05:00
1589 changed files with 50861 additions and 16162 deletions
+6
View File
@@ -1,3 +1,5 @@
\#*
.#*
*~
*.old
*.gz
@@ -20,7 +22,11 @@ configure
dddrun*
doxygen-doc
gdbrun*
gmon.out
ncverilog.history
internals.txt
verilator.txt
verilator_bin*
verilator_coverage_bin*
verilator.pc
**/obj_dir/*
+584 -6
View File
@@ -1,9 +1,587 @@
Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks!
The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 3.867 devel
* 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
old test_c and test_sc directories.
*** Add --getenv option for simplifying Makefiles.
*** Add --x-initial option for specifying initial value assignment behavior.
*** Add --no-relative-cfuncs and related default optimization, bug1224. [John Coiner]
*** Add /*verilator tag*/ for XML extraction applications. [Chris Randall]
**** The internal test_verilated test directory is moved to be part of test_regress.
**** The experimental VL_THREADED setting (only, not normal mode) now requires C++11.
**** Fix over-aggressive inlining, bug1223. [John Coiner]
**** Fix Ubuntu 17.10 issues, bug1223 partial. [John Coiner]
**** Fix compiler warning when WIDTH warning ignored on large compare.
**** Fix memory leak in VerilatedVcd dumps, bug1222 partial. [Shareef Jalloq]
**** Fix unnecessary Vdly variables, bug1224 partial. [John Coiner]
**** Fix conditional slices and add related optimizations.
**** Fix `` expansion of `defines, bug1225, bug1227, bug1228. [Odd Magne Reitan]
**** Fix -E duplicating output, bug1226. [Odd Magne Reitan]
**** Fix float-conversion warning, bug1229. [Robert Henry]
**** Fix MacOS portability, bug1230, bug1231. [Jeff Bush]
* Verilator 3.912 2017-09-23
** Verilated headers no longer "use namespace std;"
User's code without "std::" prefixes may need "use namespace std;" to compile.
*** Support or/and/xor array intrinsic methods, bug1210. [Mike Popoloski]
*** Support package export, bug1217. [Usuario Eda]
*** Fix ordering of arrayed cell wide connections, bug1202 partial. [Mike Popoloski]
**** Support module port parameters without defaults, bug 1213. [Mike Popoloski]
**** Add performance information to --stats file.
**** Simplify VL_CONST_W macro generation for faster compiles.
**** Fix LITENDIAN warning on arrayed cells, bug1202. [Mike Popoloski]
**** Fix enum ranges without colons, bug1204. [Mike Popoloski]
**** Fix GCC noreturn compile error, bug1209. [Mike Popoloski]
**** Fix constant function default parameters, bug1211. [Mike Popoloski]
**** Fix non-colon array of interface modports, bug1212. [Mike Popoloski]
**** Fix .name connections on interfaces, bug1214. [Mike Popoloski]
**** Fix wide array indices causing compile error.
**** Better optimize Shift-And, and replication constructs.
* Verilator 3.910 2017-09-07
*** SystemPerl mode (-sp-deprecated) has been removed.
**** Update keyword warnings to include C++11 and others.
* Verilator 3.908 2017-08-28
**** Support x in $readmem, bug1180. [Arthur Kahlich]
**** Support packed struct DPI imports, bug1190. [Rob Stoddard]
**** Fix GCC 6 warnings.
**** Fix compile error on unused VL_VALUEPLUSARGS_IW, bug1181. [Thomas J Whatson]
**** Fix undefined VL_POW_WWI. [Clifford Wolf]
**** Fix internal error on unconnected inouts, bug1187. [Rob Stoddard]
* Verilator 3.906 2017-06-22
*** Support set_time_unit/set_time_precision in C traces, msg2261.
*** Fix extract of packed array with non-zero LSB, bug1172. [James Pallister]
*** Fix shifts by more than 32-bit numbers, bug1174. [Clifford Wolf]
*** Fix power operator on wide constants, bug761. [Clifford Wolf]
*** Fix .* on interface pins, bug1176. [Maciej Piechotka]
* Verilator 3.904 2017-05-30
*** Fix non-cutable ordering loops on clock arrays, bug1009. [Todd Strader]
*** Support ports of array of reals, bug1154. [J Briquet]
*** Support arrayed parameter overrides, bug1153. [John Stevenson]
*** Support $value$plusargs with variables, bug1165. [Wesley Terpstra]
**** Support modport access to un-modport objects, bug1161. [Todd Strader]
**** Add stack trace when can't optimize function, bug1158. [Todd Strader]
**** Add warning on mis-sized literal, bug1156. [Todd Strader]
**** Fix interface functions returning wrong parameters, bug996. [Todd Strader]
**** Fix non-arrayed cells with interface arrays, bug1153. [John Stevenson]
**** Fix --assert with complex case statements, bug1164. [Enzo Chi]
* Verilator 3.902 2017-04-02
** Add -FI option to force includes,msg2146. [Amir Gonnen]
** Add --relative-includes. [Rob Stoddard]
*** Add error on duplicate pattern assignments, bug1145. [Johan Bjork]
**** Fix error on improperly widthed default function, bug984. [Todd Strader]
**** Fix 2009 localparam syntax, msg2139. [Galen Seitz]
**** Fix ugly interface-to-non-interface errors, bug1112. [Johan Bjork]
**** Fix LDFLAGS and CFLAGS not preserving order, bug1130. [Olof Kindgren]
**** Fix internal error on initializing parameter array, bug1131. [Jie Xu]
**** Fix internal error on interface arrays, bug1135. [John Stevenson]
**** Fix calling sformatf to display, and elab $displays, bug1139. [Johan Bjork]
**** Fix realpath compile issue on MSVC++, bug1141. [Miodrag Milanovic]
**** Fix missing error on interface size mismatch, bug1143. [Johan Bjork]
**** Fix error on parameters with dotted references, bug1146. [Johan Bjork]
**** Fix wreal not handling continuous assign, bug1150. [J Briquet]
**** Fix nested structure parameter selects, bug1150. [J Briquet]
* Verilator 3.900 2017-01-15
** Internal code changes for improved compatibility and performance.
*** Support old-style $display($time), bug467. [John Demme]
**** With --bbox-unsup, suppress desassign and mixed edges, bug1120. [Galen Seitz]
**** Fix parsing sensitivity with &&, bug934. [Luke Yang]
**** Fix internal error on double-for loop unrolling, bug1044. [Jan Egil Ruud]
**** Fix internal error on unique casez with --assert, bug1117. [Enzo Chi]
**** Fix bad code when tracing array of structs, bug1122. [Andrew Bardsley]
* Verilator 3.890 2016-11-25
*** Honor --output-split on coverage constructors, bug1098. [Johan Bjork]
**** Fix various issues when making outside of the kit.
**** Fix flex 2.6.2 bug, bug1103. [Sergey Kvachonok]
**** Fix error on bad interface name, bug1097. [Todd Strader]
**** Fix error on referencing variable in parent, bug1099. [Ian Thompson]
**** Fix type parameters with low optimization, bug1101. [Stefan Wallentowitz]
* Verilator 3.888 2016-10-14
** Support foreach, bug1078. [Xuan Guo]
*** Add --no-decoration to remove output comments, msg2015. [Frederic Requin]
*** If VM_PARALLEL_BUILDS=1, use OPT_FAST and OPT_SLOW. [Frederic Requin]
Set VM_DEFAULT_RULES=0 for old behavior.
**** Add error on DPI functions > 32 bits, msg1995. [Elliot Mednick]
**** Fix SystemC compiles with VPI, bug1081. [Arthur Kahlich]
**** Fix error on wide numbers that represent shifts, msg1991, bug1088. [Mandy Xu]
**** Improve Verilation performance on internal strings, msg1975. [Johan Bjork]
**** Improve Verilation performance on trace duplicates, bug1090. [Johan Bjork]
* Verilator 3.886 2016-07-30
**** Fix enum values of 11-16 bits wide using .next/.prev, bug1062. [Brian Flachs]
**** Fix false warnings on non-power-2 enums using .next/.prev.
**** Fix comparison of unpacked arrays, bug1071. [Andrew Bardsley]
**** Fix compiler warning in GCC 6. [David Horton]
* Verilator 3.884 2016-05-18
** Support parameter type, bug376. [Alan Hunter, et al]
** Support command-line -G/+pvalue param overrides, bug1045. [Stefan Wallentowitz]
*** The default l2 scope name is now the same as the top-level module, bug1050.
Use "--l2-name v" for the historical behavior.
*** Add --l2-name option for controlling "v" naming.
**** Fix --output-split of constructors, bug1035. [Johan Bjork]
**** Fix removal of empty packages, modules and cells, bug1034. [Johan Bjork]
**** Fix core dump on Arch Linux/GCC 6.1.1, bug1058. [Jannis Harder]
**** Fix $value$plusargs to string, msg1890. [Frederic Requin]
* Verilator 3.882 2016-03-01
**** Internal Verilation-time performance enhancements, bug1021. [Johan Bjork]
**** Support inlining interfaces, bug1018. [Johan Bjork]
**** Support SV strings to readmemh, bug1040. [Stefan Wallentowitz]
**** Fix unrolling complicated for-loop bounds, bug677. [Johan Bjork]
**** Fix stats file containing multiple unroll entries, bug1020. [Johan Bjork]
**** Fix using short parameter names on negative params, bug1022. [Duraid Madina]
**** Fix read-after-free error, bug1031. [Johan Bjork]
**** Fix elaboration-time display warnings, bug1032. [Johan Bjork]
**** Fix crash on very deep function trees, bug1028. [Jonathan Kimmitt]
**** Fix slicing mix of big and little-endian, bug1033. [Geoff Barrett]
**** Fix pattern assignment width propagation, bug1037. [Johan Bjork]
* Verilator 3.880 2015-12-19
*** Support display %u, %v, %p, %z, bug989. [Johan Bjork]
**** Fix real parameters causing bad module names, bug992. [Johan Bjork]
**** Fix size-changing cast on packed struct, bug993. [Johan Bjork]
**** Fix function calls on arrayed interface, bug994. [Johan Bjork]
**** Fix arrayed interfaces, bug879, bug1001. [Todd Strader]
**** Fix constant function assigned to packed structs, bug997. [Johan Bjork]
**** Fix interface inside generate, bug998. [Johan Bjork]
**** Fix $signed casts under generates, bug999. [Clifford Wolf]
**** Fix genvar constant propagation, bug1003. [Johan Bjork]
**** Fix parameter constant propagation from package, bug1004. [Johan Bjork]
**** Fix array slicing of non-const indexes, bug1006. [Johan Bjork]
**** Fix dotted generated array error, bug1005. [Jeff Bush, Johan Bjork]
**** Fix error instead of warning on large concat, msg1768. [Paul Rolfe]
**** Fix $bitstoreal constant propagation, bug1012. [Jonathan Kimmitt]
**** Fix model restore crash, bug1013. [Jason McMullan]
**** Fix arrayed instances to unpacked of same size, bug1015. [Varun Koyyalagunta]
**** Fix slices of unpacked arrays with non-zero LSBs.
**** Fix ternary operation with unpacked array, bug1017. [Varun Koyyalagunta].
* Verilator 3.878 2015-11-01
** Add --vpi flag, and fix VPI linkage, bug969. [Arthur Kahlich]
** Support genvar indexes into arrayed cells, bug517. [Todd Strader]
** Support $sformatf, bug977. [Johan Bjork]
*** Support elaboration assertions, bug973. [Johan Bjork]
*** Support $display with non-format arguments, bug467. [Jamey Hicks]
**** Add VerilatedScopeNameMap for introspection, bug966. [Todd Strader]
**** Ignore %l in $display, bug983. [Todd Strader]
**** Fix very long module names, bug937. [Todd Strader]
**** Fix internal error on dotted refs into generates, bug958. [Jie Xu]
**** Fix structure parameter constant propagation, bug968. [Todd Strader]
**** Fix enum constant propagation, bug970. [Todd Strader]
**** Fix mis-optimizing public DPI functions, bug963. [Wei Song]
**** Fix package:scope.scope variable references.
**** Fix $fwrite to constant stderr/stdout, bug961. [Wei Song]
**** Fix struct.enum.name method calls, bug855. [Jonathon Donaldson]
**** Fix dot indexing into arrayed inferfaces, bug978. [Johan Bjork]
**** Fix crash in commandArgsPlusMatch, bug987. [Jamie Iles]
**** Fix error message on missing interface, bug985. [Todd Strader]
* Verilator 3.876 2015-08-12
*** Add tracing_on, etc to vlt files, bug932. [Frederic Requin]
**** Support extraction of enum bits, bug951. [Jonathon Donaldson]
**** Fix MinGW compiler error, bug927, bug929. [Hans Tichelaar]
**** Fix .c files to be treated as .cpp, bug930. [Jonathon Donaldson]
**** Fix string-to-int space conversion, bug931. [Fabrizio Ferrandi]
**** Fix dpi imports inside generates. [Michael Tresidder]
**** Fix rounding in trace $timescale, bug946. [Frederic Requin]
**** Fix $fopen with SV string, bug947. [Sven Stucki]
**** Fix hashed error with typedef inside block, bug948. [Sven Stucki]
**** Fix makefile with --coverage, bug953. [Eivind Liland]
**** Fix coverage documentation, bug954. [Thomas J Whatson]
**** Fix parameters with function parameter arguments, bug952. [Jie Xu]
**** Fix size casts as second argument of cast item, bug950. [Jonathon Donaldson]
* Verilator 3.874 2015-06-06
*** Add pkg-config .pc file, bug919. [Stefan Wallentowitz]
**** Fix installing missing manpages, bug908. [Ahmed El-Mahmoudy]
**** Fix sign extension in large localparams, bug910. [Mike Thyer]
**** Fix core dump in sync-async warnings, bug911. [Sebastian Dressler]
**** Fix truncation warning with -pins-bv, bug912. [Alfonso Martinez]
**** Fix Cygwin uint32 compile, bug914. [Matthew Barr]
**** Fix preprocessing stringified newline escapes, bug915. [Anton Rapp]
**** Fix part-select in constant function, bug916. [Andrew Bardsley]
**** Fix width extension on mis-width ports, bug918. [Patrick Maupin]
**** Fix width propagation on sized casts, bug925. [Jonathon Donaldson]
**** Fix MSVC++ compiler error, bug927. [Hans Tichelaar]
* Verilator 3.872 2015-04-05
*** Add VerilatedVcdFile to allow real-time waveforms, bug890. [HyungKi Jeong]
*** Add --clk and related optimizations, msg1533. [Jie Xu]
*** Fix order of C style arrays. [Duraid Madina]
**** Add --dump-treei-<srcfile>, bug894. [Jie Xu]
**** Fix comma-instantiations with parameters, bug884. [Franck Jullien]
**** Fix SystemC arrayed bit vectors, bug886. [David Poole]
**** Fix compile error on MinGW, bug887. [HyungKi Jeong]
* Verilator 3.870 2015-02-12
**** Suppress COMBDLY when inside always_latch, bug864. [Iztok Jeras]
**** Support cast operator with expression size, bug865. [Iztok Jeras]
**** Add warning on slice selection out of bounds, bug875. [Cong Van Nguyen].
**** Fix member select error broke in 3.868, bug867. [Iztok Jeras]
**** Fix $sccanf from string, bug866. [David Pierce]
**** Fix VM_PARALLEL_BUILDS broke in 3.868, bug870. [Hiroki Honda]
**** Fix non-ANSI modport instantiations, bug868. [Kevin Thompson]
**** Fix UNOPTFLAT change detect on multidim arrays, bug872. [Andrew Bardsley]
**** Fix slice connections of arrays to ports, bug880. [Varun Koyyalagunta]
**** Fix mis-optimizing gate assignments in unopt blocks, bug881. [Mike Thyer]
**** Fix sign extension of pattern members, bug882. [Iztok Jeras]
**** Fix clang compile warnings.
* Verilator 3.868 2014-12-20
** New verilator_coverage program added to replace SystemPerl's vcoverage.
@@ -1635,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]
@@ -2503,12 +3081,12 @@ of input ports exists for tracing.
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
Copyright 2001-2014 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.
Local variables:
mode: outline
paragraph-separate: "[ \f\n]*$"
paragraph-separate: "[ \f\n]*$"
end:
+9
View File
@@ -12,13 +12,19 @@
.*\.tex
.*\.key
.*\.vcd
.*\.1
/obj_dir/
/obj_dbg/
/obj_opt/
/obj_vlt/
/obj_vltmt/
/obj_dist/
/INCA_libs/
/cov_work/
/logs/
^Makefile$
bin/verilator_bin.*
bin/verilator_coverage_bin.*
src/Makefile$
src/Makefile_obj$
include/verilated.mk$
@@ -27,9 +33,11 @@ config.cache$
config.status$
verilator.log
verilator.tex
verilator.pc$
verilator_bin.*
verilator_coverage_bin.*
.vcsmx_rebuild$
ncverilog.history
autom4te\.cache/
nodist/
/simv$
@@ -37,5 +45,6 @@ nodist/
/vc_hdrs.h$
/csrc/
doxygen-doc/.*
obj_dir/.*
TAGS
.*~
+95 -64
View File
@@ -3,13 +3,11 @@
#
# This file is part of Verilator.
#
# Author: Wilson Snyder <[email protected]>
#
# Code available from: http://www.veripool.org/verilator
#
#*****************************************************************************
#
# Copyright 2003-2014 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.
@@ -44,9 +42,6 @@
# reconstructed with this Makefile. This typically includes
# everything deleted by distclean, plus more: C source files
# produced by Bison, tags tables, info files, and so on.
#
# make extraclean
# Still more severe - delete backup and autosave files, too.
#### Start of system configuration section. ####
@@ -73,7 +68,7 @@ exec_prefix = @exec_prefix@
# Directory in which to install scripts.
bindir = @bindir@
# Directory in which to install scripts.
# Directory in which to install manpages.
mandir = @mandir@
# Directory in which to install library files.
@@ -86,6 +81,10 @@ infodir = @infodir@
# Generally ${prefix}/share/verilator
pkgdatadir = @pkgdatadir@
# Directory in which to install pkgconfig file
# Generall ${prefix}/share/pkgconfig
pkgconfigdir = @pkgconfigdir@
# Directory in which to install data across multiple architectures
datarootdir = @datarootdir@
@@ -93,18 +92,23 @@ 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. ####
######################################################################
.SUFFIXES:
SHELL = /bin/sh
SUBDIRS = src test_verilated test_c test_sc test_regress
SUBDIRS = src test_regress \
examples/hello_world_c examples/hello_world_sc \
examples/tracing_c examples/tracing_sc \
INFOS = README README.html README.pdf internals.txt internals.html \
internals.pdf verilator.txt verilator.html verilator.1 verilator.pdf \
verilator_coverage.1
internals.pdf verilator.txt verilator.html verilator.pdf \
$(VL_INST_MAN_FILES)
# Files that can be generated, but should be up to date for a distribution.
DISTDEP = info Makefile
@@ -113,7 +117,11 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
*.in *.ac \
Changes TODO \
MANIFEST.SKIP \
bin/* \
bin/verilator \
bin/verilator_coverage \
bin/verilator_difftree \
bin/verilator_includer \
bin/verilator_profcfunc \
doxygen-mainpage doxygen.config veripool-logo.png \
install-sh configure mkinstalldirs *.pod \
include/*.[chv]* \
@@ -126,11 +134,14 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
src/vlcovgen \
src/.gdbinit \
src/*.pl src/*.pod \
examples/*/.*ignore examples/*/Makefile* \
examples/*/*.[chv]* examples/*/*.pl \
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
test_verilated/vgen*.pl \
test_regress/t/t*/*.sv* \
test_regress/t/t*/*.v* \
test_regress/t/t*/*/*.sv* \
test_regress/t/t*/*/*.v* \
test_regress/t/*.cpp \
test_regress/t/*.h \
test_regress/t/*.dat \
@@ -150,9 +161,9 @@ INST_PROJ_FILES = \
include/vltstd/*.[chv]* \
INST_PROJ_BIN_FILES = \
verilator_bin \
verilator_bin_dbg \
verilator_coverage_bin_dbg \
bin/verilator_bin \
bin/verilator_bin_dbg \
bin/verilator_coverage_bin_dbg \
DISTFILES := $(DISTFILES_INC)
@@ -179,40 +190,37 @@ verilator_exe verilator_bin verilator_bin_dbg verilator_coverage_bin_dbg:
msg_test: all_nomsg
@echo "Build complete!"
@echo
@echo "Type 'make test' to test."
@echo "Now type 'make test' to test."
@echo
.PHONY:test
.PHONY: test
ifeq ($(CFG_WITH_LONGTESTS),yes) # Local... Else don't burden users
test: test_c test_sc test_verilated test_regress
test: smoke-test examples test_regress
else
test: test_c test_sc
test: smoke-test examples
endif
@echo "Tests passed!"
@echo
@echo "Type 'make install' to install documentation."
@echo "Now type 'make install' to install."
@echo "Or type 'make' inside an examples subdirectory."
@echo
test_c: all_nomsg
@(cd test_c && $(MAKE))
test_c_debug: all_nomsg
@(cd test_c && $(MAKE) test_debug)
test_sc: all_nomsg
@(cd test_sc && $(MAKE))
test_sc_debug: all_nomsg
@(cd test_sc && $(MAKE) test_debug)
test_verilated: all_nomsg
@(cd test_verilated && $(MAKE))
smoke-test: all_nomsg
test_regress/t/t_a_first_cc.pl
test_regress/t/t_a_first_sc.pl
test_regress: all_nomsg
@(cd test_regress && $(MAKE))
examples: all_nomsg
for p in examples/* ; do \
$(MAKE) -C $$p VERILATOR_ROOT=`pwd` || exit 10; \
done
info: $(INFOS)
# Use --no-split to avoid creating filenames > 14 chars.
verilator.1: ${srcdir}/bin/verilator
pod2man $< $@
verilator_coverage.1: ${srcdir}/bin/verilator_coverage
%.1: ${srcdir}/bin/%
pod2man $< $@
verilator.txt: ${srcdir}/bin/verilator
@@ -230,16 +238,16 @@ verilator.pdf: ${srcdir}/bin/verilator Makefile
pdflatex verilator.tex
-rm -f verilator.toc verilator.aux verilator.idx verilator.out
README: readme.pod
README: README.pod
-rm -f $@
$(POD2TEXT) --loose $< > $@
README.html: readme.pod
README.html: README.pod
pod2html $< >$@
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
README.pdf: readme.pod Makefile
pod2latex --full --out README.tex readme.pod
README.pdf: README.pod Makefile
pod2latex --full --out README.tex README.pod
$(PERL) $(POD2LATEXFIX) "$(DISTTITLE) README File" "${DISTDATE}" < README.tex > README2.tex
mv README2.tex README.tex
pdflatex README.tex
@@ -269,9 +277,10 @@ VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg verilator_coverage
# so they can be found by the user, and under $VERILATOR_ROOT.
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
VL_INST_MAN_FILES = verilator.1 verilator_coverage.1
VL_INST_MAN_FILES = verilator.1 verilator_coverage.1 verilator_profcfunc.1
VL_INST_INC_BLDDIR_FILES = \
include/verilated_config.h \
include/verilated.mk \
# Files under srcdir, instead of build time
@@ -280,18 +289,16 @@ VL_INST_INC_SRCDIR_FILES = \
include/vltstd/*.[chv]* \
VL_INST_DATA_SRCDIR_FILES = \
test_v/*.[chv]* \
test_c/*.[chv]* test_c/Makefile test_c/Makefile_obj \
test_sc/*.[chv]* test_sc/Makefile test_sc/Makefile_obj \
examples/*/*.[chv]* examples/*/Makefile* \
installbin:
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir)
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator $(DESTDIR)$(bindir)/verilator )
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_coverage $(DESTDIR)$(bindir)/verilator_coverage )
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_profcfunc $(DESTDIR)$(bindir)/verilator_profcfunc )
( $(INSTALL_PROGRAM) verilator_bin $(DESTDIR)$(bindir)/verilator_bin )
( $(INSTALL_PROGRAM) verilator_bin_dbg $(DESTDIR)$(bindir)/verilator_bin_dbg )
( $(INSTALL_PROGRAM) verilator_coverage_bin_dbg $(DESTDIR)$(bindir)/verilator_coverage_bin_dbg )
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_bin $(DESTDIR)$(bindir)/verilator_bin )
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_bin_dbg $(DESTDIR)$(bindir)/verilator_bin_dbg )
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_coverage_bin_dbg $(DESTDIR)$(bindir)/verilator_coverage_bin_dbg )
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/bin
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer )
@@ -299,7 +306,8 @@ installbin:
# So important we use $< so VPATH is searched
installman: $(VL_INST_MAN_FILES)
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(mandir)/man1
for p in $< ; do \
cd $(srcdir) \
; for p in $(VL_INST_MAN_FILES) ; do \
$(INSTALL_DATA) $$p $(DESTDIR)$(mandir)/man1/$$p; \
done
@@ -312,13 +320,16 @@ installdata:
; for p in $(VL_INST_INC_SRCDIR_FILES) ; do \
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
done
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/test_c
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/test_sc
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/test_v
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/hello_world_c
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/hello_world_sc
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/tracing_c
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/tracing_sc
cd $(srcdir) \
; for p in $(VL_INST_DATA_SRCDIR_FILES) ; do \
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/examples/$$p; \
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
done
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgconfigdir)
$(INSTALL_DATA) verilator.pc $(DESTDIR)$(pkgconfigdir)
# We don't trust rm -rf, so rmdir instead as it will fail if user put in other files
uninstall:
@@ -327,16 +338,18 @@ uninstall:
-cd $(DESTDIR)$(mandir)/man1 && rm -f $(VL_INST_MAN_FILES)
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_BLDDIR_FILES)
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_SRCDIR_FILES)
-cd $(DESTDIR)$(pkgdatadir)/examples && rm -f $(VL_INST_DATA_SRCDIR_FILES)
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_DATA_SRCDIR_FILES)
-rm $(DESTDIR)$(pkgconfigdir)/verilator.pc
-rmdir $(DESTDIR)$(pkgdatadir)/bin
-rmdir $(DESTDIR)$(pkgdatadir)/include/vltstd
-rmdir $(DESTDIR)$(pkgdatadir)/include
-rmdir $(DESTDIR)$(pkgdatadir)/examples/test_c
-rmdir $(DESTDIR)$(pkgdatadir)/examples/test_sc
-rmdir $(DESTDIR)$(pkgdatadir)/examples/test_sp
-rmdir $(DESTDIR)$(pkgdatadir)/examples/test_v
-rmdir $(DESTDIR)$(pkgdatadir)/examples/hello_world_c
-rmdir $(DESTDIR)$(pkgdatadir)/examples/hello_world_sc
-rmdir $(DESTDIR)$(pkgdatadir)/examples/tracing_c
-rmdir $(DESTDIR)$(pkgdatadir)/examples/tracing_sc
-rmdir $(DESTDIR)$(pkgdatadir)/examples
-rmdir $(DESTDIR)$(pkgdatadir)
-rmdir $(DESTDIR)$(pkgconfigdir)
install: all_nomsg install-all
install-all: installbin installman installdata install-msg
@@ -352,8 +365,8 @@ INST_PROJ_CVS = cp_if_cvs_diff
install-project: dist
@echo "Install-project to $(DIRPROJECT)"
strip verilator_bin*
strip verilator_coverage_bin*
strip bin/verilator_bin*
strip bin/verilator_coverage_bin*
$(MAKE) install-project-quick
for p in $(VL_INST_MAN_FILES) ; do \
$(INSTALL_DATA) $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \
@@ -376,8 +389,8 @@ endif
install-cadtools: dist
@echo "Install-project to $(CAD_DIR)"
strip verilator_bin*
strip verilator_coverage_bin*
strip bin/verilator_bin*
strip bin/verilator_coverage_bin*
$(MAKE) install-cadtools-quick
$(SHELL) ${srcdir}/mkinstalldirs $(VERILATOR_CAD_DIR)/man/man1
for p in $(VL_INST_MAN_FILES) ; do \
@@ -406,7 +419,8 @@ endif
# Use --xml flag to see the cppcheck code to use for suppression
CPPCHECK = src/cppcheck_filtered
CPPCHECK_FLAGS = --enable=all --inline-suppr --suppress=unusedScopedObject --suppress=cstyleCast
CPPCHECK_FLAGS = --enable=all --inline-suppr \
--suppress=unusedScopedObject --suppress=cstyleCast --suppress=useInitializationList
CPPCHECK_FLAGS += --xml
CPPCHECK_CPP = $(wildcard $(srcdir)/include/*.cpp $(srcdir)/src/*.cpp)
CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CPPCHECK_CPP))
@@ -414,14 +428,25 @@ CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/src/obj_dbg -I$(srcdir)/src
cppcheck: $(CPPCHECK_DEP)
%.cppcheck: %.cpp
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 $(CPPCHECK_INC) $<
$(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:
@echo "Installed!"
@echo
@echo "Fod documentation see 'man verilator' or 'verilator --help'"
@echo "Installed binaries to $(DESTDIR)$(bindir)/verilator"
@echo "Installed man to $(DESTDIR)$(mandir)/man1"
@echo "Installed examples to $(DESTDIR)$(pkgdatadir)/examples"
@echo
@echo "For documentation see 'man verilator' or 'verilator --help'"
@echo "For forums and to report bugs see http://www.veripool.org/verilator"
@echo
@@ -447,7 +472,7 @@ endif
maintainer-clean::
@echo "This command is intended for maintainers to use;"
@echo "rebuilding the deleted files requires makeinfo."
rm -f *.info* $(INFOS) configure
rm -f *.info* *.1 $(INFOS) configure
clean mostlyclean distclean maintainer-clean maintainer-copy::
for dir in $(SUBDIRS); do \
@@ -461,10 +486,13 @@ clean mostlyclean distclean maintainer-clean::
rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs *.idx
rm -f *.ev *.evs *.ov *.ovs *.cv *.cvs *.ma *.mas
rm -f *.tex
rm -rf test_*/obj_dir
rm -rf examples/*/obj_dir examples/*/logs
distclean maintainer-clean::
rm -f Makefile config.status config.cache config.log TAGS
rm -f verilator_bin* verilator_coverage_bin*
rm -f bin/verilator_bin* bin/verilator_coverage_bin*
rm -f include/verilated.mk include/verilated_config.h
TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/*.in \
@@ -486,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
+14 -8
View File
@@ -5,11 +5,13 @@
=head1 NAME
This is the Verilator Package README file.
This is the Verilator package README file.
=head1 DISTRIBUTION
This package is Copyright 2003-2014 by Wilson Snyder. (Report bugs to
http://www.veripool.org/verilator
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
@@ -49,7 +51,7 @@ output (not Verilator itself) compiles under MSVC++ 2008 and newer.
=head1 INSTALLATION
For more details see
For more details see
L<http://www.veripool.org/projects/verilator/wiki/Installing>.
If you will be modifying Verilator, you should use the "git" method as it
@@ -115,9 +117,10 @@ and add it to path using Modules/modulecmd:
After installing you'll want a module file like the following:
set install_root /CAD_DISK/verilator/{version-number-used-above}
setenv VERILATOR_ROOT $install_root
unsetenv VERILATOR_ROOT
prepend-path PATH $install_root/bin
prepend-path MANPATH $install_root/man
prepend-path PKG_CONFIG_PATH $install_root/share/pkgconfig
=item 3.
@@ -166,6 +169,9 @@ have the verilator binary directory in your PATH (this should already be
true if using the default configure), and make sure VERILATOR_ROOT is not
set.
You may now wish to consult the examples directory. Type C<make> inside any
example directory to run the example.
=back
=head1 USAGE DOCUMENTATION
@@ -187,10 +193,10 @@ The directories in the kit after de-taring are as follows:
include/verilated.v => Stub defines for linting
include/verilated.mk => Common makefile
src/ => Translator source code
test_v => Example Verilog code for other test dirs
test_c => Example Verilog->C++ conversion
test_sc => Example Verilog->SystemC conversion
test_verilated => Internal tests
examples/hello_world_c => Example simple Verilog->C++ conversion
examples/hello_world_sc => Example simple Verilog->SystemC conversion
examples/tracing_c => Example Verilog->C++ with tracing
examples/tracing_sc => Example Verilog->SystemC with tracing
test_regress => Internal tests
=head1 LIMITATIONS
+4 -10
View File
@@ -1,6 +1,6 @@
// DESCRIPTION: Verilator: List of To Do issues.
//
// Copyright 2004-2014 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
@@ -41,27 +39,24 @@ Testing:
* // verilator debug in code so can see only tree affecting those nodes
Usability:
* Detect and pre-remove most UNOPTFLATs (4.000)
* Detect and pre-remove most UNOPTFLATs (4.000)
* Better reporting of unopt problems, including what lines of code
* Report more errors (all of them?) before exiting [Eugene Weber]
* Auto-create scons config files
* 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,
+820 -391
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
######################################################################
#
# Copyright 2003-2014 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-2014 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-2014 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.
+3 -3
View File
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
# DESCRIPTION: Print include statements for each ARGV
#
# Copyright 2003-2014 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.
######################################################################
@@ -13,8 +13,8 @@ use warnings;
print "// DESCR"."IPTION: Generated by verilator_includer via makefile\n";
foreach my $param (@ARGV) {
if ($param =~ /^-D([^=]+)=(.*)/) {
print "#define $1 $2\n"
print "#define $1 $2\n"
} else {
print "#include \"$param\"\n"
print "#include \"$param\"\n"
}
}
+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-2014 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.
+187 -27
View File
@@ -1,19 +1,31 @@
# DESCRIPTION: Process this file with autoconf to produce a configure script.
#
# Copyright 2003-2014 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.867 devel])
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
AC_CONFIG_HEADER(src/config_build.h)
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h)
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc)
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 disable hardcoded paths)
AC_MSG_CHECKING(whether to use hardcoded paths)
AC_ARG_ENABLE([defenv],
[AS_HELP_STRING([--disable-defenv],
[disable using some hardcoded data paths extracted from some default environment variables (the default is to use hardcoded paths)])],
@@ -40,7 +52,7 @@ AC_ARG_ENABLE([ccwarn],
x) CFG_WITH_CCWARN=no ;;
*) CFG_WITH_CCWARN=yes ;;
esac]
)
)
AC_SUBST(CFG_WITH_CCWARN)
AC_MSG_RESULT($CFG_WITH_CCWARN)
@@ -58,10 +70,25 @@ AC_ARG_ENABLE([longtests],
x) CFG_WITH_LONGTESTS=no ;;
*) CFG_WITH_LONGTESTS=yes ;;
esac]
)
)
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}
@@ -74,12 +101,14 @@ 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; }])],
AC_MSG_RESULT(yes),
AC_MSG_RESULT(no);AC_MSG_ERROR([a working C++ compiler is required]),
AC_MSG_RESULT(yes))
[AC_LANG_SOURCE([int main() { return 0; }])],
AC_MSG_RESULT(yes),
AC_MSG_RESULT(no);AC_MSG_ERROR([a working C++ compiler is required]),
AC_MSG_RESULT(yes))
AC_PATH_PROG(PERL,perl)
if test "x$PERL" = "x" ; then
@@ -103,45 +132,176 @@ AC_TYPE_SIZE_T
# Checks for compiler characteristics.
AC_C_INLINE
AC_DEFUN([_MY_CXX_CHECK_OPT],
[# _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options
AC_LINK_IFELSE(
[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],
[# _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options
# Set $_my_result appropriately
ACO_SAVE_CXXFLAGS="$CXXFLAGS"
# -Werror needed otherwise unknown -Wno-div-by-zero won't report problems
# new/delete is needed to find -faligned-new link problem on Darwin
CXXFLAGS="$CXXFLAGS $1 -Werror"
AC_MSG_CHECKING([whether $CXX accepts $1])
AC_LINK_IFELSE(
[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
_my_result=no
fi
fi],
[_my_result=no])
# GCC is annoying, trying to be helpful, it postpones unknown -Wno-
# options if there's no error We want to see them regardless, so try
# forcing an error and see if we get a gcc warning
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([],[])],
[_my_result=yes],
[_my_result=no])
[AC_LANG_PROGRAM([[an_error "intentional-error-for-test.h"
]],[])],
[], # Ignore ok exit
[if test -s conftest.err; then
if grep -e "$1" conftest.err >/dev/null; then
_my_result=no
fi
fi])
AC_MSG_RESULT($_my_result)
if test "$_my_result" = "yes" ; then
CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED $1"
fi
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
])# _MY_CXX_CHECK_OPT
])
AC_DEFUN([_MY_CXX_CHECK_SET],
[# _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options
# If it does, set variable to flag, only if not previously set
if test "$$1" = ""; then
_MY_CXX_CHECK_FLAG($2)
if test "$_my_result" = "yes" ; then
$1="$2"
fi
fi
])
AC_DEFUN([_MY_CXX_CHECK_OPT],
[# _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options
# If it does, append flag to variable
_MY_CXX_CHECK_FLAG($2)
if test "$_my_result" = "yes" ; then
$1="$$1 $2"
fi
])
# Flag to select newest language standard supported
# 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)
AC_SUBST(CFG_CXXFLAGS_STD_NEWEST)
# And likewise oldest standard (same list above, backwards)
# This is used for internal testing
_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)
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++17)
AC_SUBST(CFG_CXXFLAGS_STD_OLDEST)
# Flags for compiling Verilator internals including parser, and Verilated files
# These turn on extra warnings and are only used with 'configure --enable-ccwarn'
_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
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Qunused-arguments)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-faligned-new)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-fno-delete-null-pointer-checks)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-undefined-bool-conversion)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-shadow)
AC_SUBST(CFG_CXXFLAGS_SRC)
# Flags for compiling Verilator parser always (in addition to above CFG_CXXFLAGS_SRC)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-char-subscripts)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-null-conversion)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-parentheses-equality)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-unused)
AC_SUBST(CFG_CXXFLAGS_PARSER)
# Flags for Verilated makefile
# For example, -Wno-div-by-zero isn't in 4.1.2
_MY_CXX_CHECK_OPT(-Wno-char-subscripts)
_MY_CXX_CHECK_OPT(-Wno-parentheses-equality)
# Random code often does / 0. Unfortunately VL_DIV_I(0,0) will warn
# without this flag, even though there's a conditional to prevent the divide.
# We still don't add no-div-by-zero as it throws message to stdout, though doesn't die.
#_MY_CXX_CHECK_OPT(-Wno-div-by-zero)
_MY_CXX_CHECK_OPT(-Wno-sign-compare)
_MY_CXX_CHECK_OPT(-Wno-uninitialized)
_MY_CXX_CHECK_OPT(-Wno-unused-but-set-variable)
_MY_CXX_CHECK_OPT(-Wno-unused-parameter)
_MY_CXX_CHECK_OPT(-Wno-unused-variable)
_MY_CXX_CHECK_OPT(-fbracket-depth=4096)
_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)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-but-set-variable)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-parameter)
_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])],
[], [#include <sys/stat.h>])
# Checks for system services
# Other install directories
pkgdatadir=${datadir}/verilator
AC_SUBST(pkgdatadir)
pkgconfigdir=${datadir}/pkgconfig
AC_SUBST(pkgconfigdir)
AC_OUTPUT
+1 -6
View File
@@ -630,13 +630,8 @@ WARN_LOGFILE =
# with spaces.
INPUT = doxygen-mainpage \
include \
include \
src \
test_c \
test_regress \
test_sc \
test_v \
test_verilated
# 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
@@ -3,4 +3,4 @@
*.csrc
*.vcd
obj_*
project
logs
+52
View File
@@ -0,0 +1,52 @@
######################################################################
#
# DESCRIPTION: Verilator Example: Small Makefile
#
# This calls the object directory makefile. That allows the objects to
# be placed in the "current directory" which simplifies the Makefile.
#
# 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.
#
######################################################################
# Check for sanity to avoid later confusion
ifneq ($(words $(CURDIR)),1)
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
endif
######################################################################
# This is intended to be a minimal example. Before copying this to start a
# real project, it is better to start with a more complete example,
# e.g. examples/tracing_c.
# 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),)
VERILATOR = verilator
else
export VERILATOR_ROOT
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
endif
default:
@echo "-- Verilator hello-world simple example"
@echo "-- VERILATE ----------------"
$(VERILATOR) -cc --exe top.v sim_main.cpp
@echo "-- COMPILE -----------------"
$(MAKE) -j 4 -C obj_dir -f Vtop.mk
@echo "-- RUN ---------------------"
obj_dir/Vtop
@echo "-- DONE --------------------"
@echo "Note: Once this example is understood, see examples/tracing_c."
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
######################################################################
maintainer-copy::
clean mostlyclean distclean maintainer-clean::
-rm -rf obj_dir *.log *.dmp *.vpd core
+41
View File
@@ -0,0 +1,41 @@
// DESCRIPTION: Verilator: Verilog example module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2017 by Wilson Snyder.
//======================================================================
// Include common routines
#include <verilated.h>
// Include model header, generated from Verilating "top.v"
#include "Vtop.h"
int main(int argc, char** argv, char** env) {
// See a similar example walkthrough in the verilator manpage.
// This is intended to be a minimal example. Before copying this to start a
// real project, it is better to start with a more complete example,
// e.g. examples/c_tracing.
// Prevent unused variable warnings
if (0 && argc && argv && env) {}
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
Vtop* top = new Vtop;
// Simulate until $finish
while (!Verilated::gotFinish()) {
// Evaluate model
top->eval();
}
// Final model cleanup
top->final();
// Destroy model
delete top;
// Fin
exit(0);
}
+12
View File
@@ -0,0 +1,12 @@
// DESCRIPTION: Verilator: Verilog example module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2017 by Wilson Snyder.
// See also the EXAMPLE section in the verilator manpage/document.
module top;
initial begin
$display("Hello World!");
$finish;
end
endmodule
@@ -1,8 +1,6 @@
*.old
*.dmp
*.log
*.csrc
*.vcd
obj_*
logs
project
+67
View File
@@ -0,0 +1,67 @@
######################################################################
#
# DESCRIPTION: Verilator Example: Small Makefile
#
# This calls the object directory makefile. That allows the objects to
# be placed in the "current directory" which simplifies the Makefile.
#
# 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.
#
######################################################################
# Check for sanity to avoid later confusion
ifneq ($(words $(CURDIR)),1)
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
endif
######################################################################
# This is intended to be a minimal example. Before copying this to start a
# real project, it is better to start with a more complete example,
# e.g. examples/tracing_sc.
# 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),)
VERILATOR = verilator
else
export VERILATOR_ROOT
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
endif
# Check if SC exists via a verilator call (empty if not)
SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE)
ifneq ($(SYSTEMC_EXISTS),)
default: run
else
default: nosc
endif
run:
@echo "-- Verilator hello-world simple example"
@echo "-- VERILATE ----------------"
$(VERILATOR) -sc --exe top.v sc_main.cpp
@echo "-- COMPILE -----------------"
$(MAKE) -j 4 -C obj_dir -f Vtop.mk
@echo "-- RUN ---------------------"
obj_dir/Vtop
@echo "-- DONE --------------------"
@echo "Note: Once this example is understood, see examples/tracing_sc."
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
######################################################################
nosc:
@echo
@echo "%Skip: SYSTEMC_INCLUDE not in environment"
@echo "(If you have SystemC see the README, and rebuild Verilator)"
@echo
maintainer-copy::
clean mostlyclean distclean maintainer-clean::
-rm -rf obj_dir *.log *.dmp *.vpd core
+51
View File
@@ -0,0 +1,51 @@
// -*- SystemC -*-
// DESCRIPTION: Verilator Example: Top level main for invoking SystemC model
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2017 by Wilson Snyder.
//======================================================================
// SystemC global header
#include <systemc.h>
// Include common routines
#include <verilated.h>
// Include model header, generated from Verilating "top.v"
#include "Vtop.h"
int sc_main(int argc, char* argv[]) {
// See a similar example walkthrough in the verilator manpage.
// This is intended to be a minimal example. Before copying this to start a
// real project, it is better to start with a more complete example,
// e.g. examples/c_tracing.
// Prevent unused variable warnings
if (0 && argc && argv) {}
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
Vtop* top = new Vtop("top");
// Initialize SC model
#if (SYSTEMC_VERSION>=20070314)
sc_start(1,SC_NS);
#else
sc_start(1);
#endif
// Simulate until $finish
while (!Verilated::gotFinish()) {
#if (SYSTEMC_VERSION>=20070314)
sc_start(1,SC_NS);
#else
sc_start(1);
#endif
}
// Final model cleanup
top->final();
// Fin
return 0;
}
+12
View File
@@ -0,0 +1,12 @@
// DESCRIPTION: Verilator: Verilog example module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2017 by Wilson Snyder.
// See also the EXAMPLE section in the verilator manpage/document.
module top;
initial begin
$display("Hello World!");
$finish;
end
endmodule
+6
View File
@@ -0,0 +1,6 @@
*.dmp
*.log
*.csrc
*.vcd
obj_*
logs
+96
View File
@@ -0,0 +1,96 @@
######################################################################
#
# DESCRIPTION: Verilator Example: Small Makefile
#
# This calls the object directory makefile. That allows the objects to
# be placed in the "current directory" which simplifies the Makefile.
#
# 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.
#
######################################################################
# Check for sanity to avoid later confusion
ifneq ($(words $(CURDIR)),1)
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
endif
######################################################################
# Set up variables
# 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),)
VERILATOR = verilator
VERILATOR_COVERAGE = verilator_coverage
else
export VERILATOR_ROOT
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
endif
VERILATOR_FLAGS =
# Generate C++ in executable form
VERILATOR_FLAGS += -cc --exe
# Generate makefile dependencies (not shown as complicates the Makefile)
#VERILATOR_FLAGS += -MMD
# Optimize
VERILATOR_FLAGS += -O2 -x-assign 0
# Warn abount lint issues; may not want this on less solid designs
VERILATOR_FLAGS += -Wall
# Make waveforms
VERILATOR_FLAGS += --trace
# Check SystemVerilog assertions
VERILATOR_FLAGS += --assert
# Generate coverage analysis
VERILATOR_FLAGS += --coverage
# Run Verilator in debug mode
#VERILATOR_FLAGS += --debug
# Add this trace to get a backtrace in gdb
#VERILATOR_FLAGS += --gdbbt
######################################################################
default: run
run:
@echo
@echo "-- Verilator tracing example"
@echo
@echo "-- VERILATE ----------------"
$(VERILATOR) $(VERILATOR_FLAGS) -f input.vc top.v sim_main.cpp
@echo
@echo "-- COMPILE -----------------"
# To compile, we can either just do what Verilator asks,
# or call a submakefile where we can override the rules ourselves
# $(MAKE) -j 4 -C obj_dir -f Vtop.mk
$(MAKE) -j 4 -C obj_dir -f ../Makefile_obj
@echo
@echo "-- RUN ---------------------"
@mkdir -p logs
obj_dir/Vtop +trace
@echo
@echo "-- COVERAGE ----------------"
$(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
@echo
@echo "-- DONE --------------------"
@echo "To see waveforms, open vlt_dump.vcd in a waveform viewer"
@echo
######################################################################
# Other targets
show-config:
$(VERILATOR) -V
maintainer-copy::
clean mostlyclean distclean maintainer-clean::
-rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core
+58
View File
@@ -0,0 +1,58 @@
# -*- Makefile -*-
#######################################################################
#
# DESCRIPTION: Verilator Example: Makefile for inside object directory
#
# This is executed in the object directory, and called by ../Makefile
#
# 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.
#
#######################################################################
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
# Override some default compile flags
CPPFLAGS += -MMD -MP
CPPFLAGS += -DVL_DEBUG=1
# Turn on some more flags (when configured appropriately)
# For testing inside Verilator, "configure --enable-ccwarn" will do this
# automatically; otherwise you may want this unconditionally enabled
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
USER_CPPFLAGS_WALL += -W -Werror -Wall
endif
# See the benchmarking section of bin/verilator.
# Support class optimizations. This includes the tracing and symbol table.
# SystemC takes minutes to optimize, thus it is off by default.
OPT_SLOW =
# Fast path optimizations. Most time is spent in these classes.
OPT_FAST = -O2 -fstrict-aliasing
#OPT_FAST = -O
#OPT_FAST =
#######################################################################
# Linking final exe -- presumes have a sim_main.cpp
# Special compile rule
sim_main.o: sim_main.cpp $(VM_PREFIX).h
######################################################################
######################################################################
# Automatically understand dependencies
DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
include $(DEPS)
endif
+2
View File
@@ -0,0 +1,2 @@
// This file typically lists flags required by a large project, e.g. include directories
+librescan +libext+.v+.sv+.vh+.svh -y .
+124
View File
@@ -0,0 +1,124 @@
// DESCRIPTION: Verilator: Verilog example module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2017 by Wilson Snyder.
//======================================================================
// Include common routines
#include <verilated.h>
#include <sys/stat.h> // mkdir
// Include model header, generated from Verilating "top.v"
#include "Vtop.h"
// If "verilator --trace" is used, include the tracing class
#if VM_TRACE
# include <verilated_vcd_c.h>
#endif
// Current simulation time (64-bit unsigned)
vluint64_t main_time = 0;
// Called by $time in Verilog
double sc_time_stamp () {
return main_time; // Note does conversion to real, to match SystemC
}
int main(int argc, char** argv, char** env) {
// This is a more complicated example, please also see the simpler examples/hello_world_c.
// Prevent unused variable warnings
if (0 && argc && argv && env) {}
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
Verilated::commandArgs(argc, argv);
// Set debug level, 0 is off, 9 is highest presently used
Verilated::debug(0);
// Randomization reset policy
Verilated::randReset(2);
// 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 VM_TRACE
// 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
top->reset_l = !0;
top->fastclk = 0;
top->clk = 0;
top->in_small = 1;
top->in_quad = 0x1234;
top->in_wide[0] = 0x11111111;
top->in_wide[1] = 0x22222222;
top->in_wide[2] = 0x3;
// Simulate until $finish
while (!Verilated::gotFinish()) {
main_time++; // Time passes...
// Toggle clocks and such
top->fastclk = !top->fastclk;
if ((main_time % 10) == 3) {
top->clk = 1;
}
if ((main_time % 10) == 8) {
top->clk = 0;
}
if (main_time > 1 && main_time < 10) {
top->reset_l = !1; // Assert reset
} else {
top->reset_l = !0; // Deassert reset
}
// Assign some other inputs
top->in_quad += 0x12;
// 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",
main_time, top->clk, top->reset_l, top->in_quad,
top->out_quad, top->out_wide[2], top->out_wide[1], top->out_wide[0]);
}
// 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
exit(0);
}
+58
View File
@@ -0,0 +1,58 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2003 by Wilson Snyder.
// ======================================================================
module sub
(
input clk,
input fastclk,
input reset_l
);
// Example counter/flop
reg [31:0] count_f;
always_ff @ (posedge fastclk) begin
if (!reset_l) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
count_f <= 32'h0;
// End of automatics
end
else begin
count_f <= count_f + 1;
end
end
// Another example flop
reg [31:0] count_c;
always_ff @ (posedge clk) begin
if (!reset_l) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
count_c <= 32'h0;
// End of automatics
end
else begin
count_c <= count_c + 1;
if (count_c >= 3) begin
$display("[%0t] fastclk is %0d times faster than clk\n",
$time, count_f/count_c);
// This write is a magic value the Makefile uses to make sure the
// test completes successfully.
$write("*-* All Finished *-*\n");
$finish;
end
end
end
// An example assertion
always_ff @ (posedge clk) begin
AssertionExample: assert (!reset_l || count_c<100);
end
// And example coverage analysis
cover property (@(posedge clk) count_c==3);
endmodule
+42
View File
@@ -0,0 +1,42 @@
// DESCRIPTION: Verilator: Verilog example module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2003 by Wilson Snyder.
// ======================================================================
// This is intended to be a complex example of several features, please also
// see the simpler examples/hello_world_c.
module top
(
// Declare some signals so we can see how I/O works
input clk,
input fastclk,
input reset_l,
output [1:0] out_small,
output [39:0] out_quad,
output [69:0] out_wide,
input [1:0] in_small,
input [39:0] in_quad,
input [69:0] in_wide
);
// Connect up the outputs, using some trivial logic
wire [1:0] out_small = ~reset_l ? '0 : (in_small + 2'b1);
wire [39:0] out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
wire [69:0] out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
// And an example sub module. The submodule will print stuff.
sub sub (/*AUTOINST*/
// Inputs
.clk (clk),
.fastclk (fastclk),
.reset_l (reset_l));
// Print some stuff as an example
initial begin
$display("[%0t] Model running...\n", $time);
end
endmodule
+6
View File
@@ -0,0 +1,6 @@
*.dmp
*.log
*.csrc
*.vcd
obj_*
logs
+109
View File
@@ -0,0 +1,109 @@
######################################################################
#
# DESCRIPTION: Verilator Example: Small Makefile
#
# This calls the object directory makefile. That allows the objects to
# be placed in the "current directory" which simplifies the Makefile.
#
# 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.
#
######################################################################
# Check for sanity to avoid later confusion
ifneq ($(words $(CURDIR)),1)
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
endif
######################################################################
# Set up variables
# 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),)
VERILATOR = verilator
VERILATOR_COVERAGE = verilator_coverage
else
export VERILATOR_ROOT
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
endif
VERILATOR_FLAGS =
# Generate SystemC in executable form
VERILATOR_FLAGS += -sc --exe
# Generate makefile dependencies (not shown as complicates the Makefile)
#VERILATOR_FLAGS += -MMD
# Optimize
VERILATOR_FLAGS += -O2 -x-assign 0
# Warn abount lint issues; may not want this on less solid designs
VERILATOR_FLAGS += -Wall
# Make waveforms
VERILATOR_FLAGS += --trace
# Check SystemVerilog assertions
VERILATOR_FLAGS += --assert
# Generate coverage analysis
VERILATOR_FLAGS += --coverage
# Run Verilator in debug mode
#VERILATOR_FLAGS += --debug
# Add this trace to get a backtrace in gdb
#VERILATOR_FLAGS += --gdbbt
# Check if SC exists via a verilator call (empty if not)
SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE)
######################################################################
ifneq ($(SYSTEMC_EXISTS),)
default: run
else
default: nosc
endif
run:
@echo
@echo "-- Verilator tracing example"
@echo
@echo "-- VERILATE ----------------"
$(VERILATOR) $(VERILATOR_FLAGS) -f input.vc top.v sc_main.cpp
@echo
@echo "-- COMPILE ----------------="
# To compile, we can either just do what Verilator asks,
# or call a submakefile where we can override the rules ourselves
# $(MAKE) -j 4 -C obj_dir -f Vtop.mk
$(MAKE) -j 4 -C obj_dir -f ../Makefile_obj
@echo
@echo "-- RUN ---------------------"
@mkdir -p logs
obj_dir/Vtop +trace
@echo
@echo "-- COVERAGE ----------------"
$(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
@echo
@echo "-- DONE --------------------"
@echo "To see waveforms, open vlt_dump.vcd in a waveform viewer"
@echo
######################################################################
# Other targets
nosc:
@echo
@echo "%Skip: SYSTEMC_INCLUDE not in environment"
@echo "(If you have SystemC see the README, and rebuild Verilator)"
@echo
show-config:
$(VERILATOR) -V
maintainer-copy::
clean mostlyclean distclean maintainer-clean::
-rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core
+66
View File
@@ -0,0 +1,66 @@
# -*- Makefile -*-
#######################################################################
#
# DESCRIPTION: Verilator Example: Makefile for inside object directory
#
# This is executed in the object directory, and called by ../Makefile
#
# 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.
#
#######################################################################
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
# Override some default compile flags
CPPFLAGS += -MMD -MP
CPPFLAGS += -DVL_DEBUG=1
# SystemC isn't too clean
CPPFLAGS += -Wno-deprecated
# Turn on some more flags (when configured appropriately)
# For testing inside Verilator, "configure --enable-ccwarn" will do this
# automatically; otherwise you may want this unconditionally enabled
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
USER_CPPFLAGS_WALL += -W -Werror -Wall
endif
# If you build your own rules from scratch, note you need to include
# SystemC as follows (Vtop.mk file includes verilated.mk with these
# already).
# CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC_INCLUDE)
# LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC_LIBDIR)
# See the benchmarking section of bin/verilator.
# Support class optimizations. This includes the tracing and symbol table.
# SystemC takes minutes to optimize, thus it is off by default.
OPT_SLOW =
# Fast path optimizations. Most time is spent in these classes.
OPT_FAST = -O2 -fstrict-aliasing
#OPT_FAST = -O
#OPT_FAST =
#######################################################################
# Linking final exe -- presumes have a sim_main.cpp
# Special compile rule
sim_main.o: sim_main.cpp $(VM_PREFIX).h
######################################################################
######################################################################
# Automatically understand dependencies
DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
include $(DEPS)
endif
+2
View File
@@ -0,0 +1,2 @@
// This file typically lists flags required by a large project, e.g. include directories
+librescan +libext+.v+.sv+.vh+.svh -y .
+146
View File
@@ -0,0 +1,146 @@
// -*- SystemC -*-
// DESCRIPTION: Verilator Example: Top level main for invoking SystemC model
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2017 by Wilson Snyder.
//======================================================================
// SystemC global header
#include <systemc.h>
// Include common routines
#include <verilated.h>
#if VM_TRACE
#include <verilated_vcd_sc.h>
#endif
#include <sys/stat.h> // mkdir
// Include model header, generated from Verilating "top.v"
#include "Vtop.h"
int sc_main(int argc, char* argv[]) {
// This is a more complicated example, please also see the simpler examples/hello_world_c.
// Prevent unused variable warnings
if (0 && argc && argv) {}
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
Verilated::commandArgs(argc, argv);
// Set debug level, 0 is off, 9 is highest presently used
Verilated::debug(0);
// Randomization reset policy
Verilated::randReset(2);
// General logfile
ios::sync_with_stdio();
// Defaults time
#if (SYSTEMC_VERSION>20011000)
#else
sc_time dut(1.0, sc_ns);
sc_set_default_time_unit(dut);
#endif
// Define clocks
#if (SYSTEMC_VERSION>=20070314)
sc_clock clk ("clk", 10,SC_NS, 0.5, 3,SC_NS, true);
sc_clock fastclk ("fastclk", 2,SC_NS, 0.5, 2,SC_NS, true);
#else
sc_clock clk ("clk", 10, 0.5, 3, true);
sc_clock fastclk ("fastclk", 2, 0.5, 2, true);
#endif
// Define interconnect
sc_signal<bool> reset_l;
sc_signal<vluint32_t> in_small;
sc_signal<vluint64_t> in_quad;
sc_signal<sc_bv<70> > in_wide;
sc_signal<vluint32_t> out_small;
sc_signal<vluint64_t> out_quad;
sc_signal<sc_bv<70> > out_wide;
// Construct the Verilated model, from inside Vtop.h
Vtop* top = new Vtop("top");
// Attach signals to the model
top->clk (clk);
top->fastclk (fastclk);
top->reset_l (reset_l);
top->in_small (in_small);
top->in_quad (in_quad);
top->in_wide (in_wide);
top->out_small (out_small);
top->out_quad (out_quad);
top->out_wide (out_wide);
#if VM_TRACE
// Before any evaluation, need to know to calculate those signals only used for tracing
Verilated::traceEverOn(true);
#endif
// You must do one evaluation before enabling waves, in order to allow
// SystemC to interconnect everything for testing.
#if (SYSTEMC_VERSION>=20070314)
sc_start(1,SC_NS);
#else
sc_start(1);
#endif
#if VM_TRACE
// 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
while (!Verilated::gotFinish()) {
#if VM_TRACE
// 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
}
// Simulate 1ns
#if (SYSTEMC_VERSION>=20070314)
sc_start(1,SC_NS);
#else
sc_start(1);
#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;
}
+58
View File
@@ -0,0 +1,58 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2003 by Wilson Snyder.
// ======================================================================
module sub
(
input clk,
input fastclk,
input reset_l
);
// Example counter/flop
reg [31:0] count_f;
always_ff @ (posedge fastclk) begin
if (!reset_l) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
count_f <= 32'h0;
// End of automatics
end
else begin
count_f <= count_f + 1;
end
end
// Another example flop
reg [31:0] count_c;
always_ff @ (posedge clk) begin
if (!reset_l) begin
/*AUTORESET*/
// Beginning of autoreset for uninitialized flops
count_c <= 32'h0;
// End of automatics
end
else begin
count_c <= count_c + 1;
if (count_c >= 3) begin
$display("[%0t] fastclk is %0d times faster than clk\n",
$time, count_f/count_c);
// This write is a magic value the Makefile uses to make sure the
// test completes successfully.
$write("*-* All Finished *-*\n");
$finish;
end
end
end
// An example assertion
always_ff @ (posedge clk) begin
AssertionExample: assert (!reset_l || count_c<100);
end
// And example coverage analysis
cover property (@(posedge clk) count_c==3);
endmodule
+42
View File
@@ -0,0 +1,42 @@
// DESCRIPTION: Verilator: Verilog example module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2003 by Wilson Snyder.
// ======================================================================
// This is intended to be a complex example of several features, please also
// see the simpler examples/hello_world_c.
module top
(
// Declare some signals so we can see how I/O works
input clk,
input fastclk,
input reset_l,
output [1:0] out_small,
output [39:0] out_quad,
output [69:0] out_wide,
input [1:0] in_small,
input [39:0] in_quad,
input [69:0] in_wide
);
// Connect up the outputs, using some trivial logic
wire [1:0] out_small = ~reset_l ? '0 : (in_small + 2'b1);
wire [39:0] out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
wire [69:0] out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
// And an example sub module. The submodule will print stuff.
sub sub (/*AUTOINST*/
// Inputs
.clk (clk),
.fastclk (fastclk),
.reset_l (reset_l));
// Print some stuff as an example
initial begin
$display("[%0t] Model running...\n", $time);
end
endmodule
+1004 -326
View File
File diff suppressed because it is too large Load Diff
+801 -412
View File
File diff suppressed because it is too large Load Diff
+36 -38
View File
@@ -2,7 +2,7 @@
######################################################################
# DESCRIPTION: Makefile commands for all verilated target files
#
# Copyright 2003-2014 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.
######################################################################
@@ -16,13 +16,18 @@ RANLIB = ranlib
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
# Select newest language
CFG_CXXFLAGS_STD_NEWEST = @CFG_CXXFLAGS_STD_NEWEST@
# Select oldest language (for Verilator internal testing only)
CFG_CXXFLAGS_STD_OLDEST = @CFG_CXXFLAGS_STD_OLDEST@
# Compiler flags to use to turn off unused and generated code warnings, such as -Wno-div-by-zero
CFG_CXXFLAGS_NO_UNUSED = @CFG_CXXFLAGS_NO_UNUSED@
# Compiler flags that turn on extra warnings
CFG_CXXFLAGS_WEXTRA = @CFG_CXXFLAGS_WEXTRA@
######################################################################
# Programs
SP_PREPROC = sp_preproc
SP_INCLUDER = $(VERILATOR_INCLUDER)
VERILATOR_COVERAGE = $(PERL) $(VERILATOR_ROOT)/bin/verilator_coverage
VERILATOR_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
@@ -43,13 +48,13 @@ VK_CPPFLAGS_ALWAYS += \
-I$(VERILATOR_ROOT)/include \
-I$(VERILATOR_ROOT)/include/vltstd \
-DVL_PRINTF=printf \
-DVM_TRACE=$(VM_TRACE) \
-DVM_COVERAGE=$(VM_COVERAGE) \
-DVM_SC=$(VM_SC) \
-DVM_TRACE=$(VM_TRACE) \
$(CFG_CXXFLAGS_NO_UNUSED) \
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
VK_CPPFLAGS_WALL += -Wall \
-Werror
VK_CPPFLAGS_WALL += -Wall $(CFG_CXXFLAGS_WEXTRA) -Werror
endif
CPPFLAGS += -I. $(VK_CPPFLAGS_WALL) $(VK_CPPFLAGS_ALWAYS)
@@ -92,9 +97,9 @@ VM_CLASSES += $(VM_CLASSES_FAST) $(VM_CLASSES_SLOW)
VM_SUPPORT += $(VM_SUPPORT_FAST) $(VM_SUPPORT_SLOW)
#######################################################################
##### SystemC or SystemPerl builds
##### SystemC builds
ifeq ($(VM_SP_OR_SC),1)
ifeq ($(VM_SC),1)
CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC_INCLUDE)
LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC_LIBDIR)
SC_LIBS = -lsystemc
@@ -105,41 +110,24 @@ ifeq ($(VM_SP_OR_SC),1)
endif
#######################################################################
##### SystemPerl builds
##### Threaded builds
ifeq ($(VM_SP),1)
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE) -DSYSTEMPERL
VPATH += $(SYSTEMPERL_INCLUDE)
LIBS += -lm -lstdc++
VK_CLASSES_SP = $(addsuffix .sp, $(VM_CLASSES))
# This rule is called manually by the upper level makefile
preproc:
@echo " SP Preprocess" $(basename $(VM_CLASSES)) ...
$(SP_PREPROC) -M sp_preproc.d --tree $(VM_PREFIX).sp_tree \
--preproc $(VK_CLASSES_SP)
else
ifeq ($(VM_COVERAGE),1)
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE)
VPATH += $(SYSTEMPERL_INCLUDE)
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
preproc:
endif
#######################################################################
##### SystemC w/o SystemPerl builds
##### Stub
ifeq ($(VM_SC),1)
LIBS += -lm -lstdc++
endif
preproc:
#######################################################################
##### C/H builds
ifeq ($(VM_PCLI),1)
LIBS += -lm -lstdc++
endif
LIBS += -lm -lstdc++
#######################################################################
# Overall Objects Linking
@@ -153,7 +141,7 @@ VK_USER_OBJS = $(addsuffix .o, $(VM_USER_CLASSES))
VK_GLOBAL_OBJS = $(addsuffix .o, $(VM_GLOBAL_FAST) $(VM_GLOBAL_SLOW))
ifneq ($(VM_PARALLEL_BUILDS),0)
ifneq ($(VM_PARALLEL_BUILDS),1)
# Fast building, all .cpp's in one fell swoop
# This saves about 5 sec per module, but can be slower if only a little changes
VK_OBJS += $(VM_PREFIX)__ALLcls.o $(VM_PREFIX)__ALLsup.o
@@ -175,29 +163,39 @@ $(VM_PREFIX)__ALL.a: $(VK_OBJS)
######################################################################
### Compile rules
#Default rule embedded in make: (Not defined so user makefiles can override it)
#.cpp.o:
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
ifneq ($(VM_DEFAULT_RULES),0)
$(VM_PREFIX)__ALLsup.o: $(VM_PREFIX)__ALLsup.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $<
$(VM_PREFIX)__ALLcls.o: $(VM_PREFIX)__ALLcls.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
$(VM_PREFIX)%__Slow.o: $(VM_PREFIX)%__Slow.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $<
$(VM_PREFIX)%.o: $(VM_PREFIX)%.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
endif
#Default rule embedded in make:
#.cpp.o:
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
######################################################################
### Debugging
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-2014 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-2014 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.
+117 -96
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2014 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,8 +17,6 @@
/// \file
/// \brief Verilator coverage analysis
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
#include "verilatedos.h"
@@ -52,7 +50,10 @@ public: // But only local to this file
// CONSTRUCTORS
// Derived classes should call zero() in their constructor
VerilatedCovImpItem() {
for (int i=0; i<MAX_KEYS; i++) m_keys[i]=KEY_UNDEF;
for (int i=0; i<MAX_KEYS; ++i) {
m_keys[i]=KEY_UNDEF;
m_vals[i]=0;
}
}
virtual ~VerilatedCovImpItem() {}
virtual vluint64_t count() const = 0;
@@ -71,9 +72,11 @@ private:
T* m_countp; ///< Count value
public:
// METHODS
// cppcheck-suppress truncLongCastReturn
virtual vluint64_t count() const { return *m_countp; }
virtual void zero() const { *m_countp = 0; }
// CONSTRUCTORS
// cppcheck-suppress noExplicitConstructor
VerilatedCoverItemSpec(T* countp) : m_countp(countp) { zero(); }
virtual ~VerilatedCoverItemSpec() {}
};
@@ -87,19 +90,20 @@ public:
class VerilatedCovImp : VerilatedCovImpBase {
private:
// TYPES
typedef map<string,int> ValueIndexMap;
typedef map<int,string> IndexValueMap;
typedef deque<VerilatedCovImpItem*> ItemList;
typedef std::map<std::string,int> ValueIndexMap;
typedef std::map<int,std::string> IndexValueMap;
typedef std::deque<VerilatedCovImpItem*> ItemList;
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() {
@@ -107,28 +111,29 @@ 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 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;
nextIndex++; assert(nextIndex>0);
m_valueIndexes.insert(make_pair(value, nextIndex));
m_indexValues.insert(make_pair(nextIndex, value));
m_valueIndexes.insert(std::make_pair(value, nextIndex));
m_indexValues.insert(std::make_pair(nextIndex, value));
return nextIndex;
}
string dequote(const string& text) {
static std::string dequote(const std::string& text) VL_PURE {
// Quote any special characters
string rtn;
for (const char* pos = text.c_str(); *pos; pos++) {
std::string rtn;
for (const char* pos = text.c_str(); *pos; ++pos) {
if (!isprint(*pos) || *pos=='%' || *pos=='"') {
char hex[10]; sprintf(hex,"%%%02X",pos[0]);
rtn += hex;
@@ -138,7 +143,7 @@ private:
}
return rtn;
}
bool legalKey(const 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...
@@ -147,17 +152,17 @@ private:
if (key.length()==2 && isdigit(key[1])) return false;
return true;
}
string keyValueFormatter (const string& key, const string& value) {
string name;
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 += string("\001")+key;
name += std::string("\001")+key;
} else {
name += string("\001")+dequote(key);
name += std::string("\001")+dequote(key);
}
name += string("\002")+dequote(value);
name += std::string("\002")+dequote(value);
return name;
}
string combineHier (const string& old, const 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.*
@@ -175,7 +180,7 @@ private:
// We used to backup and split on only .'s but it seems better to be verbose
// and not assume . is the separator
string prefix = string(a,apre-a);
std::string prefix = std::string(a,apre-a);
// Scan backward to last mismatch
const char* apost = a+strlen(a)-1;
@@ -184,41 +189,38 @@ private:
&& apost>apre && bpost>bpre) { apost--; bpost--; }
// Forward to . so we have a whole word
string suffix = *bpost ? string(bpost+1) : "";
std::string suffix = *bpost ? std::string(bpost+1) : "";
string out = prefix+"*"+suffix;
std::string out = prefix+"*"+suffix;
//cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add<<"\nch o="<<out<<endl;
return out;
}
bool itemMatchesString(VerilatedCovImpItem* itemp, const string& match) {
for (int i=0; i<MAX_KEYS; i++) {
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
string val = m_indexValues[itemp->m_vals[i]];
if (string::npos != val.find(match)) { // Found
std::string val = m_indexValues[itemp->m_vals[i]];
if (std::string::npos != val.find(match)) { // Found
return true;
}
}
}
return false;
}
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() {
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
void clearGuts() VL_REQUIRES(m_mutex) {
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
VerilatedCovImpItem* itemp = *(it);
delete itemp;
}
@@ -226,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) {
@@ -240,47 +252,52 @@ public:
m_items = newlist;
}
}
void zero() {
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
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;
VlCovCvtToCStr linestrp (m_insertLineno);
ckeyps[1]="lineno"; valps[1]=linestrp;
std::string linestr = vlCovCvtToStr(m_insertLineno);
ckeyps[1]="lineno"; valps[1]=linestr.c_str();
// Default page if not specified
const char* fnstartp = m_insertFilenamep;
while (const char* foundp = strchr(fnstartp,'/')) fnstartp=foundp+1;
const char* fnendp = fnstartp;
while (*fnendp && *fnendp!='.') fnendp++;
string page_default = "sp_user/"+string(fnstartp,fnendp-fnstartp);
std::string page_default = "sp_user/"+std::string(fnstartp,fnendp-fnstartp);
ckeyps[2]="page"; valps[2]=page_default.c_str();
// Keys -> strings
string keys[MAX_KEYS];
for (int i=0; i<MAX_KEYS; i++) {
std::string keys[MAX_KEYS];
for (int i=0; i<MAX_KEYS; ++i) {
if (ckeyps[i] && ckeyps[i][0]) {
keys[i] = ckeyps[i];
}
}
// Ignore empty keys
for (int i=0; i<MAX_KEYS; i++) {
for (int i=0; i<MAX_KEYS; ++i) {
if (keys[i]!="") {
for (int j=i+1; j<MAX_KEYS; j++) {
for (int j=i+1; j<MAX_KEYS; ++j) {
if (keys[i] == keys[j]) { // Duplicate key. Keep the last one
keys[i] = "";
break;
@@ -290,17 +307,17 @@ public:
}
// Insert the values
int addKeynum=0;
for (int i=0; i<MAX_KEYS; i++) {
const string key = keys[i];
for (int i=0; i<MAX_KEYS; ++i) {
const std::string key = keys[i];
if (keys[i]!="") {
const string val = valps[i];
const std::string val = valps[i];
//cout<<" "<<__FUNCTION__<<" "<<key<<" = "<<val<<endl;
m_insertp->m_keys[addKeynum] = valueIndex(key);
m_insertp->m_vals[addKeynum] = valueIndex(val);
addKeynum++;
if (!legalKey(key)) {
string msg = "%Error: Coverage keys of one character, or letter+digit are illegal: "+key;
vl_fatal("",0,"",msg.c_str());
std::string msg = "%Error: Coverage keys of one character, or letter+digit are illegal: "+key;
VL_FATAL_MT("",0,"",msg.c_str());
}
}
}
@@ -309,33 +326,35 @@ 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();
ofstream os (filename);
std::ofstream os (filename);
if (os.fail()) {
string msg = (string)"%Error: Can't write '"+filename+"'";
vl_fatal("",0,"",msg.c_str());
std::string msg = std::string("%Error: Can't write '")+filename+"'";
VL_FATAL_MT("",0,"",msg.c_str());
return;
}
os << "# SystemC::Coverage-3\n";
// Build list of events; totalize if collapsing hierarchy
typedef map<string,pair<string,vluint64_t> > EventMap;
EventMap eventCounts;
typedef std::map<std::string,std::pair<std::string,vluint64_t> > EventMap;
EventMap eventCounts;
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
VerilatedCovImpItem* itemp = *(it);
string name;
string hier;
std::string name;
std::string hier;
bool per_instance = false;
for (int i=0; i<MAX_KEYS; i++) {
for (int i=0; i<MAX_KEYS; ++i) {
if (itemp->m_keys[i] != KEY_UNDEF) {
string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
string val = m_indexValues[itemp->m_vals[i]];
std::string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
std::string val = m_indexValues[itemp->m_vals[i]];
if (key == VL_CIK_PER_INSTANCE) {
if (val != "0") per_instance = true;
}
@@ -360,21 +379,21 @@ public:
// Find or insert the named event
EventMap::iterator cit = eventCounts.find(name);
if (cit != eventCounts.end()) {
const string& oldhier = cit->second.first;
const std::string& oldhier = cit->second.first;
cit->second.second += itemp->count();
cit->second.first = combineHier(oldhier, hier);
} else {
eventCounts.insert(make_pair(name, make_pair(hier,itemp->count())));
eventCounts.insert(std::make_pair(name, make_pair(hier,itemp->count())));
}
}
// Output body
for (EventMap::iterator it=eventCounts.begin(); it!=eventCounts.end(); ++it) {
os<<"C '"<<dec;
for (EventMap::const_iterator it=eventCounts.begin(); it!=eventCounts.end(); ++it) {
os<<"C '"<<std::dec;
os<<it->first;
if (it->second.first != "") os<<keyValueFormatter(VL_CIK_HIER,it->second.first);
os<<"' "<<it->second.second;
os<<endl;
os<<std::endl;
}
}
};
@@ -382,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);
}
@@ -410,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,
@@ -425,22 +444,24 @@ 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 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),
key2,VlCovCvtToCStr(val2), key3,VlCovCvtToCStr(val3), key4, val4.c_str(),
key2,val2str.c_str(), key3,val3str.c_str(), key4, val4.c_str(),
C(5),C(6),N(7),N(8),N(9),
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
+16 -30
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2014 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,8 +17,6 @@
/// \file
/// \brief Coverage analysis support
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
#ifndef _VERILATED_COV_H_
@@ -29,7 +27,6 @@
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
//=============================================================================
/// Conditionally compile coverage code
@@ -62,9 +59,9 @@ using namespace std;
///
/// vluint32_t m_cases[10];
/// constructor {
/// for (int i=0; i<10; i++) { m_cases[i]=0; }
/// for (int i=0; i<10; ++i) { m_cases[i]=0; }
/// }
/// for (int i=0; i<10; i++) {
/// for (int i=0; i<10; ++i) {
/// VL_COVER_INSERT(&m_cases[i], "comment", "Coverage Case", "i", cvtToNumStr(i));
/// }
@@ -76,45 +73,34 @@ using namespace std;
//=============================================================================
/// Convert VL_COVER_INSERT value arguments to strings
template< class T> std::string vlCovCvtToStr (const T& t) {
ostringstream os; os<<t; return os.str();
template< class T> std::string vlCovCvtToStr (const T& t) VL_PURE {
std::ostringstream os; os<<t; return os.str();
}
/// Usage: something(VlCovCvtToCStr(i))
/// Note the pointer will only be valid for as long as the object remains
/// in scope!
struct VlCovCvtToCStr {
string m_str;
// Casters
template< class T> VlCovCvtToCStr (const T& t) {
ostringstream os; os<<t; m_str=os.str();
}
~VlCovCvtToCStr() {}
operator const char* () const { return m_str.c_str(); };
};
//=============================================================================
// VerilatedCov
/// 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
@@ -130,17 +116,17 @@ public:
,A(20),D(21),D(22),D(23),D(24),D(25),D(26),D(27),D(28),D(29));
// Backward compatibility for Verilator
static void _insertp (A(0), A(1), K(2),int val2, K(3),int val3,
K(4),const string& val4, A(5),A(6));
K(4),const std::string& val4, A(5),A(6));
#undef K
#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 -44
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2014 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,8 +17,6 @@
/// \file
/// \brief Coverage item keys
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
#ifndef _VERILATED_COV_KEY_H_
@@ -27,7 +25,6 @@
#include "verilatedos.h"
#include <string>
using namespace std;
//=============================================================================
// Data used to edit below file, using vlcovgen
@@ -66,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"
@@ -105,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 string shortKey(const 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;
}
};
+572 -108
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2014 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
///
@@ -30,7 +30,9 @@
// On MSVC++ we need svdpi.h to declare exports, not imports
#define DPI_PROTOTYPES
#undef XXTERN
#define XXTERN DPI_EXTERN DPI_DLLESPEC
#undef EETERN
#define EETERN DPI_EXTERN DPI_DLLESPEC
#include "vltstd/svdpi.h"
@@ -40,11 +42,14 @@
// Not supported yet
#define _VL_SVDPI_UNIMP() \
vl_fatal(__FILE__,__LINE__,"",(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");
//======================================================================
//======================================================================
@@ -58,197 +63,656 @@ const char* svDpiVersion() {
//======================================================================
// Bit-select utility functions.
svBit svGetBitselBit(const svBitVecVal* s, int i) {
_VL_SVDPI_UNIMP(); return 0;
svBit svGetBitselBit(const svBitVecVal* sp, int bit) {
return VL_BITRSHIFT_W(sp,bit) & 1;
}
svLogic svGetBitselLogic(const svLogicVecVal* s, int i) {
_VL_SVDPI_UNIMP(); return 0;
svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) {
// 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* d, int i, svBit s) {
_VL_SVDPI_UNIMP();
void svPutBitselBit(svBitVecVal* dp, int bit, svBit s) {
VL_ASSIGNBIT_WI(32, bit, dp, s);
}
void svPutBitselLogic(svLogicVecVal* d, int i, svLogic s) {
_VL_SVDPI_UNIMP();
void svPutBitselLogic(svLogicVecVal* dp, int bit, svLogic s) {
// 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* d, const svBitVecVal* s, 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* d, const svLogicVecVal* s, 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* d, const svBitVecVal s, int i, int w) {
_VL_SVDPI_UNIMP();
}
void svPutPartselLogic(svLogicVecVal* d, const svLogicVecVal s, 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);
}
//======================================================================
@@ -261,13 +725,13 @@ svScope svGetScope() {
svScope svSetScope(const svScope scope) {
const VerilatedScope* prevScopep = Verilated::dpiScope();
const VerilatedScope* vscopep = (const VerilatedScope*)(scope);
const VerilatedScope* vscopep = reinterpret_cast<const VerilatedScope*>(scope);
Verilated::dpiScope(vscopep);
return (svScope)prevScopep;
}
const char* svGetNameFromScope(const svScope scope) {
const VerilatedScope* vscopep = (const VerilatedScope*)(scope);
const VerilatedScope* vscopep = reinterpret_cast<const VerilatedScope*>(scope);
return vscopep->name();
}
@@ -275,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;
}
+36 -19
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2014 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,9 @@
/// \file
/// \brief Verilator: Common include for all Verilated C files that use DPI
///
/// This file is included automatically by Verilator at the top of
/// all C++ files it generates where DPI is used. It contains
/// DPI interface functions required by the Verilated code.
/// This file is included automatically by Verilator at the top of
/// all C++ files it generates where DPI is used. It contains
/// DPI interface functions required by the Verilated code.
///
/// Code available from: http://www.veripool.org/verilator
///
@@ -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];
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) {
/// 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];
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
int words = VL_WORDS_I(obits);
for (int i=0; i<words-1; i++) owp[i]=lwp[i].aval;
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];
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;
}
//======================================================================
+43 -18
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2010-2014 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.
@@ -16,10 +16,10 @@
/// \file
/// \brief Verilator: String include for all Verilated C files
///
/// This file is included automatically by Verilator at the top of
/// all C++ files it generates. It is used when strings or other
/// heavyweight types are required; these contents are not part of
/// verilated.h to save compile time when such types aren't used.
/// This file is included automatically by Verilator at the top of
/// all C++ files it generates. It is used when strings or other
/// heavyweight types are required; these contents are not part of
/// verilated.h to save compile time when such types aren't used.
///
/// Code available from: http://www.veripool.org/verilator
///
@@ -36,31 +36,56 @@
//======================================================================
// Conversion functions
extern string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp);
inline string VL_CVT_PACK_STR_NQ(QData lhs) {
IData lw[2]; VL_SET_WQ(lw, 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 string VL_CVT_PACK_STR_NQ(const string& lhs) {
inline std::string VL_CVT_PACK_STR_NN(const std::string& lhs) VL_PURE {
return lhs;
}
inline string VL_CVT_PACK_STR_NI(IData lhs) {
IData lw[1]; lw[0] = 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 string VL_CONCATN_NNN(const string& lhs, const string& rhs) {
inline std::string VL_CONCATN_NNN(const std::string& lhs, const std::string& rhs) VL_PURE {
return lhs+rhs;
}
inline string VL_REPLICATEN_NNQ(int,int,int rbits, const string& lhs, IData rep) {
string out; out.reserve(lhs.length() * rep);
for (unsigned times=0; times<rep; times++) out += lhs;
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 string VL_REPLICATEN_NNI(int obits,int lbits,int rbits, const 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 void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...);
extern string VL_SFORMATF_NX(const char* formatp, ...);
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) 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) VL_MT_SAFE;
#endif // Guard
+223 -75
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2014 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,105 +34,235 @@
#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.
// TYPES
typedef vector<string> ArgVec;
typedef map<pair<const void*,void*>,void*> UserMap;
typedef map<const char*, const VerilatedScope*, VerilatedCStrCmp> ScopeNameMap;
typedef map<const char*, int, VerilatedCStrCmp> ExportNameMap;
typedef std::vector<std::string> ArgVec;
typedef std::map<std::pair<const void*,void*>,void*> UserMap;
typedef std::map<const char*, int, VerilatedCStrCmp> ExportNameMap;
// MEMBERS
static VerilatedImp s_s; ///< Static Singleton; One and only static this
// 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>
ScopeNameMap 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
vector<FILE*> m_fdps; ///< File descriptors
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::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();
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 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::iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
for (ArgVec::const_iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
if ((*it)[0]=='+') {
if (0==strncmp(prefixp, it->c_str()+1, len)) return *it;
}
}
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) {
UserMap::iterator it=s_s.m_userMap.find(make_pair(scopep,userKey));
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, make_pair(make_pair(scopep,userKey),userData));
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) {
UserMap::iterator it=s_s.m_userMap.find(make_pair(scopep,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++);
@@ -141,42 +271,51 @@ 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::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",
for (UserMap::const_iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) {
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
ScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
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, make_pair(scopep->name(),scopep));
s_s.m_nameMap.insert(it, std::make_pair(scopep->name(),scopep));
}
}
static inline const VerilatedScope* scopeFind(const char* namep) {
ScopeNameMap::iterator it=s_s.m_nameMap.find(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);
ScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
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");
for (ScopeNameMap::iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) {
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() VL_MT_SAFE_POSTINIT {
// Thread save only assuming this is called only after model construction completed
return &s_s.m_nameMap;
}
public: // But only for verilated*.cpp
@@ -188,36 +327,40 @@ 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, make_pair(namep, s_s.m_exportNext++));
s_s.m_exportMap.insert(it, std::make_pair(namep, s_s.m_exportNext++));
return s_s.m_exportNext++;
} else {
return it->second;
}
}
static int exportFind(const char* namep) {
ExportNameMap::iterator it=s_s.m_exportMap.find(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;
string msg = (string("%Error: Testbench C called ")+namep
+" but no such DPI export function name exists in ANY model");
vl_fatal("unknown",0,"", msg.c_str());
std::string msg = (std::string("%Error: Testbench C called ")+namep
+" but no such DPI export function name exists in ANY model");
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
for (ExportNameMap::iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++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::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);
for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
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
@@ -225,31 +368,36 @@ 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();
s_s.m_fdps.resize(start*2);
for (size_t i=start; i<start*2; i++) s_s.m_fdFree.push_back((IData)i);
for (size_t i=start; i<start*2; ++i) s_s.m_fdFree.push_back(static_cast<IData>(i));
}
IData idx = s_s.m_fdFree.back(); s_s.m_fdFree.pop_back();
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
+36 -34
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2014 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,8 +17,6 @@
/// \file
/// \brief C++ Tracing in VCD Format
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
#include "verilatedos.h"
@@ -42,15 +40,15 @@
#endif
// CONSTANTS
static const char* VLTSAVE_HEADER_STR = "verilatorsave01\n"; ///< Value of first bytes of each file
static const char* VLTSAVE_TRAILER_STR = "vltsaved"; ///< Value of last bytes of each file
static const char* const VLTSAVE_HEADER_STR = "verilatorsave01\n"; ///< Value of first bytes of each file
static const char* const VLTSAVE_TRAILER_STR = "vltsaved"; ///< Value of last bytes of each file
//=============================================================================
//=============================================================================
//=============================================================================
// 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;
@@ -60,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))) {
string fn = filename();
string msg = (string)"Can't deserialize save-restore file as was made from different model";
vl_fatal(fn.c_str(), 0, "", msg.c_str());
std::string fn = filename();
std::string msg = std::string("Can't deserialize save-restore file as was made from different model");
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));
@@ -80,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)))) {
string fn = filename();
string msg = (string)"Can't deserialize; file has wrong header signature";
vl_fatal(fn.c_str(), 0, "", msg.c_str());
std::string fn = filename();
std::string msg = std::string("Can't deserialize; file has wrong header signature");
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)))) {
string fn = filename();
string msg = (string)"Can't deserialize; file has wrong end-of-file signature";
vl_fatal(fn.c_str(), 0, "", msg.c_str());
std::string fn = filename();
std::string msg = std::string("Can't deserialize; file has wrong end-of-file signature");
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
close();
}
}
@@ -112,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.
@@ -134,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.
@@ -157,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();
@@ -165,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();
@@ -176,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) {
@@ -189,8 +190,8 @@ void VerilatedSave::flush() {
} else if (got < 0) {
if (errno != EAGAIN && errno != EINTR) {
// write failed, presume error (perhaps out of disk space)
string msg = string(__FUNCTION__)+": "+strerror(errno);
vl_fatal("",0,"",msg.c_str());
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
VL_FATAL_MT("",0,"",msg.c_str());
close();
break;
}
@@ -199,14 +200,15 @@ 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;
for (vluint8_t* sp=m_cp; rp < m_endp;) *rp++ = *sp++; // Overlaps
for (vluint8_t* sp=m_cp; sp < m_endp;) *rp++ = *sp++; // Overlaps
m_endp = m_bufp + (m_endp - m_cp);
m_cp = m_bufp; // Reset buffer
// Read into buffer starting at m_endp
// Read into buffer starting at m_endp
while (1) {
ssize_t remaining = (m_bufp+bufferSize() - m_endp);
if (remaining==0) break;
@@ -217,8 +219,8 @@ void VerilatedRestore::fill() {
} else if (got < 0) {
if (errno != EAGAIN && errno != EINTR) {
// write failed, presume error (perhaps out of disk space)
string msg = string(__FUNCTION__)+": "+strerror(errno);
vl_fatal("",0,"",msg.c_str());
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
VL_FATAL_MT("",0,"",msg.c_str());
close();
break;
}
+82 -65
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2012-2014 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.
//
@@ -17,8 +17,6 @@
/// \file
/// \brief Save-restore serialization of verilated modules
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
#ifndef _VERILATED_SAVE_C_H_
@@ -27,65 +25,45 @@
#include "verilatedos.h"
#include <string>
using namespace std;
//=============================================================================
// VerilatedSerialBase - internal base class for common code between VerilatedSerialize and VerilatedDeserialize
// VerilatedSerialize - convert structures to a stream representation
// This class is not thread safe, it must be called by a single thread
class VerilatedSerialBase {
class VerilatedSerialize {
protected:
// MEMBERS
// For speed, keep m_cp as the first member of this structure
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
vluint8_t* m_bufp; ///< Output buffer
bool m_isOpen; ///< True indicates open file/stream
string m_filename;
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; }
// CREATORS
VerilatedSerialBase() {
void header() VL_MT_UNSAFE_ONE;
void trailer() VL_MT_UNSAFE_ONE;
// CONSTRUCTORS
VL_UNCOPYABLE(VerilatedSerialize);
public:
VerilatedSerialize() {
m_isOpen = false;
m_bufp = new vluint8_t [bufferSize()];
m_cp = m_bufp;
}
public:
// CREATORS
virtual ~VerilatedSerialBase() {
virtual ~VerilatedSerialize() {
close();
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
}
// METHODS
bool isOpen() const { return m_isOpen; }
string filename() const { return m_filename; }
virtual void close() { flush(); }
virtual void flush() {}
};
//=============================================================================
// VerilatedSerialize - convert structures to a stream representation
class VerilatedSerialize : public VerilatedSerialBase {
protected:
virtual void close() { flush(); }
virtual void flush() {}
void header();
void trailer();
public:
// CREATORS
VerilatedSerialize() {}
virtual ~VerilatedSerialize() { close(); }
// METHODS
VerilatedSerialize& bufferCheck() {
// Flush the write buffer if there's not enough space left for new information
// We only call this once per vector, so we need enough slop for a very wide "b###" line
if (VL_UNLIKELY(m_cp > (m_bufp+(bufferSize()-bufferInsertSize())))) {
flush();
}
return *this; // For function chaining
}
inline VerilatedSerialize& write (const void* __restrict datap, size_t size) {
std::string filename() const { return m_filename; }
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();
@@ -96,23 +74,58 @@ public:
}
return *this; // For function chaining
}
private:
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())))) {
flush();
}
return *this; // For function chaining
}
};
//=============================================================================
// VerilatedDeserial - load structures from a stream representation
// This class is not thread safe, it must be called by a single thread
class VerilatedDeserialize : public VerilatedSerialBase {
class VerilatedDeserialize {
protected:
// MEMBERS
// For speed, keep m_cp as the first member of this structure
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
vluint8_t* m_bufp; ///< Output buffer
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_endp = NULL; }
virtual ~VerilatedDeserialize() { close(); }
VerilatedDeserialize() {
m_isOpen = false;
m_bufp = new vluint8_t [bufferSize()];
m_cp = m_bufp;
m_endp = NULL;
}
virtual ~VerilatedDeserialize() {
close();
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
}
// METHODS
inline VerilatedDeserialize& read (void* __restrict datap, size_t size) {
bool isOpen() const { return m_isOpen; }
std::string filename() const { return m_filename; }
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();
@@ -124,10 +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& bufferCheck() {
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:
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)) {
@@ -139,40 +154,42 @@ public:
//=============================================================================
// 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 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 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;
};
//=============================================================================
@@ -219,13 +236,13 @@ inline VerilatedSerialize& operator<<(VerilatedSerialize& os, float& rhs) {
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, float& rhs) {
return os.read(&rhs, sizeof(rhs));
}
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, string& rhs) {
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, std::string& rhs) {
vluint32_t len=rhs.length();
os<<len;
return os.write(rhs.data(), len);
}
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, string& rhs) {
vluint32_t len;
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, std::string& rhs) {
vluint32_t len=0;
os>>len;
rhs.resize(len);
return os.read((void*)rhs.data(), len);
+7 -6
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2014 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: Common include for all Verilated SystemC files
///
/// This file is included automatically by Verilator at the top of
/// all SystemC files it generates.
/// This file is included automatically by Verilator at the top of
/// all SystemC files it generates.
///
/// Code available from: http://www.veripool.org/verilator
///
@@ -35,13 +35,14 @@
// 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 vluint32_t* sp_datap(const sc_bv_base& base) {
return static_cast<const VlScBvExposer*>(&base)->sp_datatp(); }
vluint32_t* sp_datatp() const { return (vluint32_t*)(m_data); }
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:
// sc_digit* m_data; // data array
};
+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
+27 -64
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2014 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,72 +31,32 @@
#ifndef _VERILATED_SYMS_H_
#define _VERILATED_SYMS_H_ 1 ///< Header Guard
#include "verilated_sym_props.h"
#include "verilated_heavy.h"
#include <map>
//======================================================================
// Types
struct VerilatedCStrCmp {
/// Ordering maps keyed by const char*'s
bool operator() (const char *a, const char *b) const {
return std::strcmp(a, b) < 0;
}
};
//===========================================================================
/// 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 (VerilatedVarFlags)((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 VerilatedVarNameMap : public map<const char*, VerilatedVar, VerilatedCStrCmp> {
/// Class to sort maps keyed by const char*'s
struct VerilatedCStrCmp {
bool operator() (const char *a, const char *b) const {
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:
VerilatedScopeNameMap() {}
~VerilatedScopeNameMap() {}
};
/// Map of sorted variable names to find associated variable class
class VerilatedVarNameMap
: public std::map<const char*, VerilatedVar, VerilatedCStrCmp> {
public:
VerilatedVarNameMap() {}
~VerilatedVarNameMap() {}
+143 -69
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2014 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,8 +17,6 @@
/// \file
/// \brief C++ Tracing in VCD Format
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
// SPDIFF_OFF
@@ -49,9 +47,38 @@
#endif
//=============================================================================
// Global
// VerilatedVcdImp
/// Base class to hold some static state
/// This is an internally used class
vector<VerilatedVcd*> VerilatedVcd::s_vcdVecp; ///< List of all created traces
class VerilatedVcdSingleton {
private:
typedef std::vector<VerilatedVcd*> VcdVec;
struct Singleton {
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) VL_EXCLUDES(singleton().s_vcdMutex) {
VerilatedLockGuard lock(singleton().s_vcdMutex);
singleton().s_vcdVecp.push_back(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() 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();
}
}
};
//=============================================================================
// VerilatedVcdCallInfo
@@ -69,24 +96,63 @@ 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)
: m_initcb(icb), m_fullcb(fcb), m_changecb(changecb), m_userthis(ut), m_code(code) {};
~VerilatedVcdCallInfo() {}
};
//=============================================================================
//=============================================================================
//=============================================================================
// VerilatedVcdFile
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() VL_MT_UNSAFE {
::close(m_fd);
}
ssize_t VerilatedVcdFile::write(const char* bufp, ssize_t len) VL_MT_UNSAFE {
return ::write(m_fd, bufp, len);
}
//=============================================================================
//=============================================================================
//=============================================================================
// Opening/Closing
VerilatedVcd::VerilatedVcd(VerilatedVcdFile* filep)
: m_isOpen(false), m_rolloverMB(0), m_modDepth(0), m_nextCode(1) {
// Not in header to avoid link issue if header is included without this .cpp file
m_fileNewed = (filep == NULL);
m_filep = m_fileNewed ? new VerilatedVcdFile : filep;
m_namemapp = NULL;
m_timeRes = m_timeUnit = 1e-9;
m_timeLastDump = 0;
m_sigs_oldvalp = NULL;
m_evcd = false;
m_scopeEscape = '.'; // Backward compatibility
m_fullDump = true;
m_wrChunkSize = 8*1024;
m_wrBufp = new char [m_wrChunkSize*8];
m_wrFlushp = m_wrBufp + m_wrChunkSize * 6;
m_writep = m_wrBufp;
m_wroteBytes = 0;
}
void VerilatedVcd::open (const char* filename) {
m_assertOne.check();
if (isOpen()) return;
// Set member variables
m_filename = filename;
s_vcdVecp.push_back(this);
VerilatedVcdSingleton::pushVcd(this);
// SPDIFF_OFF
// Set callback so an early exit will flush us
@@ -112,10 +178,11 @@ 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
string name = m_filename;
std::string name = m_filename;
size_t pos=name.rfind(".");
if (pos>8 && 0==strncmp("_cat",name.c_str()+pos-8,4)
&& isdigit(name.c_str()[pos-4])
@@ -142,9 +209,7 @@ void VerilatedVcd::openNext (bool incFilename) {
assert(0); // Not supported yet.
} else {
// cppcheck-suppress duplicateExpression
m_fd = ::open (m_filename.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK
, 0666);
if (m_fd<0) {
if (!m_filep->open(m_filename)) {
// User code can check isOpen()
m_isOpen = false;
return;
@@ -162,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);
}
@@ -171,19 +236,19 @@ void VerilatedVcd::makeNameMap() {
// If no scope was specified, prefix everything with a "top"
// This comes from user instantiations with no name - IE Vtop("").
bool nullScope = false;
for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
const string& hiername = it->first;
for (NameMap::const_iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
const std::string& hiername = it->first;
if (hiername.size() >= 1 && hiername[0] == '\t') nullScope=true;
}
if (nullScope) {
NameMap* newmapp = new NameMap;
for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
const string& hiername = it->first;
const string& decl = it->second;
string newname = string("top");
for (NameMap::const_iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
const std::string& hiername = it->first;
const std::string& decl = it->second;
std::string newname = std::string("top");
if (hiername[0] != '\t') newname += ' ';
newname += hiername;
newmapp->insert(make_pair(newname,decl));
newmapp->insert(std::make_pair(newname,decl));
}
deleteNameMap();
m_namemapp = newmapp;
@@ -199,30 +264,37 @@ VerilatedVcd::~VerilatedVcd() {
if (m_wrBufp) { delete[] m_wrBufp; m_wrBufp=NULL; }
if (m_sigs_oldvalp) { delete[] m_sigs_oldvalp; m_sigs_oldvalp=NULL; }
deleteNameMap();
// Remove from list of traces
vector<VerilatedVcd*>::iterator pos = find(s_vcdVecp.begin(), s_vcdVecp.end(), this);
if (pos != s_vcdVecp.end()) { s_vcdVecp.erase(pos); }
if (m_filep && m_fileNewed) { delete m_filep; m_filep = NULL; }
for (CallbackVec::const_iterator it=m_callbacks.begin(); it!=m_callbacks.end(); ++it) {
delete (*it);
}
m_callbacks.clear();
VerilatedVcdSingleton::removeVcd(this);
}
void VerilatedVcd::closePrev () {
// This function is on the flush() call path
if (!isOpen()) return;
bufferFlush();
m_isOpen = false;
::close(m_fd);
m_filep->close();
}
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;
// No buffer flush, just fclose
m_isOpen = false;
::close(m_fd); // May get error, just ignore it
m_filep->close(); // May get error, just ignore it
}
void VerilatedVcd::close() {
// This function is on the flush() call path
m_assertOne.check();
if (!isOpen()) return;
if (m_evcd) {
printStr("$vcdclose ");
@@ -251,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;
@@ -271,29 +343,31 @@ 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) {
ssize_t remaining = (m_writep - wp);
if (remaining==0) break;
errno = 0;
ssize_t got = write (m_fd, wp, remaining);
ssize_t got = m_filep->write(wp, remaining);
if (got>0) {
wp += got;
m_wroteBytes += got;
} else if (got < 0) {
if (errno != EAGAIN && errno != EINTR) {
// write failed, presume error (perhaps out of disk space)
string msg = (string)"VerilatedVcd::bufferFlush: "+strerror(errno);
vl_fatal("",0,"",msg.c_str());
std::string msg = std::string("VerilatedVcd::bufferFlush: ")+strerror(errno);
VL_FATAL_MT("",0,"",msg.c_str());
closeErr();
break;
}
@@ -308,21 +382,21 @@ void VerilatedVcd::bufferFlush () {
// Simple methods
void VerilatedVcd::set_time_unit (const char* unitp) {
string unitstr (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) {
string unitstr (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);
}
double VerilatedVcd::timescaleToDouble (const char* unitp) {
char* endp;
double value = strtod(unitp, &endp);
if (!value) value=1; // On error so we allow just "ns" to return 1e-9.
if (value==0.0 && endp==unitp) value=1; // On error so we allow just "ns" to return 1e-9.
unitp=endp;
while (*unitp && isspace(*unitp)) unitp++;
switch (*unitp) {
@@ -337,7 +411,7 @@ double VerilatedVcd::timescaleToDouble (const char* unitp) {
return value;
}
string VerilatedVcd::doubleToTimescale (double value) {
std::string VerilatedVcd::doubleToTimescale (double value) {
const char* suffixp = "s";
if (value>=1e0) { suffixp="s"; value *= 1e0; }
else if (value>=1e-3 ) { suffixp="ms"; value *= 1e3; }
@@ -346,7 +420,7 @@ string VerilatedVcd::doubleToTimescale (double value) {
else if (value>=1e-12) { suffixp="ps"; value *= 1e12; }
else if (value>=1e-15) { suffixp="fs"; value *= 1e15; }
else if (value>=1e-18) { suffixp="as"; value *= 1e18; }
char valuestr[100]; sprintf(valuestr,"%d%s",(int)(value), suffixp);
char valuestr[100]; sprintf(valuestr,"%3.0f%s", value, suffixp);
return valuestr; // Gets converted to string, so no ref to stack
}
@@ -366,7 +440,7 @@ void VerilatedVcd::dumpHeader () {
printStr("$date "); printStr(ctime(&time_str)); printStr(" $end\n");
printStr("$timescale ");
const string& timeResStr = doubleToTimescale(m_timeRes);
const std::string& timeResStr = doubleToTimescale(m_timeRes);
printStr(timeResStr.c_str());
printStr(" $end\n");
@@ -380,13 +454,13 @@ void VerilatedVcd::dumpHeader () {
// We detect the spaces in module names to determine hierarchy. This
// allows signals to be declared without fixed ordering, which is
// required as Verilog signals might be separately declared from
// "SP_TRACE" signals.
// SC module signals.
// Print the signal names
const char* lastName = "";
for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
const string& hiernamestr = it->first;
const string& decl = it->second;
for (NameMap::const_iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
const std::string& hiernamestr = it->first;
const std::string& decl = it->second;
// Determine difference between the old and new names
const char* hiername = hiernamestr.c_str();
@@ -440,20 +514,21 @@ void VerilatedVcd::dumpHeader () {
deleteNameMap();
}
void VerilatedVcd::module (string name) {
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 = 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
}
@@ -471,10 +546,10 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
// Tab separates final scope from signal name
// Tab sorts before spaces, so signals nicely will print before scopes
// Note the hiername may be nothing, if so we'll add "\t{name}"
string nameasstr = name;
std::string nameasstr = name;
if (m_modName!="") { nameasstr = m_modName+m_scopeEscape+nameasstr; } // Optional ->module prefix
string hiername;
string basename;
std::string hiername;
std::string basename;
for (const char* cp=nameasstr.c_str(); *cp; cp++) {
if (isScopeEscape(*cp)) {
// Ahh, we've just read a scope, not a basename
@@ -488,13 +563,13 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
hiername += "\t"+basename;
// Print reference
string decl = "$var ";
std::string decl = "$var ";
if (m_evcd) decl += "port"; else decl += wirep; // usually "wire"
char buf [1000];
sprintf(buf, " %2d ", bits);
decl += buf;
if (m_evcd) {
sprintf(buf, "<%d", code);
sprintf(buf, "<%u", code);
decl += buf;
} else {
decl += stringCode(code);
@@ -511,7 +586,7 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
decl += buf;
}
decl += " $end\n";
m_namemapp->insert(make_pair(hiername,decl));
m_namemapp->insert(std::make_pair(hiername,decl));
}
void VerilatedVcd::declBit (vluint32_t code, const char* name, int arraynum)
@@ -538,7 +613,8 @@ void VerilatedVcd::declDouble (vluint32_t code, const char* name, int arraynum
//=============================================================================
void VerilatedVcd::fullDouble (vluint32_t code, const double newval) {
(*((double*)&m_sigs_oldvalp[code])) = newval;
// cppcheck-suppress invalidPointerCast
(*(reinterpret_cast<double*>(&m_sigs_oldvalp[code]))) = newval;
// Buffer can't overflow before sprintf; we sized during declaration
sprintf(m_writep, "r%.16g", newval);
m_writep += strlen(m_writep);
@@ -546,9 +622,10 @@ void VerilatedVcd::fullDouble (vluint32_t code, const double newval) {
bufferCheck();
}
void VerilatedVcd::fullFloat (vluint32_t code, const float newval) {
(*((float*)&m_sigs_oldvalp[code])) = newval;
// cppcheck-suppress invalidPointerCast
(*(reinterpret_cast<float*>(&m_sigs_oldvalp[code]))) = newval;
// Buffer can't overflow before sprintf; we sized during declaration
sprintf(m_writep, "r%.16g", (double)newval);
sprintf(m_writep, "r%.16g", static_cast<double>(newval));
m_writep += strlen(m_writep);
*m_writep++=' '; printCode(code); *m_writep++='\n';
bufferCheck();
@@ -557,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())) {
string msg = (string)"Internal: "+__FILE__+"::"+__FUNCTION__+" called with already open file";
vl_fatal(__FILE__,__LINE__,"",msg.c_str());
std::string msg = std::string("Internal: ")+__FILE__+"::"+__FUNCTION__+" called with already open file";
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);
}
@@ -573,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
@@ -593,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) {
@@ -606,17 +686,11 @@ void VerilatedVcd::dumpPrep (vluint64_t timeui) {
printStr("\n");
}
void VerilatedVcd::dumpDone () {
}
//======================================================================
// Static members
void VerilatedVcd::flush_all() {
for (vluint32_t ent = 0; ent< s_vcdVecp.size(); ent++) {
VerilatedVcd* vcdp = s_vcdVecp[ent];
vcdp->flush();
}
void VerilatedVcd::flush_all() VL_MT_UNSAFE_ONE {
VerilatedVcdSingleton::flush_all();
}
//======================================================================
+95 -74
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2014 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,8 +17,6 @@
/// \file
/// \brief C++ Tracing in VCD Format
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
// SPDIFF_OFF
@@ -26,16 +24,32 @@
#define _VERILATED_VCD_C_H_ 1
#include "verilatedos.h"
#include "verilated.h"
#include <string>
#include <vector>
#include <map>
using namespace std;
class VerilatedVcd;
class VerilatedVcdCallInfo;
// SPDIFF_ON
//=============================================================================
// VerilatedFile
/// File handling routines, which can be overrode for e.g. socket I/O
class VerilatedVcdFile {
private:
int m_fd; ///< File descriptor we're writing to
public:
// METHODS
VerilatedVcdFile() : m_fd(0) {}
virtual ~VerilatedVcdFile() {}
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;
};
//=============================================================================
// VerilatedVcdSig
/// Internal data on one signal being traced.
@@ -62,16 +76,17 @@ typedef void (*VerilatedVcdCallback_t)(VerilatedVcd* vcdp, void* userthis, vluin
class VerilatedVcd {
private:
VerilatedVcdFile* m_filep; ///< File we're writing to
bool m_fileNewed; ///< m_filep needs destruction
bool m_isOpen; ///< True indicates open file
bool m_evcd; ///< True for evcd format
int m_fd; ///< File descriptor we're writing to
string m_filename; ///< Filename we're writing to (if open)
std::string m_filename; ///< Filename we're writing to (if open)
vluint64_t m_rolloverMB; ///< MB of file size to rollover at
char m_scopeEscape; ///< Character to separate scope components
int m_modDepth; ///< Depth of module hierarchy
bool m_fullDump; ///< True indicates dump ignoring if changed
vluint32_t m_nextCode; ///< Next code number to assign
string m_modName; ///< Module name being traced now
std::string m_modName; ///< Module name being traced now
double m_timeRes; ///< Time resolution (ns/ms etc)
double m_timeUnit; ///< Time units (ns/ms etc)
vluint64_t m_timeLastDump; ///< Last time we did a dump
@@ -82,15 +97,18 @@ private:
vluint64_t m_wrChunkSize; ///< Output buffer size
vluint64_t m_wroteBytes; ///< Number of bytes written to this file
vluint32_t* m_sigs_oldvalp; ///< Pointer to old signal values
vector<VerilatedVcdSig> m_sigs; ///< Pointer to signal information
vector<VerilatedVcdCallInfo*> m_callbacks; ///< Routines to perform dumping
typedef map<string,string> NameMap;
NameMap* m_namemapp; ///< List of names for the header
static vector<VerilatedVcd*> s_vcdVecp; ///< List of all created traces
vluint32_t* m_sigs_oldvalp; ///< Pointer to old signal values
typedef std::vector<VerilatedVcdSig> SigVec;
SigVec m_sigs; ///< Pointer to signal information
typedef std::vector<VerilatedVcdCallInfo*> CallbackVec;
CallbackVec m_callbacks; ///< Routines to perform dumping
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
@@ -116,45 +134,26 @@ private:
// cppcheck-suppress functionConst
void dumpDone ();
inline void printCode (vluint32_t code) {
if (code>=(94*94*94)) *m_writep++ = ((char)((code/94/94/94)%94+33));
if (code>=(94*94)) *m_writep++ = ((char)((code/94/94)%94+33));
if (code>=(94)) *m_writep++ = ((char)((code/94)%94+33));
*m_writep++ = ((char)((code)%94+33));
if (code>=(94*94*94)) *m_writep++ = static_cast<char>((code/94/94/94)%94+33);
if (code>=(94*94)) *m_writep++ = static_cast<char>((code/94/94)%94+33);
if (code>=(94)) *m_writep++ = static_cast<char>((code/94)%94+33);
*m_writep++ = static_cast<char>((code)%94+33);
}
static string stringCode (vluint32_t code) {
string out;
if (code>=(94*94*94)) out += ((char)((code/94/94/94)%94+33));
if (code>=(94*94)) out += ((char)((code/94/94)%94+33));
if (code>=(94)) out += ((char)((code/94)%94+33));
return out + ((char)((code)%94+33));
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);
if (code>=(94)) out += static_cast<char>((code/94)%94+33);
return out + static_cast<char>((code)%94+33);
}
protected:
// METHODS
void evcd(bool flag) { m_evcd = flag; }
// CONSTRUCTORS
VL_UNCOPYABLE(VerilatedVcd);
public:
// CREATORS
VerilatedVcd () : m_isOpen(false), m_rolloverMB(0), m_modDepth(0), m_nextCode(1) {
m_namemapp = NULL;
m_timeRes = m_timeUnit = 1e-9;
m_timeLastDump = 0;
m_sigs_oldvalp = NULL;
m_evcd = false;
m_scopeEscape = '.'; // Backward compatibility
m_fd = 0;
m_fullDump = true;
m_wrChunkSize = 8*1024;
m_wrBufp = new char [m_wrChunkSize*8];
m_wrFlushp = m_wrBufp + m_wrChunkSize * 6;
m_writep = m_wrBufp;
m_wroteBytes = 0;
}
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?
@@ -165,33 +164,35 @@ 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 string& unit) { set_time_unit(unit.c_str()); }
void set_time_unit (const std::string& unit) { set_time_unit(unit.c_str()); }
void set_time_resolution (const char* unit); ///< Set time resolution (s/ms, defaults to ns)
void set_time_resolution (const string& unit) { set_time_resolution(unit.c_str()); }
void set_time_resolution (const std::string& unit) { set_time_resolution(unit.c_str()); }
double timescaleToDouble (const char* unitp);
string doubleToTimescale (double value);
std::string doubleToTimescale (double value);
/// Inside dumping routines, called each cycle to make the dump
void dump (vluint64_t timeui);
/// Call dump with a absolute unscaled time in seconds
void dumpSeconds (double secs) { dump((vluint64_t)(secs * m_timeRes)); }
void dumpSeconds (double secs) { dump(static_cast<vluint64_t>(secs * m_timeRes)); }
/// 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 string name);
void module (const std::string& name);
/// Inside dumping routines, declare a signal
void declBit (vluint32_t code, const char* name, int arraynum);
void declBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
@@ -209,7 +210,7 @@ public:
void fullBit (vluint32_t code, const vluint32_t newval) {
// Note the &1, so we don't require clean input -- makes more common no change case faster
m_sigs_oldvalp[code] = newval;
*m_writep++=('0'+(char)(newval&1)); printCode(code); *m_writep++='\n';
*m_writep++=('0'+static_cast<char>(newval&1)); printCode(code); *m_writep++='\n';
bufferCheck();
}
void fullBus (vluint32_t code, const vluint32_t newval, int bits) {
@@ -222,7 +223,7 @@ public:
bufferCheck();
}
void fullQuad (vluint32_t code, const vluint64_t newval, int bits) {
(*((vluint64_t*)&m_sigs_oldvalp[code])) = newval;
(*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) = newval;
*m_writep++='b';
for (int bit=bits-1; bit>=0; --bit) {
*m_writep++=((newval&(1ULL<<bit))?'1':'0');
@@ -261,8 +262,8 @@ public:
bufferCheck();
}
void fullTriQuad (vluint32_t code, const vluint64_t newval, const vluint32_t newtri, int bits) {
(*((vluint64_t*)&m_sigs_oldvalp[code])) = newval;
(*((vluint64_t*)&m_sigs_oldvalp[code+1])) = newtri;
(*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) = newval;
(*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code+1]))) = newtri;
*m_writep++='b';
for (int bit=bits-1; bit>=0; --bit) {
*m_writep++ = "01zz"[((newval >> bit)&1ULL)
@@ -326,7 +327,7 @@ public:
}
}
inline void chgQuad (vluint32_t code, const vluint64_t newval, int bits) {
vluint64_t diff = (*((vluint64_t*)&m_sigs_oldvalp[code])) ^ newval;
vluint64_t diff = (*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) ^ newval;
if (VL_UNLIKELY(diff)) {
if (VL_UNLIKELY(bits==64 || (diff & ((1ULL<<bits)-1) ))) {
fullQuad(code, newval, bits);
@@ -361,8 +362,8 @@ public:
}
}
inline void chgTriQuad (vluint32_t code, const vluint64_t newval, const vluint32_t newtri, int bits) {
vluint64_t diff = ( ((*((vluint64_t*)&m_sigs_oldvalp[code])) ^ newval)
| ((*((vluint64_t*)&m_sigs_oldvalp[code+1])) ^ newtri));
vluint64_t diff = ( ((*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) ^ newval)
| ((*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code+1]))) ^ newtri));
if (VL_UNLIKELY(diff)) {
if (VL_UNLIKELY(bits==64 || (diff & ((1ULL<<bits)-1) ))) {
fullTriQuad(code, newval, newtri, bits);
@@ -379,27 +380,38 @@ public:
}
}
inline void chgDouble (vluint32_t code, const double newval) {
if (VL_UNLIKELY((*((double*)&m_sigs_oldvalp[code])) != newval)) {
// cppcheck-suppress invalidPointerCast
if (VL_UNLIKELY((*(reinterpret_cast<double*>(&m_sigs_oldvalp[code]))) != newval)) {
fullDouble (code, newval);
}
}
inline void chgFloat (vluint32_t code, const float newval) {
if (VL_UNLIKELY((*((float*)&m_sigs_oldvalp[code])) != newval)) {
// cppcheck-suppress invalidPointerCast
if (VL_UNLIKELY((*(reinterpret_cast<float*>(&m_sigs_oldvalp[code]))) != newval)) {
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
VerilatedVcdC() {}
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(); }
@@ -407,24 +419,33 @@ 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
/// conversion warnings. It's better to use a vluint64_t time instead.
void dump (double timestamp) { dump((vluint64_t)timestamp); }
void dump (vluint32_t timestamp) { dump((vluint64_t)timestamp); }
void dump (int timestamp) { dump((vluint64_t)timestamp); }
void dump (double timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
void dump (vluint32_t timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
void dump (int timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
/// Set time units (s/ms, defaults to ns)
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
void set_time_unit (const char* unit) { m_sptrace.set_time_unit(unit); }
void set_time_unit (const std::string& unit) { set_time_unit(unit.c_str()); }
/// Set time resolution (s/ms, defaults to ns)
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
void set_time_resolution (const char* unit) { m_sptrace.set_time_resolution(unit); }
void set_time_resolution (const std::string& unit) { set_time_resolution(unit.c_str()); }
/// Internal class access
inline VerilatedVcd* spTrace () { return &m_sptrace; };
};
+9 -3
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2014 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,8 +17,6 @@
/// \file
/// \brief Verilator tracing in VCD Format
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
// SPDIFF_OFF
@@ -32,6 +30,7 @@
//--------------------------------------------------
#if (SYSTEMC_VERSION>=20050714)
// SystemC 2.1.v1
// cppcheck-suppress unusedFunction
void VerilatedVcdSc::write_comment (const std::string &) {}
void VerilatedVcdSc::trace (const unsigned int &, const std::string &, const char **) {}
@@ -40,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 )
@@ -76,6 +80,7 @@ void VerilatedVcdSc::trace (const unsigned int &, const std::string &, const cha
//--------------------------------------------------
#elif (SYSTEMC_VERSION>20011000)
// SystemC 2.0.1
// cppcheck-suppress unusedFunction
void VerilatedVcdSc::write_comment (const sc_string &) {}
void VerilatedVcdSc::trace (const unsigned int &, const sc_string &, const char **) {}
@@ -118,6 +123,7 @@ void VerilatedVcdSc::trace (const unsigned int &, const sc_string &, const char
//--------------------------------------------------
#else
// SystemC 1.2.1beta
// cppcheck-suppress unusedFunction
void VerilatedVcdSc::write_comment (const sc_string &) {}
void VerilatedVcdSc::trace (const unsigned int &, const sc_string &, const char **) {}
+11 -3
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2014 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,7 +17,7 @@
/// \file
/// \brief Verilator tracing in VCD format
///
/// AUTHOR: Wilson Snyder
/// This class is not threadsafe, as the SystemC kernel is not threadsafe.
///
//=============================================================================
// SPDIFF_OFF
@@ -39,6 +39,8 @@ class VerilatedVcdSc
: sc_trace_file
, public VerilatedVcdC
{
// CONSTRUCTORS
VL_UNCOPYABLE(VerilatedVcdSc);
public:
VerilatedVcdSc() {
sc_get_curr_simcontext()->add_trace_file(this);
@@ -58,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)
@@ -93,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 )
+1594 -14
View File
File diff suppressed because it is too large Load Diff
+13 -1433
View File
File diff suppressed because it is too large Load Diff
+148 -21
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2014 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,49 +42,100 @@
# 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_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__
# define VL_THREAD __thread ///< Storage class for thread-local storage
# if (__cplusplus < 201103L) && !defined(VL_THREADED_NO_C11_WARNING)
# 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"
# endif
# define VL_STATIC_OR_THREAD ///< Static if unthreaded, as some strings can be faster
// ///< if non-dynamic and can't do "static VL_THREAD string"
# define VL_THREAD_LOCAL thread_local ///< Use new C++ static local thread
#else
# define VL_THREAD ///< Storage class for thread-local storage
# define VL_STATIC_OR_THREAD static ///< Static if unthreaded, as some strings can be faster
// ///< if non-dynamic and can't do "static VL_THREAD string"
# define VL_THREAD_LOCAL ///< Use new C++ static local thread
#endif
#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
@@ -93,16 +144,34 @@
#endif
// This is not necessarily the same as #UL, depending on what the IData typedef is.
#define VL_UL(c) ((IData)(c##UL)) ///< Add appropriate suffix to 32-bit constant
#define VL_UL(c) (static_cast<IData>(c##UL)) ///< Add appropriate suffix to 32-bit constant
#if defined(VL_CPPCHECK) || defined(__clang_analyzer__)
# define VL_DANGLING(v)
#else
# define VL_DANGLING(v) do { (v) = NULL; } while(0) ///< After e.g. delete, set variable to NULL to indicate must not use later
#endif
//=========================================================================
// C++-2011
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define VL_EQ_DELETE = delete
# define VL_HAS_UNIQUE_PTR
# define VL_UNIQUE_PTR unique_ptr
# define VL_HAS_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 auto_ptr
# 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
//=========================================================================
@@ -139,7 +208,7 @@ typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward comp
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
# ifdef __uint32_t_defined // Newer Cygwin uint32_t in stdint.h as an unsigned int
# if defined(__uint32_t_defined) || defined(___int32_t_defined) // Newer Cygwin uint32_t in stdint.h as an unsigned int
typedef int32_t vlsint32_t; ///< 32-bit signed type
typedef uint32_t vluint32_t; ///< 32-bit unsigned type
# else // Older Cygwin has long==uint32_t
@@ -178,6 +247,7 @@ typedef signed __int32 ssize_t; ///< signed size_t; returned fro
#else // Linux or compliant Unix flavors, -m64
# include <stdint.h> // Linux and most flavors
# include <unistd.h> // Linux ssize_t
# include <inttypes.h> // Solaris
typedef uint8_t vluint8_t; ///< 32-bit unsigned type
typedef uint16_t vluint16_t; ///< 32-bit unsigned type
@@ -206,6 +276,18 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
# endif
#endif
#if defined(_WIN32) && defined(_MSC_VER)
# if (_MSC_VER < 1900)
# define VL_SNPRINTF _snprintf
# else
# define VL_SNPRINTF snprintf
# endif
# define VL_VSNPRINTF vsnprintf
#else
# define VL_SNPRINTF snprintf
# define VL_VSNPRINTF vsnprintf
#endif
//=========================================================================
// File system functions
@@ -229,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
@@ -263,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;
@@ -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 );
/*
**********************************************************
@@ -427,7 +427,7 @@ XXTERN void svGetPartSelectLogic(svLogicVec32* d, const svLogicPackedArrRef s,
/* actual <-- canonical */
XXTERN void svPutPartSelectBit(svBitPackedArrRef d, const svBitVec32 s,
int i, int w);
XXTERN void svPutPartSelectLogic(svLogicPackedArrRef d, const svLogicVec32 s,
XXTERN void svPutPartSelectLogic(svLogicPackedArrRef d, const svLogicVec32* s,
int i, int w);
/*
+5 -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
@@ -105,10 +105,12 @@ typedef unsigned char PLI_UBYTE8;
/* object is defined imported by the application */
#undef XXTERN
#define XXTERN PLI_EXTERN PLI_DLLISPEC
/* object is exported by the application */
#undef EETERN
#define EETERN PLI_EXTERN PLI_DLLESPEC
#endif
@@ -249,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 */
@@ -976,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 */
+7 -7
View File
@@ -124,7 +124,7 @@ if [ x"$dir_arg" != x ]; then
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
@@ -134,7 +134,7 @@ else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
@@ -162,7 +162,7 @@ dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
@@ -201,17 +201,17 @@ else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
@@ -242,7 +242,7 @@ else
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
+23 -11
View File
@@ -237,10 +237,10 @@ implementation is not found, the system will look in turn for overloaded
implementations up the inheritance hierarchy. For example calling C<accept>
on C<AstIf> will look in turn for:
void visit (AstIf* nodep, AstNUser* vup)
void visit (AstNodeIf* nodep, AstNUser* vup)
void visit (AstNodeStmt* nodep, AstNUser* vup)
void visit (AstNode* nodep, AstNUser* vup)
void visit (AstIf* nodep)
void visit (AstNodeIf* nodep)
void visit (AstNodeStmt* nodep)
void visit (AstNode* nodep)
There are three ways data is passed between visitor functions.
@@ -407,6 +407,18 @@ Tests that fail should by convention have the suffix C<_bad> in their name,
and include C<fails =E<gt> 1> in either their C<compile> or C<execute> step as
appropriate.
=head2 Preparing to Run Tests
For all tests to pass you must install the following packages:
* SystemC to compile the SystemC outputs, see http://systemc.org
* Parallel::Forker from CPAN to run tests in parallel, you can install this
with e.g. "sudo cpan install Parallel::Forker".
* vcddiff to find differences in VCD outputs. See the readme at
https://github.com/veripool/vcddiff
=head2 Controlling the Test Driver
Test drivers are written in PERL. All invoke the main test driver script,
@@ -473,10 +485,10 @@ be warning free.
=item --enable-longtests
In addition to the standard C, SystemC tests also run the tests in the
C<test_verilated> and C<test_regress> directories when using I<make test>.
This is disabled by default as SystemC installation problems would
otherwise falsely indicate a Verilator problem.
In addition to the standard C, SystemC examples, also run the tests in the
C<test_regress> directory when using I<make test>. This is disabled by
default as SystemC installation problems would otherwise falsely indicate a
Verilator problem.
=back
@@ -697,7 +709,7 @@ Start GDB, then C<start> with the remaining arguments.
Temporary breakpoint 1, main (argc=13, argv=0xbfffefa4, env=0xbfffefdc)
at ../Verilator.cpp:615
615 ios::sync_with_stdio();
(gdb)
(gdb)
You can then continue execution with breakpoints as required.
@@ -737,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.
@@ -773,7 +785,7 @@ in C<src/Makefile_obj.in> and reconfigure.
The latest version is available from L<http://www.veripool.org/>.
Copyright 2008-2014 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-2014 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-2014 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-2014 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-2014 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-2014 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:
+6 -5
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");
@@ -115,7 +115,8 @@ sub write_verilog {
sub cleanenv {
foreach my $var (keys %ENV) {
if ($var eq "VERILATOR_ROOT") {
if ($var eq "VERILATOR_ROOT"
|| $var eq "VERILATOR_INCLUDE") {
print "unset $var # Was '$ENV{$var}'\n";
delete $ENV{$var}
}
@@ -183,7 +184,7 @@ Runs a specific test stage (see the script).
=head1 DISTRIBUTION
Copyright 2009-2014 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-2014 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-2014 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-2014 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-vcs_mx`;
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-2014 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-2014 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-2014 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.
+10 -8
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2014 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.
@@ -46,25 +46,27 @@ obj_opt:
obj_dbg:
mkdir $@
.PHONY: ../verilator_bin ../verilator_bin_dbg ../verilator_coverage_bin_dbg
.SUFFIXES:
opt: ../verilator_bin
.PHONY: ../bin/verilator_bin ../bin/verilator_bin_dbg ../bin/verilator_coverage_bin_dbg
opt: ../bin/verilator_bin
ifeq ($(VERILATOR_NO_OPT_BUILD),1) # Faster laptop development... One build
../verilator_bin: ../verilator_bin_dbg
../bin/verilator_bin: ../bin/verilator_bin_dbg
-rm -rf $@ $@.exe
-cp -p $<$(EXEEXT) $@$(EXEEXT)
else
../verilator_bin: obj_opt prefiles
../bin/verilator_bin: obj_opt prefiles
cd obj_opt && $(MAKE) -j 1 TGT=../$@ -f ../Makefile_obj serial
cd obj_opt && $(MAKE) TGT=../$@ -f ../Makefile_obj
endif
dbg: ../verilator_bin_dbg ../verilator_coverage_bin_dbg
../verilator_bin_dbg: obj_dbg prefiles
dbg: ../bin/verilator_bin_dbg ../bin/verilator_coverage_bin_dbg
../bin/verilator_bin_dbg: obj_dbg prefiles
cd obj_dbg && $(MAKE) -j 1 TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj serial
cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj
../verilator_coverage_bin_dbg: obj_dbg prefiles
../bin/verilator_coverage_bin_dbg: obj_dbg prefiles
cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 VL_VLCOV=1 -f ../Makefile_obj serial_vlcov
cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 VL_VLCOV=1 -f ../Makefile_obj
+22 -18
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2014 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,6 +62,10 @@ CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
CPPFLAGS += @CPPFLAGS@
LDFLAGS += @LDFLAGS@
EXEEXT = @EXEEXT@
CFG_CXXFLAGS_SRC = @CFG_CXXFLAGS_SRC@
CFG_CXXFLAGS_PARSER = @CFG_CXXFLAGS_PARSER@
# Compiler flags that turn on extra warnings
CFG_CXXFLAGS_WEXTRA = @CFG_CXXFLAGS_WEXTRA@
#### End of system configuration section. ####
@@ -71,7 +75,7 @@ TGT = ../../verilator_bin
#################
ifeq ($(VL_DEBUG),)
# Optimize
COPT = -O
COPT = -O2
else
# Debug
COPT = -ggdb -DVL_DEBUG
@@ -85,7 +89,8 @@ endif
#CCMALLOC = /usr/local/lib/ccmalloc-gcc.o -lccmalloc -ldl
# -lfl not needed as Flex invoked with %nowrap option
LIBS = -lm
# -lstdc++ needed for clang, believed harmless with gcc
LIBS = -lm -lstdc++
CPPFLAGS += -MMD
CPPFLAGS += -I. -I$(bldsrc) -I$(srcdir) -I$(incdir)
@@ -94,17 +99,14 @@ CPPFLAGS += -DYYDEBUG # Required to get nice error messages
CPPFLAGS += $(COPT)
CPPFLAGS += -MP # Only works on recent GCC versions
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
CPPFLAGS += -W -Wall -Wno-unused-parameter -Wno-char-subscripts -Werror
CPPFLAGS += -W -Wall $(CFG_CXXFLAGS_WEXTRA) $(CFG_CXXFLAGS_SRC) -Werror
#CPPFLAGS += -pedantic-errors
else
CPPFLAGS += $(CFG_CXXFLAGS_SRC)
endif
CPPFLAGSWALL = $(CPPFLAGS)
CPPFLAGSNOWALL = $(CPPFLAGS) -Wno-unused
ifneq ($(SYSTEMPERL),) # Intuit SYSTEMPERL_INCLUDE as it's new
SYSTEMPERL_INCLUDE ?= $(SYSTEMPERL)/src
#else if set, leave as-is.
#else if SYSTEMPERL="" don't set _INCLUDE so source will figure it out
endif
CPPFLAGSWALL = $(CPPFLAGS)
CPPFLAGSPARSER = $(CPPFLAGS) $(CFG_CXXFLAGS_PARSER)
# Allow RPM builds to specify hardcoded data directories
# To do this:
@@ -113,8 +115,6 @@ ifeq ($(CFG_WITH_DEFENV),yes)
CPPFLAGS += -DDEFENV_SYSTEMC_ARCH=\"$(SYSTEMC_ARCH)\"
CPPFLAGS += -DDEFENV_SYSTEMC_INCLUDE=\"$(SYSTEMC_INCLUDE)\"
CPPFLAGS += -DDEFENV_SYSTEMC_LIBDIR=\"$(SYSTEMC_LIBDIR)\"
CPPFLAGS += -DDEFENV_SYSTEMPERL=\"$(SYSTEMPERL)\"
CPPFLAGS += -DDEFENV_SYSTEMPERL_INCLUDE=\"$(SYSTEMPERL_INCLUDE)\"
ifeq ($(VERILATOR_ROOT),) # Use what we're given, or intuit
CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(pkgdatadir)\"
else
@@ -161,6 +161,7 @@ RAW_OBJS = \
V3Begin.o \
V3Branch.o \
V3Broken.o \
V3CCtors.o \
V3Case.o \
V3Cast.o \
V3Cdc.o \
@@ -212,6 +213,7 @@ RAW_OBJS = \
V3Number.o \
V3Options.o \
V3Order.o \
V3Os.o \
V3Param.o \
V3PreShell.o \
V3Premit.o \
@@ -277,16 +279,16 @@ V3Number_test: V3Number_test.o
$(OBJCACHE) ${CC} ${CPPFLAGSWALL} -c $<
V3ParseLex.o: V3ParseLex.cpp V3Lexer.yy.cpp V3ParseBison.c
$(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
$(OBJCACHE) ${CXX} ${CPPFLAGSPARSER} -c $<
V3ParseGrammar.o: V3ParseGrammar.cpp V3ParseBison.c
$(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
$(OBJCACHE) ${CXX} ${CPPFLAGSPARSER} -c $<
V3ParseImp.o: V3ParseImp.cpp V3ParseBison.c
$(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
$(OBJCACHE) ${CXX} ${CPPFLAGSPARSER} -c $<
V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp
$(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
$(OBJCACHE) ${CXX} ${CPPFLAGSPARSER} -c $<
#### Generated files
@@ -295,7 +297,7 @@ serial:: V3Ast__gen_classes.h V3ParseBison.c
serial_vlcov:: vlcovgen.d
vlcovgen.d: $(VLCOVGEN) $(srcdir)/include/verilated_cov_key.h
vlcovgen.d: $(VLCOVGEN) $(srcdir)/../include/verilated_cov_key.h
$(PERL) $(VLCOVGEN) --srcdir $(srcdir)
touch $@
@@ -323,6 +325,8 @@ V3PreLex_pregen.yy.cpp: V3PreLex.l $(HEADERS)
V3PreLex.yy.cpp: V3PreLex_pregen.yy.cpp $(FLEXFIX)
$(PERL) $(FLEXFIX) V3PreLex <$< >$@
.SUFFIXES:
######################################################################
######################################################################
+55 -42
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2014 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.
@@ -73,7 +73,7 @@ private:
m_scopep->addActivep(nodep);
}
// VISITORS
virtual void visit(AstScope* nodep, AstNUser*) {
virtual void visit(AstScope* nodep) {
m_scopep = nodep;
m_iActivep = NULL;
m_cActivep = NULL;
@@ -81,15 +81,15 @@ private:
nodep->iterateChildren(*this);
// Don't clear scopep, the namer persists beyond this visit
}
virtual void visit(AstSenTree* nodep, AstNUser*) {
virtual void visit(AstSenTree* nodep) {
// Simplify sensitivity list
V3Const::constifyExpensiveEdit(nodep); nodep=NULL;
V3Const::constifyExpensiveEdit(nodep); VL_DANGLING(nodep);
}
// Empty visitors, speed things up
virtual void visit(AstNodeStmt* nodep, AstNUser*) { }
virtual void visit(AstNodeStmt* nodep) { }
//--------------------
// Default
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
// Default: Just iterate
nodep->iterateChildren(*this);
}
@@ -163,29 +163,33 @@ public:
class ActiveDlyVisitor : public ActiveBaseVisitor {
public:
enum CheckType { CT_SEQ, CT_COMBO, CT_INITIAL };
enum CheckType { CT_SEQ, CT_COMBO, CT_INITIAL, CT_LATCH };
private:
CheckType m_check; // Combo logic or other
AstNode* m_alwaysp; // Always we're under
AstNode* m_assignp; // In assign
// VISITORS
virtual void visit(AstAssignDly* nodep, AstNUser*) {
virtual void visit(AstAssignDly* nodep) {
if (m_check != CT_SEQ) {
// 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(),
nodep->rhsp()->unlinkFrBack());
nodep->replaceWith(newp);
nodep->deleteTree(); nodep = NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
}
virtual void visit(AstAssign* nodep, AstNUser*) {
virtual void visit(AstAssign* nodep) {
if (m_check == CT_SEQ) {
AstNode* las = m_assignp;
m_assignp = nodep;
@@ -193,7 +197,7 @@ private:
m_assignp = las;
}
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
virtual void visit(AstVarRef* nodep) {
AstVar* varp=nodep->varp();
if (m_check == CT_SEQ
&& m_assignp
@@ -212,7 +216,7 @@ private:
}
}
//--------------------
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
@@ -242,7 +246,7 @@ private:
bool m_itemSequent; // Found a SenItem sequential
// VISITORS
virtual void visit(AstScope* nodep, AstNUser*) {
virtual void visit(AstScope* nodep) {
// Create required actives and add to scope
UINFO(4," SCOPE "<<nodep<<endl);
// Clear last scope's names, and collect this scope's existing names
@@ -250,10 +254,10 @@ private:
m_scopeFinalp = NULL;
nodep->iterateChildren(*this);
}
virtual void visit(AstActive* nodep, AstNUser*) {
virtual void visit(AstActive* nodep) {
// Actives are being formed, so we can ignore any already made
}
virtual void visit(AstInitial* nodep, AstNUser*) {
virtual void visit(AstInitial* nodep) {
// Relink to IACTIVE, unless already under it
UINFO(4," INITIAL "<<nodep<<endl);
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
@@ -261,32 +265,32 @@ private:
nodep->unlinkFrBack();
wantactivep->addStmtsp(nodep);
}
virtual void visit(AstAssignAlias* nodep, AstNUser*) {
virtual void visit(AstAssignAlias* nodep) {
// Relink to CACTIVE, unless already under it
UINFO(4," ASSIGNW "<<nodep<<endl);
AstActive* wantactivep = m_namer.getCActive(nodep->fileline());
nodep->unlinkFrBack();
wantactivep->addStmtsp(nodep);
}
virtual void visit(AstAssignW* nodep, AstNUser*) {
virtual void visit(AstAssignW* nodep) {
// Relink to CACTIVE, unless already under it
UINFO(4," ASSIGNW "<<nodep<<endl);
AstActive* wantactivep = m_namer.getCActive(nodep->fileline());
nodep->unlinkFrBack();
wantactivep->addStmtsp(nodep);
}
virtual void visit(AstCoverToggle* nodep, AstNUser*) {
virtual void visit(AstCoverToggle* nodep) {
// Relink to CACTIVE, unless already under it
UINFO(4," COVERTOGGLE "<<nodep<<endl);
AstActive* wantactivep = m_namer.getCActive(nodep->fileline());
nodep->unlinkFrBack();
wantactivep->addStmtsp(nodep);
}
virtual void visit(AstFinal* nodep, AstNUser*) {
virtual void visit(AstFinal* nodep) {
// Relink to CFUNC for the final
UINFO(4," FINAL "<<nodep<<endl);
if (!nodep->bodysp()) { // Empty, Kill it.
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return;
}
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
@@ -302,11 +306,11 @@ private:
nodep->unlinkFrBack();
m_scopeFinalp->addStmtsp(new AstComment(nodep->fileline(), nodep->typeName()));
m_scopeFinalp->addStmtsp(nodep->bodysp()->unlinkFrBackWithNext());
nodep->deleteTree(); nodep = NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
// METHODS
void visitAlways(AstNode* nodep, AstSenTree* oldsensesp) {
void visitAlways(AstNode* nodep, AstSenTree* oldsensesp, VAlwaysKwd kwd) {
// Move always to appropriate ACTIVE based on its sense list
if (oldsensesp
&& oldsensesp->sensesp()
@@ -314,20 +318,22 @@ private:
&& oldsensesp->sensesp()->castSenItem()->isNever()) {
// Never executing. Kill it.
if (oldsensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return;
}
// Read sensitivitues
m_itemCombo = false;
m_itemSequent = false;
oldsensesp->iterateAndNext(*this);
if (oldsensesp) oldsensesp->iterateAndNext(*this);
bool combo = m_itemCombo;
bool sequent = m_itemSequent;
if (!combo && !sequent) combo=true; // If no list, Verilog 2000: always @ (*)
if (combo && sequent) {
nodep->v3error("Unsupported: Mixed edge (pos/negedge) and activity (no edge) sensitive activity list");
if (!v3Global.opt.bboxUnsup()) {
nodep->v3error("Unsupported: Mixed edge (pos/negedge) and activity (no edge) sensitive activity list");
}
sequent = false;
}
@@ -349,7 +355,7 @@ private:
// Delete sensitivity list
if (oldsensesp) {
oldsensesp->unlinkFrBackWithNext()->deleteTree(); oldsensesp=NULL;
oldsensesp->unlinkFrBackWithNext()->deleteTree(); VL_DANGLING(oldsensesp);
}
// Move node to new active
@@ -358,31 +364,35 @@ private:
// Warn and/or convert any delayed assignments
if (combo && !sequent) {
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_COMBO);
if (kwd == VAlwaysKwd::ALWAYS_LATCH) {
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_LATCH);
} else {
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_COMBO);
}
}
else if (!combo && sequent) {
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_SEQ);
}
}
virtual void visit(AstAlways* nodep, AstNUser*) {
virtual void visit(AstAlways* nodep) {
// Move always to appropriate ACTIVE based on its sense list
UINFO(4," ALW "<<nodep<<endl);
//if (debug()>=9) nodep->dumpTree(cout," Alw: ");
if (!nodep->bodysp()) {
// Empty always. Kill it.
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return;
}
visitAlways(nodep, nodep->sensesp());
visitAlways(nodep, nodep->sensesp(), nodep->keyword());
}
virtual void visit(AstAlwaysPublic* nodep, AstNUser*) {
virtual void visit(AstAlwaysPublic* nodep) {
// Move always to appropriate ACTIVE based on its sense list
UINFO(4," ALWPub "<<nodep<<endl);
//if (debug()>=9) nodep->dumpTree(cout," Alw: ");
visitAlways(nodep, nodep->sensesp());
visitAlways(nodep, nodep->sensesp(), VAlwaysKwd::ALWAYS);
}
virtual void visit(AstSenGate* nodep, AstNUser*) {
virtual void visit(AstSenGate* nodep) {
AstSenItem* subitemp = nodep->sensesp();
if (subitemp->edgeType() != AstEdgeType::ET_ANYEDGE
&& subitemp->edgeType() != AstEdgeType::ET_POSEDGE
@@ -391,12 +401,12 @@ private:
}
nodep->iterateChildren(*this);
}
virtual void visit(AstSenItem* nodep, AstNUser*) {
virtual void visit(AstSenItem* nodep) {
if (nodep->edgeType() == AstEdgeType::ET_ANYEDGE) {
m_itemCombo = true;
// Delete the sensitivity
// We'll add it as a generic COMBO SenItem in a moment.
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
} else if (nodep->varrefp()) {
// V3LinkResolve should have cleaned most of these up
if (!nodep->varrefp()->width1()) nodep->v3error("Unsupported: Non-single bit wide signal pos/negedge sensitivity: "
@@ -407,15 +417,15 @@ private:
}
// Empty visitors, speed things up
virtual void visit(AstNodeMath* nodep, AstNUser*) {}
virtual void visit(AstVarScope* nodep, AstNUser*) {}
virtual void visit(AstNodeMath* nodep) {}
virtual void visit(AstVarScope* nodep) {}
//--------------------
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
ActiveVisitor(AstNetlist* nodep) {
explicit ActiveVisitor(AstNetlist* nodep) {
m_scopeFinalp = NULL;
m_itemCombo = false;
m_itemSequent = false;
@@ -429,5 +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-2014 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 -17
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2014 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.
@@ -65,19 +65,19 @@ private:
}
// VISITORS
virtual void visit(AstTopScope* nodep, AstNUser*) {
virtual void visit(AstTopScope* nodep) {
m_topscopep = nodep;
m_finder.main(m_topscopep);
nodep->iterateChildren(*this);
m_topscopep = NULL;
}
virtual void visit(AstNodeModule* nodep, AstNUser*) {
virtual void visit(AstNodeModule* nodep) {
// Create required actives and add to module
// We can start ordering at a module, or a scope
UINFO(4," MOD "<<nodep<<endl);
nodep->iterateChildren(*this);
}
virtual void visit(AstActive* nodep, AstNUser*) {
virtual void visit(AstActive* nodep) {
UINFO(4," ACTIVE "<<nodep<<endl);
V3Const::constifyExpensiveEdit(nodep); // Remove duplicate clocks and such; sensesp() may change!
AstSenTree* sensesp = nodep->sensesp();
@@ -87,7 +87,7 @@ private:
&& sensesp->sensesp()->castSenItem()->isNever()) {
// Never executing. Kill it.
if (sensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return;
}
// Copy combo tree to settlement tree with duplicated statements
@@ -108,7 +108,7 @@ private:
// Move the active's contents to the other active
UINFO(4," merge active "<<sensesp<<" into "<<wantp<<endl);
if (nodep->sensesStorep()) {
if (sensesp != nodep->sensesStorep()) nodep->v3fatalSrc("sensesStore should have been deleted earlier if different\n");
if (sensesp != nodep->sensesStorep()) nodep->v3fatalSrc("sensesStore should have been deleted earlier if different");
sensesp->unlinkFrBack();
// There may be other references to same sense tree,
// we'll be removing all references when we get to them,
@@ -120,34 +120,34 @@ private:
// No need to do statements under it, they're already moved.
//nodep->iterateChildren(*this);
}
virtual void visit(AstInitial* nodep, AstNUser*) {
virtual void visit(AstInitial* nodep) {
nodep->v3fatalSrc("Node should have been under ACTIVE");
}
virtual void visit(AstAssignAlias* nodep, AstNUser*) {
virtual void visit(AstAssignAlias* nodep) {
nodep->v3fatalSrc("Node should have been under ACTIVE");
}
virtual void visit(AstAssignW* nodep, AstNUser*) {
virtual void visit(AstAssignW* nodep) {
nodep->v3fatalSrc("Node should have been under ACTIVE");
}
virtual void visit(AstAlways* nodep, AstNUser*) {
virtual void visit(AstAlways* nodep) {
nodep->v3fatalSrc("Node should have been under ACTIVE");
}
virtual void visit(AstAlwaysPublic* nodep, AstNUser*) {
virtual void visit(AstAlwaysPublic* nodep) {
nodep->v3fatalSrc("Node should have been under ACTIVE");
}
virtual void visit(AstFinal* nodep, AstNUser*) {
virtual void visit(AstFinal* nodep) {
nodep->v3fatalSrc("Node should have been deleted");
}
// Empty visitors, speed things up
virtual void visit(AstNodeMath* nodep, AstNUser*) {}
virtual void visit(AstVarScope* nodep, AstNUser*) {}
virtual void visit(AstNodeMath* nodep) {}
virtual void visit(AstVarScope* nodep) {}
//--------------------
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
ActiveTopVisitor(AstNetlist* nodep) {
explicit ActiveTopVisitor(AstNetlist* nodep) {
m_topscopep = NULL;
nodep->accept(*this);
}
@@ -159,5 +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-2014 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.
+74 -50
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2005-2014 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,26 +88,17 @@ private:
return newp;
}
AstNode* newIfCoverageOn(AstNode* nodep) {
// Add a internal if to check coverage is on
// Don't make this a AND term, as it's unlikely to need to test this.
AstNode* newp
= new AstIf (nodep->fileline(),
// If assertions are off, have constant propagation rip them out later
// This allows syntax errors and such to be detected normally.
(v3Global.opt.coverage()
? (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicTrue()))
: (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicFalse()))),
nodep, NULL);
newp->user1(true); // Don't assert/cover this if
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;
}
@@ -120,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 {
@@ -131,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 (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,
@@ -153,7 +162,7 @@ private:
nodep->replaceWith(newp);
}
// Bye
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
void newVAssertion(AstVAssert* nodep, AstNode* propp) {
@@ -175,10 +184,10 @@ private:
// Install it
nodep->replaceWith(newp);
// Bye
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstIf* nodep, AstNUser*) {
virtual void visit(AstIf* nodep) {
if (nodep->user1SetOnce()) return;
if (nodep->uniquePragma() || nodep->unique0Pragma()) {
AstNodeIf* ifp = nodep;
@@ -192,12 +201,12 @@ private:
// Recurse into the true case.
ifp->ifsp()->iterateAndNext(*this);
// If the last else is not an else if, recurse into that too.
if (ifp->elsesp() && !nextifp) {
ifp->elsesp()->iterateAndNext(*this);
}
// Build a bitmask of the true predicates
AstNode* predp = ifp->condp()->cloneTree(false);
if (propp) {
@@ -210,18 +219,21 @@ private:
if (ifp->elsesp() && !nextifp) {
hasDefaultElse = true;
}
ifp = nextifp;
} while (ifp);
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)
? (new AstOneHot0(nodep->fileline(), propp))->castNode()
: (new AstOneHot (nodep->fileline(), propp))->castNode());
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
: static_cast<AstNode*>(new AstOneHot (nodep->fileline(), propp)));
AstIf* checkifp = new AstIf (nodep->fileline(),
new AstLogNot (nodep->fileline(), ohot),
newFireAssert(nodep, "'unique if' statement violated"),
@@ -235,7 +247,7 @@ private:
}
// VISITORS //========== Case assertions
virtual void visit(AstCase* nodep, AstNUser*) {
virtual void visit(AstCase* nodep) {
nodep->iterateChildren(*this);
if (!nodep->user1SetOnce()) {
bool has_default=false;
@@ -260,17 +272,27 @@ private:
AstNode* propp = NULL;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
AstNode* onep = new AstEq(icondp->fileline(),
nodep->exprp()->cloneTree(false),
icondp->cloneTree(false));
AstNode* onep;
if (nodep->casex() || nodep->casez() || nodep->caseInside()) {
onep = AstEqWild::newTyped(itemp->fileline(),
nodep->exprp()->cloneTree(false),
icondp->cloneTree(false));
} else {
onep = AstEq::newTyped(icondp->fileline(),
nodep->exprp()->cloneTree(false),
icondp->cloneTree(false));
}
if (propp) propp = new AstConcat(icondp->fileline(), onep, propp);
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
? (new AstOneHot0(nodep->fileline(), propp))->castNode()
: (new AstOneHot (nodep->fileline(), propp))->castNode());
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
: static_cast<AstNode*>(new AstOneHot (nodep->fileline(), propp)));
AstIf* ifp = new AstIf (nodep->fileline(),
new AstLogNot (nodep->fileline(), ohot),
newFireAssert(nodep, "synthesis parallel_case, but multiple matches found"),
@@ -283,7 +305,7 @@ private:
}
// VISITORS //========== Statements
virtual void visit(AstDisplay* nodep, AstNUser*) {
virtual void visit(AstDisplay* nodep) {
nodep->iterateChildren(*this);
// Replace the special types with standard text
if (nodep->displayType()==AstDisplayType::DT_INFO) {
@@ -296,27 +318,26 @@ private:
}
}
virtual void visit(AstPslCover* nodep, AstNUser*) {
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()); nodep=NULL;
++m_statAsCover;
nodep->stmtsp(), nodep->name()); VL_DANGLING(nodep);
}
virtual void visit(AstVAssert* nodep, AstNUser*) {
virtual void visit(AstVAssert* nodep) {
nodep->iterateChildren(*this);
newVAssertion(nodep, nodep->propp()); nodep=NULL;
newVAssertion(nodep, nodep->propp()); VL_DANGLING(nodep);
++m_statAsSV;
}
virtual void visit(AstNodeModule* nodep, AstNUser*) {
virtual void visit(AstNodeModule* nodep) {
m_modp = nodep;
//
nodep->iterateChildren(*this);
// Reset defaults
m_modp = NULL;
}
virtual void visit(AstBegin* nodep, AstNUser*) {
virtual void visit(AstBegin* nodep) {
// This code is needed rather than a visitor in V3Begin,
// because V3Assert is called before V3Begin
AstBegin* lastp = m_beginp;
@@ -327,12 +348,12 @@ private:
m_beginp = lastp;
}
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
// CONSTRUCTORS
AssertVisitor(AstNetlist* nodep) {
explicit AssertVisitor(AstNetlist* nodep) {
m_beginp = NULL;
m_modp = NULL;
// Process
@@ -351,5 +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-2014 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.
+13 -10
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2005-2014 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.
@@ -73,7 +73,7 @@ private:
}
// VISITORS //========== Statements
virtual void visit(AstClocking* nodep, AstNUser*) {
virtual void visit(AstClocking* nodep) {
UINFO(8," CLOCKING"<<nodep<<endl);
// Store the new default clock, reset on new module
m_seniDefaultp = nodep->sensesp();
@@ -83,17 +83,17 @@ private:
} else {
nodep->unlinkFrBack();
}
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstPslCover* nodep, AstNUser*) {
virtual void visit(AstNodePslCoverOrAssert* nodep) {
if (nodep->sentreep()) return; // Already processed
clearAssertInfo();
nodep->iterateChildren(*this);
nodep->sentreep(newSenTree(nodep));
clearAssertInfo();
}
virtual void visit(AstPslClocked* nodep, AstNUser*) {
virtual void visit(AstPslClocked* nodep) {
nodep->iterateChildren(*this);
if (m_senip) {
nodep->v3error("Unsupported: Only one PSL clock allowed per assertion");
@@ -109,20 +109,20 @@ private:
// Unlink and just keep a pointer to it, convert to sentree as needed
m_senip = nodep->sensesp();
nodep->replaceWith(blockp);
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstNodeModule* nodep, AstNUser*) {
virtual void visit(AstNodeModule* nodep) {
nodep->iterateChildren(*this);
// Reset defaults
m_seniDefaultp = NULL;
}
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
// CONSTRUCTORS
AssertPreVisitor(AstNetlist* nodep) {
explicit AssertPreVisitor(AstNetlist* nodep) {
m_seniDefaultp = NULL;
clearAssertInfo();
// Process
@@ -136,5 +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-2014 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.
+201 -160
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2014 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,6 +28,7 @@
#include "V3File.h"
#include "V3Global.h"
#include "V3Broken.h"
#include "V3String.h"
//======================================================================
// Statics
@@ -79,30 +80,30 @@ void AstNode::init() {
// Attributes
m_didWidth = false;
m_doingWidth = false;
m_user1p = NULL;
m_user1u = VNUser(0);
m_user1Cnt = 0;
m_user2p = NULL;
m_user2u = VNUser(0);
m_user2Cnt = 0;
m_user3p = NULL;
m_user3u = VNUser(0);
m_user3Cnt = 0;
m_user4p = NULL;
m_user4u = VNUser(0);
m_user4Cnt = 0;
m_user5p = NULL;
m_user5u = VNUser(0);
m_user5Cnt = 0;
}
string AstNode::encodeName(const string& namein) {
// Encode signal name raw from parser, then not called again on same signal
const char* start = namein.c_str();
string out;
for (const char* pos = start; *pos; pos++) {
if ((pos==start) ? isalpha(pos[0]) // digits can't lead identifiers
for (string::const_iterator pos = namein.begin(); pos!=namein.end(); ++pos) {
if ((pos==namein.begin()) ? isalpha(pos[0]) // digits can't lead identifiers
: isalnum(pos[0])) {
out += pos[0];
} else if (pos[0]=='_') {
if (pos[1]=='_') {
out += "_"; out += "__05F"; // hex(_) = 0x5F
pos++;
++pos;
if (pos==namein.end()) break;
} else {
out += pos[0];
}
@@ -115,6 +116,10 @@ string AstNode::encodeName(const string& namein) {
out += hex;
}
}
// Shorten names
// TODO long term use VName in place of "string name"
VName vname(out);
out = vname.hashedName();
return out;
}
@@ -161,40 +166,53 @@ string AstNode::vcdName(const string& namein) {
}
string AstNode::prettyName(const string& namein) {
// This function is somewhat hot, so we short-circuit some compares
string pretty;
pretty = "";
pretty.reserve(namein.length());
for (const char* pos = namein.c_str(); *pos; ) {
if (0==strncmp(pos,"__BRA__",7)) {
pretty += "[";
pos += 7;
}
else if (0==strncmp(pos,"__KET__",7)) {
pretty += "]";
pos += 7;
}
else if (0==strncmp(pos,"__DOT__",7)) {
if (pos[0]=='-' && pos[1]=='>') { // ->
pretty += ".";
pos += 7;
pos += 2;
continue;
}
else if (0==strncmp(pos,"__PVT__",7)) {
pretty += "";
pos += 7;
}
else if (pos[0]=='_' && pos[1]=='_' && pos[2]=='0'
&& isxdigit(pos[3]) && isxdigit(pos[4])) {
char value = 0;
value += 16*(isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10));
value += (isdigit(pos[4]) ? (pos[4]-'0') : (tolower(pos[4])-'a'+10));
pretty += value;
pos += 5;
}
else {
pretty += pos[0];
pos++;
if (pos[0]=='_' && pos[1]=='_') { // Short-circuit
if (0==strncmp(pos,"__BRA__",7)) {
pretty += "[";
pos += 7;
continue;
}
if (0==strncmp(pos,"__KET__",7)) {
pretty += "]";
pos += 7;
continue;
}
if (0==strncmp(pos,"__DOT__",7)) {
pretty += ".";
pos += 7;
continue;
}
if (0==strncmp(pos,"__PVT__",7)) {
pretty += "";
pos += 7;
continue;
}
if (pos[0]=='_' && pos[1]=='_' && pos[2]=='0'
&& isxdigit(pos[3]) && isxdigit(pos[4])) {
char value = 0;
value += 16*(isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10));
value += (isdigit(pos[4]) ? (pos[4]-'0') : (tolower(pos[4])-'a'+10));
pretty += value;
pos += 5;
continue;
}
}
// Default
pretty += pos[0];
++pos;
}
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
if (pretty.substr(0,5) == "TOP->") pretty.replace(0,5,"");
if (pretty[0]=='T' && pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
if (pretty[0]=='T' && pretty.substr(0,5) == "TOP->") pretty.replace(0,5,"");
return pretty;
}
@@ -211,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
@@ -226,20 +245,20 @@ inline void AstNode::debugTreeChange(const char* prefix, int lineno, bool next)
#endif
}
AstNode* AstNode::addNext(AstNode* newp) {
AstNode* AstNode::addNext(AstNode* nodep, AstNode* newp) {
// Add to m_nextp, returns this
UASSERT(newp,"Null item passed to addNext\n");
this->debugTreeChange("-addNextThs: ", __LINE__, false);
UDEBUGONLY(if (!newp) nodep->v3fatalSrc("Null item passed to addNext"););
nodep->debugTreeChange("-addNextThs: ", __LINE__, false);
newp->debugTreeChange("-addNextNew: ", __LINE__, true);
if (this == NULL) {
if (!nodep) { // verilog.y and lots of other places assume this
return (newp);
} else {
// Find end of old list
AstNode* oldtailp = this;
AstNode* oldtailp = nodep;
if (oldtailp->m_nextp) {
if (oldtailp->m_headtailp) {
oldtailp = oldtailp->m_headtailp; // This=beginning of list, jump to end
UASSERT(!oldtailp->m_nextp, "Node had next, but headtail says it shouldn't");
UDEBUGONLY(if (oldtailp->m_nextp) nodep->v3fatalSrc("Node had next, but headtail says it shouldn't"););
} else {
// Though inefficent, we are occasionally passed a addNext in the middle of a list.
while (oldtailp->m_nextp != NULL) oldtailp = oldtailp->m_nextp;
@@ -258,22 +277,22 @@ AstNode* AstNode::addNext(AstNode* newp) {
newp->editCountInc();
if (oldtailp->m_iterpp) *(oldtailp->m_iterpp) = newp; // Iterate on new item
}
this->debugTreeChange("-addNextOut:", __LINE__, true);
return this;
nodep->debugTreeChange("-addNextOut:", __LINE__, true);
return nodep;
}
AstNode* AstNode::addNextNull(AstNode* newp) {
if (!newp) return this;
return addNext(newp);
AstNode* AstNode::addNextNull(AstNode* nodep, AstNode* newp) {
if (!newp) return nodep;
return addNext(nodep, newp);
}
void AstNode::addNextHere(AstNode* newp) {
// Add to m_nextp on exact node passed, not at the end.
// This could be at head, tail, or both (single)
// New could be head of single node, or list
UASSERT(newp,"Null item passed to addNext");
UASSERT(this,"Null base node");
UASSERT(newp->backp()==NULL,"New node (back) already assigned?");
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
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();
@@ -316,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"););
@@ -329,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"););
@@ -342,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"););
@@ -355,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"););
@@ -368,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); }
}
@@ -412,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) {
@@ -460,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) {
@@ -512,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; }
@@ -596,12 +615,12 @@ void AstNode::swapWith (AstNode* bp) {
// Clone
AstNode* AstNode::cloneTreeIter() {
if (!this) return NULL;
// private: Clone single node and children
AstNode* newp = this->clone();
newp->op1p(this->m_op1p->cloneTreeIterList());
newp->op2p(this->m_op2p->cloneTreeIterList());
newp->op3p(this->m_op3p->cloneTreeIterList());
newp->op4p(this->m_op4p->cloneTreeIterList());
if (this->m_op1p) newp->op1p(this->m_op1p->cloneTreeIterList());
if (this->m_op2p) newp->op2p(this->m_op2p->cloneTreeIterList());
if (this->m_op3p) newp->op3p(this->m_op3p->cloneTreeIterList());
if (this->m_op4p) newp->op4p(this->m_op4p->cloneTreeIterList());
newp->m_iterpp = NULL;
newp->clonep(this); // Save pointers to/from both to simplify relinking.
this->clonep(newp); // Save pointers to/from both to simplify relinking.
@@ -609,10 +628,10 @@ AstNode* AstNode::cloneTreeIter() {
}
AstNode* AstNode::cloneTreeIterList() {
// Clone list of nodes, set m_headtailp
if (!this) return NULL;
// private: Clone list of nodes, set m_headtailp
AstNode* newheadp = NULL;
AstNode* newtailp = NULL;
// Audited to make sure this is never NULL
for (AstNode* oldp = this; oldp; oldp=oldp->m_nextp) {
AstNode* newp = oldp->cloneTreeIter();
newp->m_headtailp = NULL;
@@ -627,7 +646,7 @@ AstNode* AstNode::cloneTreeIterList() {
}
AstNode* AstNode::cloneTree(bool cloneNextLink) {
if (!this) return NULL;
if (!this) return NULL; // verilog.y relies on this
this->debugTreeChange("-cloneThs: ", __LINE__, cloneNextLink);
cloneClearTree();
AstNode* newp;
@@ -648,8 +667,8 @@ AstNode* AstNode::cloneTree(bool cloneNextLink) {
// Delete
void AstNode::deleteNode() {
if (!this) return;
UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n");
// private: Delete single node. Publicly call deleteTree() instead.
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;
@@ -659,23 +678,32 @@ 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() {
}
void AstNode::deleteTreeIter() {
if (!this) return;
// private: Delete list of nodes. Publicly call deleteTree() instead.
// Audited to make sure this is never NULL
for (AstNode* nodep=this, *nnextp; nodep; nodep=nnextp) {
nnextp = nodep->m_nextp;
// MUST be depth first!
nodep->m_op1p->deleteTreeIter();
nodep->m_op2p->deleteTreeIter();
nodep->m_op3p->deleteTreeIter();
nodep->m_op4p->deleteTreeIter();
if (nodep->m_op1p) nodep->m_op1p->deleteTreeIter();
if (nodep->m_op2p) nodep->m_op2p->deleteTreeIter();
if (nodep->m_op3p) nodep->m_op3p->deleteTreeIter();
if (nodep->m_op4p) nodep->m_op4p->deleteTreeIter();
nodep->m_nextp = NULL;
nodep->m_backp = NULL;
nodep->deleteNode();
@@ -685,8 +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.
if (!this) return;
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!
@@ -698,6 +725,7 @@ void AstNode::deleteTree() {
#ifdef VL_LEAK_CHECKS
void* AstNode::operator new(size_t size) {
// Optimization note: Aligning to cache line is a loss, due to lost packing
AstNode* objp = static_cast<AstNode*>(::operator new(size));
V3Broken::addNewed(objp);
return objp;
@@ -714,55 +742,55 @@ void AstNode::operator delete(void* objp, size_t size) {
//======================================================================
// Iterators
void AstNode::iterateChildren(AstNVisitor& v, AstNUser* vup) {
void AstNode::iterateChildren(AstNVisitor& v) {
// This is a very hot function
if (!this) return;
// Optimization note: Grabbing m_op#p->m_nextp is a net loss
ASTNODE_PREFETCH(m_op1p);
ASTNODE_PREFETCH(m_op2p);
ASTNODE_PREFETCH(m_op3p);
ASTNODE_PREFETCH(m_op4p);
// if () not needed since iterateAndNext accepts null this, but faster with it.
if (m_op1p) m_op1p->iterateAndNext(v, vup);
if (m_op2p) m_op2p->iterateAndNext(v, vup);
if (m_op3p) m_op3p->iterateAndNext(v, vup);
if (m_op4p) m_op4p->iterateAndNext(v, vup);
if (m_op1p) m_op1p->iterateAndNext(v);
if (m_op2p) m_op2p->iterateAndNext(v);
if (m_op3p) m_op3p->iterateAndNext(v);
if (m_op4p) m_op4p->iterateAndNext(v);
}
void AstNode::iterateChildrenConst(AstNVisitor& v, AstNUser* vup) {
void AstNode::iterateChildrenConst(AstNVisitor& v) {
// This is a very hot function
if (!this) return;
ASTNODE_PREFETCH(m_op1p);
ASTNODE_PREFETCH(m_op2p);
ASTNODE_PREFETCH(m_op3p);
ASTNODE_PREFETCH(m_op4p);
// if () not needed since iterateAndNext accepts null this, but faster with it.
if (m_op1p) m_op1p->iterateAndNextConst(v, vup);
if (m_op2p) m_op2p->iterateAndNextConst(v, vup);
if (m_op3p) m_op3p->iterateAndNextConst(v, vup);
if (m_op4p) m_op4p->iterateAndNextConst(v, vup);
if (m_op1p) m_op1p->iterateAndNextConst(v);
if (m_op2p) m_op2p->iterateAndNextConst(v);
if (m_op3p) m_op3p->iterateAndNextConst(v);
if (m_op4p) m_op4p->iterateAndNextConst(v);
}
void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
void AstNode::iterateAndNext(AstNVisitor& v) {
// This is a very hot function
// IMPORTANT: If you replace a node that's the target of this iterator,
// then the NEW node will be iterated on next, it isn't skipped!
// if (!this) return; // Part of for()
// Future versions of this function may require the node to have a back to be iterated;
// there's no lower level reason yet though the back must exist.
AstNode* nodep=this;
#ifdef VL_DEBUG // Otherwise too hot of a function for debug
if (VL_UNLIKELY(nodep && !nodep->m_backp)) nodep->v3fatalSrc("iterateAndNext node has no back");
#endif
while (nodep) {
if (nodep) ASTNODE_PREFETCH(nodep->m_nextp);
while (nodep) { // effectively: if (!this) return; // Callers rely on this
if (nodep->m_nextp) ASTNODE_PREFETCH(nodep->m_nextp->m_nextp);
AstNode* niterp = nodep; // This address may get stomped via m_iterpp if the node is edited
ASTNODE_PREFETCH(nodep->m_nextp);
// Desirable check, but many places where multiple iterations are OK
//if (VL_UNLIKELY(niterp->m_iterpp)) niterp->v3fatalSrc("IterateAndNext under iterateAndNext may miss edits");
// Optimization note: Doing PREFETCH_RW on m_iterpp is a net even
// cppcheck-suppress nullPointer
niterp->m_iterpp = &niterp;
niterp->accept(v, vup);
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
@@ -773,38 +801,37 @@ void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
}
}
void AstNode::iterateListBackwards(AstNVisitor& v, AstNUser* vup) {
if (!this) return;
void AstNode::iterateListBackwards(AstNVisitor& v) {
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
AstNode* nodep=this;
while (nodep->m_nextp) nodep=nodep->m_nextp;
while (nodep) {
// Edits not supported: nodep->m_iterpp = &nodep;
nodep->accept(v, vup);
nodep->accept(v);
if (nodep->backp()->m_nextp == nodep) nodep=nodep->backp();
else nodep = NULL; // else: backp points up the tree.
}
}
void AstNode::iterateChildrenBackwards(AstNVisitor& v, AstNUser* vup) {
if (!this) return;
this->op1p()->iterateListBackwards(v,vup);
this->op2p()->iterateListBackwards(v,vup);
this->op3p()->iterateListBackwards(v,vup);
this->op4p()->iterateListBackwards(v,vup);
void AstNode::iterateChildrenBackwards(AstNVisitor& v) {
if (m_op1p) m_op1p->iterateListBackwards(v);
if (m_op2p) m_op2p->iterateListBackwards(v);
if (m_op3p) m_op3p->iterateListBackwards(v);
if (m_op4p) m_op4p->iterateListBackwards(v);
}
void AstNode::iterateAndNextConst(AstNVisitor& v, AstNUser* vup) {
void AstNode::iterateAndNextConst(AstNVisitor& v) {
// Keep following the current list even if edits change it
if (!this) return;
for (AstNode* nodep=this; nodep; ) {
if (!this) return; // A few cases could be cleaned up, but want symmetry with iterateAndNext
for (AstNode* nodep=this; nodep; ) { // effectively: if (!this) return; // Callers rely on this
AstNode* nnextp = nodep->m_nextp;
ASTNODE_PREFETCH(nnextp);
nodep->accept(v, vup);
nodep->accept(v);
nodep = nnextp;
}
}
AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
AstNode* AstNode::iterateSubtreeReturnEdits(AstNVisitor& v) {
// Some visitors perform tree edits (such as V3Const), and may even
// replace/delete the exact nodep that the visitor is called with. If
// this happens, the parent will lose the handle to the node that was
@@ -814,15 +841,15 @@ AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
AstNode* nodep = this; // Note "this" may point to bogus point later in this function
if (nodep->castNetlist()) {
// Calling on top level; we know the netlist won't get replaced
nodep->accept(v, vup);
nodep->accept(v);
} else if (!nodep->backp()) {
// Calling on standalone tree; insert a shim node so we can keep track, then delete it on completion
AstBegin* tempp = new AstBegin(nodep->fileline(),"[EditWrapper]",nodep);
{
tempp->stmtsp()->accept(v, vup); nodep=NULL; // nodep to null as may be replaced
tempp->stmtsp()->accept(v); VL_DANGLING(nodep); // nodep to null as may be replaced
}
nodep = tempp->stmtsp()->unlinkFrBackWithNext();
tempp->deleteTree(); tempp=NULL;
tempp->deleteTree(); VL_DANGLING(tempp);
} else {
// Use back to determine who's pointing at us (IE assume new node grafts into same place as old one)
AstNode** nextnodepp = NULL;
@@ -833,7 +860,7 @@ AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
else if (this->m_backp->m_nextp == this) nextnodepp = &(this->m_backp->m_nextp);
if (!nextnodepp) this->v3fatalSrc("Node's back doesn't point to forward to node itself");
{
nodep->accept(v, vup); nodep=NULL; // nodep to null as may be replaced
nodep->accept(v); VL_DANGLING(nodep); // nodep to null as may be replaced
}
nodep = *nextnodepp; // Grab new node from point where old was connected
}
@@ -843,44 +870,54 @@ AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
//======================================================================
void AstNode::cloneRelinkTree() {
if (!this) return;
// private: Cleanup clone() operation on whole tree. Publicly call cloneTree() instead.
for (AstNode* nodep=this; nodep; nodep=nodep->m_nextp) {
if (m_dtypep && m_dtypep->clonep()) {
m_dtypep = m_dtypep->clonep()->castNodeDType();
m_dtypep = m_dtypep->clonep();
}
nodep->cloneRelink();
nodep->m_op1p->cloneRelinkTree();
nodep->m_op2p->cloneRelinkTree();
nodep->m_op3p->cloneRelinkTree();
nodep->m_op4p->cloneRelinkTree();
if (nodep->m_op1p) nodep->m_op1p->cloneRelinkTree();
if (nodep->m_op2p) nodep->m_op2p->cloneRelinkTree();
if (nodep->m_op3p) nodep->m_op3p->cloneRelinkTree();
if (nodep->m_op4p) nodep->m_op4p->cloneRelinkTree();
}
}
//======================================================================
// Comparison
bool AstNode::sameTreeIter(AstNode* node2p, bool ignNext, bool gateOnly) {
// Return true if the two trees are identical
if (this==NULL && node2p==NULL) return true;
if (this==NULL || node2p==NULL) return false;
if (this->type() != node2p->type()
|| this->dtypep() != node2p->dtypep()
|| !this->same(node2p)
|| (gateOnly && !this->isGateOptimizable())) {
bool AstNode::gateTreeIter() {
// private: Return true if the two trees are identical
if (!isGateOptimizable()) return false;
if (m_op1p && !m_op1p->gateTreeIter()) return false;
if (m_op2p && !m_op2p->gateTreeIter()) return false;
if (m_op3p && !m_op3p->gateTreeIter()) return false;
if (m_op4p && !m_op4p->gateTreeIter()) return false;
return true;
}
bool AstNode::sameTreeIter(AstNode* node1p, AstNode* node2p, bool ignNext, bool gateOnly) {
// private: Return true if the two trees are identical
if (!node1p && !node2p) return true;
if (!node1p || !node2p) return false;
if (node1p->type() != node2p->type()
|| node1p->dtypep() != node2p->dtypep()
|| !node1p->same(node2p)
|| (gateOnly && !node1p->isGateOptimizable())) {
return false;
}
return (this->op1p()->sameTreeIter(node2p->op1p(),false,gateOnly)
&& this->op2p()->sameTreeIter(node2p->op2p(),false,gateOnly)
&& this->op3p()->sameTreeIter(node2p->op3p(),false,gateOnly)
&& this->op4p()->sameTreeIter(node2p->op4p(),false,gateOnly)
&& (ignNext || this->nextp()->sameTreeIter(node2p->nextp(),false,gateOnly))
return (sameTreeIter(node1p->m_op1p, node2p->m_op1p,false,gateOnly)
&& sameTreeIter(node1p->m_op2p, node2p->m_op2p,false,gateOnly)
&& sameTreeIter(node1p->m_op3p, node2p->m_op3p,false,gateOnly)
&& sameTreeIter(node1p->m_op4p, node2p->m_op4p,false,gateOnly)
&& (ignNext || sameTreeIter(node1p->m_nextp, node2p->m_nextp,false,gateOnly))
);
}
//======================================================================
// Static utilities
ostream& operator<<(ostream& os, V3Hash rhs) {
ostream& operator<<(ostream& os, const V3Hash& rhs) {
return os<<hex<<setw(2)<<setfill('0')<<rhs.depth()
<<"_"<<setw(6)<<setfill('0')<<rhs.hshval();
}
@@ -897,6 +934,7 @@ V3Hash::V3Hash(const string& name) {
// Debugging
void AstNode::checkTreeIter(AstNode* backp) {
// private: Check a tree and children
if (backp != this->backp()) {
this->v3fatalSrc("Back node inconsistent");
}
@@ -905,15 +943,15 @@ void AstNode::checkTreeIter(AstNode* backp) {
if (op1p()||op2p()||op3p()||op4p())
this->v3fatalSrc("Terminal operation with non-terminals");
}
if (op1p()) op1p()->checkTreeIterList(this);
if (op2p()) op2p()->checkTreeIterList(this);
if (op3p()) op3p()->checkTreeIterList(this);
if (op4p()) op4p()->checkTreeIterList(this);
if (m_op1p) m_op1p->checkTreeIterList(this);
if (m_op2p) m_op2p->checkTreeIterList(this);
if (m_op3p) m_op3p->checkTreeIterList(this);
if (m_op4p) m_op4p->checkTreeIterList(this);
}
void AstNode::checkTreeIterList(AstNode* backp) {
// Check a (possible) list of nodes, this is always the head of the list
if (!this) v3fatalSrc("Null nodep");
// private: Check a (possible) list of nodes, this is always the head of the list
// Audited to make sure this is never NULL
AstNode* headp = this;
AstNode* tailp = this;
for (AstNode* nodep=headp; nodep; nodep=nodep->nextp()) {
@@ -927,7 +965,6 @@ void AstNode::checkTreeIterList(AstNode* backp) {
}
void AstNode::checkTree() {
if (!this) return;
if (!debug()) return;
if (this->backp()) {
// Linked tree- check only the passed node
@@ -938,17 +975,17 @@ void AstNode::checkTree() {
}
void AstNode::dumpGdb() { // For GDB only
if (!this) { cout<<"This=NULL"<<endl; return; }
if (!dynamic_cast<const AstNode*>(this)) { cout<<"This=NULL"<<endl; return; }
dumpGdbHeader();
cout<<" "; dump(cout); cout<<endl;
}
void AstNode::dumpGdbHeader() const { // For GDB only
if (!this) { cout<<"This=NULL"<<endl; return; }
if (!dynamic_cast<const AstNode*>(this)) { cout<<"This=NULL"<<endl; return; }
dumpPtrs(cout);
cout<<" Fileline = "<<fileline()<<endl;
}
void AstNode::dumpTreeGdb() { // For GDB only
if (!this) { cout<<"This=NULL"<<endl; return; }
if (!dynamic_cast<const AstNode*>(this)) { cout<<"This=NULL"<<endl; return; }
dumpGdbHeader();
dumpTree(cout);
}
@@ -988,7 +1025,6 @@ void AstNode::dumpPtrs(ostream& os) const {
}
void AstNode::dumpTree(ostream& os, const string& indent, int maxDepth) {
if (!this) return;
os<<indent<<" "<<this<<endl;
if (debug()>8) { os<<indent<<" "; dumpPtrs(os); }
if (maxDepth==1) {
@@ -1002,18 +1038,18 @@ void AstNode::dumpTree(ostream& os, const string& indent, int maxDepth) {
}
void AstNode::dumpTreeAndNext(ostream& os, const string& indent, int maxDepth) {
if (!this) return;
// Audited to make sure this is never NULL
for (AstNode* nodep=this; nodep; nodep=nodep->nextp()) {
nodep->dumpTree(os, indent, maxDepth);
}
}
void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
if (v3Global.opt.dumpTree() && doDump) {
if (doDump) {
{ // Write log & close
UINFO(2,"Dumping "<<filename<<endl);
const auto_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()
@@ -1036,8 +1072,16 @@ void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
editCountSetLast();
}
void AstNode::v3errorEndFatal(ostringstream& str) const { v3errorEnd(str); assert(0); }
void AstNode::v3errorEnd(ostringstream& str) const {
if (this && m_fileline) {
if (!dynamic_cast<const AstNode*>(this)) {
// No known cases cause this, but better than a core dump
if (debug()) UINFO(0, "-node: NULL. Please report this along with a --gdbbt backtrace as a Verilator bug.\n");
V3Error::v3errorEnd(str);
} else if (!m_fileline) {
V3Error::v3errorEnd(str);
} else {
ostringstream nsstr;
nsstr<<str.str();
if (debug()) {
@@ -1045,14 +1089,11 @@ void AstNode::v3errorEnd(ostringstream& str) const {
nsstr<<"-node: "; ((AstNode*)this)->dump(nsstr); nsstr<<endl;
}
m_fileline->v3errorEnd(nsstr);
} else {
V3Error::v3errorEnd(str);
}
}
string AstNode::warnMore() const {
if (this) return this->fileline()->warnMore();
else return V3Error::warnMore();
return fileline()->warnMore();
}
//======================================================================
+414 -217
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2014 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.
+144 -53
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2014 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"
@@ -53,7 +54,7 @@ const char* AstNodeVarRef::broken() const {
}
void AstNodeVarRef::cloneRelink() {
if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep()->castVar(); }
if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep(); }
}
int AstNodeSel::bitConst() const {
@@ -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);
}
@@ -140,6 +142,13 @@ AstNodeBiop* AstLte::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
}
}
AstNodeBiop* AstEqWild::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
if (lhsp->isDouble() && rhsp->isDouble()) {
return new AstEqD(fl, lhsp, rhsp);
} else {
return new AstEqWild(fl, lhsp, rhsp);
}
}
bool AstVar::isSigPublic() const {
return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar()));
@@ -195,6 +204,8 @@ string AstVar::verilogKwd() const {
return "tri";
} else if (varType()==AstVarType::WIRE) {
return "wire";
} else if (varType()==AstVarType::WREAL) {
return "wreal";
} else {
return dtypep()->name();
}
@@ -217,7 +228,7 @@ string AstVar::vlArgType(bool named, bool forReturn, bool forFunc) const {
arg += "float";
} else if (strtype) {
if (isInOnly()) arg += "const ";
arg += "string";
arg += "std::string";
} else if (widthMin() <= 8) {
arg += "CData";
} else if (widthMin() <= 16) {
@@ -229,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;
@@ -265,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 {
@@ -303,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 += "*";
@@ -317,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()) {
@@ -350,6 +419,27 @@ string AstVar::scType() const {
}
}
AstVar* AstVar::scVarRecurse(AstNode* nodep) {
// See if this is a SC assignment; if so return that type
// Historically sc variables are identified by a variable
// attribute. TODO it would better be a data type attribute.
if (AstVar* anodep = nodep->castVar()) {
if (anodep->isSc()) return anodep;
else return NULL;
}
else if (nodep->castVarRef()) {
if (nodep->castVarRef()->varp()->isSc()) return nodep->castVarRef()->varp();
else return NULL;
}
else if (nodep->castArraySel()) {
if (nodep->op1p()) if (AstVar* p = scVarRecurse(nodep->op1p())) return p;
if (nodep->op2p()) if (AstVar* p = scVarRecurse(nodep->op2p())) return p;
if (nodep->op3p()) if (AstVar* p = scVarRecurse(nodep->op3p())) return p;
if (nodep->op4p()) if (AstVar* p = scVarRecurse(nodep->op4p())) return p;
}
return NULL;
}
AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
// dimension passed from AstArraySel::dimension
// Dimension 0 means the VAR itself, 1 is the closest SEL to the AstVar,
@@ -365,6 +455,7 @@ AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
// TODO this function should be removed in favor of recursing the dtype(),
// as that allows for more complicated data types.
int dim = 0;
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
for (AstNodeDType* dtypep=this; dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
@@ -399,6 +490,7 @@ AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
uint32_t AstNodeDType::arrayUnpackedElements() {
uint32_t entries=1;
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
for (AstNodeDType* dtypep=this; dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) {
@@ -417,6 +509,7 @@ pair<uint32_t,uint32_t> AstNodeDType::dimensions(bool includeBasic) {
// How many array dimensions (packed,unpacked) does this Var have?
uint32_t packed = 0;
uint32_t unpacked = 0;
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
for (AstNodeDType* dtypep=this; dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
@@ -471,9 +564,9 @@ const char* AstScope::broken() const {
}
void AstScope::cloneRelink() {
if (m_aboveScopep && m_aboveScopep->clonep()) m_aboveScopep->clonep()->castScope();
if (m_aboveCellp && m_aboveCellp->clonep()) m_aboveCellp->clonep()->castCell();
if (m_modp && ((AstNode*)m_modp)->clonep()) ((AstNode*)m_modp)->clonep()->castNodeModule();
if (m_aboveScopep && m_aboveScopep->clonep()) m_aboveScopep->clonep();
if (m_aboveCellp && m_aboveCellp->clonep()) m_aboveCellp->clonep();
if (m_modp && ((AstNode*)m_modp)->clonep()) ((AstNode*)m_modp)->clonep();
}
string AstScope::nameDotless() const {
@@ -485,9 +578,9 @@ string AstScope::nameDotless() const {
return out;
}
string AstScopeName::scopePrettyName() const {
string AstScopeName::scopePrettyNameFormatter(AstText* scopeTextp) const {
string out;
for (AstText* textp=scopeAttrp(); textp; textp=textp->nextp()->castText()) {
for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
out += textp->text();
}
// TOP will be replaced by top->name()
@@ -497,9 +590,9 @@ string AstScopeName::scopePrettyName() const {
return AstNode::prettyName(out);
}
string AstScopeName::scopeSymName() const {
string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
string out;
for (AstText* textp=scopeAttrp(); textp; textp=textp->nextp()->castText()) {
for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
out += textp->text();
}
if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
@@ -515,46 +608,28 @@ string AstScopeName::scopeSymName() const {
return out;
}
string AstScopeName::scopeDpiName() const {
string out;
for (AstText* textp=scopeEntrp(); textp; textp=textp->nextp()->castText()) {
out += textp->text();
}
if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
if (out.substr(0,7) == "__DOT__") out.replace(0,7,"");
if (out.substr(0,1) == ".") out.replace(0,1,"");
string::size_type pos;
while ((pos=out.find(".")) != string::npos) {
out.replace(pos, 1, "__");
}
while ((pos=out.find("__DOT__")) != string::npos) {
out.replace(pos, 7, "__");
}
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;
@@ -748,10 +823,6 @@ void AstAlways::dump(ostream& str) {
if (keyword() != VAlwaysKwd::ALWAYS) str<<" ["<<keyword().ascii()<<"]";
}
void AstArraySel::dump(ostream& str) {
this->AstNode::dump(str);
str<<" [start:"<<start()<<"] [length:"<<length()<<"]";
}
void AstAttrOf::dump(ostream& str) {
this->AstNode::dump(str);
str<<" ["<<attrType().ascii()<<"]";
@@ -767,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(); }
}
@@ -838,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);
@@ -863,7 +936,7 @@ void AstNodeDType::dumpSmall(ostream& str) {
void AstNodeArrayDType::dumpSmall(ostream& str) {
this->AstNodeDType::dumpSmall(str);
if (castPackArrayDType()) str<<"p"; else str<<"u";
str<<" "<<declRange();
str<<declRange();
}
void AstNodeArrayDType::dump(ostream& str) {
this->AstNodeDType::dump(str);
@@ -875,6 +948,12 @@ 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);
str<<" -> "<<packagep();
}
void AstPackageImport::dump(ostream& str) {
this->AstNode::dump(str);
@@ -887,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) {
@@ -918,14 +1003,16 @@ void AstTypeTable::dump(ostream& str) {
for (DetailedMap::const_iterator it = mapr.begin(); it != mapr.end(); ++it) {
AstBasicDType* dtypep = it->second;
str<<endl; // Newline from caller, so newline first
stringstream nsstr;
str<<"\t\tdetailed -> ";
dtypep->dump(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]";
@@ -937,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); }
@@ -972,6 +1059,8 @@ 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();
}
void AstSenTree::dump(ostream& str) {
@@ -1006,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"; }
}
@@ -1016,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) {
+1265 -611
View File
File diff suppressed because it is too large Load Diff
+48 -20
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2014 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.
@@ -56,7 +56,7 @@ public:
m_anyFuncInBegin = false;
}
~BeginState() {}
void userMarkChanged(AstNodeFTask* nodep) {
void userMarkChanged(AstNode* nodep) {
nodep->user1(true);
m_anyFuncInBegin = true;
}
@@ -84,13 +84,13 @@ private:
}
// VISITORS
virtual void visit(AstNodeModule* nodep, AstNUser*) {
virtual void visit(AstNodeModule* nodep) {
m_modp = nodep;
m_repeatNum = 0;
nodep->iterateChildren(*this);
m_modp = NULL;
}
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
virtual void visit(AstNodeFTask* nodep) {
UINFO(8," "<<nodep<<endl);
// Rename it
if (m_unnamedScope != "") {
@@ -113,7 +113,7 @@ private:
m_namedScope = oldScope;
m_unnamedScope = oldUnnamed;
}
virtual void visit(AstBegin* nodep, AstNUser*) {
virtual void visit(AstBegin* nodep) {
// Begin blocks were only useful in variable creation, change names and delete
UINFO(8," "<<nodep<<endl);
string oldScope = m_namedScope;
@@ -160,21 +160,23 @@ private:
} else {
nodep->unlinkFrBack();
}
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstVar* nodep, AstNUser*) {
virtual void visit(AstVar* nodep) {
if (m_unnamedScope != "") {
// Rename it
nodep->name(m_unnamedScope+"__DOT__"+nodep->name());
m_statep->userMarkChanged(nodep);
// Move to module
nodep->unlinkFrBack();
if (m_ftaskp) m_ftaskp->addStmtsp(nodep); // Begins under funcs just move into the func
else m_modp->addStmtp(nodep);
}
}
virtual void visit(AstCell* nodep, AstNUser*) {
virtual void visit(AstCell* nodep) {
UINFO(8," CELL "<<nodep<<endl);
if (m_namedScope != "") {
m_statep->userMarkChanged(nodep);
// Rename it
nodep->name(m_namedScope+"__DOT__"+nodep->name());
UINFO(8," rename to "<<nodep->name()<<endl);
@@ -182,8 +184,16 @@ private:
nodep->unlinkFrBack();
m_modp->addStmtp(nodep);
}
nodep->iterateChildren(*this);
}
virtual void visit(AstScopeName* nodep, AstNUser*) {
virtual void visit(AstVarXRef* nodep) {
UINFO(9, " VARXREF "<<nodep<<endl);
if (m_namedScope != "" && nodep->inlinedDots() == "") {
nodep->inlinedDots(m_namedScope);
UINFO(9, " rescope to "<<nodep<<endl);
}
}
virtual void visit(AstScopeName* nodep) {
// If there's a %m in the display text, we add a special node that will contain the name()
// Similar code in V3Inline
if (nodep->user1SetOnce()) return; // Don't double-add text's
@@ -196,13 +206,13 @@ private:
}
nodep->iterateChildren(*this);
}
virtual void visit(AstCoverDecl* nodep, AstNUser*) {
virtual void visit(AstCoverDecl* nodep) {
// Don't need to fix path in coverage statements, they're not under
// any BEGINs, but V3Coverage adds them all under the module itself.
nodep->iterateChildren(*this);
}
// VISITORS - LINT CHECK
virtual void visit(AstIf* nodep, AstNUser*) { // Note not AstNodeIf; other types don't get covered
virtual void visit(AstIf* nodep) { // Note not AstNodeIf; other types don't get covered
// Check IFDEPTH warning - could be in other transform files if desire
int prevIfDepth = m_ifDepth;
if (m_ifDepth == -1 || v3Global.opt.ifDepth()<1) { // Turned off
@@ -215,8 +225,8 @@ private:
}
nodep->iterateChildren(*this);
m_ifDepth = prevIfDepth;
}
virtual void visit(AstNode* nodep, AstNUser*) {
}
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
@@ -242,15 +252,30 @@ private:
// AstNodeFTask::user1p // Node replaced, rename it
// VISITORS
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
virtual void visit(AstNodeFTaskRef* nodep) {
if (nodep->taskp()->user1()) { // It was converted
UINFO(9, " relinkFTask "<<nodep<<endl);
nodep->name(nodep->taskp()->name());
}
nodep->iterateChildren(*this);
}
virtual void visit(AstVarRef* nodep) {
if (nodep->varp()->user1()) { // It was converted
UINFO(9, " relinVarRef "<<nodep<<endl);
nodep->name(nodep->varp()->name());
}
nodep->iterateChildren(*this);
}
virtual void visit(AstIfaceRefDType* nodep) {
// May have changed cell names
// TypeTable is always after all modules, so names are stable
UINFO(8," IFACEREFDTYPE "<<nodep<<endl);
if (nodep->cellp()) nodep->cellName(nodep->cellp()->name());
UINFO(8," rename to "<<nodep<<endl);
nodep->iterateChildren(*this);
}
//--------------------
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
@@ -266,9 +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-2014 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 -6
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2014 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.
@@ -75,7 +75,7 @@ private:
}
// VISITORS
virtual void visit(AstNodeIf* nodep, AstNUser*) {
virtual void visit(AstNodeIf* nodep) {
UINFO(4," IF: "<<nodep<<endl);
int lastLikely = m_likely;
int lastUnlikely = m_unlikely;
@@ -101,17 +101,17 @@ private:
m_likely = lastLikely;
m_unlikely = lastUnlikely;
}
virtual void visit(AstCCall* nodep, AstNUser*) {
virtual void visit(AstCCall* nodep) {
checkUnlikely(nodep);
nodep->funcp()->user1Inc();
nodep->iterateChildren(*this);
}
virtual void visit(AstCFunc* nodep, AstNUser*) {
virtual void visit(AstCFunc* nodep) {
checkUnlikely(nodep);
m_cfuncsp.push_back(nodep);
nodep->iterateChildren(*this);
}
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
checkUnlikely(nodep);
nodep->iterateChildren(*this);
}
@@ -128,7 +128,7 @@ private:
public:
// CONSTUCTORS
BranchVisitor(AstNetlist* nodep) {
explicit BranchVisitor(AstNetlist* nodep) {
reset();
nodep->iterateChildren(*this);
calc_tasks();
+2 -2
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2014 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);
};
+46 -26
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2014 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.
@@ -31,7 +31,7 @@
#include <cstdarg>
#include <unistd.h>
#include <algorithm>
#include <map>
#include VL_INCLUDE_UNORDERED_MAP
#include "V3Global.h"
#include "V3Broken.h"
@@ -47,7 +47,7 @@ class BrokenTable : public AstNVisitor {
private:
// MEMBERS
// For each node, we keep if it exists or not.
typedef map<const AstNode*,int> NodeMap;
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
@@ -62,16 +62,20 @@ public:
if (debug()>=9) cout<<"-nodeDel: "<<(void*)(nodep)<<endl;
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter==s_nodes.end() || !(iter->second & FLAG_ALLOCATED)) {
((AstNode*)(nodep))->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted\n");
((AstNode*)(nodep))->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted");
}
if (iter!=s_nodes.end()) s_nodes.erase(iter);
}
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 4
// GCC 4.4.* compiler warning bug, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39390
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
static void addNewed(const AstNode* nodep) {
// Called by operator new on any node - only if VL_LEAK_CHECKS
if (debug()>=9) cout<<"-nodeNew: "<<(void*)(nodep)<<endl;
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter!=s_nodes.end() || (iter->second & FLAG_ALLOCATED)) {
((AstNode*)(nodep))->v3fatalSrc("Newing AstNode object that is already allocated\n");
nodep->v3fatalSrc("Newing AstNode object that is already allocated");
}
if (iter == s_nodes.end()) {
int flags = FLAG_ALLOCATED; // This int needed to appease GCC 4.1.2
@@ -94,16 +98,16 @@ public:
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter == s_nodes.end()) {
#ifdef VL_LEAK_CHECKS
nodep->v3fatalSrc("AstNode is in tree, but not allocated\n");
nodep->v3fatalSrc("AstNode is in tree, but not allocated");
#endif
} else {
if (!(iter->second & FLAG_ALLOCATED)) {
#ifdef VL_LEAK_CHECKS
nodep->v3fatalSrc("AstNode is in tree, but not allocated\n");
nodep->v3fatalSrc("AstNode is in tree, but not allocated");
#endif
}
if (iter->second & FLAG_IN_TREE) {
nodep->v3fatalSrc("AstNode is already in tree at another location\n");
nodep->v3fatalSrc("AstNode is already in tree at another location");
}
}
int or_flags = FLAG_IN_TREE | (linkable?FLAG_LINKABLE:0);
@@ -186,14 +190,18 @@ private:
// NODE STATE
// Nothing! // This may be called deep inside other routines
// // so userp and friends may not be used
// VISITORS
virtual void visit(AstNode* nodep, AstNUser*) {
// METHODS
void processAndIterate(AstNode* nodep) {
BrokenTable::addInTree(nodep, nodep->maybePointedTo());
nodep->iterateChildrenConst(*this);
}
// VISITORS
virtual void visit(AstNode* nodep) {
processAndIterate(nodep);
}
public:
// CONSTUCTORS
BrokenMarkVisitor(AstNetlist* nodep) {
explicit BrokenMarkVisitor(AstNetlist* nodep) {
nodep->accept(*this);
}
virtual ~BrokenMarkVisitor() {}
@@ -204,14 +212,23 @@ public:
class BrokenCheckVisitor : public AstNVisitor {
private:
virtual void visit(AstNode* nodep, AstNUser*) {
void checkWidthMin(AstNode* nodep) {
if (nodep->width() != nodep->widthMin()
&& v3Global.widthMinUsage()==VWidthMinUsage::MATCHES_WIDTH) {
nodep->v3fatalSrc("Width != WidthMin");
}
}
void processAndIterate(AstNode* nodep) {
BrokenTable::setUnder(nodep,true);
if (const char* whyp=nodep->broken()) {
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()) {
@@ -220,24 +237,27 @@ private:
if (nodep->dtypep()) nodep->v3fatalSrc("DType on node without hasDType(): "<<nodep->prettyTypeName());
}
if (nodep->getChildDTypep()) nodep->v3fatalSrc("childDTypep() non-null on node after should have removed");
if (AstNodeDType* dnodep = nodep->castNodeDType()) {
if (dnodep->width() != dnodep->widthMin()
&& v3Global.assertWidthsMatch()) {
dnodep->v3fatalSrc("Width != WidthMin");
}
}
}
if (v3Global.assertWidthsMatch()) {
if (nodep->width() != nodep->widthMin()) {
nodep->v3fatalSrc("Width != WidthMin");
}
if (AstNodeDType* dnodep = nodep->castNodeDType()) checkWidthMin(dnodep);
}
checkWidthMin(nodep);
nodep->iterateChildrenConst(*this);
BrokenTable::setUnder(nodep,false);
}
virtual void visit(AstNodeAssign* nodep) {
processAndIterate(nodep);
if (v3Global.assertDTypesResolved()
&& nodep->brokeLhsMustBeLvalue()
&& nodep->lhsp()->castNodeVarRef()
&& !nodep->lhsp()->castNodeVarRef()->lvalue()) {
nodep->v3fatalSrc("Assignment LHS is not an lvalue");
}
}
virtual void visit(AstNode* nodep) {
processAndIterate(nodep);
}
public:
// CONSTUCTORS
BrokenCheckVisitor(AstNetlist* nodep) {
explicit BrokenCheckVisitor(AstNetlist* nodep) {
nodep->accept(*this);
}
virtual ~BrokenCheckVisitor() {}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2014 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
View File
@@ -0,0 +1,174 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Generate C language constructors and AstCReset nodes.
//
// Code available from: http://www.veripool.org/verilator
//
//*************************************************************************
//
// 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.
//
//*************************************************************************
// V3CCtors's Transformations:
// Iterates over all modules and
// for all AstVar, create a creates a AstCReset node in an _ctor_var_reset AstCFunc.
// 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"
#include "verilatedos.h"
#include <cstdio>
#include <cstdarg>
#include <unistd.h>
#include <cmath>
#include <map>
#include <vector>
#include <algorithm>
#include "V3Global.h"
#include "V3EmitCBase.h"
#include "V3CCtors.h"
class V3CCtorsVisitor {
private:
string m_basename;
string m_argsp;
string m_callargsp;
AstNodeModule* m_modp; // Current module
AstCFunc* m_tlFuncp; // Top level function being built
AstCFunc* m_funcp; // Current function
int m_numStmts; // Number of statements output
int m_funcNum; // Function number being built
public:
void add(AstNode* nodep) {
if (v3Global.opt.outputSplitCFuncs()
&& v3Global.opt.outputSplitCFuncs() < m_numStmts) {
m_funcp = NULL;
}
if (!m_funcp) {
m_funcp = new AstCFunc(m_modp->fileline(), m_basename + "_" + cvtToStr(++m_funcNum), NULL, "void");
m_funcp->isStatic(false);
m_funcp->declPrivate(true);
m_funcp->slow(true);
m_funcp->argTypes(m_argsp);
m_modp->addStmtp(m_funcp);
// Add a top call to it
AstCCall* callp = new AstCCall(m_modp->fileline(), m_funcp);
callp->argTypes(m_callargsp);
m_tlFuncp->addStmtsp(callp);
m_numStmts = 0;
}
m_funcp->addStmtsp(nodep);
m_numStmts += 1;
}
V3CCtorsVisitor(AstNodeModule* nodep, const string& basename,
const string& argsp="", const string& callargsp="",
const string& stmt="") {
m_basename = basename;
m_argsp = argsp;
m_callargsp = callargsp;
m_modp = nodep;
m_numStmts = 0;
m_funcNum = 0;
m_tlFuncp = new AstCFunc(nodep->fileline(), basename, NULL, "void");
m_tlFuncp->declPrivate(true);
m_tlFuncp->isStatic(false);
m_tlFuncp->slow(true);
m_tlFuncp->argTypes(m_argsp);
if (stmt != "") {
m_tlFuncp->addStmtsp(new AstCStmt(nodep->fileline(), stmt));
}
m_funcp = m_tlFuncp;
m_modp->addStmtp(m_tlFuncp);
}
~V3CCtorsVisitor() {}
private:
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()) {
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");
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
if (AstCoverDecl* coverp = np->castCoverDecl()) {
AstNode* backp = coverp->backp();
coverp->unlinkFrBack();
configure_coverage.add(coverp);
np = backp;
}
}
}
}
}
+38
View File
@@ -0,0 +1,38 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Emit CFunc's for class construction and configuration
//
// Code available from: http://www.veripool.org/verilator
//
//*************************************************************************
//
// 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.
//
//*************************************************************************
#ifndef _V3CCTORS_H_
#define _V3CCTORS_H_ 1
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
//============================================================================
class V3CCtors {
public:
static void cctorsAll();
private:
static void evalAsserts();
};
#endif // Guard
+30 -27
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2014 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.
@@ -65,7 +65,7 @@ private:
return level;
}
virtual void visit(AstNodeCase* nodep, AstNUser*) {
virtual void visit(AstNodeCase* nodep) {
if (nodep->castCase() && nodep->castCase()->casex()) {
nodep->v3warn(CASEX,"Suggest casez (with ?'s) in place of casex (with X's)");
}
@@ -90,7 +90,7 @@ private:
m_caseExprp = NULL;
}
}
virtual void visit(AstConst* nodep, AstNUser*) {
virtual void visit(AstConst* nodep) {
// See also neverItem
if (m_caseExprp && nodep->num().isFourState()) {
if (m_caseExprp->castGenCase()) {
@@ -107,12 +107,12 @@ private:
}
}
}
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
CaseLintVisitor(AstNodeCase* nodep) {
explicit CaseLintVisitor(AstNodeCase* nodep) {
m_caseExprp = NULL;
nodep->accept(*this);
}
@@ -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;
@@ -174,7 +174,7 @@ private:
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
//if (debug()>=9) icondp->dumpTree(cout," caseitem: ");
AstConst* iconstp = icondp->castConst();
if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this\n");
if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this");
if (neverItem(nodep, iconstp)) {
// X in casez can't ever be executed
} else {
@@ -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;
@@ -246,7 +246,7 @@ private:
if (m_valueItem[a] != m_valueItem[b]) { same=false; break; }
}
if (same) {
tree1p->deleteTree(); tree1p=NULL;
tree1p->deleteTree(); VL_DANGLING(tree1p);
return tree0p;
}
@@ -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);
}
@@ -295,8 +295,8 @@ private:
if (ifrootp) nodep->replaceWith(ifrootp);
else nodep->unlinkFrBack();
nodep->deleteTree(); nodep=NULL;
cexprp->deleteTree(); cexprp=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
cexprp->deleteTree(); VL_DANGLING(cexprp);
if (debug()>=9) ifrootp->dumpTree(cout," _simp: ");
}
@@ -327,7 +327,7 @@ private:
AstConst* iconstp = icondp->castConst();
if (iconstp && neverItem(nodep, iconstp)) {
// X in casez can't ever be executed
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
icondp->deleteTree(); VL_DANGLING(icondp); VL_DANGLING(iconstp);
// For simplicity, make expression that is not equal, and let later
// optimizations remove it
condp = new AstConst(itemp->fileline(), AstConst::LogicFalse());
@@ -351,7 +351,7 @@ private:
AstNode* and2p = new AstAnd(itemp->fileline(),
new AstConst(itemp->fileline(), numval),
new AstConst(itemp->fileline(), nummask));
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
icondp->deleteTree(); VL_DANGLING(icondp); VL_DANGLING(iconstp);
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
} else {
// Not a caseX mask, we can simply build CASEEQ(cexpr icond)
@@ -369,7 +369,7 @@ private:
itemp->condsp(ifexprp);
}
}
cexprp->deleteTree(); cexprp=NULL;
cexprp->deleteTree(); VL_DANGLING(cexprp);
if (!hadDefault) {
// If there was no default, add a empty one, this greatly simplifies below code
// and constant propagation will just eliminate it for us later.
@@ -408,9 +408,9 @@ private:
}
}
{ // Make the new lower IF and attach in the tree
AstNode* itemexprp = ifexprp; ifexprp=NULL;
AstNode* itemexprp = ifexprp; VL_DANGLING(ifexprp);
if (depth == (CASE_ENCODER_GROUP_DEPTH)) { // End of group - can skip the condition
itemexprp->deleteTree(); itemexprp=NULL;
itemexprp->deleteTree(); VL_DANGLING(itemexprp);
itemexprp = new AstConst(itemp->fileline(), AstConst::LogicTrue());
}
AstIf* newp = new AstIf(itemp->fileline(), itemexprp, istmtsp, NULL);
@@ -423,10 +423,10 @@ private:
// Handle any assertions
replaceCaseParallel(nodep, false);
// Replace the CASE... with IF...
if (debug()>=9) grouprootp->dumpTree(cout," _new: ");
if (debug()>=9 && grouprootp) grouprootp->dumpTree(cout," _new: ");
if (grouprootp) nodep->replaceWith(grouprootp);
else nodep->unlinkFrBack();
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
void replaceCaseParallel(AstCase* nodep, bool noOverlapsAllCovered) {
@@ -451,7 +451,7 @@ private:
}
// VISITORS
virtual void visit(AstCase* nodep, AstNUser*) {
virtual void visit(AstCase* nodep) {
V3Case::caseLint(nodep);
nodep->iterateChildren(*this);
if (debug()>=9) nodep->dumpTree(cout," case_old: ");
@@ -459,21 +459,21 @@ private:
// It's a simple priority encoder or complete statement
// we can make a tree of statements to avoid extra comparisons
++m_statCaseFast;
replaceCaseFast(nodep); nodep=NULL;
replaceCaseFast(nodep); VL_DANGLING(nodep);
} else {
++m_statCaseSlow;
replaceCaseComplicated(nodep); nodep=NULL;
replaceCaseComplicated(nodep); VL_DANGLING(nodep);
}
}
//--------------------
// Default: Just iterate
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
CaseVisitor(AstNetlist* nodep) {
explicit CaseVisitor(AstNetlist* nodep) {
m_caseNoOverlapsAllCovered = false;
nodep->accept(*this);
}
@@ -488,7 +488,10 @@ 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) {
UINFO(4,__FUNCTION__<<": "<<endl);

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