Compare commits

...
191 Commits
Author SHA1 Message Date
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
572 changed files with 14223 additions and 6081 deletions
+4
View File
@@ -1,3 +1,5 @@
\#*
.#*
*~
*.old
*.gz
@@ -20,8 +22,10 @@ configure
dddrun*
doxygen-doc
gdbrun*
gmon.out
internals.txt
verilator.txt
verilator_bin*
verilator_coverage_bin*
verilator.pc
**/obj_dir/*
+180 -1
View File
@@ -2,6 +2,185 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. Thanks!
* 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
@@ -2770,7 +2949,7 @@ of input ports exists for tracing.
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
Copyright 2001-2016 by Wilson Snyder. This program is free software; you
Copyright 2001-2017 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+3
View File
@@ -20,6 +20,8 @@
/cov_work/
/logs/
^Makefile$
bin/verilator_bin.*
bin/verilator_coverage_bin.*
src/Makefile$
src/Makefile_obj$
include/verilated.mk$
@@ -39,5 +41,6 @@ nodist/
/vc_hdrs.h$
/csrc/
doxygen-doc/.*
obj_dir/.*
TAGS
.*~
+58 -44
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2017 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.
@@ -101,7 +101,9 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
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.pdf \
@@ -114,7 +116,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]* \
@@ -127,11 +133,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 \
@@ -151,9 +160,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)
@@ -180,33 +189,33 @@ 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` ; \
done
info: $(INFOS)
# Use --no-split to avoid creating filenames > 14 chars.
@@ -279,18 +288,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 )
@@ -312,12 +319,13 @@ 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)
@@ -329,15 +337,15 @@ 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)
@@ -356,8 +364,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; \
@@ -380,8 +388,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 \
@@ -419,12 +427,15 @@ 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) $<
ftp: info
install-msg:
@echo "Installed!"
@echo
@echo "Installed binaries to $(DESTDIR)$(bindir)/verilator"
@echo "Installed man to $(DESTDIR)$(mandir)/man1"
@echo "Installed examples to $(DESTDIR)$(pkgdatadir)/examples"
@echo
@echo "For documentation see 'man verilator' or 'verilator --help'"
@echo "For forums and to report bugs see http://www.veripool.org/verilator"
@@ -452,7 +463,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 \
@@ -466,10 +477,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 \
+9 -6
View File
@@ -11,7 +11,7 @@ This is the Verilator package README file.
http://www.veripool.org/verilator
This package is Copyright 2003-2016 by Wilson Snyder. (Report bugs to
This package is Copyright 2003-2017 by Wilson Snyder. (Report bugs to
L<http://www.veripool.org/>.)
Verilator is free software; you can redistribute it and/or modify it under
@@ -51,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
@@ -169,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
@@ -190,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
+2 -2
View File
@@ -1,6 +1,6 @@
// DESCRIPTION: Verilator: List of To Do issues.
//
// Copyright 2004-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -41,7 +41,7 @@ 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
+228 -94
View File
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
######################################################################
#
# Copyright 2003-2016 by Wilson Snyder. This program is free software; you
# Copyright 2003-2017 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.
@@ -182,7 +182,9 @@ sub run {
warn "%Error: $command\n";
}
if ($status & 127) {
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
if (($status & 127) == 4 # SIGILL
|| ($status & 127) == 8 # SIGFPA
|| ($status & 127) == 11) { # SIGSEGV
warn "%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt\n" if !$Debug;
} elsif (($status & 127) == 6) { # SIGABRT
warn "%Error: Verilator aborted. Consider trying --debug --gdbbt\n" if !$Debug;
@@ -209,9 +211,9 @@ Verilator - Convert Verilog code to C++/SystemC
verilator --help
verilator --version
verilator --cc [options] [top_level.v]... [opt_c_files.cpp/c/cc/a/o/so]
verilator --sc [options] [top_level.v]... [opt_c_files.cpp/c/cc/a/o/so]
verilator --lint-only [top_level.v]...
verilator --cc [options] [source_files.v]... [opt_c_files.cpp/c/cc/a/o/so]
verilator --sc [options] [source_files.v]... [opt_c_files.cpp/c/cc/a/o/so]
verilator --lint-only [source_files.v]...
=head1 DESCRIPTION
@@ -239,7 +241,7 @@ To get started, jump down to "EXAMPLE C++ EXECUTION".
This is a short summary of the arguments to Verilator. See the detailed
descriptions in the next sections for more information.
{file.v} Verilog top level filenames
{file.v} Verilog package, module and top module filenames
{file.c/cc/cpp} Optional C++ files to compile in
{file.a/o/so} Optional C++ files to link in
@@ -280,9 +282,11 @@ descriptions in the next sections for more information.
--exe Link to create executable
-F <file> Parse options from a file, relatively
-f <file> Parse options from a file
-FI <file> Force include of a file
-G<name>=<value> Overwrite toplevel parameter
--gdb Run Verilator under GDB interactively
--gdbbt Run Verilator under GDB for backtrace
--getenv <var> Get environment variable with defaults
--help Display this help
-I<dir> Directory to search for includes
--if-depth <value> Tune IFDEPTH warning
@@ -323,6 +327,8 @@ descriptions in the next sections for more information.
--private Debugging; see docs
--public Debugging; see docs
-pvalue+<name>=<value> Overwrite toplevel parameter
--relative-includes Resolve includes relative to current file
--no-relative-cfuncs Disallow 'this->' in generated functions
--report-unoptflat Extra diagnostics for UNOPTFLAT
--savable Enable model save-restore
--sc Create SystemC output
@@ -347,13 +353,15 @@ descriptions in the next sections for more information.
+verilog1995ext+<ext> Synonym for +1364-1995ext+<ext>
+verilog2001ext+<ext> Synonym for +1364-2001ext+<ext>
--vpi Enable VPI compiles
-Werror-<message> Convert warning to error
-Wall Enable all style warnings
-Werror-<message> Convert warnings to errors
-Wfuture-<message> Disable unknown message warnings
-Wno-<message> Disable warning
-Wno-lint Disable all lint warnings
-Wno-style Disable all style warnings
-Wno-fatal Disable fatal exit on warnings
--x-assign <mode> Initially assign Xs to this value
--x-assign <mode> Assign non-initial Xs to this value
--x-initial <mode> Assign initial Xs to this value
--x-initial-edge Enable initial X->0 and X->1 edge triggers
-y <dir> Directory to search for modules
@@ -423,9 +431,6 @@ C<+1364-1995ext+> etc. specify both the syntax I<and> semantics to be used.
Enable all assertions.
See also --x-assign and --x-initial-edge; setting "--x-assign unique"
and/or "--x-initial-edge" may be desirable.
=item --autoflush
After every $display or $fdisplay, flush the output stream. This insures
@@ -444,9 +449,10 @@ calls.
=item --bbox-unsup
Black box some unsupported language features, currently UDP tables and the
cmos and tran gate primitives. This may enable linting the rest of the
design even when unsupported constructs are present.
Black box some unsupported language features, currently UDP tables, the
cmos and tran gate primitives, deassign statements, and mixed edge errors.
This may enable linting the rest of the design even when unsupported
constructs are present.
=item --bin I<filename>
@@ -480,7 +486,7 @@ interest in adding more traditional CDC checks, please contact the authors.
Sometimes it is quite difficult for Verilator to distinguish clock signals from
other data signals. Occasionally the clock signals can end up in the checking
list of signals which determines if further evaluation is needed. This will
heavily degrade the performance of verilated model.
heavily degrade the performance of a Verilated model.
With --clk <signal-name>, user can specified root clock into the model, then
Verilator will mark the signal as clocker and propagate the clocker attribute
@@ -492,6 +498,10 @@ If the signal is the input to top-module, the directly the signal name. If you
find it difficult to find the exact name, try to use C</*verilator clocker*/> in
RTL file to mark the signal directly.
If clock signals are assigned to vectors and then later used individually,
Verilator will attempt to decompose the vector and connect the single-bit
clock signals directly. This should be transparent to the user.
=item --compiler I<compiler-name>
Enables tunings and workarounds for the specified C++ compiler.
@@ -506,7 +516,7 @@ breaking deep structures as for msvc as described below.
=item gcc
Tune for Gnu C++, although generated code should work on almost any
Tune for GNU C++, although generated code should work on almost any
compliant C++ compiler. Currently the default.
=item msvc
@@ -703,6 +713,14 @@ The file may contain // comments which are ignored to the end of the line.
Any $VAR, $(VAR), or ${VAR} will be replaced with the specified environment
variable.
=item -FI <file>
Force include of the specified C++ header file. All generated C++ files
will insert a #include of the specified file before any other includes. The
specified file might be used to contain define prototypes of custom
VL_VPRINTF functions, and may need to include verilatedos.h as this file is
included before any other standard includes.
=item -GI<name>=I<value>
Overwrites the given parameter of the toplevel module. The value is limited
@@ -744,6 +762,14 @@ backtrace on exit, then exit GDB immediately. Without --debug or if GDB
doesn't seem to work, this flag is ignored. Intended for easy creation of
backtraces by users; otherwise see the --gdb flag.
=item --getenv I<variable>
If the variable is declared in the environment, print it and exit
immediately. Otherwise, if it's built into Verilator (e.g. VERILATOR_ROOT),
print that and exit immediately. Otherwise, print a newline and exit
immediately. This can be useful in makefiles. See also -V, and the various
*.mk files.
=item --help
Displays this message and program version and exits.
@@ -855,6 +881,22 @@ change the ultimate model's performance, but may in some cases.
Backward compatible alias for "--pins-bv 33".
=item --no-relative-cfuncs
Disable 'this->' references in generated functions, and instead Verilator
will generate absolute references starting from 'vlTOPp->'. This prevents
V3Combine from merging functions from multiple instances of the same
module, so it can grow the instruction stream.
This is a work around for old compilers. Don't set this if your C++
compiler supports __restrict__ properly, as GCC 4.5.x and newer do. For
older compilers, test if this switch gives you better performance or not.
Compilers which don't honor __restrict__ will suspect that 'this->'
references and 'vlTOPp->' references may alias, and may write slow code
with extra loads and stores to handle the (imaginary) aliasing. Using only
'vlTOPp->' references allows these old compilers to produce tight code.
=item --no-skip-identical
Rarely needed. Disables skipping execution of Verilator if all source
@@ -896,7 +938,7 @@ developers.
=item --output-split I<bytes>
Enables splitting the output .cpp/.sp files into multiple outputs. When a
Enables splitting the output .cpp files into multiple outputs. When a
C++ file exceeds the specified number of operations, a new file will be
created at the next function boundary. In addition, any slow routines will
be placed into __Slow files. This accelerates compilation by as
@@ -908,7 +950,7 @@ one-minute-compile chunks.
=item --output-split-cfuncs I<statements>
Enables splitting functions in the output .cpp/.sp files into multiple
Enables splitting functions in the output .cpp files into multiple
functions. When a generated function exceeds the specified number of
operations, a new function will be created. With --output-split, this will
enable GCC to compile faster, at a small loss in performance that gets
@@ -918,7 +960,7 @@ function.
=item --output-split-ctrace I<statements>
Enables splitting trace functions in the output .cpp/.sp files into
Enables splitting trace functions in the output .cpp files into
multiple functions. Defaults to same setting as --output-split-cfuncs.
=item -P
@@ -1013,6 +1055,12 @@ inlining. This will also turn off inlining as if all modules had a
Overwrites the given parameter(s) of the toplevel module. See -G for a
detailed description.
=item --relative-includes
When a file references an include file, resolve the filename relative to
the path of the referencing file, instead of relative to the current
directory.
=item --report-unoptflat
Extra diagnostics for UNOPTFLAT warnings. This includes for each loop, the
@@ -1157,7 +1205,7 @@ Setting it to "" disables matching.
=item -V
Shows the verbose version, including configuration information compiled
into Verilator. (Similar to perl -V.)
into Verilator. (Similar to perl -V.) See also --getenv.
=item -v I<filename>
@@ -1177,8 +1225,9 @@ Enable use of VPI and linking against the verilated_vpi.cpp files.
=item -Wall
Enable all warnings, including code style warnings that are normally
disabled by default.
Enable all code style warnings, including code style warnings that are
normally disabled by default. Equivelent to "-Wwarn-lint -Wwarn-style".
Excludes some specialty warnings, i.e. IMPERFECTSCH.
=item -Werror-I<message>
@@ -1273,7 +1322,30 @@ enable rerunning with that same seed so you can reproduce bugs.
B<Note.> This option applies only to variables which are explicitly assigned
to X in the Verilog source code. Initial values of clocks are set to 0 unless
--x-initial-edge is specified. Initial values of all other state holding
variables are set as though --x-assign unique had been specified.
variables are controlled with --x-initial.
=item --x-initial 0
=item --x-initial fast
=item --x-initial unique (default)
Controls the two-state value that is used to initialize variables that are
not otherwise initialized.
--x-initial=0, initializes all otherwise uninitialized variables to zero.
--x-initial=unique, the default, initializes variables using a function,
which determines the value to use each initialization. This gives greatest
flexibility and allows finding reset bugs. See L</"Unknown states">
--x-initial=fast, is best for performance, and initializes all variables to
a state Verilator determines is optimal. This may allow further code
optimizations, but will likely hide any code bugs relating to missing
resets.
B<Note.> This option applies only to initial values of variables. Initial
values of clocks are set to 0 unless --x-initial-edge is specified.
=item --x-initial-edge
@@ -1335,7 +1407,7 @@ We'll compile this example into C++.
cat <<EOF >sim_main.cpp
#include "Vour.h"
#include "verilated.h"
int main(int argc, char **argv, char **env) {
int main(int argc, char** argv, char** env) {
Verilated::commandArgs(argc, argv);
Vour* top = new Vour;
while (!Verilated::gotFinish()) { top->eval(); }
@@ -1344,9 +1416,15 @@ We'll compile this example into C++.
}
EOF
If you installed Verilator from sources, or a tarball, but not as part of
your operating system (as an RPM), first you need to point to the kit:
See the README in the source kit for various ways to install or point to
Verilator binaries. In brief, if you are running Verilator that came from
your operating system (as an RPM), or did a "make install" to place
Verilator into your default path, you do not need anything special in your
environment, and should not have VERILATOR_ROOT set. However, if you
installed Verilator from sources and want to run Verilator out of where you
compiled Verilator, you need to point to the kit:
# See above; don't do this if using an OS-distributed Verilator
export VERILATOR_ROOT=/path/to/where/verilator/was/installed
export PATH=$VERILATOR_ROOT/bin:$PATH
@@ -1378,8 +1456,8 @@ And we get as output
Really, you're better off writing a Makefile to do all this for you. Then,
when your source changes it will automatically run all of these steps; to
aid this Verilator can create a makefile dependency file. See the test_c
directory in the distribution for an example.
aid this Verilator can create a makefile dependency file. See the examples
directory in the distribution.
=head1 EXAMPLE SYSTEMC EXECUTION
@@ -1403,17 +1481,23 @@ This is an example similar to the above, but using SystemC.
Verilated::commandArgs(argc, argv);
sc_clock clk ("clk",10, 0.5, 3, true);
Vour* top;
top = new Vour("top"); // SP_CELL (top, Vour);
top->clk(clk); // SP_PIN (top, clk, clk);
top = new Vour("top");
top->clk(clk);
while (!Verilated::gotFinish()) { sc_start(1, SC_NS); }
delete top;
exit(0);
}
EOF
If you installed Verilator from sources, or a tarball, but not as part of
your operating system (as an RPM), first you need to point to the kit:
See the README in the source kit for various ways to install or point to
Verilator binaries. In brief, if you are running Verilator that came from
your operating system (as an RPM), or did a "make install" to place
Verilator into your default path, you do not need anything special in your
environment, and should not have VERILATOR_ROOT set. However, if you
installed Verilator from sources and want to run Verilator out of where you
compiled Verilator, you need to point to the kit:
# See above; don't do this if using an OS-distributed Verilator
export VERILATOR_ROOT=/path/to/where/verilator/was/installed
export PATH=$VERILATOR_ROOT/bin:$PATH
@@ -1450,15 +1534,16 @@ And we get the same output as the C++ example:
Really, you're better off using a Makefile to do all this for you. Then,
when your source changes it will automatically run all of these steps. See
the test_sc directory in the distribution for an example.
the examples directory in the distribution.
=head1 BENCHMARKING & OPTIMIZATION
For best performance, run Verilator with the "-O3 --x-assign=fast
--noassert" flags. The -O3 flag will require longer compile times, and
--x-assign=fast may increase the risk of reset bugs in trade for
performance; see the above documentation for these flags.
--x-initial=fast --noassert" flags. The -O3 flag will require longer
compile times, and --x-assign=fast --x-initial=fast may increase the risk
of reset bugs in trade for performance; see the above documentation for
these flags.
Minor Verilog code changes can also give big wins. You should not have any
UNOPTFLAT warnings from Verilator. Fixing these warnings can result in
@@ -1477,7 +1562,7 @@ OPT, OPT_FAST, or OPT_SLOW lib/verilated.mk. Or, use the -CFLAGS and/or
the compiler or linker. Or, just for one run, pass them on the command
line to make:
make OPT_FAST="-O2" -f Vour.mk Vour__ALL.a
make OPT_FAST="-O2 -fno-stack-protector" -f Vour.mk Vour__ALL.a
OPT_FAST specifies optimizations for those programs that are part of the
fast path, mostly code that is executed every cycle. OPT_SLOW specifies
@@ -1884,54 +1969,71 @@ documented below.
Verilator has an important difference from an event based simulator; signal
values that are changed by the VPI will not immediately propagate their
values, instead the top level header file's eval() method must be called.
Normally this would be part of the normal evaluation (IE the next clock
Normally this would be part of the normal evaluation (i.e. the next clock
edge), not as part of the value change. This makes the performance of VPI
routines extremely fast compared to event based simulators, but can confuse
some test-benches that expect immediate propagation.
Note the VPI by it's specified implementation will always be much slower
Note the VPI by its specified implementation will always be much slower
than accessing the Verilator values by direct reference
(structure->module->signame), as the VPI accessors perform lookup in
functions at runtime requiring at best hundreds of instructions, while the
direct references are evaluated by the compiler and result in only a couple
of instructions.
For signal callbacks to work the main loop of the program must call
VerilatedVpi::callValueCbs().
=head2 VPI Example
In the below example, we have readme marked read-only, and writeme which if
written from outside the model will have the same semantics as if it
changed on the specified clock edge.
module t;
reg readme /*verilator public_flat_rd*/;
reg writeme /*verilator public_flat_rw @(posedge clk) */;
endmodule
cat <<EOF >our.v
module our (input clk);
reg readme /*verilator public_flat_rd*/;
reg writeme /*verilator public_flat_rw @(posedge clk) */;
initial $finish;
endmodule
EOF
There are many online tutorials and books on the VPI, but an example that
accesses the above would be:
accesses the above signal "readme" would be:
void read_and_check() {
vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"t.readme", NULL);
if (!vh1) { error... }
const char* name = vpi_get_str(vpiName, vh1);
printf("Module name: %s\n"); // Prints "readme"
cat <<EOF >sim_main.cpp
#include "Vour.h"
#include "verilated.h"
#include "verilated_vpi.h" // Required to get definitions
s_vpi_value v;
v.format = vpiIntVal;
vpi_get_value(vh1, &v);
printf("Value of v: %d\n", v.value.integer); // Prints "readme"
}
vluint64_t main_time = 0; // See comments in first example
double sc_time_stamp () { return main_time; }
For signal callbacks to work the main loop of the program must call
VerilatedVpi::callValueCbs().
void read_and_check() {
vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"TOP.our.readme", NULL);
if (!vh1) { vl_fatal(__FILE__, __LINE__, "sim_main", "No handle found"); }
const char* name = vpi_get_str(vpiName, vh1);
printf("Module name: %s\n", name); // Prints "readme"
#include "verilated_vpi.h" // Required to get definitions
...
while (time passes) {
...
topp->eval();
VerilatedVpi::callValueCbs();
}
s_vpi_value v;
v.format = vpiIntVal;
vpi_get_value(vh1, &v);
printf("Value of v: %d\n", v.value.integer); // Prints "readme"
}
int main(int argc, char** argv, char** env) {
Verilated::commandArgs(argc, argv);
Vour* top = new Vour;
Verilated::internalsDump(); // See scopes to help debug
while (!Verilated::gotFinish()) {
top->eval();
VerilatedVpi::callValueCbs(); // For signal callbacks
read_and_check();
}
delete top;
exit(0);
}
EOF
=head1 CROSS COMPILATION
@@ -2029,8 +2131,9 @@ numbers (or all lines if omitted).
With lint_off using '*' will override any lint_on directives in the source,
i.e. the warning will still not be printed.
If the -msg is omitted, all lint warnings are enabled/disabled. This will
override all later lint warning enables for the specified region.
If the -msg is omitted, all lint warnings (see list in -Wno-lint) are
enabled/disabled. This will override all later lint warning enables for
the specified region.
=item tracing_on [-file "<filename>" [-lines <line> [ - <line> ]]]
@@ -2371,6 +2474,14 @@ reduce the size of the final executable when a task is used a very large
number of times. For this flag to work, the task and tasks below it must
be pure; they cannot reference any variables outside the task itself.
=item /*verilator public*/ (parameter)
Used after a parameter declaration to indicate the emitted C code should
have the parameter values visible. Due to C++ language restrictions, this
may only be used on 64-bit or narrower integral enumerations.
parameter [2:0] PARAM /*verilator public*/ = 2'b0;
=item /*verilator public*/ (typedef enum)
Used after an enum typedef declaration to indicate the emitted C code
@@ -2463,6 +2574,12 @@ indicate the function or task should pass all remaining arguments through
$sformatf. This allows creation of DPI functions with $display like
behavior. See the test_regress/t/t_dpi_display.v file for an example.
=item /*verilator tag <text...>*/
Attached after a variable or structure member to indicate opaque (to
Verilator) text that should be passed through to the XML output as a tag,
for use by downstream applications.
=item /*verilator tracing_off*/
Disable waveform tracing for all future signals that are declared in this
@@ -2504,6 +2621,14 @@ always @* to reduce missing activity items. Avoid putting $displays in
combo blocks, as they may print multiple times when not desired, even on
compliant simulators as event ordering is not specified.
=head2 Signal Naming
To avoid conflicts with C symbol naming, any character in a signal name
that is not alphanumeric nor a single underscore will be replaced by __0hh
where hh is the hex code of the character. To avoid conflicts with
Verilator's internal symbols, any double underscore are replaced with
___05F (5F is the hex code of an underscore.)
=head2 Bind
Verilator only supports "bind" to a target module name, not an instance
@@ -2567,24 +2692,25 @@ value (see the --x-assign switch.) Thus if the value is actually used, the
random value should cause downstream errors. Integers also randomize, even
though the Verilog 2001 specification says they initialize to zero.
All variables are randomly initialized using a function. By running
several random simulation runs you can determine that reset is working
correctly. On the first run, the function initializes variables to zero.
On the second, have it initialize variables to one. On the third and
following runs have it initialize them randomly. If the results match,
reset works. (Note this is what the hardware will really do.) In
practice, just setting all variables to one at startup finds most problems.
All variables, depending on --x-initial setting, are typically randomly
initialized using a function. By running several random simulation runs
you can determine that reset is working correctly. On the first run, the
function initializes variables to zero. On the second, have it initialize
variables to one. On the third and following runs have it initialize them
randomly. If the results match, reset works. (Note this is what the
hardware will really do.) In practice, just setting all variables to one
at startup finds most problems (since typically control signals are
active-high).
B<Note.> --x-assign applies to variables explicitly initialized or assigned to
X. Uninitialized clocks are initialized to zero, while all other state holding
variables are initialized to a random value.
Event driven simulators will generally trigger an edge on a transition from X
to 1 (C<posedge>) or X to 0 (C<negedge>). However, by default, since clocks
are initialized to zero, Verilator will not trigger an initial negedge. Some
code (particularly for reset) may rely on X->0 triggering an edge. Verilator
provides a switch (see --x-initial-edge) to enable this behavior. Comparing
runs with and without this switch will find such problems.
--x-assign applies to variables explicitly initialized or assigned to
X. Uninitialized clocks are initialized to zero, while all other state
holding variables are initialized to a random value. Event driven
simulators will generally trigger an edge on a transition from X to 1
(C<posedge>) or X to 0 (C<negedge>). However, by default, since clocks are
initialized to zero, Verilator will not trigger an initial negedge. Some
code (particularly for reset) may rely on X->0 triggering an edge. The
--x-initial-edge switch enables this behavior. Comparing runs with and
without this switch will find such problems.
=head2 Tri/Inout
@@ -2908,13 +3034,12 @@ Simply use a different register for the flop:
always @* foo[0] = foo_flopped[0];
always @* foo[1] = ...
This is good coding practice anyways.
It is also possible to disable this error when one of the assignments is
inside a public task.
Ignoring this warning may make Verilator simulations differ from other
simulators.
This is not illegal in SystemVerilog, but a violation of good coding
practice. Verilator reports this as an error, because ignoring this warning
may make Verilator simulations differ from other simulators.
=item BLKSEQ
@@ -3088,8 +3213,8 @@ correctly.
Warns that the scheduling of the model is not absolutely perfect, and some
manual code edits may result in faster performance. This warning defaults
to off, and must be turned on explicitly before the top module statement is
processed.
to off, is not part of -Wall, and must be turned on explicitly before the
top module statement is processed.
=item IMPLICIT
@@ -3139,6 +3264,11 @@ Warns that a packed vector is declared with little endian bit numbering
and little numbering is now thus often due to simple oversight instead of
intent.
Also warns that a cell is declared with little endian range (i.e. [0:7] or
[7]) and is connected to a N-wide signal. Based on IEEE the bits will
likely be backwards from what you expect (i.e. cell [0] will connect to
signal bit [N-1] not bit [0]).
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
@@ -3596,7 +3726,7 @@ trace file if you want all data to land in the same output file.
#include "verilated_vcd_c.h"
...
int main(int argc, char **argv, char **env) {
int main(int argc, char** argv, char** env) {
...
Verilated::traceEverOn(true);
VerilatedVcdC* tfp = new VerilatedVcdC;
@@ -3610,6 +3740,8 @@ trace file if you want all data to land in the same output file.
tfp->close();
}
Also see the examples/tracing_cc directory in the distribution.
=item How do I generate waveforms (traces) in SystemC?
Add the --trace switch to Verilator, and in your top level C sc_main code,
@@ -3632,7 +3764,7 @@ trace file if you want all data to land in the same output file.
#include "verilated_vcd_sc.h"
...
int main(int argc, char **argv, char **env) {
int main(int argc, char** argv, char** env) {
...
Verilated::traceEverOn(true);
VerilatedVcdSc* tfp = new VerilatedVcdSc;
@@ -3644,11 +3776,13 @@ trace file if you want all data to land in the same output file.
tfp->close();
}
Also see the examples/tracing_cc directory in the distribution.
=item How do I view waveforms (traces)?
Verilator makes standard VCD (Value Change Dump) files. They are viewable
with the public domain Dinotrace or GtkWave programs, or any of the many
commercial offerings.
with the public domain GtkWave (recommended) or Dinotrace (legacy)
programs, or any of the many commercial offerings.
=item How do I reduce the size of large waveform (trace) files?
@@ -3812,7 +3946,7 @@ From the sc_main.cpp file, you'd then:
#include "Vour.h"
#include "Vour_our.h"
cout << "clock is " << top->v->clk << endl;
cout << "clock is " << top->our->clk << endl;
In this example, clk is a bool you can read or set as any other variable.
The value of normal signals may be set, though clocks shouldn't be changed
@@ -3987,7 +4121,7 @@ Thanks to them, and all those we've missed including above.
The latest version is available from L<http://www.veripool.org/>.
Copyright 2003-2016 by Wilson Snyder. Verilator is free software; you can
Copyright 2003-2017 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.
+2 -2
View File
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
######################################################################
#
# Copyright 2003-2016 by Wilson Snyder. This program is free software; you
# Copyright 2003-2017 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.
@@ -271,7 +271,7 @@ Specifies a module search directory.
The latest version is available from L<http://www.veripool.org/>.
Copyright 2003-2016 by Wilson Snyder. Verilator is free software; you can
Copyright 2003-2017 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.
+1 -1
View File
@@ -235,7 +235,7 @@ Do not show differences in line numbering.
The latest version is available from L<http://www.veripool.org/verilator>.
Copyright 2005-2016 by Wilson Snyder. This package is free software; you can
Copyright 2005-2017 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-2016 by Wilson Snyder. This package is free software; you can
# Copyright 2003-2017 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"
}
}
+1 -1
View File
@@ -222,7 +222,7 @@ Displays this message and program version and exits.
The latest version is available from L<http://www.veripool.org/>.
Copyright 2007-2016 by Wilson Snyder. Verilator is free software; you can
Copyright 2007-2017 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.
+95 -36
View File
@@ -1,13 +1,14 @@
# DESCRIPTION: Process this file with autoconf to produce a configure script.
#
# Copyright 2003-2016 by Wilson Snyder. Verilator is free software; you can
# Copyright 2003-2017 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.890 2016-11-25])
AC_INIT([Verilator],[3.914 2017-10-14])
# 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 verilator.pc)
@@ -42,7 +43,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)
@@ -60,7 +61,7 @@ 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)
@@ -78,10 +79,10 @@ AC_PROG_INSTALL
AC_LANG_PUSH(C++)
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
@@ -105,72 +106,130 @@ 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([], [[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
CXXFLAGS="$CXXFLAGS $2 -Werror"
AC_MSG_CHECKING([whether $CXX accepts $2])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([],[])],
[_my_result=yes
if test -s conftest.err; then
if grep -e "$2" conftest.err >/dev/null; then
_my_result=no
fi
fi],
[_my_result=no])
# 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([], [[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([[an_error "intentional-error-for-test.h"
]],[])],
]],[])],
[], # Ignore ok exit
[if test -s conftest.err; then
if grep -e "$2" conftest.err >/dev/null; then
if grep -e "$1" conftest.err >/dev/null; then
_my_result=no
fi
fi])
AC_MSG_RESULT($_my_result)
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
])
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
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
])# _MY_CXX_CHECK_OPT
])
# Flags for compiling Verilator internals including parser
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-char-subscripts)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-undefined-bool-conversion)
# 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++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++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=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)
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
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-unused)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-parentheses-equality)
# 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(CFG_CXXFLAGS_NO_UNUSED,-Wno-char-subscripts)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-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(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-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,-fbracket-depth=4096)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-shadow)
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
# 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
+1 -2
View File
@@ -635,8 +635,7 @@ INPUT = doxygen-mainpage \
test_c \
test_regress \
test_sc \
test_v \
test_verilated
test_v
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@@ -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-2017 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 enviornment, 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-2017 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 enviornment, 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-2017 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 enviornment, 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 | tee logs/sim.log
@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
+55
View File
@@ -0,0 +1,55 @@
# -*- Makefile -*-
#######################################################################
#
# DESCRIPTION: Verilator Example: Makefile for inside object directory
#
# This is executed in the object directory, and called by ../Makefile
#
# Copyright 2003-2017 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
#######################################################################
# 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 .
+114
View File
@@ -0,0 +1,114 @@
// 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 verilator was invoked with --trace, open trace
#if VM_TRACE
Verilated::traceEverOn(true); // Verilator must compute traced signals
VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
VerilatedVcdC* tfp = new VerilatedVcdC;
top->trace(tfp, 99); // Trace 99 levels of hierarchy
mkdir("logs", 0777);
tfp->open("logs/vlt_dump.vcd"); // Open the dump file
#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] = 0x1;
top->in_wide[1] = 0x22222222;
top->in_wide[2] = 0x33333333;
// 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();
// 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(); }
#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-2017 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 enviornment, 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 | tee logs/sim.log
@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
+63
View File
@@ -0,0 +1,63 @@
# -*- Makefile -*-
#######################################################################
#
# DESCRIPTION: Verilator Example: Makefile for inside object directory
#
# This is executed in the object directory, and called by ../Makefile
#
# Copyright 2003-2017 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
#######################################################################
# 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 .
+136
View File
@@ -0,0 +1,136 @@
// -*- 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
// Turn on waves
#if VM_TRACE
cout << "Enabling waves into logs/vlt_dump.vcd...\n";
VerilatedVcdSc* tfp = new VerilatedVcdSc;
top->trace (tfp, 99);
mkdir("logs", 0777);
tfp->open ("logs/vlt_dump.vcd");
#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();
// Apply inputs
if (VL_TIME_Q() > 1 && VL_TIME_Q() < 10) {
reset_l = !1; // Assert reset
} else if (VL_TIME_Q() > 1) {
reset_l = !0; // Deassert reset
}
#endif
// Simulate 1ns
#if (SYSTEMC_VERSION>=20070314)
sc_start(1,SC_NS);
#else
sc_start(1);
#endif
}
// Close Waves
#if VM_TRACE
if (tfp) tfp->close();
#endif
// Final model cleanup
top->final();
// Coverage analysis (since test passed)
#if VM_COVERAGE
mkdir("logs", 0777);
VerilatedCov::write("logs/coverage.dat");
#endif
// 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
+279 -155
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@@ -37,9 +37,9 @@ VerilatedVoidCb Verilated::s_flushCb = NULL;
// Keep below together in one cache line
Verilated::Serialized Verilated::s_s;
VL_THREAD const VerilatedScope* Verilated::t_dpiScopep = NULL;
VL_THREAD const char* Verilated::t_dpiFilename = "";
VL_THREAD int Verilated::t_dpiLineno = 0;
VL_THREAD_LOCAL const VerilatedScope* Verilated::t_dpiScopep = NULL;
VL_THREAD_LOCAL const char* Verilated::t_dpiFilename = "";
VL_THREAD_LOCAL int Verilated::t_dpiLineno = 0;
struct Verilated::CommandArgValues Verilated::s_args = {0, NULL};
VerilatedImp VerilatedImp::s_s;
@@ -115,7 +115,7 @@ QData VL_RANDOM_Q(int obits) {
}
WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) {
for (int i=0; i<VL_WORDS_I(obits); i++) {
for (int i=0; i<VL_WORDS_I(obits); ++i) {
if (i<(VL_WORDS_I(obits)-1)) {
outwp[i] = VL_RAND32();
} else {
@@ -146,7 +146,7 @@ QData VL_RAND_RESET_Q(int obits) {
}
WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) {
for (int i=0; i<VL_WORDS_I(obits); i++) {
for (int i=0; i<VL_WORDS_I(obits); ++i) {
if (i<(VL_WORDS_I(obits)-1)) {
outwp[i] = VL_RAND_RESET_I(32);
} else {
@@ -157,7 +157,7 @@ WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) {
}
WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) {
for (int i=0; i<VL_WORDS_I(obits); i++) outwp[i] = 0;
for (int i=0; i<VL_WORDS_I(obits); ++i) outwp[i] = 0;
return outwp;
}
@@ -166,7 +166,7 @@ WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) {
void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp) {
VL_PRINTF(" Data: w%d: ", lbits);
for (int i=VL_WORDS_I(lbits)-1; i>=0; i--) { VL_PRINTF("%08x ",iwp[i]); }
for (int i=VL_WORDS_I(lbits)-1; i>=0; --i) { VL_PRINTF("%08x ",iwp[i]); }
VL_PRINTF("\n");
}
@@ -179,7 +179,7 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, boo
// for debug see V3Number version
// Requires clean input
int words = VL_WORDS_I(lbits);
for (int i=0; i<words; i++) owp[i]=0;
for (int i=0; i<words; ++i) owp[i]=0;
// Find MSB and check for zero.
int umsbp1 = VL_MOSTSETBITP1_W(words,lwp); // dividend
int vmsbp1 = VL_MOSTSETBITP1_W(words,rwp); // divisor
@@ -193,14 +193,14 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, boo
if (vw == 1) { // Single divisor word breaks rest of algorithm
vluint64_t k = 0;
for (int j = uw-1; j >= 0; j--) {
vluint64_t unw64 = ((k<<VL_ULL(32)) + (vluint64_t)(lwp[j]));
owp[j] = unw64 / (vluint64_t)(rwp[0]);
k = unw64 - (vluint64_t)(owp[j])*(vluint64_t)(rwp[0]);
for (int j = uw-1; j >= 0; --j) {
vluint64_t unw64 = ((k<<VL_ULL(32)) + static_cast<vluint64_t>(lwp[j]));
owp[j] = unw64 / static_cast<vluint64_t>(rwp[0]);
k = unw64 - static_cast<vluint64_t>(owp[j])*static_cast<vluint64_t>(rwp[0]);
}
if (is_modulus) {
owp[0] = k;
for (int i=1; i<words; i++) owp[i]=0;
for (int i=1; i<words; ++i) owp[i]=0;
}
return owp;
}
@@ -211,13 +211,13 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, boo
// Zero for ease of debugging and to save having to zero for shifts
// Note +1 as loop will use extra word
for (int i=0; i<words+1; i++) { un[i]=vn[i]=0; }
for (int i=0; i<words+1; ++i) { un[i]=vn[i]=0; }
// Algorithm requires divisor MSB to be set
// Copy and shift to normalize divisor so MSB of vn[vw-1] is set
int s = 31-VL_BITBIT_I(vmsbp1-1); // shift amount (0...31)
vluint32_t shift_mask = s ? 0xffffffff : 0; // otherwise >> 32 won't mask the value
for (int i = vw-1; i>0; i--) {
for (int i = vw-1; i>0; --i) {
vn[i] = (rwp[i] << s) | (shift_mask & (rwp[i-1] >> (32-s)));
}
vn[0] = rwp[0] << s;
@@ -225,17 +225,17 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, boo
// Copy and shift dividend by same amount; may set new upper word
if (s) un[uw] = lwp[uw-1] >> (32-s);
else un[uw] = 0;
for (int i=uw-1; i>0; i--) {
for (int i=uw-1; i>0; --i) {
un[i] = (lwp[i] << s) | (shift_mask & (lwp[i-1] >> (32-s)));
}
un[0] = lwp[0] << s;
// Main loop
for (int j = uw - vw; j >= 0; j--) {
for (int j = uw - vw; j >= 0; --j) {
// Estimate
vluint64_t unw64 = ((vluint64_t)(un[j+vw])<<VL_ULL(32) | (vluint64_t)(un[j+vw-1]));
vluint64_t qhat = unw64 / (vluint64_t)(vn[vw-1]);
vluint64_t rhat = unw64 - qhat*(vluint64_t)(vn[vw-1]);
vluint64_t unw64 = (static_cast<vluint64_t>(un[j+vw])<<VL_ULL(32) | static_cast<vluint64_t>(un[j+vw-1]));
vluint64_t qhat = unw64 / static_cast<vluint64_t>(vn[vw-1]);
vluint64_t rhat = unw64 - qhat*static_cast<vluint64_t>(vn[vw-1]);
again:
if (qhat >= VL_ULL(0x100000000)
@@ -247,7 +247,7 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, boo
vlsint64_t t = 0; // Must be signed
vluint64_t k = 0;
for (int i=0; i<vw; i++) {
for (int i=0; i<vw; ++i) {
vluint64_t p = qhat*vn[i]; // Multiply by estimate
t = un[i+j] - k - (p & VL_ULL(0xFFFFFFFF)); // Subtract
un[i+j] = t;
@@ -261,8 +261,8 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, boo
// Over subtracted; correct by adding back
owp[j]--;
k = 0;
for (int i=0; i<vw; i++) {
t = (vluint64_t)(un[i+j]) + (vluint64_t)(vn[i]) + k;
for (int i=0; i<vw; ++i) {
t = static_cast<vluint64_t>(un[i+j]) + static_cast<vluint64_t>(vn[i]) + k;
un[i+j] = t;
k = t >> VL_ULL(32);
}
@@ -272,23 +272,99 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, boo
if (is_modulus) { // modulus
// Need to reverse normalization on copy to output
for (int i=0; i<vw; i++) {
for (int i=0; i<vw; ++i) {
owp[i] = (un[i] >> s) | (shift_mask & (un[i+1] << (32-s)));
}
for (int i=vw; i<words; i++) owp[i] = 0;
for (int i=vw; i<words; ++i) owp[i] = 0;
return owp;
} else { // division
return owp;
}
}
WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp) {
// obits==lbits, rbits can be different
owp[0] = 1;
for (int i=1; i < VL_WORDS_I(obits); i++) owp[i] = 0;
// cppcheck-suppress variableScope
WData powstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
WData lastpowstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
WData lastoutstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
// cppcheck-suppress variableScope
VL_ASSIGN_W(obits, powstore, lwp);
for (int bit=0; bit<rbits; bit++) {
if (bit>0) { // power = power*power
VL_ASSIGN_W(obits, lastpowstore, powstore);
VL_MUL_W(VL_WORDS_I(obits), powstore, lastpowstore, lastpowstore);
}
if (VL_BITISSET_W(rwp,bit)) { // out *= power
VL_ASSIGN_W(obits, lastoutstore, owp);
VL_MUL_W(VL_WORDS_I(obits), owp, lastoutstore, powstore);
}
}
return owp;
}
WDataOutP VL_POW_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp, QData rhs) {
WData rhsw[2]; VL_SET_WQ(rhsw, rhs);
return VL_POW_WWW(obits,lbits,rbits,owp,lwp,rhsw);
}
QData VL_POW_QQW(int, int, int rbits, QData lhs, WDataInP rwp) {
// Skip check for rhs == 0, as short-circuit doesn't save time
if (VL_UNLIKELY(lhs==0)) return 0;
QData power = lhs;
QData out = VL_ULL(1);
for (int bit=0; bit<rbits; ++bit) {
if (bit>0) power = power*power;
if (VL_BITISSET_W(rwp,bit)) out *= power;
}
return out;
}
WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool lsign, bool rsign) {
// obits==lbits, rbits can be different
if (rsign && VL_SIGN_W(rbits, rwp)) {
int words = VL_WORDS_I(obits);
VL_ZERO_W(obits, owp);
IData lor = 0; // 0=all zeros, ~0=all ones, else mix
for (int i=1; i < (words-1); ++i) {
lor |= lwp[i];
}
lor |= ( (lwp[words-1] == VL_MASK_I(rbits)) ? ~VL_UL(0) : 0);
if (lor==0 && lwp[0]==0) { return owp; } // "X" so return 0
else if (lor==0 && lwp[0]==1) { owp[0] = 1; return owp; } // 1
else if (lsign && lor == ~VL_UL(0) && lwp[0]==~VL_UL(0)) { // -1
if (rwp[0] & 1) { return VL_ALLONES_W(obits, owp); } // -1^odd=-1
else { owp[0] = 1; return owp; } // -1^even=1
}
return 0;
}
return VL_POW_WWW(obits, rbits, rbits, owp, lwp, rwp);
}
WDataOutP VL_POWSS_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp, QData rhs, bool lsign, bool rsign) {
WData rhsw[2]; VL_SET_WQ(rhsw, rhs);
return VL_POWSS_WWW(obits,lbits,rbits,owp,lwp,rhsw,lsign,rsign);
}
QData VL_POWSS_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp, bool lsign, bool rsign) {
// Skip check for rhs == 0, as short-circuit doesn't save time
if (rsign && VL_SIGN_W(rbits, rwp)) {
if (lhs==0) return 0; // "X"
else if (lhs==1) return 1;
else if (lsign && lhs==VL_MASK_I(obits)) { // -1
if (rwp[0] & 1) return VL_MASK_I(obits); // -1^odd=-1
else return 1; // -1^even=1
}
return 0;
}
return VL_POW_QQW(obits, rbits, rbits, lhs, rwp);
}
//===========================================================================
// Formatting
// Do a va_arg returning a quad, assuming input argument is anything less than wide
#define _VL_VA_ARG_Q(ap, bits) (((bits) <= VL_WORDSIZE) ? va_arg(ap,IData) : va_arg(ap,QData))
void _vl_vsformat(string& output, const char* formatp, va_list ap) {
void _vl_vsformat(std::string& output, const char* formatp, va_list ap) {
// Format a Verilog $write style format into the output list
// The format must be pre-processed (and lower cased) by Verilator
// Arguments are in "width, arg-value (or WDataIn* if wide)" form
@@ -296,14 +372,13 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
// Note uses a single buffer internally; presumes only one usage per printf
// Note also assumes variables < 64 are not wide, this assumption is
// sometimes not true in low-level routines written here in verilated.cpp
static VL_THREAD char tmp[VL_VALUE_STRING_MAX_WIDTH];
static VL_THREAD char tmpf[VL_VALUE_STRING_MAX_WIDTH];
static VL_THREAD_LOCAL char tmp[VL_VALUE_STRING_MAX_WIDTH];
static VL_THREAD_LOCAL char tmpf[VL_VALUE_STRING_MAX_WIDTH];
const char* pctp = NULL; // Most recent %##.##g format
bool inPct = false;
bool widthSet = false;
int width = 0;
const char* pos = formatp;
for (; *pos; ++pos) {
for (const char* pos = formatp; *pos; ++pos) {
if (!inPct && pos[0]=='%') {
pctp = pos;
inPct = true;
@@ -345,7 +420,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
}
case '@': { // Verilog/C++ string
va_arg(ap, int); // # bits is ignored
const string* cstrp = va_arg(ap, const string*);
const std::string* cstrp = va_arg(ap, const std::string*);
output += *cstrp;
break;
}
@@ -377,7 +452,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
if (fmt == 'd' || fmt == '#') fmt = 'x'; // Not supported, but show something
}
int lsb=lbits-1;
if (widthSet && width==0) while (lsb && !VL_BITISSET_W(lwp,lsb)) lsb--;
if (widthSet && width==0) while (lsb && !VL_BITISSET_W(lwp,lsb)) --lsb;
switch (fmt) {
case 'c': {
IData charval = ld & 0xff;
@@ -385,14 +460,15 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
break;
}
case 's':
for (; lsb>=0; lsb--) {
for (; lsb>=0; --lsb) {
lsb = (lsb / 8) * 8; // Next digit
IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xff;
output += (charval==0)?' ':charval;
}
break;
case 'd': { // Signed decimal
int digits=sprintf(tmp,"%" VL_PRI64 "d",(vlsint64_t)(VL_EXTENDS_QQ(lbits,lbits,ld)));
int digits = sprintf(tmp,"%" VL_PRI64 "d",
static_cast<vlsint64_t>(VL_EXTENDS_QQ(lbits,lbits,ld)));
int needmore = width-digits;
if (needmore>0) {
if (pctp && pctp[0] && pctp[1]=='0') { //%0
@@ -423,8 +499,8 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
digits=sprintf(tmp,"%" VL_PRI64 "u",ld);
} else if (VL_TIME_MULTIPLIER==1000) {
digits=sprintf(tmp,"%" VL_PRI64 "u.%03" VL_PRI64 "u",
(QData)(ld/VL_TIME_MULTIPLIER),
(QData)(ld%VL_TIME_MULTIPLIER));
static_cast<QData>(ld/VL_TIME_MULTIPLIER),
static_cast<QData>(ld%VL_TIME_MULTIPLIER));
} else {
vl_fatal(__FILE__,__LINE__,"","Unsupported VL_TIME_MULTIPLIER");
}
@@ -434,13 +510,13 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
break;
}
case 'b':
for (; lsb>=0; lsb--) {
for (; lsb>=0; --lsb) {
output += ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) + '0';
}
break;
break;
case 'o':
for (; lsb>=0; lsb--) {
for (; lsb>=0; --lsb) {
lsb = (lsb / 3) * 3; // Next digit
// Octal numbers may span more than one wide word,
// so we need to grab each bit separately and check for overrun
@@ -453,35 +529,38 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
break;
case 'u': // Packed 2-state
output.reserve(output.size() + 4*VL_WORDS_I(lbits));
for (int i=0; i<VL_WORDS_I(lbits); i++) {
output += (char)((lwp[i] >> 0) & 0xff);
output += (char)((lwp[i] >> 8) & 0xff);
output += (char)((lwp[i] >> 16) & 0xff);
output += (char)((lwp[i] >> 24) & 0xff);
for (int i=0; i<VL_WORDS_I(lbits); ++i) {
output += static_cast<char>((lwp[i] ) & 0xff);
output += static_cast<char>((lwp[i] >> 8) & 0xff);
output += static_cast<char>((lwp[i] >> 16) & 0xff);
output += static_cast<char>((lwp[i] >> 24) & 0xff);
}
break;
case 'z': // Packed 4-state
output.reserve(output.size() + 8*VL_WORDS_I(lbits));
for (int i=0; i<VL_WORDS_I(lbits); i++) {
output += (char)((lwp[i] >> 0) & 0xff);
output += (char)((lwp[i] >> 8) & 0xff);
output += (char)((lwp[i] >> 16) & 0xff);
output += (char)((lwp[i] >> 24) & 0xff);
output += "\0\0\0\0"; // No tristate
for (int i=0; i<VL_WORDS_I(lbits); ++i) {
output += static_cast<char>((lwp[i] ) & 0xff);
output += static_cast<char>((lwp[i] >> 8) & 0xff);
output += static_cast<char>((lwp[i] >> 16) & 0xff);
output += static_cast<char>((lwp[i] >> 24) & 0xff);
output += "\0\0\0\0"; // No tristate
}
break;
case 'v': // Strength; assume always strong
for (lsb=lbits-1; lsb>=0; lsb--) {
for (lsb=lbits-1; lsb>=0; --lsb) {
if ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) output += "St1 ";
else output += "St0 ";
}
break;
case 'x':
for (; lsb>=0; lsb--) {
for (; lsb>=0; --lsb) {
lsb = (lsb / 4) * 4; // Next digit
IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xf;
output += "0123456789abcdef"[charval];
}
break;
default:
string msg = string("Unknown _vl_vsformat code: ")+pos[0];
std::string msg = std::string("Unknown _vl_vsformat code: ")+pos[0];
vl_fatal(__FILE__,__LINE__,"",msg.c_str());
break;
} // switch
@@ -499,7 +578,7 @@ static inline void _vl_vsss_advance(FILE* fp, int& floc) {
if (fp) fgetc(fp);
else floc -= 8;
}
static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp, const string& fstr) {
static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr) {
// Get a character without advancing
if (fp) {
int data = fgetc(fp);
@@ -516,14 +595,14 @@ static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp, const stri
}
}
}
static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp, const string& fstr) {
static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr) {
while (1) {
int c = _vl_vsss_peek(fp, floc, fromp, fstr);
if (c==EOF || !isspace(c)) return;
_vl_vsss_advance(fp, floc);
}
}
static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const string& fstr,
static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr,
char* tmpp, const char* acceptp) {
// Read into tmp, consisting of characters from acceptp list
char* cp = tmpp;
@@ -544,10 +623,10 @@ static inline void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb, int nbits,
VL_ASSIGNBIT_WI(0, lsb, owp, ld & 1);
}
}
static inline void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp, int posstart, int posend) {
static inline void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp, size_t posstart, size_t posend) {
// Read in base "2^^baseLog2" digits from strp[posstart..posend-1] into owp of size obits.
int lsb = 0;
for (int i=0, pos=posend-1; i<obits && pos>=posstart; pos--) {
for (int i=0, pos=static_cast<int>(posend)-1; i<obits && pos>=static_cast<int>(posstart); --pos) {
switch (tolower (strp[pos])) {
case 'x': case 'z': case '?': //FALLTHRU
case '0': lsb += baseLog2; break;
@@ -573,12 +652,12 @@ static inline void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const
IData _vl_vsscanf(FILE* fp, // If a fscanf
int fbits, WDataInP fromp, // Else if a sscanf
const string& fstr, // if a sscanf to string
const std::string& fstr, // if a sscanf to string
const char* formatp, va_list ap) {
// Read a Verilog $sscanf/$fscanf style format into the output list
// The format must be pre-processed (and lower cased) by Verilator
// Arguments are in "width, arg-value (or WDataIn* if wide)" form
static VL_THREAD char tmp[VL_VALUE_STRING_MAX_WIDTH];
static VL_THREAD_LOCAL char tmp[VL_VALUE_STRING_MAX_WIDTH];
int floc = fbits - 1;
IData got = 0;
bool inPct = false;
@@ -610,12 +689,12 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
// Deal with all read-and-scan somethings
// Note LSBs are preserved if there's an overflow
const int obits = va_arg(ap, int);
WData qowp[2];
WData qowp[2] = {0, 0};
WDataOutP owp = qowp;
if (obits > VL_QUADSIZE) {
owp = va_arg(ap,WDataOutP);
}
for (int i=0; i<VL_WORDS_I(obits); i++) owp[i] = 0;
for (int i=0; i<VL_WORDS_I(obits); ++i) owp[i] = 0;
switch (fmt) {
case 'c': {
int c = _vl_vsss_peek(fp,floc,fromp,fstr);
@@ -628,10 +707,10 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
_vl_vsss_skipspace(fp,floc,fromp,fstr);
_vl_vsss_read(fp,floc,fromp,fstr, tmp, NULL);
if (!tmp[0]) goto done;
int pos = ((int)strlen(tmp))-1;
int lpos = (static_cast<int>(strlen(tmp)))-1;
int lsb = 0;
for (int i=0; i<obits && pos>=0; pos--) {
_vl_vsss_setbit(owp,obits,lsb, 8, tmp[pos]); lsb+=8;
for (int i=0; i<obits && lpos>=0; --lpos) {
_vl_vsss_setbit(owp,obits,lsb, 8, tmp[lpos]); lsb+=8;
}
break;
}
@@ -670,25 +749,25 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
_vl_vsss_skipspace(fp,floc,fromp,fstr);
_vl_vsss_read(fp,floc,fromp,fstr, tmp, "01xXzZ?_");
if (!tmp[0]) goto done;
_vl_vsss_based(owp,obits, 1, tmp, 0, (int)strlen(tmp));
_vl_vsss_based(owp,obits, 1, tmp, 0, strlen(tmp));
break;
}
case 'o': {
_vl_vsss_skipspace(fp,floc,fromp,fstr);
_vl_vsss_read(fp,floc,fromp,fstr, tmp, "01234567xXzZ?_");
if (!tmp[0]) goto done;
_vl_vsss_based(owp,obits, 3, tmp, 0, (int)strlen(tmp));
_vl_vsss_based(owp,obits, 3, tmp, 0, strlen(tmp));
break;
}
case 'x': {
_vl_vsss_skipspace(fp,floc,fromp,fstr);
_vl_vsss_read(fp,floc,fromp,fstr, tmp, "0123456789abcdefABCDEFxXzZ?_");
if (!tmp[0]) goto done;
_vl_vsss_based(owp,obits, 4, tmp, 0, (int)strlen(tmp));
_vl_vsss_based(owp,obits, 4, tmp, 0, strlen(tmp));
break;
}
default:
string msg = string("Unknown _vl_vsscanf code: ")+pos[0];
std::string msg = std::string("Unknown _vl_vsscanf code: ")+pos[0];
vl_fatal(__FILE__,__LINE__,"",msg.c_str());
break;
} // switch
@@ -724,7 +803,7 @@ void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) {
int lsb=obits-1;
bool start=true;
char* destp = destoutp;
for (; lsb>=0; lsb--) {
for (; lsb>=0; --lsb) {
lsb = (lsb / 8) * 8; // Next digit
IData charval = (sourcep[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xff;
if (!start || charval) {
@@ -736,14 +815,14 @@ void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) {
if (!start) while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0'; // Drop trailing spaces
}
void _VL_STRING_TO_VINT(int obits, void* destp, int srclen, const char* srcp) {
void _VL_STRING_TO_VINT(int obits, void* destp, size_t srclen, const char* srcp) {
// Convert C string to Verilog format
int bytes = VL_BYTES_I(obits);
char* op = ((char*)(destp));
size_t bytes = VL_BYTES_I(obits);
char* op = reinterpret_cast<char*>(destp);
if (srclen > bytes) srclen = bytes; // Don't overflow destination
int i;
for (i=0; i<srclen; i++) { *op++ = srcp[srclen-1-i]; }
for (; i<bytes; i++) { *op++ = 0; }
size_t i;
for (i=0; i<srclen; ++i) { *op++ = srcp[srclen-1-i]; }
for (; i<bytes; ++i) { *op++ = 0; }
}
IData VL_FGETS_IXI(int obits, void* destp, IData fpi) {
@@ -774,13 +853,13 @@ IData VL_FGETS_IXI(int obits, void* destp, IData fpi) {
return got;
}
IData VL_FOPEN_NI(const string& filename, IData mode) {
IData VL_FOPEN_NI(const std::string& filename, IData mode) {
char modez[5];
_VL_VINT_TO_STRING(VL_WORDSIZE, modez, &mode);
return VL_FOPEN_S(filename.c_str(), modez);
}
IData VL_FOPEN_QI(QData filename, IData mode) {
IData fnw[2]; VL_SET_WQ(fnw, filename);
WData fnw[2]; VL_SET_WQ(fnw, filename);
return VL_FOPEN_WI(2, fnw, mode);
}
IData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) {
@@ -802,61 +881,61 @@ void VL_FCLOSE_I(IData fdi) {
}
void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
static VL_THREAD_LOCAL std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
_vl_vsformat(output, formatp, ap);
va_end(ap);
_VL_STRING_TO_VINT(obits, &destr, (int)output.length(), output.c_str());
_VL_STRING_TO_VINT(obits, &destr, output.length(), output.c_str());
}
void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
static VL_THREAD_LOCAL std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
_vl_vsformat(output, formatp, ap);
va_end(ap);
_VL_STRING_TO_VINT(obits, &destr, (int)output.length(), output.c_str());
_VL_STRING_TO_VINT(obits, &destr, output.length(), output.c_str());
}
void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
static VL_THREAD_LOCAL std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
_vl_vsformat(output, formatp, ap);
va_end(ap);
_VL_STRING_TO_VINT(obits, &destr, (int)output.length(), output.c_str());
_VL_STRING_TO_VINT(obits, &destr, output.length(), output.c_str());
}
void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
static VL_THREAD_LOCAL std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
_vl_vsformat(output, formatp, ap);
va_end(ap);
_VL_STRING_TO_VINT(obits, &destr, (int)output.length(), output.c_str());
_VL_STRING_TO_VINT(obits, &destr, output.length(), output.c_str());
}
void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
static VL_THREAD_LOCAL std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
_vl_vsformat(output, formatp, ap);
va_end(ap);
_VL_STRING_TO_VINT(obits, destp, (int)output.length(), output.c_str());
_VL_STRING_TO_VINT(obits, destp, output.length(), output.c_str());
}
void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...) {
void VL_SFORMAT_X(int obits_ignored, std::string &output, const char* formatp, ...) {
if (obits_ignored) {}
output = "";
va_list ap;
@@ -865,8 +944,8 @@ void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...) {
va_end(ap);
}
string VL_SFORMATF_NX(const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
std::string VL_SFORMATF_NX(const char* formatp, ...) {
static VL_THREAD_LOCAL std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
@@ -877,7 +956,7 @@ string VL_SFORMATF_NX(const char* formatp, ...) {
}
void VL_WRITEF(const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
static VL_THREAD_LOCAL std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
@@ -889,7 +968,7 @@ void VL_WRITEF(const char* formatp, ...) {
}
void VL_FWRITEF(IData fpi, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
static VL_THREAD_LOCAL std::string output; // static only for speed
output = "";
FILE* fp = VL_CVT_I_FP(fpi);
if (VL_UNLIKELY(!fp)) return;
@@ -914,7 +993,7 @@ IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) {
}
IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) {
IData fnw[2]; VL_SET_WI(fnw, ld);
WData fnw[2]; VL_SET_WI(fnw, ld);
va_list ap;
va_start(ap,formatp);
@@ -923,7 +1002,7 @@ IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) {
return got;
}
IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...) {
IData fnw[2]; VL_SET_WQ(fnw, ld);
WData fnw[2]; VL_SET_WQ(fnw, ld);
va_list ap;
va_start(ap,formatp);
@@ -938,7 +1017,7 @@ IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...) {
va_end(ap);
return got;
}
IData VL_SSCANF_INX(int, const string& ld, const char* formatp, ...) {
IData VL_SSCANF_INX(int, const std::string& ld, const char* formatp, ...) {
va_list ap;
va_start(ap,formatp);
IData got = _vl_vsscanf(NULL, ld.length()*8, NULL, ld, formatp, ap);
@@ -948,7 +1027,7 @@ IData VL_SSCANF_INX(int, const string& ld, const char* formatp, ...) {
void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int,
QData ofilename, void* memp, IData start, IData end) {
IData fnw[2]; VL_SET_WQ(fnw, ofilename);
WData fnw[2]; VL_SET_WQ(fnw, ofilename);
return VL_READMEM_W(hex,width,depth,array_lsb,2, fnw,memp,start,end);
}
@@ -956,12 +1035,12 @@ void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
WDataInP ofilenamep, void* memp, IData start, IData end) {
char ofilenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
_VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, ofilenamez, ofilenamep);
string ofilenames(ofilenamez);
std::string ofilenames(ofilenamez);
return VL_READMEM_N(hex,width,depth,array_lsb,fnwords,ofilenames,memp,start,end);
}
void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
const string& ofilenamep, void* memp, IData start, IData end) {
const std::string& ofilenamep, void* memp, IData start, IData end) {
if (fnwords) {}
FILE* fp = fopen(ofilenamep.c_str(), "r");
if (VL_UNLIKELY(!fp)) {
@@ -997,9 +1076,9 @@ void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
else if (c=='_') {}
else if (c=='@') { reading_addr = true; innum=false; needinc=false; }
// Check for hex or binary digits as file format requests
else if (isxdigit(c)) {
else if (isxdigit(c) || (!reading_addr && (c=='x' || c=='X'))) {
c = tolower(c);
int value = (c >= 'a' ? (c-'a'+10) : (c-'0'));
int value = (c >= 'a' ? (c=='x' ? VL_RAND_RESET_I(4) : (c-'a'+10)) : (c-'0'));
if (!innum) { // Prep for next number
if (needinc) { addr++; needinc=false; }
}
@@ -1010,32 +1089,34 @@ void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
} else {
needinc = true;
//printf(" Value width=%d @%x = %c\n", width, addr, c);
if (VL_UNLIKELY(addr >= (IData)(depth+array_lsb) || addr < (IData)(array_lsb))) {
if (VL_UNLIKELY(addr >= static_cast<IData>(depth+array_lsb)
|| addr < static_cast<IData>(array_lsb))) {
vl_fatal (ofilenamep.c_str(), linenum, "", "$readmem file address beyond bounds of array");
} else {
int entry = addr - array_lsb;
QData shift = hex ? VL_ULL(4) : VL_ULL(1);
// Shift value in
if (width<=8) {
CData* datap = &((CData*)(memp))[entry];
CData* datap = &(reinterpret_cast<CData*>(memp))[entry];
if (!innum) { *datap = 0; }
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
} else if (width<=16) {
SData* datap = &((SData*)(memp))[entry];
SData* datap = &(reinterpret_cast<SData*>(memp))[entry];
if (!innum) { *datap = 0; }
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
} else if (width<=VL_WORDSIZE) {
IData* datap = &((IData*)(memp))[entry];
IData* datap = &(reinterpret_cast<IData*>(memp))[entry];
if (!innum) { *datap = 0; }
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
} else if (width<=VL_QUADSIZE) {
QData* datap = &((QData*)(memp))[entry];
QData* datap = &(reinterpret_cast<QData*>(memp))[entry];
if (!innum) { *datap = 0; }
*datap = ((*datap << (QData)(shift)) + (QData)(value)) & VL_MASK_Q(width);
*datap = ((*datap << static_cast<QData>(shift))
+ static_cast<QData>(value)) & VL_MASK_Q(width);
} else {
WDataOutP datap = &((WDataOutP)(memp))[ entry*VL_WORDS_I(width) ];
WDataOutP datap = &(reinterpret_cast<WDataOutP>(memp))[ entry*VL_WORDS_I(width) ];
if (!innum) { VL_ZERO_RESET_W(width, datap); }
_VL_SHIFTL_INPLACE_W(width, datap, (IData)shift);
_VL_SHIFTL_INPLACE_W(width, datap, static_cast<IData>(shift));
datap[0] |= value;
}
if (VL_UNLIKELY(value>=(1<<shift))) {
@@ -1051,7 +1132,7 @@ void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
}
lastc = c;
}
if (needinc) { addr++; needinc=false; }
if (needinc) { addr++; }
// Final checks
fclose(fp);
@@ -1061,7 +1142,7 @@ void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
}
IData VL_SYSTEM_IQ(QData lhs) {
IData lhsw[2]; VL_SET_WQ(lhsw, lhs);
WData lhsw[2]; VL_SET_WQ(lhsw, lhs);
return VL_SYSTEM_IW(2, lhsw);
}
IData VL_SYSTEM_IW(int lhswords, WDataInP filenamep) {
@@ -1072,58 +1153,101 @@ IData VL_SYSTEM_IW(int lhswords, WDataInP filenamep) {
}
IData VL_TESTPLUSARGS_I(const char* formatp) {
const string& match = VerilatedImp::argPlusMatch(formatp);
const std::string& match = VerilatedImp::argPlusMatch(formatp);
if (match == "") return 0;
else return 1;
}
IData VL_VALUEPLUSARGS_IN(int, const char* prefixp, char, string& ldr) {
const string& match = VerilatedImp::argPlusMatch(prefixp);
const char* dp = match.c_str() + 1 /*leading + */ + strlen(prefixp);
if (match == "") return 0;
ldr = string(dp);
return 1;
}
IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) {
std::string prefix;
bool inPct = false;
bool done = false;
char fmt = ' ';
for (const char* posp = ld.c_str(); !done && *posp; ++posp) {
if (!inPct && posp[0]=='%') {
inPct = true;
} else if (!inPct) { // Normal text
prefix += *posp;
} else { // Format character
switch (tolower(*posp)) {
case '%':
prefix += *posp;
inPct = false;
break;
default:
fmt = *posp;
done = true;
break;
}
}
}
IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp) {
const string& match = VerilatedImp::argPlusMatch(prefixp);
const char* dp = match.c_str() + 1 /*leading + */ + strlen(prefixp);
const std::string& match = VerilatedImp::argPlusMatch(prefix.c_str());
const char* dp = match.c_str() + 1 /*leading + */ + prefix.length();
if (match == "") return 0;
VL_ZERO_RESET_W(rbits, rwp);
switch (tolower(fmt)) {
case '%':
break;
case 'd':
vlsint64_t ld;
sscanf(dp,"%30" VL_PRI64 "d",&ld);
VL_SET_WQ(rwp,ld);
vlsint64_t lld;
sscanf(dp,"%30" VL_PRI64 "d",&lld);
VL_SET_WQ(rwp,lld);
break;
case 'b':
_vl_vsss_based(rwp,rbits, 1, dp, 0, (int)strlen(dp));
_vl_vsss_based(rwp,rbits, 1, dp, 0, strlen(dp));
break;
case 'o':
_vl_vsss_based(rwp,rbits, 3, dp, 0, (int)strlen(dp));
_vl_vsss_based(rwp,rbits, 3, dp, 0, strlen(dp));
break;
case 'h': //FALLTHRU
case 'x':
_vl_vsss_based(rwp,rbits, 4, dp, 0, (int)strlen(dp));
_vl_vsss_based(rwp,rbits, 4, dp, 0, strlen(dp));
break;
case 's':
for (int i=0, lsb=0, pos=((int)strlen(dp))-1; i<rbits && pos>=0; pos--) {
_vl_vsss_setbit(rwp,rbits,lsb, 8, dp[pos]); lsb+=8;
case 's': // string/no conversion
for (int i=0, lsb=0, posp=static_cast<int>(strlen(dp))-1; i<rbits && posp>=0; --posp) {
_vl_vsss_setbit(rwp,rbits,lsb, 8, dp[posp]); lsb+=8;
}
break;
default: // Compile time should have found all errors before this
vl_fatal (__FILE__, __LINE__, "", "$value$plusargs format error");
break;
case 'e': //FALLTHRU - Unsupported
case 'f': //FALLTHRU - Unsupported
case 'g': //FALLTHRU - Unsupported
default: // Other simulators simply return 0 in these cases and don't error out
return 0;
}
_VL_CLEAN_INPLACE_W(rbits,rwp);
return 1;
}
IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr) {
std::string prefix;
bool inPct = false;
bool done = false;
for (const char* posp = ld.c_str(); !done && *posp; ++posp) {
if (!inPct && posp[0]=='%') {
inPct = true;
} else if (!inPct) { // Normal text
prefix += *posp;
} else { // Format character
switch (tolower(*posp)) {
case '%':
prefix += *posp;
inPct = false;
break;
default:
done = true;
break;
}
}
}
const std::string& match = VerilatedImp::argPlusMatch(prefix.c_str());
const char* dp = match.c_str() + 1 /*leading + */ + prefix.length();
if (match == "") return 0;
rdr = std::string(dp);
return 1;
}
const char* vl_mc_scan_plusargs(const char* prefixp) {
const string& match = VerilatedImp::argPlusMatch(prefixp);
static VL_THREAD char outstr[VL_VALUE_STRING_MAX_WIDTH];
const std::string& match = VerilatedImp::argPlusMatch(prefixp);
static VL_THREAD_LOCAL char outstr[VL_VALUE_STRING_MAX_WIDTH];
if (match == "") return NULL;
strncpy(outstr, match.c_str()+strlen(prefixp)+1, // +1 to skip the "+"
VL_VALUE_STRING_MAX_WIDTH);
@@ -1134,7 +1258,7 @@ const char* vl_mc_scan_plusargs(const char* prefixp) {
//===========================================================================
// Heavy functions
string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) {
std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) {
// See also _VL_VINT_TO_STRING
char destout[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
int obits = lwords * VL_WORDSIZE;
@@ -1142,7 +1266,7 @@ string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) {
bool start=true;
char* destp = destout;
int len = 0;
for (; lsb>=0; lsb--) {
for (; lsb>=0; --lsb) {
lsb = (lsb / 8) * 8; // Next digit
IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xff;
if (!start || charval) {
@@ -1151,7 +1275,7 @@ string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) {
start = false; // Drop leading 0s
}
}
return string(destout, len);
return std::string(destout, len);
}
//===========================================================================
@@ -1163,7 +1287,7 @@ const char* Verilated::catName(const char* n1, const char* n2) {
static char* strp = NULL;
static size_t len = 0;
size_t newlen = strlen(n1)+strlen(n2)+2;
if (newlen > len) {
if (!strp || newlen > len) {
if (strp) delete [] strp;
strp = new char[newlen];
len = newlen;
@@ -1190,8 +1314,8 @@ void Verilated::commandArgs(int argc, const char** argv) {
}
const char* Verilated::commandArgsPlusMatch(const char* prefixp) {
const string& match = VerilatedImp::argPlusMatch(prefixp);
static VL_THREAD char outstr[VL_VALUE_STRING_MAX_WIDTH];
const std::string& match = VerilatedImp::argPlusMatch(prefixp);
static VL_THREAD_LOCAL char outstr[VL_VALUE_STRING_MAX_WIDTH];
if (match == "") return "";
strncpy(outstr, match.c_str(), VL_VALUE_STRING_MAX_WIDTH);
outstr[VL_VALUE_STRING_MAX_WIDTH-1] = '\0';
@@ -1321,19 +1445,19 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap,
} else {
// We could have a linked list of ranges, but really this whole thing needs
// to be generalized to support structs and unions, etc.
vl_fatal(__FILE__,__LINE__,"",(string("Unsupported multi-dimensional public varInsert: ")+namep).c_str());
vl_fatal(__FILE__,__LINE__,"",(std::string("Unsupported multi-dimensional public varInsert: ")+namep).c_str());
}
}
va_end(ap);
m_varsp->insert(make_pair(namep,var));
m_varsp->insert(std::make_pair(namep,var));
}
// cppcheck-suppress unusedFunction // Used by applications
VerilatedVar* VerilatedScope::varFind(const char* namep) const {
if (VL_LIKELY(m_varsp)) {
VerilatedVarNameMap::iterator it = m_varsp->find(namep);
if (VL_LIKELY(it != m_varsp->end())) {
if (VL_LIKELY(it != m_varsp->end())) {
return &(it->second);
}
}
@@ -1342,26 +1466,26 @@ VerilatedVar* VerilatedScope::varFind(const char* namep) const {
void* VerilatedScope::exportFindNullError(int funcnum) {
// Slowpath - Called only when find has failed
string msg = (string("Testbench C called '")
+VerilatedImp::exportName(funcnum)
+"' but scope wasn't set, perhaps due to dpi import call without 'context'");
std::string msg = (std::string("Testbench C called '")
+VerilatedImp::exportName(funcnum)
+"' but scope wasn't set, perhaps due to dpi import call without 'context'");
vl_fatal("unknown",0,"", msg.c_str());
return NULL;
}
void* VerilatedScope::exportFindError(int funcnum) const {
// Slowpath - Called only when find has failed
string msg = (string("Testbench C called '")
+VerilatedImp::exportName(funcnum)
+"' but this DPI export function exists only in other scopes, not scope '"
+name()+"'");
std::string msg = (std::string("Testbench C called '")
+VerilatedImp::exportName(funcnum)
+"' but this DPI export function exists only in other scopes, not scope '"
+name()+"'");
vl_fatal("unknown",0,"", msg.c_str());
return NULL;
}
void VerilatedScope::scopeDump() const {
VL_PRINTF(" SCOPE %p: %s\n", this, name());
for (int i=0; i<m_funcnumMax; i++) {
for (int i=0; i<m_funcnumMax; ++i) {
if (m_callbacksp && m_callbacksp[i]) {
VL_PRINTF(" DPI-EXPORT %p: %s\n",
m_callbacksp[i], VerilatedImp::exportName(i));
+300 -192
View File
File diff suppressed because it is too large Load Diff
+12 -22
View File
@@ -2,7 +2,7 @@
######################################################################
# DESCRIPTION: Makefile commands for all verilated target files
#
# Copyright 2003-2016 by Wilson Snyder. Verilator is free software; you can
# Copyright 2003-2017 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
@@ -49,8 +54,7 @@ VK_CPPFLAGS_ALWAYS += \
$(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)
@@ -93,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
@@ -106,23 +110,9 @@ ifeq ($(VM_SP_OR_SC),1)
endif
#######################################################################
##### SystemPerl builds
##### Stub
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
preproc:
endif
preproc:
#######################################################################
##### C/H builds
+1 -1
View File
@@ -4,7 +4,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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 -55
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
// Copyright 2001-2017 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.
//
@@ -50,7 +50,7 @@ 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++) {
for (int i=0; i<MAX_KEYS; ++i) {
m_keys[i]=KEY_UNDEF;
m_vals[i]=0;
}
@@ -72,6 +72,7 @@ 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
@@ -89,9 +90,9 @@ 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
@@ -118,19 +119,19 @@ public:
private:
// PRIVATE METHODS
int valueIndex(const string& value) {
int valueIndex(const std::string& value) {
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) {
// 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;
@@ -140,7 +141,7 @@ private:
}
return rtn;
}
bool legalKey(const string& key) {
static bool legalKey(const std::string& key) {
// 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...
@@ -149,17 +150,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) {
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) {
// (foo.a.x, foo.b.x) => foo.*.x
// (foo.a.x, foo.b.y) => foo.*
// (foo.a.x, foo.b) => foo.*
@@ -177,7 +178,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;
@@ -186,26 +187,26 @@ 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) {
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() {
// 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");
@@ -220,7 +221,7 @@ private:
public:
// PUBLIC METHODS
void clear() {
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
VerilatedCovImpItem* itemp = *(it);
delete itemp;
}
@@ -243,7 +244,7 @@ public:
}
}
void zero() {
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
(*it)->zero();
}
}
@@ -262,27 +263,27 @@ public:
assert(m_insertp);
// First two key/vals are filename
ckeyps[0]="filename"; valps[0]=m_insertFilenamep;
string linestr = vlCovCvtToStr(m_insertLineno);
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;
@@ -292,16 +293,16 @@ 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;
std::string msg = "%Error: Coverage keys of one character, or letter+digit are illegal: "+key;
vl_fatal("",0,"",msg.c_str());
}
}
@@ -317,27 +318,27 @@ public:
#endif
selftest();
ofstream os (filename);
std::ofstream os (filename);
if (os.fail()) {
string msg = (string)"%Error: Can't write '"+filename+"'";
std::string msg = std::string("%Error: Can't write '")+filename+"'";
vl_fatal("",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;
}
@@ -362,21 +363,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;
}
}
};
@@ -440,9 +441,9 @@ void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
}
// 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)) {
string val2str = vlCovCvtToStr(val2);
string val3str = vlCovCvtToStr(val3);
K(4),const std::string& val4, A(5),A(6)) {
std::string val2str = vlCovCvtToStr(val2);
std::string val3str = vlCovCvtToStr(val3);
_insertp(C(0),C(1),
key2,val2str.c_str(), key3,val3str.c_str(), key4, val4.c_str(),
C(5),C(6),N(7),N(8),N(9),
+5 -6
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
// Copyright 2001-2017 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,7 +27,6 @@
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
//=============================================================================
/// Conditionally compile coverage code
@@ -60,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));
/// }
@@ -75,7 +74,7 @@ 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();
std::ostringstream os; os<<t; return os.str();
}
//=============================================================================
@@ -115,7 +114,7 @@ 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
+2 -3
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
// Copyright 2001-2017 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.
//
@@ -25,7 +25,6 @@
#include "verilatedos.h"
#include <string>
using namespace std;
//=============================================================================
// Data used to edit below file, using vlcovgen
@@ -105,7 +104,7 @@ VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr
class VerilatedCovKey {
public:
static string shortKey(const string& key) {
static std::string shortKey(const std::string& key) {
// VLCOVGEN_SHORT_AUTO_EDIT_BEGIN
if (key == "col0") return VL_CIK_COL0;
if (key == "col0_name") return VL_CIK_COL0_NAME;
+16 -14
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@@ -30,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,7 +42,7 @@
// Not supported yet
#define _VL_SVDPI_UNIMP() \
vl_fatal(__FILE__,__LINE__,"",(string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str())
vl_fatal(__FILE__,__LINE__,"",(std::string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str())
// Function requires a "context" in the import declaration
#define _VL_SVDPI_CONTEXT_WARN() \
@@ -58,31 +60,31 @@ 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_BITISSET_W(sp,bit);
}
svLogic svGetBitselLogic(const svLogicVecVal* s, int i) {
svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) {
_VL_SVDPI_UNIMP(); return 0;
}
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) {
void svPutBitselLogic(svLogicVecVal* dp, int bit, svLogic s) {
_VL_SVDPI_UNIMP();
}
void svGetPartselBit(svBitVecVal* d, const svBitVecVal* s, int i, int w) {
void svGetPartselBit(svBitVecVal* dp, const svBitVecVal* sp, int i, int w) {
_VL_SVDPI_UNIMP();
}
void svGetPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w) {
void svGetPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int i, int w) {
_VL_SVDPI_UNIMP();
}
void svPutPartselBit(svBitVecVal* d, const svBitVecVal s, int i, int w) {
void svPutPartselBit(svBitVecVal* dp, const svBitVecVal s, int i, int w) {
_VL_SVDPI_UNIMP();
}
void svPutPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w) {
void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int i, int w) {
_VL_SVDPI_UNIMP();
}
@@ -261,13 +263,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();
}
+9 -9
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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
///
@@ -37,25 +37,25 @@
/// Return svBitVecVal from WData
static inline void VL_SET_W_SVBV(int obits, WDataOutP owp, svBitVecVal* lwp) {
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) {
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_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
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);
}
+35 -22
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2010-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2010-2017 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,36 +36,49 @@
//======================================================================
// 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);
inline std::string VL_CVT_PACK_STR_NQ(QData lhs) {
WData lw[2]; VL_SET_WQ(lw, lhs);
return VL_CVT_PACK_STR_NW(2, lw);
}
inline string VL_CVT_PACK_STR_NN(const string& lhs) {
inline std::string VL_CVT_PACK_STR_NN(const std::string& lhs) {
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) {
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) {
return lhs+rhs;
}
inline string VL_REPLICATEN_NNQ(int,int,int, 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) {
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) {
return VL_REPLICATEN_NNQ(obits,lbits,rbits,lhs,rep);
}
extern IData VL_FOPEN_NI(const string& filename, IData mode);
extern IData VL_FOPEN_NI(const std::string& filename, IData mode);
extern void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
const string& ofilename, void* memp, IData start, IData end);
extern IData VL_SSCANF_INX(int lbits, const string& ld, const char* formatp, ...);
extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...);
extern string VL_SFORMATF_NX(const char* formatp, ...);
extern IData VL_VALUEPLUSARGS_IN(int rbits, const char* prefixp, char fmt, string& ldr);
const std::string& ofilename, void* memp, IData start, IData end);
extern IData VL_SSCANF_INX(int lbits, const std::string& ld, const char* formatp, ...);
extern void VL_SFORMAT_X(int obits_ignored, std::string &output, const char* formatp, ...);
extern std::string VL_SFORMATF_NX(const char* formatp, ...);
extern IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rdp);
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, IData& rdr) {
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) {
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);
#endif // Guard
+24 -24
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@@ -47,9 +47,9 @@ 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*, 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
@@ -65,8 +65,8 @@ class VerilatedImp {
int m_exportNext; ///< Next export funcnum
// File I/O
vector<FILE*> m_fdps; ///< File descriptors
deque<IData> m_fdFree; ///< List of free descriptors (SLOW - FOPEN/CLOSE only)
std::vector<FILE*> m_fdps; ///< File descriptors
std::deque<IData> m_fdFree; ///< List of free descriptors (SLOW - FOPEN/CLOSE only)
public: // But only for verilated*.cpp
// CONSTRUCTORS
@@ -80,7 +80,7 @@ public: // But only for verilated*.cpp
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) {
for (ArgVec::const_iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
VL_PRINTF(" %s",it->c_str());
}
VL_PRINTF("\n");
@@ -97,10 +97,10 @@ public: // But only for verilated*.cpp
}
static void commandArgsAdd(int argc, const char** argv) {
if (!s_s.m_argVecLoaded) s_s.m_argVec.clear();
for (int i=0; i<argc; i++) s_s.m_argVec.push_back(argv[i]);
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) {
static std::string argPlusMatch(const char* prefixp) {
// Note prefixp does not include the leading "+"
size_t len = strlen(prefixp);
if (VL_UNLIKELY(!s_s.m_argVecLoaded)) {
@@ -109,7 +109,7 @@ public: // But only for verilated*.cpp
"%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;
}
@@ -122,13 +122,13 @@ public: // But only for verilated*.cpp
// 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));
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));
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;
}
@@ -146,7 +146,7 @@ private:
}
static void userDump() {
bool first = true;
for (UserMap::iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) {
for (UserMap::const_iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) {
if (first) { VL_PRINTF(" userDump:\n"); first=false; }
VL_PRINTF(" DPI_USER_DATA scope %p key %p: %p\n",
it->first.first, it->first.second, it->second);
@@ -159,11 +159,11 @@ public: // But only for verilated*.cpp
// Slow ok - called once/scope at construction
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) {
VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(namep);
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;
}
@@ -175,7 +175,7 @@ public: // But only for verilated*.cpp
}
static void scopesDump() {
VL_PRINTF(" scopesDump:\n");
for (VerilatedScopeNameMap::iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) {
for (VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) {
const VerilatedScope* scopep = it->second;
scopep->scopeDump();
}
@@ -198,30 +198,30 @@ public: // But only for verilated*.cpp
// Slow ok - called once/function at creation
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);
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");
std::string msg = (std::string("%Error: Testbench C called ")+namep
+" but no such DPI export function name exists in ANY model");
vl_fatal("unknown",0,"", msg.c_str());
return -1;
}
static const char* exportName(int funcnum) {
// 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) {
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() {
bool first = true;
for (ExportNameMap::iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
if (first) { VL_PRINTF(" exportDump:\n"); first=false; }
VL_PRINTF(" DPI_EXPORT_NAME %05d: %s\n", it->second, it->first);
}
@@ -238,7 +238,7 @@ public: // But only for verilated*.cpp
// 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;
+12 -12
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
// Copyright 2001-2017 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.
//
@@ -40,8 +40,8 @@
#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
//=============================================================================
//=============================================================================
@@ -60,8 +60,8 @@ bool VerilatedDeserialize::readDiffers (const void* __restrict datap, size_t siz
VerilatedDeserialize& VerilatedDeserialize::readAssert (const void* __restrict datap, size_t size) {
if (VL_UNLIKELY(readDiffers(datap,size))) {
string fn = filename();
string msg = (string)"Can't deserialize save-restore file as was made from different model";
std::string fn = filename();
std::string msg = std::string("Can't deserialize save-restore file as was made from different model");
vl_fatal(fn.c_str(), 0, "", msg.c_str());
close();
}
@@ -81,8 +81,8 @@ void VerilatedSerialize::header() {
void VerilatedDeserialize::header() {
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";
std::string fn = filename();
std::string msg = std::string("Can't deserialize; file has wrong header signature");
vl_fatal(fn.c_str(), 0, "", msg.c_str());
close();
}
@@ -98,8 +98,8 @@ void VerilatedSerialize::trailer() {
void VerilatedDeserialize::trailer() {
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";
std::string fn = filename();
std::string msg = std::string("Can't deserialize; file has wrong end-of-file signature");
vl_fatal(fn.c_str(), 0, "", msg.c_str());
close();
}
@@ -187,7 +187,7 @@ 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);
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
vl_fatal("",0,"",msg.c_str());
close();
break;
@@ -204,7 +204,7 @@ void VerilatedRestore::fill() {
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;
@@ -215,7 +215,7 @@ 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);
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
vl_fatal("",0,"",msg.c_str());
close();
break;
+51 -43
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2012-2016 by Wilson Snyder. This program is free software;
// Copyright 2012-2017 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.
//
@@ -25,66 +25,40 @@
#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
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
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
inline static size_t bufferInsertSize() { return 16*1024; }
void header();
void trailer();
public:
// CREATORS
VerilatedSerialBase() {
VerilatedSerialize() {
m_isOpen = false;
m_bufp = new vluint8_t [bufferSize()];
m_cp = m_bufp;
}
private:
VerilatedSerialBase(const VerilatedSerialBase& ); ///< N/A, no copy constructor
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; }
std::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) {
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
while (size) {
@@ -96,22 +70,54 @@ public:
}
return *this; // For function chaining
}
private:
VerilatedSerialize(const VerilatedSerialize& ); ///< N/A, no copy constructor
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
}
};
//=============================================================================
// VerilatedDeserial - load structures from a stream representation
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
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();
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
bool isOpen() const { return m_isOpen; }
std::string filename() const { return m_filename; }
virtual void close() { flush(); }
virtual void flush() {}
inline VerilatedDeserialize& read (void* __restrict datap, size_t size) {
vluint8_t* __restrict dp = (vluint8_t* __restrict)datap;
while (size) {
@@ -127,6 +133,8 @@ public:
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)); }
private:
VerilatedDeserialize(const VerilatedDeserialize& ); ///< N/A, no copy constructor
VerilatedDeserialize& 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
@@ -150,7 +158,7 @@ public:
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()); }
void open(const std::string& filename) { open(filename.c_str()); }
virtual void close();
virtual void flush();
};
@@ -169,7 +177,7 @@ public:
// METHODS
void open(const char* filenamep); ///< Open the file; call isOpen() to see if errors
void open(const string& filename) { open(filename.c_str()); }
void open(const std::string& filename) { open(filename.c_str()); }
virtual void close();
virtual void flush() {}
virtual void fill();
@@ -219,12 +227,12 @@ 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) {
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, std::string& rhs) {
vluint32_t len=0;
os>>len;
rhs.resize(len);
+6 -6
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2017 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
///
@@ -39,9 +39,9 @@
#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) {
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
};
+6 -5
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@@ -36,7 +36,7 @@
/// Verilator range
// See also V3Ast::VNumRange
class VerilatedRange {
class VerilatedRange {
int m_left;
int m_right;
protected:
@@ -71,7 +71,7 @@ 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); }
VerilatedVarFlags vldir() const { return static_cast<VerilatedVarFlags>(static_cast<int>(m_vlflags) & VLVF_MASK_DIR); }
vluint32_t entSize() const;
bool isPublicRW() const { return ((m_vlflags & VLVF_PUB_RW) != 0); }
const VerilatedRange& range() const { return m_range; }
@@ -91,13 +91,14 @@ struct VerilatedCStrCmp {
};
class VerilatedScopeNameMap
: public map<const char*, const VerilatedScope*, VerilatedCStrCmp> {
: public std::map<const char*, const VerilatedScope*, VerilatedCStrCmp> {
public:
VerilatedScopeNameMap() {}
~VerilatedScopeNameMap() {}
};
class VerilatedVarNameMap : public map<const char*, VerilatedVar, VerilatedCStrCmp> {
class VerilatedVarNameMap
: public std::map<const char*, VerilatedVar, VerilatedCStrCmp> {
public:
VerilatedVarNameMap() {}
~VerilatedVarNameMap() {}
+64 -39
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
@@ -47,9 +47,32 @@
#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 {
VcdVec s_vcdVecp; ///< List of all created traces
};
static Singleton& singleton() { static Singleton s; return s; }
public:
static void pushVcd(VerilatedVcd* vcdp) {
singleton().s_vcdVecp.push_back(vcdp);
}
static void removeVcd(const VerilatedVcd* vcdp) {
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() {
for (VcdVec::const_iterator it=singleton().s_vcdVecp.begin(); it!=singleton().s_vcdVecp.end(); ++it) {
VerilatedVcd* vcdp = *it;
vcdp->flush();
}
}
};
//=============================================================================
// VerilatedVcdCallInfo
@@ -72,6 +95,7 @@ protected:
VerilatedVcdCallback_t changecb,
void* ut, vluint32_t code)
: m_initcb(icb), m_fullcb(fcb), m_changecb(changecb), m_userthis(ut), m_code(code) {};
~VerilatedVcdCallInfo() {}
};
//=============================================================================
@@ -79,7 +103,7 @@ protected:
//=============================================================================
// VerilatedVcdFile
bool VerilatedVcdFile::open(const string& name) {
bool VerilatedVcdFile::open(const std::string& name) {
m_fd = ::open(name.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK, 0666);
return (m_fd>=0);
}
@@ -121,7 +145,7 @@ void VerilatedVcd::open (const char* filename) {
// 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
@@ -150,7 +174,7 @@ void VerilatedVcd::openNext (bool incFilename) {
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])
@@ -204,19 +228,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;
@@ -233,9 +257,11 @@ VerilatedVcd::~VerilatedVcd() {
if (m_sigs_oldvalp) { delete[] m_sigs_oldvalp; m_sigs_oldvalp=NULL; }
deleteNameMap();
if (m_filep && m_fileNewed) { delete m_filep; m_filep = NULL; }
// 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); }
for (CallbackVec::const_iterator it=m_callbacks.begin(); it!=m_callbacks.end(); ++it) {
delete (*it);
}
m_callbacks.clear();
VerilatedVcdSingleton::removeVcd(this);
}
void VerilatedVcd::closePrev () {
@@ -326,7 +352,7 @@ void VerilatedVcd::bufferFlush () {
} 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);
std::string msg = std::string("VerilatedVcd::bufferFlush: ")+strerror(errno);
vl_fatal("",0,"",msg.c_str());
closeErr();
break;
@@ -354,7 +380,7 @@ void VerilatedVcd::set_time_resolution (const char* 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) {
@@ -369,7 +395,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; }
@@ -398,7 +424,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");
@@ -412,13 +438,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();
@@ -472,7 +498,7 @@ void VerilatedVcd::dumpHeader () {
deleteNameMap();
}
void VerilatedVcd::module (const string& name) {
void VerilatedVcd::module (const std::string& name) {
m_modName = name;
}
@@ -485,7 +511,7 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
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(nextCode(), code+codesNeeded);
if (m_sigs.capacity() <= m_nextCode) {
m_sigs.reserve(m_nextCode*2); // Power-of-2 allocation speeds things up
}
@@ -503,10 +529,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
@@ -520,7 +546,7 @@ 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);
@@ -543,7 +569,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)
@@ -570,7 +596,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);
@@ -578,9 +605,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();
@@ -594,7 +622,7 @@ void VerilatedVcd::addCallback (
void* userthis)
{
if (VL_UNLIKELY(isOpen())) {
string msg = (string)"Internal: "+__FILE__+"::"+__FUNCTION__+" called with already open file";
std::string msg = std::string("Internal: ")+__FILE__+"::"+__FUNCTION__+" called with already open file";
vl_fatal(__FILE__,__LINE__,"",msg.c_str());
}
VerilatedVcdCallInfo* vci = new VerilatedVcdCallInfo(initcb, fullcb, changecb, userthis, nextCode());
@@ -645,10 +673,7 @@ 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();
}
VerilatedVcdSingleton::flush_all();
}
//======================================================================
+49 -38
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
// Copyright 2001-2017 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,7 +28,6 @@
#include <string>
#include <vector>
#include <map>
using namespace std;
class VerilatedVcd;
class VerilatedVcdCallInfo;
@@ -45,7 +44,7 @@ public:
// METHODS
VerilatedVcdFile() : m_fd(0) {}
virtual ~VerilatedVcdFile() {}
virtual bool open(const string& name);
virtual bool open(const std::string& name);
virtual void close();
virtual ssize_t write(const char* bufp, ssize_t len);
};
@@ -80,13 +79,13 @@ private:
bool m_fileNewed; ///< m_filep needs destruction
bool m_isOpen; ///< True indicates open file
bool m_evcd; ///< True for evcd format
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
@@ -97,12 +96,13 @@ 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
void bufferResize(vluint64_t minsize);
void bufferFlush();
@@ -131,17 +131,17 @@ 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) {
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);
}
VerilatedVcd(const VerilatedVcd& ); ///< N/A, no copy constructor
@@ -175,18 +175,18 @@ public:
void close (); ///< Close the file
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,
@@ -194,7 +194,7 @@ public:
void* userthis);
/// 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);
@@ -212,7 +212,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) {
@@ -225,7 +225,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');
@@ -264,8 +264,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)
@@ -329,7 +329,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);
@@ -364,8 +364,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);
@@ -382,12 +382,14 @@ 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);
}
}
@@ -425,9 +427,18 @@ public:
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; };
};
+1 -1
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
+1 -1
View File
@@ -3,7 +3,7 @@
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
// Copyright 2001-2017 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.
//
+69 -66
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2017 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.
@@ -52,7 +52,7 @@ VerilatedVpiError* VerilatedVpi::error_info() {
// VerilatedVpiError Methods
const char* VerilatedVpiError::strFromVpiVal(PLI_INT32 vpiVal) {
static const char *names[] = {
static const char* const names[] = {
"*undefined*",
"vpiBinStrVal",
"vpiOctStrVal",
@@ -77,7 +77,7 @@ const char* VerilatedVpiError::strFromVpiVal(PLI_INT32 vpiVal) {
return names[(vpiVal<=vpiRawFourStateVal)?vpiVal:0];
}
const char* VerilatedVpiError::strFromVpiObjType(PLI_INT32 vpiVal) {
static const char *names[] = {
static const char* const names[] = {
"*undefined*",
"vpiAlways",
"vpiAssignStmt",
@@ -219,7 +219,7 @@ const char* VerilatedVpiError::strFromVpiObjType(PLI_INT32 vpiVal) {
return names[(vpiVal<=vpiGenVar)?vpiVal:0];
}
const char* VerilatedVpiError::strFromVpiMethod(PLI_INT32 vpiVal) {
static const char *names[] = {
static const char* const names[] = {
"vpiCondition",
"vpiDelay",
"vpiElseStmt",
@@ -262,7 +262,7 @@ const char* VerilatedVpiError::strFromVpiMethod(PLI_INT32 vpiVal) {
}
const char* VerilatedVpiError::strFromVpiCallbackReason(PLI_INT32 vpiVal) {
static const char *names[] = {
static const char* const names[] = {
"*undefined*",
"cbValueChange",
"cbStmt",
@@ -301,7 +301,7 @@ const char* VerilatedVpiError::strFromVpiCallbackReason(PLI_INT32 vpiVal) {
}
const char* VerilatedVpiError::strFromVpiProp(PLI_INT32 vpiVal) {
static const char *names[] = {
static const char* const names[] = {
"*undefined or other*",
"vpiType",
"vpiName",
@@ -386,7 +386,7 @@ const char* VerilatedVpiError::strFromVpiProp(PLI_INT32 vpiVal) {
#define CHECK_RESULT_CSTR(got, exp) \
if (strcmp((got),(exp))) { \
string msg = string("%Error: ") \
std::string msg = std::string("%Error: ") \
+ "GOT = '"+((got)?(got):"<null>")+"'" \
+ " EXP = '"+((exp)?(exp):"<null>")+"'"; \
vl_fatal(__FILE__,__LINE__,"",msg.c_str()); \
@@ -502,9 +502,9 @@ vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
VerilatedVpioScope* voScopep = VerilatedVpioScope::castp(scope);
const VerilatedVar* varp;
const VerilatedScope* scopep;
string scopeAndName = namep;
std::string scopeAndName = namep;
if (voScopep) {
scopeAndName = string(voScopep->fullname()) + "." + namep;
scopeAndName = std::string(voScopep->fullname()) + "." + namep;
namep = (PLI_BYTE8*)scopeAndName.c_str();
}
{
@@ -514,11 +514,11 @@ vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
return (new VerilatedVpioScope(scopep))->castVpiHandle();
}
const char* baseNamep = scopeAndName.c_str();
string scopename;
std::string scopename;
const char* dotp = strrchr(namep, '.');
if (VL_LIKELY(dotp)) {
baseNamep = dotp+1;
scopename = string(namep,dotp-namep);
scopename = std::string(namep,dotp-namep);
}
scopep = Verilated::scopeFind(scopename.c_str());
if (!scopep) return NULL;
@@ -721,9 +721,9 @@ void vpi_put_delays(vpiHandle object, p_vpi_delay delay_p) {
// value processing
void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
static VL_THREAD char outStr[1+VL_MULS_MAX_WORDS*32]; // Maximum required size is for binary string, one byte per bit plus null termination
static VL_THREAD_LOCAL char outStr[1+VL_MULS_MAX_WORDS*32]; // Maximum required size is for binary string, one byte per bit plus null termination
// cppcheck-suppress variableScope
static VL_THREAD int outStrSz = sizeof(outStr)-1;
static VL_THREAD_LOCAL int outStrSz = sizeof(outStr)-1;
VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi: vpi_get_value %p\n",object););
_VL_VPI_ERROR_RESET(); // reset vpi error status
if (VL_UNLIKELY(!value_p)) return;
@@ -733,19 +733,19 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
if (value_p->format == vpiVectorVal) {
// Vector pointer must come from our memory pool
// It only needs to persist until the next vpi_get_value
static VL_THREAD t_vpi_vecval out[VL_MULS_MAX_WORDS*2];
static VL_THREAD_LOCAL t_vpi_vecval out[VL_MULS_MAX_WORDS*2];
value_p->value.vector = out;
switch (vop->varp()->vltype()) {
case VLVT_UINT8:
out[0].aval = *((CData*)(vop->varDatap()));
out[0].aval = *(reinterpret_cast<CData*>(vop->varDatap()));
out[0].bval = 0;
return;
case VLVT_UINT16:
out[0].aval = *((SData*)(vop->varDatap()));
out[0].aval = *(reinterpret_cast<SData*>(vop->varDatap()));
out[0].bval = 0;
return;
case VLVT_UINT32:
out[0].aval = *((IData*)(vop->varDatap()));
out[0].aval = *(reinterpret_cast<IData*>(vop->varDatap()));
out[0].bval = 0;
return;
case VLVT_WDATA: {
@@ -753,18 +753,18 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
if (VL_UNLIKELY(words >= VL_MULS_MAX_WORDS)) {
vl_fatal(__FILE__,__LINE__,"", "vpi_get_value with more than VL_MULS_MAX_WORDS; increase and recompile");
}
WDataInP datap = ((IData*)(vop->varDatap()));
for (int i=0; i<words; i++) {
WDataInP datap = (reinterpret_cast<IData*>(vop->varDatap()));
for (int i=0; i<words; ++i) {
out[i].aval = datap[i];
out[i].bval = 0;
}
return;
}
case VLVT_UINT64: {
QData data = *((QData*)(vop->varDatap()));
out[1].aval = (IData)(data>>VL_ULL(32));
QData data = *(reinterpret_cast<QData*>(vop->varDatap()));
out[1].aval = static_cast<IData>(data>>VL_ULL(32));
out[1].bval = 0;
out[0].aval = (IData)(data);
out[0].aval = static_cast<IData>(data);
out[0].bval = 0;
return;
}
@@ -783,7 +783,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
case VLVT_UINT64:
case VLVT_WDATA: {
int bits = vop->varp()->range().elements();
CData* datap = ((CData*)(vop->varDatap()));
CData* datap = (reinterpret_cast<CData*>(vop->varDatap()));
int i;
if (bits > outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
@@ -791,7 +791,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, bits);
}
for (i=0; i<bits; i++) {
for (i=0; i<bits; ++i) {
char val = (datap[i>>3]>>(i&7))&1;
outStr[bits-i-1] = val?'1':'0';
}
@@ -813,7 +813,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
case VLVT_WDATA: {
int chars = (vop->varp()->range().elements()+2)/3;
int bytes = VL_BYTES_I(vop->varp()->range().elements());
CData* datap = ((CData*)(vop->varDatap()));
CData* datap = (reinterpret_cast<CData*>(vop->varDatap()));
int i;
if (chars > outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
@@ -821,7 +821,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, chars);
chars = outStrSz;
}
for (i=0; i<chars; i++) {
for (i=0; i<chars; ++i) {
div_t idx = div(i*3, 8);
int val = datap[idx.quot];
if ((idx.quot+1)<bytes) {
@@ -855,10 +855,14 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
value_p->value.str = outStr;
switch (vop->varp()->vltype()) {
// outStrSz does not include NULL termination so add one
case VLVT_UINT8 : VL_SNPRINTF(outStr, outStrSz+1, "%hhu", (unsigned char )*((CData*)(vop->varDatap()))); return;
case VLVT_UINT16: VL_SNPRINTF(outStr, outStrSz+1, "%hu", (unsigned short)*((SData*)(vop->varDatap()))); return;
case VLVT_UINT32: VL_SNPRINTF(outStr, outStrSz+1, "%u", (unsigned int )*((IData*)(vop->varDatap()))); return;
case VLVT_UINT64: VL_SNPRINTF(outStr, outStrSz+1, "%llu", (unsigned long long)*((QData*)(vop->varDatap()))); return;
case VLVT_UINT8 : VL_SNPRINTF(outStr, outStrSz+1, "%hhu",
static_cast<unsigned char>(*(reinterpret_cast<CData*>(vop->varDatap())))); return;
case VLVT_UINT16: VL_SNPRINTF(outStr, outStrSz+1, "%hu",
static_cast<unsigned short>(*(reinterpret_cast<SData*>(vop->varDatap())))); return;
case VLVT_UINT32: VL_SNPRINTF(outStr, outStrSz+1, "%u",
static_cast<unsigned int>(*(reinterpret_cast<IData*>(vop->varDatap())))); return;
case VLVT_UINT64: VL_SNPRINTF(outStr, outStrSz+1, "%llu",
static_cast<unsigned long long>(*(reinterpret_cast<QData*>(vop->varDatap())))); return;
default:
strcpy(outStr, "-1");
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s, maximum limit is 64 bits",
@@ -874,7 +878,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
case VLVT_UINT64:
case VLVT_WDATA: {
int chars = (vop->varp()->range().elements()+3)>>2;
CData* datap = ((CData*)(vop->varDatap()));
CData* datap = (reinterpret_cast<CData*>(vop->varDatap()));
int i;
if (chars > outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
@@ -882,9 +886,8 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, chars);
chars = outStrSz;
}
for (i=0; i<chars; i++) {
for (i=0; i<chars; ++i) {
char val = (datap[i>>1]>>((i&1)<<2))&15;
static char hex[] = "0123456789abcdef";
if (i==(chars-1)) {
// most signifcant char, mask off non existant bits when vector
// size is not a multiple of 4
@@ -894,7 +897,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
val &= (1<<rem)-1;
}
}
outStr[chars-i-1] = hex[static_cast<int>(val)];
outStr[chars-i-1] = "0123456789abcdef"[static_cast<int>(val)];
}
outStr[i]=0; // NULL terminate
return;
@@ -913,7 +916,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
case VLVT_UINT64:
case VLVT_WDATA: {
int bytes = VL_BYTES_I(vop->varp()->range().elements());
CData* datap = ((CData*)(vop->varDatap()));
CData* datap = (reinterpret_cast<CData*>(vop->varDatap()));
int i;
if (bytes > outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
@@ -922,7 +925,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, bytes);
bytes = outStrSz;
}
for (i=0; i<bytes; i++) {
for (i=0; i<bytes; ++i) {
char val = datap[bytes-i-1];
// other simulators replace [leading?] zero chars with spaces, replicate here.
outStr[i] = val?val:' ';
@@ -938,19 +941,18 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
} else if (value_p->format == vpiIntVal) {
switch (vop->varp()->vltype()) {
case VLVT_UINT8:
value_p->value.integer = *((CData*)(vop->varDatap()));
value_p->value.integer = *(reinterpret_cast<CData*>(vop->varDatap()));
return;
case VLVT_UINT16:
value_p->value.integer = *((SData*)(vop->varDatap()));
value_p->value.integer = *(reinterpret_cast<SData*>(vop->varDatap()));
return;
case VLVT_UINT32:
value_p->value.integer = *((IData*)(vop->varDatap()));
value_p->value.integer = *(reinterpret_cast<IData*>(vop->varDatap()));
return;
case VLVT_WDATA:
case VLVT_UINT64:
// Not legal
value_p->value.integer = 0;
case VLVT_WDATA: // FALLTHRU
case VLVT_UINT64: // FALLTHRU
default:
value_p->value.integer = 0;
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return;
@@ -996,18 +998,18 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
if (VL_UNLIKELY(!value_p->value.vector)) return NULL;
switch (vop->varp()->vltype()) {
case VLVT_UINT8:
*((CData*)(vop->varDatap())) = value_p->value.vector[0].aval & vop->mask();
*(reinterpret_cast<CData*>(vop->varDatap())) = value_p->value.vector[0].aval & vop->mask();
return object;
case VLVT_UINT16:
*((SData*)(vop->varDatap())) = value_p->value.vector[0].aval & vop->mask();
*(reinterpret_cast<SData*>(vop->varDatap())) = value_p->value.vector[0].aval & vop->mask();
return object;
case VLVT_UINT32:
*((IData*)(vop->varDatap())) = value_p->value.vector[0].aval & vop->mask();
*(reinterpret_cast<IData*>(vop->varDatap())) = value_p->value.vector[0].aval & vop->mask();
return object;
case VLVT_WDATA: {
int words = VL_WORDS_I(vop->varp()->range().elements());
WDataOutP datap = ((IData*)(vop->varDatap()));
for (int i=0; i<words; i++) {
WDataOutP datap = (reinterpret_cast<IData*>(vop->varDatap()));
for (int i=0; i<words; ++i) {
datap[i] = value_p->value.vector[i].aval;
if (i==(words-1)) {
datap[i] &= vop->mask();
@@ -1016,7 +1018,7 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
return object;
}
case VLVT_UINT64: {
*((QData*)(vop->varDatap())) = _VL_SET_QII(
*(reinterpret_cast<QData*>(vop->varDatap())) = _VL_SET_QII(
value_p->value.vector[1].aval & vop->mask(),
value_p->value.vector[0].aval);
return object;
@@ -1036,8 +1038,8 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
case VLVT_WDATA: {
int bits = vop->varp()->range().elements();
int len = strlen(value_p->value.str);
CData* datap = ((CData*)(vop->varDatap()));
for (int i=0; i<bits; i++) {
CData* datap = (reinterpret_cast<CData*>(vop->varDatap()));
for (int i=0; i<bits; ++i) {
char set = (i < len)?(value_p->value.str[len-i-1]=='1'):0;
// zero bits 7:1 of byte when assigning to bit 0, else
// or in 1 if bit set
@@ -1064,10 +1066,10 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
int chars = (vop->varp()->range().elements()+2)/3;
int bytes = VL_BYTES_I(vop->varp()->range().elements());
int len = strlen(value_p->value.str);
CData* datap = ((CData*)(vop->varDatap()));
CData* datap = (reinterpret_cast<CData*>(vop->varDatap()));
div_t idx;
datap[0] = 0; // reset zero'th byte
for (int i=0; i<chars; i++) {
for (int i=0; i<chars; ++i) {
union {
char byte[2];
short half;
@@ -1105,7 +1107,7 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
datap[idx.quot+1] &= vop->mask_byte(idx.quot+1);
}
// zero off remaining top bytes
for (int i=idx.quot+2; i<bytes; i++) {
for (int i=idx.quot+2; i<bytes; ++i) {
datap[i] = 0;
}
return object;
@@ -1129,10 +1131,11 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
VL_FUNC, remainder, value_p->value.str, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
}
switch (vop->varp()->vltype()) {
case VLVT_UINT8 : *((CData*)(vop->varDatap())) = val & vop->mask(); break;
case VLVT_UINT16: *((SData*)(vop->varDatap())) = val & vop->mask(); break;
case VLVT_UINT32: *((IData*)(vop->varDatap())) = val & vop->mask(); break;
case VLVT_UINT64: *((QData*)(vop->varDatap())) = val; ((IData*)(vop->varDatap()))[1] &= vop->mask(); break;
case VLVT_UINT8 : *(reinterpret_cast<CData*>(vop->varDatap())) = val & vop->mask(); break;
case VLVT_UINT16: *(reinterpret_cast<SData*>(vop->varDatap())) = val & vop->mask(); break;
case VLVT_UINT32: *(reinterpret_cast<IData*>(vop->varDatap())) = val & vop->mask(); break;
case VLVT_UINT64: *(reinterpret_cast<QData*>(vop->varDatap())) = val;
(reinterpret_cast<IData*>(vop->varDatap()))[1] &= vop->mask(); break;
case VLVT_WDATA:
default:
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s, maximum limit is 64 bits",
@@ -1148,14 +1151,14 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
case VLVT_UINT64:
case VLVT_WDATA: {
int chars = (vop->varp()->range().elements()+3)>>2;
CData* datap = ((CData*)(vop->varDatap()));
CData* datap = (reinterpret_cast<CData*>(vop->varDatap()));
char* val = value_p->value.str;
// skip hex ident if one is detected at the start of the string
if (val[0] == '0' && (val[1] == 'x' || val[1] == 'X')) {
val += 2;
}
int len = strlen(val);
for (int i=0; i<chars; i++) {
for (int i=0; i<chars; ++i) {
char hex;
// compute hex digit value
if (i < len) {
@@ -1196,8 +1199,8 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
case VLVT_WDATA: {
int bytes = VL_BYTES_I(vop->varp()->range().elements());
int len = strlen(value_p->value.str);
CData* datap = ((CData*)(vop->varDatap()));
for (int i=0; i<bytes; i++) {
CData* datap = (reinterpret_cast<CData*>(vop->varDatap()));
for (int i=0; i<bytes; ++i) {
datap[i] = (i < len)?value_p->value.str[len-i-1]:0; // prepend with 0 values before placing string the least signifcant bytes
}
return object;
@@ -1210,13 +1213,13 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
} else if (value_p->format == vpiIntVal) {
switch (vop->varp()->vltype()) {
case VLVT_UINT8:
*((CData*)(vop->varDatap())) = vop->mask() & value_p->value.integer;
*(reinterpret_cast<CData*>(vop->varDatap())) = vop->mask() & value_p->value.integer;
return object;
case VLVT_UINT16:
*((SData*)(vop->varDatap())) = vop->mask() & value_p->value.integer;
*(reinterpret_cast<SData*>(vop->varDatap())) = vop->mask() & value_p->value.integer;
return object;
case VLVT_UINT32:
*((IData*)(vop->varDatap())) = vop->mask() & value_p->value.integer;
*(reinterpret_cast<IData*>(vop->varDatap())) = vop->mask() & value_p->value.integer;
return object;
case VLVT_WDATA: // FALLTHRU
case VLVT_UINT64: // FALLTHRU
@@ -1255,7 +1258,7 @@ void vpi_get_time(vpiHandle object, p_vpi_time time_p) {
}
if (time_p->type == vpiSimTime) {
QData qtime = VL_TIME_Q();
IData itime[2];
WData itime[2];
VL_SET_WQ(itime, qtime);
time_p->low = itime[0];
time_p->high = itime[1];
+45 -42
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2017 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.
@@ -83,7 +83,7 @@ public:
return newp+8;
} else {
// +8: 8 bytes for next
vluint8_t* newp = (vluint8_t*)(::operator new(chunk+8));
vluint8_t* newp = reinterpret_cast<vluint8_t*>(::operator new(chunk+8));
return newp+8;
}
}
@@ -94,13 +94,13 @@ public:
}
// MEMBERS
static inline VerilatedVpio* castp(vpiHandle h) { return dynamic_cast<VerilatedVpio*>((VerilatedVpio*)h); }
inline vpiHandle castVpiHandle() { return (vpiHandle)(this); }
inline vpiHandle castVpiHandle() { return reinterpret_cast<vpiHandle>(this); }
// ACCESSORS
virtual const char* name() { return "<null>"; }
virtual const char* fullname() { return "<null>"; }
virtual const char* defname() { return "<null>"; }
virtual const vluint32_t type() { return 0; }
virtual const vluint32_t size() const { return 0; }
virtual const char* name() const { return "<null>"; }
virtual const char* fullname() const { return "<null>"; }
virtual const char* defname() const { return "<null>"; }
virtual vluint32_t type() const { return 0; }
virtual vluint32_t size() const { return 0; }
virtual const VerilatedRange* rangep() const { return NULL; }
virtual vpiHandle dovpi_scan() { return 0; }
};
@@ -120,7 +120,7 @@ public:
}
virtual ~VerilatedVpioCb() {}
static inline VerilatedVpioCb* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioCb*>((VerilatedVpio*)h); }
virtual const vluint32_t type() { return vpiCallback; }
virtual vluint32_t type() const { return vpiCallback; }
vluint32_t reason() const { return m_cbData.reason; }
VerilatedPliCb cb_rtnp() const { return m_cbData.cb_rtn; }
t_cb_data* cb_datap() { return &(m_cbData); }
@@ -133,7 +133,7 @@ public:
explicit VerilatedVpioConst(vlsint32_t num) : m_num(num) {}
virtual ~VerilatedVpioConst() {}
static inline VerilatedVpioConst* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioConst*>((VerilatedVpio*)h); }
virtual const vluint32_t type() { return vpiUndefined; }
virtual vluint32_t type() const { return vpiUndefined; }
vlsint32_t num() const { return m_num; }
};
@@ -144,8 +144,8 @@ public:
explicit VerilatedVpioRange(const VerilatedRange* range) : m_range(range), m_iteration(0) {}
virtual ~VerilatedVpioRange() {}
static inline VerilatedVpioRange* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioRange*>((VerilatedVpio*)h); }
virtual const vluint32_t type() { return vpiRange; }
virtual const vluint32_t size() const { return m_range->elements(); }
virtual vluint32_t type() const { return vpiRange; }
virtual vluint32_t size() const { return m_range->elements(); }
virtual const VerilatedRange* rangep() const { return m_range; }
int iteration() const { return m_iteration; }
void iterationInc() { ++m_iteration; }
@@ -167,10 +167,10 @@ public:
: m_scopep(scopep) {}
virtual ~VerilatedVpioScope() {}
static inline VerilatedVpioScope* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioScope*>((VerilatedVpio*)h); }
virtual const vluint32_t type() { return vpiScope; }
virtual vluint32_t type() const { return vpiScope; }
const VerilatedScope* scopep() const { return m_scopep; }
virtual const char* name() { return m_scopep->name(); }
virtual const char* fullname() { return m_scopep->name(); }
virtual const char* name() const { return m_scopep->name(); }
virtual const char* fullname() const { return m_scopep->name(); }
};
class VerilatedVpioVar : public VerilatedVpio {
@@ -206,17 +206,17 @@ public:
vluint32_t mask() const { return m_mask.u32; }
vluint8_t mask_byte(int idx) { return m_mask.u8[idx & 3]; }
vluint32_t entSize() const { return m_entSize; }
const vluint32_t index() { return m_index; }
virtual const vluint32_t type() {
vluint32_t index() { return m_index; }
virtual vluint32_t type() const {
if (varp()->vldir() != vpiNoDirection) return vpiPort;
return (varp()->dims()>1) ? vpiMemory : vpiReg; /* but might be wire, logic */
}
virtual const vluint32_t size() const { return get_range().elements(); }
virtual vluint32_t size() const { return get_range().elements(); }
virtual const VerilatedRange* rangep() const { return &get_range(); }
virtual const char* name() { return m_varp->name(); }
virtual const char* fullname() {
VL_STATIC_OR_THREAD string out;
out = string(m_scopep->name())+"."+name();
virtual const char* name() const { return m_varp->name(); }
virtual const char* fullname() const {
static VL_THREAD_LOCAL std::string out;
out = std::string(m_scopep->name())+"."+name();
return out.c_str();
}
void* prevDatap() const { return m_prevDatap; }
@@ -239,27 +239,27 @@ public:
}
virtual ~VerilatedVpioMemoryWord() {}
static inline VerilatedVpioMemoryWord* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioMemoryWord*>((VerilatedVpio*)h); }
virtual const vluint32_t type() { return vpiMemoryWord; }
virtual const vluint32_t size() const { return varp()->range().elements(); }
virtual vluint32_t type() const { return vpiMemoryWord; }
virtual vluint32_t size() const { return varp()->range().elements(); }
virtual const VerilatedRange* rangep() const { return &(varp()->range()); }
virtual const char* fullname() {
VL_STATIC_OR_THREAD string out;
virtual const char* fullname() const {
static VL_THREAD_LOCAL std::string out;
char num[20]; sprintf(num,"%d",m_index);
out = string(scopep()->name())+"."+name()+"["+num+"]";
out = std::string(scopep()->name())+"."+name()+"["+num+"]";
return out.c_str();
}
};
class VerilatedVpioVarIter : public VerilatedVpio {
const VerilatedScope* m_scopep;
VerilatedVarNameMap::iterator m_it;
VerilatedVarNameMap::const_iterator m_it;
bool m_started;
public:
explicit VerilatedVpioVarIter(const VerilatedScope* scopep)
: m_scopep(scopep), m_started(false) { }
virtual ~VerilatedVpioVarIter() {}
static inline VerilatedVpioVarIter* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVarIter*>((VerilatedVpio*)h); }
virtual const vluint32_t type() { return vpiIterator; }
virtual vluint32_t type() const { return vpiIterator; }
virtual vpiHandle dovpi_scan() {
if (VL_LIKELY(m_scopep->varsp())) {
VerilatedVarNameMap* varsp = m_scopep->varsp();
@@ -286,8 +286,10 @@ public:
: m_handle(handle), m_varp(varp), m_iteration(varp->array().right()), m_direction(VL_LIKELY(varp->array().left()>varp->array().right())?1:-1), m_done(false) { }
virtual ~VerilatedVpioMemoryWordIter() {}
static inline VerilatedVpioMemoryWordIter* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioMemoryWordIter*>((VerilatedVpio*)h); }
virtual const vluint32_t type() { return vpiIterator; }
void iterationInc() { if (!(m_done = (m_iteration == m_varp->array().left()))) m_iteration+=m_direction; }
virtual vluint32_t type() const { return vpiIterator; }
void iterationInc() {
if (!(m_done = (m_iteration == m_varp->array().left()))) m_iteration+=m_direction;
}
virtual vpiHandle dovpi_scan() {
vpiHandle result;
if (m_done) return 0;
@@ -301,8 +303,8 @@ public:
struct VerilatedVpiTimedCbsCmp {
/// Ordering sets keyed by time, then callback descriptor
bool operator() (const pair<QData,VerilatedVpioCb*>& a,
const pair<QData,VerilatedVpioCb*>& b) const {
bool operator() (const std::pair<QData,VerilatedVpioCb*>& a,
const std::pair<QData,VerilatedVpioCb*>& b) const {
if (a.first < b.first) return 1;
if (a.first > b.first) return 0;
return a.second < b.second;
@@ -313,8 +315,8 @@ class VerilatedVpiError;
class VerilatedVpi {
enum { CB_ENUM_MAX_VALUE = cbAtEndOfSimTime+1 }; // Maxium callback reason
typedef list<VerilatedVpioCb*> VpioCbList;
typedef set<pair<QData,VerilatedVpioCb*>,VerilatedVpiTimedCbsCmp > VpioTimedCbs;
typedef std::list<VerilatedVpioCb*> VpioCbList;
typedef std::set<std::pair<QData,VerilatedVpioCb*>,VerilatedVpiTimedCbsCmp > VpioTimedCbs;
struct product_info {
PLI_BYTE8* product;
@@ -339,7 +341,7 @@ public:
s_s.m_cbObjLists[vop->reason()].push_back(vop);
}
static void cbTimedAdd(VerilatedVpioCb* vop) {
s_s.m_timedCbs.insert(make_pair(vop->time(), vop));
s_s.m_timedCbs.insert(std::make_pair(vop->time(), vop));
}
static void cbReasonRemove(VerilatedVpioCb* cbp) {
VpioCbList& cbObjList = s_s.m_cbObjLists[cbp->reason()];
@@ -350,7 +352,7 @@ public:
}
}
static void cbTimedRemove(VerilatedVpioCb* cbp) {
VpioTimedCbs::iterator it=s_s.m_timedCbs.find(make_pair(cbp->time(),cbp));
VpioTimedCbs::iterator it=s_s.m_timedCbs.find(std::make_pair(cbp->time(),cbp));
if (VL_LIKELY(it != s_s.m_timedCbs.end())) {
s_s.m_timedCbs.erase(it);
}
@@ -368,7 +370,7 @@ public:
}
}
static QData cbNextDeadline() {
VpioTimedCbs::iterator it=s_s.m_timedCbs.begin();
VpioTimedCbs::const_iterator it=s_s.m_timedCbs.begin();
if (VL_LIKELY(it!=s_s.m_timedCbs.end())) {
return it->first;
} else {
@@ -389,7 +391,8 @@ public:
}
static void callValueCbs() {
VpioCbList& cbObjList = s_s.m_cbObjLists[cbValueChange];
set<VerilatedVpioVar*> update; // set of objects to update after callbacks
typedef std::set<VerilatedVpioVar*> VpioVarSet;
VpioVarSet update; // set of objects to update after callbacks
for (VpioCbList::iterator it=cbObjList.begin(); it!=cbObjList.end();) {
if (VL_UNLIKELY(!*it)) { // Deleted earlier, cleanup
it = cbObjList.erase(it);
@@ -411,7 +414,7 @@ public:
}
}
}
for (set<VerilatedVpioVar*>::iterator it=update.begin(); it!=update.end(); ++it) {
for (VpioVarSet::const_iterator it=update.begin(); it!=update.end(); ++it) {
memcpy((*it)->prevDatap(), (*it)->varDatap(), (*it)->entSize());
}
}
@@ -462,8 +465,8 @@ public:
m_errorInfo.level = level;
return this;
}
void setMessage(string file, PLI_INT32 line, string message, ...) {
static VL_THREAD string filehold;
void setMessage(std::string file, PLI_INT32 line, std::string message, ...) {
static VL_THREAD_LOCAL std::string filehold;
_VL_VPI_ERROR_SET;
m_errorInfo.state = vpiPLI;
filehold = file;
+20 -11
View File
@@ -1,7 +1,7 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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,6 +46,7 @@
# define VL_FUNC __func__
# 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)
@@ -57,6 +58,7 @@
# define VL_FUNC __FUNCTION__
# define VL_LIKELY(x) (!!(x))
# define VL_UNLIKELY(x) (!!(x))
# define VL_UNREACHABLE
# define VL_PREFETCH_RD(p)
# define VL_PREFETCH_RW(p)
#else
@@ -68,23 +70,25 @@
# define VL_FUNC "__func__" ///< Name of current function for error macros
# define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true than false
# define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false than true
# define VL_UNREACHABLE ///< Point that may never be reached
# define VL_PREFETCH_RD(p) ///< Prefetch data with read intent
# 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 support plans to move to C++-11 and later only; use newer --std to be ready"
# 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
#ifdef _MSC_VER
# define VL_ULL(c) (c##ui64) ///< Add appropriate suffix to 64-bit constant
@@ -93,9 +97,9 @@
#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
#ifdef VL_CPPCHECK
#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
@@ -106,9 +110,14 @@
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define VL_HAS_UNIQUE_PTR
# define VL_UNIQUE_PTR unique_ptr
# define VL_HAS_UNORDERED_MAP
# define VL_UNIQUE_PTR std::unique_ptr
# define VL_UNORDERED_MAP std::unordered_map
# define VL_INCLUDE_UNORDERED_MAP <unordered_map>
#else
# define VL_UNIQUE_PTR auto_ptr
# define VL_UNIQUE_PTR std::auto_ptr
# define VL_UNORDERED_MAP std::map
# define VL_INCLUDE_UNORDERED_MAP <map>
#endif
//=========================================================================
+2
View File
@@ -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
+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 &&
+10 -10
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.
@@ -485,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
@@ -709,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.
@@ -785,7 +785,7 @@ in C<src/Makefile_obj.in> and reconfigure.
The latest version is available from L<http://www.veripool.org/>.
Copyright 2008-2016 by Wilson Snyder. Verilator is free software; you can
Copyright 2008-2017 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-2016 by Wilson Snyder. This package is free software; you
# Copyright 2007-2017 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-2016 by Wilson Snyder. This package is free software; you
# Copyright 2007-2017 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-2016 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2017 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-2016 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2017 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-2016 by Wilson Snyder. This package is free software; you
# Copyright 2007-2017 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
@@ -184,7 +184,7 @@ Runs a specific test stage (see the script).
=head1 DISTRIBUTION
Copyright 2009-2016 by Wilson Snyder. This package is free software; you
Copyright 2009-2017 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-2016 by Wilson Snyder. This package is free software; you
Copyright 2005-2017 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-2016 by Wilson Snyder. This package is free software; you
Copyright 2007-2017 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_ncverilog - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2005-2016 by Wilson Snyder. This package is free software; you
Copyright 2005-2017 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`;
exec('vcs',@ARGV);
#######################################################################
@@ -28,7 +28,7 @@ invoke_vcs - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2005-2016 by Wilson Snyder. This package is free software; you
Copyright 2005-2017 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-2016 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2017 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-2016 by Wilson Snyder. This program is free software; you can
# Copyright 2012-2017 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.
+8 -8
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@@ -48,25 +48,25 @@ obj_dbg:
.SUFFIXES:
.PHONY: ../verilator_bin ../verilator_bin_dbg ../verilator_coverage_bin_dbg
.PHONY: ../bin/verilator_bin ../bin/verilator_bin_dbg ../bin/verilator_coverage_bin_dbg
opt: ../verilator_bin
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
+5 -11
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@@ -64,6 +64,8 @@ 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. ####
@@ -73,7 +75,7 @@ TGT = ../../verilator_bin
#################
ifeq ($(VL_DEBUG),)
# Optimize
COPT = -O
COPT = -O2
else
# Debug
COPT = -ggdb -DVL_DEBUG
@@ -97,7 +99,7 @@ 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 $(CFG_CXXFLAGS_SRC) -Werror
CPPFLAGS += -W -Wall $(CFG_CXXFLAGS_WEXTRA) $(CFG_CXXFLAGS_SRC) -Werror
#CPPFLAGS += -pedantic-errors
else
CPPFLAGS += $(CFG_CXXFLAGS_SRC)
@@ -105,12 +107,6 @@ endif
CPPFLAGSWALL = $(CPPFLAGS)
CPPFLAGSPARSER = $(CPPFLAGS) $(CFG_CXXFLAGS_PARSER)
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
# Allow RPM builds to specify hardcoded data directories
# To do this:
ifeq ($(CFG_WITH_DEFENV),yes)
@@ -118,8 +114,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
+29 -27
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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); 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);
}
@@ -169,14 +169,14 @@ private:
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 (=).");
} else if (m_check == CT_LATCH) {
// Suppress. Shouldn't matter that the interior of the latch races
// 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 (=).");
}
@@ -187,7 +187,7 @@ private:
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;
@@ -195,7 +195,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
@@ -214,7 +214,7 @@ private:
}
}
//--------------------
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
@@ -244,7 +244,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
@@ -252,10 +252,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);
@@ -263,28 +263,28 @@ 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.
@@ -323,13 +323,15 @@ private:
// 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;
}
@@ -370,7 +372,7 @@ private:
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: ");
@@ -382,13 +384,13 @@ private:
}
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(), 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
@@ -397,7 +399,7 @@ 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
@@ -413,10 +415,10 @@ 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:
@@ -436,5 +438,5 @@ public:
void V3Active::activeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ActiveVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("active.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("active", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+15 -15
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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();
@@ -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,29 +120,29 @@ 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:
@@ -160,5 +160,5 @@ public:
void V3ActiveTop::activeTopAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ActiveTopVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("activetop.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("activetop", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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 -19
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2005-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2017 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.
@@ -119,7 +119,7 @@ private:
} else {
nodep->v3fatalSrc("Unknown node type");
}
if (stmtsp) bodysp = bodysp->addNext(stmtsp);
if (bodysp && stmtsp) bodysp = bodysp->addNext(stmtsp);
AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL);
bodysp = ifp;
if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
@@ -162,8 +162,8 @@ private:
// Bye
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;
@@ -177,12 +177,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) {
@@ -195,13 +195,13 @@ private:
if (ifp->elsesp() && !nextifp) {
hasDefaultElse = true;
}
ifp = nextifp;
} while (ifp);
AstNode *newifp = nodep->cloneTree(false);
bool allow_none = nodep->unique0Pragma();
// 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)
@@ -220,7 +220,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;
@@ -245,9 +245,16 @@ 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;
}
@@ -268,7 +275,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) {
@@ -281,27 +288,27 @@ private:
}
}
virtual void visit(AstPslCover* nodep, AstNUser*) {
virtual void visit(AstPslCover* nodep) {
nodep->iterateChildren(*this);
if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name());
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
nodep->stmtsp(), nodep->name()); VL_DANGLING(nodep);
++m_statAsCover;
}
virtual void visit(AstVAssert* nodep, AstNUser*) {
virtual void visit(AstVAssert* nodep) {
nodep->iterateChildren(*this);
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;
@@ -312,7 +319,7 @@ private:
m_beginp = lastp;
}
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
@@ -337,5 +344,5 @@ public:
void V3Assert::assertAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
AssertVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("assert.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("assert", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2005-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+7 -7
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2005-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2017 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();
@@ -86,14 +86,14 @@ private:
pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstPslCover* nodep, AstNUser*) {
virtual void visit(AstPslCover* 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");
@@ -111,12 +111,12 @@ private:
nodep->replaceWith(blockp);
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);
}
@@ -137,5 +137,5 @@ public:
void V3AssertPre::assertPreAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
AssertPreVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("assertpre.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("assertpre", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2005-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2017 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 -40
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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.
@@ -80,15 +80,15 @@ 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;
}
@@ -716,6 +716,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;
@@ -732,31 +733,32 @@ 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
// 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 (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) {
// This is a very hot function
ASTNODE_PREFETCH(m_op1p);
ASTNODE_PREFETCH(m_op2p);
ASTNODE_PREFETCH(m_op3p);
ASTNODE_PREFETCH(m_op4p);
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->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::iterateChildrenConst(AstNVisitor& v, AstNUser* vup) {
// This is a very hot function
ASTNODE_PREFETCH(m_op1p);
ASTNODE_PREFETCH(m_op2p);
ASTNODE_PREFETCH(m_op3p);
ASTNODE_PREFETCH(m_op4p);
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);
}
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!
@@ -766,14 +768,16 @@ void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
#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
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
if (!niterp) return; // Perhaps node deleted inside accept
@@ -786,37 +790,37 @@ void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
}
}
void AstNode::iterateListBackwards(AstNVisitor& v, AstNUser* vup) {
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 (m_op1p) m_op1p->iterateListBackwards(v,vup);
if (m_op2p) m_op2p->iterateListBackwards(v,vup);
if (m_op3p) m_op3p->iterateListBackwards(v,vup);
if (m_op4p) m_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; // 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::iterateSubtreeReturnEdits(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
@@ -826,12 +830,12 @@ AstNode* AstNode::iterateSubtreeReturnEdits(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); VL_DANGLING(nodep); // 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(); VL_DANGLING(tempp);
@@ -845,7 +849,7 @@ AstNode* AstNode::iterateSubtreeReturnEdits(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); VL_DANGLING(nodep); // 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
}
@@ -902,7 +906,7 @@ bool AstNode::sameTreeIter(AstNode* node1p, AstNode* node2p, bool ignNext, bool
//======================================================================
// 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();
}
@@ -1057,6 +1061,8 @@ 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 (!dynamic_cast<const AstNode*>(this)) {
// No known cases cause this, but better than a core dump
+147 -104
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -61,7 +61,7 @@ public:
inline bool operator== (AstType lhs, AstType rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstType lhs, AstType::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstType::en lhs, AstType rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstType rhs) { return os<<rhs.ascii(); }
inline ostream& operator<<(ostream& os, const AstType& rhs) { return os<<rhs.ascii(); }
//######################################################################
@@ -82,7 +82,7 @@ public:
};
enum en m_e;
const char* ascii() const {
static const char* names[] = {
static const char* const names[] = {
"UNSIGNED","SIGNED","NOSIGN"
};
return names[m_e];
@@ -107,7 +107,7 @@ public:
inline bool operator== (AstNumeric lhs, AstNumeric rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstNumeric lhs, AstNumeric::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstNumeric::en lhs, AstNumeric rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstNumeric rhs) { return os<<rhs.ascii(); }
inline ostream& operator<<(ostream& os, const AstNumeric& rhs) { return os<<rhs.ascii(); }
//######################################################################
@@ -203,14 +203,14 @@ public:
return AstEdgeType::ET_ILLEGAL;
}
const char* ascii() const {
static const char* names[] = {
static const char* const names[] = {
"%E-edge", "ANY", "BOTH", "POS", "NEG", "HIGH", "LOW",
"COMBO","INITIAL","SETTLE","NEVER"
};
return names[m_e];
};
const char* verilogKwd() const {
static const char* names[] = {
static const char* const names[] = {
"%E-edge", "[any]", "edge", "posedge", "negedge", "[high]","[low]",
"*","[initial]","[settle]","[never]"
};
@@ -270,7 +270,7 @@ public:
};
enum en m_e;
const char* ascii() const {
static const char* names[] = {
static const char* const names[] = {
"%E-AT",
"DIM_BITS", "DIM_DIMENSIONS", "DIM_HIGH", "DIM_INCREMENT", "DIM_LEFT",
"DIM_LOW", "DIM_RIGHT", "DIM_SIZE", "DIM_UNPK_DIMENSIONS",
@@ -315,7 +315,7 @@ public:
};
enum en m_e;
const char* ascii() const {
static const char* names[] = {
static const char* const names[] = {
"%E-unk",
"bit", "byte", "chandle", "int", "integer", "logic", "longint",
"real", "shortint", "shortreal", "time",
@@ -328,7 +328,7 @@ public:
return names[m_e];
};
const char* dpiType() const {
static const char* names[] = {
static const char* const names[] = {
"%E-unk",
"unsigned char", "char", "void*", "int", "int", "svLogic", "long long",
"double", "short int", "float", "long long",
@@ -396,7 +396,7 @@ public:
return (m_e==LOGIC || m_e==BIT);
}
bool isDpiUnsupported() const {
return (m_e==LOGIC || m_e==TIME);
return (m_e==TIME);
}
bool isDpiUnsignable() const { // Can add "unsigned" to DPI
return (m_e==BYTE || m_e==SHORTINT || m_e==INT || m_e==LONGINT || m_e==INTEGER);
@@ -427,6 +427,7 @@ public:
SUPPLY0,
SUPPLY1,
WIRE,
WREAL,
IMPLICITWIRE,
TRIWIRE,
TRI0,
@@ -445,16 +446,16 @@ public:
explicit inline AstVarType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
const char* ascii() const {
static const char* names[] = {
static const char* const names[] = {
"?","GPARAM","LPARAM","GENVAR",
"VAR","INPUT","OUTPUT","INOUT",
"SUPPLY0","SUPPLY1","WIRE","IMPLICITWIRE",
"SUPPLY0","SUPPLY1","WIRE","WREAL","IMPLICITWIRE",
"TRIWIRE","TRI0","TRI1",
"PORT",
"BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP",
"IFACEREF"};
return names[m_e]; }
bool isSignal() const { return (m_e==WIRE || m_e==IMPLICITWIRE
bool isSignal() const { return (m_e==WIRE || m_e==WREAL || m_e==IMPLICITWIRE
|| m_e==TRIWIRE
|| m_e==TRI0 || m_e==TRI1
|| m_e==SUPPLY0 || m_e==SUPPLY1
@@ -463,7 +464,7 @@ public:
inline bool operator== (AstVarType lhs, AstVarType rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstVarType lhs, AstVarType::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstVarType::en lhs, AstVarType rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstVarType rhs) { return os<<rhs.ascii(); }
inline ostream& operator<<(ostream& os, const AstVarType& rhs) { return os<<rhs.ascii(); }
//######################################################################
@@ -488,14 +489,14 @@ public:
else return m_e;
}
const char* ascii() const {
static const char* names[] = {
static const char* const names[] = {
"","VL_LIKELY","VL_UNLIKELY"};
return names[m_e]; }
};
inline bool operator== (AstBranchPred lhs, AstBranchPred rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstBranchPred lhs, AstBranchPred::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstBranchPred::en lhs, AstBranchPred rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstBranchPred rhs) { return os<<rhs.ascii(); }
inline ostream& operator<<(ostream& os, const AstBranchPred& rhs) { return os<<rhs.ascii(); }
//######################################################################
@@ -521,14 +522,14 @@ public:
else return m_e;
}
const char* ascii() const {
static const char* names[] = {
static const char* const names[] = {
"","clker","non_clker"};
return names[m_e]; }
};
inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstVarAttrClocker::en lhs, AstVarAttrClocker rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstVarAttrClocker rhs) { return os<<rhs.ascii(); }
inline ostream& operator<<(ostream& os, const AstVarAttrClocker& rhs) { return os<<rhs.ascii(); }
//######################################################################
@@ -547,7 +548,7 @@ public:
explicit inline VAlwaysKwd (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
const char* ascii() const {
static const char* names[] = {
static const char* const names[] = {
"always","always_ff","always_latch","always_comb"};
return names[m_e]; }
};
@@ -597,7 +598,7 @@ public:
bool addNewline() const { return m_e!=DT_WRITE; }
bool needScopeTracking() const { return m_e!=DT_DISPLAY && m_e!=DT_WRITE; }
const char* ascii() const {
static const char* names[] = {
static const char* const names[] = {
"display","write","info","error","warning","fatal"};
return names[m_e]; }
};
@@ -620,14 +621,14 @@ public:
explicit inline AstParseRefExp (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
const char* ascii() const {
static const char* names[] = {
static const char* const names[] = {
"","TEXT","PREDOT"};
return names[m_e]; }
};
inline bool operator== (AstParseRefExp lhs, AstParseRefExp rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstParseRefExp lhs, AstParseRefExp::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstParseRefExp::en lhs, AstParseRefExp rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstParseRefExp rhs) { return os<<rhs.ascii(); }
inline ostream& operator<<(ostream& os, const AstParseRefExp& rhs) { return os<<rhs.ascii(); }
//######################################################################
// VNumRange - Structure containing numberic range information
@@ -679,7 +680,7 @@ struct VNumRange {
{ return (!m_ranged || (m_lo==0 && m_hi>=1 && !m_littleEndian)); }
void dump(ostream& str) const { if (ranged()) str<<"["<<left()<<":"<<right()<<"]"; else str<<"[norg]"; }
};
inline ostream& operator<<(ostream& os, VNumRange rhs) { rhs.dump(os); return os; }
inline ostream& operator<<(ostream& os, const VNumRange& rhs) { rhs.dump(os); return os; }
//######################################################################
@@ -708,14 +709,14 @@ struct VBasicTypeKey {
if (!(m_nrange == rhs.m_nrange)) return false; // lhs > rhs
return false; }
VBasicTypeKey(int width, int widthMin, AstNumeric numeric, AstBasicDTypeKwd kwd,
VNumRange nrange)
const VNumRange& nrange)
: m_width(width), m_widthMin(widthMin), m_numeric(numeric),
m_keyword(kwd), m_nrange(nrange) {}
~VBasicTypeKey() {}
};
//######################################################################
// AstNUser - Generic pointer base class for AST User nodes.
// AstNUser - Generic base class for AST User nodes.
// - Also used to allow parameter passing up/down iterate calls
class WidthVP;
@@ -724,26 +725,32 @@ class OrderBlockNU;
class OrderVarNU;
class V3GraphVertex;
class VSymEnt;
struct AstNUser {
AstNUser* p() { return this; } // So can take address of temporary: iterate(...,AstNUser(args).p())
class VNUser {
union {
void* up;
int ui;
} m_u;
public:
VNUser() {}
// non-explicit:
// cppcheck-suppress noExplicitConstructor
VNUser(int i) { m_u.up = 0; m_u.ui = i; }
explicit VNUser(void* p) { m_u.up = p; }
~VNUser() {}
// Casters
WidthVP* c() { return ((WidthVP*)this); }
LinkVP* castLinkVP() { return ((LinkVP*)this); }
VSymEnt* castSymEnt() { return ((VSymEnt*)this); }
AstNode* castNode() { return ((AstNode*)this); }
OrderBlockNU* castOrderBlock() { return ((OrderBlockNU*)this); }
OrderVarNU* castOrderVar() { return ((OrderVarNU*)this); }
V3GraphVertex* castGraphVertex() { return ((V3GraphVertex*)this); }
inline int castInt() {
union { AstNUser* up; int ui; } u;
u.up = this;
return u.ui;
}
static inline AstNUser* fromInt (int i) {
union { AstNUser* up; int ui; } u;
u.up=0; u.ui=i;
return u.up;
WidthVP* c() { return ((WidthVP*)m_u.up); }
LinkVP* toLinkVP() { return ((LinkVP*)m_u.up); }
VSymEnt* toSymEnt() { return ((VSymEnt*)m_u.up); }
AstNode* toNodep() { return ((AstNode*)m_u.up); }
OrderBlockNU* toOrderBlock() { return ((OrderBlockNU*)m_u.up); }
OrderVarNU* toOrderVar() { return ((OrderVarNU*)m_u.up); }
V3GraphVertex* toGraphVertex() { return ((V3GraphVertex*)m_u.up); }
inline int toInt() {
return m_u.ui;
}
static inline VNUser fromZero () { return VNUser(0); }
static inline VNUser fromInt (int i) { return VNUser(i); }
};
//######################################################################
@@ -862,8 +869,8 @@ public:
}
#include "V3Ast__gen_visitor.h" // From ./astgen
// Things like:
// virtual void visit(AstBreak* nodep, AstNUser* vup) { visit((AstNodeStmt*)(nodep),vup); }
// virtual void visit(AstNodeStmt* nodep, AstNUser* vup) { visit((AstNode*)(nodep),vup); }
// virtual void visit(AstBreak* nodep) { visit((AstNodeStmt*)(nodep)); }
// virtual void visit(AstNodeStmt* nodep) { visit((AstNode*)(nodep)); }
};
//######################################################################
@@ -886,7 +893,7 @@ public:
AstNode* oldp() const { return m_oldp; }
void dump(ostream& str=cout) const;
};
inline ostream& operator<<(ostream& os, AstNRelinker& rhs) { rhs.dump(os); return os;}
inline ostream& operator<<(ostream& os, const AstNRelinker& rhs) { rhs.dump(os); return os;}
//######################################################################
// V3Hash -- Node hashing for V3Combine
@@ -898,7 +905,8 @@ class V3Hash {
uint32_t m_both;
static const uint32_t M24 = ((1<<24)-1);
void setBoth(uint32_t depth, uint32_t hshval) {
if (depth==0) depth=1; if (depth>255) depth=255;
if (depth==0) depth=1;
if (depth>255) depth=255;
m_both = (depth<<24) | (hshval & M24);
}
public:
@@ -916,7 +924,7 @@ public:
class FullValue {}; // for creator type-overload selection
explicit V3Hash(Illegal) { m_both=0; }
// Saving and restoring inside a userp
explicit V3Hash(AstNUser* up) { m_both=up->castInt(); }
explicit V3Hash(VNUser u) { m_both=u.toInt(); }
V3Hash operator+= (const V3Hash& rh) {
setBoth(depth()+rh.depth(), (hshval()*31+rh.hshval()));
return *this; };
@@ -935,7 +943,7 @@ public:
V3Hash(V3Hash h1, V3Hash h2, V3Hash h3, V3Hash h4) {
setBoth(1,((h1.hshval()*31+h2.hshval())*31+h3.hshval())*31+h4.hshval()); }
};
ostream& operator<<(ostream& os, V3Hash rhs);
ostream& operator<<(ostream& os, const V3Hash& rhs);
//######################################################################
// AstNode -- Base type of all Ast types
@@ -975,15 +983,15 @@ class AstNode {
// // Space for more bools here
// This member ordering both allows 64 bit alignment and puts associated data together
AstNUser* m_user1p; // Pointer to any information the user iteration routine wants
VNUser m_user1u; // Contains any information the user iteration routine wants
uint32_t m_user1Cnt; // Mark of when userp was set
uint32_t m_user2Cnt; // Mark of when userp was set
AstNUser* m_user2p; // Pointer to any information the user iteration routine wants
AstNUser* m_user3p; // Pointer to any information the user iteration routine wants
VNUser m_user2u; // Contains any information the user iteration routine wants
VNUser m_user3u; // Contains any information the user iteration routine wants
uint32_t m_user3Cnt; // Mark of when userp was set
uint32_t m_user4Cnt; // Mark of when userp was set
AstNUser* m_user4p; // Pointer to any information the user iteration routine wants
AstNUser* m_user5p; // Pointer to any information the user iteration routine wants
VNUser m_user4u; // Contains any information the user iteration routine wants
VNUser m_user5u; // Contains any information the user iteration routine wants
uint32_t m_user5Cnt; // Mark of when userp was set
// METHODS
@@ -993,7 +1001,7 @@ class AstNode {
void op4p(AstNode* nodep) { m_op4p = nodep; if (nodep) nodep->m_backp = this; }
void init(); // initialize value of AstNode
void iterateListBackwards(AstNVisitor& v, AstNUser* vup=NULL);
void iterateListBackwards(AstNVisitor& v);
private:
AstNode* cloneTreeIter();
AstNode* cloneTreeIterList();
@@ -1080,6 +1088,8 @@ public:
// ACCESSORS
virtual string name() const { return ""; }
virtual void name(const string& name) { this->v3fatalSrc("name() called on object without name() method"); }
virtual void tag(const string& text) {}
virtual string tag() const { return ""; }
virtual string verilogKwd() const { return ""; }
string shortName() const; // Name with __PVT__ removed for concatenating scopes
static string dedotName(const string& namein); // Name with dots removed
@@ -1111,57 +1121,75 @@ public:
bool isSigned() const;
bool isString() const;
AstNUser* user1p() const {
VNUser user1u() const {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(AstUser1InUse::s_userBusy, "userp set w/o busy");
return ((m_user1Cnt==AstUser1InUse::s_userCntGbl)?m_user1p:NULL);
return ((m_user1Cnt==AstUser1InUse::s_userCntGbl) ? m_user1u : VNUser(0));
}
void user1p(void* userp) { m_user1p=(AstNUser*)(userp); m_user1Cnt=AstUser1InUse::s_userCntGbl; }
int user1() const { return user1p()->castInt(); }
void user1(int val) { user1p(AstNUser::fromInt(val)); }
AstNode* user1p() const { return user1u().toNodep(); }
void user1u(const VNUser& user) { m_user1u=user; m_user1Cnt=AstUser1InUse::s_userCntGbl; }
void user1p(void* userp) { user1u(VNUser(userp)); }
int user1() const { return user1u().toInt(); }
void user1(int val) { user1u(VNUser(val)); }
int user1Inc(int val=1) { int v=user1(); user1(v+val); return v; }
int user1SetOnce() { int v=user1(); if (!v) user1(1); return v; } // Better for cache than user1Inc()
static void user1ClearTree() { AstUser1InUse::clear(); } // Clear userp()'s across the entire tree
AstNUser* user2p() const {
//UASSERT_STATIC(AstUser2InUse::s_userBusy, "user2p set w/o busy");
return ((m_user2Cnt==AstUser2InUse::s_userCntGbl)?m_user2p:NULL); }
void user2p(void* userp) { m_user2p=(AstNUser*)(userp); m_user2Cnt=AstUser2InUse::s_userCntGbl; }
int user2() const { return user2p()->castInt(); }
void user2(int val) { user2p(AstNUser::fromInt(val)); }
VNUser user2u() const {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(AstUser2InUse::s_userBusy, "userp set w/o busy");
return ((m_user2Cnt==AstUser2InUse::s_userCntGbl) ? m_user2u : VNUser(0));
}
AstNode* user2p() const { return user2u().toNodep(); }
void user2u(const VNUser& user) { m_user2u=user; m_user2Cnt=AstUser2InUse::s_userCntGbl; }
void user2p(void* userp) { user2u(VNUser(userp)); }
int user2() const { return user2u().toInt(); }
void user2(int val) { user2u(VNUser(val)); }
int user2Inc(int val=1) { int v=user2(); user2(v+val); return v; }
int user2SetOnce() { int v=user2(); if (!v) user2(1); return v; }
static void user2ClearTree() { AstUser2InUse::clear(); }
int user2SetOnce() { int v=user2(); if (!v) user2(1); return v; } // Better for cache than user2Inc()
static void user2ClearTree() { AstUser2InUse::clear(); } // Clear userp()'s across the entire tree
AstNUser* user3p() const {
//UASSERT_STATIC(AstUser3InUse::s_userBusy, "user3p set w/o busy");
return ((m_user3Cnt==AstUser3InUse::s_userCntGbl)?m_user3p:NULL); }
void user3p(void* userp) { m_user3p=(AstNUser*)(userp); m_user3Cnt=AstUser3InUse::s_userCntGbl; }
int user3() const { return user3p()->castInt(); }
void user3(int val) { user3p(AstNUser::fromInt(val)); }
VNUser user3u() const {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(AstUser3InUse::s_userBusy, "userp set w/o busy");
return ((m_user3Cnt==AstUser3InUse::s_userCntGbl) ? m_user3u : VNUser(0));
}
AstNode* user3p() const { return user3u().toNodep(); }
void user3u(const VNUser& user) { m_user3u=user; m_user3Cnt=AstUser3InUse::s_userCntGbl; }
void user3p(void* userp) { user3u(VNUser(userp)); }
int user3() const { return user3u().toInt(); }
void user3(int val) { user3u(VNUser(val)); }
int user3Inc(int val=1) { int v=user3(); user3(v+val); return v; }
int user3SetOnce() { int v=user3(); if (!v) user3(1); return v; }
static void user3ClearTree() { AstUser3InUse::clear(); }
int user3SetOnce() { int v=user3(); if (!v) user3(1); return v; } // Better for cache than user3Inc()
static void user3ClearTree() { AstUser3InUse::clear(); } // Clear userp()'s across the entire tree
AstNUser* user4p() const {
//UASSERT_STATIC(AstUser4InUse::s_userBusy, "user4p set w/o busy");
return ((m_user4Cnt==AstUser4InUse::s_userCntGbl)?m_user4p:NULL); }
void user4p(void* userp) { m_user4p=(AstNUser*)(userp); m_user4Cnt=AstUser4InUse::s_userCntGbl; }
int user4() const { return user4p()->castInt(); }
void user4(int val) { user4p(AstNUser::fromInt(val)); }
VNUser user4u() const {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(AstUser4InUse::s_userBusy, "userp set w/o busy");
return ((m_user4Cnt==AstUser4InUse::s_userCntGbl) ? m_user4u : VNUser(0));
}
AstNode* user4p() const { return user4u().toNodep(); }
void user4u(const VNUser& user) { m_user4u=user; m_user4Cnt=AstUser4InUse::s_userCntGbl; }
void user4p(void* userp) { user4u(VNUser(userp)); }
int user4() const { return user4u().toInt(); }
void user4(int val) { user4u(VNUser(val)); }
int user4Inc(int val=1) { int v=user4(); user4(v+val); return v; }
int user4SetOnce() { int v=user4(); if (!v) user4(1); return v; }
static void user4ClearTree() { AstUser4InUse::clear(); }
int user4SetOnce() { int v=user4(); if (!v) user4(1); return v; } // Better for cache than user4Inc()
static void user4ClearTree() { AstUser4InUse::clear(); } // Clear userp()'s across the entire tree
AstNUser* user5p() const {
//UASSERT_STATIC(AstUser5InUse::s_userBusy, "user5p set w/o busy");
return ((m_user5Cnt==AstUser5InUse::s_userCntGbl)?m_user5p:NULL); }
void user5p(void* userp) { m_user5p=(AstNUser*)(userp); m_user5Cnt=AstUser5InUse::s_userCntGbl; }
int user5() const { return user5p()->castInt(); }
void user5(int val) { user5p(AstNUser::fromInt(val)); }
VNUser user5u() const {
// Slows things down measurably, so disabled by default
//UASSERT_STATIC(AstUser5InUse::s_userBusy, "userp set w/o busy");
return ((m_user5Cnt==AstUser5InUse::s_userCntGbl) ? m_user5u : VNUser(0));
}
AstNode* user5p() const { return user5u().toNodep(); }
void user5u(const VNUser& user) { m_user5u=user; m_user5Cnt=AstUser5InUse::s_userCntGbl; }
void user5p(void* userp) { user5u(VNUser(userp)); }
int user5() const { return user5u().toInt(); }
void user5(int val) { user5u(VNUser(val)); }
int user5Inc(int val=1) { int v=user5(); user5(v+val); return v; }
int user5SetOnce() { int v=user5(); if (!v) user5(1); return v; }
static void user5ClearTree() { AstUser5InUse::clear(); }
int user5SetOnce() { int v=user5(); if (!v) user5(1); return v; } // Better for cache than user5Inc()
static void user5ClearTree() { AstUser5InUse::clear(); } // Clear userp()'s across the entire tree
vluint64_t editCount() const { return m_editCount; }
void editCountInc() { m_editCount = ++s_editCntGbl; } // Preincrement, so can "watch AstNode::s_editCntGbl=##"
@@ -1207,6 +1235,7 @@ public:
// METHODS - dump and error
void v3errorEnd(ostringstream& str) const;
void v3errorEndFatal(ostringstream& str) const VL_ATTR_NORETURN;
string warnMore() const;
virtual void dump(ostream& str=cout);
void dumpGdb(); // For GDB only
@@ -1232,7 +1261,7 @@ public:
// METHODS - Iterate on a tree
AstNode* cloneTree(bool cloneNextLink);
bool gateTree() { return gateTreeIter(); } // Is tree gateOptimizable?
bool gateTree() { return gateTreeIter(); } // Is tree isGateOptimizable?
bool sameTree(AstNode* node2p); // Does tree of this == node2p?
bool sameGateTree(AstNode* node2p); // Does tree of this == node2p?, not allowing non-isGateOptimizable
void deleteTree(); // Always deletes the next link
@@ -1265,14 +1294,14 @@ public:
virtual const char* broken() const { return NULL; }
// INVOKERS
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) = 0;
void iterate(AstNVisitor& v, AstNUser* vup=NULL) { this->accept(v,vup); } // Does this; excludes following this->next
void iterateAndNext(AstNVisitor& v, AstNUser* vup=NULL);
void iterateAndNextConst(AstNVisitor& v, AstNUser* vup=NULL);
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next
void iterateChildrenBackwards(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next
void iterateChildrenConst(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next
AstNode* iterateSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup=NULL); // Return edited nodep; see comments in V3Ast.cpp
virtual void accept(AstNVisitor& v) = 0;
void iterate(AstNVisitor& v) { this->accept(v); } // Does this; excludes following this->next
void iterateAndNext(AstNVisitor& v);
void iterateAndNextConst(AstNVisitor& v);
void iterateChildren(AstNVisitor& v); // Excludes following this->next
void iterateChildrenBackwards(AstNVisitor& v); // Excludes following this->next
void iterateChildrenConst(AstNVisitor& v); // Excludes following this->next
AstNode* iterateSubtreeReturnEdits(AstNVisitor& v); // Return edited nodep; see comments in V3Ast.cpp
// CONVERSION
#include "V3Ast__gen_interface.h" // From ./astgen
@@ -1318,7 +1347,7 @@ public:
// Know no children, and hot function, so skip iterator for speed
// See checkTreeIter also that asserts no children
// cppcheck-suppress functionConst
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
void iterateChildren(AstNVisitor& v) { }
};
class AstNodeUniop : public AstNodeMath {
@@ -1432,6 +1461,7 @@ public:
virtual bool sizeMattersLhs() { return false; } virtual bool sizeMattersRhs() { return false; }
virtual bool sizeMattersThs() { return false; }
virtual int instrCount() const { return instrCountBranch(); }
virtual AstNode* cloneType(AstNode* condp, AstNode* expr1p, AstNode* expr2p) = 0;
};
class AstNodePreSel : public AstNode {
@@ -1486,6 +1516,7 @@ public:
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode*) const { return true; }
virtual string verilogKwd() const { return "="; }
virtual bool brokeLhsMustBeLvalue() const = 0;
};
class AstNodeFor : public AstNodeStmt {
@@ -1602,7 +1633,7 @@ public:
// Know no children, and hot function, so skip iterator for speed
// See checkTreeIter also that asserts no children
// cppcheck-suppress functionConst
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
void iterateChildren(AstNVisitor& v) { }
};
class AstNodeText : public AstNode {
@@ -1652,6 +1683,7 @@ public:
virtual bool maybePointedTo() const { return true; }
virtual AstNodeDType* virtRefDTypep() const { return NULL; } // Iff has a non-null refDTypep(), as generic node function
virtual void virtRefDTypep(AstNodeDType* nodep) { } // Iff has refDTypep(), set as generic node function
virtual bool similarDType(AstNodeDType* samep) const = 0; // Assignable equivalence. Call skipRefp() on this and samep before calling
//
// Changing the width may confuse the data type resolution, so must clear TypeTable cache after use.
void widthForce(int width, int sized) { m_width=width; m_widthMin=sized; }
@@ -1701,6 +1733,9 @@ public:
virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
// op1 = members
virtual bool similarDType(AstNodeDType* samep) const {
return this==samep; // We don't compare members, require exact equivalence
}
AstMemberDType* membersp() const { return op1p()->castMemberDType(); } // op1 = AstMember list
void addMembersp(AstNode* nodep) { addNOp1p(nodep); }
bool packed() const { return m_packed; }
@@ -1731,7 +1766,7 @@ public:
virtual void dump(ostream& str);
virtual void dumpSmall(ostream& str);
virtual const char* broken() const { BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|| (!m_refDTypep && childDTypep()))); return NULL; }
|| (!m_refDTypep && childDTypep()))); return NULL; }
virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) {
m_refDTypep = m_refDTypep->clonep();
}}
@@ -1740,6 +1775,14 @@ public:
return (msb()==sp->msb()
&& subDTypep()==sp->subDTypep()
&& rangenp()->sameTree(sp->rangenp())); } // HashedDT doesn't recurse, so need to check children
virtual bool similarDType(AstNodeDType* samep) const {
AstNodeArrayDType* sp = samep->castNodeArrayDType();
return (sp
&& type() == samep->type()
&& msb() == sp->msb()
&& rangenp()->sameTree(sp->rangenp())
&& subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp()));
}
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(msb()),V3Hash(lsb())); }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+15 -6
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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.
@@ -140,6 +140,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 +202,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 +226,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) {
@@ -754,10 +763,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()<<"]";
@@ -882,6 +887,10 @@ void AstNodeModule::dump(ostream& str) {
if (inLibrary()) str<<" [LIB]";
if (dead()) str<<" [DEAD]";
}
void AstPackageExport::dump(ostream& str) {
this->AstNode::dump(str);
str<<" -> "<<packagep();
}
void AstPackageImport::dump(ostream& str) {
this->AstNode::dump(str);
str<<" -> "<<packagep();
+116 -44
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -32,7 +32,7 @@
virtual ~Ast ##name() {} \
virtual AstType type() const { return AstType::at ## name; } \
virtual AstNode* clone() { return new Ast ##name (*this); } \
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); } \
virtual void accept(AstNVisitor& v) { v.visit(this); } \
Ast ##name * cloneTree(bool cloneNext) { return static_cast<Ast ##name *>(AstNode::cloneTree(cloneNext)); } \
Ast ##name * clonep() const { return static_cast<Ast ##name *>(AstNode::clonep()); }
@@ -121,21 +121,24 @@ public:
m_littleEndian = false;
setOp2p(new AstConst(fl,msb)); setOp3p(new AstConst(fl,lsb));
}
AstRange(FileLine* fl, VNumRange range)
AstRange(FileLine* fl, const VNumRange& range)
:AstNode(fl) {
m_littleEndian = range.littleEndian();
setOp2p(new AstConst(fl,range.hi())); setOp3p(new AstConst(fl,range.lo()));
}
ASTNODE_NODE_FUNCS(Range)
AstNode* msbp() const { return op2p(); } // op2 = Msb expression
AstNode* lsbp() const { return op3p(); } // op3 = Lsb expression
AstNode* msbp() const { return op2p(); } // op2 = Msb expression
AstNode* lsbp() const { return op3p(); } // op3 = Lsb expression
AstNode* leftp() const { return littleEndian()?lsbp():msbp(); } // How to show a declaration
AstNode* rightp() const { return littleEndian()?msbp():lsbp(); }
int msbConst() const { AstConst* constp=msbp()->castConst(); return (constp?constp->toSInt():0); }
int lsbConst() const { AstConst* constp=lsbp()->castConst(); return (constp?constp->toSInt():0); }
int elementsConst() const { return (msbConst()>lsbConst()) ? msbConst()-lsbConst()+1 : lsbConst()-msbConst()+1; }
bool littleEndian() const { return m_littleEndian; }
void littleEndian(bool flag) { m_littleEndian=flag; }
int msbConst() const { AstConst* constp=msbp()->castConst(); return (constp?constp->toSInt():0); }
int lsbConst() const { AstConst* constp=lsbp()->castConst(); return (constp?constp->toSInt():0); }
int elementsConst() const { return (msbConst()>lsbConst()) ? msbConst()-lsbConst()+1 : lsbConst()-msbConst()+1; }
int leftConst() const { AstConst* constp=leftp()->castConst(); return (constp?constp->toSInt():0); }
int rightConst() const { AstConst* constp=rightp()->castConst(); return (constp?constp->toSInt():0); }
int leftToRightInc() const { return littleEndian()?1:-1; }
bool littleEndian() const { return m_littleEndian; }
void littleEndian(bool flag) { m_littleEndian=flag; }
virtual void dump(ostream& str);
virtual string emitC() { V3ERROR_NA; return ""; }
virtual V3Hash sameHash() const { return V3Hash(); }
@@ -180,6 +183,10 @@ public:
virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); }
virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); }
virtual AstNodeDType* skipRefToEnump() const { return subDTypep()->skipRefToEnump(); }
virtual bool similarDType(AstNodeDType* samep) const {
AstParamTypeDType* sp = samep->castParamTypeDType();
return (sp && this->subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp()));
}
virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); }
virtual int widthTotalBytes() const { return dtypep()->widthTotalBytes(); }
// METHODS
@@ -251,6 +258,8 @@ public:
}
ASTNODE_NODE_FUNCS(DefImplicitDType)
virtual bool same(AstNode* samep) const { return m_uniqueNum==samep->castDefImplicitDType()->m_uniqueNum; }
virtual bool similarDType(AstNodeDType* samep) const {
return type()==samep->type() && same(samep); }
virtual V3Hash sameHash() const { return V3Hash(m_uniqueNum); }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
@@ -392,14 +401,16 @@ public:
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m.m_keyword), V3Hash(m.m_nrange.hi())); }
virtual bool same(AstNode* samep) const { // width/widthMin/numeric compared elsewhere
return samep->castBasicDType()->m == m; }
virtual bool similarDType(AstNodeDType* samep) const {
return type()==samep->type() && same(samep); }
virtual string name() const { return m.m_keyword.ascii(); }
virtual const char* broken() const { BROKEN_RTN(dtypep()!=this); return NULL; }
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable
void rangep(AstRange* nodep) { setNOp1p(nodep); }
void setSignedState(VSignedState signst) {
// Note NOSIGN does NOT change the state; this is required by the parser
if (signst==signedst_UNSIGNED) numeric(VSignedState(signst));
else if (signst==signedst_SIGNED) numeric(VSignedState(signst));
if (signst==signedst_UNSIGNED) numeric(signst);
else if (signst==signedst_SIGNED) numeric(signst);
}
// METHODS
virtual AstBasicDType* basicp() const { return (AstBasicDType*)this; } // (Slow) recurse down to find basic data type
@@ -456,6 +467,8 @@ public:
}}
virtual bool same(AstNode* samep) const {
return (m_refDTypep==samep->castConstDType()->m_refDTypep); }
virtual bool similarDType(AstNodeDType* samep) const {
return skipRefp()->similarDType(samep->skipRefp()); }
virtual V3Hash sameHash() const { return V3Hash(m_refDTypep); } // node's type() included elsewhere
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
@@ -499,6 +512,7 @@ public:
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
virtual bool similarDType(AstNodeDType* samep) const { return this==samep; }
virtual int widthAlignBytes() const { return 1; }
virtual int widthTotalBytes() const { return 1; }
string cellName() const { return m_cellName; }
@@ -540,6 +554,8 @@ public:
return (m_refDTypep==samep->castRefDType()->m_refDTypep
&& m_name==samep->castRefDType()->m_name
&& m_packagep==samep->castRefDType()->m_packagep); }
virtual bool similarDType(AstNodeDType* samep) const {
return skipRefp()->similarDType(samep->skipRefp()); }
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(m_packagep)); }
virtual void dump(ostream& str=cout);
virtual string name() const { return m_name; }
@@ -594,6 +610,7 @@ class AstMemberDType : public AstNodeDType {
private:
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
string m_name; // Name of variable
string m_tag; // Holds the string of the verilator tag -- used in XML output.
int m_lsb; // Within this level's packed struct, the LSB of the first bit of the member
//UNSUP: int m_randType; // Randomization type (IEEE)
public:
@@ -623,6 +640,7 @@ public:
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; }
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); }
virtual bool similarDType(AstNodeDType* samep) const { return this==samep; }
//
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType)
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType)
@@ -633,6 +651,8 @@ public:
virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
// METHODS
virtual void name(const string& name) { m_name = name; }
virtual void tag(const string& text) { m_tag = text;}
virtual string tag() const { return m_tag; }
int lsb() const { return m_lsb; }
void lsb(int lsb) { m_lsb=lsb; }
};
@@ -704,6 +724,7 @@ public:
m_refDTypep = m_refDTypep->clonep();
}}
virtual bool same(AstNode* samep) const { return m_uniqueNum==samep->castEnumDType()->m_uniqueNum; }
virtual bool similarDType(AstNodeDType* samep) const { return this==samep; }
virtual V3Hash sameHash() const { return V3Hash(m_uniqueNum); }
AstNodeDType* getChildDTypep() const { return childDTypep(); }
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Data type
@@ -728,11 +749,12 @@ class AstParseTypeDType : public AstNodeDType {
// During parsing, this indicates the type of a parameter is a "parameter type"
// e.g. the data type is a container of any data type
public:
AstParseTypeDType(FileLine* fl)
explicit AstParseTypeDType(FileLine* fl)
: AstNodeDType(fl) {}
ASTNODE_NODE_FUNCS(ParseTypeDType)
AstNodeDType* dtypep() const { return NULL; }
// METHODS
virtual bool similarDType(AstNodeDType* samep) const { return this==samep; }
virtual AstBasicDType* basicp() const { return NULL; }
virtual AstNodeDType* skipRefp() const { return NULL; }
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
@@ -747,8 +769,6 @@ class AstArraySel : public AstNodeSel {
// Parents: math|stmt
// Children: varref|arraysel, math
private:
unsigned m_start;
unsigned m_length;
void init(AstNode* fromp) {
if (fromp && fromp->dtypep()->skipRefp()->castNodeArrayDType()) {
// Strip off array to find what array references
@@ -757,11 +777,11 @@ private:
}
public:
AstArraySel(FileLine* fl, AstNode* fromp, AstNode* bitp)
:AstNodeSel(fl, fromp, bitp), m_start(0), m_length(1) {
:AstNodeSel(fl, fromp, bitp) {
init(fromp);
}
AstArraySel(FileLine* fl, AstNode* fromp, int bit)
:AstNodeSel(fl, fromp, new AstConst(fl,bit)), m_start(0), m_length(1) {
:AstNodeSel(fl, fromp, new AstConst(fl,bit)) {
init(fromp);
}
ASTNODE_NODE_FUNCS(ArraySel)
@@ -773,18 +793,13 @@ public:
virtual bool cleanOut() { return true; }
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
virtual bool isGateOptimizable() const { return false; }
virtual bool isGateOptimizable() const { return true; } // esp for V3Const::ifSameAssign
virtual bool isPredictOptimizable() const { return false; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
virtual int instrCount() const { return widthInstrs(); }
unsigned length() const { return m_length; }
void length(unsigned length) { m_length = length; }
void start(unsigned start) { m_start = start; }
unsigned start() const { return m_start; }
// Special operators
static AstNode* baseFromp(AstNode* nodep); ///< What is the base variable (or const) this dereferences?
virtual void dump(ostream& str);
};
class AstWordSel : public AstNodeSel {
@@ -966,6 +981,7 @@ class AstVar : public AstNode {
private:
string m_name; // Name of variable
string m_origName; // Original name before dot addition
string m_tag; // Holds the string of the verilator tag -- used in XML output.
AstVarType m_varType; // Type of variable
bool m_input:1; // Input or inout
bool m_output:1; // Output or inout
@@ -1106,6 +1122,8 @@ public:
void trace(bool flag) { m_trace=flag; }
// METHODS
virtual void name(const string& name) { m_name = name; }
virtual void tag(const string& text) { m_tag = text;}
virtual string tag() const { return m_tag; }
virtual string directionName() const { return (isInout() ? "inout" : isInput() ? "input"
: isOutput() ? "output" : varType().ascii()); }
bool isInput() const { return m_input; }
@@ -1489,6 +1507,32 @@ public:
virtual string verilogKwd() const { return "primitive"; }
};
class AstPackageExportStarStar : public AstNode {
// A package export *::* declaration
public:
// cppcheck-suppress noExplicitConstructor
AstPackageExportStarStar(FileLine* fl)
: AstNode (fl) {}
ASTNODE_NODE_FUNCS(PackageExportStarStar)
};
class AstPackageExport : public AstNode {
private:
// A package export declaration
string m_name;
AstPackage* m_packagep; // Package hierarchy
public:
AstPackageExport(FileLine* fl, AstPackage* packagep, const string& name)
: AstNode (fl), m_name(name), m_packagep(packagep) {}
ASTNODE_NODE_FUNCS(PackageExport)
virtual const char* broken() const { BROKEN_RTN(!m_packagep || !m_packagep->brokeExists()); return NULL; }
virtual void cloneRelink() { if (m_packagep && m_packagep->clonep()) m_packagep = m_packagep->clonep(); }
virtual void dump(ostream& str);
virtual string name() const { return m_name; }
AstPackage* packagep() const { return m_packagep; }
void packagep(AstPackage* nodep) { m_packagep=nodep; }
};
class AstPackageImport : public AstNode {
private:
// A package import declaration
@@ -1639,7 +1683,7 @@ private:
string m_name; // Cell name
public:
AstCellRef(FileLine* fl,
string name, AstNode* cellp, AstNode* exprp)
const string& name, AstNode* cellp, AstNode* exprp)
: AstNode(fl)
, m_name(name) {
addNOp1p(cellp); addNOp2p(exprp); }
@@ -1656,7 +1700,7 @@ private:
string m_name; // Array name
public:
AstCellArrayRef(FileLine* fl,
string name, AstNode* selectExprp)
const string& name, AstNode* selectExprp)
: AstNode(fl)
, m_name(name) {
addNOp1p(selectExprp); }
@@ -1672,7 +1716,7 @@ private:
string m_name; // Var name
public:
AstUnlinkedRef(FileLine* fl,
AstNode* refp, string name, AstNode* crp)
AstNode* refp, const string& name, AstNode* crp)
: AstNode(fl)
, m_name(name) {
addNOp1p(refp); addNOp2p(crp); }
@@ -1778,7 +1822,7 @@ public:
}}
virtual bool same(AstNode* samep) const {
return (m_packagep==samep->castPackageRef()->m_packagep); }
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_packagep)); }
virtual V3Hash sameHash() const { return V3Hash(m_packagep); }
virtual void dump(ostream& str=cout);
AstPackage* packagep() const { return m_packagep; }
void packagep(AstPackage* nodep) { m_packagep=nodep; }
@@ -1870,6 +1914,7 @@ private:
AstEdgeType m_edgeType; // Edge type
public:
class Combo {}; // for creator type-overload selection
class Illegal {}; // for creator type-overload selection
class Initial {}; // for creator type-overload selection
class Settle {}; // for creator type-overload selection
class Never {}; // for creator type-overload selection
@@ -1881,6 +1926,10 @@ public:
: AstNodeSenItem(fl) {
m_edgeType = AstEdgeType::ET_COMBO;
}
AstSenItem(FileLine* fl, Illegal)
: AstNodeSenItem(fl) {
m_edgeType = AstEdgeType::ET_ILLEGAL;
}
AstSenItem(FileLine* fl, Initial)
: AstNodeSenItem(fl) {
m_edgeType = AstEdgeType::ET_INITIAL;
@@ -1895,7 +1944,7 @@ public:
}
ASTNODE_NODE_FUNCS(SenItem)
virtual void dump(ostream& str);
virtual V3Hash sameHash() const { return V3Hash(V3Hash(edgeType())); }
virtual V3Hash sameHash() const { return V3Hash(edgeType()); }
virtual bool same(AstNode* samep) const {
return edgeType()==samep->castSenItem()->edgeType(); }
AstEdgeType edgeType() const { return m_edgeType; } // * = Posedge/negedge
@@ -1906,6 +1955,7 @@ public:
virtual bool isClocked() const { return edgeType().clockedStmt(); }
virtual bool isCombo() const { return edgeType()==AstEdgeType::ET_COMBO; }
virtual bool isInitial() const { return edgeType()==AstEdgeType::ET_INITIAL; }
virtual bool isIllegal() const { return edgeType()==AstEdgeType::ET_ILLEGAL; }
virtual bool isSettle() const { return edgeType()==AstEdgeType::ET_SETTLE; }
virtual bool isNever() const { return edgeType()==AstEdgeType::ET_NEVER; }
bool hasVar() const { return !(isCombo()||isInitial()||isSettle()||isNever()); }
@@ -2017,6 +2067,7 @@ public:
}
ASTNODE_NODE_FUNCS(Assign)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssign(this->fileline(), lhsp, rhsp); }
virtual bool brokeLhsMustBeLvalue() const { return true; }
};
class AstAssignAlias : public AstNodeAssign {
@@ -2027,6 +2078,7 @@ public:
: AstNodeAssign(fileline, lhsp, rhsp) {}
ASTNODE_NODE_FUNCS(AssignAlias)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { V3ERROR_NA; return NULL; }
virtual bool brokeLhsMustBeLvalue() const { return false; }
};
class AstAssignDly : public AstNodeAssign {
@@ -2037,6 +2089,7 @@ public:
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignDly(this->fileline(), lhsp, rhsp); }
virtual bool isGateOptimizable() const { return false; }
virtual string verilogKwd() const { return "<="; }
virtual bool brokeLhsMustBeLvalue() const { return true; }
};
class AstAssignW : public AstNodeAssign {
@@ -2046,6 +2099,7 @@ public:
: AstNodeAssign(fileline, lhsp, rhsp) { }
ASTNODE_NODE_FUNCS(AssignW)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignW(this->fileline(), lhsp, rhsp); }
virtual bool brokeLhsMustBeLvalue() const { return true; }
AstAlways* convertToAlways() {
AstNode* lhs1p = lhsp()->unlinkFrBack();
AstNode* rhs1p = rhsp()->unlinkFrBack();
@@ -2065,6 +2119,7 @@ public:
}
ASTNODE_NODE_FUNCS(AssignVarScope)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignVarScope(this->fileline(), lhsp, rhsp); }
virtual bool brokeLhsMustBeLvalue() const { return false; }
};
class AstPull : public AstNode {
@@ -2091,6 +2146,7 @@ public:
: AstNodeAssign(fileline, lhsp, rhsp) {}
ASTNODE_NODE_FUNCS(AssignPre)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignPre(this->fileline(), lhsp, rhsp); }
virtual bool brokeLhsMustBeLvalue() const { return true; }
};
class AstAssignPost : public AstNodeAssign {
@@ -2100,6 +2156,7 @@ public:
: AstNodeAssign(fileline, lhsp, rhsp) {}
ASTNODE_NODE_FUNCS(AssignPost)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignPost(this->fileline(), lhsp, rhsp); }
virtual bool brokeLhsMustBeLvalue() const { return true; }
};
class AstComment : public AstNodeStmt {
@@ -2126,6 +2183,8 @@ public:
AstCond(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p)
: AstNodeCond(fl, condp, expr1p, expr2p) {}
ASTNODE_NODE_FUNCS(Cond)
virtual AstNode* cloneType(AstNode* condp, AstNode* expr1p, AstNode* expr2p) {
return new AstCond(this->fileline(), condp, expr1p, expr2p); }
};
class AstCondBound : public AstNodeCond {
@@ -2136,6 +2195,8 @@ public:
AstCondBound(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p)
: AstNodeCond(fl, condp, expr1p, expr2p) {}
ASTNODE_NODE_FUNCS(CondBound)
virtual AstNode* cloneType(AstNode* condp, AstNode* expr1p, AstNode* expr2p) {
return new AstCondBound(this->fileline(), condp, expr1p, expr2p); }
};
class AstCoverDecl : public AstNodeStmt {
@@ -2318,9 +2379,15 @@ class AstSFormatF : public AstNode {
// Also used as "real" function for /*verilator sformat*/ functions
string m_text;
bool m_hidden; // Under display, etc
bool m_hasFormat; // Has format code
public:
class NoFormat {};
AstSFormatF(FileLine* fl, const string& text, bool hidden, AstNode* exprsp)
: AstNode(fl), m_text(text), m_hidden(hidden) {
: AstNode(fl), m_text(text), m_hidden(hidden), m_hasFormat(true) {
dtypeSetString();
addNOp1p(exprsp); addNOp2p(NULL); }
AstSFormatF(FileLine* fl, NoFormat, AstNode* exprsp)
: AstNode(fl), m_text(""), m_hidden(true), m_hasFormat(false) {
dtypeSetString();
addNOp1p(exprsp); addNOp2p(NULL); }
ASTNODE_NODE_FUNCS(SFormatF)
@@ -2339,6 +2406,8 @@ public:
bool formatScopeTracking() const { // Track scopeNamep(); Ok if false positive
return (name().find("%m") != string::npos || name().find("%M") != string::npos); }
bool hidden() const { return m_hidden; }
void hasFormat(bool flag) { m_hasFormat=flag; }
bool hasFormat() const { return m_hasFormat; }
};
class AstDisplay : public AstNodeStmt {
@@ -2354,6 +2423,12 @@ public:
setNOp3p(filep);
m_displayType = dispType;
}
AstDisplay(FileLine* fileline, AstDisplayType dispType, AstNode* filep, AstNode* exprsp)
: AstNodeStmt (fileline) {
setOp1p(new AstSFormatF(fileline, AstSFormatF::NoFormat(), exprsp));
setNOp3p(filep);
m_displayType = dispType;
}
ASTNODE_NODE_FUNCS(Display)
virtual void dump(ostream& str);
virtual const char* broken() const { BROKEN_RTN(!fmtp()); return NULL; }
@@ -2622,28 +2697,24 @@ public:
class AstValuePlusArgs : public AstNodeMath {
// Parents: expr
// Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs
private:
string m_text;
public:
AstValuePlusArgs(FileLine* fileline, const string& text, AstNode* exprsp)
: AstNodeMath (fileline), m_text(text) {
setOp1p(exprsp);
AstValuePlusArgs(FileLine* fileline, AstNode* searchp, AstNode* outp)
: AstNodeMath (fileline) {
setOp1p(searchp); setOp2p(outp);
}
ASTNODE_NODE_FUNCS(ValuePlusArgs)
virtual string name() const { return m_text; }
virtual string verilogKwd() const { return "$value$plusargs"; }
virtual string emitVerilog() { return verilogKwd(); }
virtual string emitC() { return "VL_VALUEPLUSARGS_%nq(%lw, %P, NULL)"; }
virtual string emitVerilog() { return "%f$value$plusargs(%l, %k%r)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool isGateOptimizable() const { return false; }
virtual bool isPredictOptimizable() const { return false; }
virtual bool cleanOut() { return true; }
virtual V3Hash sameHash() const { return V3Hash(text()); }
virtual bool same(AstNode* samep) const {
return text()==samep->castValuePlusArgs()->text(); }
AstNode* exprsp() const { return op1p(); } // op1 = Expressions to output
void exprsp(AstNode* nodep) { setOp1p(nodep); } // op1 = Expressions to output
string text() const { return m_text; } // * = Text to display
void text(const string& text) { m_text=text; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
AstNode* searchp() const { return op1p(); } // op1 = Search expression
void searchp(AstNode* nodep) { setOp1p(nodep); }
AstNode* outp() const { return op2p(); } // op2 = Expressions to output
void outp(AstNode* nodep) { setOp2p(nodep); }
};
class AstTestPlusArgs : public AstNodeMath {
@@ -4637,6 +4708,7 @@ public:
dtypeSetLogicBool(); }
ASTNODE_NODE_FUNCS(EqWild)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstEqWild(this->fileline(), lhsp, rhsp); }
static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp); // Return AstEqWild/AstEqD
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildEq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %f==? %r)"; }
virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; }
+16 -16
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -84,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;
@@ -162,7 +162,7 @@ private:
}
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());
@@ -173,7 +173,7 @@ private:
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);
@@ -186,14 +186,14 @@ private:
}
nodep->iterateChildren(*this);
}
virtual void visit(AstVarXRef* 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, AstNUser*) {
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
@@ -206,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
@@ -226,7 +226,7 @@ private:
nodep->iterateChildren(*this);
m_ifDepth = prevIfDepth;
}
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
@@ -252,21 +252,21 @@ 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, AstNUser*) {
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, AstNUser*) {
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);
@@ -275,7 +275,7 @@ private:
nodep->iterateChildren(*this);
}
//--------------------
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
@@ -296,5 +296,5 @@ void V3Begin::debeginAll(AstNetlist* nodep) {
if (state.anyFuncInBegin()) {
BeginRelinkVisitor brvisitor (nodep,&state);
}
V3Global::dumpCheckGlobalTree("begin.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("begin", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+5 -5
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+23 -10
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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);
@@ -192,7 +196,7 @@ private:
nodep->iterateChildrenConst(*this);
}
// VISITORS
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
processAndIterate(nodep);
}
public:
@@ -236,7 +240,16 @@ private:
nodep->iterateChildrenConst(*this);
BrokenTable::setUnder(nodep,false);
}
virtual void visit(AstNode* nodep, AstNUser*) {
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:
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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 -18
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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,8 @@ public:
m_numStmts += 1;
}
V3CCtorsVisitor(AstNodeModule* nodep, string basename, string argsp="", string callargsp="") {
V3CCtorsVisitor(AstNodeModule* nodep, string basename, string argsp="", string callargsp="",
const string& stmt="") {
m_basename = basename;
m_argsp = argsp;
m_callargsp = callargsp;
@@ -87,9 +88,15 @@ public:
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:
explicit V3CCtorsVisitor(const V3CCtorsVisitor&); ///< N/A, no copy constructor
};
//######################################################################
@@ -97,21 +104,27 @@ public:
void V3CCtors::cctorsAll() {
UINFO(2,__FUNCTION__<<": "<<endl);
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castNodeModule()) {
// Process each module in turn
V3CCtorsVisitor var_reset (modp, "_ctor_var_reset");
V3CCtorsVisitor configure_coverage (modp, "_configure_coverage",
EmitCBaseVisitor::symClassVar()+ ", bool first", "vlSymsp, first");
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
AstVar* varp = np->castVar();
if (varp) var_reset.add(new AstCReset(varp->fileline(), new AstVarRef(varp->fileline(), varp, true)));
AstCoverDecl* coverp = np->castCoverDecl();
if (coverp) {
AstNode* backp = coverp->backp();
coverp->unlinkFrBack();
configure_coverage.add(coverp);
np = backp;
}
}
// Process each module in turn
{
V3CCtorsVisitor var_reset (modp, "_ctor_var_reset");
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
if (AstVar* varp = np->castVar()) {
var_reset.add(new AstCReset(varp->fileline(), new AstVarRef(varp->fileline(), varp, true)));
}
}
}
if (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;
}
}
}
}
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+9 -9
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 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,7 +107,7 @@ private:
}
}
}
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
public:
@@ -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 {
@@ -423,7 +423,7 @@ 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(); VL_DANGLING(nodep);
@@ -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: ");
@@ -467,7 +467,7 @@ private:
}
//--------------------
// Default: Just iterate
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
@@ -489,7 +489,7 @@ public:
void V3Case::caseAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CaseVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("case.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("case", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Case::caseLint(AstNodeCase* nodep) {
UINFO(4,__FUNCTION__<<": "<<endl);
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+11 -11
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2004-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2017 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.
@@ -107,19 +107,19 @@ private:
}
// VISITORS
virtual void visit(AstNodeUniop* nodep, AstNUser*) {
virtual void visit(AstNodeUniop* nodep) {
nodep->iterateChildren(*this);
nodep->user1(nodep->lhsp()->user1());
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
}
virtual void visit(AstNodeBiop* nodep, AstNUser*) {
virtual void visit(AstNodeBiop* nodep) {
nodep->iterateChildren(*this);
nodep->user1(nodep->lhsp()->user1()
| nodep->rhsp()->user1());
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
}
virtual void visit(AstNodeTriop* nodep, AstNUser*) {
virtual void visit(AstNodeTriop* nodep) {
nodep->iterateChildren(*this);
nodep->user1(nodep->lhsp()->user1()
| nodep->rhsp()->user1()
@@ -128,12 +128,12 @@ private:
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
if (nodep->sizeMattersThs()) insureCast(nodep->thsp());
}
virtual void visit(AstCCast* nodep, AstNUser*) {
virtual void visit(AstCCast* nodep) {
nodep->iterateChildren(*this);
insureLower32Cast(nodep);
nodep->user1(1);
}
virtual void visit(AstNegate* nodep, AstNUser*) {
virtual void visit(AstNegate* nodep) {
nodep->iterateChildren(*this);
nodep->user1(nodep->lhsp()->user1());
if (nodep->lhsp()->widthMin()==1) {
@@ -145,7 +145,7 @@ private:
insureCast(nodep->lhsp());
}
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
virtual void visit(AstVarRef* nodep) {
if (!nodep->lvalue()
&& !nodep->backp()->castCCast()
&& nodep->backp()->castNodeMath()
@@ -158,7 +158,7 @@ private:
}
nodep->user1(1);
}
virtual void visit(AstConst* nodep, AstNUser*) {
virtual void visit(AstConst* nodep) {
// Constants are of unknown size if smaller than 33 bits, becase
// we're too lazy to wrap every constant in the universe in
// ((IData)#).
@@ -166,11 +166,11 @@ private:
}
// NOPs
virtual void visit(AstVar* nodep, AstNUser*) {}
virtual void visit(AstVar* nodep) {}
//--------------------
// Default: Just iterate
virtual void visit(AstNode* nodep, AstNUser*) {
virtual void visit(AstNode* nodep) {
nodep->iterateChildren(*this);
}
@@ -188,5 +188,5 @@ public:
void V3Cast::castAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CastVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("cast.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("cast", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -6,7 +6,7 @@
//
//*************************************************************************
//
// Copyright 2004-2016 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2017 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.

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