Compare commits

...
599 Commits
Author SHA1 Message Date
Wilson Snyder b46f656d17 Version bump. 2014-05-11 16:51:56 -04:00
Wilson Snyder 58fd602bbd Fix flex warning 2014-05-11 09:36:39 -04:00
Wilson Snyder 9cc95704cd Tests: Add t_inst_dff parameter width change test. 2014-05-11 09:18:04 -04:00
Wilson Snyder 5f5a3dbb0a Tests: More width testing. 2014-05-10 21:51:21 -04:00
Wilson Snyder f8f53df4ec Fix X/Z extension with WIDTH param mismatch, bug764. 2014-05-10 21:38:36 -04:00
Wilson Snyder 56b85cc63c Suppress WIDTH warnings on 'x = 1<<a' 2014-05-10 17:19:57 -04:00
Wilson Snyder 90aca97e66 Internals: Flip sense of warnOn. No functional change intended. 2014-05-10 17:12:04 -04:00
Wilson Snyder 6ce2a52c5f Fix shift-right optmiization, bug763. 2014-05-10 16:38:20 -04:00
Wilson Snyder 1f56312132 Fix -Wno-UNOPTFLAT change detection with 64-bits, bug762. 2014-05-10 12:40:35 -04:00
Wilson Snyder 3aa290cddb Add error on power > 64-bits, bug761. 2014-05-10 08:24:51 -04:00
Wilson Snyder 1d1eb4fedb Testcase for bug756. 2014-05-10 08:20:10 -04:00
Wilson Snyder 266ff41386 For --cdc, don't show data types in dump file. 2014-05-10 07:50:04 -04:00
Wilson Snyder 02331e5536 Fix begin_keywords 1800+VAMS, msg1211. 2014-05-08 07:15:44 -04:00
Wilson Snyder 621c51589a Fix shift by x, bug760. 2014-05-04 08:50:44 -04:00
Wilson Snyder 4a58e859a4 Fix concats with no argments mis-sign extending, bug759. 2014-05-03 20:20:15 -04:00
Wilson Snyder 48d393d8f5 Tests: test_verilated must match signs on == sides. 2014-05-03 20:11:38 -04:00
Wilson Snyder 321552d998 Fix wide modulus uninit var 2014-05-03 20:09:45 -04:00
Wilson Snyder a985a1f9f5 Fix >>> sign extension based on expression, bug754. 2014-05-03 09:25:12 -04:00
Wilson Snyder d532a36739 Fix change detection error on unions, bug758. 2014-05-02 08:14:23 -04:00
Wilson Snyder b631b5927b Fix shift width extension, broke recent commit, bug754. 2014-04-30 22:47:01 -04:00
Wilson Snyder adb39ceb98 Internals: cppcheck clean and add cppcheck_filtered 2014-04-29 22:59:38 -04:00
Wilson Snyder 84b91b19ca Commentary 2014-04-29 22:02:48 -04:00
Wilson Snyder aaea68d3d6 Rewrite V3Width for better spec adherence when -Wno-WIDTH. 2014-04-29 22:01:50 -04:00
Wilson Snyder 2accba2e71 Update WIDTH warning message formats to match future commit. 2014-04-29 21:11:57 -04:00
Wilson Snyder 8f4f4eb5ae Fix coredump on undriven vector[-1]. 2014-04-29 21:09:44 -04:00
Wilson Snyder c5aabb3c6e Tests: Move most old test_v tests into test_regress. 2014-04-29 19:47:26 -04:00
Wilson Snyder 60c2d136e1 Internals: V3Width renames. Fix CASEEQ signing. 2014-04-26 16:52:09 -04:00
Wilson Snyder cae6ec16ba Commentary 2014-04-26 13:59:50 -04:00
Wilson Snyder 30601c77d4 tests: Add driver --unsupported 2014-04-22 20:50:22 -04:00
Wilson Snyder b0f4cf3c9c Support {} in always sensitivity lists, bug745. 2014-04-21 19:39:28 -04:00
Wilson Snyder c41dfcf6ad Fix assertions broken from bug725, bug743. 2014-04-16 22:33:25 -04:00
Wilson Snyder 2e10555f03 Fix tracing of packed arrays without --trace-structs, bug742. 2014-04-15 20:20:45 -04:00
Wilson Snyder 6b2ee0fcf3 Fix reporting struct members as reserved words, bug741. 2014-04-15 19:35:44 -04:00
Wilson Snyder 0dbdbffba7 Fix double I/O port warnings. 2014-04-15 18:50:04 -04:00
Wilson Snyder 9c5dd8d767 Fix RHEL5.6 compile warnings. 2014-04-15 18:18:36 -04:00
Glen Gibb fff0ebb5f3 Internals: Add AstReplicate dtype init.
Signed-off-by: Wilson Snyder <[email protected]>
2014-04-10 17:54:52 -04:00
Glen Gibb d34275150c Support streaming operators, bug649.
Signed-off-by: Wilson Snyder <[email protected]>
2014-04-09 20:29:35 -04:00
Wilson Snyder d04eb977c2 Fix mis-extending red xor/xand operators. 2014-04-09 07:58:46 -04:00
Wilson Snyder fb4928b2f5 Fix power calculation; setAllOnes should not set hidden state bits in V3Number. 2014-04-08 20:28:16 -04:00
Wilson Snyder 5c39420d91 Re-fix bug729 due to bug733; other internal sign extension cleanups too. 2014-04-07 21:34:00 -04:00
Wilson Snyder 14fcfd8a40 Fix signed extension problem with -Wno-WIDTH, bug729. 2014-04-05 15:52:05 -04:00
Wilson Snyder ff19dd94f9 Fix power operator calculation, bug730. 2014-04-05 15:44:49 -04:00
Wilson Snyder b6913ff9b3 With high c-splits, even split blank functions. 2014-04-05 12:41:00 -04:00
Wilson Snyder 4573fd3069 Tests: Fix unsupported items. 2014-04-03 22:03:03 -04:00
Wilson Snyder 6cf6d9f7e1 Fix modport function import not-found error. 2014-04-03 21:53:39 -04:00
Wilson Snyder 28e35a64ea Support parameter arrays, bug683. 2014-04-01 23:16:16 -04:00
Wilson Snyder 091818483a Order initial statements based on variables used. Merge from bug683 branch. 2014-04-01 22:01:25 -04:00
Wilson Snyder 3b43556c41 Internals: Remove dead NEW_ORDERING code. 2014-03-31 20:29:35 -04:00
Wilson Snyder ed39c66715 Internals: Make const iterator to fix missed-edits on dump. Merge from bug683 branch. 2014-03-31 20:24:05 -04:00
Wilson Snyder 446b0e4e5e Support '{} assignment pattern on arrays, bug355. 2014-03-30 20:41:20 -04:00
Wilson Snyder 6e3e8318d0 Internals: Add dtype to InitArray; misc Slice cleanups. From bug355 branch. 2014-03-30 20:28:51 -04:00
Wilson Snyder 17b8b660f0 Internals: Fix assignment pattern replication. From bug355 branch. 2014-03-30 10:20:12 -04:00
Wilson Snyder 40bceea68a Fix missing coverage line on else-if, bug727. 2014-03-29 11:04:13 -04:00
Holger Waechtler b655c17c09 Fix Mac OS-X test issues.
Signed-off-by: Wilson Snyder <[email protected]>
2014-03-29 08:30:08 -04:00
Wilson Snyder a3813f94fc Add PINCONNECTEMPTY warning. 2014-03-27 21:36:52 -04:00
Wilson Snyder c70540a825 Fix Mac OS-X include compile issue. 2014-03-27 21:07:59 -04:00
Holger Waechtler 9caffe330b Fix Mac OS-X test issues.
Signed-off-by: Wilson Snyder <[email protected]>
2014-03-24 20:19:43 -04:00
Wilson Snyder 8d8c5da812 Add assertions on 'unique if', bug725. 2014-03-16 21:38:29 -04:00
Wilson Snyder 55bb766c15 Fix escaped newline in assertion failures. 2014-03-16 20:57:15 -04:00
Wilson Snyder c18df68ead Fix C++-2011 warnings. 2014-03-15 14:50:03 -04:00
Wilson Snyder 3996e94c39 Fix Bison 4.0 warnings. From Verilog-Perl. 2014-03-15 14:23:19 -04:00
Wilson Snyder 1bdf017f9e PSL is no longer supported, please use System Verilog assertions. 2014-03-14 21:14:24 -04:00
Wilson Snyder 93790c1dc6 Fix tracing of package variables and real arrays. 2014-03-14 20:36:47 -04:00
Wilson Snyder ba8c11b25d Fix scope creating extra vars for package variables. See next trace commit for test. 2014-03-14 20:24:21 -04:00
Wilson Snyder ca57edfa0b Fix assignment temporaries not using real types. 2014-03-14 20:22:06 -04:00
Wilson Snyder ccb6545c32 tests: Fix bogus set of output. 2014-03-14 20:19:56 -04:00
Wilson Snyder d146dbc9d7 Commentary. 2014-03-14 20:13:41 -04:00
Glen Gibb b4eaaccc88 Documentation fixes, bug723.
Signed-off-by: Wilson Snyder <[email protected]>
2014-03-14 07:17:03 -04:00
Wilson Snyder c9ed9e74f2 Add --no-trace-params. 2014-03-13 20:08:43 -04:00
Wilson Snyder 587c7c70f5 devel release 2014-03-11 19:52:28 -04:00
Wilson Snyder 749ff021b6 Version bump 2014-03-11 19:48:57 -04:00
Wilson Snyder 85c5765c00 Fix parsing "#0 'b0", bug256. 2014-03-11 19:07:58 -04:00
Wilson Snyder 9e76078939 Fix signed shift right optimization, bug715. 2014-03-09 21:28:28 -04:00
Wilson Snyder 334e0e1ca6 Internals: Debug message. 2014-03-09 21:22:01 -04:00
Wilson Snyder dce4519995 Optimizer: Put constants on left side of compares to match other AstBiOps and extend optimizations. No runtime result change intended. 2014-03-09 17:13:37 -04:00
Wilson Snyder 45bbae80e7 Add parameters into trace files, bug706. 2014-03-08 15:36:04 -05:00
Wilson Snyder d37709a922 test driver: Update VCDs when given HARNESS_UPDATE_GOLDEN 2014-03-08 15:34:42 -05:00
Wilson Snyder 2560ae9bc1 Fix slice extraction from packed array, bug717. 2014-03-08 14:55:05 -05:00
Wilson Snyder 2bdd3ca353 Internals: Refactoring V3WidthSel. No functional change. 2014-03-08 14:41:11 -05:00
Wilson Snyder 8a8aab1aae Internals: Shrink AstSelPlus code. No functional change. 2014-03-08 14:17:39 -05:00
Wilson Snyder 85d790ff79 Fix inside statement EQWILD error, bug718. 2014-03-08 13:33:44 -05:00
Wilson Snyder 68afc96a9f Fix internal error on "input x =" syntax error, bug716. 2014-03-08 12:26:34 -05:00
Wilson Snyder 94efaa7675 Commentary 2014-02-14 08:11:49 -05:00
Wilson Snyder 180af74a50 Fix missing VL_SHIFTRS_IQI with WIDTH warning, bug514. 2014-02-13 18:13:30 -05:00
Wilson Snyder 88af0d3509 Fix --skip-identical mis-detecting on OS-X, bug707. 2014-02-09 16:32:49 -05:00
Wilson Snyder 97633f7bed Fix array bound checks on real variables. 2014-02-09 09:19:05 -05:00
Wilson Snyder 053e016388 Add unsupported test, bug711. 2014-01-25 09:49:56 -05:00
Wilson Snyder 2d61e0270e Support case inside, bug708. 2014-01-20 21:59:53 -05:00
Wilson Snyder 3a23afb0bc devel release 2014-01-20 21:55:27 -05:00
Wilson Snyder 470f12ff46 Version bump 2014-01-18 13:16:08 -05:00
Wilson Snyder 4422de0c6c Copyright year update. 2014-01-06 19:28:57 -05:00
Wilson Snyder 8a708f52f7 Tests: Merge from pattern branch. 2013-12-21 08:29:04 -05:00
Wilson Snyder bcefc17631 Support modport import, bug696. 2013-12-21 06:51:15 -05:00
Wilson Snyder daf19e241e Fix struct trace coredump from recent commit. 2013-12-21 06:46:48 -05:00
Wilson Snyder b5f5b1fdf9 Fix wire declarations with size and not range, bug466. 2013-12-14 19:50:55 -05:00
Wilson Snyder 801b718953 Add --trace-structs to show struct names, bug673. 2013-12-14 19:13:31 -05:00
Wilson Snyder f571658aa4 Commentary 2013-12-14 18:07:55 -05:00
Wilson Snyder 5d233b8c09 Fix parameter pin vs. normal pin error, bug704. 2013-12-14 18:04:10 -05:00
Wilson Snyder 00724597f4 Fix tracing of packed structs, bug705. 2013-12-14 16:51:08 -05:00
Wilson Snyder c659940ea8 Internals: Use VNumRange for AstTraceDecl 2013-12-14 12:17:31 -05:00
Wilson Snyder 23539eb55c Fix some delayed assignments of typedefed unpacked arrays. See following trace test. 2013-12-14 10:33:08 -05:00
Wilson Snyder e69bf418de Fix --lint-only with MinGW, msg1283. 2013-11-29 08:28:48 -05:00
Wilson Snyder 0e1fcd38bb Version bump 2013-11-26 19:52:19 -05:00
Wilson Snyder e74186565d Add --compiler clang to work around compiler bug, bug694. 2013-11-26 18:46:55 -05:00
Wilson Snyder 7e54281e26 Fix array assignment from const var, bug693. 2013-10-31 22:39:26 -04:00
Wilson Snyder 15f512bdee Debug: With --debug, run check tree at all steps even if no --dump-more 2013-10-30 23:25:54 -04:00
Wilson Snyder ecfe0283e2 Fix crash with coverage of structures, bug691. 2013-10-29 20:15:01 -04:00
Wilson Snyder 3b874f759c Fix of last commit, bug689. 2013-10-28 21:57:52 -04:00
Wilson Snyder 9c9b4ed4e0 Fix vpi_remove_cb inside callback, bug689. 2013-10-28 21:00:40 -04:00
Wilson Snyder 4f6d80c602 Add UNPACKED warning to convert unpacked structs. 2013-10-28 20:41:05 -04:00
Wilson Snyder b50542531d Fix enum value extension of '1. 2013-10-28 20:24:31 -04:00
Wilson Snyder 8ab28d1d12 Merge branch 'master' of ssh://git-verilator-wsnyder/git/verilator 2013-10-28 11:15:33 -04:00
Wilson Snyder 9567da22f8 Compiler warning fix. 2013-10-28 11:14:13 -04:00
Wilson Snyder 36814b7681 Support vpi_get_time, bug688. 2013-10-22 22:02:53 -04:00
Wilson Snyder 82235e6c6f Fix vpi_get of vpiSuppressVal, bug687. 2013-10-22 22:01:19 -04:00
Wilson Snyder a8310f35f2 Fix evaluation of chained parameter functions, bug684. 2013-10-18 07:06:32 -04:00
Rich Porter 85989af031 Fix vpi_get of vpiSize, bug680.
Signed-off-by: Wilson Snyder <[email protected]>
2013-10-13 20:05:57 -04:00
Rich Porter cf9ffd16dd tests: For icarus, exit on stop. Merge from RPORTER/vpi-vpiSize-680.
Signed-off-by: Wilson Snyder <[email protected]>
2013-10-11 21:34:48 -04:00
Wilson Snyder 0602537cce Fix t/t_select_index2 test. 2013-10-11 21:29:54 -04:00
Wilson Snyder 24e32420b7 Fix multiple VPI variable callbacks, bug679. 2013-10-03 07:24:50 -04:00
Wilson Snyder 39c494260b devel release 2013-09-30 16:56:52 -04:00
Wilson Snyder 761b9c9290 Version bump 2013-09-30 16:53:45 -04:00
Wilson Snyder 27686d8c2f Add --no-order-clock-delay to work around bug613. 2013-09-30 16:52:43 -04:00
Wilson Snyder d2b007005d devel release 2013-09-29 20:56:19 -04:00
Wilson Snyder f1ef30a5bb Version bump 2013-09-29 20:52:29 -04:00
Wilson Snyder f1d9437c55 Report SELRANGE warning for non-generate if, bug675. 2013-09-10 07:16:13 -04:00
Wilson Snyder bcba5075e8 Fix ordering of , msg1229. 2013-09-07 16:43:43 -04:00
Wilson Snyder d6e8b0263c Fix crash on 32-bit Ubuntu, bug670. 2013-09-03 21:40:43 -04:00
Wilson Snyder 9aba617bad Fix --output-split-cfunc to count internal functions. 2013-09-03 19:35:32 -04:00
Wilson Snyder c24f7b1391 Support named function and task arguments. 2013-08-17 20:34:49 -04:00
Wilson Snyder d4e27b635f devel release 2013-08-15 08:43:37 -04:00
Wilson Snyder c996d2870c Version bump 2013-08-15 08:39:46 -04:00
Wilson Snyder bbd59f8a22 Support passing strings to DPI imports. 2013-08-14 21:37:13 -04:00
Wilson Snyder d3d359e757 Fix clang warnings, bug668. 2013-08-08 19:39:39 -04:00
Wilson Snyder ae763ea93d Internals: Debugs for bug666. 2013-08-08 07:05:21 -04:00
Wilson Snyder 236b9e9761 Fix parameter real conversion from integer. 2013-07-29 22:03:47 -04:00
Wilson Snyder e42c9dfd84 Grammar 2013-07-29 21:53:43 -04:00
Wilson Snyder bebf5b291b Fix final duplicate declarations when non-inlined, bug661. 2013-07-29 21:47:23 -04:00
Wilson Snyder 1e3dcd203d Fix clang warning, bug668. 2013-07-29 10:37:58 -04:00
Wilson Snyder cc7da63dec Tests: Add t_mod_recurse. 2013-06-23 22:39:08 -04:00
Wilson Snyder 1baa2a2558 Fix interface ports with comma lists, msg1058. 2013-06-13 19:38:18 -04:00
Wilson Snyder e63ff77b15 VPI internals: Rename VerilatedRange left/right to match IEEE + VNumRange. No functional change. 2013-06-13 08:05:38 -04:00
Wilson Snyder 6cf9468477 Fix vpi_iterate on memory words, bug655. 2013-06-13 07:58:52 -04:00
Jeremy Bennett b277bc8750 Fix ordering of clock enables with delayed assigns, bug613.
Signed-off-by: Wilson Snyder <[email protected]>
2013-06-05 23:35:47 -04:00
Wilson Snyder ba9da64207 Fix t_trace_cat test, bug654. 2013-06-03 19:08:15 -04:00
Wilson Snyder 9cb9f9c80b devel release 2013-06-02 14:52:19 -04:00
Wilson Snyder 7a65df7636 Version bump 2013-06-02 14:47:36 -04:00
Wilson Snyder eab46d547d Version bump. 2013-06-02 14:38:53 -04:00
Wilson Snyder 3dd552c4a2 Duplicate clock gate optimization on by default, use -Od to disable 2013-05-27 22:39:59 -04:00
Wilson Snyder 23bb045a72 Support interfaces and modports, bug102. 2013-05-27 21:39:19 -04:00
Wilson Snyder 7c834ad118 Internals: Misc cleanups from interface branch. No functional change. 2013-05-27 20:56:20 -04:00
Wilson Snyder 8e2617ab8d Internals: V3Inline support for future hard-no-inline. No functional change. 2013-05-26 11:17:42 -04:00
Wilson Snyder 24fcae4f49 Internals: When broken link fatal, say which rule violated 2013-05-25 17:05:22 -04:00
Wilson Snyder ce18674d88 Internals: (see last) also dump on first non-fatal 2013-05-25 13:31:17 -04:00
Wilson Snyder 6b8d9b5c36 Internals: If registered, dump symtable on any error 2013-05-25 12:15:38 -04:00
Wilson Snyder 81bf95763c Internals: Refactor V3Inline to simplify if(m_cellp) out. No functional change. 2013-05-25 10:42:44 -04:00
Wilson Snyder 2d64077fd0 Internals: Prep to allow future move of wrapping. No functional change. 2013-05-25 10:15:10 -04:00
Wilson Snyder 38faebcf20 Fix packed array select internal error, bug652. 2013-05-24 21:32:54 -04:00
Wilson Snyder 48d177a9d0 Fix packed array select internal error, bug652. 2013-05-24 21:14:42 -04:00
Wilson Snyder 3b3a7f7354 Commentary 2013-05-24 19:09:41 -04:00
Wilson Snyder 99cd2818a1 Tests: Allow driver to find 't' signals when not first in file. 2013-05-23 22:00:55 -04:00
Wilson Snyder 5765e099a6 Debug: More digits for debug file sorting. 2013-05-23 20:50:48 -04:00
Wilson Snyder 175d59ecba Fix GCC version runtime changes, bug651. 2013-05-23 20:19:51 -04:00
Wilson Snyder 3bd3d01968 Tests: Move driver.pl tee into perl to avoid process issue, bug650. 2013-05-23 20:08:39 -04:00
Wilson Snyder 85e2a6bb45 Tests 2013-05-21 22:38:35 -04:00
Wilson Snyder 84efd239a5 Fix arrayed input compile error, bug645. Try 2. 2013-05-18 20:17:17 -04:00
Wilson Snyder 6a69813326 Internals: Renames for interfaces. No functional change. 2013-05-18 19:45:52 -04:00
Wilson Snyder 2c9dcc3913 Fix arrayed input compile error, bug645. 2013-05-15 22:00:28 -04:00
Wilson Snyder 20ea1ca018 devel release 2013-05-11 16:16:22 -04:00
Wilson Snyder 0abde90933 Version bump 2013-05-11 16:11:38 -04:00
Wilson Snyder e01b69198a driver: Fix if no forker. 2013-05-11 16:11:26 -04:00
Wilson Snyder 53cd9d2403 Fix nested union crash, bug643. 2013-05-10 21:02:48 -04:00
Wilson Snyder 3d0f5fc078 Fix packed array non-zero right index select crash, bug642. 2013-05-10 07:09:25 -04:00
Wilson Snyder 54eedcc739 Support signal[vec]++. 2013-05-06 08:02:16 -04:00
Wilson Snyder ae6f5844da Add Verilated::internalsDump() 2013-05-04 10:29:54 -04:00
Wilson Snyder 1bea845ceb Fix simulation error when inputs and MULTIDRIVEN, bug634. 2013-05-02 08:23:17 -04:00
Wilson Snyder d581582339 Add ALWCOMBORDER warning. 2013-04-30 22:55:28 -04:00
Wilson Snyder 4eabc1992e Fix gcc 4.1.2 compile warnings 2013-04-30 22:55:03 -04:00
Wilson Snyder 316eb24bbb Example test 2013-04-28 18:58:04 -04:00
Jeremy Bennett f0a8824efc Commentary, bug639.
Signed-off-by: Wilson Snyder <[email protected]>
2013-04-28 09:04:04 -04:00
Wilson Snyder 345a5d5646 Add --pins-sc-uint and --pins-sc-biguint, bug638. 2013-04-26 21:02:32 -04:00
Wilson Snyder 464679c78b Fix module resolution with __, bug631. 2013-03-12 07:27:17 -04:00
Wilson Snyder 28eeec1cf4 devel release 2013-03-09 16:48:10 -05:00
Wilson Snyder 7d0dce3267 Version bump 2013-03-09 16:44:48 -05:00
Wilson Snyder 9e29625207 Fix UNOPTFLAT circular array bounds crossing, bug630. 2013-03-08 19:25:20 -05:00
Wilson Snyder a767da4f3f Support <number>'() sized casts, bug628. 2013-03-05 22:13:22 -05:00
Wilson Snyder 7bd96c2876 Internals: Tristate commentary 2013-02-27 22:59:17 -05:00
Wilson Snyder 70fd64dcd6 IEEE 1800-2012 is now the default language. This adds 4 new keywords and updates the svdpi.h and vpi_user.h header files. 2013-02-26 23:01:19 -05:00
Jeremy Bennett bb2822f4b5 Add --report-unoptflat, bug611.
Signed-off-by: Wilson Snyder <[email protected]>
2013-02-26 22:26:47 -05:00
Wilson Snyder ad21108b63 Internals: Create graph clone methods. 2013-02-25 21:03:50 -05:00
Wilson Snyder e6808a787c Fix opening a VerilatedVcdC file multiple times, msg1021. 2013-02-23 21:10:25 -05:00
Wilson Snyder 1fb2762725 Tests: Clocking test to consider bug623. 2013-02-22 21:00:37 -05:00
Wilson Snyder cce55941d3 Makefile: Distribute .gdbinit 2013-02-22 17:24:15 -05:00
Wilson Snyder 6c8d95e0e2 Nice message on fopen with missing argument. 2013-02-22 17:14:27 -05:00
Wilson Snyder 216a178b28 Makefile: Distribute .gdbinit 2013-02-22 17:13:31 -05:00
Wilson Snyder 6594a54a95 Fix wrong dot resolution under inlining. 2013-02-21 23:38:29 -05:00
Wilson Snyder a9a4cf061a Fix tristate duplicate __Vcellinp declaration 2013-02-20 22:28:56 -05:00
Wilson Snyder b7f0e204cb Spelling fixes 2013-02-20 21:51:39 -05:00
Varun Koyyalagunta e6a15f233b Internals: GateDedupe: Use visitor per msg980.
Signed-off-by: Wilson Snyder <[email protected]>
2013-02-20 20:26:53 -05:00
Varun Koyyalagunta e0edb596ea Add duplicate clock gate optimization, msg980.
Experimental and disabled unless -OD or -O3 used (for now),
Please try it as may get some significant speedups.

Signed-off-by: Wilson Snyder <[email protected]>
2013-02-20 20:14:15 -05:00
Varun Koyyalagunta f2fb77c15a Internals: New Hashed/Graph functions towards msg980.
Signed-off-by: Wilson Snyder <[email protected]>
2013-02-19 18:49:36 -05:00
Wilson Snyder 772a3a97eb Internals: Functions in order. No functional change. 2013-02-18 12:15:50 -05:00
Wilson Snyder 6c310836a1 Internals: Track original signal name. No functional change. 2013-02-18 11:22:24 -05:00
Wilson Snyder 75416a3016 Commentary 2013-02-18 11:05:47 -05:00
Wilson Snyder ebef78a13e Tests 2013-02-18 10:17:34 -05:00
Wilson Snyder e71baca39b Internals: Make propagateAttrClocksFrom. No functional change. 2013-02-16 08:07:18 -05:00
Wilson Snyder 18eb210313 Support bind in , bug602. 2013-02-14 06:55:09 -05:00
Wilson Snyder 7d38a5e1f9 Test bug424. 2013-02-13 21:10:17 -05:00
Wilson Snyder 4386077e2d Support pattern assignments with data type labels, bug618. 2013-02-13 20:52:38 -05:00
Wilson Snyder 49dbfd2131 Support pattern assignments in function calls, bug617. 2013-02-13 20:32:25 -05:00
Wilson Snyder a80fce5ac1 Support pattern assignments to const variables, bug616. 2013-02-13 19:32:36 -05:00
Wilson Snyder 891b981cab Fix LITENDIAN on unpacked structures, bug614. 2013-02-13 19:03:10 -05:00
Rich Porter 2dd87b8384 Fix 32-bit OS VPI scan issue, bug615.
Signed-off-by: Wilson Snyder <[email protected]>
2013-02-11 07:17:18 -05:00
Jeremy Bennett 062eb85075 Fix DETECTARRAY on packed structures, bug610.
Signed-off-by: Wilson Snyder <[email protected]>
2013-02-10 09:54:27 -05:00
Wilson Snyder e1f6802f5f tests: Fix bootstrap wouldn't cd for test_regress/t/t_dist_portability.pl. 2013-02-10 09:29:35 -05:00
Wilson Snyder 6cfcd50f12 devel release 2013-02-04 22:19:37 -05:00
Wilson Snyder bcadb0b3b3 Version bump 2013-02-04 22:12:21 -05:00
Wilson Snyder 0df561f873 Fix whole slices of arrays, bug609. 2013-02-04 22:11:10 -05:00
Wilson Snyder 238fc24684 Remove slow sync() call for NFS flushing. 2013-02-04 21:21:55 -05:00
Wilson Snyder 936855c81c Fix elimination, bug610 _2 test. 2013-02-03 14:13:16 -05:00
Jeremy Bennett 61ad9d4651 Commentary, bug610.
Signed-off-by: Wilson Snyder <[email protected]>
2013-02-03 13:29:37 -05:00
Wilson Snyder f07f6a26a8 cppcheck fixes 2013-02-03 13:27:37 -05:00
Wilson Snyder 4a5a56f8ef Tests: Fix t_vpi_var uninitialized 2013-02-03 12:21:48 -05:00
Wilson Snyder 7d44bba95c Better packed-array misconnect error message 2013-02-02 19:22:02 -05:00
Wilson Snyder 6e6f1045b8 Fix per-bit array output connection error, bug414. 2013-02-02 18:33:10 -05:00
Wilson Snyder 5dd3221759 Fix complete selection of array ports 2013-02-02 16:52:08 -05:00
Wilson Snyder 09edb467f6 Fix CDC report causing out-of-memory 2013-02-02 15:40:59 -05:00
Wilson Snyder ffb187ae15 Fix enums in sensitivity lists 2013-02-02 14:37:18 -05:00
Wilson Snyder b4a8be07f3 Fix enum items under packages. 2013-02-02 14:11:50 -05:00
Wilson Snyder 4968a2abc5 Support inside expressions. 2013-02-02 12:55:48 -05:00
Wilson Snyder 91159da30d Fix enums with X values. Test in next commit. 2013-02-02 12:43:28 -05:00
Wilson Snyder c9ad61b4fb Support wires with data types, bug608. 2013-02-02 09:33:04 -05:00
Wilson Snyder 3f0dcd8c0e Tests: Redo check macro. 2013-02-02 09:28:45 -05:00
Wilson Snyder e1eb41fe77 Fix segfault on multidimensional dotted arrays, bug607. 2013-01-25 21:27:19 -05:00
Wilson Snyder 498ab23355 Commentary 2013-01-20 13:00:02 -05:00
Wilson Snyder 5d6a053f98 Fix internal error on array pin mismatch, bug393. 2013-01-20 12:59:27 -05:00
Wilson Snyder 929aeebf12 Support , and related functions, bug448. 2013-01-20 12:19:22 -05:00
Wilson Snyder 00bd947385 Tests: Additional unsupported iface tests 2013-01-19 14:40:35 -05:00
Wilson Snyder d4ef86afc0 Fix signed/unsigned parameter misconversion, bug606. 2013-01-18 21:35:43 -05:00
Wilson Snyder 1856cad816 Maintain little endian indication for multidimensional arrays 2013-01-17 23:21:07 -05:00
Wilson Snyder 91e2d1d2a0 Tests: Make struct test pass. 2013-01-17 22:45:35 -05:00
Wilson Snyder f29f30dce0 Fix struct +: slices, bug605. 2013-01-17 21:48:35 -05:00
Wilson Snyder e7ba6ef492 Support VPI product info, warning calls, etc, bug588. 2013-01-17 21:40:37 -05:00
Wilson Snyder de4016dcff Internals: Ast classes create declRange(). 2013-01-17 20:41:45 -05:00
Wilson Snyder bbeb382cbb Internals: Rename range lo/hi to match IEEE. 2013-01-17 20:29:20 -05:00
Wilson Snyder 385c166830 Fix package logic var compile error. 2013-01-17 19:04:36 -05:00
Wilson Snyder 410e6ff203 Fix DECLFILENAME warning on . 2013-01-17 18:38:51 -05:00
Jeremy Bennett 8b47c4e307 Fix loosing logic/bit difference and -x-initial-edge fallout, bug604.
Signed-off-by: Wilson Snyder <[email protected]>
2013-01-17 07:16:19 -05:00
Wilson Snyder 6d1b42bedb Fix implicit one bit parameter selection, bug603. 2013-01-16 20:58:48 -05:00
Wilson Snyder f0a4bd28b6 Comment about -x-initial-edge and logic/bit. 2013-01-16 20:47:22 -05:00
Wilson Snyder 2879684f21 Define SYSTEMVERILOG, SV_COV_START and other IEEE mandated predefines. 2013-01-16 19:11:56 -05:00
Wilson Snyder 0437d0abea Fix pin width mismatch error, bug595. 2013-01-15 19:26:35 -05:00
Wilson Snyder 0286f588bf Tests: bind by modname 2013-01-15 19:23:46 -05:00
Wilson Snyder 042fb76837 Tests 2013-01-14 23:39:56 -05:00
Wilson Snyder 795e66eac9 Support bind, to module names only, bug602. 2013-01-14 23:19:44 -05:00
Wilson Snyder aae0615ffd Commentary 2013-01-14 21:51:02 -05:00
Wilson Snyder 8127a79cb1 Fix nested packed arrays and structs, bug600.
IMPORTANT: Packed arrays are now represented as a single linear vector in
Verilated models this may affect packed arrays that are public or accessed via the VPI.
2013-01-14 21:49:22 -05:00
Wilson Snyder 057ca497dd tests: Fix Xs on vector data 2013-01-14 21:38:16 -05:00
Wilson Snyder 66b1611649 In debug, show node dump after errors. 2013-01-14 21:37:55 -05:00
Wilson Snyder 7f5220a6ca Internals: Fix marking of packed vs unpacked wires. 2013-01-13 22:18:57 -05:00
Wilson Snyder e41e26717b Commentary 2013-01-13 19:51:15 -05:00
Wilson Snyder 7a8184d206 Internals: Remove dimension and use only dtypes for V3Width. 2013-01-13 15:21:38 -05:00
Wilson Snyder 13bf2f19ac Internals: Have V3Unknown/Const use only dtypes for selects. 2013-01-13 14:54:12 -05:00
Wilson Snyder 1d5ebfd0b1 Internals: Have V3WidthSel use only dtypes for select promotion. 2013-01-13 14:49:53 -05:00
Wilson Snyder dfc11da2ce Internals: Dump array bounds in tree file. 2013-01-13 14:30:56 -05:00
Wilson Snyder 191af2e87b Internals: Make SelPlus consistent with other branches. No functional change intended. 2013-01-13 11:30:05 -05:00
Wilson Snyder 0985b82760 Commentary 2013-01-13 09:48:12 -05:00
Wilson Snyder 26f4b5a69a Stats: Count only unpacked 2013-01-12 16:26:26 -05:00
Wilson Snyder 5c7a6e278f Internals: Split into packed and unpacked array types 2013-01-12 16:19:25 -05:00
Wilson Snyder ae1ab8aaaa Fix array slice selection of msb==lsb. 2013-01-12 15:34:09 -05:00
Wilson Snyder 18c25d1b6f Commentary 2013-01-12 14:51:16 -05:00
Wilson Snyder 5888a2c399 Internals: Move V3WidthSel::range into V3Width. No functional change intended. 2013-01-12 14:23:56 -05:00
Wilson Snyder c00603704e Commentary 2013-01-11 07:05:25 -05:00
Wilson Snyder 786bc4b04f devel release 2013-01-09 22:27:36 -05:00
Wilson Snyder 5eca20f849 Version bump 2013-01-09 22:08:30 -05:00
Wilson Snyder 0a3a582949 Fix array extraction of implicit vars, bug601. 2013-01-09 19:00:12 -05:00
Wilson Snyder 08fec0534d Fix package import preventing local var, bug599. 2013-01-08 19:06:52 -05:00
Wilson Snyder 5bf92c9d3a Fix task inlining under case values, bug598. Note this reorders high level operations, so may change loose some optimizations. 2013-01-02 18:35:21 -05:00
Wilson Snyder a8bbf7231b Copyright year update. 2013-01-01 09:42:59 -05:00
Wilson Snyder 83c171012d Test added 2012-12-31 19:06:49 -05:00
Wilson Snyder 229d854607 Fix package resolution of parameters, bug586. 2012-12-31 17:05:13 -05:00
Wilson Snyder 562460606f Internals: Add V3LinkDot m_ds structure, towards bug586. No functional change. 2012-12-31 14:00:04 -05:00
Wilson Snyder 46f70b1cbb Fix implying dotted wire names 2012-12-31 13:50:44 -05:00
Wilson Snyder a547133efe Internals: Remove VAR_MEM to match Verilog-Perl, towards bug586. 2012-12-31 13:47:34 -05:00
Wilson Snyder cf445898ce Internals: Move VARRESET rule to match Verilog-Perl and prevent next change conflict, towards bug586. No functional change. 2012-12-31 13:43:54 -05:00
Wilson Snyder 98f68e46d6 Fix package import of package imports, partial bug592. 2012-12-17 20:26:40 -05:00
Wilson Snyder 27660b271d Fix package import of non-localparam parameter, bug591. 2012-12-17 19:07:23 -05:00
Wilson Snyder 895e374860 Test for last commit. 2012-12-17 18:41:54 -05:00
Wilson Snyder 4c7f051247 Fix task inlining under , bug589. 2012-12-15 21:41:37 -05:00
Wilson Snyder e68afa53a8 Fix non-integer vpi_get_value, bug587. 2012-12-06 09:40:16 -05:00
Wilson Snyder cc47ba2404 Support "unsigned int" DPI import functions, msg966. 2012-12-03 20:43:13 -05:00
Wilson Snyder 2238fa46ed Show fileline in bison debug. 2012-12-02 18:03:34 -05:00
Wilson Snyder de8b040e31 bisonpre: Add colon to states for searching 2012-12-02 16:19:31 -05:00
Wilson Snyder 4ffc48d194 devel release 2012-12-02 16:19:26 -05:00
Wilson Snyder 2433848408 Version bump - changelog 2012-12-01 16:38:21 -05:00
Wilson Snyder e602f7febc Version bump 2012-12-01 16:15:40 -05:00
Wilson Snyder f607b32938 Fix crash on dotted references into dead modules, bug583. 2012-11-30 06:57:36 -05:00
Wilson Snyder c7a088faa5 Fix mis-optimized identical submodule subtract, bug581. Take 2. 2012-11-28 20:18:41 -05:00
Wilson Snyder 30f6c0e105 Fix mis-optimized identical submodule subtract, bug581. 2012-11-28 07:36:47 -05:00
Wilson Snyder 38b9fa7b93 driver: Print message when no Parallel::Forker. 2012-11-21 07:09:29 -05:00
Jeremy Bennett 39a31fc17f Fix --debug overriding preceding --dump-treei, bug580.
Signed-off-by: Wilson Snyder <[email protected]>
2012-11-21 06:55:28 -05:00
Wilson Snyder 899a7df14a Fix VerilatedSave compile issue on MSVCC, bug577. 2012-11-13 20:36:20 -05:00
Wilson Snyder 7a8c425103 Add +1364-1995ext and similar language options, bug532. 2012-11-13 20:12:23 -05:00
Wilson Snyder 0e8ce59022 Fix svdpi compile issue on MSVCC, bug571. 2012-11-05 10:22:19 -05:00
Wilson Snyder 77ac76a158 devel release 2012-11-03 20:19:31 -04:00
Wilson Snyder 8108b97050 Version bump 2012-11-03 20:16:01 -04:00
Wilson Snyder a1c3491dea Display speed ups, bug574. 2012-11-03 20:11:53 -04:00
Wilson Snyder 8bba96a84e Tests 2012-11-03 09:23:34 -04:00
Wilson Snyder 6cd9b25a53 Fix array of struct references giving false error, bug566. 2012-11-03 09:17:42 -04:00
Wilson Snyder 0431b1909c Fix name collision on task inputs, bug569. 2012-11-03 08:01:19 -04:00
Wilson Snyder 907665e2e8 Fix name collision on unnamed blocks, bug567. 2012-11-02 20:30:47 -04:00
Wilson Snyder 61e8836fbd Add -x-initial-edge, bug570. by Jeremy Bennett; from BENNETT/initial-edge branch. 2012-11-02 19:55:34 -04:00
Wilson Snyder 0e921b5dff Speed display, bug373. 2012-11-02 17:54:14 -04:00
Wilson Snyder 7ef37d6e17 Fix missing var access functions when no DPI, bug572. 2012-10-30 03:02:35 -04:00
Wilson Snyder dce227684a Fix mangling on GCC 4.7, msg927. 2012-10-28 17:35:48 -04:00
Wilson Snyder 158e112752 Internals: Resolve misc bison comments with Verilog-Perl. No functional change. 2012-10-08 21:20:13 -04:00
Wilson Snyder ec992c7f5e Internals: Resolve misc bison comments with Verilog-Perl 2012-10-08 20:45:39 -04:00
Wilson Snyder e7d63c7644 Fix large shift error on large shift constants. 2012-10-08 07:05:54 -04:00
Wilson Snyder 6464e8fee6 Misc code cleanups. Merge from assignment pattern branch. No functional change. 2012-09-25 19:27:00 -04:00
Wilson Snyder 047d66a657 Slice code cleanup. No functional change. 2012-09-25 19:17:57 -04:00
Wilson Snyder 55c23360d9 Commentary 2012-09-24 18:28:19 -04:00
Wilson Snyder c378d32c85 Fix parameter pins interspersed with cells broke in 3.840. 2012-09-07 19:51:41 -04:00
Wilson Snyder 3d9540c58c devel release 2012-09-03 20:32:32 -04:00
Wilson Snyder 39724eb916 Version bump 2012-09-03 20:03:25 -04:00
Jeremy Bennett 48dddd4ae7 Debug: Use dot label rather than a custom nTITLE node to label the graph. Generate all graph level attributes as attributes of the graph entity. bug555.
Signed-off-by: Wilson Snyder <[email protected]>
2012-08-27 19:02:27 -04:00
Wilson Snyder 9c00fd10de Add --savable to support model save/restore. 2012-08-26 21:19:43 -04:00
Jeremy Bennett 9309d0b00f Commentary on internals.pod, bug554.
Signed-off-by: Wilson Snyder <[email protected]>
2012-08-25 12:47:59 -04:00
Wilson Snyder 038b5d32a3 Commentary 2012-08-25 12:18:06 -04:00
Jeremy Bennett 706920ba19 Tests: t_vpi_var: Fix vector length, bug553.
Signed-off-by: Wilson Snyder <[email protected]>
2012-08-25 12:05:08 -04:00
Jeremy Bennett 39492a0726 Tidy up .gitignore and MANIFEST.SKIP, bug552.
Signed-off-by: Wilson Snyder <[email protected]>
2012-08-25 07:52:07 -04:00
Wilson Snyder df1170fea9 Test 2012-08-23 13:26:12 -04:00
Wilson Snyder f0e1d204fa Fix triangle symbol resolution error broke in 3.840, bug550.
This requires the parse symbol table persist across all parse runs. This is
probably more correct than before, but may result in some fallout if people
relied on data types not being persistant across separately parsed cells.
2012-08-15 21:28:30 -04:00
Wilson Snyder 8ece0a8a5f Create V3ParseSym. No functional change. 2012-08-15 21:14:20 -04:00
Wilson Snyder 1373b81e7c Include: Allow external progs to test command args 2012-08-14 20:37:15 -04:00
Wilson Snyder d3601dd561 Support '{} assignment pattern on structures, part of bug355. 2012-08-12 15:15:21 -04:00
Wilson Snyder f685cf1d0c Fix duplicate begin error broke in 3.840, bug548. 2012-08-10 19:39:18 -04:00
Wilson Snyder d5fcf0c153 Test for bug349 2012-08-08 22:15:07 -04:00
Wilson Snyder 5f9810070d Fix imports under multiple instantiated cells, bug542. 2012-08-08 21:59:17 -04:00
Wilson Snyder 923efa004b New tests 2012-08-07 20:59:34 -04:00
Wilson Snyder 869e8eab3c tests; check package to package refs 2012-08-07 20:37:28 -04:00
Wilson Snyder b51d197117 Fix defparam in generate broke in 3.840, bug543. 2012-08-07 18:24:51 -04:00
Wilson Snyder e4f0a8952c Fix double-deep parameter cell WIDTHs, bug541. 2012-08-02 07:02:57 -04:00
Wilson Snyder 072ee425f4 Fix previous mis-commit 2012-08-02 07:00:12 -04:00
Wilson Snyder a4c2819be2 Commentary 2012-07-31 19:23:19 -04:00
Wilson Snyder 2a274f9c19 Devel version 2012-07-31 18:53:51 -04:00
Wilson Snyder b4d5a20670 Version bump 2012-07-31 18:09:00 -04:00
Wilson Snyder 6339159b04 MAJOR: Support packed structures and unions, bug181. 2012-07-29 10:16:20 -04:00
Wilson Snyder aec019991c Tests: Misc fixes from struct branch. 2012-07-28 14:05:30 -04:00
Wilson Snyder 33e6a17747 Internals: Look at tree state instead of back for AstAttr. No functional change. 2012-07-28 10:52:29 -04:00
Wilson Snyder ecf508ec23 Fix replicate verilog dump being backwards 2012-07-28 08:25:27 -04:00
Wilson Snyder a5bcfc0509 Tests: Rename t_structure 2012-07-27 21:14:13 -04:00
Wilson Snyder 1899096ff4 Internals: Width debug and null print check 2012-07-27 21:12:06 -04:00
Wilson Snyder 6e219f5831 Internals: Rework V3WidthSel func for non-vars. No functional change intended. 2012-07-25 07:26:41 -04:00
Jeremy Bennett de1bb5aeb6 Tests: fix driver.pl not tracing time 0, bug536.
Signed-off-by: Wilson Snyder <[email protected]>
2012-07-24 18:48:51 -04:00
Wilson Snyder b52d94273c Internals: Move variable referencing into LinkDot in support of structs. 2012-07-24 06:26:35 -04:00
Wilson Snyder e655c85489 Internals: findBit etc can be const. No functional change. 2012-07-23 21:29:53 -04:00
Wilson Snyder dee7210231 Debug: add GDB dtf function to dump tree to file 2012-07-23 20:21:04 -04:00
Wilson Snyder cbd073ed08 Commentary: pthread 2012-07-23 10:12:43 -04:00
Wilson Snyder 09ebc0c163 Internals: Fix 0x tree debug suffix. Misc merges from struct. No functional change. 2012-07-22 22:48:39 -04:00
Wilson Snyder d2ede75c71 Fix compile error under git submodules, bug534. 2012-07-22 19:51:14 -04:00
Wilson Snyder 3e03fef3e3 Tests: Add t_var_notfound_bad 2012-07-22 09:09:53 -04:00
Wilson Snyder 0f583f4b33 Internals: Remove dead varref code, part of last change. 2012-07-21 21:23:57 -04:00
Wilson Snyder f175db74a5 Internals: Rework implicit handling to make room for ParseRef vs. VarRef 2012-07-21 21:18:07 -04:00
Wilson Snyder 8d5e37a413 Internals: Move trace check up. No functional change. 2012-07-21 20:33:24 -04:00
Wilson Snyder 8b9b7178a2 Internals: MAJOR CHANGE. Combine V3Link and V3LinkDot stages for structures.
Functionality should be similar, but may introduce instability in resolving variables/cells.
Final merge from dot.
2012-07-21 17:12:42 -04:00
Wilson Snyder a2f49063e2 Internals: Rename LinkDot methods. Merge from dot. No functional change 2012-07-21 09:27:57 -04:00
Wilson Snyder f3f34baa73 debug: Avoid identical skip in driver debug 2012-07-21 09:16:19 -04:00
Wilson Snyder abe9ecd225 Internals: Move AstBegin code below GenFor. No functional change. 2012-07-21 07:28:39 -04:00
Wilson Snyder 67409af38d Fix valgrind uninitialized bits. 2012-07-19 22:26:15 -04:00
Wilson Snyder b7d1c34aa6 Internals: Add more sym table debug, renames. Merge from dot. No functional change 2012-07-19 21:18:39 -04:00
Wilson Snyder 92809b95c9 driver: Sort results. Merge from dot. 2012-07-19 21:02:36 -04:00
Wilson Snyder b18690cbe2 Linking renames. Merge from dot. No functional change. 2012-07-17 21:29:10 -04:00
Wilson Snyder 96155365b2 Fix GCC 4.7.0 compile warnings, bug530. 2012-07-15 12:27:36 -04:00
Wilson Snyder 3e5067feb1 Fix svdpi.h for apple. 2012-07-15 11:33:27 -04:00
Wilson Snyder 3ec687a0cf Internals: Merge from struct branch, rework LinkDot symbol table. No functional change intended. 2012-06-20 06:13:28 -04:00
Wilson Snyder 365034d7dd Internals: Merge from struct branch, rename SymTable calls. No functional change intended. 2012-06-20 06:09:07 -04:00
Wilson Snyder 09aa9f87d8 Internals: Move initial resolution to V3LinkParse. No functional change intended. 2012-06-13 23:08:45 -04:00
Wilson Snyder 97963fb8c9 Internals: Move DECLFILENAME code to LinkCells. 2012-06-13 22:18:12 -04:00
Wilson Snyder ee1643ce39 Fix false UNUSED warning on file system calls. 2012-06-03 08:20:12 -04:00
Wilson Snyder a82cdcfe48 Add --converge-limit option. 2012-05-31 18:56:31 -04:00
Wilson Snyder 1b439703ff Fix leak issues, bug521 2012-05-30 23:17:55 -04:00
Wilson Snyder 4cc5943f90 Leak fix - Null sense item shouldn't disable event 2012-05-30 23:15:25 -04:00
Wilson Snyder 5fad666678 Fix +: and -: memory leak. 2012-05-29 23:16:13 -04:00
Wilson Snyder e12bf35996 Fix leak check compile and run, bug521. 2012-05-29 22:59:17 -04:00
Wilson Snyder d34fccec22 Internals: Remove typedefFwd earlier to simplify Link 2012-05-28 10:23:47 -04:00
Wilson Snyder 429437f1b9 Internals: Reorder code. No functional change. 2012-05-28 09:19:51 -04:00
Wilson Snyder c6e7d87960 Commentary - Remove author lines as amany contributors now 2012-05-24 19:19:48 -04:00
Wilson Snyder 716320f3ca Extra debug check 2012-05-24 19:15:28 -04:00
Wilson Snyder 1d12b47cb8 Fix internal readWholefile error check, bug518. 2012-05-22 10:20:35 -04:00
Wilson Snyder 1bc1ee9e08 Fix duplicate warnings/errors, bug516. 2012-05-21 21:31:52 -04:00
Wilson Snyder 53f50463bc Internals: Add warnMore() for all continued messages. 2012-05-21 21:24:17 -04:00
Jeremy Bennett 7ab91e660f Tests: Add t_sv_enum_type_methods, bug515.
Signed-off-by: Wilson Snyder <[email protected]>
2012-05-21 18:39:45 -04:00
Wilson Snyder 2f0e230522 Tests: New struct tests. Merge from branch. 2012-05-16 22:27:59 -04:00
Wilson Snyder 280f674ce9 Fix signed extending biops with WIDTH warning off, bug511. 2012-05-16 22:18:52 -04:00
Wilson Snyder a92c66d512 Internals: Pass expected dtype in width. No functional change intended. 2012-05-16 20:58:15 -04:00
Wilson Snyder c45eedcb02 Tests: New t_inst_signed test 2012-05-16 20:21:02 -04:00
Wilson Snyder a9a49345ba Fix loop error message to report line, bug513. 2012-05-16 19:31:24 -04:00
Wilson Snyder 8d960a2eb9 Tests: Add t_sv_cpu, bug473. By Jeremy Bennett. 2012-05-16 18:38:01 -04:00
Wilson Snyder 3e623b8959 Fix GCC 4.6.3 warning 2012-05-15 19:28:07 -04:00
Wilson Snyder 1b1991d53d Fix output with select hitting tristate, bug514. 2012-05-15 19:26:20 -04:00
Wilson Snyder 6d0f39d841 Fix sign-extension underneath boolean operators. (In theory shouldn't matter, since comparing to zero.) 2012-05-11 18:26:45 -04:00
Wilson Snyder 3087501b6c Tests: file_grep prints failing expected value when possible. 2012-05-11 18:24:49 -04:00
Wilson Snyder b429319bc0 Portability fixes for gcc 4.6.3 2012-05-10 22:04:53 -04:00
Wilson Snyder 247e855dbf Fix not showing internal error when no coredump. 2012-05-10 21:58:02 -04:00
Wilson Snyder 1aec645510 Internals: Fix dead parameter calls. No functional change. 2012-05-09 23:06:43 -04:00
Wilson Snyder 3ea2038d3d Internals: Fix dead parameter calls. No functional change. 2012-05-09 23:04:20 -04:00
Wilson Snyder 942cb5e87e Internals: Make findDtype functions use this. No functional change. 2012-05-09 22:12:57 -04:00
Wilson Snyder 37a3a7cdce Fix tristate bug512, broken with tristate commit. 2012-05-09 20:34:15 -04:00
Wilson Snyder 435a27b66a Tristate: Major rework to support Z tieoffs, bug499, bug510. 2012-05-08 21:53:22 -04:00
Wilson Snyder b31a7cdcbf Internals: Fix uninitialized m_alhs 2012-05-08 20:05:43 -04:00
Wilson Snyder ac61548e6a Optimize tristate structure OR(AND(x,y),AND(z,y)). 2012-05-08 19:20:23 -04:00
Wilson Snyder f5ace0f72a Tests: Add bug508, bug509 examples 2012-05-08 17:41:42 -04:00
Wilson Snyder e498b73933 Internals: Misc tristate merges. Pins renamed but... No functional change intended. 2012-05-07 23:43:19 -04:00
Wilson Snyder ff69bdbc6f Debug: Add @ to end of dtype to avoid miscutting 2012-05-07 19:01:45 -04:00
Wilson Snyder 0c1e184cb7 Fix newlines in radix values, bug507. 2012-05-07 08:58:29 -04:00
Wilson Snyder e97541dcbc Internals: Minor tristate changes from branch. No functional change. 2012-05-06 16:52:08 -04:00
Wilson Snyder 7b3eb22865 Fix compile warning 2012-05-06 14:05:56 -04:00
Wilson Snyder d55f065ce2 Internals: Tristate join AND/OR visitor pull setter. No functional change 2012-05-05 15:04:33 -04:00
Wilson Snyder 86af244636 Internals: Tristate common pull setter. No functional change 2012-05-05 15:03:00 -04:00
Wilson Snyder 2c9e2b2e3c Internals: Common insert function in tristate. No functional change. 2012-05-05 14:55:35 -04:00
Wilson Snyder 33c8bf886e Debug: Assume PDF output for dot. 2012-05-05 14:50:11 -04:00
Wilson Snyder ef71a089a6 Internals: Spacing. No functional change 2012-05-05 14:49:43 -04:00
Wilson Snyder 5fc98cce0d Fix parameters not supported in constant functions, bug474. 2012-05-03 21:59:47 -04:00
Wilson Snyder b9101c3d6a Better message for display-like format warnings, bug500. 2012-05-02 21:04:50 -04:00
Wilson Snyder 6aab0f627c Fix input and real loosing real data type, bug501. 2012-05-02 20:53:38 -04:00
Wilson Snyder 6b97673d0a Internals: Fix dtype() dead code drop on assign varrefs 2012-05-02 20:53:19 -04:00
Wilson Snyder 5d8c1ce84e Internals: Avoid broken recusion 2012-05-02 20:52:10 -04:00
Wilson Snyder 33c9591a4b Internals: Move widthPow2. No functional change. 2012-04-29 11:34:25 -04:00
Wilson Snyder 87e8736823 IMPORTANT: Major internal changes for supporting complex data types.
Adds dtype() to every node, keep global table of dtypes and remove duplicates.
Final merge from dtype branch.
2012-04-29 10:14:13 -04:00
Wilson Snyder c0da16bfcd Internals: Create dtypeFrom. Merge from dtype. No functional change. 2012-04-29 09:42:17 -04:00
Wilson Snyder a4ddc5b3ac Internals: Create user1SetOnce(). No functional change. 2012-04-29 08:55:33 -04:00
Wilson Snyder 91e4010039 Internals: Rename AstRefDType subDTypep. Merge from dtype. No functional change. 2012-04-29 08:38:53 -04:00
Wilson Snyder 486b6580d8 Internals: Rename VSignedState. Merge from dtype. No functional change. 2012-04-29 08:30:02 -04:00
Wilson Snyder 9c4ef27d49 Internals: Cleanup dead function names. Merge from dtype. No functional change. 2012-04-29 08:24:32 -04:00
Wilson Snyder 33577eaa68 Tests: Less sensitivity to XML change 2012-04-29 08:23:24 -04:00
Wilson Snyder d5e19661bd Debug: Tree compare between versions; merge from dtype branch. No functional change. 2012-04-28 13:00:44 -04:00
Wilson Snyder 799afac05b Internals: V3Hashed cleanups; merge from dtype branch. No functional change. 2012-04-28 12:33:51 -04:00
Wilson Snyder 3ba36dc30c Debugging: Show tree file writes, commentary 2012-04-28 12:22:38 -04:00
Wilson Snyder 641024c235 Fix generated inouts with duplicated modules, bug498. 2012-04-27 19:41:13 -04:00
Wilson Snyder d9598db117 Internals: In debug dumps, show user pointers 2012-04-27 19:01:08 -04:00
Wilson Snyder 2e4da07a15 Fix ITOD internal error on real conversions, bug491. 2012-04-26 22:30:22 -04:00
Wilson Snyder 40f4411b69 Fix tristate connection to unconnected input, bug494, bug495. 2012-04-26 21:11:48 -04:00
Wilson Snyder c75de0f37c Add INITIALDLY warning on initial assignments, bug478. 2012-04-26 20:40:13 -04:00
Wilson Snyder 74c4c1bf44 Internals: Pass unconnected pins through structures. No functional change intended. 2012-04-26 19:01:11 -04:00
Wilson Snyder 60a637921c Add PINMISSING and PINNOCONNECT lint checks. 2012-04-26 18:46:44 -04:00
Wilson Snyder 22312b3c9c Internals: Remove dead code. No functional change intended. 2012-04-26 18:42:02 -04:00
Wilson Snyder 2e26e44538 Commentary, bug497. Merge from Bennett. 2012-04-26 07:10:49 -04:00
Wilson Snyder 24e79ecc68 Fix coredump on constant connect 2012-04-25 22:51:31 -04:00
Wilson Snyder 5b532a1812 Fix generate if, broke in earlier committ, bug492. Merge from Bennett. 2012-04-25 18:17:10 -04:00
Wilson Snyder f3867d7f80 Fix imports causing symbol table error, bug490. 2012-04-24 21:21:26 -04:00
Wilson Snyder fb90e47e70 Tests: Add t_udp_noname, bug468 2012-04-24 20:43:15 -04:00
Wilson Snyder 68046244dd Fix 'output tri0' 2001 declaration; Var characteristics must be attributes 2012-04-24 07:45:02 -04:00
Wilson Snyder b1507060ad Fix output with tri1, but489 2012-04-24 07:12:51 -04:00
Wilson Snyder ffbd595d88 Support nmos and pmos, bug488. 2012-04-23 20:13:07 -04:00
Wilson Snyder ed5bc1e69c Internals: Rename arrayp to rangep(). No functional change intended. 2012-04-22 19:18:51 -04:00
Wilson Snyder 9734931f67 IMPORTANT: Rewrite tristate handling, tri0, tri1, etc. 2012-04-21 21:45:28 -04:00
Wilson Snyder 0048b04540 Merge from Tristate branch, part 1 of 2. No functional change intended 2012-04-21 19:30:08 -04:00
Wilson Snyder c361932fe2 Commentary: Test documentation, bug486. Merge from Bennett. 2012-04-21 12:58:46 -04:00
Wilson Snyder 2d8feabe54 Fix generate operators not short circuiting, bug413. Merge from Jeremy Bennett. 2012-04-19 22:53:52 -04:00
Wilson Snyder 1b511dd130 Internals: Add opLogIf(f). No functional change. Merge from Jeremy Bennet. 2012-04-19 21:02:08 -04:00
Wilson Snyder 52024f4d80 Makefile: Correct tag file selection. Merge from Jeremy Bennet. 2012-04-19 21:00:58 -04:00
Wilson Snyder 735fa6287f Fix linking suppressing duplicate var and block name errors 2012-04-19 20:51:21 -04:00
Wilson Snyder 7eb407fe2b driver.pl: Add --no-verilation option 2012-04-16 20:28:24 -04:00
Wilson Snyder 897d5c58b3 Devel version 2012-04-16 20:20:58 -04:00
Wilson Snyder dc9086512b Doxygen logo and commentary 2012-04-16 07:31:27 -04:00
Wilson Snyder 0029d068c7 Version bump 2012-04-15 16:21:31 -04:00
Wilson Snyder de388b3dc8 Part of last commit 2012-04-15 16:14:18 -04:00
Wilson Snyder fb904d53cd Add doxygen comments, bug482 2012-04-15 15:44:32 -04:00
Wilson Snyder 600cc02de3 Commentary 2012-04-15 15:08:13 -04:00
Wilson Snyder 946d0cd219 Add readme.pdf and internal.pdf 2012-04-15 14:51:04 -04:00
Wilson Snyder 4d0b964e36 Internals: Merge from dtype. Create subDTypep. No functional change intended. 2012-04-14 12:43:03 -04:00
Wilson Snyder 2b12ab4d5a Internals: Merge from dtype. Add hasDType; still unused. No functional change. 2012-04-14 11:03:38 -04:00
Wilson Snyder 8114957e6d Internals: Merge from dtype. Rename isSigned to dtypeChgSigned. No functional change. 2012-04-14 10:45:24 -04:00
Wilson Snyder 50edef4ab2 Add Emacs indentation line. No functional change 2012-04-12 21:08:20 -04:00
Wilson Snyder e5a991988f Tests added 2012-04-12 20:13:35 -04:00
Wilson Snyder e85eb6d0f4 Tests: Add t_enum_type_methods, bug473 2012-04-12 18:21:08 -04:00
Wilson Snyder 6949f35f22 Tests: Add t_array_query, t_sv_conditional, bug473 2012-04-12 18:15:39 -04:00
Wilson Snyder e0391b93c4 Commentary 2012-04-12 06:48:02 -04:00
Wilson Snyder 4a5e775a2b Fix change detections on arrays. 2012-04-09 20:17:51 -04:00
Wilson Snyder 323f019350 Tests: Add t_interface, bug481. Merge from JERAS/test_sv. 2012-04-08 18:13:56 -04:00
Wilson Snyder 98053c2d4c Tests: Add t_param_type, bug480. Merge from JERAS/test_sv. 2012-04-08 17:59:46 -04:00
Wilson Snyder aab338760c Increase VL_VALUE_STRING_MAX_WIDTH, bug479 2012-04-05 21:46:55 -04:00
Wilson Snyder ab9a2b1728 Internal: Prevent possible buffer overrun 2012-04-05 21:46:03 -04:00
Wilson Snyder 6a38d3bcf3 Add SELRANGE as warning instead of error, bug477. 2012-04-04 21:55:20 -04:00
Wilson Snyder 76f3cbdf4c Merge branch 'master' of ssh://git-verilator-wsnyder/git/verilator 2012-04-02 22:05:40 -04:00
Wilson Snyder d45d58b6bf Fix real constant parameter functions, bug475. 2012-04-02 21:58:40 -04:00
Wilson Snyder f32a422330 Tests: New test 2012-04-02 19:38:42 -04:00
Wilson Snyder 74d4be28dd Commentary 2012-04-02 07:17:37 -04:00
Wilson Snyder b4a31bd292 Internals: Merge AstCCast minwidth set. No functional change intended 2012-04-01 21:17:58 -04:00
Wilson Snyder cc1adf9b38 Internals: merge V3Hashed cleanups. No functional change intended 2012-04-01 21:04:28 -04:00
Wilson Snyder 1601b3b6b0 Internals: Merge VFlagChildDtype calls. No functional change intended. 2012-03-31 11:22:19 -04:00
Wilson Snyder 61cbdd1a19 Internals: Merge VFlag rename. No functional change. 2012-03-31 11:10:34 -04:00
Wilson Snyder a3ee6131a3 Internals: Merge using dtypeSetLogicSized. No functional change intended 2012-03-31 10:53:53 -04:00
Wilson Snyder 6dfddaa453 Internals: Rename dtypeChg to dtypeSet. No functional change 2012-03-31 10:19:27 -04:00
Wilson Snyder de696b7092 Debug: Print dtype big endian correctly 2012-03-30 21:50:37 -04:00
Wilson Snyder 9165233657 Fix OpenSolaris compile error. 2012-03-30 07:26:00 -04:00
Wilson Snyder aa3a417e97 Tests: Add t_dpi_accessors 2012-03-27 20:06:59 -04:00
Wilson Snyder 996f48fcf0 Fix processing unused parametrized modules, bug470. 2012-03-24 15:54:06 -04:00
Wilson Snyder 81d83f629f Tests: default_nettype is ok 2012-03-24 15:15:32 -04:00
Wilson Snyder 5e3b0bf348 tests: Add unsupported as target type; additional tests 2012-03-24 11:10:17 -04:00
Wilson Snyder 4a31463299 Fix genvar and begin under generate, bug461. 2012-03-23 08:49:47 -04:00
Wilson Snyder 8a5471e175 Tests: skip test for bug462 2012-03-22 22:35:24 -04:00
Wilson Snyder 605fd9f8e1 Tests: Skip test for bug461 2012-03-22 22:15:35 -04:00
Wilson Snyder 2bda43875d Support += and -= in standard for loops, bug463. 2012-03-22 21:02:38 -04:00
Wilson Snyder 11edc9e7a7 Debug: Add --dump-treei option 2012-03-20 22:45:35 -04:00
Wilson Snyder 3b9b823511 tests: Fix missing manifest from earlier test commit 2012-03-20 22:45:00 -04:00
Wilson Snyder da0ecf59c6 Tests: Rename t_mem_packed_assign_bad since fails 2012-03-20 20:55:16 -04:00
Wilson Snyder e5b1fdf668 Tests: Added additional SystemVerilog tests.
Squashed commit of the following:

commit c1eeda7d472fc14a0ffd5c1712ae7f7c614073a1
Author: Iztok Jeras <[email protected]>
Date:   Tue Mar 20 16:39:44 2012 +0100

- fixed assignment operator in t_array_packed_write_read.v from = to <=
- added tests for enumerations (existing tests do not use methods like
next(), num(), ...)
- added t_sv_bus_mux_demux test, with packed arrays, structures and unions
2012-03-20 19:28:35 -04:00
Wilson Snyder 204fb82975 Add very experimental --xml option 2012-03-20 16:13:10 -04:00
Wilson Snyder 37839e2709 Cleanup trailing whitespace. No functional change 2012-03-20 16:01:53 -04:00
Wilson Snyder dbaedb5995 Internals: Add XML output internals, unused. No functional change. 2012-03-20 15:57:29 -04:00
Wilson Snyder 0a832e90bd Internals: Rename left/right to match IEEE. No functional change. 2012-03-19 21:32:05 -04:00
Wilson Snyder b4e908d04d Fix warning on gcc 4.6.1 2012-03-16 18:06:32 -04:00
Wilson Snyder 4619d29b78 Commentary; bug457 2012-03-15 18:44:08 -04:00
Wilson Snyder c63b697636 Fix signed array warning, bug456. 2012-03-12 20:29:00 -04:00
Wilson Snyder 06d29d6fda Commentary 2012-03-10 10:56:48 -05:00
Wilson Snyder c0f7bc4b5e Tests: Parameter bug case 2012-03-09 19:35:37 -05:00
Wilson Snyder 7139c9ae59 Fix and document --gdb option, bug454. 2012-03-09 18:37:38 -05:00
Wilson Snyder 0ae00fc921 Commentary; bug452. 2012-03-08 18:36:51 -05:00
Wilson Snyder fe456cb83d Devel version 2012-03-07 23:02:24 -05:00
Wilson Snyder a8432ed4a4 Version bump 2012-03-07 22:50:13 -05:00
Wilson Snyder 04f910b747 Fix V3Tristate t_tri_select crash 2012-03-07 22:42:47 -05:00
Wilson Snyder 1c3de70155 Internals: Debug merge. No functional change 2012-03-07 21:48:02 -05:00
Wilson Snyder b73642f8a8 Report ENDLABEL on mismatching end labels, bug450. 2012-03-07 20:14:18 -05:00
Wilson Snyder 479b497528 Tests: Add new tests from Iztok Jeras, bug446, bug450. 2012-03-07 20:00:09 -05:00
Wilson Snyder 31b55d3844 Tests: Fix running different simulators simultaneously 2012-03-06 20:58:23 -05:00
Wilson Snyder dbf4e08d09 Tests 2012-03-06 20:12:47 -05:00
Wilson Snyder 274359e6ee Tests: Bit extraction from non-logic types 2012-03-04 17:17:57 -05:00
Wilson Snyder 8687dcbce1 Internals: Add isRanged, more debug. No functional change. 2012-03-04 16:18:41 -05:00
Wilson Snyder 03dfbdb7b1 Fix inheriting signed type across untyped parameters. 2012-03-03 21:03:34 -05:00
Wilson Snyder 3c8519f245 Fix inheriting real type across untyped parameters. 2012-03-03 16:29:06 -05:00
Wilson Snyder 4d2cc3ebdd Tests: New param value test 2012-03-03 15:44:56 -05:00
Wilson Snyder 6e2758ae26 Internals: Minor refactorings from dtype branch. No functional change. 2012-03-03 12:10:29 -05:00
Wilson Snyder 4637e06ad2 Fix backward widths in function output warning 2012-03-03 12:09:01 -05:00
Wilson Snyder 764399256c Internals: Rename gdb dump utilities, add fileline dump 2012-03-03 11:29:09 -05:00
Wilson Snyder f4ca4edc64 Debug: Add default .gdbinit file 2012-03-02 20:59:47 -05:00
Wilson Snyder 872a1216a7 Internals: Fix enum widthTotalBytes. 2012-03-02 06:58:19 -05:00
Wilson Snyder 8c75674591 Internals: V3Dead: Avoid iterating over vars we can't remove. 2012-02-29 23:05:11 -05:00
Wilson Snyder e6244ca204 Internals: Move dimension accessors from AstVar to AstNodeDType. 2012-02-28 21:33:17 -05:00
Wilson Snyder f540362e36 Fix expansion of back-slashed escaped macros, bug441. 2012-02-25 21:31:36 -05:00
Wilson Snyder 2be6699a6a Internals: Make covergroup parsing closer to normal types 2012-02-23 22:09:51 -05:00
Wilson Snyder 09c10492ab Fix hang on recursive substitution `defines, bug443. 2012-02-23 21:54:37 -05:00
Wilson Snyder c8e4b1fc84 Fix functions inside generate for block. 2012-02-21 22:23:06 -05:00
Wilson Snyder 0de7cece5b Fix hang when functions inside begin block. 2012-02-21 21:25:11 -05:00
Wilson Snyder a3413a6749 Merge branch 'master' of ssh://git-verilator-wsnyder/git/verilator 2012-02-21 08:03:07 -05:00
Wilson Snyder b104ab9491 Internals: AstRefDType points to type _below_ AstTyperef. No functional change 2012-02-21 07:27:17 -05:00
Wilson Snyder 269c5dce60 Internals: Use dtypeChgLogicBool(). No functional change. 2012-02-20 20:51:24 -05:00
Wilson Snyder a39c81c63f Internals: Remove width() on AstCaseItem. No functional change. 2012-02-20 16:48:52 -05:00
Wilson Snyder d699247269 Internals: In AstBasicDType avoid use of Range for constants. No functional change. 2012-02-20 11:48:31 -05:00
Wilson Snyder 7caafb4014 Internals: Use dtype functions; changes to integer to match spec 2012-02-20 09:55:20 -05:00
Wilson Snyder f1546abf09 Fix error when using UDPs without --bbox-unsup 2012-02-20 09:02:59 -05:00
Wilson Snyder 3083562f6f tests: Avoid massive make parallelism. 2012-02-17 21:40:52 -05:00
Wilson Snyder da2ee70462 Makefile: Print build done in right parallel spot 2012-02-16 20:39:13 -05:00
Wilson Snyder 7e9dda3c5e Fix false command not found warning in Makefiles. 2012-02-16 07:17:08 -05:00
Wilson Snyder 0b96f88875 Fix bisonpre documentation 2012-02-12 20:53:43 -05:00
Wilson Snyder f13ffe2098 Internals: Merge from VHDL branch. Minor stuff, no functional change. 2012-02-11 20:40:58 -05:00
Wilson Snyder bca5d26583 Backout ca927fe5; snps isn't supported in DC. 2012-02-10 22:36:19 -05:00
Wilson Snyder 660bc757f1 Tests: Remove debug 2012-02-04 20:00:36 -05:00
Wilson Snyder ca927fe587 Support snps directives 2012-02-02 10:26:45 -05:00
Wilson Snyder 9df8966f4a Support arrayed SystemC I/O pins. 2012-02-01 20:20:43 -05:00
Wilson Snyder 3429f41489 Typo 2012-01-29 18:26:39 -05:00
Wilson Snyder 0c7c4924ee Fix core dump with over 100 deep UNOPTFLAT, bug432. 2012-01-26 20:20:23 -05:00
Wilson Snyder 8f40d6617e For generated variables, opt towards 2-state so zero init 2012-01-26 08:29:55 -05:00
Wilson Snyder af9e85bda1 Fix memory delayed assignments from multiple clock domains. 2012-01-26 08:10:50 -05:00
Wilson Snyder 717f45d117 Devel version 2012-01-25 19:23:58 -05:00
Wilson Snyder 35c53865fb Check c style array 2012-01-25 19:23:41 -05:00
Wilson Snyder a1d1d6d3d4 Version bump 2012-01-20 07:02:39 -05:00
Wilson Snyder d17f812827 Fix BLKSEQ warnings on variables declared inside always. 2012-01-19 21:15:21 -05:00
Wilson Snyder 3916758529 readme.texi is very old 2012-01-19 20:32:32 -05:00
Wilson Snyder 2396181bc5 Add SYSTEMC_INCLUDE and SYSTEMC_LIBDIR 2012-01-19 20:30:41 -05:00
Wilson Snyder 6e8640bf1b SystemC 2.3.0 support 2012-01-19 19:48:37 -05:00
Wilson Snyder c2c7c7bd9a Copyright year update 2012-01-15 10:26:28 -05:00
Wilson Snyder 071a1c4adb Internals: Fix cppcheck warning 2011-12-27 12:15:20 -05:00
Wilson Snyder d5b2dda2e8 Fix loop iterator 2011-12-26 18:32:40 -05:00
Wilson Snyder 2ac281eb3e Commentary 2011-12-23 19:32:56 -05:00
Wilson Snyder 5e81543448 Internals: Use width when widthMin is the same. No functional change intended 2011-12-22 21:10:28 -05:00
Wilson Snyder b32f925468 Internals: remove extra width sets 2011-12-22 19:08:49 -05:00
Wilson Snyder fdeb6bcae0 Internals: Progress towards proper short-circuit evaluation 2011-12-22 08:33:16 -05:00
Wilson Snyder 76232cd9e7 Internals: Separate pure from branching. No functional change. 2011-12-15 22:23:11 -05:00
Wilson Snyder 4da9b5e491 Internals: Rename isSplittable->isPure. No functional change 2011-12-15 19:13:54 -05:00
Wilson Snyder c4504a9221 tests: Fix t_dist_install breaking corunning test 2011-12-15 18:39:51 -05:00
Wilson Snyder 65de8359e7 Internals: Comment out unused code, no funtional change 2011-12-15 18:39:29 -05:00
Wilson Snyder f6fab74436 tests: GHDL test driver support 2011-12-09 19:58:14 -05:00
Wilson Snyder 350ba264e8 Internals: Create bools/doubles with dtypeChg functions. No functional change. 2011-11-30 19:32:33 -05:00
Wilson Snyder 29e24818a1 Internals: Rename and cleanup some width() usages. No functional change. 2011-11-30 18:50:21 -05:00
Wilson Snyder 71cd6f7b90 Spelling fixes 2011-11-30 18:20:19 -05:00
Wilson Snyder 84ba253791 Last commit - don't allow error overrides if not lint 2011-11-30 18:07:11 -05:00
Wilson Snyder fce158b8ad Make DETECTARRAY so can turn off for lint 2011-11-30 16:20:43 -05:00
Wilson Snyder da13ba6c67 Internals: Use elementsConst for AstRange width. 2011-11-30 07:51:05 -05:00
Wilson Snyder 7618133298 Internals: Renames towards common dtype. No functional change. 2011-11-29 22:36:51 -05:00
Wilson Snyder 0d1698f81d Internals: Allow v3Global in V3Ast.h. No functional change. 2011-11-29 22:29:16 -05:00
Wilson Snyder 362d642c87 Support "generate for (genvar i=0; ...". 2011-11-29 18:23:18 -05:00
Wilson Snyder e4c96d5be5 Fix array of instantiations with sub-range output, bug414. 2011-11-28 22:10:43 -05:00
Wilson Snyder f488701adc Fix dpi exports with > 32 bit but < 64 bit args, bug423. 2011-11-28 21:15:57 -05:00
Wilson Snyder 8ff2bf51c5 Merge branch 'master' of ssh://git-verilator-wsnyder/git/verilator 2011-11-28 09:48:14 -05:00
Wilson Snyder a2490a55a9 tests: Test $countones on other simulators 2011-11-28 09:48:01 -05:00
Wilson Snyder 20189f5191 Fix empty generate region, bug422. 2011-11-28 07:49:36 -05:00
Wilson Snyder 06b796c6bd Suppress VARHIDDEN on dpi import arguments. 2011-11-27 12:03:22 -05:00
Wilson Snyder ad4edf6c68 Postrelease 2011-11-27 10:39:30 -05:00
880 changed files with 48216 additions and 9052 deletions
+3 -1
View File
@@ -9,15 +9,17 @@
.*.swp
*.tmp
*.tex
*.pdf
/Makefile
README
TAGS
autom4te.cache
config.cache
config.status
configure
dddrun*
doxygen-doc
gdbrun*
internals.txt
verilator.pdf
verilator.txt
verilator_bin*
+422 -4
View File
@@ -3,6 +3,424 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.860 2014-05-11
** PSL is no longer supported, please use System Verilog assertions.
** Support '{} assignment pattern on arrays, bug355.
** Support streaming operators, bug649. [Glen Gibb]
** Fix expression problems with -Wno-WIDTH, bug729, bug736, bug737, bug759.
Where WIDTH warnings were ignored this might result in different
warning messages and results, though it should better match the spec.
[Clifford Wolf]
*** Add --no-trace-params.
*** Add assertions on 'unique if', bug725. [Jeff Bush]
*** Add PINCONNECTEMPTY warning. [Holger Waechtler]
*** Support parameter arrays, bug683. [Jeremy Bennett]
*** Fix begin_keywords "1800+VAMS", msg1211.
**** Documentation fixes, bug723. [Glen Gibb]
**** Support {} in always sensitivity lists, bug745. [Igor Lesik]
**** Fix tracing of package variables and real arrays.
**** Fix tracing of packed arrays without --trace-structs, bug742. [Jie Xu]
**** Fix missing coverage line on else-if, bug727. [Sharad Bagri]
**** Fix modport function import not-found error.
**** Fix power operator calculation, bug730, bug735. [Clifford Wolf]
**** Fix reporting struct members as reserved words, bug741. [Chris Randall]
**** Fix change detection error on unions, bug758. [Jie Xu]
**** Fix -Wno-UNOPTFLAT change detection with 64-bits, bug762. [Clifford Wolf]
**** Fix shift-right optimization, bug763. [Clifford Wolf]
**** Fix Mac OS-X test issues. [Holger Waechtler]
**** Fix C++-2011 warnings.
* Verilator 3.856 2014-03-11
*** Support case inside, bug708. [Jan Egil Ruud]
*** Add parameters into trace files, bug706. [Alex Solomatnikov]
**** Fix parsing "#0 'b0", bug256.
**** Fix array bound checks on real variables.
**** Fix --skip-identical mis-detecting on OS-X, bug707.
**** Fix missing VL_SHIFTRS_IQI with WIDTH warning, bug714. [Fabrizio Ferrandi]
**** Fix signed shift right optimization, bug715. [Fabrizio Ferrandi]
**** Fix internal error on "input x =" syntax error, bug716. [Lane Brooks]
**** Fix slice extraction from packed array, bug717. [Jan Egil Ruud]
**** Fix inside statement EQWILD error, bug718. [Jan Egil Ruud]
* Verilator 3.855 2014-01-18
*** Support modport import, bug696. [Jeremy Bennett]
*** Add --trace-structs to show struct names, bug673. [Chris Randall]
**** Fix tracing of packed structs, bug705. [Jie Xu]
**** Fix --lint-only with MinGW, msg1283. [HyungKi Jeong]
**** Fix some delayed assignments of typedefed unpacked arrays.
**** Fix wire declarations with size and not range, bug466. [Alex Solomatnikov]
**** Fix parameter pin vs. normal pin error, bug704. [Alex Solomatnikov]
* Verilator 3.854 2013-11-26
*** Add UNPACKED warning to convert unpacked structs. [Jeremy Bennett]
*** Add --compiler clang to work around compiler bug, bug694. [Stefan Ludwig]
**** Support vpi_get of vpiSuppressVal, bug687. [Varun Koyyalagunta]
**** Support vpi_get_time, bug688. [Varun Koyyalagunta]
**** Fix evaluation of chained parameter functions, bug684. [Ted Campbell]
**** Fix enum value extension of '1.
**** Fix multiple VPI variable callbacks, bug679. [Rich Porter]
**** Fix vpi_get of vpiSize, bug680. [Rich Porter]
**** Fix vpi_remove_cb inside callback, bug689. [Varun Koyyalagunta]
**** Fix crash with coverage of structures, bug691. [Eivind Liland]
**** Fix array assignment from const var, bug693. [Jie Xu]
* Verilator 3.853 2013-09-30
**** Add --no-order-clock-delay to work around bug613. [Charlie Brej]
* Verilator 3.852 2013-09-29
*** Support named function and task arguments. [Chris Randall]
*** Report SELRANGE warning for non-generate if, bug675. [Roland Kruse]
**** Fix ordering of $fgetc, msg1229. [Frederic Requin]
**** Fix --output-split-cfunc to count internal functions. [Chris Randall]
**** Fix crash on 32-bit Ubuntu, bug670. [Mark Jackson Pulver]
* Verilator 3.851 2013-08-15
*** Fix ordering of clock enables with delayed assigns, bug613. [Jeremy Bennett]
*** Fix vpi_iterate on memory words, bug655. [Rich Porter]
**** Fix final duplicate declarations when non-inlined, bug661. [Charlie Brej]
**** Fix interface ports with comma lists, msg1058. [Ed Lander]
**** Fix parameter real conversion from integer.
**** Fix clang warnings, bug668. [Yutetsu Takatsukasa]
* Verilator 3.850 2013-06-02
** Support interfaces and modports, bug102. [Byron Bradley, Jeremy Bennett]
*** Duplicate clock gate optimization on by default, bug621.
**** Fix arrayed input compile error, bug645. [Krzysztof Jankowski]
**** Fix GCC version runtime changes, bug651. [Jeremy Bennett]
**** Fix packed array select internal error, bug652. [Krzysztof Jankowski]
* Verilator 3.847 2013-05-11
*** Add ALWCOMBORDER warning. [KC Buckenmaier]
*** Add --pins-sc-uint and --pins-sc-biguint, bug638. [Alex Hornung]
**** Support "signal[vec]++".
**** Fix simulation error when inputs and MULTIDRIVEN, bug634. [Ted Campbell]
**** Fix module resolution with __, bug631. [Jason McMullan]
**** Fix packed array non-zero right index select crash, bug642. [Krzysztof Jankowski]
**** Fix nested union crash, bug643. [Krzysztof Jankowski]
* Verilator 3.846 2013-03-09
** IEEE 1800-2012 is now the default language. This adds 4 new keywords
and updates the svdpi.h and vpi_user.h header files.
*** Add --report-unoptflat, bug611. [Jeremy Bennett]
*** Add duplicate clock gate optimization, msg980. [Varun Koyyalagunta]
Disabled unless -OD or -O3 used, please try it as may get some
significant speedups.
*** Fix wrong dot resolution under inlining. [Art Stamness]
**** Support pattern assignment features, bug616, bug617, bug618. [Ed Lander]
**** Support bind in $unit, bug602. [Ed Lander]
**** Support <number>'() sized casts, bug628. [Ed Lander]
**** Fix DETECTARRAY on packed structures, bug610. [Jeremy Bennett]
**** Fix LITENDIAN on unpacked structures, bug614. [Wai Sum Mong]
**** Fix 32-bit OS VPI scan issue, bug615. [Jeremy Bennett, Rich Porter]
**** Fix opening a VerilatedVcdC file multiple times, msg1021. [Frederic Requin]
**** Fix UNOPTFLAT circular array bounds crossing, bug630. [Jie Xu]
* Verilator 3.845 2013/02/04
*** Fix nested packed arrays and struct, bug600. [Jeremy Bennett]
Packed arrays are now represented as a single linear vector in
Verilated models. This may affect packed arrays that are public or
accessed via the VPI.
*** Support wires with data types, bug608. [Ed Lander]
*** Support bind, to module names only, bug602. [Ed Lander]
*** Support VPI product info, warning calls, etc, bug588. [Rick Porter]
*** Support $left, $right and related functions, bug448. [Iztok Jeras]
*** Support inside expressions.
*** Define SYSTEMVERILOG, SV_COV_START and other IEEE mandated predefines.
**** Fix pin width mismatch error, bug595. [Alex Solomatnikov]
**** Fix implicit one bit parameter selection, bug603. [Jeremy Bennett]
**** Fix signed/unsigned parameter misconversion, bug606. [Jeremy Bennett]
**** Fix segfault on multidimensional dotted arrays, bug607. [Jie Xu]
**** Fix per-bit array output connection error, bug414. [Jan Egil Ruud]
**** Fix package logic var compile error.
**** Fix enums with X values.
* Verilator 3.844 2013/01/09
*** Support "unsigned int" DPI import functions, msg966. [Alex Lee]
*** Fix package resolution of parameters, bug586. [Jeremy Bennett]
**** Fix non-integer vpi_get_value, bug587. [Rich Porter]
**** Fix task inlining under $display and case, bug589, bug598. [Holger Waechtler]
**** Fix package import of non-localparam parameter, bug474, bug591. [Jeremy Bennett]
**** Fix package import of package imports, partial bug592. [Jeremy Bennett]
**** Fix package import preventing local var, bug599. [Jeremy Bennett]
**** Fix array extraction of implicit vars, bug601. [Joe Eiler]
* Verilator 3.843 2012/12/01
*** Add +1364-1995ext and similar language options, bug532. [Jeremy Bennett]
**** Fix mis-optimized identical submodule subtract, bug581. [Charlie Brej]
**** Fix crash on dotted references into dead modules, bug583. [Jeremy Bennett]
**** Fix compile issues on MSVCC, bug571, bug577. [Amir Gonnen]
**** Fix --debug overriding preceding --dump-treei, bug580. [Jeremy Bennett]
* Verilator 3.842 2012/11/03
**** Add -x-initial-edge, bug570. [Jeremy Bennett]
**** Fix parameter pins interspersed with cells broke in 3.840. [Bernard Deadman]
**** Fix large shift error on large shift constants. [David Welch]
**** Fix $display mangling on GCC 4.7 and speed up, msg927, bug373, bug574. [R Diez]
**** Fix array of struct references giving false error, bug566. [Julius Baxter]
**** Fix missing var access functions when no DPI, bug572. [Amir Gonnen]
**** Fix name collision on unnamed blocks, bug567. [Chandan Egbert]
**** Fix name collision on task inputs, bug569. [Chandan Egbert]
* Verilator 3.841 2012/09/03
*** Add --savable to support model save/restore. [Jeremy Bennett]
*** Support '{} assignment pattern on structures, part of bug355.
**** Fix double-deep parameter cell WIDTHs, bug541. [Hiroki Honda]
**** Fix imports under multiple instantiated cells, bug542. [Alex Solomatnikov]
**** Fix defparam in generate broke in 3.840, bug543. [Alex Solomatnikov]
**** Fix duplicate begin error broke in 3.840, bug548. [Alex Solomatnikov]
**** Fix triangle symbol resolution error broke in 3.840, bug550. [Ted Campbell]
* Verilator 3.840 2012/07/31 Beta
** Rewrote tristate handling; supports tri0, tri1, tristate bit selects,
concatenates and pullup/pulldowns, bug395, bug56, bug54, bug51.
[Alex Solomatnikov, Lane Brooks, et al]
** Support packed structures and unions, bug181.
Note this was a major internal change that may lead to some instability.
*** Support tri0 and tri1, bug462. [Alex Solomatnikov]
*** Support nmos and pmos, bug488. [Alex Solomatnikov]
*** Add INITIALDLY warning on initial assignments, bug478. [Alex Solomatnikov]
*** Add PINMISSING and PINNOCONNECT lint checks.
*** Add --converge-limit option.
*** Fix generate operators not short circuiting, bug413. [by Jeremy Bennett]
*** Fix parameters not supported in constant functions, bug474. [Alex Solomatnikov]
**** Fix duplicate warnings/errors, bug516. [Alex Solomatnikov]
**** Fix signed extending biops with WIDTH warning off, bug511. [Junji Hashimoto]
**** Fix ITOD internal error on real conversions, bug491. [Alex Solomatnikov]
**** Fix input and real loosing real data type, bug501. [Alex Solomatnikov]
**** Fix imports causing symbol table error, bug490. [Alex Solomatnikov]
**** Fix newlines in radix values, bug507. [Walter Lavino]
**** Fix loop error message to report line, bug513. [Jeremy Bennett]
**** Fix false UNUSED warning on file system calls.
**** Fix GCC 4.7.0 compile warnings, bug530. [Jeremy Bennett]
**** Fix svdpi.h compile error on Apple OS.
**** Fix compile error under git submodules, bug534. [Aurelien Francillon]
* Verilator 3.833 2012/04/15
*** Support += and -= in standard for loops, bug463. [Alex Solomatnikov]
*** Fix processing unused parametrized modules, bug469, bug470. [Alex Solomatnikov]
**** Add SELRANGE as warning instead of error, bug477. [Alex Solomatnikov]
**** Add readme.pdf and internal.pdf and doxygen, bug483. [by Jeremy Bennett]
**** Fix change detections on arrays, bug364. [John Stevenson, Alex Solomatnikov]
**** Fix signed array warning, bug456. [Alex Solomatnikov]
**** Fix genvar and begin under generate, bug461. [Alex Solomatnikov]
**** Fix real constant parameter functions, bug475. [Alex Solomatnikov]
**** Fix and document --gdb option, bug454. [Jeremy Bennett]
**** Fix OpenSolaris compile error. [Sanjay Singh]
* Verilator 3.832 2012/03/07
*** Fix memory delayed assignments from multiple clock domains. [Andrew Ling]
*** Support arrayed SystemC I/O pins. [Christophe Joly]
*** Report MULTIDRIVEN on memories set in multiple clock domains.
*** Report ENDLABEL on mismatching end labels, bug450. [Iztok Jeras]
**** Fix expansion of back-slashed escaped macros, bug441. [Alberto Del Rio]
**** Fix inheriting real and signed type across untyped parameters.
**** Fix core dump with over 100 deep UNOPTFLAT, bug432. [Joe Eiler]
**** Fix false command not found warning in makefiles. [Ruben Diez]
**** Fix hang when functions inside begin block. [David Welch]
**** Fix hang on recursive substitution `defines, bug443. [Alex Solomatnikov]
* Verilator 3.831 2012/01/20
** Support SystemC 2.3.0 prerelease. This requires setting the new
SYSTEMC_INCLUDE and SYSTEMC_LIBDIR variables in place of now
deprecated SYSTEMC and SYSTEMC_ARCH. [Iztok Jeras]
**** Suppress VARHIDDEN on dpi import arguments. [Ruben Diez]
**** Support "generate for (genvar i=0; ...". [David Kravitz]
**** Fix dpi exports with > 32 bit but < 64 bit args, bug423. [Chandan Egbert]
**** Fix array of instantiations with sub-range output, bug414. [Jeremy Bennett]
**** Fix BLKSEQ warnings on variables declared inside always. [Ruben Diez]
* Verilator 3.830 2011/11/27
@@ -16,7 +434,7 @@ indicates the contributor was also the author of the fix; Thanks!
**** Support $system. [Ruben Diez]
**** Support $sscanf with %g. [Holger Wächtler]
**** Support $sscanf with %g. [Holger Waechtler]
**** Indicate 'exiting due to errors' if errors, not warnings. [Ruben Diez]
@@ -24,7 +442,7 @@ indicates the contributor was also the author of the fix; Thanks!
**** Fix reporting not found modules if generate-off, bug403. [Jeremy Bennett]
**** Fix $display with %d following %g. [Holger Wächtler]
**** Fix $display with %d following %g. [Holger Waechtler]
* Verilator 3.824 2011/10/25
@@ -75,7 +493,7 @@ indicates the contributor was also the author of the fix; Thanks!
*** Support $fopen and I/O with integer instead of `verilator_file_descriptor.
*** Support coverage in -cc and -sc output modes. [John Li]
Note this requires SystemPerl 1.338 or newer.
Note this requires SystemPerl 1.338 or newer.
**** Fix vpi_register_cb using bad s_cb_data, bug370. [by Thomas Watts]
@@ -1975,7 +2393,7 @@ of input ports exists for tracing.
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
Copyright 2001-2011 by Wilson Snyder. This program is free software; you
Copyright 2001-2014 by Wilson Snyder. This program is free software; you
can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License Version 3 or the Perl Artistic License
Version 2.0.
+4
View File
@@ -22,6 +22,7 @@
src/Makefile$
src/Makefile_obj$
include/verilated.mk$
test_regress/.gdbinit$
config.cache$
config.status$
verilator.log
@@ -34,3 +35,6 @@ nodist/
/simv.daidir/
/vc_hdrs.h$
/csrc/
doxygen-doc/.*
TAGS
.*~
+53 -21
View File
@@ -9,7 +9,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
@@ -54,11 +54,13 @@ srcdir = @srcdir@
VPATH = @srcdir@
HOST = @HOST@
DOXYGEN = doxygen
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
MAKEINFO = makeinfo
POD2TEXT = pod2text
POD2LATEXFIX = $(srcdir)/src/pod2latexfix
PERL = @PERL@
# Destination prefix for RPMs
@@ -100,7 +102,8 @@ SHELL = /bin/sh
SUBDIRS = src test_verilated test_c test_sc test_sp test_regress test_vcs
INFOS = README internals.txt verilator.txt verilator.html verilator.1 verilator.pdf
INFOS = README README.html README.pdf internals.txt internals.html \
internals.pdf verilator.txt verilator.html verilator.1 verilator.pdf
# Files that can be generated, but should be up to date for a distribution.
DISTDEP = info Makefile
@@ -110,18 +113,22 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
Changes TODO \
MANIFEST.SKIP \
bin/* \
doxygen-mainpage doxygen.config veripool-logo.png \
install-sh configure mkinstalldirs *.pod \
include/*.[chv]* \
include/*.in \
include/.*ignore \
include/vltstd/*.[chv]* \
.*attributes */.*attributes */*/.*attributes \
src/.*ignore src/*.in src/*.cpp src/*.[chly] src/astgen src/bisonpre src/*fix \
src/.*ignore src/*.in src/*.cpp src/*.[chly] \
src/astgen src/bisonpre src/*fix src/cppcheck_filtered \
src/.gdbinit \
src/*.pl src/*.pod \
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
test_verilated/vgen*.pl \
test_regress/t/tsub/*.v* \
test_regress/t/t*/*.sv* \
test_regress/t/t*/*.v* \
test_regress/t/*.cpp \
test_regress/t/*.h \
test_regress/t/*.dat \
@@ -164,7 +171,7 @@ verilator_exe verilator_bin verilator_bin_dbg:
(cd src && $(MAKE) $(OBJCACHE_JOBS) )
.PHONY:msg_test
msg_test:
msg_test: all_nomsg
@echo "Build complete!"
@echo
@echo "Type 'make test' to test."
@@ -215,15 +222,7 @@ verilator.html: ${srcdir}/bin/verilator
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
verilator.pdf: ${srcdir}/bin/verilator Makefile
pod2latex --full --out verilator.tex ${srcdir}/bin/verilator
cat < verilator.tex \
| sed 's/\\begin{document}/\\usepackage[left=1.7in,right=1.7in,top=1.3in,bottom=1.3in]{geometry}\n\\begin{document}/' \
| sed 's/\\begin{document}/\\usepackage[pdftex,bookmarks=true,bookmarksnumbered=true,hypertexnames=false,breaklinks=true,linkbordercolor={0 0 1}]{hyperref}\n\\begin{document}/' \
| sed 's/\\begin{document}/\\usepackage{fancyhdr} \\pagestyle{fancy}\n\\begin{document}/' \
| sed 's/\\begin{document}/\\setlength{\\parindent}{0pt} \\setlength{\\parskip}{\\baselineskip}\n\\begin{document}/' \
| sed 's/\\begin{document}/\\title{$(DISTTITLE)} \\date{${DISTDATE}} \\author{Wilson Snyder\\\\ http:\/\/www.veripool.org}\n\\begin{document}/' \
| sed 's/\\begin{document}/\\lhead[$(DISTTITLE)]{$(DISTTITLE)}\n\\begin{document}/' \
| sed 's/\\tableofcontents/\\begin{titlepage} \\maketitle \\end{titlepage}\n\\tableofcontents/' \
> verilator2.tex
$(PERL) $(POD2LATEXFIX) "$(DISTTITLE)" "${DISTDATE}" < verilator.tex > verilator2.tex
mv verilator2.tex verilator.tex
pdflatex verilator.tex
pdflatex verilator.tex
@@ -233,10 +232,34 @@ README: readme.pod
-rm -f $@
$(POD2TEXT) --loose $< > $@
README.html: readme.pod
pod2html $< >$@
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
README.pdf: readme.pod Makefile
pod2latex --full --out README.tex readme.pod
$(PERL) $(POD2LATEXFIX) "$(DISTTITLE) README File" "${DISTDATE}" < README.tex > README2.tex
mv README2.tex README.tex
pdflatex README.tex
pdflatex README.tex
-rm -f README.toc README.aux README.idx README.out
internals.txt: internals.pod
-rm -f $@
$(POD2TEXT) --loose $< > $@
internals.html: internals.pod
pod2html $< >$@
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
internals.pdf: internals.pod Makefile
pod2latex --full --out internals.tex internals.pod
$(PERL) $(POD2LATEXFIX) "$(DISTTITLE) Internals Manual" "${DISTDATE}" < internals.tex > internals2.tex
mv internals2.tex internals.tex
pdflatex internals.tex
pdflatex internals.tex
-rm -f internals.toc internals.aux internals.idx internals.out
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg \
verilator_includer verilator_profcfunc
@@ -313,7 +336,8 @@ uninstall:
-rmdir $(DESTDIR)$(pkgdatadir)/examples
-rmdir $(DESTDIR)$(pkgdatadir)
install: all_nomsg installbin installman installdata install-msg
install: all_nomsg install-all
install-all: installbin installman installdata install-msg
install-here: installman ftp
@@ -376,14 +400,17 @@ endif
# VERILATOR_AUTHOR_SITE
endif
CPPCHECK = cppcheck
CPPCHECK_FLAGS = --enable=all --inline-suppr --suppress=unusedScopedObject
# Use --xml flag to see the cppcheck code to use for suppression
CPPCHECK = src/cppcheck_filtered
CPPCHECK_FLAGS = --enable=all --inline-suppr --suppress=unusedScopedObject --suppress=cstyleCast
CPPCHECK_FLAGS += --xml
CPPCHECK_CPP = $(wildcard $(srcdir)/include/*.cpp $(srcdir)/src/*.cpp)
CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CPPCHECK_CPP))
CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/src/obj_dbg -I$(srcdir)/src
cppcheck: $(CPPCHECK_DEP)
%.cppcheck: %.cpp
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -I$(srcdir)/include -I$(srcdir)/src $<
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 $(CPPCHECK_INC) $<
ftp: info
@@ -433,14 +460,19 @@ clean mostlyclean distclean maintainer-clean::
distclean maintainer-clean::
rm -f Makefile config.status config.cache config.log verilator_bin* TAGS
rm -f include/verilated.mk
rm -f include/verilated.mk include/verilated_config.h
TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/[a-z]*.in \
${srcdir}/[a-z]*.in ${srcdir}/*.pod
TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/*.in \
${srcdir}/*.in ${srcdir}/*.pod
TAGS: $(TAGFILES)
etags $(TAGFILES)
.PHONY: doxygen
doxygen:
$(DOXYGEN) doxygen.config
######################################################################
# Test targets
Regular → Executable
+5 -2
View File
@@ -1,6 +1,6 @@
// DESCRIPTION: Verilator: List of To Do issues.
//
// Copyright 2004-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2014 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,11 +31,13 @@ Configure/Make/Install
* Distribute with flex/bison already expanded?
Flex library not needed. Probably too difficult to be worth it.
* Integrate SystemPerl coverage
see the SystemPerl git branch coverage_only
(Note in /usr/include there are no upper cased include files.)
Coverage.pm -- Need all functionality, but in C?
Coverage/Item.pm -- Need all functionality, but in C?
Coverage/ItemKey.pm -- Need all functionality, but in C?
sp_preproc -- Some steps in here need to be moved to generated C
-- -- note uses Verilog::Getopt
src/Sp.cpp -- n/a
src/SpCommon.h -- mostly overlaps verilatedos.h
src/SpCoverage.cpp/h -- All needed
@@ -53,6 +55,7 @@ Testing:
* New random program generator
* Better graph viewer with search and zoom
* Port and test against opencores.org code
* // verilator debug in code so can see only tree affecting those nodes
Usability:
* Detect and pre-remove most UNOPTFLATs (4.000)
@@ -62,7 +65,7 @@ Usability:
* Print version/etc message at runtime. (4.000?)
Include number of lines of code, percent comments, code complexity measurement
<-80chars------------------------------------------------------------------->
Verilator 3.600 - fast, free, open-sourced. Copyright 2001-2011.
Verilator 3.600 - fast, free, open-sourced. Copyright 2001-2013.
Verilated #### modules, #### instances, ##### sigs,
#### non-comment lines, ##### ops, ### KB model size
* Default the --l2name to remove extra "v" level of hierarchy (flag to make "top")
+640 -225
View File
File diff suppressed because it is too large Load Diff
+64 -6
View File
@@ -14,6 +14,19 @@ use vars qw ($Debug);
#======================================================================
# Old version 1 dump nodes with no dtypep's
our %Ver1_Non_Dtyped = map {$_ => 1} qw(
ACTIVE ALWAYS ALWAYSPOST ALWAYSPUBLIC ATTROF BEGIN BREAK CASE CASEITEM
CCALL CELL CELLINLINE CFILE CFUNC CHANGEDET CLOCKING COMMENT CONTINUE
COVERDECL COVERINC COVERTOGGLE CRETURN CSTMT DEFPARAM DISABLE DISPLAY DOT
DPIEXPORT FCLOSE FFLUSH FINAL FINISH FOPEN GENCASE GENERATE GENFOR GENIF
IF IMPLICIT INITARRAY INITIAL JUMPGO JUMPLABEL MODULE NETLIST
NOTFOUNDMODULE PACKAGE PACKAGEIMPORT PARSEREF PIN PORT PRAGMA PRIMITIVE
PSLASSERT PSLCOVER PSLDEFCLOCK PULL RANGE READMEM REPEAT RETURN SCCTOR
SCDTOR SCHDR SCIMP SCIMPHDR SCINT SCOPE SELBIT SELEXTRACT SELMINUS
SELPLUS SENGATE SENITEM SENTREE SFORMAT SFORMATF STOP SYSIGNORE SYSTEMT
TASK TASKREF TEXT TOPSCOPE TYPEDEFFWD TYPETABLE UCSTMT UDPTABLE
UDPTABLELINE UNTILSTABLE VASSERT WHILE );
#======================================================================
# main
@@ -79,27 +92,72 @@ sub diff_file {
my $a = shift;
my $b = shift;
# Compare the two tree files
my $tmp_a = "/tmp/$$.a";
my $tmp_b = "/tmp/$$.b";
(my $short_a = $a) =~ s/[^a-zA-Z0-9.]+/_/g;
(my $short_b = $b) =~ s/[^a-zA-Z0-9.]+/_/g;
my $tmp_a = "/tmp/${$}_${short_a}.a";
my $tmp_b = "/tmp/${$}_${short_b}.b";
filter ($a, $tmp_a);
filter ($b, $tmp_b);
my $vera = version_from($a);
my $verb = version_from($b);
my $verCvt = (($vera < 0x3900 && $verb >= 0x3900)
|| ($vera >= 0x3900 && $verb < 0x3900));
filter ($a, $tmp_a, $verCvt);
filter ($b, $tmp_b, $verCvt);
system("diff -u $tmp_a $tmp_b");
unlink $tmp_a;
unlink $tmp_b;
}
sub version_from {
my $fn = shift;
# Return dump format
my $f1 = IO::File->new ($fn) or die "%Error: $! $fn,";
while (defined (my $line=$f1->getline())) {
last if $. > 10;
return hex $1 if $line =~ /\(format (0x[0-9.]+)\)/;
}
return 1.0;
}
sub filter {
my $fn1 = shift;
my $fn2 = shift;
my $verCvt = shift;
# Remove hex numbers before diffing
my $f1 = IO::File->new ($fn1) or die "%Error: $! $fn1,";
my $f2 = IO::File->new ($fn2,"w") or die "%Error: $! $fn2,";
while (defined (my $line=$f1->getline())) {
same_line:
next if $line =~ / This=/;
$line =~ s/0x[a-f0-9]+/0x/g;
$line =~ s/<e[0-9]+\#?>/<e>/g;
$line =~ s/{[a-z]*\d+}/{}/g if !$Opt_Lineno;
if ($verCvt) {
next if $line =~ /^ NETLIST/;
$line =~ s!\@dt=0x\(G?/?([^)]+)\)!$1!g; # NEW: @dt -> OLD: non @dt format
# # Below Ver1_Non_Dtyped may replace above further
if ($line =~ /: ([A-Z]+) /) {
my $type = $1;
next if $type =~ 'DTYPE';
if ($type eq 'TYPETABLE' || $type eq 'RANGE') {
$line =~ /^(\s+\S+:) /; my $prefix = $1;
while (defined ($line=$f1->getline())) {
next if $line =~ /^\s+[a-z]/; # Table body
next if $line =~ /^${prefix}[0-9]:/;
goto same_line;
}
next;
}
if ($Ver1_Non_Dtyped{$type}) {
$line =~ s! w[0-9]+!!g;
}
}
$line =~ s!\@dt=0$!NoW!g; # NEW: dt=null -> common format
$line =~ s!\@dt=0 !NoW !g; # NEW: dt=null -> common format
$line =~ s! s?w0$! NoW!g; # OLD: no width -> common format
$line =~ s! s?w0 ! NoW !g; # OLD: no width -> common format
}
print $f2 $line;
}
$f1->close;
@@ -177,7 +235,7 @@ Do not show differences in line numbering.
The latest version is available from L<http://www.veripool.org/verilator>.
Copyright 2005-2011 by Wilson Snyder. This package is free software; you can
Copyright 2005-2014 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.
@@ -193,5 +251,5 @@ C<verilator>
######################################################################
### Local Variables:
### compile-command: "$V4/bin/verilator_difftree $V4/test_c/obj_dir/V*_03_*.tree $V4N/test_c/obj_dir/V*_03_*.tree"
### compile-command: "$V4/bin/verilator_difftree {$V4D,$V4}/test_regress/obj_dir/t_EXAMPLE/V*_03_*.tree"
### End:
+1 -1
View File
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
# DESCRIPTION: Print include statements for each ARGV
#
# Copyright 2003-2011 by Wilson Snyder. This package is free software; you can
# Copyright 2003-2014 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
@@ -208,7 +208,7 @@ Displays this message and program version and exits.
The latest version is available from L<http://www.veripool.org/>.
Copyright 2007-2011 by Wilson Snyder. Verilator is free software; you can
Copyright 2007-2014 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.
+6 -3
View File
@@ -1,12 +1,14 @@
# DESCRIPTION: Process this file with autoconf to produce a configure script.
#
# Copyright 2003-2011 by Wilson Snyder. Verilator is free software; you can
# Copyright 2003-2014 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],[3.830])
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[3.860 2014-05-11])
AC_CONFIG_HEADER(src/config_build.h)
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk)
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h)
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
@@ -128,6 +130,7 @@ _MY_CXX_CHECK_OPT(-Wno-sign-compare)
_MY_CXX_CHECK_OPT(-Wno-uninitialized)
_MY_CXX_CHECK_OPT(-Wno-unused-parameter)
_MY_CXX_CHECK_OPT(-Wno-unused-variable)
_MY_CXX_CHECK_OPT(-Wno-unused-but-set-variable)
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
# Checks for library functions.
+6
View File
@@ -0,0 +1,6 @@
/*! \mainpage Verilator Doxygen Documentation
*
* \section intro_sec Introduction
*
* This is a full doxygen analysis of the Verilator source tree.
*/
+1772
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -1 +1,2 @@
verilated.mk
verilated_config.h
+62 -27
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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,23 +27,20 @@
#include "verilated_imp.h"
#include <cctype>
#define VL_VALUE_STRING_MAX_WIDTH 1024 ///< Max static char array for VL_VALUE_STRING
#define VL_VALUE_STRING_MAX_WIDTH 8192 ///< Max static char array for VL_VALUE_STRING
//===========================================================================
// Global variables
// Slow path variables
int Verilated::s_randReset = 0;
VerilatedVoidCb Verilated::s_flushCb = NULL;
// Keep below together in one cache line
int Verilated::s_debug = 0;
bool Verilated::s_calcUnusedSigs = false;
bool Verilated::s_gotFinish = false;
bool Verilated::s_assertOn = true;
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;
struct Verilated::CommandArgValues Verilated::s_args = {0, NULL};
VerilatedImp VerilatedImp::s_s;
@@ -81,6 +78,18 @@ void vl_fatal (const char* filename, int linenum, const char* hier, const char*
}
#endif
//===========================================================================
// Overall class init
Verilated::Serialized::Serialized() {
s_randReset = 0;
s_debug = 0;
s_calcUnusedSigs = false;
s_gotFinish = false;
s_assertOn = true;
s_fatalOnVpiError = true; // retains old default behaviour
}
//===========================================================================
// Random reset -- Only called at init time, so don't inline.
@@ -198,7 +207,8 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, boo
vluint32_t vn[VL_MULS_MAX_WORDS+1]; // v normalized
// Zero for ease of debugging and to save having to zero for shifts
for (int i=0; i<words; i++) { un[i]=vn[i]=0; }
// Note +1 as loop will use extra word
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
@@ -301,7 +311,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
const char *ep = pos;
while (ep[0] && ep[0]!='%') ep++;
if (ep != pos) {
output += string(pos, ep-pos);
output.append(pos, ep-pos);
pos += ep-pos-1;
}
} else { // Format character
@@ -346,9 +356,9 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
// Deal with all read-and-print somethings
const int lbits = va_arg(ap, int);
QData ld = 0;
WData qlwp[2];
WDataInP lwp;
if (lbits <= VL_QUADSIZE) {
WData qlwp[2];
ld = _VL_VA_ARG_Q(ap, lbits);
VL_SET_WQ(qlwp,ld);
lwp = qlwp;
@@ -594,7 +604,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789+-xXzZ?_");
if (!tmp[0]) goto done;
vlsint64_t ld;
sscanf(tmp,"%" VL_PRI64 "d",&ld);
sscanf(tmp,"%30" VL_PRI64 "d",&ld);
VL_SET_WQ(owp,ld);
break;
}
@@ -615,7 +625,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789+-xXzZ?_");
if (!tmp[0]) goto done;
QData ld;
sscanf(tmp,"%" VL_PRI64 "u",&ld);
sscanf(tmp,"%30" VL_PRI64 "u",&ld);
VL_SET_WQ(owp,ld);
break;
}
@@ -750,19 +760,30 @@ void VL_FCLOSE_I(IData fdi) {
}
void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
string output;
_vl_vsformat(output, formatp, ap);
va_end(ap);
_VL_STRING_TO_VINT(obits, destp, (int)output.length(), output.c_str());
}
string VL_SFORMATF_NX(const char* formatp, ...) {
void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...) {
if (obits_ignored) {}
output = "";
va_list ap;
va_start(ap,formatp);
_vl_vsformat(output, formatp, ap);
va_end(ap);
}
string VL_SFORMATF_NX(const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
string output;
_vl_vsformat(output, formatp, ap);
va_end(ap);
@@ -770,9 +791,10 @@ string VL_SFORMATF_NX(const char* formatp, ...) {
}
void VL_WRITEF(const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
string output;
_vl_vsformat(output, formatp, ap);
va_end(ap);
@@ -781,12 +803,13 @@ void VL_WRITEF(const char* formatp, ...) {
}
void VL_FWRITEF(IData fpi, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
output = "";
FILE* fp = VL_CVT_I_FP(fpi);
if (VL_UNLIKELY(!fp)) return;
va_list ap;
va_start(ap,formatp);
string output;
_vl_vsformat(output, formatp, ap);
va_end(ap);
@@ -949,13 +972,13 @@ IData VL_SYSTEM_IW(int lhswords, WDataInP filenamep) {
}
IData VL_TESTPLUSARGS_I(const char* formatp) {
string match = VerilatedImp::argPlusMatch(formatp);
const string& match = VerilatedImp::argPlusMatch(formatp);
if (match == "") return 0;
else return 1;
}
IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp) {
string match = VerilatedImp::argPlusMatch(prefixp);
const string& match = VerilatedImp::argPlusMatch(prefixp);
const char* dp = match.c_str() + 1 /*leading + */ + strlen(prefixp);
if (match == "") return 0;
VL_ZERO_RESET_W(rbits, rwp);
@@ -964,7 +987,7 @@ IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rw
break;
case 'd':
vlsint64_t ld;
sscanf(dp,"%" VL_PRI64 "d",&ld);
sscanf(dp,"%30" VL_PRI64 "d",&ld);
VL_SET_WQ(rwp,ld);
break;
case 'b':
@@ -991,7 +1014,7 @@ IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rw
}
const char* vl_mc_scan_plusargs(const char* prefixp) {
string match = VerilatedImp::argPlusMatch(prefixp);
const string& match = VerilatedImp::argPlusMatch(prefixp);
static VL_THREAD char outstr[VL_VALUE_STRING_MAX_WIDTH];
if (match == "") return NULL;
strncpy(outstr, match.c_str()+strlen(prefixp)+1, // +1 to skip the "+"
@@ -1053,9 +1076,19 @@ void Verilated::flushCb(VerilatedVoidCb cb) {
}
void Verilated::commandArgs(int argc, const char** argv) {
s_args.argc = argc;
s_args.argv = argv;
VerilatedImp::commandArgs(argc,argv);
}
const char* Verilated::commandArgsPlusMatch(const char* prefixp) {
return VerilatedImp::argPlusMatch(prefixp).c_str();
}
void Verilated::internalsDump() {
VerilatedImp::internalsDump();
}
void Verilated::scopesDump() {
VerilatedImp::scopesDump();
}
@@ -1082,6 +1115,7 @@ VerilatedModule::~VerilatedModule() {
//======================================================================
// VerilatedVar:: Methods
// cppcheck-suppress unusedFunction // Used by applications
vluint32_t VerilatedVar::entSize() const {
vluint32_t size = 1;
switch (vltype()) {
@@ -1090,7 +1124,7 @@ vluint32_t VerilatedVar::entSize() const {
case VLVT_UINT16: size=sizeof(SData); break;
case VLVT_UINT32: size=sizeof(IData); break;
case VLVT_UINT64: size=sizeof(QData); break;
case VLVT_WDATA: size=VL_WORDS_I(range().bits())*sizeof(IData); break;
case VLVT_WDATA: size=VL_WORDS_I(range().elements())*sizeof(IData); break;
default: size=0; break;
}
return size;
@@ -1162,11 +1196,11 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap,
int msb = va_arg(ap,int);
int lsb = va_arg(ap,int);
if (i==0) {
var.m_range.m_lhs = msb;
var.m_range.m_rhs = lsb;
var.m_range.m_left = msb;
var.m_range.m_right = lsb;
} else if (i==1) {
var.m_array.m_lhs = msb;
var.m_array.m_rhs = lsb;
var.m_array.m_left = msb;
var.m_array.m_right = lsb;
} else {
// We could have a linked list of ranges, but really this whole thing needs
// to be generalized to support structs and unions, etc.
@@ -1178,6 +1212,7 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap,
m_varsp->insert(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);
+245 -34
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@@ -28,6 +28,7 @@
#ifndef _VERILATED_H_
#define _VERILATED_H_ 1 ///< Header Guard
#include "verilated_config.h"
#include "verilatedos.h"
#include <cassert>
@@ -144,7 +145,7 @@ public:
# define VL_CELL(instname,type) ///< Declare a cell, ala SP_CELL
/// Declare a module, ala SC_MODULE
# define VL_MODULE(modname) struct modname : public VerilatedModule
# define VL_MODULE(modname) class modname : public VerilatedModule
/// Constructor, ala SC_CTOR
# define VL_CTOR(modname) modname(const char* __VCname="")
@@ -215,23 +216,34 @@ public: // But internals only - called from VerilatedModule's
//===========================================================================
/// Verilator global static information class
struct Verilated {
class Verilated {
// MEMBERS
private:
// Slow path variables
static int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
static VerilatedVoidCb s_flushCb; ///< Flush callback function
// Fast path
static int s_debug; ///< See accessors... only when VL_DEBUG set
static bool s_calcUnusedSigs; ///< Waves file on, need all signals calculated
static bool s_gotFinish; ///< A $finish statement executed
static bool s_assertOn; ///< Assertions are enabled
static struct Serialized { // All these members serialized/deserialized
// Slow path
int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
// Fast path
int s_debug; ///< See accessors... only when VL_DEBUG set
bool s_calcUnusedSigs; ///< Waves file on, need all signals calculated
bool s_gotFinish; ///< A $finish statement executed
bool s_assertOn; ///< Assertions are enabled
bool s_fatalOnVpiError; ///< Stop on vpi error/unsupported
Serialized();
} s_s;
static VL_THREAD const VerilatedScope* t_dpiScopep; ///< DPI context scope
static VL_THREAD const char* t_dpiFilename; ///< DPI context filename
static VL_THREAD int t_dpiLineno; ///< DPI context line number
// no need to be save-restored (serialized) the
// assumption is that the restore is allowed to pass different arguments
static struct CommandArgValues {
int argc;
const char** argv;
} s_args;
public:
// METHODS - User called
@@ -241,29 +253,32 @@ public:
/// 0 = Set to zeros
/// 1 = Set all bits to one
/// 2 = Randomize all bits
static void randReset(int val) { s_randReset=val; }
static int randReset() { return s_randReset; } ///< Return randReset value
static void randReset(int val) { s_s.s_randReset=val; }
static int randReset() { return s_s.s_randReset; } ///< Return randReset value
/// Enable debug of internal verilated code
static inline void debug(int level) { s_debug = level; }
static inline void debug(int level) { s_s.s_debug = level; }
#ifdef VL_DEBUG
static inline int debug() { return s_debug; } ///< Return debug value
static inline int debug() { return s_s.s_debug; } ///< Return debug value
#else
static inline int debug() { return 0; } ///< Constant 0 debug, so C++'s optimizer rips up
#endif
/// Enable calculation of unused signals
static void calcUnusedSigs(bool flag) { s_calcUnusedSigs=flag; }
static bool calcUnusedSigs() { return s_calcUnusedSigs; } ///< Return calcUnusedSigs value
static void calcUnusedSigs(bool flag) { s_s.s_calcUnusedSigs=flag; }
static bool calcUnusedSigs() { return s_s.s_calcUnusedSigs; } ///< Return calcUnusedSigs value
/// Did the simulation $finish?
static void gotFinish(bool flag) { s_gotFinish=flag; }
static bool gotFinish() { return s_gotFinish; } ///< Return if got a $finish
static void gotFinish(bool flag) { s_s.s_gotFinish=flag; }
static bool gotFinish() { return s_s.s_gotFinish; } ///< Return if got a $finish
/// Allow traces to at some point be enabled (disables some optimizations)
static void traceEverOn(bool flag) {
if (flag) { calcUnusedSigs(flag); }
}
/// Enable/disable assertions
static void assertOn(bool flag) { s_assertOn=flag; }
static bool assertOn() { return s_assertOn; }
static void assertOn(bool flag) { s_s.s_assertOn=flag; }
static bool assertOn() { return s_s.s_assertOn; }
/// Enable/disable vpi fatal
static void fatalOnVpiError(bool flag) { s_s.s_fatalOnVpiError=flag; }
static bool fatalOnVpiError() { return s_s.s_fatalOnVpiError; }
/// Flush callback for VCD waves
static void flushCb(VerilatedVoidCb cb);
static void flushCall() { if (s_flushCb) (*s_flushCb)(); }
@@ -271,6 +286,17 @@ public:
/// Record command line arguments, for retrieval by $test$plusargs/$value$plusargs
static void commandArgs(int argc, const char** argv);
static void commandArgs(int argc, char** argv) { commandArgs(argc,(const char**)argv); }
static CommandArgValues* getCommandArgs() {return &s_args;}
static const char* commandArgsPlusMatch(const char* prefixp);
/// Produce name & version for (at least) VPI
static const char* productName() { return VERILATOR_PRODUCT; }
static const char* productVersion() { return VERILATOR_VERSION; }
/// For debugging, print much of the Verilator internal state.
/// The output of this function may change in future
/// releases - contact the authors before production use.
static void internalsDump();
/// For debugging, print text list of all scope names with
/// dpiImport/Export context. This function may change in future
@@ -292,6 +318,8 @@ public:
static const char* dpiFilenamep() { return t_dpiFilename; }
static int dpiLineno() { return t_dpiLineno; }
static int exportFuncNum(const char* namep);
static size_t serializedSize() { return sizeof(s_s); }
static void* serializedPtr() { return &s_s; }
};
//=========================================================================
@@ -523,6 +551,7 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
//===================================================================
// SYSTEMC OPERATORS
// Copying verilog format to systemc integers and bit vectors.
// Get a SystemC variable
#define VL_ASSIGN_ISI(obits,vvar,svar) { (vvar) = VL_CLEAN_II((obits),(obits),(svar).read()); }
#define VL_ASSIGN_QSQ(obits,vvar,svar) { (vvar) = VL_CLEAN_QQ((obits),(obits),(svar).read()); }
@@ -540,7 +569,21 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
owp[words-1] &= VL_MASK_I(obits); \
}
#define VL_ASSIGN_ISU(obits,vvar,svar) { (vvar) = VL_CLEAN_II((obits),(obits),(svar).read().to_uint()); }
#define VL_ASSIGN_QSU(obits,vvar,svar) { (vvar) = VL_CLEAN_QQ((obits),(obits),(svar).read().to_uint64()); }
#define VL_ASSIGN_WSB(obits,owp,svar) { \
int words = VL_WORDS_I(obits); \
sc_biguint<obits> _butemp = (svar).read(); \
for (int i=0; i < words; i++) { \
int msb = ((i+1)*VL_WORDSIZE) - 1; \
msb = (msb >= obits) ? (obits-1) : msb; \
owp[i] = _butemp.range(msb,i*VL_WORDSIZE).to_uint(); \
} \
owp[words-1] &= VL_MASK_I(obits); \
}
// Copying verilog format from systemc integers and bit vectors.
// Set a SystemC variable
#define VL_ASSIGN_SII(obits,svar,vvar) { (svar).write(vvar); }
#define VL_ASSIGN_SQQ(obits,svar,vvar) { (svar).write(vvar); }
@@ -562,6 +605,20 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
svar.write(_bvtemp); \
}
#define VL_ASSIGN_SUI(obits,svar,rd) { (svar).write(rd); }
#define VL_ASSIGN_SUQ(obits,svar,rd) { (svar).write(rd); }
#define VL_ASSIGN_SBI(obits,svar,rd) { (svar).write(rd); }
#define VL_ASSIGN_SBQ(obits,svar,rd) { (svar).write(rd); }
#define VL_ASSIGN_SBW(obits,svar,rwp) { \
sc_biguint<obits> _butemp; \
for (int i=0; i < VL_WORDS_I(obits); i++) { \
int msb = ((i+1)*VL_WORDSIZE) - 1; \
msb = (msb >= obits) ? (obits-1) : msb; \
_butemp.range(msb,i*VL_WORDSIZE) = rwp[i]; \
} \
svar.write(_butemp); \
}
//===================================================================
// Extending sizes
@@ -813,7 +870,7 @@ static inline WDataOutP VL_OR_W(int words, WDataOutP owp,WDataInP lwp,WDataInP r
}
// EMIT_RULE: VL_CHANGEXOR: oclean=1; obits=32; lbits==rbits;
static inline IData VL_CHANGEXOR_W(int words, WDataInP lwp,WDataInP rwp){
IData od;
IData od = 0;
for (int i=0; (i < words); i++) od |= (lwp[i] ^ rwp[i]);
return(od);
}
@@ -1106,7 +1163,10 @@ static inline WDataOutP VL_MODDIVS_WWW(int lbits, WDataOutP owp,WDataInP lwp,WDa
}
}
#define VL_POW_QQI(obits,lbits,rbits,lhs,rhs) VL_POW_QQQ(obits,lbits,rbits,lhs,rhs)
static inline IData VL_POW_III(int, int, int rbits, IData lhs, IData rhs) {
if (VL_UNLIKELY(rhs==0)) return 1;
if (VL_UNLIKELY(lhs==0)) return 0;
IData power = lhs;
IData out = 1;
@@ -1116,10 +1176,8 @@ static inline IData VL_POW_III(int, int, int rbits, IData lhs, IData rhs) {
}
return out;
}
#define VL_POW_QQI(obits,lbits,rbits,lhs,rhs) VL_POW_QQQ(obits,lbits,rbits,lhs,rhs)
static inline QData VL_POW_QQQ(int, int, int rbits, QData lhs, QData rhs) {
if (VL_UNLIKELY(rhs==0)) return 1;
if (VL_UNLIKELY(lhs==0)) return 0;
QData power = lhs;
QData out = VL_ULL(1);
@@ -1130,6 +1188,36 @@ static inline QData VL_POW_QQQ(int, int, int rbits, QData lhs, QData rhs) {
return out;
}
#define VL_POWSS_QQI(obits,lbits,rbits,lhs,rhs,lsign,rsign) VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
static inline IData VL_POWSS_III(int obits, int, int rbits, IData lhs, IData rhs, bool lsign, bool rsign) {
if (VL_UNLIKELY(rhs==0)) return 1;
if (rsign && VL_SIGN_I(rbits, rhs)) {
if (lhs==0) return 0; // "X"
else if (lhs==1) return 1;
else if (lsign && lhs==VL_MASK_I(obits)) { //-1
if (rhs & 1) return VL_MASK_I(obits); // -1^odd=-1
else return 1; // -1^even=1
}
return 0;
}
return VL_POW_III(obits, obits, rbits, lhs, rhs);
}
static inline QData VL_POWSS_QQQ(int obits, int, int rbits, QData lhs, QData rhs, bool lsign, bool rsign) {
if (VL_UNLIKELY(rhs==0)) return 1;
if (rsign && VL_SIGN_I(rbits, rhs)) {
if (lhs==0) return 0; // "X"
else if (lhs==1) return 1;
else if (lsign && lhs==VL_MASK_I(obits)) { //-1
if (rhs & 1) return VL_MASK_I(obits); // -1^odd=-1
else return 1; // -1^even=1
}
return 0;
}
return VL_POW_QQQ(obits, obits, rbits, lhs, rhs);
}
//===================================================================
// Concat/replication
@@ -1270,6 +1358,120 @@ static inline WDataOutP VL_REPLICATE_WWI(int obits, int lbits, int, WDataOutP ow
return(owp);
}
// Left stream operator. Output will always be clean. LHS and RHS must be clean.
// Special "fast" versions for slice sizes that are a power of 2. These use
// shifts and masks to execute faster than the slower for-loop approach where a
// subset of bits is copied in during each iteration.
static inline IData VL_STREAML_FAST_III(int, int lbits, int, IData ld, IData rd_log2) {
// Pre-shift bits in most-significant slice:
//
// If lbits is not a multiple of the slice size (i.e., lbits % rd != 0),
// then we end up with a "gap" in our reversed result. For example, if we
// have a 5-bit Verlilog signal (lbits=5) in an 8-bit C data type:
//
// ld = ---43210
//
// (where numbers are the Verilog signal bit numbers and '-' is an unused bit).
// Executing the switch statement below with a slice size of two (rd=2,
// rd_log2=1) produces:
//
// ret = 1032-400
//
// Pre-shifting the bits in the most-significant slice allows us to avoid
// this gap in the shuffled data:
//
// ld_adjusted = --4-3210
// ret = 10324---
IData ret = ld;
if (rd_log2) {
vluint32_t lbitsFloor = lbits & ~VL_MASK_I(rd_log2); // max multiple of rd <= lbits
vluint32_t lbitsRem = lbits - lbitsFloor; // number of bits in most-sig slice (MSS)
IData msbMask = VL_MASK_I(lbitsRem) << lbitsFloor; // mask to sel only bits in MSS
ret = (ret & ~msbMask) | ((ret & msbMask) << ((VL_UL(1) << rd_log2) - lbitsRem));
}
switch (rd_log2) {
case 0:
ret = ((ret >> 1) & VL_UL(0x55555555)) | ((ret & VL_UL(0x55555555)) << 1); // FALLTHRU
case 1:
ret = ((ret >> 2) & VL_UL(0x33333333)) | ((ret & VL_UL(0x33333333)) << 2); // FALLTHRU
case 2:
ret = ((ret >> 4) & VL_UL(0x0f0f0f0f)) | ((ret & VL_UL(0x0f0f0f0f)) << 4); // FALLTHRU
case 3:
ret = ((ret >> 8) & VL_UL(0x00ff00ff)) | ((ret & VL_UL(0x00ff00ff)) << 8); // FALLTHRU
case 4:
ret = ((ret >> 16) | (ret << 16));
}
return ret >> (VL_WORDSIZE - lbits);
}
static inline QData VL_STREAML_FAST_QQI(int, int lbits, int, QData ld, IData rd_log2) {
// Pre-shift bits in most-significant slice (see comment in VL_STREAML_FAST_III)
QData ret = ld;
if (rd_log2) {
vluint32_t lbitsFloor = lbits & ~VL_MASK_I(rd_log2);
vluint32_t lbitsRem = lbits - lbitsFloor;
QData msbMask = VL_MASK_Q(lbitsRem) << lbitsFloor;
ret = (ret & ~msbMask) | ((ret & msbMask) << ((VL_ULL(1) << rd_log2) - lbitsRem));
}
switch (rd_log2) {
case 0:
ret = ((ret >> 1) & VL_ULL(0x5555555555555555)) | ((ret & VL_ULL(0x5555555555555555)) << 1); // FALLTHRU
case 1:
ret = ((ret >> 2) & VL_ULL(0x3333333333333333)) | ((ret & VL_ULL(0x3333333333333333)) << 2); // FALLTHRU
case 2:
ret = ((ret >> 4) & VL_ULL(0x0f0f0f0f0f0f0f0f)) | ((ret & VL_ULL(0x0f0f0f0f0f0f0f0f)) << 4); // FALLTHRU
case 3:
ret = ((ret >> 8) & VL_ULL(0x00ff00ff00ff00ff)) | ((ret & VL_ULL(0x00ff00ff00ff00ff)) << 8); // FALLTHRU
case 4:
ret = ((ret >> 16) & VL_ULL(0x0000ffff0000ffff)) | ((ret & VL_ULL(0x0000ffff0000ffff)) << 16); // FALLTHRU
case 5:
ret = ((ret >> 32) | (ret << 32));
}
return ret >> (VL_QUADSIZE - lbits);
}
// Regular "slow" streaming operators
static inline IData VL_STREAML_III(int, int lbits, int, IData ld, IData rd) {
IData ret = 0;
// Slice size should never exceed the lhs width
IData mask = VL_MASK_I(rd);
for (int istart=0; istart<lbits; istart+=rd) {
int ostart=lbits-rd-istart;
ostart = ostart > 0 ? ostart : 0;
ret |= ((ld >> istart) & mask) << ostart;
}
return ret;
}
static inline QData VL_STREAML_QQI(int, int lbits, int, QData ld, IData rd) {
QData ret = 0;
// Slice size should never exceed the lhs width
QData mask = VL_MASK_Q(rd);
for (int istart=0; istart<lbits; istart+=rd) {
int ostart=lbits-rd-istart;
ostart = ostart > 0 ? ostart : 0;
ret |= ((ld >> istart) & mask) << ostart;
}
return ret;
}
static inline WDataOutP VL_STREAML_WWI(int, int lbits, int, WDataOutP owp, WDataInP lwp, IData rd) {
VL_ZERO_RESET_W(lbits, owp);
// Slice size should never exceed the lhs width
int ssize = ((int)rd < lbits) ? ((int)rd) : lbits;
for (int istart=0; istart<lbits; istart+=rd) {
int ostart=lbits-rd-istart;
ostart = ostart > 0 ? ostart : 0;
for (int sbit=0; sbit<ssize && sbit<lbits-istart; sbit++) {
// Extract a single bit from lwp and shift it to the correct
// location for owp.
WData bit= ((lwp[VL_BITWORD_I(istart+sbit)] >> VL_BITBIT_I(istart+sbit)) & 1) << VL_BITBIT_I(ostart+sbit);
owp[VL_BITWORD_I(ostart+sbit)] |= bit;
}
}
return owp;
}
// Because concats are common and wide, it's valuable to always have a clean output.
// Thus we specify inputs must be clean, so we don't need to clean the output.
// Note the bit shifts are always constants, so the adds in these constify out.
@@ -1398,29 +1600,37 @@ static inline WDataOutP VL_SHIFTR_WWI(int obits,int,int,WDataOutP owp,WDataInP l
}
// EMIT_RULE: VL_SHIFTRS: oclean=false; lclean=clean, rclean==clean;
static inline IData VL_SHIFTRS_III(int obits, int, int, IData lhs, IData rhs) {
static inline IData VL_SHIFTRS_III(int obits, int lbits, int, IData lhs, IData rhs) {
// Note the C standard does not specify the >> operator as a arithmetic shift!
IData sign = -(lhs >> (obits-1)); // ffff_ffff if negative
IData signext = ~(VL_MASK_I(obits) >> rhs); // One with bits where we've shifted "past"
// IEEE says signed if output signed, but bit position from lbits;
// must use lbits for sign; lbits might != obits,
// an EXTEND(SHIFTRS(...)) can became a SHIFTRS(...) within same 32/64 bit word length
IData sign = -(lhs >> (lbits-1)); // ffff_ffff if negative
IData signext = ~(VL_MASK_I(lbits) >> rhs); // One with bits where we've shifted "past"
return (lhs >> rhs) | (sign & VL_CLEAN_II(obits,obits,signext));
}
static inline QData VL_SHIFTRS_QQI(int obits, int, int, QData lhs, IData rhs) {
QData sign = -(lhs >> (obits-1));
QData signext = ~(VL_MASK_Q(obits) >> rhs);
static inline QData VL_SHIFTRS_QQI(int obits, int lbits, int, QData lhs, IData rhs) {
QData sign = -(lhs >> (lbits-1));
QData signext = ~(VL_MASK_Q(lbits) >> rhs);
return (lhs >> rhs) | (sign & VL_CLEAN_QQ(obits,obits,signext));
}
static inline WDataOutP VL_SHIFTRS_WWI(int obits,int,int,WDataOutP owp,WDataInP lwp, IData rd) {
static inline IData VL_SHIFTRS_IQI(int obits, int lbits, int rbits, QData lhs, IData rhs) {
return (IData)(VL_SHIFTRS_QQI(obits, lbits, rbits, lhs, rhs));
}
static inline WDataOutP VL_SHIFTRS_WWI(int obits,int lbits,int,WDataOutP owp,WDataInP lwp, IData rd) {
int word_shift = VL_BITWORD_I(rd);
int bit_shift = VL_BITBIT_I(rd);
int lmsw = VL_WORDS_I(obits)-1;
IData sign = VL_SIGNONES_I(obits,lwp[lmsw]);
if ((int)rd >= obits) {
IData sign = VL_SIGNONES_I(lbits,lwp[lmsw]);
if ((int)rd >= obits) { // Shifting past end, sign in all of lbits
for (int i=0; i <= lmsw; i++) owp[i] = sign;
owp[lmsw] &= VL_MASK_I(lbits);
} else if (bit_shift==0) { // Aligned word shift (>>0,>>32,>>64 etc)
int copy_words = (VL_WORDS_I(obits)-word_shift);
for (int i=0; i < copy_words; i++) owp[i] = lwp[i+word_shift];
if (copy_words>=0) owp[copy_words-1] |= ~VL_MASK_I(obits) & sign;
for (int i=copy_words; i < VL_WORDS_I(obits); i++) owp[i] = sign;
owp[lmsw] &= VL_MASK_I(lbits);
} else {
int loffset = rd & VL_SIZEBITS_I;
int nbitsonright = 32-loffset; // bits that end up in lword (know loffset!=0)
@@ -1435,6 +1645,7 @@ static inline WDataOutP VL_SHIFTRS_WWI(int obits,int,int,WDataOutP owp,WDataInP
}
if (words) owp[words-1] |= sign & ~VL_MASK_I(obits-loffset);
for (int i=words; i<VL_WORDS_I(obits); i++) owp[i] = sign;
owp[lmsw] &= VL_MASK_I(lbits);
}
return(owp);
}
+4 -4
View File
@@ -2,7 +2,7 @@
######################################################################
# DESCRIPTION: Makefile commands for all verilated target files
#
# Copyright 2003-2011 by Wilson Snyder. Verilator is free software; you can
# Copyright 2003-2014 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.
######################################################################
@@ -93,10 +93,10 @@ VM_SUPPORT += $(VM_SUPPORT_FAST) $(VM_SUPPORT_SLOW)
##### SystemC or SystemPerl builds
ifeq ($(VM_SP_OR_SC),1)
CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC)/include
LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC)/lib-$(VM_SC_TARGET_ARCH)
CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC_INCLUDE)
LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC_LIBDIR)
SC_LIBS = -lsystemc
ifneq ($(wildcard $(SYSTEMC)/lib-$(VM_SC_TARGET_ARCH)/*numeric_bit*),)
ifneq ($(wildcard $(SYSTEMC_LIBDIR)/*numeric_bit*),)
# Systemc 1.2.1beta
SC_LIBS += -lnumeric_bit -lqt
endif
+2 -3
View File
@@ -1,11 +1,10 @@
// -*- C++ -*-
//*************************************************************************
//
// Code available from: http://www.veripool.org/verilator
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@@ -23,7 +22,7 @@
`define _VERILATED_V_ 1
// Hide verilator pragmas from other tools
`ifdef verilator `else
`ifdef VERILATOR `else
`define coverage_block_off
`endif
+28
View File
@@ -0,0 +1,28 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
///
/// \file
/// \brief Verilator: Auto version information include for all Verilated C files
///
/// Code available from: http://www.veripool.org/verilator
///
//*************************************************************************
///**** Product and Version name
// Autoconf substitutes this with the strings from AC_INIT.
#define VERILATOR_PRODUCT "@PACKAGE_NAME@"
#define VERILATOR_VERSION "@PACKAGE_VERSION@"
+2 -5
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@@ -104,9 +104,6 @@ int svHigh(const svOpenArrayHandle h, int d) {
int svIncrement(const svOpenArrayHandle h, int d) {
_VL_SVDPI_UNIMP(); return 0;
}
int svLength(const svOpenArrayHandle h, int d) {
_VL_SVDPI_UNIMP(); return 0;
}
int svDimensions(const svOpenArrayHandle h) {
_VL_SVDPI_UNIMP(); return 0;
}
+2 -2
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
+6 -2
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2010-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2010-2014 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,11 +41,15 @@ inline string VL_CVT_PACK_STR_NQ(QData lhs) {
IData lw[2]; VL_SET_WQ(lw, lhs);
return VL_CVT_PACK_STR_NW(2, lw);
}
inline string VL_CVT_PACK_STR_NQ(string lhs) {
return lhs;
}
inline string VL_CVT_PACK_STR_NI(IData lhs) {
IData lw[1]; lw[0] = lhs;
return VL_CVT_PACK_STR_NW(1, lw);
}
extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...);
extern string VL_SFORMATF_NX(const char* formatp, ...);
#endif // Guard
+33 -5
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License.
// Version 2.0.
@@ -55,7 +55,9 @@ class VerilatedImp {
// MEMBERS
static VerilatedImp s_s; ///< Static Singleton; One and only static this
ArgVec m_argVec; ///< Argument list
// Nothing here is save-restored; users expected to re-register appropriately
ArgVec m_argVec; ///< Argument list (NOT save-restored, may want different results)
bool m_argVecLoaded; ///< Ever loaded argument list
UserMap m_userMap; ///< Map of <(scope,userkey), userData>
ScopeNameMap m_nameMap; ///< Map of <scope_name, scope pointer>
@@ -76,6 +78,18 @@ public: // But only for verilated*.cpp
m_fdps[2] = stderr;
}
~VerilatedImp() {}
static void internalsDump() {
VL_PRINTF("internalsDump:\n");
VL_PRINTF(" Argv:");
for (ArgVec::iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
VL_PRINTF(" %s",it->c_str());
}
VL_PRINTF("\n");
VL_PRINTF(" Version: %s %s\n", Verilated::productName(), Verilated::productVersion());
scopesDump();
exportsDump();
userDump();
}
// METHODS - arguments
static void commandArgs(int argc, const char** argv) {
@@ -127,6 +141,14 @@ private:
}
}
}
static void userDump() {
bool first = true;
for (UserMap::iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) {
if (first) { VL_PRINTF(" userDump:\n"); first=false; }
VL_PRINTF(" DPI_USER_DATA scope %p key %p: %p\n",
it->first.first, it->first.second, it->second);
}
}
public: // But only for verilated*.cpp
// METHODS - scope name
@@ -148,9 +170,8 @@ public: // But only for verilated*.cpp
ScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
if (it != s_s.m_nameMap.end()) s_s.m_nameMap.erase(it);
}
static void scopesDump() {
VL_PRINTF("scopesDump:\n");
VL_PRINTF(" scopesDump:\n");
for (ScopeNameMap::iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) {
const VerilatedScope* scopep = it->second;
scopep->scopeDump();
@@ -192,6 +213,13 @@ public: // But only for verilated*.cpp
}
return "*UNKNOWN*";
}
static void exportsDump() {
bool first = true;
for (ExportNameMap::iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
if (first) { VL_PRINTF(" exportDump:\n"); first=false; }
VL_PRINTF(" DPI_EXPORT_NAME %05d: %s\n", it->second, it->first);
}
}
// We don't free up m_exportMap until the end, because we can't be sure
// what other models are using the assigned funcnum's.
+233
View File
@@ -0,0 +1,233 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//=============================================================================
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2014 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.
//
// This is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
//=============================================================================
///
/// \file
/// \brief C++ Tracing in VCD Format
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
#include "verilatedos.h"
#include "verilated.h"
#include "verilated_save.h"
#include <fcntl.h>
#include <cerrno>
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
# include <io.h>
#else
# include <unistd.h>
#endif
#ifndef O_LARGEFILE // For example on WIN32
# define O_LARGEFILE 0
#endif
#ifndef O_NONBLOCK
# define O_NONBLOCK 0
#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
//=============================================================================
//=============================================================================
//=============================================================================
// Searalization
bool VerilatedDeserialize::readDiffers (const void* __restrict datap, size_t size) {
bufferCheck();
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
vluint8_t miss = 0;
while (size--) {
miss |= (*dp++ ^ *m_cp++);
}
return (miss!=0);
}
VerilatedDeserialize& VerilatedDeserialize::readAssert (const void* __restrict datap, size_t size) {
if (VL_UNLIKELY(readDiffers(datap,size))) {
string msg = (string)"Can't deserialize save-restore file as was made from different model";
vl_fatal(filename().c_str(), 0, "", msg.c_str());
close();
}
return *this; // For function chaining
}
void VerilatedSerialize::header() {
VerilatedSerialize& os = *this; // So can cut and paste standard << code below
assert((strlen(VLTSAVE_HEADER_STR) & 7) == 0); // Keep aligned
os.write(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR));
// Verilated doesn't do it itself, as if we're not using save/restore
// it doesn't need to compile this stuff in
os.write(Verilated::serializedPtr(), Verilated::serializedSize());
}
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 msg = (string)"Can't deserialize; file has wrong header signature";
vl_fatal(filename().c_str(), 0, "", msg.c_str());
close();
}
os.read(Verilated::serializedPtr(), Verilated::serializedSize());
}
void VerilatedSerialize::trailer() {
VerilatedSerialize& os = *this; // So can cut and paste standard << code below
assert((strlen(VLTSAVE_TRAILER_STR) & 7) == 0); // Keep aligned
os.write(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR));
}
void VerilatedDeserialize::trailer() {
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR)))) {
string msg = (string)"Can't deserialize; file has wrong end-of-file signature";
vl_fatal(filename().c_str(), 0, "", msg.c_str());
close();
}
}
//=============================================================================
//=============================================================================
//=============================================================================
// Opening/Closing
void VerilatedSave::open (const char* filenamep) {
if (isOpen()) return;
VL_DEBUG_IF(VL_PRINTF("-vltSave: opening save file %s\n",filenamep););
if (filenamep[0]=='|') {
assert(0); // Not supported yet.
} else {
// cppcheck-suppress duplicateExpression
m_fd = ::open (filenamep, O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK
, 0666);
if (m_fd<0) {
// User code can check isOpen()
m_isOpen = false;
return;
}
}
m_isOpen = true;
m_filename = filenamep;
m_cp = m_bufp;
header();
}
void VerilatedRestore::open (const char* filenamep) {
if (isOpen()) return;
VL_DEBUG_IF(VL_PRINTF("-vltRestore: opening restore file %s\n",filenamep););
if (filenamep[0]=='|') {
assert(0); // Not supported yet.
} else {
// cppcheck-suppress duplicateExpression
m_fd = ::open (filenamep, O_CREAT|O_RDONLY|O_LARGEFILE
, 0666);
if (m_fd<0) {
// User code can check isOpen()
m_isOpen = false;
return;
}
}
m_isOpen = true;
m_filename = filenamep;
m_cp = m_bufp;
m_endp = m_bufp;
header();
}
void VerilatedSave::close () {
if (!isOpen()) return;
trailer();
flush();
m_isOpen = false;
::close(m_fd); // May get error, just ignore it
}
void VerilatedRestore::close () {
if (!isOpen()) return;
trailer();
flush();
m_isOpen = false;
::close(m_fd); // May get error, just ignore it
}
//=============================================================================
// Buffer management
void VerilatedSave::flush() {
if (VL_UNLIKELY(!isOpen())) return;
vluint8_t* wp = m_bufp;
while (1) {
ssize_t remaining = (m_cp - wp);
if (remaining==0) break;
errno = 0;
ssize_t got = ::write (m_fd, wp, remaining);
if (got>0) {
wp += got;
} else if (got < 0) {
if (errno != EAGAIN && errno != EINTR) {
// write failed, presume error (perhaps out of disk space)
string msg = string(__FUNCTION__)+": "+strerror(errno);
vl_fatal("",0,"",msg.c_str());
close();
break;
}
}
}
m_cp = m_bufp; // Reset buffer
}
void VerilatedRestore::fill() {
if (VL_UNLIKELY(!isOpen())) return;
// Move remaining characters down to start of buffer. (No memcpy, overlaps allowed)
vluint8_t* rp = m_bufp;
for (vluint8_t* sp=m_cp; rp < m_endp;) *rp++ = *sp++; // Overlaps
m_endp = m_bufp + (m_endp - m_cp);
m_cp = m_bufp; // Reset buffer
// Read into buffer starting at m_endp
while (1) {
ssize_t remaining = (m_bufp+bufferSize() - m_endp);
if (remaining==0) break;
errno = 0;
ssize_t got = ::read (m_fd, m_endp, remaining);
if (got>0) {
m_endp += got;
} else if (got < 0) {
if (errno != EAGAIN && errno != EINTR) {
// write failed, presume error (perhaps out of disk space)
string msg = string(__FUNCTION__)+": "+strerror(errno);
vl_fatal("",0,"",msg.c_str());
close();
break;
}
} else { // got==0, EOF
// Fill buffer from here to end with NULLs so reader's don't need to check eof each character.
while (m_endp < m_bufp+bufferSize()) *m_endp++ = '\0';
break;
}
}
}
//=============================================================================
// Serialization of types
+234
View File
@@ -0,0 +1,234 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//=============================================================================
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2012-2014 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.
//
// This is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
//=============================================================================
///
/// \file
/// \brief Save-restore serialization of verilated modules
///
/// AUTHOR: Wilson Snyder
///
//=============================================================================
#ifndef _VERILATED_SAVE_C_H_
#define _VERILATED_SAVE_C_H_ 1
#include "verilatedos.h"
#include <string>
using namespace std;
//=============================================================================
// VerilatedSerialBase - internal base class for common code between VerilatedSerialize and VerilatedDeserialize
class VerilatedSerialBase {
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;
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
inline static size_t bufferInsertSize() { return 16*1024; }
// CREATORS
VerilatedSerialBase() {
m_isOpen = false;
m_bufp = new vluint8_t [bufferSize()];
m_cp = m_bufp;
}
public:
// CREATORS
virtual ~VerilatedSerialBase() {
close();
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
}
// METHODS
bool isOpen() const { return m_isOpen; }
string filename() const { return m_filename; }
virtual void close() { flush(); }
virtual void flush() {}
};
//=============================================================================
// VerilatedSerialize - convert structures to a stream representation
class VerilatedSerialize : public VerilatedSerialBase {
protected:
virtual void close() { flush(); }
virtual void flush() {}
void header();
void trailer();
public:
// CREATORS
VerilatedSerialize() {}
virtual ~VerilatedSerialize() { close(); }
// METHODS
VerilatedSerialize& bufferCheck() {
// Flush the write buffer if there's not enough space left for new information
// We only call this once per vector, so we need enough slop for a very wide "b###" line
if (VL_UNLIKELY(m_cp > (m_bufp+(bufferSize()-bufferInsertSize())))) {
flush();
}
return *this; // For function chaining
}
inline VerilatedSerialize& write (const void* __restrict datap, size_t size) {
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
while (size) {
bufferCheck();
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
const vluint8_t* __restrict maxp = dp + blk;
while (dp < maxp) *m_cp++ = *dp++;
size -= blk;
}
return *this; // For function chaining
}
};
//=============================================================================
// VerilatedDeserial - load structures from a stream representation
class VerilatedDeserialize : public VerilatedSerialBase {
protected:
vluint8_t* m_endp; ///< Last valid byte in m_bufp buffer
virtual void fill() = 0;
void header();
void trailer();
public:
// CREATORS
VerilatedDeserialize() { m_endp = NULL; }
virtual ~VerilatedDeserialize() { close(); }
// METHODS
inline VerilatedDeserialize& read (void* __restrict datap, size_t size) {
vluint8_t* __restrict dp = (vluint8_t* __restrict)datap;
while (size) {
bufferCheck();
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
const vluint8_t* __restrict maxp = dp + blk;
while (dp < maxp) *dp++ = *m_cp++;
size -= blk;
}
return *this; // For function chaining
}
// Read a datum and compare with expected value
bool readDiffers (const void* __restrict datap, size_t size);
VerilatedDeserialize& readAssert (const void* __restrict datap, size_t size);
VerilatedDeserialize& readAssert (vluint64_t data) { return readAssert(&data, sizeof(data)); }
VerilatedDeserialize& bufferCheck() {
// Flush the write buffer if there's not enough space left for new information
// We only call this once per vector, so we need enough slop for a very wide "b###" line
if (VL_UNLIKELY((m_cp+bufferInsertSize()) > m_endp)) {
fill();
}
return *this; // For function chaining
}
};
//=============================================================================
// VerilatedSave - serialize to a file
class VerilatedSave : public VerilatedSerialize {
private:
int m_fd; ///< File descriptor we're writing to
public:
// CREATORS
VerilatedSave() { m_fd=-1; }
virtual ~VerilatedSave() { close(); }
// METHODS
void open(const char* filenamep); ///< Open the file; call isOpen() to see if errors
void open(const string& filename) { open(filename.c_str()); }
virtual void close();
virtual void flush();
};
//=============================================================================
// VerilatedRestore - deserialize from a file
class VerilatedRestore : public VerilatedDeserialize {
private:
int m_fd; ///< File descriptor we're writing to
public:
// CREATORS
VerilatedRestore() { m_fd=-1; }
virtual ~VerilatedRestore() { close(); }
// METHODS
void open(const char* filenamep); ///< Open the file; call isOpen() to see if errors
void open(const string& filename) { open(filename.c_str()); }
virtual void close();
virtual void flush() {}
virtual void fill();
};
//=============================================================================
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint64_t& rhs) {
return os.write(&rhs, sizeof(rhs));
}
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint64_t& rhs){
return os.read(&rhs, sizeof(rhs));
}
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint32_t& rhs) {
return os.write(&rhs, sizeof(rhs));
}
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint32_t& rhs) {
return os.read(&rhs, sizeof(rhs));
}
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint16_t& rhs) {
return os.write(&rhs, sizeof(rhs));
}
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint16_t& rhs) {
return os.read(&rhs, sizeof(rhs));
}
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint8_t& rhs) {
return os.write(&rhs, sizeof(rhs));
}
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint8_t& rhs) {
return os.read(&rhs, sizeof(rhs));
}
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, bool& rhs) {
return os.write(&rhs, sizeof(rhs));
}
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, bool& rhs) {
return os.read(&rhs, sizeof(rhs));
}
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, double& rhs) {
return os.write(&rhs, sizeof(rhs));
}
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, double& rhs) {
return os.read(&rhs, sizeof(rhs));
}
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, float& rhs) {
return os.write(&rhs, sizeof(rhs));
}
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, float& rhs) {
return os.read(&rhs, sizeof(rhs));
}
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, string& rhs) {
vluint32_t len=rhs.length();
os<<len;
return os.write(rhs.data(), len);
}
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, string& rhs) {
vluint32_t len;
os>>len;
rhs.resize(len);
return os.read((void*)rhs.data(), len);
}
#endif // guard
+2 -2
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2014 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.
+12 -10
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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.
@@ -45,19 +45,20 @@ struct VerilatedCStrCmp {
//===========================================================================
/// Verilator range
// See also V3Ast::VNumRange
class VerilatedRange {
int m_lhs;
int m_rhs;
int m_left;
int m_right;
protected:
friend class VerilatedVar;
friend class VerilatedScope;
VerilatedRange() : m_lhs(0), m_rhs(0) {}
void sets(int lhs, int rhs) { m_lhs=lhs; m_rhs=rhs; }
VerilatedRange() : m_left(0), m_right(0) {}
void sets(int left, int right) { m_left=left; m_right=right; }
public:
~VerilatedRange() {}
int lhs() const { return m_lhs; }
int rhs() const { return m_rhs; }
int bits() const { return (VL_LIKELY(m_lhs>=m_rhs)?(m_lhs-m_rhs+1):(m_rhs-m_lhs+1)); }
int left() const { return m_left; }
int right() const { return m_right; }
int elements() const { return (VL_LIKELY(m_left>=m_right)?(m_left-m_right+1):(m_right-m_left+1)); }
};
//===========================================================================
@@ -92,7 +93,8 @@ public:
//======================================================================
/// Types
struct VerilatedVarNameMap : public map<const char*, VerilatedVar, VerilatedCStrCmp> {
class VerilatedVarNameMap : public map<const char*, VerilatedVar, VerilatedCStrCmp> {
public:
VerilatedVarNameMap() {}
~VerilatedVarNameMap() {}
};
+12 -4
View File
@@ -1,9 +1,9 @@
// -*- SystemC -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//=============================================================================
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2011 by Wilson Snyder. This program is free software;
// Copyright 2001-2014 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.
//
@@ -141,6 +141,7 @@ void VerilatedVcd::openNext (bool incFilename) {
if (m_filename[0]=='|') {
assert(0); // Not supported yet.
} else {
// cppcheck-suppress duplicateExpression
m_fd = ::open (m_filename.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK
, 0666);
if (m_fd<0) {
@@ -156,6 +157,8 @@ void VerilatedVcd::openNext (bool incFilename) {
void VerilatedVcd::makeNameMap() {
// Take signal information from each module and build m_namemapp
deleteNameMap();
m_nextCode = 1;
m_namemapp = new NameMap;
for (vluint32_t ent = 0; ent< m_callbacks.size(); ent++) {
VerilatedVcdCallInfo *cip = m_callbacks[ent];
@@ -182,15 +185,20 @@ void VerilatedVcd::makeNameMap() {
newname += hiername;
newmapp->insert(make_pair(newname,decl));
}
delete m_namemapp; m_namemapp=NULL;
deleteNameMap();
m_namemapp = newmapp;
}
}
void VerilatedVcd::deleteNameMap() {
if (m_namemapp) { delete m_namemapp; m_namemapp=NULL; }
}
VerilatedVcd::~VerilatedVcd() {
close();
if (m_wrBufp) { delete[] m_wrBufp; m_wrBufp=NULL; }
if (m_sigs_oldvalp) { delete[] m_sigs_oldvalp; m_sigs_oldvalp=NULL; }
deleteNameMap();
// Remove from list of traces
vector<VerilatedVcd*>::iterator pos = find(s_vcdVecp.begin(), s_vcdVecp.end(), this);
if (pos != s_vcdVecp.end()) { s_vcdVecp.erase(pos); }
@@ -413,7 +421,7 @@ void VerilatedVcd::dumpHeader () {
assert (m_modDepth==0);
// Reclaim storage
delete m_namemapp;
deleteNameMap();
}
void VerilatedVcd::module (string name) {
+9 -3
View File
@@ -1,9 +1,9 @@
// -*- SystemC -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//=============================================================================
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2011 by Wilson Snyder. This program is free software;
// Copyright 2001-2014 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.
//
@@ -57,7 +57,8 @@ typedef void (*VerilatedVcdCallback_t)(VerilatedVcd* vcdp, void* userthis, vluin
//=============================================================================
// VerilatedVcd
/// Create a SystemPerl VCD dump
/// Base class to create a Verilator VCD dump
/// This is an internally used class - see VerilatedVcdC for what to call from applications
class VerilatedVcd {
private:
@@ -100,6 +101,7 @@ private:
void closeErr();
void openNext();
void makeNameMap();
void deleteNameMap();
void printIndent (int levelchange);
void printStr (const char* str);
void printQuad (vluint64_t n);
@@ -400,8 +402,12 @@ public:
bool isOpen() const { return m_sptrace.isOpen(); }
// METHODS
/// Open a new VCD file
/// This includes a complete header dump each time it is called,
/// just as if this object was deleted and reconstructed.
void open (const char* filename) { m_sptrace.open(filename); }
/// Continue a VCD dump by rotating to a new file name
/// The header is only in the first file created, this allows
/// "cat" to be used to combine the header plus any number of data files.
void openNext (bool incFilename=true) { m_sptrace.openNext(incFilename); }
/// Set size in megabytes after which new file should be created
void rolloverMB(size_t rolloverMB) { m_sptrace.rolloverMB(rolloverMB); };
+2 -2
View File
@@ -1,9 +1,9 @@
// -*- SystemC -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//=============================================================================
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2011 by Wilson Snyder. This program is free software;
// Copyright 2001-2014 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
+4 -2
View File
@@ -1,9 +1,9 @@
// -*- SystemC -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//=============================================================================
//
// THIS MODULE IS PUBLICLY LICENSED
//
// Copyright 2001-2011 by Wilson Snyder. This program is free software;
// Copyright 2001-2014 by Wilson Snyder. This program is free software;
// you can redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
//
@@ -76,6 +76,8 @@ private:
#ifdef NC_SYSTEMC
// Cadence Incisive has these as abstract functions so we must create them
virtual void set_time_unit( int exponent10_seconds ) {} // deprecated
#endif
#if defined(NC_SYSTEMC) || (SYSTEMC_VERSION>=20111100)
virtual void set_time_unit( double v, sc_time_unit tu ) {}
#endif
+333 -2
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2009-2014 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,3 +31,334 @@ VerilatedVpi VerilatedVpi::s_s; // Singleton
vluint8_t* VerilatedVpio::s_freeHead = NULL;
//======================================================================
const char* VerilatedVpiError::strFromVpiVal(PLI_INT32 vpiVal) {
static const char *names[] = {
"*undefined*",
"vpiBinStrVal",
"vpiOctStrVal",
"vpiDecStrVal",
"vpiHexStrVal",
"vpiScalarVal",
"vpiIntVal",
"vpiRealVal",
"vpiStringVal",
"vpiVectorVal",
"vpiStrengthVal",
"vpiTimeVal",
"vpiObjTypeVal",
"vpiSuppressVal",
"vpiShortIntVal",
"vpiLongIntVal",
"vpiShortRealVal",
"vpiRawTwoStateVal",
"vpiRawFourStateVal",
};
if (vpiVal < 0) return names[0];
return names[(vpiVal<=vpiRawFourStateVal)?vpiVal:0];
}
const char* VerilatedVpiError::strFromVpiObjType(PLI_INT32 vpiVal) {
static const char *names[] = {
"*undefined*",
"vpiAlways",
"vpiAssignStmt",
"vpiAssignment",
"vpiBegin",
"vpiCase",
"vpiCaseItem",
"vpiConstant",
"vpiContAssign",
"vpiDeassign",
"vpiDefParam",
"vpiDelayControl",
"vpiDisable",
"vpiEventControl",
"vpiEventStmt",
"vpiFor",
"vpiForce",
"vpiForever",
"vpiFork",
"vpiFuncCall",
"vpiFunction",
"vpiGate",
"vpiIf",
"vpiIfElse",
"vpiInitial",
"vpiIntegerVar",
"vpiInterModPath",
"vpiIterator",
"vpiIODecl",
"vpiMemory",
"vpiMemoryWord",
"vpiModPath",
"vpiModule",
"vpiNamedBegin",
"vpiNamedEvent",
"vpiNamedFork",
"vpiNet",
"vpiNetBit",
"vpiNullStmt",
"vpiOperation",
"vpiParamAssign",
"vpiParameter",
"vpiPartSelect",
"vpiPathTerm",
"vpiPort",
"vpiPortBit",
"vpiPrimTerm",
"vpiRealVar",
"vpiReg",
"vpiRegBit",
"vpiRelease",
"vpiRepeat",
"vpiRepeatControl",
"vpiSchedEvent",
"vpiSpecParam",
"vpiSwitch",
"vpiSysFuncCall",
"vpiSysTaskCall",
"vpiTableEntry",
"vpiTask",
"vpiTaskCall",
"vpiTchk",
"vpiTchkTerm",
"vpiTimeVar",
"vpiTimeQueue",
"vpiUdp",
"vpiUdpDefn",
"vpiUserSystf",
"vpiVarSelect",
"vpiWait",
"vpiWhile",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"vpiAttribute",
"vpiBitSelect",
"vpiCallback",
"vpiDelayTerm",
"vpiDelayDevice",
"vpiFrame",
"vpiGateArray",
"vpiModuleArray",
"vpiPrimitiveArray",
"vpiNetArray",
"vpiRange",
"vpiRegArray",
"vpiSwitchArray",
"vpiUdpArray",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"*undefined*",
"vpiContAssignBit",
"vpiNamedEventArray",
"vpiIndexedPartSelect",
"*undefined*",
"*undefined*",
"vpiGenScopeArray",
"vpiGenScope",
"vpiGenVar"
};
if (vpiVal < 0) return names[0];
return names[(vpiVal<=vpiGenVar)?vpiVal:0];
}
const char* VerilatedVpiError::strFromVpiMethod(PLI_INT32 vpiVal) {
static const char *names[] = {
"vpiCondition",
"vpiDelay",
"vpiElseStmt",
"vpiForIncStmt",
"vpiForInitStmt",
"vpiHighConn",
"vpiLhs",
"vpiIndex",
"vpiLeftRange",
"vpiLowConn",
"vpiParent",
"vpiRhs",
"vpiRightRange",
"vpiScope",
"vpiSysTfCall",
"vpiTchkDataTerm",
"vpiTchkNotifier",
"vpiTchkRefTerm",
"vpiArgument",
"vpiBit",
"vpiDriver",
"vpiInternalScope",
"vpiLoad",
"vpiModDataPathIn",
"vpiModPathIn",
"vpiModPathOut",
"vpiOperand",
"vpiPortInst",
"vpiProcess",
"vpiVariables",
"vpiUse",
"vpiExpr",
"vpiPrimitive",
"vpiStmt"
};
if (vpiVal>vpiStmt || vpiVal<vpiCondition) {
return "*undefined*";
}
return names[vpiVal-vpiCondition];
}
const char* VerilatedVpiError::strFromVpiCallbackReason(PLI_INT32 vpiVal) {
static const char *names[] = {
"*undefined*",
"cbValueChange",
"cbStmt",
"cbForce",
"cbRelease",
"cbAtStartOfSimTime",
"cbReadWriteSynch",
"cbReadOnlySynch",
"cbNextSimTime",
"cbAfterDelay",
"cbEndOfCompile",
"cbStartOfSimulation",
"cbEndOfSimulation",
"cbError",
"cbTchkViolation",
"cbStartOfSave",
"cbEndOfSave",
"cbStartOfRestart",
"cbEndOfRestart",
"cbStartOfReset",
"cbEndOfReset",
"cbEnterInteractive",
"cbExitInteractive",
"cbInteractiveScopeChange",
"cbUnresolvedSystf",
"cbAssign",
"cbDeassign",
"cbDisable",
"cbPLIError",
"cbSignal",
"cbNBASynch",
"cbAtEndOfSimTime"
};
if (vpiVal < 0) return names[0];
return names[(vpiVal<=cbAtEndOfSimTime)?vpiVal:0];
}
const char* VerilatedVpiError::strFromVpiProp(PLI_INT32 vpiVal) {
static const char *names[] = {
"*undefined or other*",
"vpiType",
"vpiName",
"vpiFullName",
"vpiSize",
"vpiFile",
"vpiLineNo",
"vpiTopModule",
"vpiCellInstance",
"vpiDefName",
"vpiProtected",
"vpiTimeUnit",
"vpiTimePrecision",
"vpiDefNetType",
"vpiUnconnDrive",
"vpiDefFile",
"vpiDefLineNo",
"vpiScalar",
"vpiVector",
"vpiExplicitName",
"vpiDirection",
"vpiConnByName",
"vpiNetType",
"vpiExplicitScalared",
"vpiExplicitVectored",
"vpiExpanded",
"vpiImplicitDecl",
"vpiChargeStrength",
"vpiArray",
"vpiPortIndex",
"vpiTermIndex",
"vpiStrength0",
"vpiStrength1",
"vpiPrimType",
"vpiPolarity",
"vpiDataPolarity",
"vpiEdge",
"vpiPathType",
"vpiTchkType",
"vpiOpType",
"vpiConstType",
"vpiBlocking",
"vpiCaseType",
"vpiFuncType",
"vpiNetDeclAssign",
"vpiUserDefn",
"vpiScheduled",
"*undefined*",
"*undefined*",
"vpiActive",
"vpiAutomatic",
"vpiCell",
"vpiConfig",
"vpiConstantSelect",
"vpiDecompile",
"vpiDefAttribute",
"vpiDelayType",
"vpiIteratorType",
"vpiLibrary",
"*undefined*",
"vpiOffset",
"vpiResolvedNetType",
"vpiSaveRestartID",
"vpiSaveRestartLocation",
"vpiValid",
"vpiSigned",
"vpiStop",
"vpiFinish",
"vpiReset",
"vpiSetInteractiveScope",
"vpiLocalParam",
"vpiModPathHasIfNone",
"vpiIndexedPartSelectType",
"vpiIsMemory",
"vpiIsProtected"
};
if (vpiVal == vpiUndefined) {
return "vpiUndefined";
}
return names[(vpiVal<=vpiIsProtected)?vpiVal:0];
}
+778 -156
View File
File diff suppressed because it is too large Load Diff
+25 -2
View File
@@ -1,7 +1,7 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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.
@@ -78,8 +78,12 @@
# 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"
#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"
#endif
#ifdef _MSC_VER
@@ -91,6 +95,16 @@
// 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
//=========================================================================
// C++-2011
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define VL_HAS_UNIQUE_PTR
# define VL_UNIQUE_PTR unique_ptr
#else
# define VL_UNIQUE_PTR auto_ptr
#endif
//=========================================================================
// Warning disabled
@@ -185,6 +199,15 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
# endif
#endif
//=========================================================================
// File system functions
#ifdef _WIN32
# define VL_DEV_NULL "nul"
#else // Linux or compliant Unix flavors
# define VL_DEV_NULL "/dev/null"
#endif
//=========================================================================
// Integer size macros
+12 -6
View File
@@ -7,7 +7,7 @@
* This file contains the constant definitions, structure definitions,
* and routine declarations used by SystemVerilog DPI.
*
* This file is from the SystemVerilog IEEE 1800-2009 Annex I.
* This file is from the SystemVerilog IEEE 1800-2012 Annex I.
*/
#ifndef INCLUDED_SVDPI
@@ -27,25 +27,31 @@ typedef signed __int32 int32_t;
typedef signed __int8 int8_t;
#elif defined(__MINGW32__)
#include <stdint.h>
#elif defined(__linux)
#elif defined(__APPLE__)
#include <stdint.h>
#elif defined(__linux) || (defined(__APPLE__) && defined(__MACH__))
#include <inttypes.h>
#else
#include <sys/types.h>
#endif
/* Use to export a symbol from application */
#if defined (_MSC_VER)
/* Use to import a symbol into dll */
#ifndef DPI_DLLISPEC
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
#define DPI_DLLISPEC __declspec(dllimport)
#else
#define DPI_DLLISPEC
#endif
#endif
/* Use to import a symbol into application */
#if defined (_MSC_VER)
/* Use to export a symbol from dll */
#ifndef DPI_DLLESPEC
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
#define DPI_DLLESPEC __declspec(dllexport)
#else
#define DPI_DLLESPEC
#endif
#endif
/* Use to mark a function as external */
#ifndef DPI_EXTERN
+22 -22
View File
@@ -1,7 +1,7 @@
/*******************************************************************************
* vpi_user.h
*
* IEEE Std 1800 Programming Language Interface (PLI)
* IEEE Std 1800-2012 Programming Language Interface (PLI)
*
* This file contains the constant definitions, structure definitions, and
* routine declarations used by the SystemVerilog Verification Procedural
@@ -37,7 +37,7 @@ typedef signed __int32 int32_t;
typedef signed __int8 int8_t;
#elif defined(__MINGW32__)
#include <stdint.h>
#elif defined(__linux)
#elif defined(__linux) || (defined(__APPLE__) && defined(__MACH__))
#include <inttypes.h>
#else
#include <sys/types.h>
@@ -61,9 +61,9 @@ typedef char PLI_BYTE8;
typedef unsigned char PLI_UBYTE8;
#endif
/* Use to export a symbol */
/* Use to import a symbol */
#if WIN32
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
#ifndef PLI_DLLISPEC
#define PLI_DLLISPEC __declspec(dllimport)
#define VPI_USER_DEFINED_DLLISPEC 1
@@ -74,9 +74,9 @@ typedef unsigned char PLI_UBYTE8;
#endif
#endif
/* Use to import a symbol */
/* Use to export a symbol */
#if WIN32
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
#ifndef PLI_DLLESPEC
#define PLI_DLLESPEC __declspec(dllexport)
#define VPI_USER_DEFINED_DLLESPEC 1
@@ -438,12 +438,12 @@ typedef PLI_UINT32 *vpiHandle;
#define vpiPlusOp 2 /* unary plus */
#define vpiNotOp 3 /* unary not */
#define vpiBitNegOp 4 /* bitwise negation */
#define vpiUnaryAndOp 5 /* bitwise reduction and */
#define vpiUnaryNandOp 6 /* bitwise reduction nand */
#define vpiUnaryOrOp 7 /* bitwise reduction or */
#define vpiUnaryNorOp 8 /* bitwise reduction nor */
#define vpiUnaryXorOp 9 /* bitwise reduction xor */
#define vpiUnaryXNorOp 10 /* bitwise reduction xnor */
#define vpiUnaryAndOp 5 /* bitwise reduction AND */
#define vpiUnaryNandOp 6 /* bitwise reduction NAND */
#define vpiUnaryOrOp 7 /* bitwise reduction OR */
#define vpiUnaryNorOp 8 /* bitwise reduction NOR */
#define vpiUnaryXorOp 9 /* bitwise reduction XOR */
#define vpiUnaryXNorOp 10 /* bitwise reduction XNOR */
#define vpiSubOp 11 /* binary subtraction */
#define vpiDivOp 12 /* binary division */
#define vpiModOp 13 /* binary modulus */
@@ -459,17 +459,17 @@ typedef PLI_UINT32 *vpiHandle;
#define vpiRShiftOp 23 /* binary right shift */
#define vpiAddOp 24 /* binary addition */
#define vpiMultOp 25 /* binary multiplication */
#define vpiLogAndOp 26 /* binary logical and */
#define vpiLogOrOp 27 /* binary logical or */
#define vpiBitAndOp 28 /* binary bitwise and */
#define vpiBitOrOp 29 /* binary bitwise or */
#define vpiBitXorOp 30 /* binary bitwise xor */
#define vpiBitXNorOp 31 /* binary bitwise xnor */
#define vpiLogAndOp 26 /* binary logical AND */
#define vpiLogOrOp 27 /* binary logical OR */
#define vpiBitAndOp 28 /* binary bitwise AND */
#define vpiBitOrOp 29 /* binary bitwise OR */
#define vpiBitXorOp 30 /* binary bitwise XOR */
#define vpiBitXNorOp 31 /* binary bitwise XNOR */
#define vpiBitXnorOp vpiBitXNorOp /* added with 1364-2001 */
#define vpiConditionOp 32 /* ternary conditional */
#define vpiConcatOp 33 /* n-ary concatenation */
#define vpiMultiConcatOp 34 /* repeated concatenation */
#define vpiEventOrOp 35 /* event or */
#define vpiEventOrOp 35 /* event OR */
#define vpiNullOp 36 /* null operation */
#define vpiListOp 37 /* list of expressions */
#define vpiMinTypMaxOp 38 /* min:typ:max: delay expression */
@@ -536,7 +536,7 @@ typedef PLI_UINT32 *vpiHandle;
same subtypes as vpiNetType */
#define vpiSaveRestartID 62 /* unique ID for save/restart data */
#define vpiSaveRestartLocation 63 /* name of save/restart data file */
/* vpiValid,vpiValidTrue,vpiValidFalse are deprecated in 1800-2009 */
/* vpiValid,vpiValidTrue,vpiValidFalse were deprecated in 1800-2009 */
#define vpiValid 64 /* reentrant task/func frame or automatic
variable is valid */
#define vpiValidFalse 0
@@ -661,7 +661,7 @@ typedef struct t_vpi_arrayvalue
{
PLI_INT32 *integers; /* integer values */
PLI_INT16 *shortints; /* short integer values */
PLI_INT16 *longints; /* long integer values */
PLI_INT64 *longints; /* long integer values */
PLI_BYTE8 *rawvals; /* 2/4-state vector elements */
struct t_vpi_vecval *vectors; /* 4-state vector elements */
struct t_vpi_time *times; /* time values */
@@ -944,7 +944,7 @@ XXTERN PLI_INT32 vpi_compare_objects PROTO_PARAMS((vpiHandle object1,
vpiHandle object2));
XXTERN PLI_INT32 vpi_chk_error PROTO_PARAMS((p_vpi_error_info
error_info_p));
/* vpi_free_object() is deprecated in 1800-2009 */
/* vpi_free_object() was deprecated in 1800-2009 */
XXTERN PLI_INT32 vpi_free_object PROTO_PARAMS((vpiHandle object));
XXTERN PLI_INT32 vpi_release_handle PROTO_PARAMS((vpiHandle object));
XXTERN PLI_INT32 vpi_get_vlog_info PROTO_PARAMS((p_vpi_vlog_info
+603 -75
View File
@@ -14,32 +14,6 @@ the first for reference for developers and debugging problems.
See also the Verilator internals presentation at http://www.veripool.org.
=head1 ADDING A NEW FEATURE
Generally what would you do to add a new feature?
=over 4
File a bug (if there isn't already) so others know what you're working on.
Make a testcase in the test_regress/t/t_EXAMPLE format, see TESTING Below.
If grammar changes are needed, look at the git version of VerilogPerl's
src/VParseGrammar.y, as this grammar supports the full SystemVerilog
language and has a lot of back-and-forth with Verilator's grammar. Copy
the appropriate rules to src/verilog.y and modify the productions.
If a new Ast type is needed, add it to V3AstNodes.h.
Now you can run "test_regress/t/t_{new testcase}.pl --debug" and it'll
probably fail but you'll see a test_regress/obj_dir/t_{newtestcase}/*.tree
file which you can examine to see if the parsing worked. See also the
sections below on debugging.
Modify the later visitor functions to process the new feature as needed.
=back
=head1 CODE FLOWS
=head2 Verilator Flow
@@ -52,7 +26,11 @@ preprocessing, then lexical analysis with Flex and parsing with Bison.
This produces an abstract syntax tree (AST) representation of the design,
which is what is visible in the .tree files described below.
Cells are then linked, which will read and parse additional files as above.
Verilator then makes a series of passes over the AST, progressively refining
and optimizing it.
Cells in the AST first linked, which will read and parse additional files as
above.
Functions, variable and other references are linked to their definitions.
@@ -62,7 +40,7 @@ Verilator then performs many additional edits and optimizations on the
hierarchical design. This includes coverage, assertions, X elimination,
inlining, constant propagation, and dead code elimination.
References in the design are then psudo-flattened. Each module's variables
References in the design are then pseudo-flattened. Each module's variables
and functions get "Scope" references. A scope reference is an occurrence of
that un-flattened variable in the flattened hierarchy. A module that occurs
only once in the hierarchy will have a single scope and single VarScope for
@@ -71,7 +49,7 @@ occurrence, and two VarScopes for each variable. This allows optimizations
to proceed across the flattened design, while still preserving the
hierarchy.
Additional edits and optimizations proceed on the psudo-flat design. These
Additional edits and optimizations proceed on the pseudo-flat design. These
include module references, function inlining, loop unrolling, variable
lifetime analysis, lookup table creation, always splitting, and logic gate
simplifications (pushing inverters, etc).
@@ -87,6 +65,96 @@ hints, and performs additional constant propagation.
Verilator finally writes the C++ modules.
=head2 Key Classes Used in the Verilator Flow
=over 4
=item C<AstNode>
The AST is represented at the top level by the class C<AstNode>. This abstract
class has derived classes for the individual components (e.g. C<AstGenerate>
for a generate block) or groups of components (e.g. C<AstNodeFTask> for
functions and tasks, which in turn has C<AstFunc> and C<AstTask> as derived
classes).
Each C<AstNode> has pointers to up to four children, accessed by the
C<op1p> through C<op4p> methods. These methods are then abstracted in a
specific Ast* node class to a more specific name. For example with the
C<AstIf> node (for C<if> statements), C<ifsp> calls C<op2p> to give the
pointer to the AST for the "then" block, while C<elsesp> calls C<op3p> to
give the pointer to the AST for the "else" block, or NULL if there is not
one.
C<AstNode> has the concept of a next and previous AST - for example the
next and previous statements in a block. Pointers to the AST for these
statements (if they exist) can be obtained using the C<back> and C<next>
methods.
It is useful to remember that the derived class C<AstNetlist> is at the top
of the tree, so checking for this class is the standard way to see if you
are at the top of the tree.
By convention, each function/method uses the variable C<nodep> as a pointer
to the C<AstNode> currently being processed.
=item C<AstNVisitor>
The passes are implemented by AST visitor classes (see L</Visitor
Functions>). These are implemented by subclasses of the abstract class,
C<AstNVisitor>. Each pass creates an instance of the visitor class, which
in turn implements a method to perform the pass.
=item C<V3Graph>
A number of passes use graph algorithms, and the class C<V3Graph> is provided
to represent those graphs. Graphs are directed, and algorithms are provided to
manipulate the graphs and to output them in I<GraphViz> dot format (see
L<http://www.graphviz.org/>). C<V3Graph.h> provides documentation of this
class.
=item C<V3GraphVertex>
This is the base class for vertices in a graph. Vertices have an associated
C<fanout>, C<color> and C<rank>, which may be used in algorithms for ordering
the graph. A generic C<user>/C<userp> member variable is also provided.
Virtual methods are provided to specify the name, color, shape and style to be
used in dot output. Typically users provide derived classes from
C<V3GraphVertex> which will reimplement these methods.
Iterators are provided to access in and out edges. Typically these are used in
the form:
for (V3GraphEdge *edgep = vertexp->inBeginp();
edgep;
edgep = edgep->inNextp()) {
=item C<V3GraphEdge>
This is the base class for directed edges between pairs of vertices. Edges
have an associated C<weight> and may also be made C<cutable>. A generic
C<user>/C<userp> member variable is also provided.
Accessors, C<fromp> and C<top> return the "from" and "to" vertices
respectively.
Virtual methods are provided to specify the label, color and style to be
used in dot output. Typically users provided derived classes from
C<V3GraphEdge> which will reimplement these methods.
=item C<V3GraphAlg>
This is the base class for graph algorithms. It implements a C<bool> method,
C<followEdge> which algorithms can use to decide whether an edge is
followed. This method returns true if the graph edge has weight greater than
one and a user function, C<edgeFuncp> (supplied in the constructor) returns
C<true>.
A number of predefined derived algorithm classes and access methods are
provided and documented in C<V3GraphAlg.cpp>.
=back
=head2 Verilated Flow
The evaluation loop outputted by Verilator is designed to allow a single
@@ -120,64 +188,338 @@ changed; if clear, checking those signals for changes may be skipped.
To match the indentation of Verilator C++ sources, use 4 spaces per level,
and leave tabs at 8 columns, so every other indent level is a tab stop.
In Emacs, use in your ~/.emacs
All files should contain the magic header to insure standard indentation:
(add-hook 'c-mode-common-hook '(lambda ()
(c-set-style "cc-mode"))))
// -*- mode: C++; c-file-style: "cc-mode" -*-
This sets indentation to the cc-mode defaults. (Verilator predates a
CC-mode change of several years ago which overrides the defaults with GNU
style indentation; the c-set-style undoes that.)
=head2 The C<astgen> script
Some of the code implementing passes is extremely repetitive, and must be
implemented for each sub-class of C<AstNode>. However, while repetitive,
there is more variability than can be handled in C++ macros.
In Verilator this is implemented by using a Perl script, C<astgen> to
pre-process the C++ code. For example in C<V3Const.cpp> this is used to
implement the C<visit()> functions for each binary operation using the
TREEOP macro.
The original C++ source code is transformed into C++ code in the C<obj_opt>
and C<obj_dbg> sub-directories (the former for the optimized version of
Verilator, the latter for the debug version). So for example C<V3Const.cpp>
into C<V3Const__gen.cpp>.
=head2 Visitor Functions
There's three ways data is passed between visitor functions.
Verilator uses the I<Visitor> design pattern to implement its refinement
and optimization passes. This allows separation of the pass algorithm from
the AST on which it operates. Wikipedia provides an introduction to the
concept at L<http://en.wikipedia.org/wiki/Visitor_pattern>.
1. A visitor-class member variable. This is generally for passing "parent"
information down to children. m_modp is a common example. It's set to
NULL in the constructor, where that node (AstModule visitor) sets it, then
the children are iterated, then it's cleared. Children under an AstModule
will see it set, while nodes elsewhere will see it clear. If there can be
nested items (for example an AstFor under an AstFor) the variable needs to
be save-set-restored in the AstFor visitor, otherwise exiting the lower for
will loose the upper for's setting.
As noted above, all visitors are derived classes of C<AstNVisitor>. All
derived classes of C<AstNode> implement the C<accept> method, which takes
as argument a reference to an instance or a C<AstNVisitor> derived class
and applies the visit method of the C<AstNVisitor> to the invoking AstNode
instance (i.e. C<this>).
One possible difficulty is that a call to C<accept> may perform an edit
which destroys the node it receives as argument. The
C<acceptSubtreeReturnEdits> method of C<AstNode> is provided to apply
C<accept> and return the resulting node, even if the original node is
destroyed (if it is not destroyed it will just return the original node).
The behavior of the visitor classes is achieved by overloading the C<visit>
function for the different C<AstNode> derived classes. If a specific
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)
There are three ways data is passed between visitor functions.
=over 4
=item 1.
A visitor-class member variable. This is generally for passing "parent"
information down to children. C<m_modp> is a common example. It's set to
NULL in the constructor, where that node (C<AstModule> visitor) sets it,
then the children are iterated, then it's cleared. Children under an
C<AstModule> will see it set, while nodes elsewhere will see it clear. If
there can be nested items (for example an C<AstFor> under an C<AstFor>) the
variable needs to be save-set-restored in the C<AstFor> visitor, otherwise
exiting the lower for will lose the upper for's setting.
=item 2.
User attributes. Each C<AstNode> (B<Note.> The AST node, not the visitor)
has five user attributes, which may be accessed as an integer using the
C<user1()> through C<user5()> methods, or as a pointer (of type
C<AstNUser>) using the C<user1p()> through C<user5p()> methods (a common
technique lifted from graph traversal packages).
2. User() attributes. Each node has 5 ->user() number or ->userp() pointer
utility values (a common technique lifted from graph traversal packages).
A visitor first clears the one it wants to use by calling
AstNode::user#ClearTree(), then it can mark any node's user() with whatever
data it wants. Readers just call nodep->user(), but may need to cast
appropriately, so you'll often see nodep->userp()->castSOMETYPE(). At the
top of each visitor are comments describing how the user() stuff applies to
that visitor class. For example:
C<AstNode::user#ClearTree()>, then it can mark any node's user() with whatever
data it wants. Readers just call C<< nodep->user() >>, but may need to cast
appropriately, so you'll often see C<< nodep->userp()->castSOMETYPE() >>. At
the top of each visitor are comments describing how the C<user()> stuff
applies to that visitor class. For example:
// NODE STATE
// Cleared entire netlist
// AstModule::user1p() // bool. True to inline this module
This says that at the AstNetlist user1ClearTree() is called. Each
AstModule's is user1() is used to indicate if we're going to inline it.
This says that at the C<AstNetlist> C<user1ClearTree()> is called. Each
C<AstModule>'s C<user1()> is used to indicate if we're going to inline it.
These comments are important to make sure a user#() on a given AstNode type
is never being used for two different purposes.
These comments are important to make sure a C<user#()> on a given C<AstNode>
type is never being used for two different purposes.
Note that calling user#ClearTree is fast, it doesn't walk the tree, so it's
ok to call fairly often. For example, it's commonly called on every
Note that calling C<user#ClearTree> is fast, it doesn't walk the tree, so
it's ok to call fairly often. For example, it's commonly called on every
module.
3. Parameters can be passed between the visitors in close to the "normal"
function caller to callee way. This is the second "vup" parameter that is
ignored on most of the visitor functions. V3Width does this, but it proved
more messy than the above and is deprecated. (V3Width was nearly the first
module written. Someday this scheme may be removed, as it slows the
program down to have to pass vup everywhere.)
=item 3.
Parameters can be passed between the visitors in close to the "normal"
function caller to callee way. This is the second C<vup> parameter of type
C<AstNUser> that is ignored on most of the visitor functions. V3Width does
this, but it proved more messy than the above and is deprecated. (V3Width
was nearly the first module written. Someday this scheme may be removed,
as it slows the program down to have to pass vup everywhere.)
=back
=head2 Iterators
C<AstNode> provides a set of iterators to facilitate walking over the
tree. Each takes two arguments, a visitor, C<v>, of type C<AstNVisitor> and
an optional pointer user data, C<vup>, of type C<AstNUser*>. The second is
one of the ways to pass parameters to visitors described in L</Visitor
Functions>, but its use is now deprecated and should I<not> be used for new
visitor classes.
=over 4
=item C<iterate()>
This just applies the C<accept> method of the C<AstNode> to the visitor
function.
=item C<iterateAndNextIgnoreEdit>
Applies the C<accept> method of each C<AstNode> in a list (i.e. connected
by C<nextp> and C<backp> pointers).
=item C<iterateAndNext>
Applies the C<accept> method of each C<AstNode> in a list. If a node is
edited by the call to C<accept>, apply C<accept> again, until the node does
not change.
=item C<iterateListBackwards>
Applies the C<accept> method of each C<AstNode> in a list, starting with
the last one.
=item C<iterateChildren>
Apply the C<iterateAndNext> method on each child C<op1p> through C<op4p> in
turn.
=item C<iterateChildrenBackwards>
Apply the C<iterateListBackwards> method on each child C<op1p> through
C<op4p> in turn.
=back
=head3 Caution on Using Iterators When Child Changes
Visitors often replace one node with another node; V3Width and V3Const are
major examples. A visitor which is the parent of such a replacement needs
to be aware that calling iteration may cause the children to change. For
example:
// nodep->lhsp() is 0x1234000
nodep->lhsp()->iterateAndNext(...); // and under covers nodep->lhsp() changes
// nodep->lhsp() is 0x5678400
nodep->lhsp()->iterateAndNext(...);
Will work fine, as even if the first iterate causes a new node to take the
place of the lhsp(), that edit will update nodep->lhsp() and the second
call will correctly see the change. Alternatively:
lp = nodep->lhsp();
// nodep->lhsp() is 0x1234000, lp is 0x1234000
lp->iterateAndNext(...); **lhsp=NULL;** // and under covers nodep->lhsp() changes
// nodep->lhsp() is 0x5678400, lp is 0x1234000
lp->iterateAndNext(...);
This will cause bugs or a core dump, as lp is a dangling pointer. Thus it
is advisable to set lhsp=NULL shown in the *'s above to make sure these
dangles are avoided. Another alternative used in special cases mostly in
V3Width is to use acceptSubtreeReturnEdits, which operates on a single node
and returns the new pointer if any. Note acceptSubtreeReturnEdits does not
follow nextp() links.
lp = lp->acceptSubtreeReturnEdits()
=head2 Identifying derived classes
A common requirement is to identify the specific C<AstNode> class we are
dealing with. For example a visitor might not implement separate C<visit>
methods for C<AstIf> and C<AstGenIf>, but just a single method for the base
class:
void visit (AstNodeIf* nodep, AstNUser* vup)
However that method might want to specify additional code if it is called
for C<AstGenIf>. Verilator does this by providing a C<castSOMETYPE()>
method for each possible node type, using C++ C<dynamic_cast>. This either
returns a pointer to the object cast to that type (if it is of class
C<SOMETYPE>, or a derived class of C<SOMETYPE>) or else NULL. So our
C<visit> method could use:
if (nodep->castAstGenIf()) {
<code specific to AstGenIf>
}
A common test is for C<AstNetlist>, which is the node at the root of the
AST.
=head1 TESTING
To write a test see notes in the forum and in the verilator.txt manual.
For an overview of how to write a test see the BUGS section of the
Verilator primary manual.
Note you can run the regression tests in parallel; see the
test_regress/driver.pl script -j flag.
It is important to add tests for failures as well as success (for example to
check that an error message is correctly triggered).
Tests that fail should by convention have the suffix C<_bad> in their name,
and include C<fails =E<gt> 1> in either their C<compile> or C<execute> step as
appropriate.
=head2 Controlling the Test Driver
Test drivers are written in PERL. All invoke the main test driver script,
which can provide detailed help on all the features available when writing
a test driver.
test_regress/t/driver.pl --help
For convenience, a summary of the most commonly used features is provided
here. All drivers require a call to C<compile> subroutine to compile the
test. For run-time tests, this is followed by a call to the C<execute>
subroutine. Both of these functions can optionally be provided with a hash
table as argument specifying additional options.
The test driver assumes by default that the source Verilog file name
matches the PERL driver name. So a test whose driver is C<t/t_mytest.pl>
will expect a Verilog source file C<t/t_mytest.v>. This can be changed
using the C<top_filename> subroutine, for example
top_filename("t/t_myothertest.v");
By default all tests will run with major simulators (Icarus Verilog, NC,
VCS, ModelSim) as well as Verilator, to allow results to be
compared. However if you wish a test only to be used with Verilator, you
can use the following:
$Self->{vlt} or $Self->skip("Verilator only test");
Of the many options that can be set through arguments to C<compiler> and
C<execute>, the following are particularly useful:
=over 4
=item C<verilator_flags2>
A list of flags to be passed to verilator when compiling.
=item C<fails>
Set to 1 to indicate that the compilation or execution is intended to fail.
=back
For example the following would specify that compilation requires two
defines and is expected to fail.
compile (
verilator_flags2 => ["-DSMALL_CLOCK -DGATED_COMMENT"],
fails => 1,
);
=head2 Regression Testing for Developers
Developers will also want to call ./configure with two extra flags:
=over 4
=item --enable-ccwarn
Causes the build to stop on warnings as well as errors. A good way to
ensure no sloppy code gets added, however it can be painful when it comes
to testing, since third party code used in the tests (e.g. SystemC) may not
be warning free.
=item --enable-longtests
In addition to the standard C, SystemC and SystemPerl tests also run the
tests in the C<test_vcs>, C<test_verilated> and C<test_regress> directories
when using I<make test>. This is disabled by default as SystemC/SystemPerl
installation problems would otherwise falsely indicate a Verilator problem.
=back
When enabling the long tests, some additional PERL modules are needed, which
you can install using cpan.
cpan install Unix::Processors
There are some traps to avoid when running regression tests
=over 4
=item *
The regression tests will assume that you have a version of SystemPerl to
match. Typically if working on Verilator from git, also use SystemPerl from
git.
=item *
When checking the MANIFEST, the test will barf on unexpected code in the
Verilator tree. So make sure to keep any such code outside the tree.
=item *
Not all Linux systems install Perldoc by default. This is needed for the
I<--help> option to Verilator, and also for regression testing. This can be
installed using cpan:
cpan install Pod::Perldoc
Many Linux systems also offer a standard package for this. Red
Hat/Fedora/Centos offer I<perl-Pod-Perldoc>, while Debian/Ubuntu/Linux Mint
offer I<perl-doc>.
=item *
Running regression may exhaust resources on some Linux systems, particularly
file handles and user processes. Increase these to respectively 16,384 and
4,096. The method of doing this is system dependent, but on Fedora Linux it
would require editing the C</etc/security/limits.conf> file as root.
=back
=head1 DEBUGGING
@@ -207,27 +549,32 @@ viewers let us know; ZGRViewer isn't great for large graphs.
Tree files are dumps of the AST Tree and are produced between every major
algorithmic stage. An example:
NETLIST 0x90fb00 <e1> {a0} w0
1: MODULE 0x912b20 <e8822> {a8} w0 top L2 [P]
*1:2: VAR 0x91a780 <e74#> {a22} w70 out_wide [O] WIRE
1:2:1: BASICDTYPE 0x91a3c0 <e73> {a22} w70 [logic]
NETLIST 0x90fb00 <e1> {a0}
1: MODULE 0x912b20 <e8822> {a8} top L2 [P]
*1:2: VAR 0x91a780 <e74#> {a22} @dt=0xa2e640(w32) out_wide [O] WIRE
1:2:1: BASICDTYPE 0xa2e640 <e2149> {e24} @dt=this(sw32) integer kwd=integer range=[31:0]
=over 4
"1:2:" indicates the hierarchy the VAR is op2p under the MODULE.
The following summarizes the above example dump, with more detail on each
field in the section below.
"1:2:" indicates the hierarchy of the C<VAR> is the C<op2p> pointer under
the C<MODULE>, which in turn is the C<op1p> pointer under the C<NETLIST>
"VAR" is the AstNodeType.
"0x91a780" is the address of this node.
"<e74>" means the 74th edit to the netlist was the last modification to
this node. A trailing # indicates this node changed since the last tree
dump was made. You can gdb break on this edit; see below.
this node.
"{a22}" indicates this node is related to line 22 in the source filename
"a", where "a" is the first file read, "z" the 36th, and "aa" the 37th.
"a", where "a" is the first file read, "z" the 26th, and "aa" the 27th.
"w70" indicates the width is 70 bits. sw70 would be signed 70 bits.
"@dt=0x..." indicates the address of the data type this node contains.
"w32" indicates the width is 32 bits.
"out_wide" is the name of the node, in this case the name of the variable.
@@ -236,22 +583,203 @@ variable is an output.
=back
In more detail the following fields are dumped common to all nodes. They
are produced by the C<AstNode::dump()> method:
=over 4
=item Tree Hierarchy
The dump lines begin with numbers and colons to indicate the child node
hierarchy. As noted above in L</Key Classes Used in the Verilator Flow>,
C<AstNode> has lists of items at the same level in the AST, connected by
the C<nextp()> and C<prevp()> pointers. These appear as nodes at the same
level. For example after inlining:
NETLIST 0x929c1c8 <e1> {a0} w0
1: MODULE 0x92bac80 <e3144> {e14} w0 TOP_t L1 [P]
1:1: CELLINLINE 0x92bab18 <e3686#> {e14} w0 v -> t
1:1: CELLINLINE 0x92bc1d8 <e3688#> {e24} w0 v__DOT__i_test_gen -> test_gen
...
1: MODULE 0x92b9bb0 <e503> {e47} w0 test_gen L3
...
=item AstNode type
The textual name of this node AST type (always in capitals). Many of these
correspond directly to Verilog entities (for example C<MODULE> and
C<TASK>), but others are internal to Verialtor (for example C<NETLIST> and
C<BASICDTYPE>).
=item Address of the node
A hexadecimal address of the node in memory. Useful for examining with the
debugger.
=item Last edit number
Of the form C<< <ennnn> >> or C<< <ennnn#> >> , where C<nnnn> is the number
of the last edit to modify this node. The trailing C<#> indicates the node
has been edited since the last tree dump (which typically means in the last
refinement or optimization pass). GDB can watch for this, see L</Debugging
with GDB>.
=item Source file and line
Of the form C<< {xxnnnn} >>, where C{xx} is the filename letter (or
letters) and C<nnnn> is the line number within that file. The first file is
C<a>, the 26th is C<z>, the 27th is C<aa> and so on.
=item User pointers
Shows the value of the node's user1p...user5p, if non-NULL.
=item Data type
Many nodes have an explicit data type. "@dt=0x..." indicates the address
of the data type (AstNodeDType) this node uses.
If a data type is present and is numeric, it then prints the width of the
item. This field is a sequence of flag characters and width data as follows:
C<s> if the node is signed.
C<d> if the node is a double (i.e a floating point entity).
C<w> always present, indicating this is the width field.
C<u> if the node is unsized.
C</nnnn> if the node is unsized, where C<nnnn> is the minimum width.
=item Name of the entity represented by the node if it exists
For example for a C<VAR> it is the name of the variable.
=back
Many nodes follow these fields with additional node specific
information. Thus the C<VARREF> node will print either C<[LV]> or C<[RV]>
to indicate a left value or right value, followed by the node of the
variable being referred to. For example:
1:2:1:1: VARREF 0x92c2598 <e509> {e24} w0 clk [RV] <- VAR 0x92a2e90 <e79> {e18} w0 clk [I] INPUT
In general, examine the C<dump()> method in C<V3AstNodes.cpp> of the node
type in question to determine additional fields that may be printed.
The C<MODULE> has a list of C<CELLINLINE> nodes referred to by its
C<op1p()> pointer, connected by C<nextp()> and C<prevp()> pointers.
Similarly the C<NETLIST> has a list of modules referred to by its C<op1p()>
pointer.
=head2 Debugging with GDB
The test_regress/driver.pl script accepts --debug --gdb to start Verilator
under gdb. You can also use --debug --gdbbt to just backtrace and then
exit gdb.
under gdb and break when an error is hit or the program is about to exit.
You can also use --debug --gdbbt to just backtrace and then exit gdb. To
debug the Verilated executable, use --gdbsim.
If you wish to start Verilator under GDB (or another debugger), then you
can use --debug and look at the underlying invocation of verilator_dgb. For
example
t/t_alw_dly.pl --debug
shows it invokes the command:
../verilator_bin_dbg --prefix Vt_alw_dly --x-assign unique --debug
-cc -Mdir obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v
Start GDB, then C<start> with the remaining arguments.
gdb ../verilator_bin_dbg
...
(gdb) start --prefix Vt_alw_dly --x-assign unique --debug -cc -Mdir
obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v
> obj_dir/t_alw_dly/vlt_compile.log
...
Temporary breakpoint 1, main (argc=13, argv=0xbfffefa4, env=0xbfffefdc)
at ../Verilator.cpp:615
615 ios::sync_with_stdio();
(gdb)
You can then continue execution with breakpoints as required.
To break at a specific edit number which changed a node (presumably to find
what made a <e####> line in the tree dumps):
watch AstNode::s_editCntGbl==####
To print a node:
pn nodep
# or: call nodep->dumpGdb() # aliased to "pn" in src/.gdbinit
pnt nodep
# or: call nodep->dumpTreeGdb() # aliased to "pnt" in src/.gdbinit
When GDB halts, it is useful to understand that the backtrace will commonly
show the iterator functions between each invocation of C<visit> in the
backtrace. You will typically see a frame sequence something like
...
visit()
iterateChildren()
iterateAndNext()
accept()
visit()
...
=head1 ADDING A NEW FEATURE
Generally what would you do to add a new feature?
=over 4
=item 1.
File a bug (if there isn't already) so others know what you're working on.
=item 2.
Make a testcase in the test_regress/t/t_EXAMPLE format, see L<TESTING>.
=item 3.
If grammar changes are needed, look at the git version of VerilogPerl's
src/VParseGrammar.y, as this grammar supports the full SystemVerilog
language and has a lot of back-and-forth with Verilator's grammar. Copy
the appropriate rules to src/verilog.y and modify the productions.
=item 4.
If a new Ast type is needed, add it to V3AstNodes.h.
=back
Now you can run "test_regress/t/t_{new testcase}.pl --debug" and it'll
probably fail but you'll see a test_regress/obj_dir/t_{newtestcase}/*.tree
file which you can examine to see if the parsing worked. See also the
sections above on debugging.
Modify the later visitor functions to process the new feature as needed.
=head2 Adding a new pass
For more substantial changes you may need to add a new pass. The simplest way
to do this is to copy the C<.cpp> and C<.h> files from an existing
pass. You'll need to add a call into your pass from the C<process()> function
in C<src/verilator.cpp>.
To get your pass to build you'll need to add its binary filename to the list
in C<src/Makefile_obj.in> and reconfigure.
=head1 DISTRIBUTION
The latest version is available from L<http://www.veripool.org/>.
Copyright 2008-2011 by Wilson Snyder. Verilator is free software; you can
Copyright 2008-2014 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-2011 by Wilson Snyder. This package is free software; you
# Copyright 2007-2014 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-2011 by Wilson Snyder. This package is free software; you
# Copyright 2007-2014 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-2011 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2014 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-2011 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2014 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-2011 by Wilson Snyder. This package is free software; you
# Copyright 2007-2014 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.
+24 -2
View File
@@ -13,6 +13,7 @@ use vars qw ($Debug);
# main
our $Opt_Stage = 0;
our $Opt_Jobs = calc_jobs();
autoflush STDOUT 1;
autoflush STDERR 1;
@@ -21,11 +22,13 @@ if (! GetOptions (
"debug" => sub { $Debug = 1; },
"<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; },
"stage=i" => \$Opt_Stage,
"j=i" => \$Opt_Jobs,
)) {
die "%Error: Bad usage, try 'install_test --help'\n";
}
test();
exit(0);
#######################################################################
@@ -47,7 +50,7 @@ sub test {
run("/bin/rm -rf $blddir");
run("/bin/mkdir -p $blddir");
run("cd $blddir && $srcdir/configure --prefix $prefix");
run("cd $blddir && make -j");
run("cd $blddir && make -j $Opt_Jobs");
}
# Install it under the prefix
@@ -121,6 +124,16 @@ sub cleanenv {
#######################################################################
sub calc_jobs {
my $ok = eval "
use Unix::Processors;
return Unix::Processors->new->max_online;
";
$ok && !$@ or return 1;
print "driver.pl: Found $ok cores, using -j ",$ok+1,"\n" if $Debug;
return $ok + 1;
}
sub run {
# Run a system command, check errors
my $command = shift;
@@ -157,11 +170,20 @@ required.
Displays this message and program version and exits.
=item -j I<jobs>
Specify make -j flag. Defaults to number of cores + 1 if Perl's
Unix::Processors is installed, else 1.
=item -stage I<stage>
Runs a specific test stage (see the script).
=back
=head1 DISTRIBUTION
Copyright 2009-2011 by Wilson Snyder. This package is free software; you
Copyright 2009-2014 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-2011 by Wilson Snyder. This package is free software; you
Copyright 2005-2014 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-2011 by Wilson Snyder. This package is free software; you
Copyright 2007-2014 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-2011 by Wilson Snyder. This package is free software; you
Copyright 2005-2014 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`;
eval `modulecmd perl add synopsys-vcs_mx`;
exec('vcs',@ARGV);
#######################################################################
@@ -28,7 +28,7 @@ invoke_vcs - Invoke tool under "modules" command
=head1 DISTRIBUTION
Copyright 2005-2011 by Wilson Snyder. This package is free software; you
Copyright 2005-2014 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 2010-2011 by Wilson Snyder. This package is free software; you
# Copyright 2010-2014 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-2011 by Wilson Snyder. Verilator is free software; you can
Copyright 2005-2014 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.
+22 -30
View File
@@ -9,7 +9,7 @@ This is the Verilator Package README file.
=head1 DISTRIBUTION
This package is Copyright 2003-2011 by Wilson Snyder. (Report bugs to
This package is Copyright 2003-2014 by Wilson Snyder. (Report bugs to
L<http://www.veripool.org/>.)
Verilator is free software; you can redistribute it and/or modify it under
@@ -24,14 +24,14 @@ more details.
=head1 DESCRIPTION
Verilator converts synthesizable (not behavioral) Verilog code into C++ or
SystemC code. It is not a complete simulator, just a translator.
Verilator converts synthesizable (generally not behavioral) Verilog code
into C++ or SystemC code. It is not a complete simulator, just a
translator.
Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It
reads the specified Verilog code, lints it, and optionally adds coverage
code. For C++ format, it outputs .cpp and .h files. For SystemC format,
it outputs .sp files for the SystemPerl preprocessor available at
http://www.veripool.org.
it outputs .cpp and .h files using the standard SystemC headers.
The resulting files are then compiled with C++. The user writes a little
C++ wrapper file, which instantiates the top level module. This is
@@ -41,14 +41,11 @@ The resulting executable will perform the actual simulation.
=head1 SUPPORTED SYSTEMS
Verilator is developed and has primary testing on:
SuSE 11.1 AMD64 i686-linux-2.6.27, GCC 4.3.2
Versions have also built on Redhat Linux, Macs OS-X, HPUX and Solaris. It
should run with minor porting on any Linix-ish platform. Verilator also
works on Windows under Cygwin, and Windows under MinGW (gcc -mno-cygwin).
Verilated output (not Verilator itself) compiles under MSVC++ 2008.
Verilator is developed and has primary testing on Ubuntu. Versions have
also built on Redhat Linux, Macs OS-X, HPUX and Solaris. It should run
with minor porting on any Linix-ish platform. Verilator also works on
Windows under Cygwin, and Windows under MinGW (gcc -mno-cygwin). Verilated
output (not Verilator itself) compiles under MSVC++ 2008 and newer.
=head1 INSTALLATION
@@ -71,15 +68,11 @@ Download the latest package from that site, and decompress.
=item
If you will be using SystemC (vs straight C++ output), download SystemC
2.0.1 from L<http://www.systemc.org>. Follow their installation
instructions. You will need to set the SYSTEMC environment variable to
point to this download. Also, setenv SYSTEMC_ARCH to the architecture name
you used with SystemC, generally 'linux' or 'cygwin'.
Verilator assumes you did a make in the SystemC kit directory and SYSTEMC
points to that directory. There must be appropriate files in
C<$SYSTEMC/include> and C<$SYSTEMC/lib-linux> for SystemC compilation to
work.
from L<http://www.systemc.org>. Follow their installation instructions.
You will need to set SYSTEMC_INCLUDE to point to the include directory with
systemc.h in it, and SYSTEMC_LIBDIR to points to the directory with
libsystemc.a in it. (Older installations may set SYSTEMC and SYSTEMC_ARCH
instead.)
=item
@@ -101,8 +94,8 @@ C<cd> to the Verilator directory containing this README.
You now have to decide how you're going to eventually install the kit.
Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC,
SYSTEMC_ARCH, SYSTEMPERL, and SYSTEMPERL_INCLUDE as defaults into the
Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC_INCLUDE,
SYSTEMC_LIBDIR, SYSTEMPERL, and SYSTEMPERL_INCLUDE as defaults into the
executable, so try to have them correct before configuring.
=over 4
@@ -111,7 +104,7 @@ executable, so try to have them correct before configuring.
Our personal favorite is to always run Verilator from the kit directory.
This allows the easiest experimentation and upgrading. It's also how most
EDA tools operate; to run any of them you point to the tarball.
EDA tools operate; to run you point to the tarball, no install is needed.
export VERILATOR_ROOT=`pwd` # if your shell is bash
setenv VERILATOR_ROOT `pwd` # if your shell is csh
@@ -160,11 +153,10 @@ PATH.
Type C<make> to compile Verilator.
Type C<make test_c> to check the compilation.
Type C<make test> to check the compilation.
Type C<make test> for a more complete test. You may get a error about the
Bit::Vector Perl package. You will need to install it and SystemPerl if
you want all tests to pass.
Configure with C<--enable-longtests> for more complete developer tests.
Additional packages may be required for these tests.
You may get a error about a typedef conflict for uint32_t. Edit
verilated.h to change the typedef to work, probably to @samp{typedef
@@ -199,7 +191,7 @@ The directories in the kit after de-taring are as follows:
bin/verilator => Compiler Wrapper invoked to Verilate code
include/ => Files that should be in your -I compiler path
include/verilated*.cpp => Global routines to link into your simulator
include/verilated.h => Global headers
include/verilated*.h => Global headers
include/verilated.v => Stub defines for linting
include/verilated.mk => Common makefile
src/ => Translator source code
-197
View File
@@ -1,197 +0,0 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename readme.info
@settitle Verilator Installation
@c %**end of header
@c DESCRIPTION: TexInfo: DOCUMENT source run through texinfo to produce README file
@c Use 'make README' to produce the output file
@c Before release, run C-u C-c C-u C-a (texinfo-all-menus-update)
@node Top, Copyright, (dir), (dir)
@chapter Verilator
This is the Verilator Package.
@menu
* Copyright::
* Description::
* Obtaining Distribution::
* Directory Structure::
* Supported Systems::
* Installation::
* Limitations::
@end menu
@node Copyright, Description, Top, Top
@section Copyright
This package is Copyright 2003-2011 by Wilson Snyder @email{wsnyder@@wsnyder.org}.
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. (See the
documentation for more details.)
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
@node Description, Obtaining Distribution, Copyright, Top
@section Description
Verilator converts synthesizable (not behavioral) Verilog code into C++ or
SystemC code. It is not a complete simulator, just a translator.
Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It
reads the specified Verilog code, lints it, and optionally adds coverage
code. For C++ format, it outputs .cpp and .h files. For SystemC format,
it outputs .sp files for the SystemPerl preprocessor available at
http://www.veripool.org.
The resulting files are then compiled with C++. The user writes a little
C++ wrapper file, which instantiates the top level module. This is
compiled in C++, and linked with the Verilated files.
The resulting executable will perform the actual simulation.
@node Obtaining Distribution, Directory Structure, Description, Top
@section Obtaining Distribution
The latest version is available at
@uref{http://www.veripool.org/verilator}
Download the latest package from that site, and decompress.
@samp{tar xvzf verilator_version.tgz}
@node Directory Structure, Supported Systems, Obtaining Distribution, Top
@section Directory Structure
The directories after de-taring are as follows:
@itemize @bullet
@item bin/verilator => Compiler Wrapper invoked on user Verilog code
@item include/ => Files that should be in your -I compiler path
@item include/verilated.cpp => Global routines to link into your simulator
@item include/verilated.h => Global headers
@item include/verilated.v => Stub defines for linting
@item include/verilated.mk => Common makefile
@item src/ => Translator source code
@item test_v => Example Verilog code for other test dirs
@item test_c => Example Verilog->C++ conversion
@item test_sc => Example Verilog->SystemC conversion
@item test_sp => Example Verilog->SystemPerl conversion
@item test_vcs => Example Verilog->VCS conversion (test the test)
@item test_verilated => Internal tests
@item test_regress => Internal tests
@end itemize
@node Supported Systems, Installation, Directory Structure, Top
@section Supported Systems
This version of verilator has been built and tested on:
@itemize @bullet
@item SuSE AMD64 i686-linux-2.6.5
@end itemize
Other users report success with Redhat Linux 2.4, Windows under
Cygwin, HPUX and Solaris. It should run with minor porting on any
Unix system.
@node Installation, Limitations, Supported Systems, Top
@section Installation
@enumerate
@item
If you will be using SystemC (vs straight C++ output), download
SystemC 2.0.1 from @url{http://www.systemc.org}. Follow their
installation instructions. As described in the System-Perl README,
you will need to set SYSTEMC and/or SYSTEMC_KIT to point to this
download. Also, set SYSTEMC_ARCH to the architecture name you used
with SystemC, generally 'linux' or 'cygwin'.
@item
If you will be using SystemC, download and install Verilog-Perl,
@url{http://search.cpan.org/search?module=Verilog::Language}.
@item
If you will be using SystemC, download and install System-Perl,
@url{http://search.cpan.org/search?module=SystemC::Netlist}. Note
you'll need to set a @samp{SYSTEMPERL} environment variable to point
to the downloaded kit. Optionally also set @samp{SYSTEMPERL_INCLUDE}
to point to the installed headers.
@item
@code{cd} to the Verilator directory containing this README.
@item
Type @samp{./configure} to configure Verilator for your system.
If you are configuring Verilator to be part of a RPM or other
distribution package system, you may want to use the --enable-defenv
configure flag. This will take the current value of VERILATOR_ROOT,
SYSTEMC, SYSTEMC_ARCH, SYSTEMPERL, and SYSTEMPERL_INCLUDE and build
them as defaults into the executable.
@item
Type @samp{make} to compile Verilator.
On Cygwin (Windows) you may get a error about libperl.a not being
found. You need to copy your perl libraries as follows.
@enumerate
@item
Type @samp{perl -MExtUtils::Embed -e ldopts}
@item
It will show a directory name ending in /CORE. cd to that directory.
@item
@samp{cp libperl5_6_1.a libperl.a}
@item
@samp{cp libperl5_6_1.dll libperl.dll}
@item
@samp{cp libperl5_6_1.def libperl.def}
@end enumerate
@item
Type @samp{make test} to check the compilation.
You may get a error about the Bit::Vector perl package. You will need to install
it if you want the tests to pass. (Try @samp{make test_c} for a smaller test that
doesn't require it.)
You may get a error about a typedef conflict for uint32_t. Edit verilated.h to change
the typedef to work, probably to @samp{typedef unsigned long uint32_t;}.
If you get warnings, you might want to edit @samp{include/verilated.mk} to delete the
lines that define VK_CPPFLAGS_WALL.
@item
There is no installation at present; this package runs from the
distribution directory. Programs should set the environment variable
VERILATOR_ROOT to point to this distribution, then execute
$VERILATOR_ROOT/bin/verilator, which will find the path to all needed
files.
Verilator assumes you did a make in the SystemC kit directory. If not, you will need
to populate @samp{$SYSTEMC/include} and @samp{$SYSTEMC/lib-linux} appropriately.
If you will be modifying Verilator, you will probably want a second
stable copy of this kit for others to use while you experiment.
@item
Detailed documentation and the man page can be seen by running:
bin/verilator --help
or reading verilator.txt in the same directory as this README.
@end enumerate
@node Limitations, , Installation, Top
@section Limitations
See verilator.txt (or execute @samp{bin/verilator --help}) for limitations.
+34
View File
@@ -0,0 +1,34 @@
# DESCRIPTION: Verilator: GDB startup file with useful defines
#
# Copyright 2012-2014 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.
define pn
call $arg0->dumpGdb()
end
document pn
Verilator: Print single AstNode NODEP
end
define pnt
call $arg0->dumpTreeGdb()
end
document pnt
Verilator: Print AstNode NODEP's tree
end
define dtf
call AstNode::dumpTreeFileGdb(0)
end
document dtf
Verilator: Dump AstNode tree to file
end
define watchedit
watch AstNode::s_editCntGbl==$arg0
end
document watchedit
Verilator: Create watch on where a edit number is made
end
+5 -3
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2014 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,12 +65,14 @@ dbg: ../verilator_bin_dbg
cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj
prefiles::
ifneq ($(UNDER_GIT),) # If local git tree... Else don't burden users
prefiles:: config_rev.h
ifneq ($(UNDER_GIT),) # If local git tree... Else don't burden users
# This output goes into srcdir if locally configured, as we need to distribute it as part of the kit.
config_rev.h: ${srcdir}/config_rev.pl ${srcdir}/../.git/logs/HEAD
$(PERL) ${srcdir}/config_rev.pl ${srcdir} >$@
else
config_rev.h: ${srcdir}/config_rev.pl
$(PERL) ${srcdir}/config_rev.pl ${srcdir} >$@
endif
maintainer-copy::
+6 -3
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2014 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,7 @@ config_srcdir = @srcdir@
ifeq ($(config_srcdir),.)
srcdir = ..
else # Run an experiment
ifeq ($(shell -e $(config_srcdir)/../Makefile_obj.in),)
ifeq ($(wildcard $(config_srcdir)/../Makefile_obj.in),)
srcdir = $(config_srcdir)
else
srcdir = $(config_srcdir)/..
@@ -111,6 +111,8 @@ endif
ifeq ($(CFG_WITH_DEFENV),yes)
CPPFLAGS += -DDEFENV_SYSTEMC=\"$(SYSTEMC)\"
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
@@ -180,6 +182,7 @@ RAW_OBJS = \
V3EmitCSyms.o \
V3EmitMk.o \
V3EmitV.o \
V3EmitXml.o \
V3Error.o \
V3Expand.o \
V3File.o \
@@ -195,7 +198,6 @@ RAW_OBJS = \
V3Inst.o \
V3Life.o \
V3LifePost.o \
V3Link.o \
V3LinkCells.o \
V3LinkDot.o \
V3LinkJump.o \
@@ -217,6 +219,7 @@ RAW_OBJS = \
V3SplitAs.o \
V3Stats.o \
V3StatsReport.o \
V3String.o \
V3Subst.o \
V3Table.o \
V3Task.o \
+21 -16
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity active domains
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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.
@@ -163,16 +162,22 @@ public:
// Active AssignDly replacement functions
class ActiveDlyVisitor : public ActiveBaseVisitor {
public:
enum CheckType { CT_SEQ, CT_COMBO, CT_INITIAL };
private:
bool m_combo; // Combo logic
CheckType m_check; // Combo logic or other
AstNode* m_alwaysp; // Always we're under
AstNode* m_assignp; // In assign
// VISITORS
virtual void visit(AstAssignDly* nodep, AstNUser*) {
if (m_combo) {
if (m_check != CT_SEQ) {
// Convert to a non-delayed assignment
UINFO(5," ASSIGNDLY "<<nodep<<endl);
nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=).");
if (m_check == CT_INITIAL) {
nodep->v3warn(INITIALDLY,"Delayed assignments (<=) in initial or final block; suggest blocking assignments (=).");
} else {
nodep->v3warn(COMBDLY,"Delayed assignments (<=) in non-clocked (non flop or latch) block; suggest blocking assignments (=).");
}
AstNode* newp = new AstAssign (nodep->fileline(),
nodep->lhsp()->unlinkFrBack(),
nodep->rhsp()->unlinkFrBack());
@@ -181,7 +186,7 @@ private:
}
}
virtual void visit(AstAssign* nodep, AstNUser*) {
if (!m_combo) {
if (m_check == CT_SEQ) {
AstNode* las = m_assignp;
m_assignp = nodep;
nodep->lhsp()->iterateAndNext(*this);
@@ -190,7 +195,7 @@ private:
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
AstVar* varp=nodep->varp();
if (!m_combo
if (m_check == CT_SEQ
&& m_assignp
&& !varp->isUsedLoopIdx() // Ignore loop indicies
&& !varp->isTemp()
@@ -212,9 +217,9 @@ private:
}
public:
// CONSTUCTORS
ActiveDlyVisitor(AstNode* nodep, bool combo) {
ActiveDlyVisitor(AstNode* nodep, CheckType check) {
m_alwaysp = nodep;
m_combo = combo;
m_check = check;
m_assignp = NULL;
nodep->accept(*this);
}
@@ -251,6 +256,7 @@ private:
virtual void visit(AstInitial* nodep, AstNUser*) {
// Relink to IACTIVE, unless already under it
UINFO(4," INITIAL "<<nodep<<endl);
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
AstActive* wantactivep = m_namer.getIActive(nodep->fileline());
nodep->unlinkFrBack();
wantactivep->addStmtsp(nodep);
@@ -283,8 +289,9 @@ private:
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
return;
}
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
if (!m_scopeFinalp) {
m_scopeFinalp = new AstCFunc(nodep->fileline(), "_final", m_namer.scopep());
m_scopeFinalp = new AstCFunc(nodep->fileline(), "_final_"+m_namer.scopep()->nameDotless(), m_namer.scopep());
m_scopeFinalp->argTypes(EmitCBaseVisitor::symClassVar());
m_scopeFinalp->addInitsp(new AstCStmt(nodep->fileline(), EmitCBaseVisitor::symTopAssign()+"\n"));
m_scopeFinalp->dontCombine(true);
@@ -319,12 +326,10 @@ private:
bool sequent = m_itemSequent;
if (!combo && !sequent) combo=true; // If no list, Verilog 2000: always @ (*)
#ifndef NEW_ORDERING
if (combo && sequent) {
nodep->v3error("Unsupported: Mixed edge (pos/negedge) and activity (no edge) sensitive activity list");
sequent = false;
}
#endif
AstActive* wantactivep = NULL;
if (combo && !sequent) {
@@ -353,10 +358,10 @@ private:
// Warn and/or convert any delayed assignments
if (combo && !sequent) {
ActiveDlyVisitor dlyvisitor (nodep, true);
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_COMBO);
}
else if (!combo && sequent) {
ActiveDlyVisitor dlyvisitor (nodep, false);
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_SEQ);
}
}
virtual void visit(AstAlways* nodep, AstNUser*) {
@@ -394,7 +399,7 @@ private:
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
} else if (nodep->varrefp()) {
// V3LinkResolve should have cleaned most of these up
if (nodep->varrefp()->width()>1) nodep->v3error("Unsupported: Non-single bit wide signal pos/negedge sensitivity: "
if (!nodep->varrefp()->width1()) nodep->v3error("Unsupported: Non-single bit wide signal pos/negedge sensitivity: "
<<nodep->varrefp()->prettyName());
m_itemSequent = true;
nodep->varrefp()->varp()->usedClock(true);
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity block domains
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+2 -3
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity active domains
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity block domains
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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.
+82 -19
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Collect and print statistics
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2005-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2014 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.
@@ -57,12 +56,13 @@ private:
+":"+cvtToStr(nodep->fileline()->lineno())
+": Assertion failed in %m"
+((message != "")?": ":"")+message
+"\\n");
+"\n");
}
void replaceDisplay(AstDisplay* nodep, const string& prefix) {
nodep->displayType(AstDisplayType::DT_WRITE);
nodep->fmtp()->text(assertDisplayMessage(nodep, prefix, nodep->fmtp()->text()));
AstNode* timesp = nodep->fmtp()->exprsp(); if (timesp) timesp->unlinkFrBack();
// cppcheck-suppress nullPointer
timesp = timesp->addNext(new AstTime(nodep->fileline()));
nodep->fmtp()->exprsp(timesp);
if (!nodep->fmtp()->scopeNamep() && nodep->fmtp()->formatScopeTracking()) {
@@ -73,25 +73,31 @@ private:
AstNode* newIfAssertOn(AstNode* nodep) {
// Add a internal if to check assertions are on.
// Don't make this a AND term, as it's unlikely to need to test this.
return new AstIf (nodep->fileline(),
// If assertions are off, have constant propagation rip them out later
// This allows syntax errors and such to be detected normally.
(v3Global.opt.assertOn()
? (AstNode*)(new AstCMath(nodep->fileline(), "Verilated::assertOn()", 1))
: (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicFalse()))),
nodep, NULL);
AstNode* newp
= new AstIf (nodep->fileline(),
// If assertions are off, have constant propagation rip them out later
// This allows syntax errors and such to be detected normally.
(v3Global.opt.assertOn()
? (AstNode*)(new AstCMath(nodep->fileline(), "Verilated::assertOn()", 1))
: (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicFalse()))),
nodep, NULL);
newp->user1(true); // Don't assert/cover this if
return newp;
}
AstNode* newIfCoverageOn(AstNode* nodep) {
// Add a internal if to check coverage is on
// Don't make this a AND term, as it's unlikely to need to test this.
return new AstIf (nodep->fileline(),
// If assertions are off, have constant propagation rip them out later
// This allows syntax errors and such to be detected normally.
(v3Global.opt.coverage()
? (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicTrue()))
: (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicFalse()))),
nodep, NULL);
AstNode* newp
= new AstIf (nodep->fileline(),
// If assertions are off, have constant propagation rip them out later
// This allows syntax errors and such to be detected normally.
(v3Global.opt.coverage()
? (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicTrue()))
: (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicFalse()))),
nodep, NULL);
newp->user1(true); // Don't assert/cover this if
return newp;
}
AstNode* newFireAssert(AstNode* nodep, const string& message) {
@@ -137,6 +143,7 @@ private:
if (nodep->castPslAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
//
AstNode* newp = new AstAlways (nodep->fileline(),
VAlwaysKwd::ALWAYS,
sentreep,
bodysp);
// Install it
@@ -173,11 +180,67 @@ private:
// Bye
pushDeletep(nodep); nodep=NULL;
}
virtual void visit(AstIf* nodep, AstNUser*) {
if (nodep->user1SetOnce()) return;
if (nodep->uniquePragma() || nodep->unique0Pragma()) {
AstNodeIf* ifp = nodep;
AstNode* propp = NULL;
bool hasDefaultElse = false;
do {
// If this statement ends with 'else if', then nextIf will point to the
// nextIf statement. Otherwise it will be null.
AstNodeIf* nextifp = dynamic_cast<AstNodeIf*>(ifp->elsesp());
ifp->condp()->iterateAndNext(*this);
// 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) {
propp = new AstConcat(nodep->fileline(), predp, propp);
} else {
propp = predp;
}
// Record if this ends with an 'else' that does not have an if
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)
? (new AstOneHot0(nodep->fileline(), propp))->castNode()
: (new AstOneHot (nodep->fileline(), propp))->castNode());
AstIf* checkifp = new AstIf (nodep->fileline(),
new AstLogNot (nodep->fileline(), ohot),
newFireAssert(nodep, "'unique if' statement violated"),
newifp);
checkifp->branchPred(AstBranchPred::BP_UNLIKELY);
nodep->replaceWith(checkifp);
pushDeletep(nodep);
} else {
nodep->iterateChildren(*this);
}
}
// VISITORS //========== Case assertions
virtual void visit(AstCase* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (!nodep->user1Inc()) {
if (!nodep->user1SetOnce()) {
bool has_default=false;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
if (itemp->isDefault()) has_default=true;
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Assertion expansion
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2005-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+2 -3
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Collect and print statistics
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2005-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Assertion pre-expansion
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2005-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2014 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.
+135 -29
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Ast node structures
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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,6 +51,9 @@ bool AstUser3InUse::s_userBusy=false;
bool AstUser4InUse::s_userBusy=false;
bool AstUser5InUse::s_userBusy=false;
int AstNodeDType::s_uniqueNum = 0;
//######################################################################
// V3AstType
@@ -71,14 +73,12 @@ void AstNode::init() {
m_op3p = NULL;
m_op4p = NULL;
m_iterpp = NULL;
m_dtypep = NULL;
m_clonep = NULL;
m_cloneCnt = 0;
// Attributes
m_numeric = (int)AstNumeric::UNSIGNED;
m_didWidth = false;
m_doingWidth = false;
m_width = 0;
m_widthMin = 0;
m_user1p = NULL;
m_user1Cnt = 0;
m_user2p = NULL;
@@ -228,15 +228,6 @@ string AstNode::quoteName(const string& namein) {
return out;
}
int AstNode::widthPow2() const {
// I.e. width 30 returns 32, width 32 returns 32.
uint32_t width = this->width();
for (int p2=30; p2>=0; p2--) {
if (width > (1UL<<p2)) return (1UL<<(p2+1));
}
return 1;
}
//######################################################################
// Insertion
@@ -245,9 +236,12 @@ inline void AstNode::debugTreeChange(const char* prefix, int lineno, bool next)
// Called on all major tree changers.
// Only for use for those really nasty bugs relating to internals
// Note this may be null.
//if (debug()) cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<": "<<(void*)this<<endl;
//if (debug()) cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<": "<<(void*)this<<" <e"<<AstNode::s_editCntGbl<<">"<<endl;
//if (debug()) {
// cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<endl;
// // Commenting out the section below may crash, as the tree state
// // between edits is not always consistent for printing
// cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<endl;
// v3Global.rootp()->dumpTree(cout,"-treeChange: ");
// if (next||1) this->dumpTreeAndNext(cout, prefix);
// else this->dumpTree(cout, prefix);
@@ -570,7 +564,7 @@ void AstNode::relink(AstNRelinker* linkerp) {
if (linkerp->m_iterpp) {
// If we're iterating over a next() link, we need to follow links off the
// NEW node. Thus we pass iteration information via a pointer in the node.
// This adds a unfortunate 4 bytes to every AstNode, but is faster than passing
// This adds a unfortunate hot 8 bytes to every AstNode, but is faster than passing
// across every function.
// If anyone has a cleaner way, I'd be grateful.
*(linkerp->m_iterpp) = newp;
@@ -719,6 +713,7 @@ void AstNode::deleteTree() {
if (!this) return;
UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n");
this->debugTreeChange("-delTree: ", __LINE__, true);
this->editCountInc();
// MUST be depth first!
deleteTreeIter();
}
@@ -758,6 +753,20 @@ void AstNode::iterateChildren(AstNVisitor& v, AstNUser* vup) {
if (m_op4p) m_op4p->iterateAndNext(v, vup);
}
void AstNode::iterateChildrenConst(AstNVisitor& v, AstNUser* vup) {
// This is a very hot function
if (!this) return;
ASTNODE_PREFETCH(m_op1p);
ASTNODE_PREFETCH(m_op2p);
ASTNODE_PREFETCH(m_op3p);
ASTNODE_PREFETCH(m_op4p);
// if () not needed since iterateAndNext accepts null this, but faster with it.
if (m_op1p) m_op1p->iterateAndNextConst(v, vup);
if (m_op2p) m_op2p->iterateAndNextConst(v, vup);
if (m_op3p) m_op3p->iterateAndNextConst(v, vup);
if (m_op4p) m_op4p->iterateAndNextConst(v, vup);
}
void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
// This is a very hot function
// IMPORTANT: If you replace a node that's the target of this iterator,
@@ -766,18 +775,24 @@ void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
// Future versions of this function may require the node to have a back to be iterated;
// there's no lower level reason yet though the back must exist.
AstNode* nodep=this;
#ifdef VL_DEBUG // Otherwise too hot of a function for debug
if (VL_UNLIKELY(nodep && !nodep->m_backp)) nodep->v3fatalSrc("iterateAndNext node has no back");
#endif
while (nodep) {
AstNode* niterp = nodep;
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");
// cppcheck-suppress nullPointer
niterp->m_iterpp = &niterp;
niterp->accept(v, vup);
// accept may do a replaceNode and change niterp on us...
if (!niterp) return;
//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
niterp->m_iterpp = NULL;
if (VL_UNLIKELY(niterp!=nodep)) { // Edited it
if (VL_UNLIKELY(niterp!=nodep)) { // Edited node inside accept
nodep = niterp;
} else { // Same node, just loop
} else { // Unchanged node, just continue loop
nodep = niterp->m_nextp;
}
}
@@ -803,11 +818,12 @@ void AstNode::iterateChildrenBackwards(AstNVisitor& v, AstNUser* vup) {
this->op4p()->iterateListBackwards(v,vup);
}
void AstNode::iterateAndNextIgnoreEdit(AstNVisitor& v, AstNUser* vup) {
void AstNode::iterateAndNextConst(AstNVisitor& v, AstNUser* vup) {
// Keep following the current list even if edits change it
if (!this) return;
for (AstNode* nodep=this; nodep; ) {
AstNode* nnextp = nodep->m_nextp;
ASTNODE_PREFETCH(nnextp);
nodep->accept(v, vup);
nodep = nnextp;
}
@@ -854,6 +870,9 @@ AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
void AstNode::cloneRelinkTree() {
if (!this) return;
for (AstNode* nodep=this; nodep; nodep=nodep->m_nextp) {
if (m_dtypep && m_dtypep->clonep()) {
m_dtypep = m_dtypep->clonep()->castNodeDType();
}
nodep->cloneRelink();
nodep->m_op1p->cloneRelinkTree();
nodep->m_op2p->cloneRelinkTree();
@@ -874,8 +893,7 @@ bool AstNode::sameTreeIter(AstNode* node2p, bool ignNext) {
if (this==NULL && node2p==NULL) return true;
if (this==NULL || node2p==NULL) return false;
if (this->type() != node2p->type()
|| this->width() != node2p->width()
|| this->numeric() != node2p->numeric()
|| this->dtypep() != node2p->dtypep()
|| !this->same(node2p)) {
return false;
}
@@ -947,6 +965,34 @@ void AstNode::checkTree() {
}
}
void AstNode::dumpGdb() { // For GDB only
if (!this) { cout<<"This=NULL"<<endl; return; }
dumpGdbHeader();
cout<<" "; dump(cout); cout<<endl;
}
void AstNode::dumpGdbHeader() const { // For GDB only
if (!this) { cout<<"This=NULL"<<endl; return; }
dumpPtrs(cout);
cout<<" Fileline = "<<fileline()<<endl;
}
void AstNode::dumpTreeGdb() { // For GDB only
if (!this) { cout<<"This=NULL"<<endl; return; }
dumpGdbHeader();
dumpTree(cout);
}
void AstNode::dumpTreeFileGdb(const char* filenamep) { // For GDB only
string filename = filenamep ? filenamep : v3Global.debugFilename("debug.tree",98);
v3Global.rootp()->dumpTreeFile(filename);
}
void AstNode::checkIter() const {
if (m_iterpp) {
dumpPtrs(cout);
// Perhaps something forgot to clear m_iterpp?
this->v3fatalSrc("Iteration link should be NULL");
}
}
void AstNode::dumpPtrs(ostream& os) const {
os<<"This="<<typeName()<<" "<<(void*)this;
os<<" back="<<(void*)backp();
@@ -990,14 +1036,16 @@ void AstNode::dumpTreeAndNext(ostream& os, const string& indent, int maxDepth) {
}
}
void AstNode::dumpTreeFile(const string& filename, bool append) {
if (v3Global.opt.dumpTree()) {
void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
if (v3Global.opt.dumpTree() && doDump) {
{ // Write log & close
UINFO(2,"Dumping "<<filename<<endl);
const auto_ptr<ofstream> logsp (V3File::new_ofstream(filename, append));
if (logsp->fail()) v3fatalSrc("Can't write "<<filename);
*logsp<<"Tree Dump from <e"<<dec<<editCountLast()<<">";
*logsp<<"Verilator Tree Dump (format 0x3900) from <e"<<dec<<editCountLast()<<">";
*logsp<<" to <e"<<dec<<editCountGbl()<<">"<<endl;
if (editCountGbl()==editCountLast()) {
if (editCountGbl()==editCountLast()
&& !(v3Global.opt.dumpTree()>=9)) {
*logsp<<endl;
*logsp<<"No changes since last dump!\n";
} else {
@@ -1022,7 +1070,7 @@ void AstNode::v3errorEnd(ostringstream& str) const {
nsstr<<str.str();
if (debug()) {
nsstr<<endl;
nsstr<<"-node: "<<this<<endl;
nsstr<<"-node: "; ((AstNode*)this)->dump(nsstr); nsstr<<endl;
}
m_fileline->v3errorEnd(nsstr);
} else {
@@ -1030,6 +1078,64 @@ void AstNode::v3errorEnd(ostringstream& str) const {
}
}
string AstNode::warnMore() const {
if (this) return this->fileline()->warnMore();
else return V3Error::warnMore();
}
//======================================================================
// Data type conversion
void AstNode::dtypeChgSigned(bool flag) {
if (!dtypep()) this->v3fatalSrc("No dtype when changing to (un)signed");
dtypeChgWidthSigned(dtypep()->width(), dtypep()->widthMin(),
flag ? AstNumeric::SIGNED : AstNumeric::UNSIGNED);
}
void AstNode::dtypeChgWidth(int width, int widthMin) {
if (!dtypep()) this->v3fatalSrc("No dtype when changing width"); // Use ChgWidthSigned(...UNSIGNED) otherwise
dtypeChgWidthSigned(width, widthMin, dtypep()->numeric());
}
void AstNode::dtypeChgWidthSigned(int width, int widthMin, AstNumeric numeric) {
if (!dtypep()) {
// We allow dtypep() to be null, as before/during widthing dtypes are not resolved
dtypeSetLogicSized(width, widthMin, numeric);
} else {
if (width==dtypep()->width()
&& widthMin==dtypep()->widthMin()
&& numeric==dtypep()->numeric()) return; // Correct already
// FUTURE: We may be pointing at a two state data type, and this may
// convert it to logic. Since the AstVar remains correct, we
// work OK but this assumption may break in the future.
// Note we can't just clone and do a widthForce, as if it's a BasicDType
// the msb() indications etc will be incorrect.
dtypeSetLogicSized(width, widthMin, numeric);
}
}
AstNodeDType* AstNode::findBasicDType(AstBasicDTypeKwd kwd) const {
// For 'simple' types we use the global directory. These are all unsized.
// More advanced types land under the module/task/etc
return v3Global.rootp()->typeTablep()
->findBasicDType(fileline(), kwd);
}
AstNodeDType* AstNode::findBitDType(int width, int widthMin, AstNumeric numeric) const {
return v3Global.rootp()->typeTablep()
->findLogicBitDType(fileline(), AstBasicDTypeKwd::BIT, width, widthMin, numeric);
}
AstNodeDType* AstNode::findLogicDType(int width, int widthMin, AstNumeric numeric) const {
return v3Global.rootp()->typeTablep()
->findLogicBitDType(fileline(), AstBasicDTypeKwd::LOGIC, width, widthMin, numeric);
}
AstNodeDType* AstNode::findLogicRangeDType(VNumRange range, int widthMin, AstNumeric numeric) const {
return v3Global.rootp()->typeTablep()
->findLogicBitDType(fileline(), AstBasicDTypeKwd::LOGIC, range, widthMin, numeric);
}
AstBasicDType* AstNode::findInsertSameDType(AstBasicDType* nodep) {
return v3Global.rootp()->typeTablep()
->findInsertSameDType(nodep);
}
//######################################################################
// AstNVisitor
+485 -98
View File
File diff suppressed because it is too large Load Diff
+33
View File
@@ -0,0 +1,33 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Ast node structure
//
// Code available from: http://www.veripool.org/verilator
//
//*************************************************************************
//
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
#ifndef _V3ASTCONSTONLY_H_
#define _V3ASTCONSTONLY_H_ 1
// Include only in visitors that do not not edit nodes, so should use constant iterators
#define iterateAndNext error_use_iterateAndNextConst
#define iterateChildren error_use_iterateChildrenConst
#define addNext error_no_addNext_in_ConstOnlyVisitor
#define replaceWith error_no_replaceWith_in_ConstOnlyVisitor
#define deleteTree error_no_deleteTree_in_ConstOnlyVisitor
#define unlinkFrBack error_no_unlinkFrBack_in_ConstOnlyVisitor
#endif // Guard
+410 -75
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Ast node structures
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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,8 +35,22 @@
// Special methods
// We need these here, because the classes they point to aren't defined when we declare the class
bool AstNodeVarRef::broken() const { return ((m_varScopep && !m_varScopep->brokeExists())
|| (m_varp && !m_varp->brokeExists())); }
const char* AstIfaceRefDType::broken() const {
BROKEN_RTN(m_ifacep && !m_ifacep->brokeExists());
BROKEN_RTN(m_cellp && !m_cellp->brokeExists());
BROKEN_RTN(m_modportp && !m_modportp->brokeExists());
return NULL;
}
AstIface* AstIfaceRefDType::ifaceViaCellp() const {
return ((m_cellp && m_cellp->modp()) ? m_cellp->modp()->castIface() : m_ifacep);
}
const char* AstNodeVarRef::broken() const {
BROKEN_RTN(m_varScopep && !m_varScopep->brokeExists());
BROKEN_RTN(m_varp && !m_varp->brokeExists());
return NULL;
}
void AstNodeVarRef::cloneRelink() {
if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep()->castVar(); }
@@ -47,6 +60,28 @@ int AstNodeSel::bitConst() const {
AstConst* constp=bitp()->castConst(); return (constp?constp->toSInt():0);
}
void AstNodeClassDType::repairMemberCache() {
clearCache();
for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
if (m_members.find(itemp->name())!=m_members.end()) { itemp->v3error("Duplicate declaration of member name: "<<itemp->prettyName()); }
else m_members.insert(make_pair(itemp->name(), itemp));
}
}
const char* AstNodeClassDType::broken() const {
set<AstMemberDType*> exists;
for (AstMemberDType* itemp = membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
exists.insert(itemp);
}
for (MemberNameMap::const_iterator it=m_members.begin(); it!=m_members.end(); ++it) {
if (VL_UNLIKELY(exists.find(it->second) == exists.end())) {
this->v3error("Internal: Structure member broken: "<<it->first);
return "member broken";
}
}
return NULL;
}
int AstBasicDType::widthAlignBytes() const {
if (width()<=8) return 1;
else if (width()<=16) return 2;
@@ -61,29 +96,92 @@ int AstBasicDType::widthTotalBytes() const {
else return widthWords()*(VL_WORDSIZE/8);
}
int AstNodeClassDType::widthTotalBytes() const {
if (width()<=8) return 1;
else if (width()<=16) return 2;
else if (isQuad()) return 8;
else return widthWords()*(VL_WORDSIZE/8);
}
int AstNodeClassDType::widthAlignBytes() const {
// Could do max across members but that would be slow,
// instead intuit based on total structure size
if (width()<=8) return 1;
else if (width()<=16) return 2;
else if (width()<=32) return 4;
else return 8;
}
AstNodeBiop* AstEq::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
if (lhsp->isDouble() && rhsp->isDouble()) {
return new AstEqD(fl, lhsp, rhsp);
} else {
return new AstEq(fl, lhsp, rhsp);
}
}
AstNodeBiop* AstGte::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
if (lhsp->isDouble() && rhsp->isDouble()) {
return new AstGteD(fl, lhsp, rhsp);
} else if (lhsp->isSigned() && rhsp->isSigned()) {
return new AstGteS(fl, lhsp, rhsp);
} else {
return new AstGte(fl, lhsp, rhsp);
}
}
AstNodeBiop* AstLte::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
if (lhsp->isDouble() && rhsp->isDouble()) {
return new AstLteD(fl, lhsp, rhsp);
} else if (lhsp->isSigned() && rhsp->isSigned()) {
return new AstLteS(fl, lhsp, rhsp);
} else {
return new AstLte(fl, lhsp, rhsp);
}
}
bool AstVar::isSigPublic() const {
return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar()));
}
bool AstVar::isScQuad() const {
return (isSc() && isQuad() && !isScBv());
return (isSc() && isQuad() && !isScBv() && !isScBigUint());
}
bool AstVar::isScBv() const {
return ((isSc() && width() >= v3Global.opt.pinsBv()) || m_attrScBv);
}
bool AstVar::isScUint() const {
return ((isSc() && v3Global.opt.pinsScUint() && width() >= 2 && width() <= 64) && !isScBv());
}
bool AstVar::isScBigUint() const {
return ((isSc() && v3Global.opt.pinsScBigUint() && width() >= 65 && width() <= 512) && !isScBv());
}
void AstVar::combineType(AstVarType type) {
// These flags get combined with the existing settings of the flags.
// We don't test varType for certain types, instead set flags since
// when we combine wires cross-hierarchy we need a union of all characteristics.
if (type == AstVarType::SUPPLY0) type = AstVarType::WIRE;
if (type == AstVarType::SUPPLY1) type = AstVarType::WIRE;
m_varType=type; // For debugging prints only
// These flags get combined with the existing settings of the flags.
if (type==AstVarType::INPUT || type==AstVarType::INOUT)
m_input = true;
if (type==AstVarType::OUTPUT || type==AstVarType::INOUT)
if (type==AstVarType::OUTPUT || type==AstVarType::INOUT) {
m_output = true;
if (type==AstVarType::INOUT || type==AstVarType::TRIWIRE)
m_declOutput = true;
}
if (type==AstVarType::INOUT || type==AstVarType::TRIWIRE
|| type==AstVarType::TRI0 || type==AstVarType::TRI1)
m_tristate = true;
if (type==AstVarType::TRI0)
m_isPulldown = true;
if (type==AstVarType::TRI1)
m_isPullup = true;
}
string AstVar::verilogKwd() const {
@@ -102,7 +200,7 @@ string AstVar::verilogKwd() const {
}
}
string AstVar::vlArgType(bool named, bool forReturn) const {
string AstVar::vlArgType(bool named, bool forReturn, bool forFunc) const {
if (forReturn) named=false;
if (forReturn) v3fatalSrc("verilator internal data is never passed as return, but as first argument");
string arg;
@@ -135,7 +233,7 @@ string AstVar::vlArgType(bool named, bool forReturn) const {
arg += " (& "+name();
arg += ")["+cvtToStr(widthWords())+"]";
} else {
if (isOutput() || (strtype && isInput())) arg += "&";
if (forFunc && (isOutput() || (strtype && isInput()))) arg += "&";
if (named) arg += " "+name();
}
return arg;
@@ -221,6 +319,9 @@ string AstVar::dpiArgType(bool named, bool forReturn) const {
}
} else {
arg = basicp()->keyword().dpiType();
if (basicp()->keyword().isDpiUnsignable() && !basicp()->isSigned()) {
arg = "unsigned "+arg;
}
if (!forReturn && isOutput()) arg += "*";
}
if (named) arg += " "+name();
@@ -228,7 +329,11 @@ string AstVar::dpiArgType(bool named, bool forReturn) const {
}
string AstVar::scType() const {
if (isScBv()) {
if (isScBigUint()) {
return (string("sc_biguint<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
} else if (isScUint()) {
return (string("sc_uint<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
} else if (isScBv()) {
return (string("sc_bv<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
} else if (widthMin() == 1) {
return "bool";
@@ -245,7 +350,7 @@ string AstVar::scType() const {
}
}
AstNodeDType* AstVar::dtypeDimensionp(int dimension) const {
AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
// dimension passed from AstArraySel::dimension
// Dimension 0 means the VAR itself, 1 is the closest SEL to the AstVar,
// which is the lowest in the dtype list.
@@ -257,19 +362,29 @@ AstNodeDType* AstVar::dtypeDimensionp(int dimension) const {
// DECL: VAR a (ARRAYSEL0 (ARRAYSEL1 (ARRAYSEL2 (DT RANGE3))))
// *or* VAR a (ARRAYSEL0 (ARRAYSEL1 (ARRAYSEL2 (ARRAYSEL3 (DT))))
// SEL1 needs to select from entire variable which is a pointer to ARRAYSEL0
// TODO this function should be removed in favor of recursing the dtype(),
// as that allows for more complicated data types.
int dim = 0;
for (AstNodeDType* dtypep=this->dtypep(); dtypep; ) {
for (AstNodeDType* dtypep=this; dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstArrayDType* adtypep = dtypep->castArrayDType()) {
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
if ((dim++)==dimension) {
return dtypep;
}
dtypep = adtypep->dtypep();
dtypep = adtypep->subDTypep();
continue;
}
else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
// AstBasicDType - nothing below, return null
if (adtypep->rangep()) {
if (adtypep->isRanged()) {
if ((dim++) == dimension) {
return adtypep;
}
}
return NULL;
}
else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) {
if (adtypep->packed()) {
if ((dim++) == dimension) {
return adtypep;
}
@@ -282,13 +397,13 @@ AstNodeDType* AstVar::dtypeDimensionp(int dimension) const {
return NULL;
}
uint32_t AstVar::arrayElements() const {
uint32_t AstNodeDType::arrayUnpackedElements() {
uint32_t entries=1;
for (AstNodeDType* dtypep=this->dtypep(); dtypep; ) {
for (AstNodeDType* dtypep=this; dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstArrayDType* adtypep = dtypep->castArrayDType()) {
if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) {
entries *= adtypep->elementsConst();
dtypep = adtypep->dtypep();
dtypep = adtypep->subDTypep();
}
else {
// AstBasicDType - nothing below, 1
@@ -298,45 +413,41 @@ uint32_t AstVar::arrayElements() const {
return entries;
}
pair<uint32_t,uint32_t> AstVar::dimensions() const {
pair<uint32_t,uint32_t> AstNodeDType::dimensions(bool includeBasic) {
// How many array dimensions (packed,unpacked) does this Var have?
uint32_t packed = 0;
uint32_t unpacked = 0;
for (AstNodeDType* dtypep=this->dtypep(); dtypep; ) {
for (AstNodeDType* dtypep=this; dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstArrayDType* adtypep = dtypep->castArrayDType()) {
if (adtypep->isPacked()) packed += 1;
else unpacked += 1;
dtypep = adtypep->dtypep();
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
if (adtypep->castPackArrayDType()) packed++;
else unpacked++;
dtypep = adtypep->subDTypep();
continue;
}
else {
// AstBasicDType - nothing below, 1
break;
else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
if (includeBasic && adtypep->isRanged()) packed++;
}
break;
}
return make_pair(packed, unpacked);
}
// Special operators
int AstArraySel::dimension(AstNode* nodep) {
// How many dimensions is this reference from the base variable?
// nodep is typically the fromp() of a select; thus the first select
// is selecting from the entire variable type - effectively dimension 0.
// Dimension passed to AstVar::dtypeDimensionp; see comments there
int dim = 0;
while (nodep) {
if (nodep->castNodeSel()) { dim++; nodep=nodep->castNodeSel()->fromp(); continue; }
if (nodep->castNodePreSel()) { dim++; nodep=nodep->castNodePreSel()->fromp(); continue; }
break;
int AstNodeDType::widthPow2() const {
// I.e. width 30 returns 32, width 32 returns 32.
uint32_t width = this->width();
for (int p2=30; p2>=0; p2--) {
if (width > (1UL<<p2)) return (1UL<<(p2+1));
}
return dim;
return 1;
}
AstNode* AstArraySel::baseFromp(AstNode* nodep) { ///< What is the base variable (or const) this dereferences?
// Else AstArraySel etc; search for the base
while (nodep) {
if (nodep->castArraySel()) { nodep=nodep->castArraySel()->fromp(); continue; }
else if (nodep->castSel()) { nodep=nodep->castSel()->fromp(); continue; }
// AstNodeSelPre stashes the associated variable under a ATTROF so it isn't constified
// AstNodeSelPre stashes the associated variable under an ATTROF of AstAttrType::VAR_BASE/MEMBER_BASE so it isn't constified
else if (nodep->castAttrOf()) { nodep=nodep->castAttrOf()->fromp(); continue; }
else if (nodep->castNodePreSel()) {
if (nodep->castNodePreSel()->attrp()) {
@@ -351,10 +462,12 @@ AstNode* AstArraySel::baseFromp(AstNode* nodep) { ///< What is the base variable
return nodep;
}
bool AstScope::broken() const {
return ((m_aboveScopep && !m_aboveScopep->brokeExists())
|| (m_aboveCellp && !m_aboveCellp->brokeExists())
|| !m_modp || !m_modp->brokeExists());
const char* AstScope::broken() const {
BROKEN_RTN(m_aboveScopep && !m_aboveScopep->brokeExists());
BROKEN_RTN(m_aboveCellp && !m_aboveCellp->brokeExists());
BROKEN_RTN(!m_modp);
BROKEN_RTN(m_modp && !m_modp->brokeExists());
return NULL;
}
void AstScope::cloneRelink() {
@@ -431,6 +544,96 @@ bool AstSenTree::hasCombo() {
return false;
}
void AstTypeTable::clearCache() {
// When we mass-change widthMin in V3WidthCommit, we need to correct the table.
// Just clear out the maps; the search functions will be used to rebuild the map
for (int i=0; i<(int)(AstBasicDTypeKwd::_ENUM_MAX); ++i) {
m_basicps[i] = NULL;
}
for (int isbit=0; isbit<_IDX0_MAX; ++isbit) {
for (int numer=0; numer<AstNumeric::_ENUM_MAX; ++numer) {
LogicMap& mapr = m_logicMap[isbit][numer];
mapr.clear();
}
}
m_detailedMap.clear();
// Clear generic()'s so dead detection will work
for (AstNode* nodep = typesp(); nodep; nodep=nodep->nextp()) {
if (AstBasicDType* bdtypep = nodep->castBasicDType()) {
bdtypep->generic(false);
}
}
}
void AstTypeTable::repairCache() {
// After we mass-change widthMin in V3WidthCommit, we need to correct the table.
clearCache();
for (AstNode* nodep = typesp(); nodep; nodep=nodep->nextp()) {
if (AstBasicDType* bdtypep = nodep->castBasicDType()) {
(void)findInsertSameDType(bdtypep);
}
}
}
AstBasicDType* AstTypeTable::findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd) {
if (m_basicps[kwd]) return m_basicps[kwd];
//
AstBasicDType* new1p = new AstBasicDType(fl, kwd);
// Because the detailed map doesn't update this map,
// check the detailed map for this same node
// Also adds this new node to the detailed map
AstBasicDType* newp = findInsertSameDType(new1p);
if (newp != new1p) new1p->deleteTree();
else addTypesp(newp);
//
m_basicps[kwd] = newp;
return newp;
}
AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd,
int width, int widthMin, AstNumeric numeric) {
int idx = IDX0_LOGIC;
if (kwd == AstBasicDTypeKwd::LOGIC) idx = IDX0_LOGIC;
else if (kwd == AstBasicDTypeKwd::BIT) idx = IDX0_BIT;
else fl->v3fatalSrc("Bad kwd for findLogicBitDType");
pair<int,int> widths = make_pair(width,widthMin);
LogicMap& mapr = m_logicMap[idx][(int)numeric];
LogicMap::const_iterator it = mapr.find(widths);
if (it != mapr.end()) return it->second;
//
AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, width, widthMin);
// Because the detailed map doesn't update this map,
// check the detailed map for this same node, and if found update this map
// Also adds this new node to the detailed map
AstBasicDType* newp = findInsertSameDType(new1p);
if (newp != new1p) new1p->deleteTree();
else addTypesp(newp);
//
mapr.insert(make_pair(widths,newp));
return newp;
}
AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd,
VNumRange range, int widthMin, AstNumeric numeric) {
AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, range, widthMin);
AstBasicDType* newp = findInsertSameDType(new1p);
if (newp != new1p) new1p->deleteTree();
else addTypesp(newp);
return newp;
}
AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) {
VBasicTypeKey key (nodep->width(), nodep->widthMin(), nodep->numeric(),
nodep->keyword(), nodep->nrange());
DetailedMap& mapr = m_detailedMap;
DetailedMap::const_iterator it = mapr.find(key);
if (it != mapr.end()) return it->second;
mapr.insert(make_pair(key,nodep));
nodep->generic(true);
// No addTypesp; the upper function that called new() is responsible for adding
return nodep;
}
//======================================================================
// Special walking tree inserters
@@ -496,23 +699,34 @@ void AstWhile::addNextStmt(AstNode* newp, AstNode* belowp) {
//======================================================================
// Per-type Debugging
void AstNode::dump(ostream& os) {
os<<typeName()<<" "<<(void*)this
void AstNode::dump(ostream& str) {
str<<typeName()<<" "<<(void*)this
//<<" "<<(void*)this->m_backp
<<" <e"<<dec<<editCount()
<<((editCount()>=editCountLast())?"#>":">")
<<" {"<<fileline()->filenameLetters()<<dec<<fileline()->lineno()<<"}"
<<" "<<(isSigned()?"s":"")
<<(isDouble()?"d":"")
<<"w"<<(widthSized()?"":"u")<<width();
if (!widthSized()) os<<"/"<<widthMin();
if (name()!="") os<<" "<<AstNode::quoteName(name());
<<" <e"<<dec<<editCount()
<<((editCount()>=editCountLast())?"#>":">")
<<" {"<<fileline()->filenameLetters()<<dec<<fileline()->lineno()<<"}";
if (user1p()) str<<" u1="<<(void*)user1p();
if (user2p()) str<<" u2="<<(void*)user2p();
if (user3p()) str<<" u3="<<(void*)user3p();
if (user4p()) str<<" u4="<<(void*)user4p();
if (user5p()) str<<" u5="<<(void*)user5p();
if (hasDType()) {
if (dtypep()==this) str<<" @dt="<<"this@";
else str<<" @dt="<<(void*)dtypep()<<"@"; // Final @ so less likely to by accident think it's nodep
if (AstNodeDType* dtp = dtypep()) {
dtp->dumpSmall(str);
}
} else { // V3Broken will throw an error
if (dtypep()) str<<" %Error-dtype-exp=null,got="<<(void*)dtypep();
}
if (name()!="") str<<" "<<AstNode::quoteName(name());
}
void AstArrayDType::dump(ostream& str) {
void AstAlways::dump(ostream& str) {
this->AstNode::dump(str);
if (isPacked()) str<<" [PACKED]";
if (keyword() != VAlwaysKwd::ALWAYS) str<<" ["<<keyword().ascii()<<"]";
}
void AstArraySel::dump(ostream& str) {
this->AstNode::dump(str);
str<<" [start:"<<start()<<"] [length:"<<length()<<"]";
@@ -522,9 +736,9 @@ void AstAttrOf::dump(ostream& str) {
str<<" ["<<attrType().ascii()<<"]";
}
void AstBasicDType::dump(ostream& str) {
this->AstNode::dump(str);
str<<" ["<<keyword().ascii()<<"]";
if (implicit()) str<<" [IMPLICIT]";
this->AstNodeDType::dump(str);
str<<" kwd="<<keyword().ascii();
if (isRanged() && !rangep()) str<<" range=["<<left()<<":"<<right()<<"]";
}
void AstCCast::dump(ostream& str) {
this->AstNode::dump(str);
@@ -543,17 +757,43 @@ void AstDisplay::dump(ostream& str) {
this->AstNode::dump(str);
//str<<" "<<displayType().ascii();
}
void AstEnumItemRef::dump(ostream& str) {
this->AstNode::dump(str);
str<<" -> ";
if (itemp()) { itemp()->dump(str); }
else { str<<"UNLINKED"; }
}
void AstIfaceRefDType::dump(ostream& str) {
this->AstNode::dump(str);
if (cellName()!="") { str<<" cell="<<cellName(); }
if (ifaceName()!="") { str<<" if="<<ifaceName(); }
if (modportName()!="") { str<<" mp="<<modportName(); }
if (cellp()) { str<<" -> "; cellp()->dump(str); }
else if (ifacep()) { str<<" -> "; ifacep()->dump(str); }
else { str<<" -> UNLINKED"; }
}
void AstIfaceRefDType::dumpSmall(ostream& str) {
this->AstNodeDType::dumpSmall(str);
str<<"iface";
}
void AstJumpGo::dump(ostream& str) {
this->AstNode::dump(str);
str<<" -> ";
if (labelp()) { labelp()->dump(str); }
else { str<<"%Error:UNLINKED"; }
}
void AstEnumItemRef::dump(ostream& str) {
void AstModportFTaskRef::dump(ostream& str) {
this->AstNode::dump(str);
str<<" -> ";
if (itemp()) { itemp()->dump(str); }
else { str<<"UNLINKED"; }
if (isExport()) str<<" EXPORT";
if (isImport()) str<<" IMPORT";
if (ftaskp()) { str<<" -> "; ftaskp()->dump(str); }
else { str<<" -> UNLINKED"; }
}
void AstModportVarRef::dump(ostream& str) {
this->AstNode::dump(str);
str<<" "<<varType();
if (varp()) { str<<" -> "; varp()->dump(str); }
else { str<<" -> UNLINKED"; }
}
void AstPin::dump(ostream& str) {
this->AstNode::dump(str);
@@ -566,38 +806,118 @@ void AstRange::dump(ostream& str) {
if (littleEndian()) str<<" [LITTLE]";
}
void AstRefDType::dump(ostream& str) {
this->AstNode::dump(str);
this->AstNodeDType::dump(str);
if (defp()) { str<<" -> "; defp()->dump(str); }
else { str<<" -> UNLINKED"; }
}
void AstVarXRef::dump(ostream& str) {
void AstNodeClassDType::dump(ostream& str) {
this->AstNode::dump(str);
if (lvalue()) str<<" [LV] => ";
else str<<" [RV] <- ";
str<<dotted()<<". - ";
if (inlinedDots()!="") str<<" flat.="<<inlinedDots()<<" - ";
if (varScopep()) { varScopep()->dump(str); }
else if (varp()) { varp()->dump(str); }
else { str<<"UNLINKED"; }
if (packed()) str<<" [PACKED]";
}
void AstNodeDType::dump(ostream& str) {
this->AstNode::dump(str);
if (generic()) str<<" [GENERIC]";
if (AstNodeDType* dtp = virtRefDTypep()) {
str<<" refdt="<<(void*)(dtp);
dtp->dumpSmall(str);
}
}
void AstNodeDType::dumpSmall(ostream& str) {
str<<"("
<<(generic()?"G/":"")
<<((isSigned()&&!isDouble())?"s":"")
<<(isNosign()?"n":"")
<<(isDouble()?"d":"")
<<"w"<<(widthSized()?"":"u")<<width();
if (!widthSized()) str<<"/"<<widthMin();
str<<")";
}
void AstNodeArrayDType::dumpSmall(ostream& str) {
this->AstNodeDType::dumpSmall(str);
if (castPackArrayDType()) str<<"p"; else str<<"u";
str<<" "<<declRange();
}
void AstNodeArrayDType::dump(ostream& str) {
this->AstNodeDType::dump(str);
str<<" "<<declRange();
}
void AstNodeModule::dump(ostream& str) {
this->AstNode::dump(str);
str<<" L"<<level();
if (modPublic()) str<<" [P]";
if (inLibrary()) str<<" [LIB]";
if (dead()) str<<" [DEAD]";
}
void AstPackageImport::dump(ostream& str) {
this->AstNode::dump(str);
str<<" -> "<<packagep();
}
void AstSel::dump(ostream& str) {
this->AstNode::dump(str);
if (declRange().ranged()) {
str<<" decl"<<declRange()<<"]";
if (declElWidth()!=1) str<<"/"<<declElWidth();
}
}
void AstTypeTable::dump(ostream& str) {
this->AstNode::dump(str);
for (int i=0; i<(int)(AstBasicDTypeKwd::_ENUM_MAX); ++i) {
if (AstBasicDType* subnodep=m_basicps[i]) {
str<<endl; // Newline from caller, so newline first
str<<"\t\t"<<setw(8)<<AstBasicDTypeKwd(i).ascii();
str<<" -> ";
subnodep->dump(str);
}
}
for (int isbit=0; isbit<2; ++isbit) {
for (int issigned=0; issigned<AstNumeric::_ENUM_MAX; ++issigned) {
LogicMap& mapr = m_logicMap[isbit][issigned];
for (LogicMap::const_iterator it = mapr.begin(); it != mapr.end(); ++it) {
AstBasicDType* dtypep = it->second;
str<<endl; // Newline from caller, so newline first
stringstream nsstr;
nsstr<<(isbit?"bw":"lw")
<<it->first.first<<"/"<<it->first.second;
str<<"\t\t"<<setw(8)<<nsstr.str();
if (issigned) str<<" s"; else str<<" u";
str<<" -> ";
dtypep->dump(str);
}
}
}
{
DetailedMap& mapr = m_detailedMap;
for (DetailedMap::const_iterator it = mapr.begin(); it != mapr.end(); ++it) {
AstBasicDType* dtypep = it->second;
str<<endl; // Newline from caller, so newline first
stringstream nsstr;
str<<"\t\tdetailed -> ";
dtypep->dump(str);
}
}
// Note get newline from caller too.
}
void AstVarScope::dump(ostream& str) {
this->AstNode::dump(str);
if (isCircular()) str<<" [CIRC]";
if (varp()) { str<<" -> "; varp()->dump(str); }
else { str<<" ->UNLINKED"; }
}
void AstVarXRef::dump(ostream& str) {
this->AstNode::dump(str);
if (packagep()) { str<<" pkg="<<(void*)packagep(); }
if (lvalue()) str<<" [LV] => ";
else str<<" [RV] <- ";
str<<dotted()<<". - ";
if (inlinedDots()!="") str<<" inline.="<<inlinedDots()<<" - ";
if (varScopep()) { varScopep()->dump(str); }
else if (varp()) { varp()->dump(str); }
else { str<<"UNLINKED"; }
}
void AstVarRef::dump(ostream& str) {
this->AstNode::dump(str);
if (packagep()) { str<<" pkg="<<(void*)packagep(); }
if (lvalue()) str<<" [LV] => ";
else str<<" [RV] <- ";
if (varScopep()) { varScopep()->dump(str); }
@@ -614,9 +934,11 @@ void AstVar::dump(ostream& str) {
else if (isOutput()) str<<" [O]";
}
if (isConst()) str<<" [CONST]";
if (isPullup()) str<<" [PULLUP]";
if (isPulldown()) str<<" [PULLDOWN]";
if (isUsedClock()) str<<" [CLK]";
if (isSigPublic()) str<<" [P]";
if (isUsedLoopIdx()) str<<" [LOOP]";
if (isUsedLoopIdx()) str<<" [LOOP]";
if (attrClockEn()) str<<" [aCLKEN]";
if (attrIsolateAssign()) str<<" [aISO]";
if (attrFileDescr()) str<<" [aFD]";
@@ -636,6 +958,16 @@ void AstParseRef::dump(ostream& str) {
this->AstNode::dump(str);
str<<" ["<<expect().ascii()<<"]";
}
void AstPackageRef::dump(ostream& str) {
this->AstNode::dump(str);
if (packagep()) { str<<" pkg="<<(void*)packagep(); }
str<<" -> ";
if (packagep()) { packagep()->dump(str); }
else { str<<"UNLINKED"; }
}
void AstDot::dump(ostream& str) {
this->AstNode::dump(str);
}
void AstActive::dump(ostream& str) {
this->AstNode::dump(str);
str<<" => ";
@@ -644,6 +976,7 @@ void AstActive::dump(ostream& str) {
}
void AstNodeFTaskRef::dump(ostream& str) {
this->AstNode::dump(str);
if (packagep()) { str<<" pkg="<<(void*)packagep(); }
str<<" -> ";
if (dotted()!="") { str<<dotted()<<". - "; }
if (taskp()) { taskp()->dump(str); }
@@ -660,6 +993,8 @@ void AstNodeFTask::dump(ostream& str) {
void AstBegin::dump(ostream& str) {
this->AstNode::dump(str);
if (unnamed()) str<<" [UNNAMED]";
if (generate()) str<<" [GEN]";
if (genforp()) str<<" [GENFOR]";
}
void AstCoverDecl::dump(ostream& str) {
this->AstNode::dump(str);
+1156 -426
View File
File diff suppressed because it is too large Load Diff
+103 -21
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Removal of named begin blocks
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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.
@@ -45,9 +44,31 @@
//######################################################################
class BeginState {
private:
// NODE STATE
//Entire netlist:
// AstNodeFTask::user1 -> bool, 1=processed
AstUser1InUse m_inuser1;
bool m_anyFuncInBegin;
public:
BeginState() {
m_anyFuncInBegin = false;
}
~BeginState() {}
void userMarkChanged(AstNodeFTask* nodep) {
nodep->user1(true);
m_anyFuncInBegin = true;
}
bool anyFuncInBegin() const { return m_anyFuncInBegin; }
};
//######################################################################
class BeginVisitor : public AstNVisitor {
private:
// STATE
BeginState* m_statep; // Current global state
AstNodeModule* m_modp; // Current module
AstNodeFTask* m_ftaskp; // Current function/task
string m_namedScope; // Name of begin blocks above us
@@ -70,9 +91,27 @@ private:
m_modp = NULL;
}
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
m_ftaskp = nodep;
nodep->iterateChildren(*this);
m_ftaskp = NULL;
UINFO(8," "<<nodep<<endl);
// Rename it
if (m_unnamedScope != "") {
nodep->name(m_unnamedScope+"__DOT__"+nodep->name());
UINFO(8," rename to "<<nodep->name()<<endl);
m_statep->userMarkChanged(nodep);
}
// BEGIN wrapping a function rename that function, but don't affect the inside function's variables
// We then restart with empty naming; so that any begin's inside the function will rename inside the function
// Process children
string oldScope = m_namedScope;
string oldUnnamed = m_unnamedScope;
{
m_namedScope = "";
m_unnamedScope = "";
m_ftaskp = nodep;
nodep->iterateChildren(*this);
m_ftaskp = NULL;
}
m_namedScope = oldScope;
m_unnamedScope = oldUnnamed;
}
virtual void visit(AstBegin* nodep, AstNUser*) {
// Begin blocks were only useful in variable creation, change names and delete
@@ -80,7 +119,7 @@ private:
string oldScope = m_namedScope;
string oldUnnamed = m_unnamedScope;
{
//UINFO(8,"nname "<<m_namedScope<<endl);
UINFO(8,"nname "<<m_namedScope<<endl);
if (nodep->name() != "") { // Else unneeded unnamed block
// Create data for dotted variable resolution
string dottedname = nodep->name() + "__DOT__"; // So always found
@@ -95,25 +134,33 @@ private:
if (m_unnamedScope=="") m_unnamedScope = ident;
else m_unnamedScope = m_unnamedScope + "__DOT__"+ident;
// Create CellInline for dotted var resolution
AstCellInline* inlinep = new AstCellInline(nodep->fileline(),
m_unnamedScope, "__BEGIN__");
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
if (!m_ftaskp) {
AstCellInline* inlinep = new AstCellInline(nodep->fileline(),
m_unnamedScope, "__BEGIN__");
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
}
}
}
// Remap var names and replace lower Begins
nodep->iterateChildren(*this);
if (AstNode* stmtsp = nodep->stmtsp()) {
stmtsp->unlinkFrBackWithNext();
nodep->replaceWith(stmtsp);
} else {
nodep->unlinkFrBack();
}
pushDeletep(nodep); nodep=NULL;
nodep->stmtsp()->iterateAndNext(*this);
if (nodep->genforp()) nodep->v3fatalSrc("GENFORs should have been expanded earlier");
}
m_namedScope = oldScope;
m_unnamedScope = oldUnnamed;
// Cleanup
AstNode* addsp = NULL;
if (AstNode* stmtsp = nodep->stmtsp()) {
stmtsp->unlinkFrBackWithNext();
if (addsp) { addsp = addsp->addNextNull(stmtsp); } else { addsp = stmtsp; }
}
if (addsp) {
nodep->replaceWith(addsp);
} else {
nodep->unlinkFrBack();
}
pushDeletep(nodep); nodep=NULL;
}
virtual void visit(AstVar* nodep, AstNUser*) {
if (m_unnamedScope != "") {
@@ -139,6 +186,7 @@ private:
virtual void visit(AstScopeName* nodep, AstNUser*) {
// 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
if (m_namedScope != "") {
// To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp();
@@ -173,7 +221,8 @@ private:
}
public:
// CONSTUCTORS
BeginVisitor(AstNetlist* nodep) {
BeginVisitor(AstNetlist* nodep, BeginState* statep) {
m_statep = statep;
m_modp = NULL;
m_ftaskp = NULL;
m_repeatNum = 0;
@@ -183,10 +232,43 @@ public:
virtual ~BeginVisitor() {}
};
//######################################################################
class BeginRelinkVisitor : public AstNVisitor {
// Replace tasks with new pointer
private:
// NODE STATE
// Input:
// AstNodeFTask::user1p // Node replaced, rename it
// VISITORS
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
if (nodep->taskp()->user1()) { // It was converted
UINFO(9, " relinkFTask "<<nodep<<endl);
nodep->name(nodep->taskp()->name());
}
nodep->iterateChildren(*this);
}
//--------------------
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
BeginRelinkVisitor(AstNetlist* nodep, BeginState*) {
nodep->accept(*this);
}
virtual ~BeginRelinkVisitor() {}
};
//######################################################################
// Task class functions
void V3Begin::debeginAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
BeginVisitor bvisitor (nodep);
BeginState state;
{ BeginVisitor bvisitor (nodep,&state); }
if (state.anyFuncInBegin()) {
BeginRelinkVisitor brvisitor (nodep,&state);
}
}
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Removal of named begin blocks
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+4 -5
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Branch prediction
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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.
@@ -95,9 +94,9 @@ private:
public:
// CONSTUCTORS
BranchVisitor(AstNetlist* rootp) {
BranchVisitor(AstNetlist* nodep) {
reset();
rootp->iterateChildren(*this);
nodep->iterateChildren(*this);
}
virtual ~BranchVisitor() {}
};
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Branch prediction
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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.
+51 -25
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Find broken links in tree
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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.
@@ -38,6 +37,9 @@
#include "V3Broken.h"
#include "V3Ast.h"
// This visitor does not edit nodes, and is called at error-exit, so should use constant iterators
#include "V3AstConstOnly.h"
//######################################################################
class BrokenTable : public AstNVisitor {
@@ -48,16 +50,16 @@ private:
typedef map<const AstNode*,int> NodeMap;
static NodeMap s_nodes; // Set of all nodes that exist
// BITMASK
static const int FLAG_ALLOCATED = 0x01; // new() and not delete()ed
static const int FLAG_IN_TREE = 0x02; // Is in netlist tree
static const int FLAG_LINKABLE = 0x04; // Is in netlist tree, can be linked to
static const int FLAG_LEAKED = 0x08; // Known to have been leaked
static const int FLAG_UNDER_NOW = 0x10; // Is in tree as parent of current node
enum { FLAG_ALLOCATED = 0x01 }; // new() and not delete()ed
enum { FLAG_IN_TREE = 0x02 }; // Is in netlist tree
enum { FLAG_LINKABLE = 0x04 }; // Is in netlist tree, can be linked to
enum { FLAG_LEAKED = 0x08 }; // Known to have been leaked
enum { FLAG_UNDER_NOW = 0x10 }; // Is in tree as parent of current node
public:
// METHODS
static void deleted(const AstNode* nodep) {
// Called by operator delete on any node - only if VL_LEAK_CHECKS
if (debug()) cout<<"-nodeDel: "<<(void*)(nodep)<<endl;
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");
@@ -66,13 +68,14 @@ public:
}
static void addNewed(const AstNode* nodep) {
// Called by operator new on any node - only if VL_LEAK_CHECKS
if (debug()) cout<<"-nodeNew: "<<(void*)(nodep)<<endl;
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");
}
if (iter == s_nodes.end()) {
s_nodes.insert(make_pair(nodep,FLAG_ALLOCATED));
int flags = FLAG_ALLOCATED; // This int needed to appease GCC 4.1.2
s_nodes.insert(make_pair(nodep,flags));
}
}
static void setUnder(const AstNode* nodep, bool flag) {
@@ -147,7 +150,7 @@ public:
&& (it->first->backp() ? backs==1 : backs==0)) {
// Use only AstNode::dump instead of the virtual one, as there
// may be varp() and other cross links that are bad.
if (debug()) {
if (v3Global.opt.debugCheck()) {
cerr<<"%Error: LeakedNode"<<(it->first->backp()?"Back: ":": ");
((AstNode*)(it->first))->AstNode::dump(cerr);
cerr<<endl;
@@ -186,7 +189,7 @@ private:
// VISITORS
virtual void visit(AstNode* nodep, AstNUser*) {
BrokenTable::addInTree(nodep, nodep->maybePointedTo());
nodep->iterateChildren(*this);
nodep->iterateChildrenConst(*this);
}
public:
// CONSTUCTORS
@@ -203,18 +206,33 @@ class BrokenCheckVisitor : public AstNVisitor {
private:
virtual void visit(AstNode* nodep, AstNUser*) {
BrokenTable::setUnder(nodep,true);
if (nodep->broken()) {
nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo)\n");
if (const char* whyp=nodep->broken()) {
nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo): "<<whyp);
}
if (v3Global.assertWidthsSame()) {
if (nodep->dtypep()) {
if (!nodep->dtypep()->brokeExists()) { nodep->v3fatalSrc("Broken link in node->dtypep() to "<<(void*)nodep->dtypep()); }
else if (!nodep->dtypep()->castNodeDType()) { nodep->v3fatalSrc("Non-dtype link in node->dtypep() to "<<(void*)nodep->dtypep()); }
}
if (v3Global.assertDTypesResolved()) {
if (nodep->hasDType()) {
if (!nodep->dtypep()) nodep->v3fatalSrc("No dtype on node with hasDType(): "<<nodep->prettyTypeName());
} else {
if (nodep->dtypep()) nodep->v3fatalSrc("DType on node without hasDType(): "<<nodep->prettyTypeName());
}
if (nodep->getChildDTypep()) nodep->v3fatalSrc("childDTypep() non-null on node after should have removed");
if (AstNodeDType* dnodep = nodep->castNodeDType()) {
if (dnodep->width() != dnodep->widthMin()
&& v3Global.assertWidthsMatch()) {
dnodep->v3fatalSrc("Width != WidthMin");
}
}
}
if (v3Global.assertWidthsMatch()) {
if (nodep->width() != nodep->widthMin()) {
nodep->v3fatalSrc("Width != WidthMin\n");
}
if (!nodep->width() && nodep->castNodeMath()) {
nodep->v3fatalSrc("Math node has no assigned width\n");
nodep->v3fatalSrc("Width != WidthMin");
}
}
nodep->iterateChildren(*this);
nodep->iterateChildrenConst(*this);
BrokenTable::setUnder(nodep,false);
}
public:
@@ -230,10 +248,18 @@ public:
void V3Broken::brokenAll(AstNetlist* nodep) {
//UINFO(9,__FUNCTION__<<": "<<endl);
BrokenTable::prepForTree();
BrokenMarkVisitor mvisitor (nodep);
BrokenCheckVisitor cvisitor (nodep);
BrokenTable::doneWithTree();
static bool inBroken = false;
if (inBroken) {
// A error called by broken can recurse back into broken; avoid this
UINFO(1,"Broken called under broken, skipping recursion.\n");
} else {
inBroken = true;
BrokenTable::prepForTree();
BrokenMarkVisitor mvisitor (nodep);
BrokenCheckVisitor cvisitor (nodep);
BrokenTable::doneWithTree();
inBroken = false;
}
}
void V3Broken::addNewed(AstNode* nodep) {
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Find broken links in tree
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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 -21
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break case statements up and add Unknown assigns
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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.
@@ -98,7 +97,8 @@ private:
nodep->v3error("Use of x/? constant in generate case statement, (no such thing as 'generate casez')");
} else if (m_caseExprp->castCase() && m_caseExprp->castCase()->casex()) {
// Don't sweat it, we already complained about casex in general
} else if (m_caseExprp->castCase() && m_caseExprp->castCase()->casez()) {
} else if (m_caseExprp->castCase() && (m_caseExprp->castCase()->casez()
|| m_caseExprp->castCase()->caseInside())) {
if (nodep->num().isUnknown()) {
nodep->v3warn(CASEWITHX, "Use of x constant in casez statement, (perhaps intended ?/z in constant)");
}
@@ -197,7 +197,7 @@ private:
}
}
}
// Defaults were moved to last in the caseitem list by V3Link
// Defaults were moved to last in the caseitem list by V3LinkDot
if (itemp->isDefault()) { // Case statement's default... Fill the table
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
if (!m_valueItem[i]) m_valueItem[i] = itemp;
@@ -323,36 +323,42 @@ private:
icondNextp = icondp->nextp();
icondp->unlinkFrBack();
AstNode* and1p;
AstNode* and2p;
AstNode* condp = NULL; // Default is to use and1p/and2p
AstConst* iconstp = icondp->castConst();
if (iconstp && neverItem(nodep, iconstp)) {
// X in casez can't ever be executed
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
// For simplicity, make expression that is not equal, and let later
// optimizations remove it
and1p = new AstConst(itemp->fileline(), AstConst::LogicFalse());
and2p = new AstConst(itemp->fileline(), AstConst::LogicTrue());
condp = new AstConst(itemp->fileline(), AstConst::LogicFalse());
} else if (AstInsideRange* irangep = icondp->castInsideRange()) {
// Similar logic in V3Width::visit(AstInside)
AstNode* ap = AstGte::newTyped(itemp->fileline(),
cexprp->cloneTree(false),
irangep->lhsp()->unlinkFrBack());
AstNode* bp = AstLte::newTyped(itemp->fileline(),
cexprp->cloneTree(false),
irangep->rhsp()->unlinkFrBack());
condp = new AstAnd(itemp->fileline(), ap, bp);
} else if (iconstp && iconstp->num().isFourState()
&& (nodep->casex() || nodep->casez())) {
&& (nodep->casex() || nodep->casez() || nodep->caseInside())) {
V3Number nummask (itemp->fileline(), iconstp->width());
nummask.opBitsNonX(iconstp->num());
V3Number numval (itemp->fileline(), iconstp->width());
numval.opBitsOne(iconstp->num());
and1p = new AstAnd(itemp->fileline(), cexprp->cloneTree(false),
new AstConst(itemp->fileline(), nummask));
and2p = new AstAnd(itemp->fileline(),
new AstConst(itemp->fileline(), numval),
new AstConst(itemp->fileline(), nummask));
AstNode* and1p = new AstAnd(itemp->fileline(), cexprp->cloneTree(false),
new AstConst(itemp->fileline(), nummask));
AstNode* and2p = new AstAnd(itemp->fileline(),
new AstConst(itemp->fileline(), numval),
new AstConst(itemp->fileline(), nummask));
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
} else {
// Not a caseX mask, we can simply build CASEEQ(cexpr icond)
and1p = cexprp->cloneTree(false);
and2p = icondp;
AstNode* and1p = cexprp->cloneTree(false);
AstNode* and2p = icondp;
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
}
AstNodeBiop* condp = (and1p->isDouble()
? (new AstEqD(itemp->fileline(), and1p, and2p))->castNodeBiop()
: (new AstEq(itemp->fileline(), and1p, and2p))->castNodeBiop());
if (!ifexprp) {
ifexprp = condp;
} else {
@@ -436,7 +442,7 @@ private:
bool neverItem(AstCase* casep, AstConst* itemp) {
// Xs in case or casez are impossible due to two state simulations
if (casep->casex()) {
} else if (casep->casez()) {
} else if (casep->casez() || casep->caseInside()) {
if (itemp->num().isUnknown()) return true;
} else {
if (itemp->num().isFourState()) return true;
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break case statements up and add Unknown assigns
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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 -5
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Add C++ casts across expression size changes
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2004-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2014 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.
@@ -77,8 +76,7 @@ private:
AstNRelinker relinkHandle;
nodep->unlinkFrBack(&relinkHandle);
//
AstCCast* castp = new AstCCast (nodep->fileline(), nodep, needsize);
castp->width(needsize, nodep->widthMin());
AstCCast* castp = new AstCCast (nodep->fileline(), nodep, needsize, nodep->widthMin());
relinkHandle.relink(castp);
//if (debug()>8) castp->dumpTree(cout,"-castins: ");
//
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Add C++ casts across expression size changes
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2004-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2014 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
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Clock Domain Crossing Lint
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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.
@@ -361,7 +360,7 @@ private:
CdcEitherVertex* traceAsyncRecurse(CdcEitherVertex* vertexp, bool mark) {
// First pass: Return vertex of any hazardous stuff attached, or NULL if OK
// If first pass returns true, second pass calls asyncPath() on appropriate nodes
if (vertexp->user()>=m_userGeneration) return false; // Processed - prevent loop
if (vertexp->user()>=m_userGeneration) return NULL; // Processed - prevent loop
vertexp->user(m_userGeneration);
CdcEitherVertex* mark_outp = NULL;
@@ -384,7 +383,7 @@ private:
CdcEitherVertex* eFromVertexp = (CdcEitherVertex*)edgep->fromp();
eFromVertexp->asyncPath(true);
}
return false;
return NULL;
}
// Also ok if from flop, but partially trace the flop so more obvious to users
if (vvertexp->fromFlop()) {
@@ -392,7 +391,7 @@ private:
CdcEitherVertex* eFromVertexp = (CdcEitherVertex*)edgep->fromp();
eFromVertexp->asyncPath(true);
}
return false;
return NULL;
}
}
@@ -527,7 +526,7 @@ private:
}
}
}
sort(report.begin(), report.end());
stable_sort(report.begin(), report.end());
for (deque<string>::iterator it = report.begin(); it!=report.end(); ++it) {
*ofp << *it;
}
@@ -713,6 +712,7 @@ private:
virtual void visit(AstInitial* nodep, AstNUser*) { }
virtual void visit(AstTraceInc* nodep, AstNUser*) { }
virtual void visit(AstCoverToggle* nodep, AstNUser*) { }
virtual void visit(AstNodeDType* nodep, AstNUser*) { }
//--------------------
// Default
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity block domains
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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 -21
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Add temporaries, such as for changed nodes
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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.
@@ -59,6 +58,12 @@ private:
AstScope* m_scopetopp; // Scope under TOPSCOPE
AstCFunc* m_chgFuncp; // Change function we're building
// CONSTANTS
enum MiscConsts {
DETECTARRAY_MAX_INDEXES = 256 // How many indexes before error
// Ok to increase this, but may result in much slower model
};
// METHODS
static int debug() {
static int level = -1;
@@ -66,14 +71,32 @@ private:
return level;
}
AstNode* aselIfNeeded(bool isArray, int index, AstNode* childp) {
if (isArray) {
return new AstArraySel(childp->fileline(), childp,
new AstConst(childp->fileline(), index));
} else {
return childp;
}
}
void genChangeDet(AstVarScope* vscp) {
#ifdef NEW_ORDERING
vscp->v3fatalSrc("Not applicable\n");
#endif
AstVar* varp = vscp->varp();
vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<<vscp);
if (!varp->dtypeSkipRefp()->castBasicDType()) {
vscp->v3error("Unsupported: Can't detect changes on arrayed variable (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName());
AstUnpackArrayDType* arrayp = varp->dtypeSkipRefp()->castUnpackArrayDType();
AstNodeClassDType *classp = varp->dtypeSkipRefp()->castNodeClassDType();
bool isArray = arrayp;
bool isClass = classp && classp->packedUnsup();
int elements = isArray ? arrayp->elementsConst() : 1;
if (isArray && (elements > DETECTARRAY_MAX_INDEXES)) {
vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect more than "<<cvtToStr(DETECTARRAY_MAX_INDEXES)
<<" array indexes (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName()<<endl
<<vscp->warnMore()
<<"... Could recompile with DETECTARRAY_MAX_INDEXES increased to at least "<<cvtToStr(elements));
} else if (!isArray && !isClass
&& !varp->dtypeSkipRefp()->castBasicDType()) {
if (debug()) varp->dumpTree(cout,"-DETECTARRAY-");
vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName());
} else {
string newvarname = "__Vchglast__"+vscp->scopep()->nameDotless()+"__"+varp->shortName();
// Create: VARREF(_last)
@@ -84,17 +107,23 @@ private:
m_topModp->addStmtp(newvarp);
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp);
m_scopetopp->addVarp(newvscp);
AstChangeDet* changep
= new AstChangeDet (vscp->fileline(),
new AstVarRef(vscp->fileline(), vscp, false),
new AstVarRef(vscp->fileline(), newvscp, false),
false);
m_chgFuncp->addStmtsp(changep);
AstAssign* initp
= new AstAssign (vscp->fileline(),
new AstVarRef(vscp->fileline(), newvscp, true),
new AstVarRef(vscp->fileline(), vscp, false));
m_chgFuncp->addFinalsp(initp);
for (int index=0; index<elements; ++index) {
AstChangeDet* changep
= new AstChangeDet (vscp->fileline(),
aselIfNeeded(isArray, index,
new AstVarRef(vscp->fileline(), vscp, false)),
aselIfNeeded(isArray, index,
new AstVarRef(vscp->fileline(), newvscp, false)),
false);
m_chgFuncp->addStmtsp(changep);
AstAssign* initp
= new AstAssign (vscp->fileline(),
aselIfNeeded(isArray, index,
new AstVarRef(vscp->fileline(), newvscp, true)),
aselIfNeeded(isArray, index,
new AstVarRef(vscp->fileline(), vscp, false)));
m_chgFuncp->addFinalsp(initp);
}
}
}
@@ -115,7 +144,7 @@ private:
if (!scopep) nodep->v3fatalSrc("No scope found on top level, perhaps you have no statements?\n");
m_scopetopp = scopep;
// Create change detection function
m_chgFuncp = new AstCFunc(nodep->fileline(), "_change_request", scopep, "IData");
m_chgFuncp = new AstCFunc(nodep->fileline(), "_change_request", scopep, "QData");
m_chgFuncp->argTypes(EmitCBaseVisitor::symClassVar());
m_chgFuncp->symProlog(true);
m_chgFuncp->declPrivate(true);
@@ -128,7 +157,7 @@ private:
virtual void visit(AstVarScope* nodep, AstNUser*) {
if (nodep->isCircular()) {
UINFO(8," CIRC "<<nodep<<endl);
if (!nodep->user1Inc()) {
if (!nodep->user1SetOnce()) {
genChangeDet(nodep);
}
}
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Pre C-Emit stage changes
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+24 -11
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Add temporaries, such as for clean nodes
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -24,7 +23,7 @@
// For each math operator, if it requires a clean operand,
// and the operand is dirty, insert a CLEAN node.
// Resize operands to C++ 32/64/wide types.
// Copy all width() values to minWidth() so RANGE, etc can still see orig widths
// Copy all width() values to widthMin() so RANGE, etc can still see orig widths
//
//*************************************************************************
@@ -47,9 +46,11 @@ private:
// NODE STATE
// Entire netlist:
// AstNode::user() -> CleanState. For this node, 0==UNKNOWN
// AstNode::user2() -> bool. True indicates minWidth has been propagated
// AstNode::user2() -> bool. True indicates widthMin has been propagated
// AstNodeDType::user3() -> AstNodeDType*. Alternative node with C size
AstUser1InUse m_inuser1;
AstUser2InUse m_inuser2;
AstUser3InUse m_inuser3;
// TYPES
enum CleanState { CS_UNKNOWN, CS_CLEAN, CS_DIRTY };
@@ -70,16 +71,28 @@ private:
else if (nodep->width()<=VL_QUADSIZE) return VL_QUADSIZE;
else return nodep->widthWords()*VL_WORDSIZE;
}
void setCppWidth (AstNode* nodep, int width, int widthMin) {
void setCppWidth (AstNode* nodep) {
nodep->user2(true); // Don't resize it again
nodep->width(width, widthMin);
AstNodeDType* old_dtypep = nodep->dtypep();
int width=cppWidth(nodep); // widthMin is unchanged
if (old_dtypep->width() != width) {
// Since any given dtype's cppWidth() is the same, we can just
// remember one convertion for each, and reuse it
if (AstNodeDType* new_dtypep = old_dtypep->user3p()->castNode()->castNodeDType()) {
nodep->dtypep(new_dtypep);
} else {
nodep->dtypeChgWidth(width, nodep->widthMin());
AstNodeDType* new_dtypep2 = nodep->dtypep();
if (new_dtypep2 == old_dtypep) nodep->v3fatalSrc("Dtype didn't change when width changed");
old_dtypep->user3p(new_dtypep2); // Remember for next time
}
}
}
void computeCppWidth (AstNode* nodep) {
if (!nodep->user2()) {
if (!nodep->user2() && nodep->hasDType()) {
if (nodep->castVar() || nodep->castNodeDType()) { // Don't want to change variable widths!
setCppWidth(nodep, nodep->width(), nodep->width()); // set widthMin anyways so can see it later
} else {
setCppWidth(nodep, cppWidth(nodep), nodep->widthMin());
setCppWidth(nodep);
}
}
}
@@ -116,7 +129,7 @@ private:
AstNode* cleanp = new AstAnd (nodep->fileline(),
new AstConst (nodep->fileline(), mask),
nodep);
setCppWidth (cleanp, cppWidth(nodep), nodep->widthMin());
cleanp->dtypeFrom(nodep); // Otherwise the AND normally picks LHS
relinkHandle.relink(cleanp);
}
void insureClean(AstNode* nodep) {
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Pre C-Emit stage changes
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+6 -7
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity active domains
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2008-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2008-2014 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.
@@ -686,6 +684,7 @@ class GaterVisitor : public GaterBaseVisitor {
AstNode* bodyp = nodep->bodysp()->cloneTree(true);
AstAlways* alwp = new AstAlways(nodep->fileline(),
nodep->keyword(),
sensesp,
bodyp);
@@ -705,7 +704,7 @@ class GaterVisitor : public GaterBaseVisitor {
virtual void visit(AstAlways* nodep, AstNUser*) {
if (debug()>=9) cout<<endl<<endl<<endl;
UINFO(5, "Gater: ALWAYS: "<<nodep<<endl);
if (nodep->user4Inc()) return;
if (nodep->user4SetOnce()) return;
clear();
@@ -862,9 +861,9 @@ class GaterVisitor : public GaterBaseVisitor {
m_stmtVscp = NULL;
m_stmtInPli = false;
}
if (!nodep->isSplittable()) {
if (!nodep->isPure() || nodep->isBrancher()) {
// May also be a new statement (above if); if so we mark it immediately
UINFO(9," NotSplittable "<<nodep<<endl);
UINFO(9," NotPure "<<nodep<<endl);
scoreboardPli(nodep);
}
{
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into clock gated blocks
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+20 -151
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Clocking POS/NEGEDGE insertion
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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,10 +82,9 @@ private:
AstVarScope* getCreateLastClk(AstVarScope* vscp) {
if (vscp->user1p()) return ((AstVarScope*)vscp->user1p());
AstVar* varp = vscp->varp();
if (varp->width()!=1) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<<varp->prettyName());
string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->shortName());
AstVar* newvarp = new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, AstLogicPacked(), 1);
newvarp->width(1,1);
if (!varp->width1()) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<<varp->prettyName());
string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->name());
AstVar* newvarp = new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, VFlagLogicPacked(), 1);
m_modp->addStmtp(newvarp);
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp);
vscp->user1p(newvscp);
@@ -104,7 +102,7 @@ private:
AstVarScope* getCreateLocalVar(FileLine* fl, const string& name, AstVar* examplep, int width) {
AstVar* newvarp;
if (width) {
newvarp = new AstVar (fl, AstVarType::BLOCKTEMP, name, AstLogicPacked(), width);
newvarp = new AstVar (fl, AstVarType::BLOCKTEMP, name, VFlagLogicPacked(), width);
} else {
newvarp = new AstVar (fl, AstVarType::BLOCKTEMP, name, examplep); // No range; 1 bit.
}
@@ -322,40 +320,14 @@ private:
}
nodep->deleteTree(); nodep = NULL;
}
void moveInitial(AstActive* nodep) {
// Change to CFunc
AstNode* stmtsp = nodep->stmtsp();
if (stmtsp) {
if (!m_scopep) nodep->v3fatalSrc("Initial Active not under scope\n");
AstCFunc* funcp = new AstCFunc(nodep->fileline(), "_initial__"+m_scopep->nameDotless(),
m_scopep);
funcp->argTypes(EmitCBaseVisitor::symClassVar());
funcp->symProlog(true);
funcp->slow(true);
stmtsp->unlinkFrBackWithNext();
funcp->addStmtsp(stmtsp);
nodep->replaceWith(funcp);
// Add top level call to it
AstCCall* callp = new AstCCall(nodep->fileline(), funcp);
callp->argTypes("vlSymsp");
m_initFuncp->addStmtsp(callp);
} else {
nodep->unlinkFrBack();
}
nodep->deleteTree(); nodep=NULL;
}
virtual void visit(AstCFunc* nodep, AstNUser*) {
nodep->iterateChildren(*this);
// Link to global function
if (nodep->formCallTree()) {
if (nodep->name() == "_final") {
UINFO(4, " formCallTree "<<nodep<<endl);
AstCCall* callp = new AstCCall(nodep->fileline(), nodep);
callp->argTypes("vlSymsp");
m_finalFuncp->addStmtsp(callp);
} else {
nodep->v3fatalSrc("Unknown CFunc name. Make code more generic, with a map of func names");
}
UINFO(4, " formCallTree "<<nodep<<endl);
AstCCall* callp = new AstCCall(nodep->fileline(), nodep);
callp->argTypes("vlSymsp");
m_finalFuncp->addStmtsp(callp);
}
}
virtual void visit(AstSenTree* nodep, AstNUser*) {
@@ -371,13 +343,14 @@ private:
if (m_untilp) m_untilp->addBodysp(stmtsp); // In a until loop, add to body
else m_settleFuncp->addStmtsp(stmtsp); // else add to top level function
}
void addToInitial(AstNode* stmtsp) {
if (m_untilp) m_untilp->addBodysp(stmtsp); // In a until loop, add to body
else m_initFuncp->addStmtsp(stmtsp); // else add to top level function
}
virtual void visit(AstActive* nodep, AstNUser*) {
// Careful if adding variables here, ACTIVES can be under other ACTIVES
// Need to save and restore any member state in AstUntilStable block
if (nodep->hasInitial()) {
moveInitial(nodep);
}
else if (!m_topScopep || !nodep->stmtsp()) {
if (!m_topScopep || !nodep->stmtsp()) {
// Not at the top or empty block...
// Only empty blocks should be leftover on the non-top. Killem.
if (nodep->stmtsp()) nodep->v3fatalSrc("Non-empty lower active");
@@ -387,6 +360,7 @@ private:
AstNode* stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
if (nodep->hasClocked()) {
// Remember the latest sensitivity so we can compare it next time
if (nodep->hasInitial()) nodep->v3fatalSrc("Initial block should not have clock sensitivity");
if (m_lastSenp && nodep->sensesp()->sameTree(m_lastSenp)) {
UINFO(4," sameSenseTree\n");
} else {
@@ -398,6 +372,10 @@ private:
}
// Move statements to if
m_lastIfp->addIfsp(stmtsp);
} else if (nodep->hasInitial()) {
// Don't need to: clearLastSen();, as we're adding it to different cfunc
// Move statements to function
addToInitial(stmtsp);
} else if (nodep->hasSettle()) {
// Don't need to: clearLastSen();, as we're adding it to different cfunc
// Move statements to function
@@ -412,115 +390,6 @@ private:
}
}
#ifdef NEW_ORDERING
virtual void visit(AstUntilStable* nodep, AstNUser*) {
// Process any sub ACTIVE statements first
UINFO(4," UNTILSTABLE "<<nodep<<endl);
{
// Keep vars if in middle of other stable
AstUntilStable* lastUntilp = m_untilp;
AstSenTree* lastSenp = m_lastSenp;
AstIf* lastIfp = m_lastIfp;
m_untilp = nodep;
m_lastSenp = NULL;
m_lastIfp = NULL;
nodep->iterateChildren(*this);
m_untilp = lastUntilp;
m_lastSenp = lastSenp;
m_lastIfp = lastIfp;
}
// Set "unstable" to 100. (non-stabilization count)
// int __VclockLoop = 0
// IData __Vchange = 1
// while (__Vchange) {
// Save old values of each until stable variable
// Evaluate the body
// __Vchange = {change_detect} contribution
// if (++__VclockLoop > 100) converge_error
if (debug()>4) nodep->dumpTree(cout, " UntilSt-old: ");
FileLine* fl = nodep->fileline();
if (nodep->bodysp()) fl = nodep->bodysp()->fileline(); // Point to applicable code...
m_stableNum++;
AstNode* origBodysp = nodep->bodysp(); if (origBodysp) origBodysp->unlinkFrBackWithNext();
AstVarScope* changeVarp = getCreateLocalVar(fl, "__Vchange"+cvtToStr(m_stableNum), NULL, 32);
AstVarScope* countVarp = getCreateLocalVar(fl, "__VloopCount"+cvtToStr(m_stableNum), NULL, 32);
AstWhile* untilp = new AstWhile(fl, new AstVarRef(fl, changeVarp, false), NULL);
AstNode* preUntilp = new AstComment(fl, "Change loop "+cvtToStr(m_stableNum));
preUntilp->addNext(new AstAssign(fl, new AstVarRef(fl, changeVarp, true),
new AstConst(fl, 1)));
preUntilp->addNext(new AstAssign(fl, new AstVarRef(fl, countVarp, true),
new AstConst(fl, 0)));
// Add stable variables & preinits
AstNode* setChglastp = NULL;
for (AstVarRef* varrefp = nodep->stablesp(); varrefp; varrefp=varrefp->nextp()->castVarRef()) {
AstVarScope* cmpvscp = getCreateLocalVar(varrefp->varp()->fileline(),
"__Vchglast"+cvtToStr(m_stableNum)+"__"+varrefp->name(),
varrefp->varp(), 0);
varrefp->varScopep()->user2p(cmpvscp);
setChglastp = setChglastp->addNext(
new AstAssign(fl, new AstVarRef(fl, cmpvscp, true),
new AstVarRef(fl, varrefp->varScopep(), false)));
}
if (!setChglastp) nodep->v3fatalSrc("UntilStable without any variables");
untilp->addBodysp(setChglastp);
untilp->addBodysp(new AstComment(fl, "Change Loop body begin"));
if (origBodysp) untilp->addBodysp(origBodysp);
untilp->addBodysp(new AstComment(fl, "Change Loop body end"));
// Add stable checks
// The order of the variables doesn't matter, but it's more expensive to test
// wide variables, and more so 64 bit wide ones. Someday it might be faster to
// set the changed variable in a "distributed" fashion over the code, IE,
// logic... logic.... a=....; Changed |= (a ^ old_a); more logic... Changed |=...
// But then, one hopes users don't have much unoptimized logic
AstNode* changeExprp = NULL;
int doublecount = 0;
for (int wide=0; wide<3; wide++) { // Adding backwards; wide, quad, then normal
for (AstVarRef* varrefp = nodep->stablesp(); varrefp; varrefp=varrefp->nextp()->castVarRef()) {
if (wide== ( varrefp->isQuad()?0:(varrefp->isWide() ? 1:2))) {
AstVarScope* cmpvscp = (AstVarScope*)(varrefp->varScopep()->user2p());
if (!cmpvscp) varrefp->v3fatalSrc("should have created above");
AstChangeXor* changep
= new AstChangeXor (fl,
new AstVarRef(fl, varrefp->varScopep(), false),
new AstVarRef(fl, cmpvscp, false));
if (!changeExprp) changeExprp = changep;
else if (doublecount++ > DOUBLE_OR_RATE) {
doublecount = 0;
changeExprp = new AstLogOr (fl, changep, changeExprp);
} else {
changeExprp = new AstOr (fl, changep, changeExprp);
}
}
}
}
if (!changeExprp) nodep->v3fatalSrc("UntilStable without any variables");
changeExprp = new AstAssign(fl, new AstVarRef(fl, changeVarp, true),
changeExprp);
untilp->addBodysp(changeExprp);
//
// Final body
AstNode* ifstmtp = new AstAssign(fl, new AstVarRef(fl, countVarp, true),
new AstAdd(fl, new AstConst(fl, 1),
new AstVarRef(fl, countVarp, false)));
ifstmtp->addNext(new AstIf(fl,
new AstLt (fl, new AstConst(fl, 100),
new AstVarRef(fl, countVarp, false)),
(new AstDisplay (fl, AstDisplayType::DT_DISPLAY,
"%%Error: Verilated model didn't converge", NULL, NULL))
->addNext(new AstStop (fl)),
NULL));
untilp->addBodysp(new AstIf(fl, new AstNeq(fl, new AstConst(fl, 0),
new AstVarRef(fl, changeVarp, false)),
ifstmtp, NULL));
//
// Replace it
preUntilp->addNext(untilp);
if (debug()>4) preUntilp->dumpTreeAndNext(cout, " UntilSt-new: ");
nodep->replaceWith(preUntilp); nodep->deleteTree(); nodep=NULL;
}
#endif
//--------------------
// Default: Just iterate
virtual void visit(AstNode* nodep, AstNUser*) {
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Clocking POS/NEGEDGE insertion
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+2 -3
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Combine common code into functions
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Combine common code into functions
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Configuration Files
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2010-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2010-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -26,6 +25,7 @@
#include <set>
#include "V3Global.h"
#include "V3String.h"
#include "V3Config.h"
//######################################################################
@@ -62,7 +62,7 @@ class V3ConfigIgnores {
IgnFiles m_ignWilds; // Ignores for each wildcarded filename
IgnFiles m_ignFiles; // Ignores for each non-wildcarded filename
static V3ConfigIgnores s_singleton; // Singleton (not via local static, as that's slow)
V3ConfigIgnores() { m_lastLineno = -1; }
@@ -90,7 +90,7 @@ class V3ConfigIgnores {
it = m_ignFiles.find(filename);
// Make new list for this file of all matches
for (IgnFiles::iterator fnit = m_ignWilds.begin(); fnit != m_ignWilds.end(); ++fnit) {
if (V3Options::wildmatch(filename.c_str(), fnit->first.c_str())) {
if (VString::wildmatch(filename.c_str(), fnit->first.c_str())) {
for (IgnLines::iterator lit = fnit->second.begin(); lit != fnit->second.end(); ++lit) {
it->second.insert(*lit);
}
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Configuration Files
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2010-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2010-2014 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.
+403 -145
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Constant folding
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -104,9 +103,13 @@ private:
bool m_warn; // Output warnings
bool m_doExpensive; // Enable computationally expensive optimizations
bool m_doNConst; // Enable non-constant-child simplifications
bool m_doShort; // Remove expressions that short circuit
bool m_doV; // Verilog, not C++ conversion
AstNodeModule* m_modp; // Current module
bool m_doGenerate; // Postpone width checking inside generate
AstNodeModule* m_modp; // Current module
AstArraySel* m_selp; // Current select
AstNode* m_scopep; // Current scope
AstAttrOf* m_attrp; // Current attribute
// METHODS
static int debug() {
@@ -149,7 +152,7 @@ private:
// BIASV(CONSTa,BIASV(b...,BIASV(CONSTc,d...))) // hits operandAsvUp
// BIASV(CONSTa,BIASV(CONSTc,BIASV(c...,d...))) // hits operandAsvConst
// BIASV(BIASV(CONSTa,CONSTc),BIASV(c...,d...))) // hits normal constant propagation
// BIASV(CONST_a_c,BIASV(c...,d...)))
// BIASV(CONST_a_c,BIASV(c...,d...)))
//
// Idea for the future: All BiComAsvs could be lists, sorted by if they're constant
AstNodeBiComAsv* bnodep = nodep->castNodeBiComAsv();
@@ -171,13 +174,16 @@ private:
return rnodep->lhsp()->castConst();
}
static bool operandAndOrSame(AstNode* nodep) {
// OR( AND(VAL,x), AND(VAL,y)) -> AND(VAL,OR(x,y))
// OR( AND(x,VAL), AND(y,VAL)) -> AND(OR(x,y),VAL)
AstNodeBiop* np = nodep->castNodeBiop();
AstNodeBiop* lp = np->lhsp()->castNodeBiop();
AstNodeBiop* rp = np->rhsp()->castNodeBiop();
return (lp && rp
&& lp->width()==rp->width()
&& lp->type()==rp->type()
&& operandsSame(lp->lhsp(),rp->lhsp()));
&& (operandsSame(lp->lhsp(),rp->lhsp())
|| operandsSame(lp->rhsp(),rp->rhsp())));
}
static bool matchOrAndNot(AstNodeBiop* nodep) {
// AstOr{$a, AstAnd{AstNot{$b}, $c}} if $a.width1, $a==$b => AstOr{$a,$c}
@@ -228,14 +234,19 @@ private:
}
bool operandHugeShiftL(AstNodeBiop* nodep) {
return (nodep->rhsp()->castConst()
&& nodep->rhsp()->castConst()->toUInt() >= (uint32_t)(nodep->width()));
&& !nodep->rhsp()->castConst()->num().isFourState()
&& nodep->rhsp()->castConst()->toUInt() >= (uint32_t)(nodep->width())
&& isTPure(nodep->lhsp()));
}
bool operandHugeShiftR(AstNodeBiop* nodep) {
return (nodep->rhsp()->castConst()
&& nodep->rhsp()->castConst()->toUInt() >= (uint32_t)(nodep->lhsp()->width()));
&& !nodep->rhsp()->castConst()->num().isFourState()
&& nodep->rhsp()->castConst()->toUInt() >= (uint32_t)(nodep->lhsp()->width())
&& isTPure(nodep->lhsp()));
}
bool operandIsTwo(AstNode* nodep) {
return (nodep->castConst()
&& !nodep->castConst()->num().isFourState()
&& nodep->width() <= VL_QUADSIZE
&& nodep->castConst()->toUQuad()==2);
}
@@ -320,27 +331,27 @@ private:
}
bool operandBiExtendConst(AstNodeBiop* nodep) {
// Loop unrolling likes standalone compares
// EQ(EXTEND(xx{width3}), const{width32}) -> EQ(xx{3},const{3})
// Loop unrolling favors standalone compares
// EQ(const{width32}, EXTEND(xx{width3})) -> EQ(const{3}, xx{3})
// Beware that the constant must have zero bits (+ 1 if signed) or compare
// would be incorrect
AstExtend* extendp = nodep->lhsp()->castExtend();
AstExtend* extendp = nodep->rhsp()->castExtend();
if (!extendp) return false;
AstNode* smallerp = extendp->lhsp();
int subsize = smallerp->width();
AstConst* constp = nodep->rhsp()->castConst();
AstConst* constp = nodep->lhsp()->castConst();
if (!constp) return false;
if (!constp->num().isBitsZero(constp->width()-1, subsize)) return false;
//
if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-in:");
smallerp->unlinkFrBack();
extendp->unlinkFrBack()->deleteTree(); // aka nodep->lhsp.
nodep->lhsp(smallerp);
nodep->rhsp(smallerp);
constp->unlinkFrBack();
V3Number num (constp->fileline(), subsize);
num.opAssign(constp->num());
nodep->rhsp(new AstConst(constp->fileline(), num));
nodep->lhsp(new AstConst(constp->fileline(), num));
constp->deleteTree(); constp=NULL;
if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-ou:");
return true;
@@ -353,34 +364,50 @@ private:
return nodep;
}
bool isTPure(AstNode* nodep) {
// Pure checks - if this node and all nodes under it are free of
// side effects can do this optimization
// Eventually we'll recurse through tree when unknown, memoizing results so far,
// but for now can disable en-mass until V3Purify takes effect.
return m_doShort || nodep->castVarRef() || nodep->castConst();
}
// Extraction checks
bool warnSelect(AstSel* nodep) {
AstNode* basefromp = AstArraySel::baseFromp(nodep);
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
AstVar* varp = varrefp->varp();
if (!varp->dtypep()) varp->v3fatalSrc("Data type lost");
AstBasicDType* bdtypep = varp->basicp(); if (!bdtypep) varp->v3fatalSrc("Select of non-selectable type");
if (m_warn
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& (!bdtypep->rangep() || bdtypep->msb())) { // else it's non-resolvable parameterized
if (nodep->lsbp()->castConst()->num().isFourState()
|| nodep->widthp()->castConst()->num().isFourState()) {
nodep->v3error("Selection index is constantly unknown or tristated: "
"lsb="<<nodep->lsbp()->name()<<" width="<<nodep->widthp()->name());
// Replacing nodep will make a mess above, so we replace the offender
replaceZero(nodep->lsbp());
}
else if ((nodep->msbConst() > bdtypep->msbMaxSelect())
|| (nodep->lsbConst() > bdtypep->msbMaxSelect())) {
// See also warning in V3Width
nodep->v3error("Selection index out of range: "
<<nodep->msbConst()<<":"<<nodep->lsbConst()
<<" outside "<<bdtypep->msbMaxSelect()<<":0"
<<(bdtypep->lsb()>=0 ? ""
:" (adjusted +"+cvtToStr(-bdtypep->lsb())+" to account for negative lsb)"));
// Don't replace with zero, we'll do it later
}
if (m_doGenerate) {
// Never checked yet
V3Width::widthParamsEdit(nodep);
nodep->iterateChildren(*this); // May need "constifying"
}
// Find range of dtype we are selecting from
// Similar code in V3Unknown::AstSel
bool doit = true;
if (m_warn
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& doit) {
int maxDeclBit = nodep->declRange().hiMaxSelect()*nodep->declElWidth() + (nodep->declElWidth()-1);
if (nodep->lsbp()->castConst()->num().isFourState()
|| nodep->widthp()->castConst()->num().isFourState()) {
nodep->v3error("Selection index is constantly unknown or tristated: "
"lsb="<<nodep->lsbp()->name()<<" width="<<nodep->widthp()->name());
// Replacing nodep will make a mess above, so we replace the offender
replaceZero(nodep->lsbp());
}
else if (nodep->declRange().ranged()
&& (nodep->msbConst() > maxDeclBit
|| nodep->lsbConst() > maxDeclBit)) {
// See also warning in V3Width
// Must adjust by element width as declRange() is in number of elements
nodep->v3warn(SELRANGE, "Selection index out of range: "
<<(nodep->msbConst()/nodep->declElWidth())
<<":"<<(nodep->lsbConst()/nodep->declElWidth())
<<" outside "<<nodep->declRange().hiMaxSelect()<<":0"
<<(nodep->declRange().lo()>=0 ? ""
:(" (adjusted +"+cvtToStr(-nodep->declRange().lo())
+" to account for negative lsb)")));
UINFO(1," Related Raw index is "<<nodep->msbConst()<<":"<<nodep->lsbConst()<<endl);
// Don't replace with zero, we'll do it later
}
}
return false; // Not a transform, so NOP
@@ -392,7 +419,10 @@ private:
return node1p->sameTree(node2p);
}
else if (node1p->castVarRef() && node2p->castVarRef()) {
return node1p->sameTree(node2p);
// Avoid comparing widthMin's, which results in lost optimization attempts
// If cleanup sameTree to be smarter, this can be restored.
//return node1p->sameTree(node2p);
return node1p->same(node2p);
} else {
return false;
}
@@ -407,7 +437,7 @@ private:
AstVarRef* elsevarp = elsep->lhsp()->castVarRef();
if (!ifvarp || !elsevarp) return false;
if (ifvarp->isWide()) return false; // Would need temporaries, so not worth it
if (ifvarp->varp() != elsevarp->varp()) return false;
if (!ifvarp->sameTree(elsevarp)) return false;
return true;
}
bool operandIfIf(AstNodeIf* nodep) {
@@ -430,7 +460,7 @@ private:
oldp->v3fatalSrc("Already constant??\n");
}
AstNode* newp = new AstConst(oldp->fileline(), num);
newp->widthSignedFrom(oldp);
newp->dtypeFrom(oldp);
if (debug()>5) oldp->dumpTree(cout," const_old: ");
if (debug()>5) newp->dumpTree(cout," _new: ");
oldp->replaceWith(newp);
@@ -455,6 +485,21 @@ private:
void replaceZero(AstNode* nodep) {
replaceNum(nodep, 0); nodep=NULL;
}
void replaceZeroChkPure(AstNode* nodep, AstNode* checkp) {
// For example, "0 * n" -> 0 if n has no side effects
// Else strength reduce it to 0 & n.
// If ever change the operation note AstAnd rule specially ignores this created pattern
if (isTPure(checkp)) {
replaceNum(nodep, 0); nodep=NULL;
} else {
AstNode* newp = new AstAnd(nodep->fileline(),
new AstConst(nodep->fileline(), 0),
checkp->unlinkFrBack());
newp->dtypeFrom(nodep);
nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL;
}
}
void replaceAllOnes (AstNode* nodep) {
V3Number ones (nodep->fileline(), nodep->width(), 0);
ones.setMask(nodep->width());
@@ -497,10 +542,26 @@ private:
void replaceWChild(AstNode* nodep, AstNode* childp) {
// NODE(..., CHILD(...)) -> CHILD(...)
childp->unlinkFrBackWithNext();
childp->widthSignedFrom(nodep);
// If replacing a SEL for example, the data type comes from the parent (is less wide).
// This may adversly affect the operation of the node being replaced.
childp->dtypeFrom(nodep);
nodep->replaceWith(childp);
nodep->deleteTree(); nodep=NULL;
}
//! Replace a ternary node with its RHS after iterating
//! Used with short-circuting, where the RHS has not yet been iterated.
void replaceWIteratedRhs(AstNodeTriop* nodep) {
if (AstNode *rhsp = nodep->rhsp()) rhsp->iterateAndNext(*this);
replaceWChild(nodep, nodep->rhsp()); // May have changed
}
//! Replace a ternary node with its THS after iterating
//! Used with short-circuting, where the THS has not yet been iterated.
void replaceWIteratedThs(AstNodeTriop* nodep) {
if (AstNode *thsp = nodep->thsp()) thsp->iterateAndNext(*this);
replaceWChild(nodep, nodep->thsp()); // May have changed
}
void replaceWLhs(AstNodeUniop* nodep) {
// Keep LHS, remove RHS
replaceWChild(nodep, nodep->lhsp());
@@ -557,7 +618,9 @@ private:
//nodep->dumpTree(cout, " repAsvRUp_new: ");
}
void replaceAndOr (AstNodeBiop* nodep) {
// Or(And(CONSTll,lr),And(CONSTrl==ll,rr)) -> And(CONSTll,Or(lr,rr))
// OR (AND (CONSTll,lr), AND(CONSTrl==ll,rr)) -> AND (CONSTll, OR(lr,rr))
// OR (AND (CONSTll,lr), AND(CONSTrl, rr=lr)) -> AND (OR(ll,rl), rr)
// nodep ^lp ^llp ^lrp ^rp ^rlp ^rrp
// (Or/And may also be reversed)
AstNodeBiop* lp = nodep->lhsp()->unlinkFrBack()->castNodeBiop();
AstNode* llp = lp->lhsp()->unlinkFrBack();
@@ -566,12 +629,23 @@ private:
AstNode* rlp = rp->lhsp()->unlinkFrBack();
AstNode* rrp = rp->rhsp()->unlinkFrBack();
nodep->replaceWith(lp);
lp->lhsp(llp);
lp->rhsp(nodep);
nodep->lhsp(lrp);
nodep->rhsp(rrp);
rp->deleteTree();
rlp->deleteTree();
if (operandsSame(llp,rlp)) {
lp->lhsp(llp);
lp->rhsp(nodep);
nodep->lhsp(lrp);
nodep->rhsp(rrp);
rp->deleteTree();
rlp->deleteTree();
} else if (operandsSame(lrp, rrp)) {
lp->lhsp(nodep);
lp->rhsp(rrp);
nodep->lhsp(llp);
nodep->rhsp(rlp);
rp->deleteTree();
lrp->deleteTree();
} else {
nodep->v3fatalSrc("replaceAndOr on something operandAndOrSame shouldn't have matched");
}
//nodep->dumpTree(cout, " repAndOr_new: ");
}
void replaceShiftSame (AstNodeBiop* nodep) {
@@ -599,7 +673,7 @@ private:
AstNode* newp = (nodep->castExtendS()
? (new AstExtendS(nodep->fileline(), arg0p))->castNode()
: (new AstExtend (nodep->fileline(), arg0p))->castNode());
newp->widthSignedFrom(nodep);
newp->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
}
void replacePowShift (AstNodeBiop* nodep) { // Pow or PowS
@@ -608,8 +682,8 @@ private:
AstShiftL* newp = new AstShiftL(nodep->fileline(),
new AstConst(nodep->fileline(), 1),
rhsp);
newp->widthSignedFrom(nodep);
newp->lhsp()->widthSignedFrom(nodep);
newp->dtypeFrom(nodep);
newp->lhsp()->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
}
void replaceMulShift (AstMul* nodep) { // Mul, but not MulS as not simple shift
@@ -618,7 +692,7 @@ private:
AstNode* opp = nodep->rhsp()->unlinkFrBack();
AstShiftL* newp = new AstShiftL(nodep->fileline(),
opp, new AstConst(nodep->fileline(), amount));
newp->widthSignedFrom(nodep);
newp->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
}
void replaceDivShift (AstDiv* nodep) { // Mul, but not MulS as not simple shift
@@ -627,7 +701,7 @@ private:
AstNode* opp = nodep->lhsp()->unlinkFrBack();
AstShiftR* newp = new AstShiftR(nodep->fileline(),
opp, new AstConst(nodep->fileline(), amount));
newp->widthSignedFrom(nodep);
newp->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
}
void replaceShiftOp (AstNodeBiop* nodep) {
@@ -654,9 +728,15 @@ private:
AstNode* ap = lhsp->lhsp()->unlinkFrBack();
AstNode* shift1p = lhsp->rhsp()->unlinkFrBack();
AstNode* shift2p = nodep->rhsp()->unlinkFrBack();
// Shift1p and shift2p may have different sizes, both are self-determined so sum with infinite width
if (nodep->type()==lhsp->type()) {
int shift1 = shift1p->castConst()->toUInt();
int shift2 = shift2p->castConst()->toUInt();
int newshift = shift1+shift2;
shift1p->deleteTree(); shift1p=NULL;
shift2p->deleteTree(); shift2p=NULL;
nodep->lhsp(ap);
nodep->rhsp(new AstAdd(nodep->fileline(), shift1p, shift2p));
nodep->rhsp(new AstConst(nodep->fileline(), newshift));
nodep->accept(*this); // Further reduce, either node may have more reductions.
} else {
// We know shift amounts are constant, but might be a mixed left/right shift
@@ -664,7 +744,7 @@ private:
int shift2 = shift2p->castConst()->toUInt(); if (nodep->castShiftR()) shift2=-shift2;
int newshift = shift1+shift2;
shift1p->deleteTree(); shift1p=NULL;
shift2p->deleteTree(); shift1p=NULL;
shift2p->deleteTree(); shift2p=NULL;
AstNode* newp;
V3Number mask1 (nodep->fileline(), nodep->width());
V3Number ones (nodep->fileline(), nodep->width());
@@ -687,11 +767,11 @@ private:
newp = new AstShiftL(nodep->fileline(), ap,
new AstConst(nodep->fileline(), newshift));
}
newp->widthSignedFrom(nodep);
newp->dtypeFrom(nodep);
newp = new AstAnd (nodep->fileline(),
newp,
new AstConst (nodep->fileline(), mask));
newp->widthSignedFrom(nodep);
newp->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
//newp->dumpTree(cout, " repShiftShift_new: ");
newp->accept(*this); // Further reduce, either node may have more reductions.
@@ -710,7 +790,7 @@ private:
AstSel* sel2p = nextp->lhsp()->castSel(); if (!sel2p) return false;
AstVarRef* varref1p = sel1p->fromp()->castVarRef(); if (!varref1p) return false;
AstVarRef* varref2p = sel2p->fromp()->castVarRef(); if (!varref2p) return false;
if (varref1p->varp() != varref2p->varp()) return false;
if (!varref1p->sameTree(varref2p)) return false;
AstConst* con1p = sel1p->lsbp()->castConst(); if (!con1p) return false;
AstConst* con2p = sel2p->lsbp()->castConst(); if (!con2p) return false;
// We need to make sure there's no self-references involved in either
@@ -747,9 +827,10 @@ private:
bool varNotReferenced(AstNode* nodep, AstVar* varp, int level=0) {
// Return true if varp never referenced under node.
// Return false if referenced, or tree too deep to be worth it
// Return false if referenced, or tree too deep to be worth it, or side effects
if (!nodep) return true;
if (level>2) return false;
if (nodep->isPure()) return false; // For example a $fgetc can't be reordered
if (nodep->castNodeVarRef() && nodep->castNodeVarRef()->varp()==varp) return false;
return (varNotReferenced (nodep->nextp(),varp,level+1)
&& varNotReferenced(nodep->op1p(),varp,level+1)
@@ -761,7 +842,7 @@ private:
bool replaceNodeAssign(AstNodeAssign* nodep) {
if (nodep->lhsp()->castVarRef()
&& nodep->rhsp()->castVarRef()
&& nodep->lhsp()->sameTree(nodep->rhsp())
&& nodep->lhsp()->castVarRef()->sameNoLvalue(nodep->rhsp()->castVarRef())
&& !nodep->castAssignDly()) {
// X = X. Quite pointless, though X <= X may override another earlier assignment
if (nodep->castAssignW()) {
@@ -797,10 +878,10 @@ private:
}
if (debug()>=9) nodep->dumpTree(cout," Ass_old: ");
// Unlink the stuff
AstNode* lc1p = nodep->lhsp()->castConcat()->lhsp()->unlinkFrBack();
AstNode* lc2p = nodep->lhsp()->castConcat()->rhsp()->unlinkFrBack();
AstNode* conp = nodep->lhsp()->castConcat()->unlinkFrBack();
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
AstNode* lc1p = nodep->lhsp()->castConcat()->lhsp()->unlinkFrBack();
AstNode* lc2p = nodep->lhsp()->castConcat()->rhsp()->unlinkFrBack();
AstNode* conp = nodep->lhsp()->castConcat()->unlinkFrBack();
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
AstNode* rhs2p = rhsp->cloneTree(false);
// Calc widths
int lsb2 = 0;
@@ -811,16 +892,14 @@ private:
// Form ranges
AstSel* sel1p = new AstSel(conp->fileline(), rhsp, lsb1, msb1-lsb1+1);
AstSel* sel2p = new AstSel(conp->fileline(), rhs2p, lsb2, msb2-lsb2+1);
sel1p->width(msb1-lsb1+1,msb1-lsb1+1);
sel2p->width(msb2-lsb2+1,msb2-lsb2+1);
// Make new assigns of same flavor as old one
//*** Not cloneTree; just one node.
AstNode* newp = NULL;
if (!need_temp) {
AstNodeAssign* asn1ap=nodep->cloneType(lc1p, sel1p)->castNodeAssign();
AstNodeAssign* asn2ap=nodep->cloneType(lc2p, sel2p)->castNodeAssign();
asn1ap->width(msb1-lsb1+1,msb1-lsb1+1);
asn2ap->width(msb2-lsb2+1,msb2-lsb2+1);
asn1ap->dtypeFrom(sel1p);
asn2ap->dtypeFrom(sel2p);
// cppcheck-suppress nullPointer // addNext deals with it
newp = newp->addNext(asn1ap);
// cppcheck-suppress nullPointer // addNext deals with it
@@ -832,9 +911,9 @@ private:
string name1 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc()));
string name2 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc()));
AstVar* temp1p = new AstVar(sel1p->fileline(), AstVarType::BLOCKTEMP, name1,
AstLogicPacked(), msb1-lsb1+1);
VFlagLogicPacked(), msb1-lsb1+1);
AstVar* temp2p = new AstVar(sel2p->fileline(), AstVarType::BLOCKTEMP, name2,
AstLogicPacked(), msb2-lsb2+1);
VFlagLogicPacked(), msb2-lsb2+1);
m_modp->addStmtp(temp1p);
m_modp->addStmtp(temp2p);
AstNodeAssign* asn1ap=nodep->cloneType
@@ -849,10 +928,10 @@ private:
AstNodeAssign* asn2bp=nodep->cloneType
(lc2p, new AstVarRef(sel2p->fileline(), temp2p, false))
->castNodeAssign();
asn1ap->width(msb1-lsb1+1,msb1-lsb1+1);
asn1bp->width(msb1-lsb1+1,msb1-lsb1+1);
asn2ap->width(msb2-lsb2+1,msb2-lsb2+1);
asn2bp->width(msb2-lsb2+1,msb2-lsb2+1);
asn1ap->dtypeFrom(temp1p);
asn1bp->dtypeFrom(temp1p);
asn2ap->dtypeFrom(temp2p);
asn2bp->dtypeFrom(temp2p);
// This order matters
// cppcheck-suppress nullPointer // addNext deals with it
newp = newp->addNext(asn1ap);
@@ -871,6 +950,64 @@ private:
// Further reduce, either node may have more reductions.
return true;
}
else if (m_doV && nodep->rhsp()->castStreamR()) {
// The right-streaming operator on rhs of assignment does not
// change the order of bits. Eliminate stream but keep its lhsp
// Unlink the stuff
AstNode* srcp = nodep->rhsp()->castStreamR()->lhsp()->unlinkFrBack();
AstNode* sizep = nodep->rhsp()->castStreamR()->rhsp()->unlinkFrBack();
AstNode* streamp = nodep->rhsp()->castStreamR()->unlinkFrBack();
nodep->rhsp(srcp);
// Cleanup
sizep->deleteTree(); sizep=NULL;
streamp->deleteTree(); streamp=NULL;
// Further reduce, any of the nodes may have more reductions.
return true;
}
else if (m_doV && nodep->lhsp()->castStreamL()) {
// Push the stream operator to the rhs of the assignment statement
int dWidth = nodep->lhsp()->castStreamL()->lhsp()->width();
int sWidth = nodep->rhsp()->width();
// Unlink the stuff
AstNode* dstp = nodep->lhsp()->castStreamL()->lhsp()->unlinkFrBack();
AstNode* streamp = nodep->lhsp()->castStreamL()->unlinkFrBack();
AstNode* srcp = nodep->rhsp()->unlinkFrBack();
// Connect the rhs to the stream operator and update its width
streamp->castStreamL()->lhsp(srcp);
streamp->dtypeSetLogicSized((srcp->width()),
(srcp->widthMin()),
AstNumeric::UNSIGNED);
// Shrink the RHS if necessary
if (sWidth > dWidth) {
streamp = new AstSel(streamp->fileline(), streamp, sWidth-dWidth, dWidth);
}
// Link the nodes back in
nodep->lhsp(dstp);
nodep->rhsp(streamp);
return true;
}
else if (m_doV && nodep->lhsp()->castStreamR()) {
// The right stream operator on lhs of assignment statement does
// not reorder bits. However, if the rhs is wider than the lhs,
// then we select bits from the left-most, not the right-most.
int dWidth = nodep->lhsp()->castStreamR()->lhsp()->width();
int sWidth = nodep->rhsp()->width();
// Unlink the stuff
AstNode* dstp = nodep->lhsp()->castStreamR()->lhsp()->unlinkFrBack();
AstNode* sizep = nodep->lhsp()->castStreamR()->rhsp()->unlinkFrBack();
AstNode* streamp = nodep->lhsp()->castStreamR()->unlinkFrBack();
AstNode* srcp = nodep->rhsp()->unlinkFrBack();
if (sWidth > dWidth) {
srcp = new AstSel(streamp->fileline(), srcp, sWidth-dWidth, dWidth);
}
nodep->lhsp(dstp);
nodep->rhsp(srcp);
// Cleanup
sizep->deleteTree(); sizep=NULL;
streamp->deleteTree(); streamp=NULL;
// Further reduce, any of the nodes may have more reductions.
return true;
}
else if (replaceAssignMultiSel(nodep)) {
return true;
}
@@ -898,7 +1035,7 @@ private:
AstAnd* newp = new AstAnd(nodep->fileline(),
new AstConst(nodep->fileline(), val),
fromp);
newp->width(nodep->width(), nodep->width()); // widthMin no longer applicable
newp->dtypeSetLogicSized(nodep->width(), nodep->width(), AstNumeric::UNSIGNED); // widthMin no longer applicable if different C-expanded width
nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL;
if (debug()>=9) newp->dumpTree(cout," _new: ");
@@ -912,7 +1049,7 @@ private:
AstNode* errorp = simvis.whyNotNodep(); if (!errorp) errorp = nodep;
nodep->v3error("Expecting expression to be constant, but can't determine constant for "
<<nodep->prettyTypeName()<<endl
<<V3Error::msgPrefix(V3ErrorCode::EC_ERROR,false)<<errorp->fileline()<<"... Location of non-constant "
<<errorp->warnMore()<<"... Location of non-constant "
<<errorp->prettyTypeName()<<": "<<simvis.whyNotMessage());
replaceZero(nodep); nodep=NULL;
} else {
@@ -1049,8 +1186,8 @@ private:
// expression, not the potentially smaller lsb1p's width
newlsbp = new AstAdd(lsb1p->fileline(),
lsb2p, new AstExtend(lsb1p->fileline(), lsb1p));
newlsbp->widthFrom(lsb2p); // Unsigned
newlsbp->castAdd()->rhsp()->widthFrom(lsb2p); // Unsigned
newlsbp->dtypeFrom(lsb2p); // Unsigned
newlsbp->castAdd()->rhsp()->dtypeFrom(lsb2p);
}
AstSel* newp = new AstSel(nodep->fileline(),
fromp,
@@ -1110,7 +1247,7 @@ private:
fromp,
new AstConst(lsbp->fileline(), lsbp->toUInt() % fromp->width()),
widthp);
newp->widthSignedFrom(nodep);
newp->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
}
@@ -1128,7 +1265,7 @@ private:
bilhsp, lsbp->cloneTree(true), widthp->cloneTree(true)));
fromp->rhsp(new AstSel(nodep->fileline(),
birhsp, lsbp, widthp));
fromp->widthSignedFrom(nodep);
fromp->dtypeFrom(nodep);
nodep->replaceWith(fromp); nodep->deleteTree(); nodep=NULL;
}
void replaceSelIntoUniop(AstSel* nodep) {
@@ -1141,30 +1278,70 @@ private:
AstNode* bilhsp = fromp->lhsp()->unlinkFrBack();
//
fromp->lhsp(new AstSel(nodep->fileline(),
bilhsp, lsbp->cloneTree(true), widthp->cloneTree(true)));
fromp->widthSignedFrom(nodep);
bilhsp, lsbp, widthp));
fromp->dtypeFrom(nodep);
nodep->replaceWith(fromp); nodep->deleteTree(); nodep=NULL;
}
virtual void visit(AstAttrOf* nodep, AstNUser*) {
AstAttrOf* oldAttr = m_attrp;
m_attrp = nodep;
nodep->iterateChildren(*this);
m_attrp = oldAttr;
}
virtual void visit(AstArraySel* nodep, AstNUser*) {
nodep->bitp()->iterateAndNext(*this);
if (nodep->bitp()->castConst()
&& nodep->fromp()->castVarRef()
// Need to make sure it's an array object so don't mis-allow a constant (bug509.)
&& nodep->fromp()->castVarRef()->varp()
&& nodep->fromp()->castVarRef()->varp()->valuep()->castInitArray()) {
m_selp = nodep; // Ask visit(AstVarRef) to replace varref with const
}
nodep->fromp()->iterateAndNext(*this);
if (nodep->fromp()->castConst()) { // It did.
if (!m_selp) {
nodep->v3error("Illegal assignment of constant to unpacked array");
} else {
nodep->replaceWith(nodep->fromp()->unlinkFrBack());
}
}
m_selp = NULL;
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (!nodep->varp()) nodep->v3fatalSrc("Not linked");
bool did=false;
if (m_doV && nodep->varp()->hasSimpleInit() && !nodep->backp()->castAttrOf()) {
//if (debug()) nodep->varp()->valuep()->dumpTree(cout," visitvaref: ");
nodep->varp()->valuep()->iterateAndNext(*this);
if (operandConst(nodep->varp()->valuep())
&& !nodep->lvalue()
if (m_doV && nodep->varp()->valuep() && !m_attrp) {
//if (debug()) valuep->dumpTree(cout," visitvaref: ");
nodep->varp()->valuep()->iterateAndNext(*this); // May change nodep->varp()->valuep()
AstNode* valuep = nodep->varp()->valuep();
if (!nodep->lvalue()
&& ((!m_params // Can reduce constant wires into equations
&& m_doNConst
&& v3Global.opt.oConst()
&& !(nodep->varp()->isFuncLocal() // Default value, not a "known" constant for this usage
&& nodep->varp()->isInput())
&& !nodep->varp()->isSigPublic())
|| nodep->varp()->isParam())) {
AstConst* constp = nodep->varp()->valuep()->castConst();
const V3Number& num = constp->num();
//UINFO(2,"constVisit "<<(void*)constp<<" "<<num<<endl);
replaceNum(nodep, num); nodep=NULL;
did=true;
if (operandConst(valuep)) {
const V3Number& num = valuep->castConst()->num();
//UINFO(2,"constVisit "<<(void*)valuep<<" "<<num<<endl);
replaceNum(nodep, num); nodep=NULL;
did=true;
}
else if (m_selp && valuep->castInitArray()) {
int bit = m_selp->bitConst();
AstNode* itemp = valuep->castInitArray()->initsp();
for (int n=0; n<bit && itemp; ++n, itemp=itemp->nextp()) {}
if (itemp->castConst()) {
const V3Number& num = itemp->castConst()->num();
//UINFO(2,"constVisit "<<(void*)valuep<<" "<<num<<endl);
replaceNum(nodep, num); nodep=NULL;
did=true;
}
}
}
}
if (!did && m_required) {
@@ -1193,16 +1370,6 @@ private:
// Not constant propagated (for today) because AstMath::isOpaque is set
// Someday if lower is constant, convert to quoted "string".
virtual void visit(AstAttrOf* nodep, AstNUser*) {
// Don't iterate children, don't want to lose VarRef.
if (nodep->attrType()==AstAttrType::EXPR_BITS) {
if (!nodep->fromp() || !nodep->fromp()->widthMin()) nodep->v3fatalSrc("Unsized expression");
V3Number num (nodep->fileline(), 32, nodep->fromp()->widthMin());
replaceNum(nodep, num); nodep=NULL;
} else {
nodep->v3fatalSrc("Missing ATTR type case");
}
}
bool onlySenItemInSenTree(AstNodeSenItem* nodep) {
// Only one if it's not in a list
return (!nodep->nextp() && nodep->backp()->nextp() != nodep);
@@ -1211,6 +1378,7 @@ private:
nodep->iterateChildren(*this);
if (m_doNConst
&& (nodep->sensp()->castConst()
|| nodep->sensp()->castEnumItemRef()
|| (nodep->varrefp() && nodep->varrefp()->varp()->isParam()))) {
// Constants in sensitivity lists may be removed (we'll simplify later)
if (nodep->isClocked()) { // A constant can never get a pos/negexge
@@ -1239,6 +1407,9 @@ private:
if (!senvarp) sensp->v3fatalSrc("Non-varref sensitivity variable");
sensp->replaceWith(senvarp);
sensp->deleteTree(); sensp=NULL;
} else if (!m_doNConst // Deal with later when doNConst missing
&& (nodep->sensp()->castEnumItemRef()
|| nodep->sensp()->castConst())) {
} else {
if (nodep->hasVar() && !nodep->varrefp()) nodep->v3fatalSrc("Null sensitivity variable");
}
@@ -1338,6 +1509,7 @@ private:
for (AstNodeSenItem* nextp, * senp = nodep->sensesp()->castNodeSenItem();
senp; senp=nextp) {
nextp=senp->nextp()->castNodeSenItem();
// cppcheck-suppress unassignedVariable // cppcheck bug
SenItemCmp cmp;
if (nextp && !cmp(senp, nextp)) {
// Something's out of order, sort it
@@ -1346,7 +1518,7 @@ private:
for (AstNodeSenItem* senp = nodep->sensesp()->castNodeSenItem(); senp; senp=senp->nextp()->castNodeSenItem()) {
vec.push_back(senp);
}
sort(vec.begin(), vec.end(), SenItemCmp());
stable_sort(vec.begin(), vec.end(), SenItemCmp());
for (vector<AstNodeSenItem*>::iterator it=vec.begin(); it!=vec.end(); ++it) {
(*it)->unlinkFrBack();
}
@@ -1356,7 +1528,7 @@ private:
break;
}
}
// Pass2, remove dup edges
for (AstNodeSenItem* nextp, * senp = nodep->sensesp()->castNodeSenItem();
senp; senp=nextp) {
@@ -1399,6 +1571,9 @@ private:
virtual void visit(AstAssignAlias* nodep, AstNUser*) {
// Don't perform any optimizations, keep the alias around
}
virtual void visit(AstAssignVarScope* nodep, AstNUser*) {
// Don't perform any optimizations, the node won't be linked yet
}
virtual void visit(AstAssignW* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (m_doNConst && replaceNodeAssign(nodep)) return;
@@ -1573,7 +1748,10 @@ private:
replaceWithSimulation(nodep);
}
}
virtual void visit(AstArg* nodep, AstNUser*) {
// replaceWithSimulation on the Arg's parent FuncRef replaces these
nodep->iterateChildren(*this);
}
virtual void visit(AstWhile* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (m_doNConst) {
@@ -1588,6 +1766,10 @@ private:
}
}
}
virtual void visit(AstInitArray* nodep, AstNUser*) {
// Constant if all children are constant
nodep->iterateChildren(*this);
}
// These are converted by V3Param. Don't constify as we don't want the from() VARREF to disappear, if any
// If output of a presel didn't get consted, chances are V3Param didn't visit properly
@@ -1601,6 +1783,12 @@ private:
}
}
// Simplify
virtual void visit(AstBasicDType* nodep, AstNUser*) {
nodep->iterateChildren(*this);
nodep->cvtRangeConst();
}
//-----
// Jump elimination
@@ -1627,6 +1815,12 @@ private:
//-----
// Below lines are magic expressions processed by astgen
// TREE_SKIP_VISIT("AstNODETYPE") # Rename normal visit to visitGen and don't iterate
//-----
TREE_SKIP_VISIT("ArraySel");
//-----
// "AstNODETYPE { # bracket not paren
// $accessor_name, ...
// # ,, gets replaced with a , rather than &&
@@ -1648,34 +1842,46 @@ private:
// v--- *1* These ops are always first, as we warn before replacing
// v--- *V* This op is a verilog op, only in m_doV mode
// v--- *C* This op works on all constant children, allowed in m_doConst mode
// v--- *S* This op specifies a type should use short-circuting of its lhs op
TREEOP1("AstSel{warnSelect(nodep)}", "NEVER");
// Generic constants on both side. Do this first to avoid other replacements
TREEOPC("AstNodeBiop {$lhsp.castConst, $rhsp.castConst}", "replaceConst(nodep)");
TREEOPC("AstNodeUniop{$lhsp.castConst, !nodep->isOpaque()}", "replaceConst(nodep)");
// Zero on one side or the other
TREEOP ("AstAdd {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstAnd {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstAnd {$lhsp.isZero, $rhsp, isTPure($rhsp)}", "replaceZero(nodep)"); // Can't use replaceZeroChkPure as we make this pattern in ChkPure
// This visit function here must allow for short-circuiting.
TREEOPS("AstLogAnd {$lhsp.isZero}", "replaceZero(nodep)");
TREEOP ("AstLogAnd{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
// This visit function here must allow for short-circuiting.
TREEOPS("AstLogOr {$lhsp.isOne}", "replaceNum(nodep, 1)");
TREEOP ("AstLogOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstDiv {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstDivS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstMul {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstMulS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstPow {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstPowS {$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstDiv {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
TREEOP ("AstDivS {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
TREEOP ("AstMul {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
TREEOP ("AstMulS {$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
TREEOP ("AstPow {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule
TREEOP ("AstPowSS {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule
TREEOP ("AstPowSU {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule
TREEOP ("AstPowUS {$rhsp.isZero}", "replaceNum(nodep, 1)"); // Overrides lhs zero rule
TREEOP ("AstPow {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)");
TREEOP ("AstPowSU {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)");
TREEOP ("AstPowUS {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)");
TREEOP ("AstPowSU {$lhsp.isZero, !$rhsp.isZero}", "replaceZeroChkPure(nodep,$rhsp)");
TREEOP ("AstOr {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstShiftL{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstShiftR{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstShiftRS{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP ("AstShiftL{$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
TREEOP ("AstShiftR{$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
TREEOP ("AstShiftRS{$lhsp.isZero, $rhsp}", "replaceZeroChkPure(nodep,$rhsp)");
TREEOP ("AstXor {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstXnor {$lhsp.isZero, $rhsp}", "AstNot{$rhsp}");
TREEOP ("AstSub {$lhsp.isZero, $rhsp}", "AstNegate{$rhsp}");
TREEOP ("AstAdd {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP ("AstAnd {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
TREEOP ("AstLogAnd{$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
TREEOP ("AstAnd {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)");
TREEOP ("AstLogAnd{$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)");
TREEOP ("AstLogOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP ("AstMul {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
TREEOP ("AstMulS {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
TREEOP ("AstMul {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)");
TREEOP ("AstMulS {$lhsp, $rhsp.isZero}", "replaceZeroChkPure(nodep,$lhsp)");
TREEOP ("AstOr {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP ("AstShiftL{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP ("AstShiftR{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
@@ -1686,12 +1892,12 @@ private:
// Non-zero on one side or the other
TREEOP ("AstAnd {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstLogAnd{$lhsp.isNeqZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstOr {$lhsp.isAllOnes, $rhsp}", "replaceWLhs(nodep)"); //->allOnes
TREEOP ("AstOr {$lhsp.isAllOnes, $rhsp, isTPure($rhsp)}", "replaceWLhs(nodep)"); //->allOnes
TREEOP ("AstLogOr {$lhsp.isNeqZero, $rhsp}", "replaceNum(nodep,1)");
TREEOP ("AstAnd {$lhsp, $rhsp.isAllOnes}", "replaceWLhs(nodep)");
TREEOP ("AstLogAnd{$lhsp, $rhsp.isNeqZero}", "replaceWLhs(nodep)");
TREEOP ("AstOr {$lhsp, $rhsp.isAllOnes}", "replaceWRhs(nodep)"); //->allOnes
TREEOP ("AstLogOr {$lhsp, $rhsp.isNeqZero}", "replaceNum(nodep,1)");
TREEOP ("AstOr {$lhsp, $rhsp.isAllOnes, isTPure($lhsp)}", "replaceWRhs(nodep)"); //->allOnes
TREEOP ("AstLogOr {$lhsp, $rhsp.isNeqZero, isTPure($lhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstXor {$lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}");
TREEOP ("AstXnor {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
TREEOP ("AstMul {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)");
@@ -1701,7 +1907,6 @@ private:
TREEOP ("AstMul {operandIsPowTwo($lhsp), $rhsp}", "replaceMulShift(nodep)"); // a*2^n -> a<<n
TREEOP ("AstDiv {$lhsp, operandIsPowTwo($rhsp)}", "replaceDivShift(nodep)"); // a/2^n -> a>>n
TREEOP ("AstPow {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<<a
TREEOP ("AstPowS {operandIsTwo($lhsp), $rhsp}", "replacePowShift(nodep)"); // 2**a == 1<<a
// Trinary ops
// Note V3Case::Sel requires Cond to always be conditionally executed in C to prevent core dump!
TREEOP ("AstNodeCond{$condp.isZero, $expr1p, $expr2p}", "replaceWChild(nodep,$expr2p)");
@@ -1709,11 +1914,14 @@ private:
TREEOPC("AstNodeCond{$condp.isZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr2p)");
TREEOPC("AstNodeCond{$condp.isNeqZero, $expr1p.castConst, $expr2p.castConst}", "replaceWChild(nodep,$expr1p)");
TREEOP ("AstNodeCond{$condp, operandsSame($expr1p,,$expr2p)}","replaceWChild(nodep,$expr1p)");
// This visit function here must allow for short-circuiting.
TREEOPS("AstCond {$lhsp.isZero}", "replaceWIteratedThs(nodep)");
TREEOPS("AstCond {$lhsp.isNeqZero}", "replaceWIteratedRhs(nodep)");
TREEOP ("AstCond{$condp->castNot(), $expr1p, $expr2p}", "AstCond{$condp->op1p(), $expr2p, $expr1p}");
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isAllOnes, $expr2p}", "AstOr {$condp, $expr2p}"); // a?1:b == a|b
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isZero}", "AstAnd{$condp, $expr1p}"); // a?b:0 == a&b
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isAllOnes}", "AstOr {AstNot{$condp}, $expr1p}"); // a?b:1 == ~a|b
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isZero, $expr2p}", "AstAnd{AstNot{$condp}, $expr2p}"); // a?0:b == ~a&b
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isAllOnes, $expr2p}", "AstLogOr {$condp, $expr2p}"); // a?1:b == a||b
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isZero}", "AstLogAnd{$condp, $expr1p}"); // a?b:0 == a&&b
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p, $expr2p.isAllOnes}", "AstLogOr {AstNot{$condp}, $expr1p}"); // a?b:1 == ~a||b
TREEOP ("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isZero, $expr2p}", "AstLogAnd{AstNot{$condp}, $expr2p}"); // a?0:b == ~a&&b
TREEOP ("AstNodeCond{!$condp.width1, operandBoolShift(nodep->condp())}", "replaceBoolShift(nodep->condp())");
// Prefer constants on left, since that often needs a shift, it lets constant red remove the shift
TREEOP ("AstNodeBiCom{!$lhsp.castConst, $rhsp.castConst}", "swapSides(nodep)");
@@ -1721,6 +1929,14 @@ private:
TREEOP ("AstNodeBiComAsv{operandAsvSame(nodep)}", "replaceAsv(nodep)");
TREEOP ("AstNodeBiComAsv{operandAsvLUp(nodep)}", "replaceAsvLUp(nodep)");
TREEOP ("AstNodeBiComAsv{operandAsvRUp(nodep)}", "replaceAsvRUp(nodep)");
TREEOP ("AstLt {!$lhsp.castConst,$rhsp.castConst}", "AstGt {$rhsp,$lhsp}");
TREEOP ("AstLtS {!$lhsp.castConst,$rhsp.castConst}", "AstGtS {$rhsp,$lhsp}");
TREEOP ("AstLte {!$lhsp.castConst,$rhsp.castConst}", "AstGte {$rhsp,$lhsp}");
TREEOP ("AstLteS {!$lhsp.castConst,$rhsp.castConst}", "AstGteS{$rhsp,$lhsp}");
TREEOP ("AstGt {!$lhsp.castConst,$rhsp.castConst}", "AstLt {$rhsp,$lhsp}");
TREEOP ("AstGtS {!$lhsp.castConst,$rhsp.castConst}", "AstLtS {$rhsp,$lhsp}");
TREEOP ("AstGte {!$lhsp.castConst,$rhsp.castConst}", "AstLte {$rhsp,$lhsp}");
TREEOP ("AstGteS {!$lhsp.castConst,$rhsp.castConst}", "AstLteS{$rhsp,$lhsp}");
// v--- *1* as These ops are always first, as we warn before replacing
TREEOP1("AstLt {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,0)");
TREEOP1("AstGte {$lhsp, $rhsp.isZero}", "replaceNumSigned(nodep,1)");
@@ -1732,7 +1948,7 @@ private:
TREEOP1("AstGte {$lhsp.isAllOnes, $rhsp, $lhsp->width()==$rhsp->width()}", "replaceNumLimited(nodep,1)");
// Two level bubble pushing
TREEOP ("AstNot {$lhsp.castNot, $lhsp->width()==$lhsp->castNot()->lhsp()->width()}", "replaceWChild(nodep, $lhsp->op1p())"); // NOT(NOT(x))->x
TREEOP ("AstLogNot{$lhsp.castLogNot}", "replaceWChild(nodep, $lhsp->op1p())"); // NOT(NOT(x))->x
TREEOP ("AstLogNot{$lhsp.castLogNot}", "replaceWChild(nodep, $lhsp->op1p())"); // LOGNOT(LOGNOT(x))->x
TREEOPV("AstNot {$lhsp.castEqCase, $lhsp.width1}","AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase {$lhsp->op1p(),$lhsp->op2p()}");
@@ -1770,12 +1986,12 @@ private:
TREEOP ("AstShiftR{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
TREEOP ("AstWordSel{operandWordOOB(nodep)}", "replaceZero(nodep)");
// Compress out EXTENDs to appease loop unroller
TREEOPV("AstEq {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstNeq {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstGt {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstGte {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstLt {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstLte {$lhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstEq {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstNeq {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstGt {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstGte {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstLt {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
TREEOPV("AstLte {$rhsp.castExtend,operandBiExtendConst(nodep)}", "DONE");
// Identical operands on both sides
// AstLogAnd/AstLogOr already converted to AstAnd/AstOr for these rules
// AstAdd->ShiftL(#,1) but uncommon
@@ -1838,9 +2054,9 @@ private:
TREEOPV("AstOneHot{$lhsp.width1}", "replaceWLhs(nodep)");
TREEOPV("AstOneHot0{$lhsp.width1}", "replaceNum(nodep,1)");
// Binary AND/OR is faster than logical and/or (usually)
TREEOPV("AstLogAnd{$lhsp.width1, $rhsp.width1}", "AstAnd{$lhsp,$rhsp}");
TREEOPV("AstLogOr {$lhsp.width1, $rhsp.width1}", "AstOr{$lhsp,$rhsp}");
TREEOPV("AstLogNot{$lhsp.width1}", "AstNot{$lhsp}");
TREEOPV("AstLogAnd{$lhsp.width1, $rhsp.width1, isTPure($lhsp), isTPure($rhsp)}", "AstAnd{$lhsp,$rhsp}");
TREEOPV("AstLogOr {$lhsp.width1, $rhsp.width1, isTPure($lhsp), isTPure($rhsp)}", "AstOr{$lhsp,$rhsp}");
TREEOPV("AstLogNot{$lhsp.width1, isTPure($lhsp)}", "AstNot{$lhsp}");
// CONCAT(CONCAT({a},{b}),{c}) -> CONCAT({a},CONCAT({b},{c}))
// CONCAT({const},CONCAT({const},{c})) -> CONCAT((constifiedCONC{const|const},{c}))
TREEOPV("AstConcat{operandConcatMove(nodep)}", "moveConcat(nodep)");
@@ -1882,6 +2098,8 @@ private:
TREEOPV("AstSel{$fromp.castXnor,$lhsp.castConst}", "replaceSelIntoUniop(nodep)");
// Conversions
TREEOPV("AstRedXnor{$lhsp}", "AstNot{AstRedXor{$lhsp}}"); // Just eliminate XNOR's
// This visit function here must allow for short-circuiting.
TREEOPS("AstLogIf {$lhsp.isZero}", "replaceNum(nodep, 1)");
TREEOPV("AstLogIf {$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}");
TREEOPV("AstLogIff{$lhsp, $rhsp}", "AstLogNot{AstXor{$lhsp,$rhsp}}");
// Strings
@@ -1915,27 +2133,33 @@ public:
// Processing Mode Enum
enum ProcMode {
PROC_PARAMS,
PROC_GENERATE,
PROC_LIVE,
PROC_V_WARN,
PROC_V_NOWARN,
PROC_V_EXPENSIVE,
PROC_CPP
};
// CONSTUCTORS
ConstVisitor(ProcMode pmode) {
m_params = false;
m_required = false;
m_doExpensive = false;
m_doNConst = false;
m_doShort = true; // Presently always done
m_doV = false;
m_doGenerate = false; // Inside generate conditionals
m_warn = false;
m_wremove = true; // Overridden in visitors
m_modp = NULL;
m_selp = NULL;
m_scopep = NULL;
m_attrp = NULL;
//
switch (pmode) {
case PROC_PARAMS: m_doV = true; m_doNConst = true; m_params = true; m_required = true; break;
case PROC_GENERATE: m_doV = true; m_doNConst = true; m_params = true; m_required = true; m_doGenerate = true; break;
case PROC_LIVE: break;
case PROC_V_WARN: m_doV = true; m_doNConst = true; m_warn = true; break;
case PROC_V_NOWARN: m_doV = true; m_doNConst = true; break;
@@ -1954,12 +2178,46 @@ public:
//######################################################################
// Const class functions
//! Force this cell node's parameter list to become a constant
//! @return Pointer to the edited node.
AstNode* V3Const::constifyParamsEdit(AstNode* nodep) {
//if (debug()>0) nodep->dumpTree(cout," forceConPRE : ");
// Resize even if the node already has a width, because burried in the treee we may
// have a node we just created with signing, etc, that isn't sized yet.
nodep = V3Width::widthParamsEdit(nodep); // Make sure we've sized everything first
ConstVisitor visitor (ConstVisitor::PROC_PARAMS);
// Resize even if the node already has a width, because buried in the tree
// we may have a node we just created with signing, etc, that isn't sized yet.
// Make sure we've sized everything first
nodep = V3Width::widthParamsEdit(nodep);
ConstVisitor visitor(ConstVisitor::PROC_PARAMS);
if (AstVar* varp=nodep->castVar()) {
// If a var wants to be constified, it's really a param, and
// we want the value to be constant. We aren't passed just the
// init value because we need widthing above to handle the var's type.
if (varp->valuep()) visitor.mainAcceptEdit(varp->valuep());
} else {
nodep = visitor.mainAcceptEdit(nodep);
}
// Because we do edits, nodep links may get trashed and core dump this.
//if (debug()>0) nodep->dumpTree(cout," forceConDONE: ");
return nodep;
}
//! Force this cell node's parameter list to become a constant inside generate.
//! If we are inside a generated "if", "case" or "for", we don't want to
//! trigger warnings when we deal with the width. It is possible that these
//! are spurious, existing within sub-expressions that will not actually be
//! generated. Since such occurrences, must be constant, in order to be
//! someting a generate block can depend on, we can wait until later to do the
//! width check.
//! @return Pointer to the edited node.
AstNode* V3Const::constifyGenerateParamsEdit(AstNode* nodep) {
//if (debug()>0) nodep->dumpTree(cout," forceConPRE : ");
// Resize even if the node already has a width, because buried in the tree
// we may have a node we just created with signing, etc, that isn't sized
// yet.
// Make sure we've sized everything first
nodep = V3Width::widthGenerateParamsEdit(nodep);
ConstVisitor visitor(ConstVisitor::PROC_GENERATE);
if (AstVar* varp=nodep->castVar()) {
// If a var wants to be constified, it's really a param, and
// we want the value to be constant. We aren't passed just the
+3 -6
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Propagate constants across AST
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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,9 +29,8 @@
class V3Const {
public:
// Force this cell node's parameter list to become a constant
// Return new node that may have replaced nodep
static AstNode* constifyParamsEdit(AstNode* nodep);
static AstNode* constifyGenerateParamsEdit(AstNode* nodep);
// Only do constant pushing, without removing dead logic
static void constifyAllLive(AstNetlist* nodep);
// Everything that's possible
+76 -20
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Netlist (top level) functions
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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,10 +60,16 @@ private:
}
};
// NODE STATE
// Entire netlist:
// AstIf::user1() -> bool. True indicates ifelse processed
AstUser1InUse m_inuser1;
// STATE
bool m_checkBlock; // Should this block get covered?
AstNodeModule* m_modp; // Current module to add statement to
bool m_checkBlock; // Should this block get covered?
AstNodeModule* m_modp; // Current module to add statement to
bool m_inToggleOff; // In function/task etc
bool m_inModOff; // In module with no coverage
FileMap m_fileps; // Column counts for each fileline
string m_beginHier; // AstBegin hier name for user coverage points
@@ -87,7 +92,7 @@ private:
if (prettyName.find("._") != string::npos)
return "Inlined leading underscore";
}
if ((nodep->width()*nodep->arrayElements()) > 256) return "Wide bus/array > 256 bits";
if ((nodep->width()*nodep->dtypep()->arrayUnpackedElements()) > 256) return "Wide bus/array > 256 bits";
// We allow this, though tracing doesn't
// if (nodep->arrayp(1)) return "Unsupported: Multi-dimensional array";
return NULL;
@@ -125,9 +130,11 @@ private:
// VISITORS - BOTH
virtual void visit(AstNodeModule* nodep, AstNUser*) {
m_modp = nodep;
m_inModOff = nodep->isTop(); // Ignore coverage on top module; it's a shell we created
m_fileps.clear();
nodep->iterateChildren(*this);
m_modp = NULL;
m_inModOff = true;
}
// VISITORS - TOGGLE COVERAGE
@@ -141,7 +148,7 @@ private:
}
virtual void visit(AstVar* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (m_modp && !m_inToggleOff
if (m_modp && !m_inModOff && !m_inToggleOff
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageToggle()) {
const char* disablep = varIgnoreToggle(nodep);
if (disablep) {
@@ -193,7 +200,7 @@ private:
const ToggleEnt& above,
AstVar* varp, AstVar* chgVarp) { // Constant
if (AstBasicDType* bdtypep = dtypep->castBasicDType()) {
if (bdtypep->rangep()) {
if (bdtypep->isRanged()) {
for (int index_docs=bdtypep->lsb(); index_docs<bdtypep->msb()+1; index_docs++) {
int index_code = index_docs - bdtypep->lsb();
ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]",
@@ -210,13 +217,57 @@ private:
varp, chgVarp);
}
}
else if (AstArrayDType* adtypep = dtypep->castArrayDType()) {
for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb()+1; ++index_docs) {
else if (AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType()) {
for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb(); ++index_docs) {
int index_code = index_docs - adtypep->lsb();
ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]",
new AstArraySel(varp->fileline(), above.m_varRefp->cloneTree(true), index_code),
new AstArraySel(varp->fileline(), above.m_chgRefp->cloneTree(true), index_code));
toggleVarRecurse(adtypep->dtypeSkipRefp(), depth+1,
toggleVarRecurse(adtypep->subDTypep()->skipRefp(), depth+1,
newent,
varp, chgVarp);
newent.cleanup();
}
}
else if (AstPackArrayDType* adtypep = dtypep->castPackArrayDType()) {
for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb(); ++index_docs) {
AstNodeDType* subtypep = adtypep->subDTypep()->skipRefp();
int index_code = index_docs - adtypep->lsb();
ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]",
new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true),
index_code*subtypep->width(), subtypep->width()),
new AstSel(varp->fileline(), above.m_chgRefp->cloneTree(true),
index_code*subtypep->width(), subtypep->width()));
toggleVarRecurse(adtypep->subDTypep()->skipRefp(), depth+1,
newent,
varp, chgVarp);
newent.cleanup();
}
}
else if (AstStructDType* adtypep = dtypep->castStructDType()) {
// For now it's packed, so similar to array
for (AstMemberDType* itemp = adtypep->membersp(); itemp; itemp=itemp->nextp()->castMemberDType()) {
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
int index_code = itemp->lsb();
ToggleEnt newent (above.m_comment+string(".")+itemp->name(),
new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true),
index_code, subtypep->width()),
new AstSel(varp->fileline(), above.m_chgRefp->cloneTree(true),
index_code, subtypep->width()));
toggleVarRecurse(subtypep, depth+1,
newent,
varp, chgVarp);
newent.cleanup();
}
}
else if (AstUnionDType* adtypep = dtypep->castUnionDType()) {
// Arbitrarially handle only the first member of the union
if (AstMemberDType* itemp = adtypep->membersp()) {
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
ToggleEnt newent (above.m_comment+string(".")+itemp->name(),
above.m_varRefp->cloneTree(true),
above.m_chgRefp->cloneTree(true));
toggleVarRecurse(subtypep, depth+1,
newent,
varp, chgVarp);
newent.cleanup();
@@ -231,12 +282,18 @@ private:
virtual void visit(AstIf* nodep, AstNUser*) { // Note not AstNodeIf; other types don't get covered
UINFO(4," IF: "<<nodep<<endl);
if (m_checkBlock) {
// An else-if. When we iterate the if, use "elsif" marking
bool elsif = (nodep->elsesp()->castIf()
&& !nodep->elsesp()->castIf()->nextp());
if (elsif) nodep->elsesp()->castIf()->user1(true);
//
nodep->ifsp()->iterateAndNext(*this);
if (m_checkBlock
if (m_checkBlock && !m_inModOff
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) { // if a "if" branch didn't disable it
if (!nodep->backp()->castIf()
|| nodep->backp()->castIf()->elsesp()!=nodep) { // Ignore if else; did earlier
UINFO(4," COVER: "<<nodep<<endl);
UINFO(4," COVER: "<<nodep<<endl);
if (nodep->user1()) {
nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "elsif"));
} else {
nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "if"));
}
}
@@ -244,12 +301,10 @@ private:
if (nodep->elsesp()) {
m_checkBlock = true;
nodep->elsesp()->iterateAndNext(*this);
if (m_checkBlock
if (m_checkBlock && !m_inModOff
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) { // if a "else" branch didn't disable it
UINFO(4," COVER: "<<nodep<<endl);
if (nodep->elsesp()->castIf()) {
nodep->addElsesp(newCoverInc(nodep->elsesp()->fileline(), "", "v_line", "elsif"));
} else {
if (!elsif) { // elsif done inside if()
nodep->addElsesp(newCoverInc(nodep->elsesp()->fileline(), "", "v_line", "else"));
}
}
@@ -259,7 +314,7 @@ private:
}
virtual void visit(AstCaseItem* nodep, AstNUser*) {
UINFO(4," CASEI: "<<nodep<<endl);
if (m_checkBlock
if (m_checkBlock && !m_inModOff
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) {
nodep->bodysp()->iterateAndNext(*this);
if (m_checkBlock) { // if the case body didn't disable it
@@ -328,6 +383,7 @@ public:
m_checkBlock = true;
m_beginHier = "";
m_inToggleOff = false;
m_inModOff = true;
rootp->iterateChildren(*this);
}
virtual ~CoverageVisitor() {}
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Coverage modules/signals together
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+2 -3
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Netlist (top level) functions
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Coverage modules/signals together
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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 -18
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Dead code elimination
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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.
@@ -22,6 +21,8 @@
// Remove any unreferenced modules
// Remove any unreferenced variables
//
// TODO: A graph would make the process of circular and interlinked
// dependencies easier to resolve.
// NOTE: If redo this, consider using maybePointedTo()/broken() ish scheme
// instead of needing as many visitors.
//*************************************************************************
@@ -70,19 +71,21 @@ class DeadVisitor : public AstNVisitor {
private:
// NODE STATE
// Entire Netlist:
// AstNodeModule::user() -> int. Count of number of cells referencing this module.
// AstVar::user() -> int. Count of number of references
// AstVarScope::user() -> int. Count of number of references
// AstNodeModule::user1() -> int. Count of number of cells referencing this module.
// AstVar::user1() -> int. Count of number of references
// AstVarScope::user1() -> int. Count of number of references
// AstNodeDType::user1() -> int. Count of number of references
AstUser1InUse m_inuser1;
// TYPES
typedef multimap<AstVarScope*,AstNodeAssign*> AssignMap;
// STATE
vector<AstVar*> m_varsp; // List of all encountered to avoid another loop through tree
vector<AstNode*> m_varEtcsp; // List of all encountered to avoid another loop through tree
vector<AstVarScope*> m_vscsp; // List of all encountered to avoid another loop through tree
AssignMap m_assignMap; // List of all simple assignments for each variable
bool m_elimUserVars; // Allow removal of user's vars
bool m_elimDTypes; // Allow removal of DTypes
bool m_sideEffect; // Side effects discovered in assign RHS
// METHODS
@@ -92,13 +95,31 @@ private:
return level;
}
void checkAll(AstNode* nodep) {
if (nodep != nodep->dtypep()) { // NodeDTypes reference themselves
if (AstNode* subnodep = nodep->dtypep()) subnodep->user1Inc();
}
if (AstNode* subnodep = nodep->getChildDTypep()) subnodep->user1Inc();
}
void checkDType(AstNodeDType* nodep) {
if (!nodep->generic() // Don't remove generic types
&& m_elimDTypes // dtypes stick around until post-widthing
&& !nodep->castMemberDType() // Keep member names iff upper type exists
) {
m_varEtcsp.push_back(nodep);
}
if (AstNode* subnodep = nodep->virtRefDTypep()) subnodep->user1Inc();
}
// VISITORS
virtual void visit(AstCell* nodep, AstNUser*) {
nodep->iterateChildren(*this);
checkAll(nodep);
nodep->modp()->user1Inc();
}
virtual void visit(AstNodeVarRef* nodep, AstNUser*) {
nodep->iterateChildren(*this);
checkAll(nodep);
if (nodep->varScopep()) {
nodep->varScopep()->user1Inc();
nodep->varScopep()->varp()->user1Inc();
@@ -112,29 +133,44 @@ private:
}
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
nodep->iterateChildren(*this);
checkAll(nodep);
if (nodep->packagep()) {
nodep->packagep()->user1Inc();
}
}
virtual void visit(AstRefDType* nodep, AstNUser*) {
nodep->iterateChildren(*this);
checkDType(nodep);
checkAll(nodep);
if (nodep->packagep()) {
nodep->packagep()->user1Inc();
}
}
virtual void visit(AstNodeDType* nodep, AstNUser*) {
nodep->iterateChildren(*this);
checkDType(nodep);
checkAll(nodep);
}
virtual void visit(AstEnumItemRef* nodep, AstNUser*) {
nodep->iterateChildren(*this);
checkAll(nodep);
if (nodep->packagep()) {
nodep->packagep()->user1Inc();
}
}
virtual void visit(AstVarScope* nodep, AstNUser*) {
nodep->iterateChildren(*this);
m_vscsp.push_back(nodep);
checkAll(nodep);
if (mightElim(nodep->varp())) {
m_vscsp.push_back(nodep);
}
}
virtual void visit(AstVar* nodep, AstNUser*) {
nodep->iterateChildren(*this);
m_varsp.push_back(nodep);
checkAll(nodep);
if (mightElim(nodep)) {
m_varEtcsp.push_back(nodep);
}
}
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
@@ -142,20 +178,24 @@ private:
// Similar code in V3Life
m_sideEffect = false;
nodep->rhsp()->iterateAndNext(*this);
checkAll(nodep);
// Has to be direct assignment without any EXTRACTing.
AstVarRef* varrefp = nodep->lhsp()->castVarRef();
if (varrefp && !m_sideEffect
&& varrefp->varScopep()) { // For simplicity, we only remove post-scoping
m_assignMap.insert(make_pair(varrefp->varScopep(), nodep));
checkAll(varrefp); // Must track reference to dtype()
} else { // Track like any other statement
nodep->lhsp()->iterateAndNext(*this);
}
checkAll(nodep);
}
//-----
virtual void visit(AstNode* nodep, AstNUser*) {
if (nodep->isOutputter()) m_sideEffect=true;
nodep->iterateChildren(*this);
checkAll(nodep);
}
// METHODS
@@ -168,7 +208,7 @@ private:
AstNodeModule* nextmodp;
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=nextmodp) {
nextmodp = modp->nextp()->castNodeModule();
if (modp->level()>2 && modp->user1()==0) {
if (modp->level()>2 && modp->user1()==0 && !modp->internal()) {
// > 2 because L1 is the wrapper, L2 is the top user module
UINFO(4," Dead module "<<modp<<endl);
// And its children may now be killable too; correct counts
@@ -180,16 +220,18 @@ private:
}
}
}
bool canElim(AstVar* nodep) {
bool mightElim(AstVar* nodep) {
return (!nodep->isSigPublic() // Can't elim publics!
&& !nodep->isIO()
&& (nodep->isTemp() || nodep->isParam() || m_elimUserVars));
&& (nodep->isTemp()
|| (nodep->isParam() && !nodep->isTrace())
|| m_elimUserVars)); // Post-Trace can kill most anything
}
void deadCheckVar() {
// Delete any unused varscopes
for (vector<AstVarScope*>::iterator it = m_vscsp.begin(); it!=m_vscsp.end(); ++it) {
AstVarScope* vscp = *it;
if (vscp->user1() == 0 && canElim(vscp->varp())) {
if (vscp->user1() == 0) {
UINFO(4," Dead "<<vscp<<endl);
pair <AssignMap::iterator,AssignMap::iterator> eqrange = m_assignMap.equal_range(vscp);
for (AssignMap::iterator it = eqrange.first; it != eqrange.second; ++it) {
@@ -200,8 +242,8 @@ private:
vscp->unlinkFrBack()->deleteTree(); vscp=NULL;
}
}
for (vector<AstVar*>::iterator it = m_varsp.begin(); it!=m_varsp.end(); ++it) {
if ((*it)->user1() == 0 && canElim((*it))) {
for (vector<AstNode*>::iterator it = m_varEtcsp.begin(); it!=m_varEtcsp.end(); ++it) {
if ((*it)->user1() == 0) {
UINFO(4," Dead "<<(*it)<<endl);
(*it)->unlinkFrBack()->deleteTree(); (*it)=NULL;
}
@@ -210,14 +252,19 @@ private:
public:
// CONSTRUCTORS
DeadVisitor(AstNetlist* nodep, bool elimUserVars) {
DeadVisitor(AstNetlist* nodep, bool elimUserVars, bool elimDTypes) {
m_elimUserVars = elimUserVars;
m_elimDTypes = elimDTypes;
m_sideEffect = false;
// Prepare to remove some datatypes
nodep->typeTablep()->clearCache();
// Operate on whole netlist
nodep->accept(*this);
deadCheckVar();
// Modules after vars, because might be vars we delete inside a mod we delete
deadCheckMod();
// We may have removed some datatypes, cleanup
nodep->typeTablep()->repairCache();
}
virtual ~DeadVisitor() {}
};
@@ -225,7 +272,15 @@ public:
//######################################################################
// Dead class functions
void V3Dead::deadifyAll(AstNetlist* nodep, bool elimUserVars) {
void V3Dead::deadifyModules(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, elimUserVars);
DeadVisitor visitor (nodep, false, false);
}
void V3Dead::deadifyDTypes(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, false, true);
}
void V3Dead::deadifyAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, true, true);
}
+7 -5
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Dead branch elimination
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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,8 +29,12 @@
class V3Dead {
public:
// Modules, no vars/dtypes
static void deadifyModules(AstNetlist* nodep);
// Modules, Data types
static void deadifyDTypes(AstNetlist* nodep);
// Everything that's possible
static void deadifyAll(AstNetlist* nodep, bool elimUserVars);
static void deadifyAll(AstNetlist* nodep);
};
#endif // Guard
+72 -54
View File
@@ -1,13 +1,12 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Add temporaries, such as for delayed nodes
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
@@ -74,14 +73,15 @@ private:
// NODE STATE
// Cleared each module:
// AstVarScope::user1p() -> AstVarScope*. Points to temp var created.
// AstVarScope::user2p() -> AstActive*. Points to activity block of signal
// AstVarScope::user2p() -> AstActive*. Points to activity block of signal (valid when AstVarScope::user1p is valid)
// AstVarScope::user4p() -> AstAlwaysPost*. Post block for this variable
// AstVarScope::user5() -> VarUsage. Tracks delayed vs non-delayed usage
// AstVar::user2() -> bool. Set true if already made warning
// AstVar::user4() -> int. Vector number, for assignment creation
// AstVarRef::user2() -> bool. Set true if already processed
// AstAlwaysPost::user2() -> ActActive*. Points to activity block of signal (valid when AstAlwaysPost::user4p is valid)
// AstAlwaysPost::user4() -> AstIf*. Last IF (__Vdlyvset__) created under this AlwaysPost
// Cleared each scope:
// Cleared each scope/active:
// AstAssignDly::user3() -> AstVarScope*. __Vdlyvset__ created for this assign
// AstAlwaysPost::user3() -> AstVarScope*. __Vdlyvset__ last referenced in IF
AstUser1InUse m_inuser1;
@@ -118,22 +118,24 @@ private:
nodep->v3warn(BLKANDNBLK,"Unsupported: Blocked and non-blocking assignments to same variable: "<<nodep->varp()->prettyName());
}
}
AstVarScope* createVarSc(AstVarScope* oldvarscp, string name, int width/*0==fromoldvar*/) {
AstVarScope* createVarSc(AstVarScope* oldvarscp, string name, int width/*0==fromoldvar*/, AstNodeDType* newdtypep) {
// Because we've already scoped it, we may need to add both the AstVar and the AstVarScope
if (!oldvarscp->scopep()) oldvarscp->v3fatalSrc("Var unscoped");
AstVar* varp;
AstNodeModule* addmodp = oldvarscp->scopep()->modp();
// We need a new AstVar, but only one for all scopes, to match the new AstVarScope
VarMap::iterator iter = m_modVarMap.find(make_pair(addmodp,name));
if (iter != m_modVarMap.end()) {
VarMap::iterator it = m_modVarMap.find(make_pair(addmodp,name));
if (it != m_modVarMap.end()) {
// Created module's AstVar earlier under some other scope
varp = iter->second;
varp = it->second;
} else {
if (width==0) {
if (newdtypep) {
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, newdtypep);
} else if (width==0) {
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, oldvarscp->varp());
varp->widthSignedFrom(oldvarscp);
} else {
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, AstLogicPacked(), width);
varp->dtypeFrom(oldvarscp);
} else { // Used for vset and dimensions, so can zero init
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, VFlagBitPacked(), width);
}
addmodp->addStmtp(varp);
m_modVarMap.insert(make_pair(make_pair(addmodp, name), varp));
@@ -144,6 +146,40 @@ private:
return varscp;
}
AstActive* createActivePost(AstVarRef* varrefp) {
AstActive* newactp = new AstActive (varrefp->fileline(), "sequentdly",
m_activep->sensesp());
m_activep->addNext(newactp);
return newactp;
}
void checkActivePost(AstVarRef* varrefp, AstActive* oldactivep) {
// Check for MULTIDRIVEN, and if so make new sentree that joins old & new sentree
if (!oldactivep) varrefp->v3fatalSrc("<= old dly assignment not put under sensitivity block");
if (oldactivep->sensesp() != m_activep->sensesp()) {
if (!varrefp->varp()->fileline()->warnIsOff(V3ErrorCode::MULTIDRIVEN)
&& !varrefp->varp()->user2()) {
varrefp->varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks: "<<varrefp->varp()->prettyName()<<endl
<<varrefp->warnMore()<<"... Location of first driving block"<<endl
<<oldactivep->warnMore()<<"... Location of other driving block");
varrefp->varp()->user2(true);
}
UINFO(4,"AssignDupDlyVar: "<<varrefp<<endl);
UINFO(4," Act: "<<m_activep<<endl);
UINFO(4," Act: "<<oldactivep<<endl);
// Make a new sensitivity list, which is the combination of both blocks
AstNodeSenItem* sena = m_activep->sensesp()->sensesp()->cloneTree(true);
AstNodeSenItem* senb = oldactivep->sensesp()->sensesp()->cloneTree(true);
AstSenTree* treep = new AstSenTree(m_activep->fileline(), sena);
if (senb) treep->addSensesp(senb);
if (AstSenTree* storep = oldactivep->sensesStorep()) {
storep->unlinkFrBack();
pushDeletep(storep);
}
oldactivep->sensesStorep(treep);
oldactivep->sensesp(treep);
}
}
AstNode* createDlyArray(AstAssignDly* nodep, AstNode* lhsp) {
// Create delayed assignment
// See top of this file for transformation
@@ -185,7 +221,7 @@ private:
} else {
string bitvarname = (string("__Vdlyvdim")+cvtToStr(dimension)
+"__"+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, dimp->width());
AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, dimp->width(), NULL);
AstAssign* bitassignp
= new AstAssign (nodep->fileline(),
new AstVarRef(nodep->fileline(), bitvscp, true),
@@ -203,7 +239,7 @@ private:
bitreadp = lsbvaluep;
} else {
string bitvarname = (string("__Vdlyvlsb__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, lsbvaluep->width());
AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, lsbvaluep->width(), NULL);
AstAssign* bitassignp = new AstAssign (nodep->fileline(),
new AstVarRef(nodep->fileline(), bitvscp, true),
lsbvaluep);
@@ -218,13 +254,14 @@ private:
valreadp = nodep->rhsp()->unlinkFrBack();
} else {
string valvarname = (string("__Vdlyvval__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
AstVarScope* valvscp = createVarSc(varrefp->varScopep(), valvarname, nodep->rhsp()->width());
AstVarScope* valvscp = createVarSc(varrefp->varScopep(), valvarname, 0, nodep->rhsp()->dtypep());
newlhsp = new AstVarRef(nodep->fileline(), valvscp, true);
valreadp = new AstVarRef(nodep->fileline(), valvscp, false);
}
//
//=== Setting/not setting boolean: __Vdlyvset__
AstVarScope* setvscp;
AstAssignPre* setinitp = NULL;
if (nodep->user3p()) {
// Simplistic optimization. If the previous statement in same scope was also a =>,
@@ -235,12 +272,10 @@ private:
++m_statSharedSet;
} else { // Create new one
string setvarname = (string("__Vdlyvset__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
setvscp = createVarSc(varrefp->varScopep(), setvarname, 1);
AstAssignPre* setinitp
= new AstAssignPre (nodep->fileline(),
new AstVarRef(nodep->fileline(), setvscp, true),
new AstConst(nodep->fileline(), 0));
m_activep->addStmtsp(setinitp);
setvscp = createVarSc(varrefp->varScopep(), setvarname, 1, NULL);
setinitp = new AstAssignPre (nodep->fileline(),
new AstVarRef(nodep->fileline(), setvscp, true),
new AstConst(nodep->fileline(), 0));
AstAssign* setassignp
= new AstAssign (nodep->fileline(),
new AstVarRef(nodep->fileline(), setvscp, true),
@@ -269,11 +304,18 @@ private:
UINFO(9," For "<<setvscp<<endl);
UINFO(9," & "<<varrefp<<endl);
AstAlwaysPost* finalp = varrefp->varScopep()->user4p()->castNode()->castAlwaysPost();
if (!finalp) {
if (finalp) {
AstActive* oldactivep = finalp->user2p()->castNode()->castActive();
checkActivePost(varrefp, oldactivep);
if (setinitp) oldactivep->addStmtsp(setinitp);
} else { // first time we've dealt with this memory
finalp = new AstAlwaysPost(nodep->fileline(), NULL/*sens*/, NULL/*body*/);
UINFO(9," Created "<<finalp<<endl);
m_activep->addStmtsp(finalp);
AstActive* newactp = createActivePost(varrefp);
newactp->addStmtsp(finalp);
varrefp->varScopep()->user4p(finalp);
finalp->user2p(newactp);
if (setinitp) newactp->addStmtsp(setinitp);
}
AstIf* postLogicp;
if (finalp->user3p()->castNode() == setvscp) {
@@ -292,7 +334,6 @@ private:
finalp->user4p(postLogicp); // and the associated IF, as we may be able to reuse it
}
postLogicp->addIfsp(new AstAssign(nodep->fileline(), selectsp, valreadp));
return newlhsp;
}
@@ -316,6 +357,7 @@ private:
m_activep = nodep;
bool oldinit = m_inInitial;
m_inInitial = nodep->hasInitial();
AstNode::user3ClearTree(); // Two sets to same variable in different actives must use different vars.
nodep->iterateChildren(*this);
m_inInitial = oldinit;
}
@@ -342,6 +384,7 @@ private:
m_inDly = false;
m_nextDlyp = NULL;
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (!nodep->user2Inc()) { // Not done yet
if (m_inDly && nodep->lvalue()) {
@@ -354,34 +397,11 @@ private:
AstVarScope* dlyvscp = oldvscp->user1p()->castNode()->castVarScope();
if (dlyvscp) { // Multiple use of delayed variable
AstActive* oldactivep = dlyvscp->user2p()->castNode()->castActive();
if (!oldactivep) nodep->v3fatalSrc("<= old dly assignment not put under sensitivity block");
if (oldactivep->sensesp() != m_activep->sensesp()) {
if (!nodep->varp()->fileline()->warnIsOff(V3ErrorCode::MULTIDRIVEN)
&& !nodep->varp()->user2()) {
nodep->varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks: "<<nodep->varp()->prettyName());
nodep->v3warn(MULTIDRIVEN,"... Location of first driving block");
oldactivep->v3warn(MULTIDRIVEN,"... Location of other driving block");
nodep->varp()->user2(true);
}
UINFO(4,"AssignDupDlyVar: "<<nodep<<endl);
UINFO(4," Act: "<<m_activep<<endl);
UINFO(4," Act: "<<oldactivep<<endl);
// Make a new sensitivity list, which is the combination of both blocks
AstNodeSenItem* sena = m_activep->sensesp()->sensesp()->cloneTree(true);
AstNodeSenItem* senb = oldactivep->sensesp()->sensesp()->cloneTree(true);
AstSenTree* treep = new AstSenTree(m_activep->fileline(), sena);
if (senb) treep->addSensesp(senb);
if (AstSenTree* storep = oldactivep->sensesStorep()) {
storep->unlinkFrBack();
pushDeletep(storep);
}
oldactivep->sensesStorep(treep);
oldactivep->sensesp(treep);
}
checkActivePost(nodep, oldactivep);
}
if (!dlyvscp) { // First use of this delayed variable
string newvarname = (string("__Vdly__")+nodep->varp()->shortName());
dlyvscp = createVarSc(oldvscp, newvarname, 0);
dlyvscp = createVarSc(oldvscp, newvarname, 0, NULL);
AstNodeAssign* prep
= new AstAssignPre (nodep->fileline(),
new AstVarRef(nodep->fileline(), dlyvscp, true),
@@ -393,12 +413,10 @@ private:
postp->lhsp()->user2(true); // Don't detect this assignment
oldvscp->user1p(dlyvscp); // So we can find it later
// Make new ACTIVE with identical sensitivity tree
AstActive* newactp = new AstActive (nodep->fileline(), "sequentdly",
m_activep->sensesp());
AstActive* newactp = createActivePost(nodep);
dlyvscp->user2p(newactp);
newactp->addStmtsp(prep); // Add to FRONT of statements
newactp->addStmtsp(postp);
m_activep->addNext(newactp);
dlyvscp->user2p(newactp);
}
AstVarRef* newrefp = new AstVarRef(nodep->fileline(), dlyvscp, true);
newrefp->user2(true); // No reason to do it again
+2 -4
View File
@@ -1,14 +1,12 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Pre C-Emit stage changes
//
// Code available from: http://www.veripool.org/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2011 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2014 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