Compare commits

..
104 Commits
Author SHA1 Message Date
Wilson Snyder eae1f380cd Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@901 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-12 12:58:08 +00:00
Wilson Snyder e7280d7237 Make V3Number::setMask to refactor some code
git-svn-id: file://localhost/svn/verilator/trunk/verilator@900 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-09 15:18:56 +00:00
Wilson Snyder 78997ee13c Another 64 bit fix
git-svn-id: file://localhost/svn/verilator/trunk/verilator@899 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-08 20:48:22 +00:00
Wilson Snyder 79ab50d84f Support trivial SV assertions
git-svn-id: file://localhost/svn/verilator/trunk/verilator@898 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-06 21:43:38 +00:00
Wilson Snyder 98282114c9 Fix display %m names inside named blocks.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@897 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-06 18:53:24 +00:00
Wilson Snyder d6cb175f96 More cleanup of verilog.l
git-svn-id: file://localhost/svn/verilator/trunk/verilator@896 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-06 17:07:13 +00:00
Wilson Snyder b4d9eb6ec4 Commentary
git-svn-id: file://localhost/svn/verilator/trunk/verilator@895 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-05 22:22:34 +00:00
Wilson Snyder fabbfbc46e Add `begin_keywords support
git-svn-id: file://localhost/svn/verilator/trunk/verilator@894 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-05 21:35:49 +00:00
Wilson Snyder c7d80f8cf8 Update keywords to indicate which language spec
git-svn-id: file://localhost/svn/verilator/trunk/verilator@893 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-05 20:29:05 +00:00
Wilson Snyder c70add7d0f Fix user() not zeroing all 64 bits in graphalg
git-svn-id: file://localhost/svn/verilator/trunk/verilator@892 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-05 13:52:21 +00:00
Wilson Snyder 44fe8741f3 Add /*verilator public_flat*/
git-svn-id: file://localhost/svn/verilator/trunk/verilator@891 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-02 22:24:51 +00:00
Wilson Snyder f8680cf5c2 Don't constant prop public signals
git-svn-id: file://localhost/svn/verilator/trunk/verilator@890 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-02 21:14:22 +00:00
Wilson Snyder 24c3424e51 Try all +libext's in the exact order given.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@889 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-02-27 20:00:29 +00:00
Wilson Snyder bd264006ef Fix empty for blocks
git-svn-id: file://localhost/svn/verilator/trunk/verilator@888 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-02-27 14:30:22 +00:00
Wilson Snyder bec3daa79f Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@885 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-02-07 14:27:37 +00:00
Wilson Snyder ead01ba0b9 Commentary and fix old SYSTEMPERL pointer
git-svn-id: file://localhost/svn/verilator/trunk/verilator@884 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-02-07 14:26:53 +00:00
Wilson Snyder 8e7267f0e2 With VL_DEBUG, show wires causing convergance errors.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@883 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-31 21:49:13 +00:00
Wilson Snyder 5dbae27f01 Fix 's with array select followed by wide AND. [David Hewson]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@882 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-31 15:44:36 +00:00
Wilson Snyder ecb938f20e Add isolate_assignments to functions
git-svn-id: file://localhost/svn/verilator/trunk/verilator@881 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-30 15:51:16 +00:00
Wilson Snyder f1a2ee3273 Allow isolate_assignments on task input/outputs
git-svn-id: file://localhost/svn/verilator/trunk/verilator@880 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-26 21:53:03 +00:00
Wilson Snyder eb2eb14297 Make tests work on NCV
git-svn-id: file://localhost/svn/verilator/trunk/verilator@879 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-26 15:56:09 +00:00
Wilson Snyder da07cc6ed1 Testcases should use !== to avoid Xs matching
git-svn-id: file://localhost/svn/verilator/trunk/verilator@878 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-26 14:59:30 +00:00
Wilson Snyder 3ff10b40d6 Fix isolate_assignments when many signals per always.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@877 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-23 18:11:26 +00:00
Wilson Snyder 7f515e6033 Add --trace-depth option
git-svn-id: file://localhost/svn/verilator/trunk/verilator@876 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-18 18:31:49 +00:00
Wilson Snyder a583592cd4 Make error code for MULTITOP and document
git-svn-id: file://localhost/svn/verilator/trunk/verilator@875 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-18 14:30:45 +00:00
Wilson Snyder b6f2b5b46a Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@872 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-18 00:52:10 +00:00
Wilson Snyder 895a3264a3 Add isolate_assignments meta comment
git-svn-id: file://localhost/svn/verilator/trunk/verilator@871 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-18 00:51:26 +00:00
Wilson Snyder 8738a51449 Add combo test
git-svn-id: file://localhost/svn/verilator/trunk/verilator@870 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-17 21:19:29 +00:00
Wilson Snyder 8ca6901f1f Commentary
git-svn-id: file://localhost/svn/verilator/trunk/verilator@869 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-17 19:56:39 +00:00
Wilson Snyder c14818ebb3 Fix complex sensitivity, try 2
git-svn-id: file://localhost/svn/verilator/trunk/verilator@866 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-03 03:30:30 +00:00
Wilson Snyder 58dc91605b Fix array selects in sense lists
git-svn-id: file://localhost/svn/verilator/trunk/verilator@865 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-03 03:01:36 +00:00
Wilson Snyder b5b1d94d4a Copyright date update
git-svn-id: file://localhost/svn/verilator/trunk/verilator@864 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-01-02 22:06:40 +00:00
Wilson Snyder 5a65f6debb Support [#] in dotted cell names
git-svn-id: file://localhost/svn/verilator/trunk/verilator@863 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-22 15:06:13 +00:00
Wilson Snyder 58b1ad1439 Rework parser and add V3LinkParse so we can handle foo[#].foo[#].foo[#:#] etc
git-svn-id: file://localhost/svn/verilator/trunk/verilator@862 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-21 21:53:51 +00:00
Wilson Snyder 94d0aa2058 Rename some verilog.y states for next checkin; no functional change
git-svn-id: file://localhost/svn/verilator/trunk/verilator@861 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-21 16:29:10 +00:00
Wilson Snyder 1d6495e2dc Remove unsupported verilator one_hot/one_cold to cleanup bison warnings
git-svn-id: file://localhost/svn/verilator/trunk/verilator@860 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-21 16:18:31 +00:00
Wilson Snyder 42883e7b6a Fix * with filenames < 8 characters
git-svn-id: file://localhost/svn/verilator/trunk/verilator@859 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-21 15:28:32 +00:00
Wilson Snyder dc6a164e01 Split V3LinkResolve into V3LinkLValue, and remove lvalue determination from bison code
git-svn-id: file://localhost/svn/verilator/trunk/verilator@858 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-21 14:35:19 +00:00
Wilson Snyder 26bab12257 Show warnings if use
git-svn-id: file://localhost/svn/verilator/trunk/verilator@857 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-20 21:14:22 +00:00
Wilson Snyder 8714ee591f Yet another round of dotted generate fixes
git-svn-id: file://localhost/svn/verilator/trunk/verilator@856 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-20 20:45:13 +00:00
Wilson Snyder 11335fae5f Add funcRef grammer object - no functional change
git-svn-id: file://localhost/svn/verilator/trunk/verilator@855 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-20 16:10:47 +00:00
Wilson Snyder ce531c5a67 Release configure.ac file in kit
git-svn-id: file://localhost/svn/verilator/trunk/verilator@851 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-20 01:11:25 +00:00
Wilson Snyder 52e36fb434 Reduce depth of priority encoded case statements.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@848 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-19 16:26:49 +00:00
Wilson Snyder 100d5b386c Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@847 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-19 14:13:34 +00:00
Wilson Snyder 699563c9bd Add support.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@846 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-19 14:09:57 +00:00
Wilson Snyder a599fbea18 Have tests pick up standard .mk so PERL is set based on configure
git-svn-id: file://localhost/svn/verilator/trunk/verilator@845 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-18 20:33:10 +00:00
Wilson Snyder c5f0ed9c99 Fix makefile typo, and remove unneeded PWD variable
git-svn-id: file://localhost/svn/verilator/trunk/verilator@844 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-18 20:05:02 +00:00
Wilson Snyder 2ce30e78a1 Move some test_v tests into test_regress area
git-svn-id: file://localhost/svn/verilator/trunk/verilator@843 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-18 19:49:36 +00:00
Wilson Snyder 3b554f4c5b Rename config.h to config_build.h, and add cross compile notes.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@842 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-18 19:20:45 +00:00
Wilson Snyder cf40fd356f Fix split list ordering causing circular refs
git-svn-id: file://localhost/svn/verilator/trunk/verilator@841 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-18 18:20:13 +00:00
Wilson Snyder 8848469bf9 Fix dotted references into generate fors
git-svn-id: file://localhost/svn/verilator/trunk/verilator@840 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-18 18:14:53 +00:00
Wilson Snyder 4100417f83 Show known scopes when dotted errors show up
git-svn-id: file://localhost/svn/verilator/trunk/verilator@839 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-15 22:28:18 +00:00
Wilson Snyder bd6d743f9c Move configure.in to configure.ac
git-svn-id: file://localhost/svn/verilator/trunk/verilator@838 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-15 21:18:41 +00:00
Wilson Snyder 857ac24ba7 Fix dotted ref signals under generate cells
git-svn-id: file://localhost/svn/verilator/trunk/verilator@837 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-12 18:25:33 +00:00
Wilson Snyder 5672b99203 Add t_extend_class example
git-svn-id: file://localhost/svn/verilator/trunk/verilator@836 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-10 22:48:26 +00:00
Wilson Snyder 3d8de3194c Fix SuSE10.0 compile warnings
git-svn-id: file://localhost/svn/verilator/trunk/verilator@833 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-05 15:24:38 +00:00
Wilson Snyder 8b91a9f898 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@832 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-12-05 15:12:19 +00:00
Wilson Snyder 038ee69a96 Add M32 make variable
git-svn-id: file://localhost/svn/verilator/trunk/verilator@831 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-11-02 19:13:07 +00:00
Wilson Snyder 8986d1f16f Avoid some duplicate sensitivity ifs.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@830 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-26 01:20:49 +00:00
Wilson Snyder 86c8e7b3e6 Add --output-split-cfuncs for accelerating GCC.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@829 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-26 01:08:44 +00:00
Wilson Snyder 9026118a7c Fix (blah) with width violation
git-svn-id: file://localhost/svn/verilator/trunk/verilator@828 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-25 21:41:32 +00:00
Wilson Snyder 58fc922737 Test fix
git-svn-id: file://localhost/svn/verilator/trunk/verilator@825 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-18 13:56:54 +00:00
Wilson Snyder 3b5c791332 Test fix
git-svn-id: file://localhost/svn/verilator/trunk/verilator@824 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-18 13:54:36 +00:00
Wilson Snyder 6e16bc1b7b Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@823 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-18 13:50:44 +00:00
Wilson Snyder 1aba0f6379 Show error code on non-generic errors; add TASKNSVAR
git-svn-id: file://localhost/svn/verilator/trunk/verilator@822 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-18 13:45:50 +00:00
Wilson Snyder 11cfa3c072 Suppress unused warnings using attribute
git-svn-id: file://localhost/svn/verilator/trunk/verilator@821 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-18 12:59:30 +00:00
Wilson Snyder 59141b1678 Fix --skip-identical
git-svn-id: file://localhost/svn/verilator/trunk/verilator@820 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-12 14:01:06 +00:00
Wilson Snyder 2083c071ce Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@817 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-11 15:42:32 +00:00
Wilson Snyder 3ad5872d30 Add verilator no_inline_task
git-svn-id: file://localhost/svn/verilator/trunk/verilator@816 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-11 15:41:42 +00:00
Wilson Snyder ea6bb21cdc Fix V3Subst mis-optimizing concats in t_case_write
git-svn-id: file://localhost/svn/verilator/trunk/verilator@815 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-11 15:34:50 +00:00
Wilson Snyder 3d4fe0364a No functional change; have V3Subst use a sub-structure.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@814 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-11 14:13:37 +00:00
Wilson Snyder 710d7c0ee5 Fix link error when using --exe with --trace.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@813 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-09 13:38:15 +00:00
Wilson Snyder 1c8fd37745 Fix some Coverity Prevent warnings
git-svn-id: file://localhost/svn/verilator/trunk/verilator@812 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-06 16:08:46 +00:00
Wilson Snyder 956c854662 Add t_case_write test
git-svn-id: file://localhost/svn/verilator/trunk/verilator@811 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-05 17:54:52 +00:00
Wilson Snyder 318a6e348c Support wide public task outputs.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@810 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-05 14:53:17 +00:00
Wilson Snyder e471a34323 Add maybePointedTo to v3Broken for better and faster checks
git-svn-id: file://localhost/svn/verilator/trunk/verilator@809 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-05 00:45:39 +00:00
Wilson Snyder 95c5b85e88 Unlink .vpp files without --debug
git-svn-id: file://localhost/svn/verilator/trunk/verilator@808 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-04 18:46:42 +00:00
Wilson Snyder a46a556a64 Don't coredump without --debug
git-svn-id: file://localhost/svn/verilator/trunk/verilator@807 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-04 15:46:13 +00:00
Wilson Snyder fa3e03e071 version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@804 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-04 12:57:29 +00:00
Wilson Snyder 74d7c55f1b Fix dotted variables in always sensitivity lists.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@803 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-03 13:02:21 +00:00
Wilson Snyder 79e02858cb Add --debug-check flag
git-svn-id: file://localhost/svn/verilator/trunk/verilator@802 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-10-02 17:09:56 +00:00
Wilson Snyder 7738b202ac Remove --bin from perl shell, use argv[0] instead
git-svn-id: file://localhost/svn/verilator/trunk/verilator@801 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-30 00:27:05 +00:00
Wilson Snyder b4d4917c6c Fix coredump in XREFs under FUNCREF's
git-svn-id: file://localhost/svn/verilator/trunk/verilator@800 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-30 00:08:09 +00:00
Wilson Snyder 5c93520b27 Associative same variable elimination
git-svn-id: file://localhost/svn/verilator/trunk/verilator@799 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-28 14:37:28 +00:00
Wilson Snyder 94f0809d33 Add more boolean identity fixes
git-svn-id: file://localhost/svn/verilator/trunk/verilator@798 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-27 18:00:53 +00:00
Wilson Snyder ca4e3c1737 Eliminate assigned only variables
git-svn-id: file://localhost/svn/verilator/trunk/verilator@797 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-26 17:05:08 +00:00
Wilson Snyder ba7b4f261a Redo V3Life to also do constant propagation
git-svn-id: file://localhost/svn/verilator/trunk/verilator@796 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-26 15:05:35 +00:00
Wilson Snyder 4f42c25c7c Fix inout task arguments
git-svn-id: file://localhost/svn/verilator/trunk/verilator@795 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-25 20:40:52 +00:00
Wilson Snyder 621ef70c31 Allow overriding PERL, YACC, LEX versions.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@794 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-25 15:58:17 +00:00
Wilson Snyder e3f17e7853 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@791 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-20 13:25:03 +00:00
Wilson Snyder 73c897ac69 Fix printf ULL warnings with a cast.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@790 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-20 13:24:18 +00:00
Wilson Snyder a4db880809 Use vluint8/16/64 in source code
git-svn-id: file://localhost/svn/verilator/trunk/verilator@789 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-19 15:27:15 +00:00
Wilson Snyder f9697463cc Have preprocessor strip all DOS returns
git-svn-id: file://localhost/svn/verilator/trunk/verilator@788 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-13 14:38:48 +00:00
Wilson Snyder f283076570 Rename {newline} in lex; no functional change
git-svn-id: file://localhost/svn/verilator/trunk/verilator@787 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-13 13:18:24 +00:00
Wilson Snyder e15228498d Define VL_PRINTF by default, and remove old coverageRequest
git-svn-id: file://localhost/svn/verilator/trunk/verilator@786 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-12 00:55:27 +00:00
Wilson Snyder 53155b3a36 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@783 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-11 20:44:54 +00:00
Wilson Snyder 12ae70ba95 Prep for removing begin under first generate, but doesn't work. Commentary instead
git-svn-id: file://localhost/svn/verilator/trunk/verilator@782 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-11 20:42:47 +00:00
Wilson Snyder 88809587f9 Fix function references under top inlined module.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@781 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-08 16:16:30 +00:00
Wilson Snyder 1b20481100 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@778 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-06 17:50:47 +00:00
Wilson Snyder 21eb939f37 Allow dotted references of arrayed cells
git-svn-id: file://localhost/svn/verilator/trunk/verilator@777 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-06 17:48:41 +00:00
Wilson Snyder 0a765fbb54 Fix function calls inside loop bounds
git-svn-id: file://localhost/svn/verilator/trunk/verilator@776 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-05 20:06:23 +00:00
Wilson Snyder 749fdaae31 Optimize n*powers of 2. (For parameterized DDR model)
git-svn-id: file://localhost/svn/verilator/trunk/verilator@775 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-01 16:53:14 +00:00
Wilson Snyder 6f48185a1f Fix arrayed instances
git-svn-id: file://localhost/svn/verilator/trunk/verilator@774 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-01 15:31:07 +00:00
Wilson Snyder 7f1b16837e Fix dead modules under generate cells not getting removed
git-svn-id: file://localhost/svn/verilator/trunk/verilator@773 77ca24e4-aefa-0310-84f0-b9a241c72d87
2006-09-01 14:05:20 +00:00
370 changed files with 15891 additions and 2309 deletions
+134 -9
View File
@@ -3,23 +3,148 @@ 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.60**
* Verilator 3.640 3/12/2007
*** Changed how internal functions are invoked to avoid aliasing in GCC 3.3+.
*** Support Verilog 2005 `begin_keywords and `end_keywords.
*** Updated list of SystemVerilog keywords to correspond to IEEE 1800-2005.
*** Add /*verilator public_flat*/. [Eugene Weber]
**** Try all +libext's in the exact order given. [Michael Shinkarovsky]
**** Fix elimination of public signals assigned to constants. [Eugene Weber]
**** Fix internal error when public for loop has empty body. [David Addison]
**** Fix "Loops detected" assertion when model exceeds 4GB. [David Hewson]
**** Fix display %m names inside named blocks.
* Verilator 3.633 2/7/2007
*** Add --trace-depth option for minimizing VCD file size. [Emerson Suguimoto]
*** With VL_DEBUG, show wires causing convergence errors. [Mike Shinkarovsky]
**** Fix isolate_assignments when many signals per always. [Mike Shinkarovsky]
**** Fix isolate_assignments across task/func temporaries. [Mike Shinkarovsky]
**** Fix $display's with array select followed by wide AND. [David Hewson]
* Verilator 3.632 1/17/2007
*** Add /*verilator isolate_assignments*/ attribute. [Mike Shinkarovsky]
* Verilator 3.631 1/2/2007
** Support standard NAME[#] for cells created by arraying or generate for.
This replaces the non-standard name__# syntax used in earlier versions.
**** Fix again dotted references into generate cells. [David Hewson]
Verilator no longer accepts duplicated variables inside unique
generate blocks as this is illegal according to the specification.
**** Fix $readmem* with filenames < 8 characters. [Emerson Suguimoto]
* Verilator 3.630 12/19/2006
** Support $readmemb and $readmemh. [Eugene Weber, Arthur Kahlich]
*** Fixed configure and compiling under Solaris. [Bob Farrell]
*** When dotted signal lookup fails, help the user by showing known scopes.
*** Reduce depth of priority encoded case statements. [Eugene Weber]
**** Fix dotted references inside generated cells. [David Hewson]
**** Fix missed split optimization points underneath other re-split blocks.
* Verilator 3.623 12/05/2006
*** Add --output-split-cfuncs for accelerating GCC compile. [Eugene Weber]
**** Fix $signed mis-extending when input has a WIDTH violation. [Eugene Weber]
**** Add M32 make variable to support -m32 compiles. [Eugene Weber]
* Verilator 3.622 10/17/2006 Stable
**** Fix --skip-identical without --debug, broken in 3.621. [Andy Meier]
* Verilator 3.621 10/11/2006 Beta
** Add /*verilator no_inline_task*/ to prevent over-expansion. [Eugene Weber]
*** Public functions now allow > 64 bit arguments.
**** Remove .vpp intermediate files when not under --debug.
**** Fix link error when using --exe with --trace. [Eugene Weber]
**** Fix mis-optimization of wide concats with constants.
**** Fix core dump on printing error when not under --debug. [Allan Cochrane]
* Verilator 3.620 10/04/2006 Stable
*** Support simple inout task ports. [Eugene Weber]
*** Allow overriding Perl, Flex and Bison versions. [by Robert Farrell]
*** Optimize variables set to constants within basic blocks for ~3%.
**** Default make no longer makes the docs; if you edit the documentation.
sources, run "make info" to get them.
**** Optimize additional boolean identities (a|a = a, etc.)
**** Fix coredump when dotted cross-ref inside task call. [Eugene Weber]
**** Fix dotted variables in always sensitivity lists. [Allan Cochrane]
* Verilator 3.610 09/20/2006 Stable
*** Verilator now works under DJGPP (Pentium GCC). [John Stroebel]
**** Add default define for VL_PRINTF. [John Stroebel]
**** Removed coverage request variable; see Coverage limitations in docs.
**** Fix DOS carriage returns in multiline defines. [Ralf Karge]
**** Fix printf format warnings on 64-bit linux.
* Verilator 3.602 09/11/2006 Stable
**** Fix function references under top inlined module. [David Hewson]
* Verilator 3.601 09/06/2006 Beta
*** Added --inhibit-sim flag for environments using old __Vm_inhibitSim.
*** Added `systemc_dtor for destructor extentions. [Allan Cochrane]
*** Added `systemc_dtor for destructor extensions. [Allan Cochrane]
*** Added -MP to make phony dependencies, ala GCC's.
**** Declare optimized lookup tables as 'static', to reduce D-Cache miss rate.
*** Changed how internal functions are invoked to reduce aliasing.
Useful when using GCC's -O2 or -fstrict-aliasing, to gain another ~4%.
**** Fix memory leak when destroying modules. [John Stroebel]
**** Fix coredump when unused modules have unused cells. [David Hewson]
**** Fix 3.600 internal error with arrayed instances. [David Hewson]
**** Fix 3.600 internal error with non-unrolled function loops. [David Hewson]
**** Fix $display %m name not matching Verilog name inside SystemC modules.
* Verilator 3.600 08/28/2006
**** Declare optimized lookup tables as 'static', to reduce D-Cache miss rate.
* Verilator 3.600 08/28/2006 Beta
** Support dotted cross-hierarchy variable and task references.
@@ -35,7 +160,7 @@ indicates the contributor was also the author of the fix; Thanks!
**** Fix extraneous UNSIGNED warning when comparing genvars. [David Hewson]
**** Fix extra whitespace in $display %c. [by David Addison]
**** Fix extra white space in $display %c. [by David Addison]
**** vl_finish and vl_fatal now print via VL_PRINTF rather then cerr/cout.
@@ -138,7 +263,7 @@ indicates the contributor was also the author of the fix; Thanks!
**** Fix functions where regs are declared before inputs. [Danny Ding]
**** Fix bad deep expressions with bitselects and rotate. [Prabhat Gupta]
**** Fix bad deep expressions with bit-selects and rotate. [Prabhat Gupta]
* Verilator 3.500 10/30/2005 Stable
@@ -386,7 +511,7 @@ indicates the contributor was also the author of the fix; Thanks!
**** Added NC Verilog as alternative to VCS for reference tests.
**** Support implicit wire declarations on input-only signals.
(Dangerous, as leads to wires without drivers, but allowed by spec.)
(Dangerous, as leads to wires without drivers, but allowed by spec.)
**** Fixed compile warnings on Suse 9.1
@@ -922,7 +1047,7 @@ $Id$
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
Copyright 2001-2006 by Wilson Snyder. This program is free software;
Copyright 2001-2007 by Wilson Snyder. This program is free software;
you can redistribute it and/or modify it under the terms of either the GNU
General Public License or the Perl Artistic License.
+15 -16
View File
@@ -10,7 +10,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
#
@@ -78,7 +78,6 @@ datadir = @datadir@
infodir = @infodir@
# Directory in which to install package specific files
# Note this gets coded into v3c/config.h also
pkgdatadir = @pkgdatadir@
#### End of system configuration section. ####
@@ -91,11 +90,11 @@ SUBDIRS = src test_verilated test_c test_sc test_sp test_regress test_vcs
INFOS = README verilator.txt verilator.html verilator.1 verilator.pdf
# Files that can be generated, but should be up to date for a distribution.
DISTDEP = $(INFOS) Makefile
DISTDEP = info Makefile
# Files to distribute.
DISTBIN = $(wildcard bin/verilator-*)
DISTFILES_INC = $(INFOS) .cvsignore COPYING *.in \
DISTFILES_INC = $(INFOS) .cvsignore COPYING *.in *.ac \
Changes README TODO \
bin/* \
install-sh configure mkinstalldirs *.texi \
@@ -126,7 +125,7 @@ INST_PROJ_BIN_FILES = \
DISTFILES := $(DISTFILES_INC)
all: all_nomsg msg_test
all_nomsg: verilator_exe info
all_nomsg: verilator_exe
.PHONY:verilator_exe
verilator_exe verilator_bin verilator_bin_dbg:
@@ -156,15 +155,15 @@ test_vcs: all_nomsg
test_c: all_nomsg
@(cd test_c && $(MAKE))
test_c_debug: all_nomsg
@(cd test_c && $(MAKE) debug)
@(cd test_c && $(MAKE) test_debug)
test_sc: all_nomsg
@(cd test_sc && $(MAKE))
test_sc_debug: all_nomsg
@(cd test_sc && $(MAKE) debug)
@(cd test_sc && $(MAKE) test_debug)
test_sp: all_nomsg
@(cd test_sp && $(MAKE))
test_sp_debug: all_nomsg
@(cd test_sp && $(MAKE) debug)
@(cd test_sp && $(MAKE) test_debug)
test_verilated: all_nomsg
@(cd test_verilated && $(MAKE))
test_regress: all_nomsg
@@ -218,7 +217,7 @@ installman:
$(INSTALL_PROGRAM) $$p $(mandir)/man1/$$p; \
done
install: all_nomsg info installdirs installbin installman install-msg
install: all_nomsg installdirs installbin installman install-msg
install-here: installman ftp
@@ -265,16 +264,16 @@ uninstall:
-cd $(mandir)/man1 && rm -f $(VL_INST_MAN_FILES)
-cd $(bindir) && rm -f $(VL_INST_BIN_FILES)
# autoheader might not change config.h.in, so touch a stamp file.
# autoheader might not change config_build.h.in, so touch a stamp file.
IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in ${srcdir}/*/*/*.in \
*.in */*.in */*.in
${srcdir}/config.h.in: stamp-h.in
${srcdir}/stamp-h.in: configure.in $(wildcard $(IN_WILD))
${srcdir}/config_build.h.in: stamp-h.in
${srcdir}/stamp-h.in: configure.ac $(wildcard $(IN_WILD))
cd ${srcdir} && autoheader
echo timestamp > ${srcdir}/stamp-h.in
config.h: stamp-h
stamp-h: config.h.in config.status
config_build.h: stamp-h
stamp-h: config_build.h.in config.status
./config.status
Makefile: Makefile.in config.status
./config.status
@@ -282,7 +281,7 @@ src/Makefile: src/Makefile.in config.status
./config.status
config.status: configure
./config.status --recheck
configure: configure.in
configure: configure.ac
autoconf
maintainer-clean::
@@ -317,7 +316,7 @@ TAGS: $(TAGFILES)
######################################################################
# Distributions
DISTCONFIG = src/config.h.in
DISTCONFIG = src/config_build.h.in
DISTTITLE := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e 's/v/V/' -e q $(DISTCONFIG))
DISTNAME := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e q $(DISTCONFIG))
+1 -1
View File
@@ -6,7 +6,7 @@ This is the Verilator Package.
1.1 Copyright
=============
This package is Copyright 2003-2006 by Wilson Snyder
This package is Copyright 2003-2007 by Wilson Snyder
<[email protected]>.
You may distribute under the terms of either the GNU General Public
+6 -1
View File
@@ -1,7 +1,7 @@
// $Id$
// DESCRIPTION: Verilator: List of To Do issues.
//
// Copyright 2004-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
@@ -47,6 +47,10 @@ Testing:
Better graph viewer with search and zoom
Port and test against opencores.org code
Usability:
Better reporting of unopt problems, including what lines of code
Report more errors (all of them?) before exiting [Eugene Weber]
Performance:
Constant propagation
Extra cleaning AND: 1 & ((VARREF >> 1) | ((&VARREF >> 1) & VARREF))
@@ -97,6 +101,7 @@ Performance:
Track recirculation and convert into clock-enables
Clock enables should become new clocking domains for speed
If floped(a) & flopped(b) and no other a&b, then instead flop(a&b).
Sort by output bitselects so can combine more assignments (see DDP example dx_dm signal)
//**********************************************************************
//* Detailed notes on 'todo' features
+489 -139
View File
@@ -4,7 +4,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
# $Id$
######################################################################
#
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
#
@@ -104,16 +104,16 @@ if ($Opt_Sp) {
}
if ($Opt_Sp eq 'sp' || $Opt_Trace) {
if (!defined $ENV{SYSTEMPERL}) {
my $try = "$ENV{W}/hw/utils/perltools/SystemC/src";
my $try = "$ENV{W}/hw/utils/perltools/SystemC";
$ENV{SYSTEMPERL} = $try if -d $try;
}
(defined $ENV{SYSTEMPERL}) or die "%Error: verilator: Need \$SYSTEMPERL in environment for --sp or --trace\nProbably System-Perl isn't installed, see http://www.veripool.com/systemperl.html\n";
(-d "$ENV{SYSTEMPERL}/src") or die "%Error: verilator: \$SYSTEMPERL environment var doesn't seem to point to System-Perl kit\n";
}
# Determine runtime flags
my $vcmd =(($opt_gdb?"$opt_gdb ":"")
.verilator_bin()
." --bin ".verilator_bin() # So we get binary name into .d file
." ".join(' ',@Opt_Verilator_Sw)
);
@@ -169,7 +169,7 @@ sub run {
warn "%Error: export VERILATOR_ROOT=$ENV{VERILATOR_ROOT}\n";
warn "%Error: $command\n";
}
die "%Error: Command Failed $command, $status, stopped";
die "%Error: Command Failed $command\n";
}
}
@@ -234,6 +234,13 @@ linking with make rules you write yourself.
Enable all assertions, includes enabling the --psl flag. (If psl is not
desired, but other assertions are, use --assert --nopsl.)
=item --bin I<filename>
Rarely needed. Override the default filename for Verilator itself. When a
dependency (.d) file is created, this filename will become a source
dependency, such that a change in this binary will have make rebuild the
output files.
=item --cc
Specifies C++ without SystemC output mode; see also --sc and --sp.
@@ -247,10 +254,10 @@ Enables all forms of coverage, alias for --coverage-line, --coverage-user
Specifies basic block line coverage analysis code should be inserted.
Coverage analysis adds statements at each code flow change point, which are
the branches of IF and CASE statements, a superset of normal Verilog Line
Coverage. At each such branch a C++ macro is called, which SystemPerl uses
to increment an array. At the end of a test, logs/coverage.pl is written
with the data from the array.
the branches of IF and CASE statements, a super-set of normal Verilog Line
Coverage. At each such branch a unique counter is incremented. At the end
of a test, the counters along with the filename and line number
corresponding to each counter are written into logs/coverage.pl.
After running multiple tests, the vcoverage utility (from the SystemPerl
package) is executed. Vcoverage reads the logs/coverage.pl file(s), and
@@ -261,6 +268,10 @@ them, as it is assumed $stop branches contain an error check that should
not occur. A /*verilator coverage_block_off*/ comment will perform a
similar function on any code in that block or below.
Note Verilator may over-count combinatorial (non-clocked) blocks when those
blocks receive signals which have had the UNOPTFLAT warning disabled; for
most accurate results do not disable this warning when using coverage.
For an example, after running 'make test' in the Verilator distribution,
see the test_sp/logs/coverage_source directory. Grep for lines starting
with '%' to see what lines Verilator believes need more coverage.
@@ -279,8 +290,13 @@ the comment "DefaultClock":
=item --debug
Select the debug built image of Verilator (if available), and enable
debugging messages and intermediate form dump files.
Select the debug built image of Verilator (if available), and enable more
internal assertions, debugging messages, and intermediate form dump files.
=item --debug-check
Rarely needed. Enable internal debugging assertion checks, without
changing debug verbosity. Enabled automatically when --debug specified.
=item -E
@@ -299,10 +315,10 @@ Displays this message and program version and exits.
=item --inhibit-sim
Create a "inhibitSim(bool)" function to enable and disable evaluation.
This allows a upper level testbench to disable modules that are not
important in a given simulation, without needing to recompile or change the
SystemC modules instantiated.
Rarely needed. Create a "inhibitSim(bool)" function to enable and disable
evaluation. This allows a upper level testbench to disable modules that
are not important in a given simulation, without needing to recompile or
change the SystemC modules instantiated.
=item --inline-mult I<value>
@@ -335,8 +351,8 @@ the same as --prefix.
=item --no-skip-identical
Disables skipping execution of Verilator if all source files are identical,
and all output files exist with newer dates.
Rarely needed. Disables skipping execution of Verilator if all source
files are identical, and all output files exist with newer dates.
=item -O0
@@ -349,11 +365,11 @@ cost of compile time. This currently sets --inline-mult -1.
=item -OI<optimization-letter>
Enables or disables a specific optimizations, with the optimization
selected based on the letter passed. A lowercase letter disables an
optimization, an upper case letter enables it. This is intended for
debugging use only; see the source code for version-dependent mappings of
optimizations to -O letters.
Rarely needed. Enables or disables a specific optimizations, with the
optimization selected based on the letter passed. A lowercase letter
disables an optimization, an upper case letter enables it. This is
intended for debugging use only; see the source code for version-dependent
mappings of optimizations to -O letters.
=item --output-split I<bytes>
@@ -362,9 +378,18 @@ C++ file exceeds the specified number of operations, a new file will be
created. In addition, any slow routines will be placed into __Slow files.
This accelerates compilation by as optimization can be disabled on the slow
routines, and the remaining files can be compiled on parallel machines.
Using --output-split should have only a trivial impact on performance.
With GCC 3.3 on a 2GHz Opteron, --output-split 20000 will result in
splitting into approximately one-minute-compile chunks.
=item --output-split-cfuncs I<statements>
Enables splitting functions in the output .cpp/.sp files into multiple
functions. When a generated function exceeds the specified number of
operations, a new function will be created. With --output-split, this will
enable GCC to compile faster, at a small loss in performance that increases
with smaller statement values.
=item --pins64
Specifies SystemC outputs of 33-64 bits wide should use uint64_t instead of
@@ -392,17 +417,20 @@ compatibility.
=item --psl
Enable PSL parsing. Without this switch, psl meta-comments are ignored.
Enable PSL parsing. Without this switch, PSL meta-comments are ignored.
See the --assert flag to enable all assertions, and --coverage-user to
enable functional coverage.
=item --public
This is only for historical debug use. Using it may result in
mis-simulation of generated clocks.
Declares all signals and modules public. This will turn off signal
optimizations as if all signals had a /*verilator public*/ comments. This
will also turn off inlining as if all modules had a /*verilator
public_module*/, unless the module specifically enabled it with /*verilator
inline_module*/.
optimizations as if all signals had a /*verilator public*/ comments and
inlining. This will also turn off inlining as if all modules had a
/*verilator public_module*/, unless the module specifically enabled it with
/*verilator inline_module*/.
=item --sc
@@ -422,12 +450,19 @@ Adds waveform tracing code to the model. Having tracing compiled in may
result in some small performance losses, even when waveforms are not turned
on during model execution.
=item --trace-depth I<levels>
Specify the number of levels deep to enable tracing, for example
--trace-level 1 to only see the top level's signals. Defaults to the
entire model. Using a small number will decrease visibility, but greatly
improve runtime and trace file size.
=item --underline-zero
Signals starting with a underline should be initialized to zero, as was
done in Verilator 2. Default is for all signals including those with
underlines being randomized. This option may be depreciated in future
versions.
Rarely needed. Signals starting with a underline should be initialized to
zero, as was done in Verilator 2. Default is for all signals including
those with underlines being randomized. This option may be depreciated in
future versions.
=item -Werror-I<message>
@@ -548,7 +583,7 @@ And we get as output
Hello World
- our.v:2: Verilog $finish
Really, you're better off using a Makefile to do all this for you. Then,
Really, you're better off writing a Makefile to do all this for you. Then,
when your source changes it will automatically run all of these steps. See
the test_c directory in the distribution for an example.
@@ -591,7 +626,7 @@ Then we convert the SystemPerl output to SystemC.
$SYSTEMPERL/sp_preproc --preproc *.sp
(You can also skip the above sp_preproc by getting pure SystemC from
verilator by replacing the verilator --sp flag in the previous step with
Verilator by replacing the verilator --sp flag in the previous step with
-sc.)
We then can compile it
@@ -702,7 +737,7 @@ In certain optimization modes, it also creates:
It also creates internal files that can be mostly ignored:
{each_verilog_module}.vpp // Post-processed verilog source code
{each_verilog_module}.vpp // Post-processed verilog (--debug)
{prefix}.flags_vbin // Verilator dependencies
{prefix}.flags_vpp // Pre-processor dependencies
{prefix}{misc}.d // Make dependencies (-MMD)
@@ -828,30 +863,73 @@ Lower modules are not pure SystemC code. This is a feature, as using the
SystemC pin interconnect scheme everywhere would reduce performance by an
order of magnitude.
=head1 VERILOG 2001 SUPPORT
=head1 CROSS COMPILATION
Verilator supports cross-compiling Verilated code. This is generally used
to run Verilator on a Linux system and produce C++ code that is then compiled
on Windows.
Cross compilation involves up to three different OSes. The build system is
where you configured and compiled Verilator, the host system where you run
Verilator, and the target system where you compile the Verilated code and
run the simulation.
Currently, Verilator requires the build and host system type to be the
same, though the target system type may be different. To support this,
./configure and make Verilator on the build system. Then, run Verilator on
the host system. Finally, the output of Verilator may be compiled on the
different target system.
To support this, none of the files that Verilator produces will reference
any configure generated build-system specific files, such as config.h
(which is renamed in Verilator to config_build.h to reduce confusion.) The
disadvantage of this approach is that include/verilatedos.h must
self-detect the requirements of the target system, rather then using
configure.
The target system may also require edits to the Makefiles, the simple
Makefiles produced by Verilator presume the target system is the same type
as the build system.
=head1 VERILOG 2001 (IEEE 1364-2001) SUPPORT
Verilator supports the more common Verilog 2001 language features. This
includes signed numbers, "always @*", comma separated sensitivity lists,
generate statements, multidimensional arrays, localparam, and C-style
declarations inside port lists.
=head1 SYSTEMVERILOG 3.1 SUPPORT
=head1 VERILOG 2005 (IEEE 1364-2005) SUPPORT
Verilator currently has very minimal support for SystemVerilog.
Verilator supports the `begin_keywords and `end_keywords compiler
directives.
Verilator implement the full SystemVerilog 3.1 preprocessor subset,
including function call-like preprocessor defines. Verilator also
implements $bits, $countones, $isunknown, $onehot, and $onehot0,
always_comb, always_ff, always_latch, and final.
Verilator partially supports the uwire keyword.
=head1 SYSTEMVERILOG (IEEE 1800-2005) SUPPORT
Verilator currently has very minimal support for SystemVerilog as they
become more common, contact the author if a feature you need is missing.
Verilator implements the full SystemVerilog 1800-2005 preprocessor subset,
including function call-like preprocessor defines.
Verilator supports $bits, $countones, $error, $fatal, $info, $isunknown,
$onehot, $onehot0, $warning, always_comb, always_ff, always_latch, and
final.
Verilator partially supports assert.
=head1 SUGAR/PSL SUPPORT
With the --assert switch, Verilator is just beginning to support the
Property Specification Language (PSL), specifically the simple subset
without time-branching primitives. Verilator currently only converts PSL
Most future work is being directed towards improving SystemVerilog
assertions instead of PSL. If you are using these PSL features, please
contact the author as they may be depreciated in future versions.
With the --assert switch, Verilator enables support of the Property
Specification Language (PSL), specifically the simple PSL subset without
time-branching primitives. Verilator currently only converts PSL
assertions to simple "if (...) error" statements, and coverage statements
to increment the line counters described in the coverage section. If you
need additional features please contact the author.
to increment the line counters described in the coverage section.
Verilator implements these keywords: assert, assume (same as assert),
default (for clocking), countones, cover, isunknown, onehot, onehot0,
@@ -860,18 +938,16 @@ report, true.
Verilator implements these operators: -> (logical if).
Verilator does not support SEREs yet. All assertion and coverage
statements must be simple expressions that complete in one cycle.
(Arguably SEREs are the whole point of PSL, but one must start somewhere.)
PSL vmode/vprop/vunits are not supported. PSL statements must be in the
module they reference, at the module level where you would put an
statements must be simple expressions that complete in one cycle. PSL
vmode/vprop/vunits are not supported. PSL statements must be in the module
they reference, at the module level where you would put an
initial... statement.
Verilator only supports (posedge CLK) or (negedge CLK), where CLK is the
name of a one bit signal. You may not use arbitrary expressions as
assertion clocks.
=head1 SYNTHESIS DIRECTIVE ASSERTIONS
=head1 SYNTHESIS DIRECTIVE ASSERTION SUPPORT
With the --assert switch, Verilator reads any "//synopsys full_case" or "//
synopsys parallel_case" directives. The same applies to any "//cadence" or
@@ -920,7 +996,7 @@ call C++ functions from your Verilog code.
String arguments will be put directly into the output C++ code. Expression
arguments will have the code to evaluate the expression inserted. Thus to
call a C++ function, $c("func(",a,")") will result in 'func(a)' in the
output C++ code. For input arguments, rather then hardcoding variable
output C++ code. For input arguments, rather then hard-coding variable
names in the string $c("func(a)"), instead pass the variable as an
expression $c("func(",a,")"). This will allow the call to work inside
Verilog functions where the variable is flattened out, and also enable
@@ -936,21 +1012,11 @@ each different output width.
=item $display, $write, $fdisplay, $fwrite
$display format arguments may use C fprintf sizes after the % escape. Per
the Verilog standard, %x prints a number with the natural width, %0x prints
a number with minimum width, however %5x prints 5 digits per the C standard
Format arguments may use C fprintf sizes after the % escape. Per the
Verilog standard, %x prints a number with the natural width, %0x prints a
number with minimum width, however %5x prints 5 digits per the C standard
(it's unspecified in Verilog).
=item $fopen, $fclose, $fdisplay, $fwrite
File descriptors passed to the file PLI calls must be file descriptors, not
MCDs, which includes the mode parameter to $fopen being mandatory.
Verilator will convert the integer used to hold the file descriptor into a
internal FILE*. To prevent core dumps due to mis-use, and because integers
are 32 bits while FILE*s may be 64 bits, the descriptor must be stored in a
reg [63:0] rather then an integer. The define `verilator_file_descriptor in
verilated.v can be used to hide this difference.
=item `coverage_block_off
Specifies the entire begin/end block should be ignored for coverage analysis.
@@ -1030,6 +1096,41 @@ submodules will be named I<submodule>__DOT__I<subsignal> as C++ does not
allow "." in signal names. SystemPerl when tracing such signals will
replace the __DOT__ with the period.
=item /*verilator isolate_assignments*/
Used after a signal declaration to indicate the assignments to this signal
in any blocks should be isolated into new blocks. When there is a large
combinatorial block that is resulting in a UNOPTFLAT warning, attaching
this to the signal causing a false loop may clear up the problem.
IE, with the following
reg splitme /* verilator isolate_assignments*/;
always @* begin
if (....) begin
splitme = ....;
other assignments
end
end
Verilator will internally split the block that assigns to "splitme" into
two blocks:
It would then internally break it into (sort of):
// All assignments excluding those to splitme
always @* begin
if (....) begin
other assignments
end
end
// All assignments to splitme
always @* begin
if (....) begin
splitme = ....;
end
end
=item /*verilator lint_off I<msg>*/
Disable the specified warning message for any warnings following the comment.
@@ -1038,6 +1139,57 @@ Disable the specified warning message for any warnings following the comment.
Re-enable the specified warning message for any warnings following the comment.
=item /*verilator no_inline_task*/
Used in a function or task variable definition section to specify the
function or task should not be inlined into where it is used. This may
reduce the size of the final executable when a task is used a very large
number of times. For this flag to work, the task and tasks below it must
be pure; they cannot reference any variables outside the task itself.
=item /*verilator public*/ (variable)
Used after a input, output, register, or wire declaration to indicate the
signal should be declared so that C code may read or write the value
of the signal. This will also declare this module public, otherwise use
/*verilator public_flat*/.
=item /*verilator public*/ (task/function)
Used inside the declaration section of a function or task declaration to
indicate the function or task should be made into a C++ function, public to
outside callers. Public tasks will be declared as a void C++ function,
public functions will get the appropriate non-void (bool, uint32_t, etc)
return type. Any input arguments will become C++ arguments to the
function. Any output arguments will become C++ reference arguments. Any
local registers/integers will become function automatic variables on the
stack.
Wide variables over 64 bits cannot be function returns, to avoid exposing
complexities. However, wide variables can be input/outputs; they will be
passed as references to an array of 32 bit numbers.
This feature is still somewhat experimental. Generally, only the values of
stored state (flops) should be written, as the model will NOT notice
changes made to variables in these functions. (Same as when a signal is
declared public.)
=item /*verilator public_flat*/ (variable)
Used after a input, output, register, or wire declaration to indicate the
signal should be declared so that C code may read or write the value of the
signal. This will not declare this module public, which means the name of
the signal or path to it may change based upon the module inlining which
takes place.
=item /*verilator public_module*/
Used after a module statement to indicate the module should not be inlined
(unless specifically requested) so that C code may access the module.
Verilator automatically sets this attribute when the module contains any
public signals or `systemc_ directives. Also set for all modules when
using the --public switch.
=item /*verilator sc_clock*/
Used after a input declaration to indicate the signal should be declared in
@@ -1053,40 +1205,6 @@ that the entire module is not traced.
Re-enable waveform tracing for all future signals that are declared.
=item /*verilator public*/ (variable)
Used after a input, output, register, or wire declaration to indicate the
signal should be declared so that C code may read or write the value
of the signal. Set for all signals when using the --public switch.
=item /*verilator public*/ (task/function)
Used inside the declaration section of a function or task declaration to
indicate the function or task should be made into a C++ function, public to
outside callers. Public tasks will be declared as a void C++ function,
public functions will get the appropriate non-void (bool, uint32_t, etc)
return type. Any input arguments will become C++ arguments to the
function. Any output arguments will become C++ reference arguments. Any
local registers/integers will become function automatic variables on the
stack.
Wide variables over 64 bits cannot be I/O to the module, to avoid exposing
complexities; generally the cleanest technique is to pass a word number to
the function, and do appropriate bit selection.
This feature is still somewhat experimental. Generally, only the values of
stored state (flops) should be written, as the model will NOT notice
changes made to variables in these functions. (Same as when a signal is
declared public.)
=item /*verilator public_module*/
Used after a module statement to indicate the module should not be inlined
(unless specifically requested) so that C code may access the module.
Verilator automatically sets this attribute when the module contains any
public signals or `systemc_ directives. Also set for all modules when
using the --public switch.
=back
=head1 LANGUAGE LIMITATIONS
@@ -1116,7 +1234,21 @@ always @* to prevent these issues.)
Verilator supports dotted references to variables, functions and tasks in
different modules. However, references into named blocks and function-local
variables are not supported.
variables are not supported. The portion before the dot must have a
constant value; for example a[2].b is acceptable, while a[x].b is not.
References into generated and arrayed instances use the instance names
specified in the Verilog standard; arrayed instances are named
{cellName}[{instanceNumber}] in Verilog, which becomes
{cellname}__BRA__{instanceNumber}__KET__ inside the generated C++ code.
Verilator creates numbered "genblk" when a begin: name is not specified
around a block inside a generate statement. These numbers may differ
between other simulators, but the Verilog specification does not allow
users to use these names, so it should not matter.
If you are having trouble determining where a dotted path goes wrong, note
that Verilator will print a list of known scopes to help your debugging.
=head2 Latches
@@ -1170,12 +1302,6 @@ prepended. (If you don't know what this means, Verilator will do what you
probably expect -- what C does. The default behavior of Verilog is
different.)
=head2 Generate Statements
All instantiations and variables in generate blocks will be placed under
hierarchy that has a name different from that required in the language
specification.
=head2 Generated Clocks
Verilator attempts to deal with generated clocks correctly, however new
@@ -1230,7 +1356,84 @@ will give a width warning and wrap around the power-of-2 size. For
non-power-of-2 sizes, it will return a unspecified constant of the
appropriate width.
=head1 ERRORS
=head2 Assertions
Verilator is beginning to add support for assertions. Verilator currently
only converts assertions to simple "if (...) error" statements, and
coverage statements to increment the line counters described in the
coverage section.
Verilator does not support SEREs yet. All assertion and coverage
statements must be simple expressions that complete in one cycle.
(Arguably SEREs are much of the point, but one must start somewhere.)
=head1 LANGUAGE KEYWORD LIMITATIONS
This section describes specific limitations for each language keyword.
=over 4
=item always always_comb always_ff always_latch and assign begin buf case
casex casez default defparam else end endcase endfunction endgenerate
endmodule endspecify endtask final for function generate genvar if initial
inout input integer localparam macromodule module nand negedge nor not or
output parameter posedge reg scalared signed supply0 supply1 task tri
vectored wire xnor xor
Generally supported.
=item specify specparam
All specify blocks and timing checks are ignored.
=item uwire
Verilator does not perform warning checking on uwires, it treats the uwire
keyword as if it were the normal wire keyword.
=item $bits, $countones, $finish, $isunknown, $onehot, $onehot0, $readmemb,
$readmemh, $signed, $stop, $time, $unsigned
Generally supported.
=item $display, $write, $fdisplay, $fwrite
$display and friends must have a constant format string as the first
argument (as with C's printf), you cannot simply list variables standalone.
=item $displayb, $displayh, $displayo, $writeb, $writeh, $writeo, etc
The sized display functions are rarely used and so not supported. Replace
them with a $write with the appropriate format specifier.
=item $fopen, $fclose, $fdisplay, $fwrite
File descriptors passed to the file PLI calls must be file descriptors, not
MCDs, which includes the mode parameter to $fopen being mandatory.
Verilator will convert the integer used to hold the file descriptor into a
internal FILE*. To prevent core dumps due to mis-use, and because integers
are 32 bits while FILE*s may be 64 bits, the descriptor must be stored in a
reg [63:0] rather then an integer. The define `verilator_file_descriptor in
verilated.v can be used to hide this difference.
=item $fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal,
$setup, $setuphold, $skew, $timeskew, $width
All specify blocks and timing checks are ignored.
=item $readmemb, $readmemh
Read memory commands should work properly. Note Verilator and the Verilog
specification does not include support for readmem to multi-dimensional
arrays.
=item $realtime
Treated as $time.
=back
=head1 ERRORS AND WARNINGS
Warnings may be disabled in two ways. First, when the warning is
printed it will include a warning code. Simply surround the offending
@@ -1240,16 +1443,36 @@ line with a warn_off/warn_on pair:
if (`DEF_THAT_IS_EQ_ZERO <= 3) $stop;
// verilator lint_on UNSIGNED
They may also be globally disabled by invoking Verilator with the
C<-Wno-I<warning>> switch. This should be avoided, as it removes
all checking across the designs, and prevents other users from
compiling your code without knowing the magic set of disables needed
to successfully compile your design.
Warnings may also be globally disabled by invoking Verilator with the
C<-Wno-I<warning>> switch. This should be avoided, as it removes all
checking across the designs, and prevents other users from compiling your
code without knowing the magic set of disables needed to successfully
compile your design.
Warnings:
List of all warnings:
=over 4
=item BLKANDNBLK
Error that a variable comes from a mix of blocked and non-blocking
assignments. Generally, this is caused by a register driven by both combo
logic and a flop:
always @ (posedge clk) foo[0] <= ...
always @* foo[1] = ...
Simply use a different register for the flop:
always @ (posedge clk) foo_flopped[0] <= ...
always @* foo[0] = foo_flopped[0];
always @* foo[1] = ...
This is good coding practice anyways.
It is also possible to disable this error when one of the assignments is
inside a public task.
=item CASEINCOMPLETE
Warns that inside a case statement there is a stimulus pattern for which
@@ -1303,12 +1526,52 @@ signal before it is implicitly declared by a cell, and can lead to dangling
nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for
Emacs, available from L<http://www.veripool.com/>
=item IMPURE
Warns that a task or function that has been marked with /*verilator
no_inline_task*/ references variables that are not local to the task.
Verilator cannot schedule these variables correctly.
=item MULTIDRIVEN
Warns that the specified signal comes from multiple always blocks. This is
often unsupported by synthesis tools, and is considered bad style. It will
also cause longer runtimes due to reduced optimizations.
=item MULTITOP
Error that there are multiple top level modules, that is modules not
instantiated by any other module. Verilator only supports a single top
level, if you need more, create a module that wraps all of the top modules.
Often this error is because some low level cell is being read in, but is
not really needed. The best solution is to insure that each module is in a
unique file by the same name. Otherwise, make sure all library files are
read in as libraries with -v, instead of automatically with -y.
=item TASKNSVAR
Error when a call to a task or function has a output from that task tied to
a non-simple signal. Instead connect the task output to a temporary signal
of the appropriate width, and use that signal to set the appropriate
expression as the next statement. For example:
task foo; output sig; ... endtask
always @* begin
foo(bus_we_select_from[2]); // Will get TASKNSVAR error
end
Change this to:
reg foo_temp_out;
always @* begin
foo(foo_temp_out);
bus_we_select_from[2] = foo_temp_out;
end
Verilator doesn't do this conversion for you, as some more complicated
cases would result in simulator mismatches.
=item UNDRIVEN
Warns that the specified signal is never sourced.
@@ -1334,11 +1597,11 @@ may be only one particular usage of a multiply instantiated block. The
construct should be cleaned up to improve runtime; two times better
performance may be possible by fixing these warnings.
Unlike UNOPT this occurs after netlist flattening, and indicates a more
basic problem, as the less obvious case described under UNOPT does not
apply.
Unlike the UNOPT warning, this occurs after netlist flattening, and
indicates a more basic problem, as the less obvious case described under
UNOPT does not apply.
Often this is caused by logic that isn't truly circular as viewed by
Often UNOPTFLAT is caused by logic that isn't truly circular as viewed by
synthesis which analyzes interconnection per-bit, but is circular to
simulation which analyzes per-bus:
@@ -1346,10 +1609,36 @@ simulation which analyzes per-bus:
This statement needs to be evaluated multiple times, as a change in
"shift_in" requires "x" to be computed 3 times before it becomes stable.
This is because a change in "x" requires "x" itself to change value, which
causes the warning.
For significantly better performance, split this into 2 separate signals:
wire [2:1] x_21 = x[1:0];
wire [0:0] x_0 = shift_in;
wire [2:0] xout = {x[1:0],shift_in};
and change all receiving logic to instead receive "xout". Alternatively,
change it to
wire [2:0] x = {xin[1:0],shift_in};
and change all driving logic to instead drive "xin".
With this change this assignment needs to be evaluated only once. These
sort of changes may also speed up your traditional event driven simulator,
as it will result in fewer events per cycle.
The most complicated UNOPTFLAT path we've seen was due to low bits of a bus
being generated from an always statement that consumed high bits of the
same bus processed by another series of always blocks. The fix is the
same; split it into two separate signals generated from each block.
The UNOPTFLAT warning may also be due to clock enables, identified from the
reported path going through a clock gating cell. To fix these, use the
clock_enable meta comment described above.
The UNOPTFLAT warning may also occur where outputs from a block of logic
are independent, but occur in the same always block. To fix this, use the
isolate_assignments meta comment described above.
=item UNSIGNED
@@ -1406,19 +1695,25 @@ that is not yet supported in Verilator. See the Limitations chapter.
=item Verilated model didn't converge
Verilator sometimes has to evaluate combinatorial logic multiple times,
usually around code where a UNOPT warning was issued, but disabled. For
example:
usually around code where a UNOPTFLAT warning was issued, but disabled.
For example:
always @ (a) b=~a;
always @ (b) a=b
will toggle forever and thus the executable will give the didn't converge
error to prevent an infinite loop. To debug this, compile the Verilated
.cpp files with -DVL_DEBUG, then call Verilated::debug(1) in your main.cpp.
This will cause each module to print a message when it's invoked. From
that it should be obvious what routine(s) are part of the infinite loop.
Then in Gdb, add a break point at the routine entry point and "print *this"
on each loop so you can see what variables are changing each invocation.
error to prevent an infinite loop.
To debug this, run Verilator with --profile-cfuncs. Run make on the
generated files with "OPT=-DVL_DEBUG". Then call Verilated::debug(1) in
your main.cpp.
This will cause each change in a variable to print a message. Near the
bottom you'll see the code and variable that causes the problem. For the
program above:
CHANGE: filename.v:1: b
CHANGE: filename.v:2: a
=back
@@ -1453,18 +1748,38 @@ so your simulator shouldn't have to be -- and Verilator is closer to the
synthesis interpretation, so this is a good thing for getting working
silicon.
=item How do I generate waveforms (traces)?
=item How do I generate waveforms (traces) in C++?
See the next question for SystemC mode.
Add the --trace switch to Verilator, and make sure the SystemPerl package
is installed (SystemC itself isn't required for C++ only tracing.) In your
top level C code, call Verilated::traceEverOn(true).
is installed. SystemC itself does not need to be installed for C++ only
tracing. You do not even need to compile SystemPerl; you may simply untar
the SystemPerl kit and point the SYSTEMPERL environment variable to the
untarred directory.
Then, in SystemC mode, create a SpTraceFile object. For an example, see
the call to SpTraceFile in the test_sp/sc_main.cpp file of the
distribution.
In your top level C code, call Verilated::traceEverOn(true). Then create a
SpTraceVcdC object. For an example, see the call to SpTraceVcdC in the
test_c/sc_main.cpp file of the distribution.
Or, in C++ mode, create a SpTraceVcdCFile object, and see
test_c/sim_main.cpp.
You also need to compile SpTraceVcdC.cpp and add it to your link. This is
done for you if using the Verilator --exe flag.
=item How do I generate waveforms (traces) in SystemC?
Add the --trace switch to Verilator, and make sure the SystemPerl package
is installed.
In your top level C sc_main code, call Verilated::traceEverOn(true). Then
create a SpTraceFile object as you would create a normal SystemC trace
file. For an example, see the call to SpTraceFile in the
test_sp/sc_main.cpp file of the distribution.
=item How do I view waveforms (traces)?
Verilator makes standard VCD (Value Change Dump) files. They are viewable
with the public domain Dinotrace or GtkWave programs, or any of the many
commercial offerings.
=item Where is the translate_off command? (How do I ignore a construct?)
@@ -1483,6 +1798,16 @@ Call Verilated::assertOn(false) before you first call the model, then turn
it back on after reset. It defaults to true. When false, all assertions
controlled by --assert are disabled.
=item Why do I get "undefined reference to `sc_time_stamp()'"?
In C++ (non SystemC) code you need to define this function so that the
simulator knows the current time. See the "CONNECTING TO C++" examples.
=item Why do I get "undefined reference to `VL_RAND_RESET_I' or `Verilated::...'"?
You need to link your compiled Verilated code against the verilated.cpp
file found in the include directory of the Verilator kit.
=item Is the PLI supported?
No.
@@ -1493,6 +1818,12 @@ complex, since Verilator emits standard C++ code, you can simply write your
own C++ routines that can access and modify signal values without needing
any PLI interface code, and call it with $c("{any_c++_statement}").
=item How do I make a Verilog module that contain a C++ object?
You need to add the object to the structure that Verilator creates, then
use $c to call a method inside your object. The
test_regress/t/t_extend_class files show an example of how to do this.
=item How do I get faster build times?
Between GCC 3.0 to 3.3, each compiled progressively slower, thus if you can
@@ -1542,6 +1873,25 @@ In this example, clk is a bool you can read or set as any other variable.
The value of normal signals may be set, though clocks shouldn't be changed
by your code or you'll get strange results.
=item Should a module be in Verilog or SystemC?
Sometimes there is a block that just interconnects cells, and have a choice
as to if you write it in Verilog or SystemC. Everything else being equal,
best performance is when Verilator sees all of the design. So, look at the
hierarchy of your design, labeling cells as to if they are SystemC or
Verilog. Then:
A module with only SystemC cells below must be SystemC.
A module with a mix of Verilog and SystemC cells below must be SystemC. (As
Verilator cannot connect to lower-level SystemC cells.)
A module with only Verilog cells below can be either, but for best
performance should be Verilog. (The exception is if you have a design that
is instantiated many times; in this case Verilating one of the lower
modules and instantiating that Verilated cells multiple times into a
SystemC module *may* be faster.)
=back
=head1 BUGS
@@ -1566,7 +1916,7 @@ outputs. Now, the following should fail:
cd test_regress
t/t_BUG.pl
Finally, Mail the bug report to C<[email protected]>
Finally, Mail the bug report to C<[email protected]>.
=head1 HISTORY
@@ -1593,8 +1943,8 @@ scratch in C++. This added many optimizations, yielding about a 2-5x
performance gain.
Currently, various language features and performance enhancements are added
as the need arises. Verilator is now about 2x faster then in 2002, and
as fast as most popular commercial simulators.
as the need arises. Verilator is now about 2x faster then in 2002, and is
faster then many popular commercial simulators.
=head1 CONTRIBUTORS
@@ -1621,7 +1971,7 @@ Eugene Weber, Leon Wildman, and Mat Zeno.
The latest version is available from L<http://www.veripool.com/>.
Copyright 2003-2006 by Wilson Snyder. Verilator is free software; you can
Copyright 2003-2007 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 or the Perl Artistic License.
+6 -3
View File
@@ -4,7 +4,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
# $Id$
######################################################################
#
# Copyright 2005-2006 by Wilson Snyder <[email protected]>. This
# Copyright 2005-2007 by Wilson Snyder <[email protected]>. This
# program is free software; you can redistribute it and/or modify it under
# the terms of either the GNU Lesser General Public License or the Perl
# Artistic License.
@@ -46,6 +46,9 @@ if (! GetOptions (
defined $Opt_A or die "%Error: No old diff filename\n";
defined $Opt_B or die "%Error: No new diff filename\n";
-e $Opt_A or die "%Error: No old diff filename found: $Opt_A\n";
-e $Opt_B or die "%Error: No new diff filename found: $Opt_B\n";
if (-d $Opt_A && -d $Opt_B) {
diff_dir ($Opt_A, $Opt_B);
} elsif (-f $Opt_A && -f $Opt_B) {
@@ -176,7 +179,7 @@ Displays this message and program version and exits.
The latest version is available from L<http://www.veripool.com/>.
Copyright 2005-2006 by Wilson Snyder. This package is free software; you
Copyright 2005-2007 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 or the Perl Artistic License.
@@ -192,5 +195,5 @@ C<verilator>
######################################################################
### Local Variables:
### compile-command: "$V4/bin/verilator_difftree ~/SandBox/workwsnyder/verilator/test_c/obj_dir/V*_03_*.tree $V4/test_c/obj_dir/V*_03_*.tree"
### compile-command: "$V4/bin/verilator_difftree $V4/test_c/obj_dir/V*_03_*.tree $V4N/test_c/obj_dir/V*_03_*.tree"
### End:
+1 -1
View File
@@ -4,7 +4,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
# $Id$
# DESCRIPTION: Print include statements for each ARGV
#
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
######################################################################
+5 -3
View File
@@ -1,12 +1,12 @@
dnl $Id$
dnl DESCRIPTION: Process this file with autoconf to produce a configure script.
dnl Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
dnl Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
dnl redistribute it and/or modify it under the terms of either the GNU
dnl General Public License or the Perl Artistic License.
AC_REVISION($Revision$)dnl
AC_INIT(src/Verilator.cpp)
AC_CONFIG_HEADER(src/config.h)
AC_CONFIG_HEADER(src/config_build.h)
dnl Special Substitutions
@@ -16,13 +16,15 @@ AC_PROG_CC
AC_PROG_CXX
AC_PROG_INSTALL
AC_PATH_PROG(PERL,perl)
AC_PATH_PROG(YACC,bison)
AC_PATH_PROG(LEX,flex)
dnl Checks for libraries.
dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(fcntl.h unistd.h sys/file.h sys/time.h sys/un.h math.h stdint.h mingw/stdint.h)
AC_CHECK_HEADERS(fcntl.h unistd.h inttypes.h sys/file.h sys/time.h sys/un.h math.h stdint.h mingw/stdint.h)
dnl Checks for typedefs, structures
AC_CHECK_TYPE(size_t,unsigned int)
+109 -1
View File
@@ -1,7 +1,7 @@
// $Id$ -*- C++ -*-
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -24,6 +24,7 @@
#include "verilated.h"
#include <string.h>
#include <ctype.h>
#define VL_VALUE_STRING_MAX_WIDTH 1024 ///< Max static char array for VL_VALUE_STRING
@@ -238,6 +239,113 @@ QData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) {
return VL_CVT_FP_Q(fopen(filenamez,modez));
}
void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int,
QData ofilename, void* memp, IData start, IData end) {
IData fnw[2]; VL_SET_WQ(fnw, ofilename);
return VL_READMEM_W(hex,width,depth,array_lsb,2, fnw,memp,start,end);
}
void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
WDataInP ofilenamep, void* memp, IData start, IData end) {
char ofilenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
_VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, ofilenamez, ofilenamep);
FILE* fp = fopen(ofilenamez, "r");
if (!fp) {
// We don't report the Verilog source filename as it slow to have to pass it down
vl_fatal (ofilenamez, 0, "", "$readmem file not found");
return;
}
// Prep for reading
IData addr = start;
int linenum = 1;
bool innum = false;
bool ignore_to_eol = false;
bool ignore_to_cmt = false;
bool needinc = false;
bool reading_addr = false;
int lastc = ' ';
// Read the data
// We process a character at a time, as then we don't need to deal
// with changing buffer sizes dynamically, etc.
while (1) {
int c = fgetc(fp);
if (c==EOF) break;
//printf("%d: Got '%c' Addr%x IN%d IgE%d IgC%d ninc%d\n", linenum, c, addr, innum, ignore_to_eol, ignore_to_cmt, needinc);
if (c=='\n') { linenum++; ignore_to_eol=false; if (innum) reading_addr=false; innum=false; }
else if (c=='\t' || c==' ' || c=='\r' || c=='\f') { if (innum) reading_addr=false; innum=false; }
// Skip // comments and detect /* comments
else if (ignore_to_cmt && lastc=='*' && c=='/') {
ignore_to_cmt = false; if (innum) reading_addr=false; innum=false;
} else if (!ignore_to_eol && !ignore_to_cmt) {
if (lastc=='/' && c=='*') { ignore_to_cmt = true; }
else if (lastc=='/' && c=='/') { ignore_to_eol = true; }
else if (c=='/') {} // Part of /* or //
else if (c=='_') {}
else if (c=='@') { reading_addr = true; innum=false; needinc=false; }
// Check for hex or binary digits as file format requests
else if (isxdigit(c)) {
c = tolower(c);
int value = (c >= 'a' ? (c-'a'+10) : (c-'0'));
if (!innum) { // Prep for next number
if (needinc) { addr++; needinc=false; }
}
if (reading_addr) {
// Decode @ addresses
if (!innum) addr=0;
addr = (addr<<4) + value;
} else {
needinc = true;
//printf(" Value width=%d @%x = %c\n", width, addr, c);
if (addr >= (IData)(depth+array_lsb) || addr < (IData)(array_lsb)) {
vl_fatal (ofilenamez, linenum, "", "$readmem file address beyond bounds of array");
} else {
int entry = addr - array_lsb;
QData shift = hex ? VL_ULL(4) : VL_ULL(1);
// Shift value in
if (width<=8) {
CData* datap = &((CData*)(memp))[entry];
if (!innum) { *datap = 0; }
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
} else if (width<=16) {
SData* datap = &((SData*)(memp))[entry];
if (!innum) { *datap = 0; }
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
} else if (width<=VL_WORDSIZE) {
IData* datap = &((IData*)(memp))[entry];
if (!innum) { *datap = 0; }
*datap = ((*datap << shift) + value) & VL_MASK_I(width);
} else if (width<=VL_QUADSIZE) {
QData* datap = &((QData*)(memp))[entry];
if (!innum) { *datap = 0; }
*datap = ((*datap << (QData)(shift)) + (QData)(value)) & VL_MASK_Q(width);
} else {
WDataOutP datap = &((WDataOutP)(memp))[ entry*VL_WORDS_I(width) ];
if (!innum) { VL_ZERO_RESET_W(width, datap); }
_VL_SHIFTL_INPLACE_W(width, datap, shift);
datap[0] |= value;
}
if (value>=(1<<shift)) {
vl_fatal (ofilenamez, linenum, "", "$readmemb (binary) file contains hex characters");
}
}
}
innum = true;
}
else {
vl_fatal (ofilenamez, linenum, "", "$readmem file syntax error");
}
}
lastc = c;
}
if (needinc) { addr++; needinc=false; }
// Final checks
fclose(fp);
if (end != (IData)(~ VL_ULL(0)) && addr != (end+1)) {
vl_fatal (ofilenamez, linenum, "", "$readmem file ended before specified ending-address");
}
}
//===========================================================================
// Verilated:: Methods
+75 -9
View File
@@ -1,7 +1,7 @@
// $Id$ -*- C++ -*-
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -40,11 +40,11 @@ using namespace std;
//=========================================================================
// Basic types
typedef uint8_t CData; ///< Verilated data, 1-8 bits
typedef uint16_t SData; ///< Verilated data, 9-16 bits
typedef uint32_t IData; ///< Verilated data, 17-32 bits
typedef vluint64_t QData; ///< Verilated data, 33-64 bits
typedef uint32_t WData; ///< Verilated data, >64 bits, as an array
typedef vluint8_t CData; ///< Verilated data, 1-8 bits
typedef vluint16_t SData; ///< Verilated data, 9-16 bits
typedef vluint32_t IData; ///< Verilated data, 17-32 bits
typedef vluint64_t QData; ///< Verilated data, 33-64 bits
typedef vluint32_t WData; ///< Verilated data, >64 bits, as an array
typedef const WData* WDataInP; ///< Array input to a function
typedef WData* WDataOutP; ///< Array output from a function
@@ -115,6 +115,13 @@ public:
#endif
//=========================================================================
// Functions overridable by user defines
#ifndef VL_PRINTF
# define VL_PRINTF printf ///< Print ala printf; may redefine if desired
#endif
//===========================================================================
/// Verilator global static information class
@@ -187,9 +194,17 @@ inline const char* VL_VALUE_FORMATTED_I(int obits, char fmt, bool drop0, IData l
}
/// File I/O
extern QData VL_FOPEN_WI(int fnwords, WDataInP filename, IData mode);
extern QData VL_FOPEN_QI(QData filename, IData mode);
inline QData VL_FOPEN_II(IData filename, IData mode) { return VL_FOPEN_QI(filename,mode); }
extern QData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
extern QData VL_FOPEN_QI(QData ofilename, IData mode);
inline QData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); }
extern void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
WDataInP ofilename, void* memp, IData start, IData end);
extern void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int fnwords,
QData ofilename, void* memp, IData start, IData end);
inline void VL_READMEM_I(bool hex, int width, int depth, int array_lsb, int fnwords,
IData ofilename, void* memp, IData start, IData end) {
VL_READMEM_Q(hex, width,depth,array_lsb,fnwords, ofilename,memp,start,end); }
//=========================================================================
// Base macros
@@ -219,6 +234,13 @@ static inline QData VL_CVT_FP_Q(FILE* fp) { union { FILE* fp; QData q; } u; u.q
static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) { return (-((lhs)&(1UL<<(lbits-1)))); }
static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) { return (-((lhs)&(VL_ULL(1)<<(lbits-1)))); }
// Debugging prints
static inline void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp) {
printf(" Data: w%d: ", lbits);
for (int i=VL_WORDS_I(lbits)-1; i>=0; i--) { printf("%08x ",iwp[i]); }
printf("\n");
}
//=========================================================================
// Pli macros
@@ -1028,6 +1050,18 @@ static inline WDataOutP VL_CONCAT_WWW(int obits,int lbits,int rbits,WDataOutP ow
//===================================================================
// Shifts
// Static shift, used by internal functions
// The output is the same as the input - it overlaps!
static inline void _VL_SHIFTL_INPLACE_W(int obits,WDataOutP iowp,IData rd/*1 or 4*/) {
int words = VL_WORDS_I(obits);
IData linsmask = VL_MASK_I(rd);
for (int i=words-1; i>=1; i--) {
iowp[i] = ((iowp[i]<<rd) & ~linsmask) | ((iowp[i-1] >> (32-rd)) & linsmask);
}
iowp[0] = ((iowp[0]<<rd) & ~linsmask);
iowp[VL_WORDS_I(obits)-1] &= VL_MASK_I(obits);
}
// EMIT_RULE: VL_SHIFTL: oclean=lclean; rclean==clean;
// Important: Unlike most other funcs, the shift might well be a computed
// expression. Thus consider this when optimizing. (And perhaps have 2 funcs?)
@@ -1321,6 +1355,38 @@ static inline WDataOutP VL_CONST_W_16X(int obits, WDataOutP o,
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
_END(obits,16); }
static inline WDataOutP VL_CONST_W_17X(int obits, WDataOutP o,
I d16,
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
o[16]=d16;
_END(obits,17); }
static inline WDataOutP VL_CONST_W_18X(int obits, WDataOutP o,
I d17,I d16,
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
o[16]=d16; o[17]=d17;
_END(obits,18); }
static inline WDataOutP VL_CONST_W_19X(int obits, WDataOutP o,
I d18,I d17,I d16,
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
o[16]=d16; o[17]=d17; o[18]=d18;
_END(obits,19); }
static inline WDataOutP VL_CONST_W_20X(int obits, WDataOutP o,
I d19,I d18,I d17,I d16,
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
o[16]=d16; o[17]=d17; o[18]=d18; o[19]=d19;
_END(obits,20); }
static inline WDataOutP VL_CONST_W_24X(int obits, WDataOutP o,
I d23,I d22,I d21,I d20,I d19,I d18,I d17,I d16,
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
+8 -5
View File
@@ -2,7 +2,7 @@
######################################################################
# DESCRIPTION: Makefile commands for all verilated target files
#
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
######################################################################
@@ -48,6 +48,9 @@ VPATH += $(VERILATOR_ROOT)/include
#OPT = -ggdb -DPRINTINITSTR
CPPFLAGS += $(OPT)
CPPFLAGS += $(M32)
LDFLAGS += $(M32)
# See the benchmarking section of bin/verilator.
# Support class optimizations. This includes the tracing and symbol table.
# SystemC takes minutes to optimize, thus it is off by default.
@@ -81,8 +84,8 @@ endif
##### SystemPerl builds
ifeq ($(VM_SP),1)
CPPFLAGS += -I$(SYSTEMPERL) -I$(SYSTEMPERL)/src -DSYSTEMPERL
VPATH += $(SYSTEMPERL) $(SYSTEMPERL)/src
CPPFLAGS += -I$(SYSTEMPERL)/src -DSYSTEMPERL
VPATH += $(SYSTEMPERL)/src
VK_CLASSES_SP = $(addsuffix .sp, $(VM_CLASSES))
@@ -101,8 +104,8 @@ endif
ifeq ($(VM_PCLI),1)
LIBS += -lm -lstdc++
ifeq ($(VM_TRACE),1)
CPPFLAGS += -I$(SYSTEMPERL) -I$(SYSTEMPERL)/src
VPATH += $(SYSTEMPERL) $(SYSTEMPERL)/src
CPPFLAGS += -I$(SYSTEMPERL)/src
VPATH += $(SYSTEMPERL)/src
endif
endif
+1 -1
View File
@@ -5,7 +5,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
+32 -16
View File
@@ -1,7 +1,7 @@
// $Id$ -*- C++ -*-
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -15,9 +15,11 @@
/// \file
/// \brief Verilator: Common include for OS portability (verilated & verilator)
///
/// This header is used by both verilated code, and the verilator
/// program itself Code needed by only one goes into verilated.h or
/// config.h.in respectively.
/// This header is used by both the Verilator source code (run on the
/// build and host system), and the Verilated output (run on the target
/// system). Code needed by only the host system goes into
/// config_build.h.in, code needed by Verilated code only goes into
/// verilated.h, and code needed by both goes here (verilatedos.h).
///
/// Code available from: http://www.veripool.com/verilator
///
@@ -37,6 +39,8 @@
# define VL_ATTR_UNUSED __attribute__ ((unused))
# define VL_LIKELY(x) __builtin_expect(!!(x), 1)
# define VL_UNLIKELY(x) __builtin_expect(!!(x), 0)
# define VL_PREFETCH_RD(p) __builtin_prefetch((p),0)
# define VL_PREFETCH_RW(p) __builtin_prefetch((p),1)
#else
# define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking
# define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment
@@ -44,6 +48,8 @@
# define VL_ATTR_UNUSED ///< Function that may be never used
# define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true then false
# define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false then true
# define VL_PREFETCH_RD(p) ///< Prefetch data with read intent
# define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent
#endif
#ifdef VL_THREADED
@@ -68,24 +74,34 @@
#ifdef VL_UINTS_DEFINED
#elif defined(__CYGWIN__)
# include <stdint.h>
typedef unsigned char uint8_t; ///< 8-bit basic type
typedef unsigned short int uint16_t; ///< 16-bit basic type
typedef unsigned long uint32_t; ///< 32-bit basic type
typedef unsigned long long vluint64_t; ///< 64-bit basic type
typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility)
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility)
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
typedef long vlsint32_t; ///< 32-bit signed type
typedef unsigned long vluint32_t; ///< 32-bit unsigned type
typedef long long vlsint64_t; ///< 64-bit signed type
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
#elif defined(_WIN32)
typedef unsigned char uint8_t; ///< 8-bit basic type
typedef unsigned short int uint16_t; ///< 16-bit basic type
typedef unsigned int uint32_t; ///< 32-bit basic type
typedef unsigned __int64 vluint64_t; ///< 64-bit basic type
typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility)
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility)
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
typedef int vlsint32_t; ///< 32-bit signed type
typedef unsigned int vluint32_t; ///< 32-bit unsigned type
typedef __int64 vlsint64_t; ///< 64-bit signed type
#else // Linux or compliant Unix flavors
# include <stdint.h>
typedef unsigned long long vluint64_t; ///< 64-bit basic type
typedef long vlsint32_t; ///< 32-bit signed type
typedef unsigned __int64 vluint64_t; ///< 64-bit unsigned type
#else // Linux or compliant Unix flavors, -m64
# include <stdint.h> // Linux and most flavors
# include <inttypes.h> // Solaris
typedef uint8_t vluint8_t; ///< 32-bit unsigned type
typedef uint16_t vluint16_t; ///< 32-bit unsigned type
typedef int vlsint32_t; ///< 32-bit signed type
typedef uint32_t vluint32_t; ///< 32-bit signed type
typedef long long vlsint64_t; ///< 64-bit signed type
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
#endif
//=========================================================================
+174
View File
@@ -0,0 +1,174 @@
#!/usr/bin/perl -w
# $Id$
######################################################################
#
# Copyright 2005-2007 by Wilson Snyder <[email protected]>. This
# program is free software; you can redistribute it and/or modify it under
# the terms of either the GNU Lesser General Public License or the Perl
# Artistic License.
#
# 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.
#
######################################################################
require 5.006_001;
use Getopt::Long;
use IO::File;
use Pod::Usage;
use Data::Dumper; $Data::Dumper::Indent=1;
use strict;
use vars qw ($Debug);
#======================================================================
our @Header;
our %Vertexes;
our @Edges;
our %Edges;
#======================================================================
# main
$Debug = 0;
my $opt_filename;
autoflush STDOUT 1;
autoflush STDERR 1;
if (! GetOptions (
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
)) {
usage();
}
dotread ($opt_filename);
cwrite ("graph_export.cpp");
#----------------------------------------------------------------------
sub usage {
print '$Id$ ', "\n";
pod2usage(-verbose=>2, -exitval => 2);
exit (1);
}
sub debug {
$Debug = 1;
}
sub parameter {
my $param = shift;
if (!$opt_filename) {
$opt_filename = $param;
} else {
die "%Error: Unknown parameter: $param\n";
}
}
#######################################################################
sub dotread {
my $filename = shift;
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
my $header = 1;
my $vnum = 0;
while (defined (my $line = $fh->getline)) {
if ($line =~ /^\t([a-zA-Z0-9_]+)\t(.*)$/) {
next if $1 eq 'nTITLE';
$header = 0;
$Vertexes{$1} = {num => $vnum++,
line => $line,
name => $1,};
}
elsif ($line =~ /^\t([a-zA-Z0-9_]+)\s+->\s+([a-zA-Z0-9_]+)\s+(.*)$/) {
my $from=$1; my $to=$2;
my $weight = 1; $weight = $1 if $line =~ /weight=(\d+)/;
my $cutable = undef; $cutable = $1 if $line =~ /style=(\S+)/;
my $edge = {num => $vnum++,
line => $line,
weight => $weight,
cutable => $cutable,
from => $from,
to => $to,};
push @Edges, $edge;
$Edges{$from}{$to} = $edge;
}
elsif ($header) {
push @Header, $line;
print "IGNORE: $line";
}
}
}
#######################################################################
sub cwrite {
my $filename = shift;
my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,";
$fh->print("void V3GraphTestImport::dotImport() {\n");
$fh->print(" DfaGraph* gp = &m_graph;\n");
foreach my $ver (sort {$a->{num} <=> $b->{num}} (values %Vertexes)) {
$fh->printf(" V3GraphTestVertex* %s = new V3GraphTestVertex(gp, \"%s\"); if (%s) {}\n",
$ver->{name}, $ver->{name}, $ver->{name});
}
$fh->print("\n");
foreach my $edge (@Edges) {
$fh->printf(" new V3GraphEdge(gp, %s, %s, %s, %s);\n",
$edge->{from}, $edge->{to},
$edge->{weight}, $edge->{cutable}?"true":"false");
}
$fh->print("}\n");
}
#######################################################################
__END__
=pod
=head1 NAME
dot_importer - Take graph .dot file and convert into .cpp file
=head1 SYNOPSIS
dot_importer a.dot
=head1 DESCRIPTION
Dot_importer takes a graphvis .dot file and converts into .cpp file. This
.cpp file is then manually included in V3GraphTest.cpp to verify various
sub-algorithms.
=head1 ARGUMENTS
=over 4
=item --help
Displays this message and program version and exits.
=back
=head1 DISTRIBUTION
Copyright 2005-2007 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 or the Perl Artistic License.
=head1 AUTHORS
Wilson Snyder <[email protected]>
=head1 SEE ALSO
=cut
######################################################################
### Local Variables:
### compile-command: "./dot_importer | tee ~/d/a.dot"
### End:
+2 -2
View File
@@ -2,7 +2,7 @@
# $Id$
######################################################################
#
# Copyright 2005-2006 by Wilson Snyder <[email protected]>. This
# Copyright 2005-2007 by Wilson Snyder <[email protected]>. This
# program is free software; you can redistribute it and/or modify it under
# the terms of either the GNU Lesser General Public License or the Perl
# Artistic License.
@@ -197,7 +197,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION
Copyright 2005-2006 by Wilson Snyder. This package is free software; you
Copyright 2005-2007 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 or the Perl Artistic License.
+2 -2
View File
@@ -2,7 +2,7 @@
# $Id$
######################################################################
#
# Copyright 2005-2006 by Wilson Snyder <[email protected]>. This
# Copyright 2005-2007 by Wilson Snyder <[email protected]>. This
# program is free software; you can redistribute it and/or modify it under
# the terms of either the GNU Lesser General Public License or the Perl
# Artistic License.
@@ -344,7 +344,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION
Copyright 2005-2006 by Wilson Snyder. This package is free software; you
Copyright 2005-2007 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 or the Perl Artistic License.
+1 -1
View File
@@ -27,7 +27,7 @@ This is the Verilator Package.
@node Copyright, Description, Top, Top
@section Copyright
This package is Copyright 2003-2006 by Wilson Snyder @email{wsnyder@@wsnyder.org}.
This package is Copyright 2003-2007 by Wilson Snyder @email{wsnyder@@wsnyder.org}.
You may distribute under the terms of either the GNU General Public License
or the Artistic License, as specified in the Perl README file.
+1 -1
View File
@@ -1,5 +1,5 @@
*.old
config.h
config_build.h
Makefile
Makefile_obj
.objcache*
+4 -1
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
#
@@ -85,3 +85,6 @@ clean mostlyclean distclean maintainer-clean::
-rm -f *__gen*
-rm -f *.yy.* y.output y.tab.[cho] *_test
-rm -f .objcache*
distclean maintainer-clean::
-rm -f Makefile Makefile_obj config_build.h
+10 -8
View File
@@ -7,7 +7,7 @@
#
#*****************************************************************************
#
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
#
@@ -28,6 +28,8 @@ CC = @CC@
CXX = @CXX@
LINK = @CXX@
LDFLAGS += @LDFLAGS@
#### End of system configuration section. ####
VPATH += . $(srcdir)
@@ -36,22 +38,20 @@ TGT = ../../verilator_bin
#################
ifeq ($(VL_DEBUG),)
# Optimize
LDFLAGS =
COPT = -O
else
# Debug
LDFLAGS =
COPT = -ggdb -DVL_DEBUG
# Debug & Profile:
#LDFLAGS = -pg -g
#LDFLAGS += -pg -g
#COPT = -ggdb -pg -g
endif
#################
LEX = flex
LEX = @LEX@
LFLAGS = -d
YACC = bison -y
YFLAGS = -d -v
YACC = @YACC@
YFLAGS = -y -d -v
#LIBS += -ldl
#CCMALLOC = /usr/local/lib/ccmalloc-gcc.o -lccmalloc -ldl
@@ -89,7 +89,6 @@ clean mostlyclean distclean maintainer-clean::
-rm -f obj_* .objcache*
distclean maintainer-clean:: clean
rm -f Makefile config.h
maintainer-clean::
@@ -143,6 +142,8 @@ RAW_OBJS = \
V3LinkCells.o \
V3LinkDot.o \
V3LinkLevel.o \
V3LinkLValue.o \
V3LinkParse.o \
V3LinkResolve.o \
V3Localize.o \
V3Name.o \
@@ -155,6 +156,7 @@ RAW_OBJS = \
V3Scope.o \
V3Signed.o \
V3Split.o \
V3SplitAs.o \
V3Stats.o \
V3StatsReport.o \
V3Subst.o \
+5 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -31,7 +31,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -298,8 +299,10 @@ private:
// OPTIMIZE: We could substitute a constant for things in the sense list, for example
// always (posedge RESET) { if (RESET).... } we know RESET is true.
// Summarize a long list of combo inputs as just "combo"
#ifndef __COVERITY__ // Else dead code on next line.
if (combo) nodep->sensesp()->addSensesp
(new AstSenItem(nodep->fileline(),AstSenItem::Combo()));
#endif
wantactivep = m_namer.getActive(nodep->fileline(), nodep->sensesp());
}
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3ACTIVE_H_
#define _V3ACTIVE_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -28,7 +28,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3ACTIVETOP_H_
#define _V3ACTIVETOP_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+92 -20
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -19,7 +19,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -46,28 +47,58 @@ private:
V3Double0 m_statAsCover; // Statistic tracking
V3Double0 m_statAsPsl; // Statistic tracking
V3Double0 m_statAsFull; // Statistic tracking
V3Double0 m_statAsSV; // Statistic tracking
// METHODS
AstNode* newFireAssert(AstNode* nodep, const string& message) {
AstNode* bodysp = new AstDisplay
(nodep->fileline(), '\0',
(string("[%0t] %%Error: ")+nodep->fileline()->filebasename()
+":"+cvtToStr(nodep->fileline()->lineno())
+": Assertion failed in %m"
+((message != "")?": ":"")+message
+"\\n"),
NULL,
new AstTime(nodep->fileline()));
bodysp->addNext(new AstStop (nodep->fileline()));
string assertDisplayMessage(AstNode* nodep, const string& prefix, const string& message) {
return (string("[%0t] "+prefix+": ")+nodep->fileline()->filebasename()
+":"+cvtToStr(nodep->fileline()->lineno())
+": Assertion failed in %m"
+((message != "")?": ":"")+message
+"\\n");
}
void replaceDisplay(AstDisplay* nodep, const string& prefix) {
nodep->displayType(AstDisplayType::WRITE);
nodep->text(assertDisplayMessage(nodep, prefix, nodep->text()));
AstNode* timesp = nodep->exprsp(); if (timesp) timesp->unlinkFrBack();
timesp = timesp->addNext(new AstTime(nodep->fileline()));
nodep->exprsp(timesp);
}
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.
bodysp = new AstIf (nodep->fileline(),
new AstCMath(nodep->fileline(), "Verilated::assertOn()", 1),
bodysp, NULL);
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(), V3Number(nodep->fileline(), 1, 0)))),
nodep, NULL);
}
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(), V3Number(nodep->fileline(), 1, 1)))
: (AstNode*)(new AstConst(nodep->fileline(), V3Number(nodep->fileline(), 1, 0)))),
nodep, NULL);
}
AstNode* newFireAssert(AstNode* nodep, const string& message) {
AstDisplay* dispp = new AstDisplay (nodep->fileline(), AstDisplayType::ERROR, message, NULL, NULL);
AstNode* bodysp = dispp;
replaceDisplay(dispp, "%%Error"); // Convert to standard DISPLAY format
bodysp->addNext(new AstStop (nodep->fileline()));
bodysp = newIfAssertOn(bodysp);
return bodysp;
}
void newAssertion(AstNode* nodep, AstNode* propp, AstSenTree* sentreep, const string& message) {
void newPslAssertion(AstNode* nodep, AstNode* propp, AstSenTree* sentreep, const string& message) {
propp->unlinkFrBack();
sentreep->unlinkFrBack();
//
@@ -88,7 +119,7 @@ private:
bodysp = newFireAssert(nodep,message);
// We assert the property is always true... so report when it fails
// (Note this is opposite the behavior of coverage statements.)
//FIX 'never' operator: not hold in current or any future cycle
// Need: 'never' operator: not hold in current or any future cycle
propp = new AstLogNot (nodep->fileline(), propp);
} else {
nodep->v3fatalSrc("Unknown node type");
@@ -113,6 +144,28 @@ private:
pushDeletep(nodep); nodep=NULL;
}
void newVAssertion(AstVAssert* nodep, AstNode* propp) {
propp->unlinkFrBackWithNext();
AstNode* passsp = nodep->passsp(); if (passsp) passsp->unlinkFrBackWithNext();
AstNode* failsp = nodep->failsp(); if (failsp) failsp->unlinkFrBackWithNext();
//
if (nodep->castVAssert()) {
if (passsp) passsp = newIfAssertOn(passsp);
if (failsp) failsp = newIfAssertOn(failsp);
} else {
nodep->v3fatalSrc("Unknown node type");
}
AstIf* ifp = new AstIf (nodep->fileline(), propp, passsp, failsp);
AstNode* newp = ifp;
if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::UNLIKELY);
//
// Install it
nodep->replaceWith(newp);
// Bye
pushDeletep(nodep); nodep=NULL;
}
// VISITORS //========== Case assertions
virtual void visit(AstCase* nodep, AstNUser*) {
nodep->iterateChildren(*this);
@@ -162,16 +215,34 @@ private:
}
// VISITORS //========== Statements
virtual void visit(AstDisplay* nodep, AstNUser*) {
nodep->iterateChildren(*this);
// Replace the special types with standard text
if (nodep->displayType()==AstDisplayType::INFO) {
replaceDisplay(nodep, "-Info");
} else if (nodep->displayType()==AstDisplayType::WARNING) {
replaceDisplay(nodep, "%%Warning");
} else if (nodep->displayType()==AstDisplayType::ERROR
|| nodep->displayType()==AstDisplayType::FATAL) {
replaceDisplay(nodep, "%%Error");
}
}
virtual void visit(AstPslCover* nodep, AstNUser*) {
nodep->iterateChildren(*this);
newAssertion(nodep, nodep->propp(), nodep->sentreep(), nodep->name()); nodep=NULL;
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(), nodep->name()); nodep=NULL;
m_statAsCover++;
}
virtual void visit(AstPslAssert* nodep, AstNUser*) {
nodep->iterateChildren(*this);
newAssertion(nodep, nodep->propp(), nodep->sentreep(), nodep->name()); nodep=NULL;
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(), nodep->name()); nodep=NULL;
m_statAsPsl++;
}
virtual void visit(AstVAssert* nodep, AstNUser*) {
nodep->iterateChildren(*this);
newVAssertion(nodep, nodep->propp()); nodep=NULL;
m_statAsSV++;
}
virtual void visit(AstModule* nodep, AstNUser*) {
m_modp = nodep;
@@ -202,6 +273,7 @@ public:
}
virtual ~AssertVisitor() {
V3Stats::addStat("Assertions, PSL asserts", m_statAsPsl);
V3Stats::addStat("Assertions, SystemVerilog asserts", m_statAsSV);
V3Stats::addStat("Assertions, cover statements", m_statAsCover);
V3Stats::addStat("Assertions, full/parallel case", m_statAsFull);
}
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3ASSERT_H_
#define _V3ASSERT_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -22,7 +22,8 @@
// Attach clocks to each assertion
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3ASSERTPRE_H_
#define _V3ASSERTPRE_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+23 -9
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -33,8 +33,8 @@
//======================================================================
// Statics
uint64_t AstNode::s_editCntGbl=0;
uint64_t AstNode::s_editCntLast=0;
vluint64_t AstNode::s_editCntGbl=0;
vluint64_t AstNode::s_editCntLast=0;
// To allow for fast clearing of all user pointers, we keep a "timestamp"
// along with each userp, and thus by bumping this count we can make it look
@@ -92,17 +92,29 @@ string AstNode::shortName() const {
return pretty;
}
string AstNode::prettyName(const string& namein) {
string AstNode::dedotName(const string& namein) {
string pretty = namein;
string::size_type pos;
while ((pos=pretty.find("__DOT__")) != string::npos) {
pretty.replace(pos, 7, ".");
}
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
return pretty;
}
string AstNode::prettyName(const string& namein) {
string pretty = namein;
string::size_type pos;
while ((pos=pretty.find("__BRA__")) != string::npos) {
pretty.replace(pos, 7, "[");
}
while ((pos=pretty.find("__KET__")) != string::npos) {
pretty.replace(pos, 7, "]");
}
while ((pos=pretty.find("__PVT__")) != string::npos) {
pretty.replace(pos, 7, "");
}
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
return pretty;
return AstNode::dedotName(pretty);
}
int AstNode::widthPow2() const {
@@ -777,21 +789,23 @@ void AstNode::dumpTreeFile(const string& filename, bool append) {
if (logsp->fail()) v3fatalSrc("Can't write "<<filename);
*logsp<<"Tree Dump from <e"<<dec<<editCountLast()<<">";
*logsp<<" to <e"<<dec<<editCountGbl()<<">"<<endl;
if (editCountGbl()==editCountLast() && 0) { // Off, as messes up tree diffing
if (editCountGbl()==editCountLast() && 1) { // Off, as messes up tree diffing
*logsp<<endl;
*logsp<<"No changes since last dump!\n";
} else {
dumpTree(*logsp);
}
}
}
if (v3Global.opt.debugCheck() || v3Global.opt.dumpTree()) {
// Error check
checkTree();
// Broken isn't part of check tree because it can munge iterp's
// set by other steps if it is called in the middle of other operations
if (AstNetlist* netp=this->castNetlist()) V3Broken::brokenAll(netp);
// Next dump can indicate start from here
editCountSetLast();
}
// Next dump can indicate start from here
editCountSetLast();
}
void AstNode::v3errorEnd(ostringstream& str) {
+84 -18
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3AST_H_
#define _V3AST_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Number.h"
#include <vector>
@@ -57,6 +58,7 @@ public:
COVERAGE_BLOCK_OFF,
INLINE_MODULE,
NO_INLINE_MODULE,
NO_INLINE_TASK,
PUBLIC_MODULE,
PUBLIC_TASK
};
@@ -246,6 +248,61 @@ public:
inline bool operator== (AstBranchPred::en lhs, AstBranchPred rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstBranchPred rhs) { return os<<rhs.ascii(); }
//######################################################################
class AstDisplayType {
public:
enum en {
DISPLAY,
WRITE,
INFO,
ERROR,
WARNING,
FATAL
};
enum en m_e;
inline AstDisplayType () {};
inline AstDisplayType (en _e) : m_e(_e) {};
explicit inline AstDisplayType (int _e) : m_e(static_cast<en>(_e)) {};
operator en () const { return m_e; };
bool addNewline() const { return m_e!=WRITE; }
bool needScopeTracking() const { return m_e!=DISPLAY && m_e!=WRITE; }
const char* ascii() const {
static const char* names[] = {
"display","write","info","error","warning","fatal"};
return names[m_e];};
};
inline bool operator== (AstDisplayType lhs, AstDisplayType rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstDisplayType lhs, AstDisplayType::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstDisplayType::en lhs, AstDisplayType rhs) { return (lhs == rhs.m_e); }
//######################################################################
class AstParseRefExp {
public:
enum en {
NONE, // Used in V3LinkParse only
VAR_MEM,
VAR_ANY,
TASK,
FUNC,
_ENUM_END
};
enum en m_e;
inline AstParseRefExp() : m_e(NONE) {};
inline AstParseRefExp (en _e) : m_e(_e) {};
explicit inline AstParseRefExp (int _e) : m_e(static_cast<en>(_e)) {};
operator en () const { return m_e; };
const char* ascii() const {
static const char* names[] = {
"","VAR_MEM","VAR_ANY","TASK","FUNC"};
return names[m_e];};
};
inline bool operator== (AstParseRefExp lhs, AstParseRefExp rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstParseRefExp lhs, AstParseRefExp::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstParseRefExp::en lhs, AstParseRefExp rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstParseRefExp rhs) { return os<<rhs.ascii(); }
//######################################################################
// AstNUser - Generic pointer base class for AST User nodes.
// - Also used to allow parameter passing up/down iterate calls
@@ -391,9 +448,9 @@ private:
static int s_cloneCntGbl; // Count of which userp is set
FileLine* m_fileline; // Where it was declared
uint64_t m_editCount; // When it was last edited
static uint64_t s_editCntGbl;// Global edit counter
static uint64_t s_editCntLast;// Global edit counter, last value for printing * near node #s
vluint64_t m_editCount; // When it was last edited
static vluint64_t s_editCntGbl; // Global edit counter
static vluint64_t s_editCntLast;// Global edit counter, last value for printing * near node #s
// Attributes
bool m_signed; // Node is signed
@@ -476,6 +533,7 @@ public:
AstNode* op3p() const { return m_op3p; }
AstNode* op4p() const { return m_op4p; }
AstNode* clonep() const { return ((m_cloneCnt==s_cloneCntGbl)?m_clonep:NULL); }
AstNode* firstAbovep() const { return ((backp() && backp()->nextp()!=this) ? backp() : NULL); } // Returns NULL when second or later in list
bool brokeExists() const;
// CONSTRUCTORS
@@ -494,6 +552,7 @@ public:
virtual string name() const { return ""; }
virtual string verilogKwd() const { return ""; }
string shortName() const; // Name with __PVT__ removed for concatenating scopes
static string dedotName(const string& namein); // Name with dots removed
static string prettyName(const string& namein); // Name for printing out to the user
string prettyName() const { return prettyName(name()); }
FileLine* fileline() const { return m_fileline; }
@@ -539,10 +598,10 @@ public:
void user5(int val) { user5p(AstNUser::fromInt(val)); }
static void user5ClearTree() { s_user5CntGbl++; } // Clear userp()'s across the entire tree
uint64_t editCount() const { return m_editCount; }
vluint64_t editCount() const { return m_editCount; }
void editCountInc() { m_editCount = s_editCntGbl++; }
static uint64_t editCountLast() { return s_editCntLast; }
static uint64_t editCountGbl() { return s_editCntGbl; }
static vluint64_t editCountLast() { return s_editCntLast; }
static vluint64_t editCountGbl() { return s_editCntGbl; }
static void editCountSetLast() { s_editCntLast = editCountGbl(); }
// ACCESSORS for specific types
@@ -585,6 +644,7 @@ public:
virtual int instrCount() const { return 0; }
virtual V3Hash sameHash() const { return V3Hash(V3Hash::Illegal()); } // Not a node that supports it
virtual bool same(AstNode* otherp) const { return true; }
virtual bool maybePointedTo() const { return false; } // Another AstNode* may have a pointer into this node, other then normal front/back/etc.
virtual bool broken() const { return false; }
virtual bool emitWordForm() { return false; }
@@ -774,14 +834,14 @@ struct AstNodeAssign : public AstNodeStmt {
struct AstNodeFor : public AstNodeStmt {
AstNodeFor(FileLine* fileline, AstNode* initsp, AstNode* condp,
AstNode* assignsp, AstNode* bodysp)
AstNode* incsp, AstNode* bodysp)
: AstNodeStmt(fileline) {
addNOp1p(initsp); setOp2p(condp); addNOp3p(assignsp); addNOp4p(bodysp);
addNOp1p(initsp); setOp2p(condp); addNOp3p(incsp); addNOp4p(bodysp);
}
virtual ~AstNodeFor() {}
AstNode* initsp() const { return op1p()->castNode(); } // op1= initial statement
AstNode* initsp() const { return op1p()->castNode(); } // op1= initial statements
AstNode* condp() const { return op2p()->castNode(); } // op2= condition to continue
AstNode* assignsp() const { return op3p()->castNode(); } // op3= final statements
AstNode* incsp() const { return op3p()->castNode(); } // op3= increment statements
AstNode* bodysp() const { return op4p()->castNode(); } // op4= body of loop
virtual bool isGateOptimizable() const { return false; }
virtual bool isPredictOptimizable() const { return false; }
@@ -874,6 +934,7 @@ public:
virtual ~AstNodePli() {}
virtual string name() const { return m_text; }
virtual int instrCount() const { return instrCountPli(); }
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output
string text() const { return m_text; } // * = Text to display
void text(const string& text) { m_text=text; }
@@ -922,6 +983,7 @@ public:
virtual ~AstNodeFTask() {}
virtual void dump(ostream& str=cout);
virtual string name() const { return m_name; } // * = Var name
virtual bool maybePointedTo() const { return true; }
// {AstFunc only} op1 = Range output variable
// op3 = Statements/Ports/Vars
void name(const string& name) { m_name = name; }
@@ -939,10 +1001,10 @@ private:
string m_dotted; // Dotted part of scope to task or ""
string m_inlinedDots; // Dotted hiearchy flattened out
public:
AstNodeFTaskRef(FileLine* fl, const string& name, const string& dotted, AstNode* pinsp)
AstNodeFTaskRef(FileLine* fl, AstNode* namep, AstNode* pinsp)
:AstNode(fl)
, m_taskp(NULL), m_name(name), m_dotted(dotted) {
addNOp1p(pinsp);
, m_taskp(NULL) {
setOp1p(namep); addNOp2p(pinsp);
}
virtual ~AstNodeFTaskRef() {}
virtual bool broken() const { return m_taskp && !m_taskp->brokeExists(); }
@@ -957,9 +1019,13 @@ public:
void inlinedDots(const string& flag) { m_inlinedDots = flag; }
AstNodeFTask* taskp() const { return m_taskp; } // [After Link] Pointer to variable
void taskp(AstNodeFTask* taskp) { m_taskp=taskp; }
// op1 = Pin interconnection list
AstNode* pinsp() const { return op1p()->castNode(); }
void addPinsp(AstNode* nodep) { addOp1p(nodep); }
void name(const string& name) { m_name = name; }
void dotted(const string& name) { m_dotted = name; }
// op1 = namep
AstNode* namep() const { return op1p(); }
// op2 = Pin interconnection list
AstNode* pinsp() const { return op2p()->castNode(); }
void addPinsp(AstNode* nodep) { addOp2p(nodep); }
};
//######################################################################
+34 -8
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -19,6 +19,8 @@
//
//*************************************************************************
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <fstream>
@@ -85,7 +87,7 @@ int AstVar::widthTotalBytes() const {
}
string AstVar::verilogKwd() const {
if (isTristate()) {
if (isInout()) {
return "inout";
} else if (isInput()) {
return "input";
@@ -93,6 +95,8 @@ string AstVar::verilogKwd() const {
return "output";
} else if (isInteger()) {
return "integer";
} else if (isTristate()) {
return "tri";
} else if (varType()==AstVarType::WIRE) {
return "wire";
} else {
@@ -101,6 +105,18 @@ string AstVar::verilogKwd() const {
}
string AstVar::cType() const {
if (widthMin() == 1) {
return "bool";
} else if (widthMin() <= VL_WORDSIZE) {
return "uint32_t";
} else if (isScWide()) {
return "uint32_t"; // []'s added later
} else {
return "uint64_t";
}
}
string AstVar::scType() const {
if (widthMin() == 1) {
return "bool";
} else if (widthMin() <= VL_WORDSIZE) {
@@ -130,7 +146,7 @@ uint32_t AstVar::arrayElements() const {
bool AstScope::broken() const {
return ((m_aboveScopep && !m_aboveScopep->brokeExists())
|| (m_aboveCellp && !m_aboveCellp->brokeExists())
|| !m_modp || !((AstNode*)m_modp)->brokeExists());
|| !m_modp || !m_modp->brokeExists());
}
void AstScope::cloneRelink() {
@@ -325,14 +341,19 @@ void AstVarRef::dump(ostream& str) {
void AstVar::dump(ostream& str) {
this->AstNode::dump(str);
if (isSc()) str<<" [SC]";
if (isInput()) str<<" [I]";
if (isPrimaryIO()) str<<(isInput()?" [PI]":" [PO]");
if (isOutput()) str<<" [O]";
if (isPrimaryIO()) str<<(isInout()?" [PIO]":(isInput()?" [PI]":" [PO]"));
else {
if (isInout()) str<<" [IO]";
else if (isInput()) str<<" [I]";
else if (isOutput()) str<<" [O]";
}
if (isUsedClock()) str<<" [C]";
if (isSigPublic()) str<<" [P]";
if (attrClockEn()) str<<" [aCLKEN]";
if (attrIsolateAssign()) str<<" [aISO]";
if (attrFileDescr()) str<<" [aFD]";
if (isFuncLocal() || isFuncReturn()) str<<" [FUNC]";
if (isFuncReturn()) str<<" [FUNCRTN]";
else if (isFuncLocal()) str<<" [FUNC]";
str<<" "<<varType();
}
void AstSenTree::dump(ostream& str) {
@@ -341,7 +362,11 @@ void AstSenTree::dump(ostream& str) {
}
void AstSenItem::dump(ostream& str) {
this->AstNode::dump(str);
str<<" ["<<m_edgeType.ascii()<<"]";
str<<" ["<<edgeType().ascii()<<"]";
}
void AstParseRef::dump(ostream& str) {
this->AstNode::dump(str);
str<<" ["<<expect().ascii()<<"]";
}
void AstActive::dump(ostream& str) {
this->AstNode::dump(str);
@@ -358,6 +383,7 @@ void AstNodeFTaskRef::dump(ostream& str) {
}
void AstNodeFTask::dump(ostream& str) {
this->AstNode::dump(str);
if (taskPublic()) str<<" [PUBLIC]";
}
void AstCoverDecl::dump(ostream& str) {
this->AstNode::dump(str);
+175 -35
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -236,11 +236,13 @@ private:
bool m_scClocked:1; // SystemC sc_clk<> needed
bool m_scSensitive:1;// SystemC sensitive() needed
bool m_sigPublic:1; // User C code accesses this signal
bool m_sigModPublic:1;// User C code accesses this signal and module
bool m_usedClock:1; // Signal used as a clock
bool m_usedParam:1; // Parameter is referenced (on link; later signals not setup)
bool m_funcLocal:1; // Local variable for a function
bool m_funcReturn:1; // Return variable for a function
bool m_attrClockEn:1;// User clock enable attribute
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
bool m_fileDescr:1; // File descriptor
bool m_isConst:1; // Table contains constant data
bool m_isStatic:1; // Static variable
@@ -251,8 +253,10 @@ private:
m_primaryIO=false;
m_sc=false; m_scClocked=false; m_scSensitive=false;
m_usedClock=false; m_usedParam=false;
m_sigPublic=false; m_funcLocal=false; m_funcReturn=false;
m_attrClockEn=false; m_fileDescr=false; m_isConst=false; m_isStatic=false;
m_sigPublic=false; m_sigModPublic=false;
m_funcLocal=false; m_funcReturn=false;
m_attrClockEn=false; m_attrIsolateAssign=false;
m_fileDescr=false; m_isConst=false; m_isStatic=false;
m_trace=false;
}
public:
@@ -286,8 +290,10 @@ public:
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void dump(ostream& str);
virtual string name() const { return m_name; } // * = Var name
virtual bool maybePointedTo() const { return true; }
AstVarType varType() const { return m_varType; } // * = Type of variable
string cType() const; // Return C type: bool, uint32_t, uint64_t, etc.
string cType() const; // Return C type for declaration: bool, uint32_t, uint64_t, etc.
string scType() const; // Return SysC type: bool, uint32_t, uint64_t, sc_bv
void combineType(AstVarType type);
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable
AstRange* arraysp() const { return op2p()->castRange(); } // op2 = Array(s) of variable
@@ -299,9 +305,11 @@ public:
void attrClockEn(bool flag) { m_attrClockEn = flag; }
void attrFileDescr(bool flag) { m_fileDescr = flag; }
void attrScClocked(bool flag) { m_scClocked = flag; }
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
void usedClock(bool flag) { m_usedClock = flag; }
void usedParam(bool flag) { m_usedParam = flag; }
void sigPublic(bool flag) { m_sigPublic = flag; }
void sigModPublic(bool flag) { m_sigModPublic = flag; }
void sc(bool flag) { m_sc = flag; }
void scSensitive(bool flag) { m_scSensitive = flag; }
void primaryIO(bool flag) { m_primaryIO = flag; }
@@ -314,10 +322,13 @@ public:
void name(const string& name) { m_name = name; }
bool isInput() const { return m_input; }
bool isOutput() const { return m_output; }
bool isTristate() const { return (m_tristate); }
bool isInOnly() const { return m_input && !m_output; }
bool isOutOnly() const { return m_output && !m_input; }
bool isInout() const { return m_input && m_output; }
bool isTristate() const { return m_tristate; }
bool isPrimaryIO() const { return m_primaryIO; }
bool isPrimaryIn() const { return isPrimaryIO() && isInput(); }
bool isIO() const { return (m_input||m_output||m_tristate); }
bool isIO() const { return (m_input||m_output); }
bool isSignal() const { return (varType()==AstVarType::WIRE || varType()==AstVarType::IMPLICIT
|| varType()==AstVarType::REG || varType()==AstVarType::INTEGER); }
bool isTemp() const { return (varType()==AstVarType::BLOCKTEMP || varType()==AstVarType::MODULETEMP
@@ -335,6 +346,7 @@ public:
bool isScWide() const;
bool isScSensitive() const { return m_scSensitive; }
bool isSigPublic() const;
bool isSigModPublic() const { return m_sigModPublic; }
bool isTrace() const { return m_trace; }
bool isConst() const { return m_isConst; }
bool isStatic() const { return m_isStatic; }
@@ -343,6 +355,7 @@ public:
bool attrClockEn() const { return m_attrClockEn; }
bool attrFileDescr() const { return m_fileDescr; }
bool attrScClocked() const { return m_scClocked; }
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
int widthAlignBytes() const; // Structure alignment 1,2,4 or 8 bytes (arrays affect this)
int widthTotalBytes() const; // Width in bytes rounding up 1,2,4,8,12,...
uint32_t msb() const { if (!rangep()) return 0; return rangep()->msbConst(); }
@@ -354,6 +367,7 @@ public:
// Note the method below too
if (fromp->attrClockEn()) attrClockEn(true);
if (fromp->attrFileDescr()) attrFileDescr(true);
if (fromp->attrIsolateAssign()) attrIsolateAssign(true);
}
bool gateMultiInputOptimizable() const {
// Ok to gate optimize; must return false if propagateAttrFrom would do anything
@@ -364,6 +378,7 @@ public:
propagateAttrFrom(typevarp);
combineType(typevarp->varType());
if (typevarp->isSigPublic()) sigPublic(true);
if (typevarp->isSigModPublic()) sigModPublic(true);
if (typevarp->attrScClocked()) attrScClocked(true);
}
void inlineAttrReset(const string& name) {
@@ -419,6 +434,7 @@ public:
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void cloneRelink();
virtual bool broken() const;
virtual bool maybePointedTo() const { return true; }
virtual string name() const { return m_name; } // * = Scope name
void name(const string& name) { m_name = name; }
string nameDotless() const;
@@ -480,6 +496,7 @@ public:
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual bool broken() const { return ( (m_varp && !m_varp->brokeExists())
|| (m_scopep && !m_scopep->brokeExists())); }
virtual bool maybePointedTo() const { return true; }
virtual string name() const {return scopep()->name()+"->"+varp()->name();} // * = Var name
virtual void dump(ostream& str);
AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable
@@ -604,6 +621,7 @@ public:
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void dump(ostream& str);
virtual bool broken() const { return (m_clkReqVarp && !m_clkReqVarp->brokeExists()); }
virtual bool maybePointedTo() const { return true; }
virtual string name() const { return m_name; }
AstNode* stmtsp() const { return op2p()->castNode(); } // op2 = List of statements
AstActive* activesp() const { return op3p()->castActive(); } // op3 = List of i/sblocks
@@ -648,19 +666,21 @@ public:
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void dump(ostream& str);
virtual bool broken() const { return (m_modp && !m_modp->brokeExists()); }
virtual bool maybePointedTo() const { return true; }
// ACCESSORS
virtual string name() const { return m_name; } // * = Cell name
void name(const string& name) { m_name = name; }
string origName() const { return m_origName; } // * = Original name
void origName(const string& name) { m_origName = name; }
string modName() const { return m_modName; } // * = Instance name
void modName(const string& name) { m_modName = name; }
AstPin* pinsp() const { return op1p()->castPin(); } // op1 = List of cell ports
AstPin* paramsp() const { return op2p()->castPin(); } // op2 = List of parameter #(##) values
AstRange* rangep() const { return op3p()->castRange(); } // op3 = Range of arrayed instants (NULL=not ranged)
AstModule* modp() const { return m_modp; } // [AfterLink] = Pointer to module instantiated
void addPinsp(AstPin* pinp) { addOp1p(pinp); }
void addParamsp(AstPin* pinp) { addOp2p(pinp); }
void modp(AstModule* modp) { m_modp = modp; }
void modName(const string& name) { m_modName = name; }
void name(const string& name) { m_name = name; }
void addPinsp(AstPin* nodep) { addOp1p(nodep); }
void addParamsp(AstPin* nodep) { addOp2p(nodep); }
void modp(AstModule* nodep) { m_modp = nodep; }
};
struct AstCellInline : public AstNode {
@@ -746,6 +766,46 @@ struct AstGenerate : public AstNode {
void addStmtp(AstNode* nodep) { addOp1p(nodep); }
};
struct AstParseRef : public AstNode {
// A reference to a variable, function or task
// We don't know which at parse time due to bison constraints
// The link stages will replace this with AstVarRef, or AstTaskRef, etc.
// Parents: math|stmt
// Children: TEXT|DOT|SEL* (or expression under sel)
private:
AstParseRefExp m_expect; // Type we think it should resolve to
public:
AstParseRef(FileLine* fl, AstParseRefExp expect, AstNode* lhsp)
:AstNode(fl), m_expect(expect) { setOp1p(lhsp); }
virtual ~AstParseRef() {}
virtual AstType type() const { return AstType::PARSEREF;}
virtual AstNode* clone() { return new AstParseRef(*this);}
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void dump(ostream& str);
virtual V3Hash sameHash() const { return V3Hash(m_expect); }
virtual bool same(AstNode* samep) const { return expect() == samep->castParseRef()->expect(); }
virtual string emitVerilog() { V3ERROR_NA; return ""; }
virtual string emitOperator() { V3ERROR_NA; return ""; }
AstParseRefExp expect() const { return m_expect; }
// op1 = Components
AstNode* lhsp() const { return op1p(); } // op1 = List of statements
};
struct AstDot : public AstNode {
// A dot separating paths in a AstXRef, AstFuncRef or AstTaskRef
// These are elimiated in the link stage
AstDot(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
:AstNode(fl) { setOp1p(lhsp); setOp2p(rhsp); }
virtual ~AstDot() {}
virtual AstType type() const { return AstType::DOT;}
virtual AstNode* clone() { return new AstDot(*this);}
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual string emitVerilog() { V3ERROR_NA; return ""; }
virtual string emitOperator() { V3ERROR_NA; return ""; }
AstNode* lhsp() const { return op1p(); }
AstNode* rhsp() const { return op2p(); }
};
//######################################################################
struct AstTask : public AstNodeFTask {
@@ -759,10 +819,13 @@ struct AstTask : public AstNodeFTask {
};
struct AstFunc : public AstNodeFTask {
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
public:
// A function inside a module
AstFunc(FileLine* fl, const string& name, AstNode* stmtp, AstNode* fvarsp)
:AstNodeFTask(fl, name, stmtp) {
addNOp1p(fvarsp);
m_attrIsolateAssign = false;
}
virtual ~AstFunc() {}
virtual AstType type() const { return AstType::FUNC;}
@@ -771,12 +834,14 @@ struct AstFunc : public AstNodeFTask {
// op1 = Range output variable (functions only)
AstNode* fvarp() const { return op1p()->castNode(); }
void addFvarp(AstNode* nodep) { addOp1p(nodep); }
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
};
struct AstTaskRef : public AstNodeFTaskRef {
// A reference to a task
AstTaskRef(FileLine* fl, const string& name, const string& dotted, AstNode* pinsp)
:AstNodeFTaskRef(fl, name, dotted, pinsp) {}
AstTaskRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
:AstNodeFTaskRef(fl, namep, pinsp) {}
virtual ~AstTaskRef() {}
virtual AstType type() const { return AstType::TASKREF;}
virtual AstNode* clone() { return new AstTaskRef(*this);}
@@ -785,8 +850,8 @@ struct AstTaskRef : public AstNodeFTaskRef {
struct AstFuncRef : public AstNodeFTaskRef {
// A reference to a function
AstFuncRef(FileLine* fl, const string& name, const string& dotted, AstNode* pinsp)
:AstNodeFTaskRef(fl, name, dotted, pinsp) {}
AstFuncRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
:AstNodeFTaskRef(fl, namep, pinsp) {}
virtual ~AstFuncRef() {}
virtual AstType type() const { return AstType::FUNCREF;}
virtual AstNode* clone() { return new AstFuncRef(*this);}
@@ -805,9 +870,12 @@ public:
class Initial {}; // for creator type-overload selection
class Settle {}; // for creator type-overload selection
class Never {}; // for creator type-overload selection
AstSenItem(FileLine* fl, AstEdgeType edgeType, AstVarRef* varrefp)
: AstNode(fl) {
m_edgeType = edgeType;
AstSenItem(FileLine* fl, AstEdgeType edgeType, AstNodeVarRef* varrefp)
: AstNode(fl), m_edgeType(edgeType) {
setOp1p(varrefp);
}
AstSenItem(FileLine* fl, AstEdgeType edgeType, AstParseRef* varrefp)
: AstNode(fl), m_edgeType(edgeType) {
setOp1p(varrefp);
}
AstSenItem(FileLine* fl, Combo)
@@ -838,7 +906,7 @@ public:
AstEdgeType edgeType() const { return m_edgeType; } // * = Posedge/negedge
void edgeType(AstEdgeType type) { m_edgeType=type; editCountInc(); }// * = Posedge/negedge
AstNode* sensp() const { return op1p(); } // op1 = Signal sensitized
AstVarRef* varrefp() const { return op1p()->castVarRef(); } // op1 = Signal sensitized
AstNodeVarRef* varrefp() const { return op1p()->castNodeVarRef(); } // op1 = Signal sensitized
//
bool isClocked() const { return edgeType().clockedStmt(); }
bool isCombo() const { return edgeType()==AstEdgeType::COMBO; }
@@ -864,6 +932,7 @@ public:
virtual AstNode* clone() { return new AstSenTree(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void dump(ostream& str);
virtual bool maybePointedTo() const { return true; }
bool isMulti() const { return m_multi; }
AstSenItem* sensesp() const { return op1p()->castSenItem(); } // op1 = Sensitivity list
void addSensesp(AstSenItem* nodep) { addOp1p(nodep); }
@@ -1049,6 +1118,7 @@ public:
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void dump(ostream& str);
virtual int instrCount() const { return 1+2*instrCountLd(); }
virtual bool maybePointedTo() const { return true; }
int column() const { return m_column; }
const string& comment() const { return m_text; } // text to insert in code
const string& typeText() const { return m_typeText; }
@@ -1155,6 +1225,7 @@ public:
virtual int instrCount() const { return widthInstrs()+instrCountBranch(); }
AstNode* condsp() const { return op1p()->castNode(); } // op1= list of possible matching expressions
AstNode* bodysp() const { return op2p()->castNode(); } // op2= what to do
void condsp(AstNode* nodep) { setOp1p(nodep); }
void addBodysp(AstNode* newp) { addOp2p(newp); }
bool isDefault() const { return condsp()==NULL; }
bool ignoreOverlap() const { return m_ignoreOverlap; }
@@ -1162,20 +1233,22 @@ public:
};
struct AstDisplay : public AstNodePli {
// Parents: stmtlist
// Children: file which must be a varref, MATH to print
private:
char m_newline;
AstDisplayType m_displayType;
public:
AstDisplay(FileLine* fileline, char newln, const string& text, AstNodeVarRef* filep, AstNode* exprsp)
AstDisplay(FileLine* fileline, AstDisplayType dispType, const string& text, AstNode* filep, AstNode* exprsp)
: AstNodePli (fileline, text, exprsp) {
setNOp2p(filep);
m_newline = newln;
m_displayType = dispType;
}
virtual ~AstDisplay() {}
virtual AstType type() const { return AstType::DISPLAY;}
virtual AstNode* clone() { return new AstDisplay(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual string verilogKwd() const { return (filep() ? ((newline() == '\n')?"$fdisplay":"$fwrite")
: ((newline() == '\n')?"$display":"$write")); };
virtual string verilogKwd() const { return (filep() ? (string)"$f"+(string)displayType().ascii()
: (string)"$"+(string)displayType().ascii()); }
virtual bool isGateOptimizable() const { return false; }
virtual bool isPredictOptimizable() const { return false; }
virtual bool isSplittable() const { return false; } // SPECIAL: $display has 'visual' ordering
@@ -1183,19 +1256,25 @@ public:
virtual bool isUnlikely() const { return true; }
virtual V3Hash sameHash() const { return V3Hash(text()); }
virtual bool same(AstNode* samep) const {
return newline()==samep->castDisplay()->newline()
return displayType()==samep->castDisplay()->displayType()
&& text()==samep->castDisplay()->text(); }
// op1 used by AstNodePli
char newline() const { return m_newline; } // * = Add a newline for $display
AstNodeVarRef* filep() const { return op2p()->castVarRef(); }
AstDisplayType displayType() const { return m_displayType; }
void displayType(AstDisplayType type) { m_displayType = type; }
bool addNewline() const { return displayType().addNewline(); } // * = Add a newline for $display
AstNode* filep() const { return op2p(); }
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
AstNode* scopeAttrp() const { return op3p(); }
AstText* scopeTextp() const { return op3p()->castText(); }
void scopeAttrp(AstNode* nodep) { addOp3p(nodep); }
bool needScopeTracking() { return (displayType().needScopeTracking()
|| name().find("%m") != string::npos); }
};
struct AstFClose : public AstNodeStmt {
AstFClose(FileLine* fileline, AstNodeVarRef* filep)
// Parents: stmtlist
// Children: file which must be a varref
AstFClose(FileLine* fileline, AstNode* filep)
: AstNodeStmt (fileline) {
setNOp2p(filep);
}
@@ -1211,7 +1290,7 @@ struct AstFClose : public AstNodeStmt {
virtual bool isUnlikely() const { return true; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
AstNodeVarRef* filep() const { return op2p()->castVarRef(); }
AstNode* filep() const { return op2p(); }
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
};
@@ -1234,15 +1313,43 @@ struct AstFOpen : public AstNodeStmt {
virtual bool isUnlikely() const { return true; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
AstNodeVarRef* filep() const { return op1p()->castVarRef(); }
AstNode* filep() const { return op1p(); }
AstNode* filenamep() const { return op2p(); }
AstNode* modep() const { return op3p(); }
};
struct AstReadMem : public AstNodeStmt {
private:
bool m_isHex; // readmemh, not readmemb
public:
AstReadMem(FileLine* fileline, bool hex,
AstNode* filenamep, AstNode* memp, AstNode* lsbp, AstNode* msbp)
: AstNodeStmt (fileline), m_isHex(hex) {
setOp1p(filenamep); setOp2p(memp); setNOp3p(lsbp); setNOp4p(msbp);
}
virtual ~AstReadMem() {}
virtual AstType type() const { return AstType::READMEM;}
virtual AstNode* clone() { return new AstReadMem(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual string verilogKwd() const { return (isHex()?"$readmemh":"$readmemb"); };
virtual bool isGateOptimizable() const { return false; }
virtual bool isPredictOptimizable() const { return false; }
virtual bool isSplittable() const { return false; }
virtual bool isOutputter() const { return true; }
virtual bool isUnlikely() const { return true; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return isHex()==samep->castReadMem()->isHex(); }
bool isHex() const { return m_isHex; }
AstNode* filenamep() const { return op1p()->castNode(); }
AstNode* memp() const { return op2p()->castNode(); }
AstNode* lsbp() const { return op3p()->castNode(); }
AstNode* msbp() const { return op4p()->castNode(); }
};
struct AstGenFor : public AstNodeFor {
AstGenFor(FileLine* fileline, AstNode* initsp, AstNode* condp,
AstNode* assignsp, AstNode* bodysp)
: AstNodeFor(fileline, initsp, condp, assignsp, bodysp) {
AstNode* incsp, AstNode* bodysp)
: AstNodeFor(fileline, initsp, condp, incsp, bodysp) {
}
virtual ~AstGenFor() {}
virtual AstType type() const { return AstType::GENFOR;}
@@ -1252,8 +1359,8 @@ struct AstGenFor : public AstNodeFor {
struct AstFor : public AstNodeFor {
AstFor(FileLine* fileline, AstNode* initsp, AstNode* condp,
AstNode* assignsp, AstNode* bodysp)
: AstNodeFor(fileline, initsp, condp, assignsp, bodysp) {
AstNode* incsp, AstNode* bodysp)
: AstNodeFor(fileline, initsp, condp, incsp, bodysp) {
}
virtual ~AstFor() {}
virtual AstType type() const { return AstType::FOR;}
@@ -1502,6 +1609,7 @@ public:
virtual AstNode* clone() { return new AstTraceDecl(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual string name() const { return m_showname; }
virtual bool maybePointedTo() const { return true; }
string showname() const { return m_showname; } // * = Var name
virtual bool same(AstNode* samep) const { return false; }
// Details on what we're tracing
@@ -1593,7 +1701,8 @@ public:
bool hasClocked() const { return m_sensesp->hasClocked(); }
};
class AstAttrOf : public AstNode {
struct AstAttrOf : public AstNode {
private:
// Return a value of a attribute, for example a LSB or array LSB of a signal
AstAttrType m_attrType; // What sort of extraction
int m_dimension; // Dimension number (0 is leftmost), for ARRAY_LSB extractions
@@ -1735,6 +1844,7 @@ struct AstRedXor : public AstNodeUniop {
virtual int instrCount() const { return 1+V3Number::log2b(width()); }
};
struct AstRedXnor : public AstNodeUniop {
// AstRedXnors are replaced with AstRedXors in V3Const.
AstRedXnor(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
width(1,1); }
virtual ~AstRedXnor() {}
@@ -2510,6 +2620,30 @@ struct AstReplicate : public AstNodeBiop {
virtual int instrCount() const { return widthInstrs()*2; }
};
//======================================================================
// SysVerilog assertions
struct AstVAssert : public AstNodeStmt {
// Verilog Assertion
// Parents: {statement list}
// Children: expression, if pass statements, if fail statements
AstVAssert(FileLine* fl, AstNode* propp, AstNode* passsp, AstNode* failsp)
: AstNodeStmt(fl) {
addOp1p(propp);
addNOp2p(passsp);
addNOp3p(failsp);
}
virtual ~AstVAssert() {}
virtual AstType type() const { return AstType::VASSERT;}
virtual AstNode* clone() { return new AstVAssert(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
AstNode* propp() const { return op1p(); } // op1 = property
AstNode* passsp() const { return op2p(); } // op2 = if passes
AstNode* failsp() const { return op3p(); } // op3 = if fails
};
//======================================================================
// PSL
@@ -2772,6 +2906,7 @@ private:
bool m_funcPublic:1; // From user public task/function
bool m_isStatic:1; // Function is declared static (no this)
bool m_symProlog:1; // Setup symbol table for later instructions
bool m_entryPoint:1; // User may call into this top level function
public:
AstCFunc(FileLine* fl, const string& name, AstScope* scopep, const string& rtnType="")
: AstNode(fl) {
@@ -2787,12 +2922,15 @@ public:
m_funcPublic = false;
m_isStatic = true; // Note defaults to static, later we see where thisp is needed
m_symProlog = false;
m_entryPoint = false;
}
virtual ~AstCFunc() {}
virtual AstType type() const { return AstType::CFUNC;}
virtual AstNode* clone() { return new AstCFunc(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual string name() const { return m_name; }
virtual bool broken() const { return ( (m_scopep && !m_scopep->brokeExists())); }
virtual bool maybePointedTo() const { return true; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return ((funcType()==samep->castCFunc()->funcType())
&& (rtnTypeVoid()==samep->castCFunc()->rtnTypeVoid())
@@ -2822,6 +2960,8 @@ public:
void isStatic(bool flag) { m_isStatic = flag; }
bool symProlog() const { return m_symProlog; }
void symProlog(bool flag) { m_symProlog = flag; }
bool entryPoint() const { return m_entryPoint; }
void entryPoint(bool flag) { m_entryPoint = flag; }
//
// If adding node accessors, see below
AstNode* argsp() const { return op1p()->castNode(); }
+33 -31
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -23,10 +23,12 @@
// Each module:
// Look for BEGINs
// BEGIN(VAR...) -> VAR ... {renamed}
// FOR -> WHILEs
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -48,25 +50,6 @@ private:
string m_beginScope; // Name of begin blocks above us
//int debug() { return 9; }
bool nameMatchesGen(const char* namep, string& numr) {
numr = "";
bool needbar = false;
for (const char* cp=namep; *cp; ) {
if (0==strncmp(cp,"genblk",6) || 0==strncmp(cp,"genfor",6)) {
cp += 6;
} else if (isdigit(*cp)) {
if (needbar) { numr += '_'; needbar = false; }
numr += *cp++;
} else if (*cp=='_') {
cp++;
needbar = true;
} else {
return false; // Not exact match
}
}
return true;
}
// VISITORS
virtual void visit(AstModule* nodep, AstNUser*) {
m_modp = nodep;
@@ -83,15 +66,6 @@ private:
UINFO(8," "<<nodep<<endl);
string oldScope = m_beginScope;
{
//string nameNum;
//string oldNum;
//if (nameMatchesGen(oldScope.c_str(), oldNum/*ref*/)
// && nameMatchesGen(nodep->name().c_str(), nameNum/*ref*/)
// && 0) { // Messes up V3Link
// // Need to leave the dot or we mess up later V3LinkDot
// // gen[blk|for]##_gen[blk|for]## -> gen[blk|for]##__DOT__##...
// m_beginScope = oldScope + "__DOT__"+nameNum;
//UINFO(8,"nname "<<m_beginScope<<endl);
// Create data for dotted variable resolution
string dottedname = nodep->name() + "__DOT__"; // So always found
@@ -99,7 +73,7 @@ private:
while ((pos=dottedname.find("__DOT__")) != string::npos) {
string ident = dottedname.substr(0,pos);
dottedname = dottedname.substr(pos+strlen("__DOT__"));
if (m_beginScope=="") m_beginScope = nodep->name();
if (m_beginScope=="") m_beginScope = ident;
else m_beginScope = m_beginScope + "__DOT__"+ident;
// Create CellInline for dotted resolution
AstCellInline* inlinep = new AstCellInline(nodep->fileline(),
@@ -141,6 +115,34 @@ private:
m_modp->addStmtp(nodep);
}
}
virtual void visit(AstFor* nodep, AstNUser*) {
// So later optimizations don't need to deal with them,
// FOR(init,cond,assign,body) -> init,WHILE(cond) { body, assign }
AstNode* initsp = nodep->initsp(); if (initsp) initsp->unlinkFrBackWithNext();
AstNode* condp = nodep->condp(); if (condp) condp->unlinkFrBackWithNext();
AstNode* incsp = nodep->incsp(); if (incsp) incsp->unlinkFrBackWithNext();
AstNode* bodysp = nodep->bodysp(); if (bodysp) bodysp->unlinkFrBackWithNext();
bodysp = bodysp->addNext(incsp);
AstNode* newp = new AstWhile(nodep->fileline(),
condp,
bodysp);
initsp = initsp->addNext(newp);
newp = initsp;
nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL;
}
virtual void visit(AstDisplay* 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 (m_beginScope != "" && nodep->needScopeTracking()) {
// To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext();
nodep->scopeAttrp(new AstText(nodep->fileline(), (string)"."+AstNode::prettyName(m_beginScope)));
if (afterp) nodep->scopeAttrp(afterp);
}
nodep->iterateChildren(*this);
}
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3BEGIN_H_
#define _V3BEGIN_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -25,7 +25,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3BRANCH_H_
#define _V3BRANCH_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+9 -6
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -26,7 +26,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -81,13 +82,15 @@ private:
// // so userp and friends may not be used
// VISITORS
virtual void visit(AstNode* nodep, AstNUser*) {
BrokenTable::add(nodep);
if (nodep->maybePointedTo()) {
BrokenTable::add(nodep);
}
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
BrokenMarkVisitor(AstNode* nodep) {
nodep->iterateAndNext(*this, NULL);
BrokenMarkVisitor(AstNetlist* nodep) {
nodep->accept(*this);
}
virtual ~BrokenMarkVisitor() {}
};
@@ -99,7 +102,7 @@ class BrokenCheckVisitor : public AstNVisitor {
private:
virtual void visit(AstNode* nodep, AstNUser*) {
if (nodep->broken()) {
nodep->v3fatalSrc("Broken link in node\n");
nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo)\n");
}
if (v3Global.assertWidthsSame()) {
if (nodep->width() != nodep->widthMin()) {
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3BROKEN_H_
#define _V3BROKEN_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+82 -42
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -29,16 +29,17 @@
// (other items))
// body
// Or, converts to a if/else tree.
// Constants:
// RHS, Replace 5'bx_1_x with a module global we init to a random value
// CONST(5'bx_1_x) -> VARREF(_{numberedtemp})
// -> VAR(_{numberedtemp})
// -> INITIAL(VARREF(_{numberedtemp}), OR(5'bx_1_x,AND(random,5'b0_1_x))
// OPTIMIZE: Must not collapse this initial back into the equation.
// FUTURES:
// Large 16+ bit tables with constants and no masking (address muxes)
// Enter all into multimap, sort by value and use a tree of < and == compares.
// "Diagonal" find of {rightmost,leftmost} bit {set,clear}
// Ignoring mask, check each value is unique (using multimap as above?)
// Each branch is then mask-and-compare operation (IE <000000001_000000000 at midpoint.)
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -49,7 +50,9 @@
#include "V3Ast.h"
#include "V3Stats.h"
#define CASE_OVERLAP_WIDTH 12 // Maximum width we can check for overlaps in
#define CASE_OVERLAP_WIDTH 12 // Maximum width we can check for overlaps in
#define CASE_BARF 999999 // Magic width when non-constant
#define CASE_ENCODER_GROUP_DEPTH 8 // Levels of priority to be ORed together in top IF tree
//######################################################################
@@ -126,22 +129,22 @@ private:
//int debug() { return 9; }
// METHODS
bool checkCaseTree(AstCase* nodep) {
bool isCaseTreeFast(AstCase* nodep) {
int width = 0;
m_caseItems = 0;
m_caseNoOverlapsAllCovered = true;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
if (icondp->width() > width) width = icondp->width();
if (!icondp->castConst()) width = 999; // Can't parse; not a constant
if (!icondp->castConst()) width = CASE_BARF; // Can't parse; not a constant
m_caseItems++;
}
}
m_caseWidth = width;
if (width==0 || width > CASE_OVERLAP_WIDTH) {
m_caseNoOverlapsAllCovered = false;
return false; // Too wide for analysis
}
m_caseWidth = width;
UINFO(8,"Simple case statement: "<<nodep<<endl);
// Zero list of items for each value
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) m_valueItem[i] = NULL;
@@ -172,7 +175,7 @@ private:
}
}
// Defaults were moved to last in the caseitem list by V3Link
if (!itemp->condsp()) { // Case statement's default... Fill the table
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;
}
@@ -207,7 +210,7 @@ private:
AstNode* tree1p = replaceCaseFastRecurse(cexprp, msb-1, upperValue | (1UL<<msb));
if (tree0p == tree1p) {
// Same logic on both sides, so we can just return one of em
// Same logic on both sides, so we can just return one of 'em
return tree0p;
}
// We could have a "checkerboard" with A B A B, we can use the same IF on both edges
@@ -273,21 +276,15 @@ private:
// IF((EQ (AND MASK cexpr) (AND MASK icond1)
// ,istmts2, istmts3
AstNode* cexprp = nodep->exprp()->unlinkFrBack();
AstNode* ifrootp = NULL;
AstNode* ifnextp = NULL;
// We'll do this in two stages. First stage, convert the conditions to
// the appropriate IF AND terms.
if (debug()>=9) nodep->dumpTree(cout," _comp_IN: ");
bool hadDefault = false;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
AstNode* istmtsp = itemp->bodysp(); // Maybe null -- no action.
if (istmtsp) istmtsp->unlinkFrBackWithNext();
if (!itemp->condsp()) {
// Default clause. We reordered in link, so default is always last
if (ifnextp) {
if (istmtsp) ifnextp->castIf()->addElsesp(istmtsp);
} else { // Just a empty case default: endcase
ifnextp = istmtsp;
}
if (!ifrootp) ifrootp = istmtsp;
ifnextp = istmtsp;
itemp = NULL; break;
// Default clause. Just make true, we'll optimize it away later
itemp->condsp(new AstConst(itemp->fileline(), V3Number(itemp->fileline(), 1,1)));
hadDefault = true;
} else {
// Expressioned clause
AstNode* icondNextp = NULL;
@@ -322,24 +319,67 @@ private:
ifexprp = new AstLogOr(itemp->fileline(), ifexprp, condp);
}
}
// Make the new IF and attach in the tree
if (ifexprp) {
AstIf* newp = new AstIf(itemp->fileline(), ifexprp, istmtsp, NULL);
if (ifnextp) {
ifnextp->castIf()->addElsesp(newp);
}
if (!ifrootp) ifrootp = newp;
ifnextp = newp;
}
// Replace expression in tree
itemp->condsp(ifexprp);
}
}
if (!hadDefault) {
// If there was no default, add a empty one, this greatly simplifies below code
// and constant propagation will just eliminate it for us later.
nodep->addItemsp(new AstCaseItem(nodep->fileline(),
new AstConst(nodep->fileline(), V3Number(nodep->fileline(),1,1)),
NULL));
}
if (debug()>=9) nodep->dumpTree(cout," _comp_COND: ");
// Now build the IF statement tree
// The tree can be quite huge. Pull ever group of 8 out, and make a OR tree.
// This reduces the depth for the bottom elements, at the cost of some of the top elements.
// If we ever have profiling data, we should pull out the most common item from here and
// instead make it the first IF branch.
int depth = 0;
AstNode* grouprootp = NULL;
AstIf* groupnextp = NULL;
AstIf* itemnextp = NULL;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
AstNode* istmtsp = itemp->bodysp(); // Maybe null -- no action.
if (istmtsp) istmtsp->unlinkFrBackWithNext();
// Expressioned clause
AstNode* ifexprp = itemp->condsp()->unlinkFrBack();
{ // Prepare for next group
if (++depth > CASE_ENCODER_GROUP_DEPTH) depth = 1;
if (depth == 1) { // First group or starting new group
itemnextp = NULL;
AstIf* newp = new AstIf(itemp->fileline(), ifexprp->cloneTree(true), NULL, NULL);
if (groupnextp) groupnextp->addElsesp(newp);
else grouprootp = newp;
groupnextp = newp;
} else { // Continue group, modify if condition to OR in this new condition
AstNode* condp = groupnextp->condp()->unlinkFrBack();
groupnextp->condp(new AstOr(ifexprp->fileline(),
condp,
ifexprp->cloneTree(true)));
}
}
{ // Make the new lower IF and attach in the tree
AstNode* itemexprp = ifexprp; ifexprp=NULL;
if (depth == (CASE_ENCODER_GROUP_DEPTH)) { // End of group - can skip the condition
itemexprp->deleteTree(); itemexprp=NULL;
itemexprp = new AstConst(itemp->fileline(), V3Number(itemp->fileline(),1,1));
}
AstIf* newp = new AstIf(itemp->fileline(), itemexprp, istmtsp, NULL);
if (itemnextp) itemnextp->addElsesp(newp);
else groupnextp->addIfsp(newp); // First in a new group
itemnextp = newp;
}
}
if (debug()>=9) nodep->dumpTree(cout," _comp_TREE: ");
// Handle any assertions
replaceCaseParallel(nodep, false);
// Replace the CASE... with IF...
if (ifrootp) nodep->replaceWith(ifrootp);
if (debug()>=9) grouprootp->dumpTree(cout," _new: ");
if (grouprootp) nodep->replaceWith(grouprootp);
else nodep->unlinkFrBack();
if (debug()>=9) ifrootp->dumpTree(cout," _new: ");
nodep->deleteTree(); nodep=NULL;
}
void replaceCaseParallel(AstCase* nodep, bool noOverlapsAllCovered) {
@@ -357,7 +397,7 @@ private:
V3Case::caseLint(nodep);
nodep->iterateChildren(*this);
if (debug()>=9) nodep->dumpTree(cout," case_old: ");
if (checkCaseTree(nodep) && v3Global.opt.oCase()) {
if (isCaseTreeFast(nodep) && v3Global.opt.oCase()) {
// It's a simple priority encoder or complete statement
// we can make a tree of statements to avoid extra comparisons
m_statCaseFast++;
@@ -375,13 +415,13 @@ private:
public:
// CONSTUCTORS
CaseVisitor(AstNode* nodep) {
CaseVisitor(AstNetlist* nodep) {
m_caseNoOverlapsAllCovered = false;
nodep->accept(*this);
}
virtual ~CaseVisitor() {
V3Stats::addStat("Optimizations, Cases parallelized", m_statCaseFast);
V3Stats::addStat("Optimizations, Cases priority-encoded", m_statCaseSlow);
V3Stats::addStat("Optimizations, Cases complex", m_statCaseSlow);
}
};
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3CASE_H_
#define _V3CASE_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2004-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -42,7 +42,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2004-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3CAST_H_
#define _V3CAST_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -31,7 +31,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3CHANGED_H_
#define _V3CHANGED_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+8 -6
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -28,7 +28,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -103,11 +104,8 @@ private:
nodep->unlinkFrBack(&relinkHandle);
//
computeCppWidth(nodep);
V3Number zero (nodep->fileline(), nodep->widthMin(),0);
V3Number masksmall (nodep->fileline(), nodep->widthMin());
masksmall.opNot(zero);
V3Number mask (nodep->fileline(), cppWidth(nodep));
mask.opAssign(masksmall);
mask.setMask(nodep->widthMin());
AstNode* cleanp = new AstAnd (nodep->fileline(),
new AstConst (nodep->fileline(), mask),
nodep);
@@ -239,6 +237,10 @@ private:
nodep->iterateChildren(*this);
insureCleanAndNext (nodep->bodysp());
}
virtual void visit(AstCCall* nodep, AstNUser*) {
nodep->iterateChildren(*this);
insureCleanAndNext (nodep->argsp());
}
//--------------------
// Default: Just iterate
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3CLEAN_H_
#define _V3CLEAN_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+10 -5
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -32,7 +32,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -192,6 +193,7 @@ private:
funcp->dontCombine(true);
funcp->symProlog(true);
funcp->isStatic(true);
funcp->entryPoint(true);
m_scopep->addActivep(funcp);
m_evalFuncp = funcp;
}
@@ -202,6 +204,7 @@ private:
funcp->slow(true);
funcp->symProlog(true);
funcp->isStatic(true);
funcp->entryPoint(true);
m_scopep->addActivep(funcp);
m_initFuncp = funcp;
}
@@ -211,6 +214,7 @@ private:
funcp->dontCombine(true);
funcp->slow(true);
funcp->isStatic(false);
funcp->entryPoint(true);
funcp->addInitsp(
new AstCStmt(nodep->fileline(),
" "+EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp;\n"));
@@ -225,6 +229,7 @@ private:
funcp->slow(true);
funcp->isStatic(true);
funcp->symProlog(true);
funcp->entryPoint(true);
m_scopep->addActivep(funcp);
m_settleFuncp = funcp;
}
@@ -360,8 +365,7 @@ private:
// Move statements to if
m_lastIfp->addIfsp(stmtsp);
} else if (nodep->hasSettle()) {
// Settlement
clearLastSen();
// Don't need to: clearLastSen();, as we're adding it to different cfunc
// Move statements to function
addToSettleLoop(stmtsp);
} else {
@@ -468,7 +472,8 @@ private:
ifstmtp->addNext(new AstIf(fl,
new AstLt (fl, new AstConst(fl, 100),
new AstVarRef(fl, countVarp, false)),
(new AstDisplay (fl, '\n', "%%Error: Verilated model didn't converge", NULL, NULL))
(new AstDisplay (fl, AstDisplayType::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),
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3CLOCK_H_
#define _V3CLOCK_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -35,7 +35,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3COMBINE_H_
#define _V3COMBINE_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+95 -22
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -25,7 +25,8 @@
// If operands are constant, replace this node with constant.
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -70,6 +71,16 @@ private:
if (!rnodep->lhsp()->castConst()) return false;
return true;
}
bool operandAsvSame (AstNode* nodep) {
// BIASV(SAMEa, BIASV(SAMEb,...)) -> BIASV( BIASV(SAMEa,SAMEb), ...)
AstNodeBiComAsv* bnodep = nodep->castNodeBiComAsv();
if (!bnodep) return false;
AstNodeBiComAsv* rnodep = bnodep->rhsp()->castNodeBiComAsv();
if (!rnodep) return false;
if (rnodep->type() != bnodep->type()) return false;
if (rnodep->width() != bnodep->width()) return false;
return operandsSame(bnodep->lhsp(), rnodep->lhsp());
}
bool operandHugeShiftL(AstNodeBiop* nodep) {
return (nodep->rhsp()->castConst()
&& nodep->rhsp()->castConst()->asInt() >= (uint32_t)(nodep->width()));
@@ -87,6 +98,10 @@ private:
return (nodep->castConst()
&& !nodep->castConst()->num().isFourState());
}
bool operandIsPowTwo(AstNode* nodep) {
if (!operandIsTwostate(nodep)) return false;
return (1==nodep->castConst()->num().countOnes());
}
bool operandShiftOp(AstNodeBiop* nodep) {
if (!nodep->rhsp()->castConst()) return false;
AstNodeBiop* lhsp = nodep->lhsp()->castNodeBiop();
@@ -166,15 +181,10 @@ private:
static bool operandsSame(AstNode* node1p, AstNode* node2p) {
// For now we just detect constants & simple vars, though it could be more generic
if (node1p->castConst() && node2p->castConst()) {
// Match ignoring any X values
V3Number num (node1p->fileline(), 1);
num.opCaseEq(node1p->castConst()->num(), node2p->castConst()->num());
return num.isNeqZero();
return node1p->sameTree(node2p);
}
else if (node1p->castVarRef() && node2p->castVarRef()
&& node1p->sameTree(node2p)) {
// Same variable
return true;
else if (node1p->castVarRef() && node2p->castVarRef()) {
return node1p->sameTree(node2p);
} else {
return false;
}
@@ -235,6 +245,11 @@ private:
void replaceZero(AstNode* nodep) {
replaceNum(nodep, 0); nodep=NULL;
}
void replaceAllOnes (AstNode* nodep) {
V3Number ones (nodep->fileline(), nodep->width(), 0);
ones.setMask(nodep->width());
replaceNum(nodep, ones); nodep=NULL;
}
void replaceConst(AstNodeUniop* nodep) {
V3Number num (nodep->fileline(), nodep->width());
nodep->numberOperate(num, nodep->lhsp()->castConst()->num());
@@ -279,8 +294,9 @@ private:
// Keep RHS, remove LHS
replaceWChild(nodep, nodep->rhsp());
}
void replaceAsvConst (AstNodeBiop* nodep) {
void replaceAsv (AstNodeBiop* nodep) {
// BIASV(CONSTa, BIASV(CONSTb, c)) -> BIASV( BIASV_CONSTED(a,b), c)
// BIASV(SAMEa, BIASV(SAMEb, c)) -> BIASV( BIASV(SAMEa,SAMEb), c)
//nodep->dumpTree(cout, " repAsvConst_old: ");
AstNode* ap = nodep->lhsp();
AstNodeBiop* rp = nodep->rhsp()->castNodeBiop();
@@ -294,7 +310,7 @@ private:
nodep->rhsp(cp);
rp->lhsp(ap);
rp->rhsp(bp);
replaceConst(rp);
if (rp->lhsp()->castConst() && rp->rhsp()->castConst()) replaceConst(rp);
//nodep->dumpTree(cout, " repAsvConst_new: ");
}
void replaceExtend (AstNode* nodep, AstNode* arg0p) {
@@ -317,6 +333,24 @@ private:
newp->lhsp()->widthSignedFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
}
void replaceMulShift (AstMul* nodep) { // Mul, but not MulS as not simple shift
UINFO(5,"MUL(2^n,b)->SHIFTL(b,n) "<<nodep<<endl);
int amount = nodep->lhsp()->castConst()->num().mostSetBitP1()-1; // 2^n->n+1
AstNode* opp = nodep->rhsp()->unlinkFrBack();
AstShiftL* newp = new AstShiftL(nodep->fileline(),
opp, new AstConst(nodep->fileline(), amount));
newp->widthSignedFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
}
void replaceDivShift (AstDiv* nodep) { // Mul, but not MulS as not simple shift
UINFO(5,"DIV(b,2^n)->SHIFTR(b,n) "<<nodep<<endl);
int amount = nodep->rhsp()->castConst()->num().mostSetBitP1()-1; // 2^n->n+1
AstNode* opp = nodep->lhsp()->unlinkFrBack();
AstShiftR* newp = new AstShiftR(nodep->fileline(),
opp, new AstConst(nodep->fileline(), amount));
newp->widthSignedFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
}
void replaceShiftOp (AstNodeBiop* nodep) {
UINFO(5,"SHIFT(AND(a,b),CONST)->AND(SHIFT(a,CONST),SHIFT(b,CONST)) "<<nodep<<endl);
AstNRelinker handle;
@@ -353,7 +387,7 @@ private:
AstNode* newp;
V3Number mask1 (nodep->fileline(), nodep->width());
V3Number ones (nodep->fileline(), nodep->width());
ones.opNot(mask1);
ones.setMask(nodep->width());
if (shift1<0) {
mask1.opShiftR(ones,V3Number(nodep->fileline(),VL_WORDSIZE,-shift1));
} else {
@@ -722,7 +756,8 @@ private:
nodep->varp()->initp()->iterateAndNext(*this);
if (operandConst(nodep->varp()->initp())
&& !nodep->lvalue()
&& ((v3Global.opt.oConst() && !m_params) // Can reduce constant wires into equations
&& ((v3Global.opt.oConst() && !m_params // Can reduce constant wires into equations
&& !nodep->varp()->isSigPublic())
|| nodep->varp()->isParam())) {
AstConst* constp = nodep->varp()->initp()->castConst();
const V3Number& num = constp->num();
@@ -781,7 +816,7 @@ private:
}
UINFO(8,"senItem(NOT...) "<<nodep<<" "<<invert<<endl);
if (invert) nodep->edgeType( nodep->edgeType().invert() );
AstVarRef* senvarp = lastSensp->unlinkFrBack()->castVarRef();
AstNodeVarRef* senvarp = lastSensp->unlinkFrBack()->castNodeVarRef();
if (!senvarp) sensp->v3fatalSrc("Non-varref sensitivity variable");
sensp->replaceWith(senvarp);
sensp->deleteTree(); sensp=NULL;
@@ -923,6 +958,7 @@ private:
// }" # bracket not paren
// ,"function to call"
// or ,"AstREPLACEMENT_TYPE{ $accessor }"
// or ,"! # Print line number when matches, so can see operations
// Lint Checks
// v--- *1* These ops are always first, as we warn before replacing
@@ -947,6 +983,7 @@ private:
TREEOP("AstShiftR{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP("AstShiftRS{$lhsp.isZero, $rhsp}", "replaceZero(nodep)");
TREEOP("AstXor {$lhsp.isZero, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstXnor {$lhsp.isZero, $rhsp}", "AstNot{$rhsp}");
TREEOP("AstSub {$lhsp.isZero, $rhsp}", "AstUnaryMin{$rhsp}");
TREEOP("AstAdd {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP("AstAnd {$lhsp, $rhsp.isZero}", "replaceZero(nodep)");
@@ -960,6 +997,7 @@ private:
TREEOP("AstShiftRS{$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP("AstSub {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP("AstXor {$lhsp, $rhsp.isZero}", "replaceWLhs(nodep)");
TREEOP("AstXnor {$lhsp, $rhsp.isZero}", "AstNot{$lhsp}");
// Non-zero on one side or the other
TREEOP("AstAnd {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstLogAnd{$lhsp.isNeqZero, $rhsp}", "replaceWRhs(nodep)");
@@ -970,8 +1008,15 @@ private:
TREEOP("AstOr {$lhsp, $rhsp.isAllOnes}", "replaceWRhs(nodep)"); //->allOnes
TREEOP("AstLogOr {$lhsp, $rhsp.isNeqZero}", "replaceNum(nodep,1)");
TREEOP("AstXor {$lhsp.isAllOnes, $rhsp}", "AstNot{$rhsp}");
TREEOP("AstPow {operandIsTwo($lhsp), $rhsp}","replacePowShift(nodep)"); // 2**a == 1<<a
TREEOP("AstPowS {operandIsTwo($lhsp), $rhsp}","replacePowShift(nodep)"); // 2**a == 1<<a
TREEOP("AstXnor {$lhsp.isAllOnes, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstMul {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstMulS {$lhsp.isOne, $rhsp}", "replaceWRhs(nodep)");
TREEOP("AstDiv {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)");
TREEOP("AstDivS {$lhsp, $rhsp.isOne}", "replaceWLhs(nodep)");
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)");
@@ -984,8 +1029,9 @@ private:
TREEOP("AstNodeCond{$condp.width1, $expr1p.width1, $expr1p.isZero, $expr2p}", "AstAnd{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, $rhsp.castConst}", "swapSides(nodep)");
TREEOP("AstNodeBiComAsv{operandAsvConst(nodep)}", "replaceAsvConst(nodep)");
TREEOP("AstNodeBiCom{!$lhsp.castConst, $rhsp.castConst}", "swapSides(nodep)");
TREEOP("AstNodeBiComAsv{operandAsvConst(nodep)}", "replaceAsv(nodep)");
TREEOP("AstNodeBiComAsv{operandAsvSame(nodep)}", "replaceAsv(nodep)");
// 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)");
@@ -1030,6 +1076,31 @@ private:
TREEOP ("AstShiftL{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
TREEOP ("AstShiftR{operandShiftShift(nodep)}", "replaceShiftShift(nodep)");
TREEOP ("AstWordSel{operandWordOOB(nodep)}", "replaceZero(nodep)");
// Identical operands on both sides
// AstLogAnd/AstLogOr already converted to AstAnd/AstOr for these rules
// AstAdd->ShiftL(#,1) but uncommon
TREEOP("AstAnd {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
TREEOP("AstChangeXor{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstDiv {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstDivS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstOr {operandsSame($lhsp,,$rhsp)}", "replaceWLhs(nodep)");
TREEOP("AstSub {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstXnor {operandsSame($lhsp,,$rhsp)}", "replaceAllOnes(nodep)");
TREEOP("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
TREEOP("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstGteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstLt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstLtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstLte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstNeqCase{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstLogAnd {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
TREEOP("AstLogOr {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
///=== Verilog operators
// Comparison against 1'b0/1'b1; must be careful about widths.
// These use Not, so must be Verilog only
@@ -1047,7 +1118,6 @@ private:
TREEOPV("AstLte {$lhsp->width()==$rhsp->width(), $rhsp.isAllOnes}", "replaceNum(nodep,1)");
// Simplify reduction operators
// This also gets &{...,0,....} => const 0 (Common for unused_ok signals)
TREEOPV("AstRedXnor{$lhsp}", "AstNot{AstRedXor{$lhsp}}"); // Just eliminate XNOR's
TREEOPV("AstRedAnd{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)");
TREEOPV("AstRedOr {$lhsp, $lhsp.width1}", "replaceWLhs(nodep)");
TREEOPV("AstRedXor{$lhsp, $lhsp.width1}", "replaceWLhs(nodep)");
@@ -1080,6 +1150,7 @@ private:
TREEOPV("AstSel{$fromp.castConcat, $lsbp.castConst, $widthp.castConst, }", "replaceSelConcat(nodep)");
TREEOPV("AstSel{$fromp.castReplicate, $lsbp.castConst, $widthp.isOne, }", "replaceSelReplicate(nodep)");
// Conversions
TREEOPV("AstRedXnor{$lhsp}", "AstNot{AstRedXor{$lhsp}}"); // Just eliminate XNOR's
TREEOPV("AstLogIf {$lhsp, $rhsp}", "AstLogOr{AstLogNot{$lhsp},$rhsp}");
TREEOPV("AstLogIff{$lhsp, $rhsp}", "AstLogNot{AstXor{$lhsp,$rhsp}}");
@@ -1143,12 +1214,14 @@ void V3Const::constifyAll(AstNetlist* nodep) {
visitor.main(nodep);
}
void V3Const::constifyAllLint(AstNode* nodep) {
void V3Const::constifyAllLint(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (false,false,true,false);
visitor.main(nodep);
}
void V3Const::constifyCpp(AstNode* nodep) {
void V3Const::constifyCpp(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (false,false,false,true);
visitor.main(nodep);
}
+5 -4
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3CONST_H_
#define _V3CONST_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
@@ -34,9 +35,9 @@ public:
// Everything that's possible
static void constifyAll(AstNetlist* nodep);
// Also, warn
static void constifyAllLint(AstNode* nodep);
static void constifyAllLint(AstNetlist* nodep);
// C++ datatypes
static void constifyCpp(AstNode* nodep);
static void constifyCpp(AstNetlist* nodep);
// Only the current node and lower
static void constifyTree(AstNode* nodep);
};
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -29,7 +29,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3COVERAGE_H_
#define _V3COVERAGE_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+73 -14
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -24,16 +24,43 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <vector>
#include <map>
#include "V3Global.h"
#include "V3Dead.h"
#include "V3Ast.h"
//######################################################################
class DeadModVisitor : public AstNVisitor {
// In a module that is dead, cleanup the in-use counts of the modules
private:
// NODE STATE
// ** Shared with DeadVisitor **
// VISITORS
virtual void visit(AstCell* nodep, AstNUser*) {
nodep->iterateChildren(*this);
nodep->modp()->user(nodep->modp()->user() - 1);
}
//-----
virtual void visit(AstNodeMath* nodep, AstNUser*) {} // Accelerate
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
public:
// CONSTRUCTORS
DeadModVisitor(AstModule* nodep) {
nodep->accept(*this);
}
virtual ~DeadModVisitor() {}
};
//######################################################################
// Dead state, as a visitor of each AstNode
@@ -45,10 +72,15 @@ private:
// AstVar::user() -> int. Count of number of references
// AstVarScope::user() -> int. Count of number of references
// TYPES
typedef multimap<AstVarScope*,AstNodeAssign*> AssignMap;
// STATE
vector<AstVar*> m_varsp; // List of all encountered to avoid another loop through three
vector<AstVarScope*> m_vscsp; // List of all encountered to avoid another loop through three
vector<AstVar*> m_varsp; // 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_sideEffect; // Side effects discovered in assign RHS
//int debug() { return 9; }
// METHODS
@@ -77,6 +109,25 @@ private:
m_varsp.push_back(nodep);
}
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
// See if simple assignments to variables may be eliminated because that variable is never used.
// Similar code in V3Life
m_sideEffect = false;
nodep->rhsp()->iterateAndNext(*this);
// 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));
} else { // Track like any other statement
nodep->lhsp()->iterateAndNext(*this);
}
}
virtual void visit(AstUCFunc* nodep, AstNUser*) {
m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment
nodep->iterateChildren(*this);
}
//-----
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
@@ -85,6 +136,8 @@ private:
// METHODS
void deadCheckMod() {
// Kill any unused modules
// V3LinkCells has a graph that is capable of this too, but we need to do it
// after we've done all the generate blocks
for (bool retry=true; retry; ) {
retry=false;
AstModule* nextmodp;
@@ -93,28 +146,33 @@ private:
if (modp->level()>2 && modp->user()==0) {
// > 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....
for (AstNode* nodep = modp->stmtsp(); nodep; nodep=nodep->nextp()) {
if (AstCell* cellp=nodep->castCell()) {
cellp->modp()->user( cellp->modp()->user() - 1);
retry = true;
}
}
// And its children may now be killable too; correct counts
// Recurse, as cells may not be directly under the module but in a generate
DeadModVisitor visitor(modp);
modp->unlinkFrBack()->deleteTree(); modp=NULL;
retry = true;
}
}
}
}
bool canElim(AstVar* nodep) {
return (!nodep->isSigPublic() // Can't elim publics!
&& !nodep->isIO()
&& (nodep->isTemp() || nodep->isParam() || m_elimUserVars));
}
void deadCheckVar() {
// Delete any unused varscopes
for (vector<AstVarScope*>::iterator it = m_vscsp.begin(); it!=m_vscsp.end(); ++it) {
if ((*it)->user() == 0 && canElim((*it)->varp())) {
UINFO(4," Dead "<<(*it)<<endl);
(*it)->unlinkFrBack()->deleteTree(); (*it)=NULL;
AstVarScope* vscp = *it;
if (vscp->user() == 0 && canElim(vscp->varp())) {
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) {
AstNodeAssign* assp = it->second;
UINFO(4," Dead assign "<<assp<<endl);
assp->unlinkFrBack()->deleteTree(); assp=NULL;
}
vscp->unlinkFrBack()->deleteTree(); vscp=NULL;
}
}
for (vector<AstVar*>::iterator it = m_varsp.begin(); it!=m_varsp.end(); ++it) {
@@ -129,6 +187,7 @@ public:
// CONSTRUCTORS
DeadVisitor(AstNetlist* nodep, bool elimUserVars) {
m_elimUserVars = elimUserVars;
m_sideEffect = false;
// Operate on whole netlist
AstNode::userClearTree(); // userp() used on entire tree
nodep->accept(*this);
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3DEAD_H_
#define _V3DEAD_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -52,7 +52,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3DELAYED_H_
#define _V3DELAYED_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -28,7 +28,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3DEPTH_H_
#define _V3DEPTH_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+12 -10
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -27,7 +27,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -159,8 +160,8 @@ private:
}
}
// Not really any way the user could do this, and we'd need to come up with some return value
//newfuncp->addStmtsp(new AstDisplay (newfuncp->fileline(),
// '\n', string("%%Error: ")+name+"() called with bad scope", NULL));
//newfuncp->addStmtsp(new AstDisplay (newfuncp->fileline(), AstDisplayType::DISPLAY,
// string("%%Error: ")+name+"() called with bad scope", NULL));
//newfuncp->addStmtsp(new AstStop (newfuncp->fileline()));
if (debug()>=9) newfuncp->dumpTree(cout," newfunc: ");
} else {
@@ -224,12 +225,13 @@ private:
if (m_scopep) {
nodep->unlinkFrBack();
m_modp->addStmtp(nodep);
}
if (nodep->funcPublic()) {
// There may be multiple public functions by the same name;
// record for later correction or making of shells
m_modFuncs.insert(make_pair(nodep->name(), nodep));
nodep->name(m_scopep->nameDotless() +"__" + nodep->name());
if (nodep->funcPublic()) {
// There may be multiple public functions by the same name;
// record for later correction or making of shells
m_modFuncs.insert(make_pair(nodep->name(), nodep));
nodep->name(m_scopep->nameDotless() +"__" + nodep->name());
}
}
}
}
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3DESCOPE_H_
#define _V3DESCOPE_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+80 -24
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -19,7 +19,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -96,12 +97,17 @@ public:
string cFuncArgs(AstCFunc* nodep) {
// Return argument list for given C function
string args = nodep->argTypes();
if (args=="") {
// Might be a user function with argument list.
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (portp->isIO() && !portp->isFuncReturn()) {
if (args != "") args+= ", ";
// Might be a user function with argument list.
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (portp->isIO() && !portp->isFuncReturn()) {
if (args != "") args+= ", ";
if (portp->isWide()) {
if (portp->isInOnly()) args += "const ";
args += portp->cType();
args += " (& "+portp->name();
args += ")["+cvtToStr(portp->widthWords())+"]";
} else {
args += portp->cType();
if (portp->isOutput()) args += "&";
args += " "+portp->name();
@@ -217,8 +223,7 @@ public:
puts(");\n");
}
virtual void visit(AstCoverInc* nodep, AstNUser*) {
puts("if (VL_LIKELY(vlSymsp->__Vm_coverageRequest))");
puts(" ++this->__Vcoverage[");
puts("++this->__Vcoverage[");
puts(cvtToStr(m_coverIds.remap(nodep->declp()))); puts("];\n");
}
virtual void visit(AstCReturn* nodep, AstNUser*) {
@@ -234,14 +239,49 @@ public:
emitIQW(nodep->modep());
if (nodep->modep()->width()>4*8) nodep->modep()->v3error("$fopen mode should be <= 4 characters");
puts("(");
if (nodep->filenamep()->isWide()) puts(cvtToStr(nodep->filenamep()->widthWords()));
if (nodep->filenamep()->isWide()) {
puts(cvtToStr(nodep->filenamep()->widthWords()));
putbs(", ");
}
if (nodep->filenamep()->widthWords() > VL_TO_STRING_MAX_WORDS) {
nodep->v3error("String of "<<nodep->filenamep()->width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h\n");
}
nodep->filenamep()->iterateAndNext(*this);
putbs(", ");
nodep->modep()->iterateAndNext(*this);
puts(");\n");
}
virtual void visit(AstReadMem* nodep, AstNUser*) {
puts("VL_READMEM_");
emitIQW(nodep->filenamep());
puts(" ("); // We take a void* rather then emitIQW(nodep->memp());
puts(nodep->isHex()?"true":"false");
putbs(",");
puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width
putbs(",");
uint32_t array_lsb = 0;
{
AstVarRef* varrefp = nodep->memp()->castVarRef();
if (!varrefp || !varrefp->varp()->arrayp(0)) { nodep->v3error("Readmem loading non-arrayed variable"); }
else {
puts(cvtToStr(varrefp->varp()->arrayElements()));
array_lsb = varrefp->varp()->arrayp(0)->lsbConst();
}
}
putbs(", ");
puts(cvtToStr(array_lsb));
putbs(",");
puts(cvtToStr(nodep->filenamep()->widthWords()));
if (nodep->filenamep()->widthWords() > VL_TO_STRING_MAX_WORDS) {
nodep->v3error("String of "<<nodep->filenamep()->width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h\n");
}
putbs(", ");
nodep->filenamep()->iterateAndNext(*this);
putbs(", ");
nodep->modep()->iterateAndNext(*this);
nodep->memp()->iterateAndNext(*this);
putbs(","); if (nodep->lsbp()) { nodep->lsbp()->iterateAndNext(*this); }
else puts(cvtToStr(array_lsb));
putbs(","); if (nodep->msbp()) { nodep->msbp()->iterateAndNext(*this); } else puts("~0");
puts(");\n");
}
virtual void visit(AstFClose* nodep, AstNUser*) {
@@ -647,6 +687,21 @@ class EmitCImp : EmitCStmts {
if (gotOne) {
puts(");\n");
//puts("VL_DEBUG_IF( if (__req) cout<<\"\tCLOCKREQ );");
for (vector<AstChangeDet*>::iterator it = m_blkChangeDetVec.begin();
it != m_blkChangeDetVec.end(); ++it) {
AstChangeDet* nodep = *it;
if (nodep->lhsp()) {
puts("VL_DEBUG_IF( if(__req && (");
bool gotOneIgnore = false;
doubleOrDetect(nodep, gotOneIgnore);
string varname;
if (nodep->lhsp()->castVarRef()) {
varname = ": "+nodep->lhsp()->castVarRef()->varp()->prettyName();
}
puts(")) cout<<\"\tCHANGE: "+nodep->fileline()->ascii()
+varname+"\"<<endl; );");
}
}
}
}
@@ -703,19 +758,19 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
if (nodep->attrScClocked() && nodep->isInput()) {
puts("sc_in_clk\t");
} else {
if (nodep->isTristate()) puts("sc_inout<");
if (nodep->isInout()) puts("sc_inout<");
else if (nodep->isInput()) puts("sc_in<");
else if (nodep->isOutput()) puts("sc_out<");
else nodep->v3fatalSrc("Unknown type");
puts(nodep->cType());
puts(nodep->scType());
puts(">\t");
}
puts(nodep->name());
puts(";\n");
} else { // C++ signals
ofp()->putAlign(nodep->isStatic(), nodep->widthAlignBytes());
if (nodep->isTristate()) puts("VL_INOUT");
if (nodep->isInout()) puts("VL_INOUT");
else if (nodep->isInput()) puts("VL_IN");
else if (nodep->isOutput()) puts("VL_OUT");
else nodep->v3fatalSrc("Unknown type");
@@ -910,7 +965,6 @@ string EmitCStmts::displayFormat(AstNode* widthNodep, string in,
} else {
fmt=in;
}
if (widthNodep->isQuad() && fmtLetter!='c' && fmtLetter!='s' && !reallyString) fmt+="ll";
return fmt;
}
@@ -941,10 +995,17 @@ void EmitCStmts::displayArg(AstDisplay* dispp, AstNode** elistp, string fmt, cha
emitDispState.pushFormat(pfmt);
emitDispState.pushArg(*elistp,func);
} else {
string func;
string nfmt = displayFormat(*elistp, fmt, fmtLetter, true, false);
// We don't need to check for fmtLetter=='d', as it is above.
if ((*elistp)->isQuad() && (fmtLetter=='u'||fmtLetter=='o'||fmtLetter=='x')) {
nfmt+="ll";
func="(unsigned long long)("; // Must match %ull to avoid warnings
}
string pfmt = "%"+nfmt+fmtLetter;
emitDispState.pushFormat(pfmt);
emitDispState.pushArg(*elistp,"");
emitDispState.pushArg(*elistp,func);
}
// Next parameter
*elistp = (*elistp)->nextp();
@@ -952,7 +1013,6 @@ void EmitCStmts::displayArg(AstDisplay* dispp, AstNode** elistp, string fmt, cha
void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
string vformat = nodep->text();
bool addNewline = (nodep->newline() == '\n');
AstNode* elistp = nodep->exprsp();
// Convert Verilog display to C printf formats
@@ -1015,7 +1075,7 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
if (elistp != NULL) {
nodep->v3error("Extra arguments for $display format\n");
}
if (addNewline) emitDispState.pushFormat("\\n");
if (nodep->addNewline()) emitDispState.pushFormat("\\n");
displayEmit(nodep);
}
@@ -1246,12 +1306,8 @@ void EmitCImp::emitWrapEval(AstModule* modp) {
puts("while (VL_LIKELY(__Vchange)) {\n");
puts( "VL_DEBUG_IF(cout<<\" Clock loop\"<<endl;);\n");
#endif
// Not exactly correct for coverage. w/combo logic interspersed, this is complicated. Punt.
// Perhaps have temp & each _combo_ turn it on or off
if (v3Global.opt.coverage()) puts( "vlSymsp->__Vm_coverageRequest = true;\n");
puts( "vlSymsp->__Vm_activity = true;\n");
puts( "_eval(vlSymsp);\n");
if (v3Global.opt.coverage()) puts( "vlSymsp->__Vm_coverageRequest = false;\n");
#ifndef NEW_ORDERING
puts( "__Vchange = _change_request(vlSymsp);\n");
puts( "if (++__VclockLoop > 100) vl_fatal(__FILE__,__LINE__,__FILE__,\"Verilated model didn't converge\");\n");
@@ -1284,7 +1340,7 @@ void EmitCImp::emitWrapEval(AstModule* modp) {
void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& prefixIfImp) {
// Put out a list of signal declarations
// in order of 0:clocks, 1:uint8, 2:uint16, 4:uint32, 5:uint64, 6:wide, 7:arrays
// in order of 0:clocks, 1:vluint8, 2:vluint16, 4:vluint32, 5:vluint64, 6:wide, 7:arrays
// This aids cache packing and locality
// Largest->smallest reduces the number of pad variables.
// But for now, Smallest->largest makes it more likely a small offset will allow access to the signal.
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3EMITC_H_
#define _V3EMITC_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+4 -3
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -22,7 +22,8 @@
#ifndef _V3EMITCBASE_H_
#define _V3EMITCBASE_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -109,7 +110,7 @@ public:
bool optSystemPerl() { return v3Global.opt.systemPerl(); }
static string symClassName() { return v3Global.opt.prefix()+"__Syms"; }
static string symClassVar() { return symClassName()+"* __restrict vlSymsp"; }
static string symTopAssign() { return v3Global.opt.prefix()+"* __restrict vlTOPp = vlSymsp->TOPp;"; }
static string symTopAssign() { return v3Global.opt.prefix()+"* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;"; }
static string modClassName(AstModule* modp) { // Return name of current module being processed
if (modp->isTop()) {
return v3Global.opt.prefix();
+5 -9
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -19,7 +19,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -124,18 +125,14 @@ void EmitCSyms::emitInt() {
//puts("\n// STATIC STATE\n");
puts("\n// LOCAL STATE\n");
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(uint64_t));
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(vluint64_t));
puts("const char* __Vm_namep;\n"); // Must be before subcells, as constructor order needed before _vlCoverInsert.
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
puts("bool\t__Vm_activity;\t\t///< Used by trace routines to determine change occurred\n");
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
puts("bool\t__Vm_didInit;\n");
if (v3Global.opt.coverage()) {
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
puts("bool __Vm_coverageRequest;\n");
}
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(uint64_t));
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(vluint64_t));
puts("\n// SUBCELL STATE\n");
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
AstScope* scopep = it->first; AstModule* modp = it->second;
@@ -184,7 +181,6 @@ void EmitCSyms::emitImp() {
puts("\t: __Vm_namep(namep)\n"); // No leak, as we get destroyed when the top is destroyed
puts("\t, __Vm_activity(false)\n");
puts("\t, __Vm_didInit(false)\n");
if (v3Global.opt.coverage()) puts("\t, __Vm_coverageRequest(false)\n");
puts("\t// Setup submodule names\n");
char comma=',';
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
+6 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2004-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -19,7 +19,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -96,6 +97,9 @@ public:
// Imply generating verilated.o
if (v3Global.opt.exe()) {
v3Global.opt.addCppFile("verilated.cpp");
if (v3Global.opt.trace()) {
v3Global.opt.addCppFile("SpTraceVcdC.cpp");
}
}
V3StringSet dirs;
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3EMITMK_H_
#define _V3EMITMK_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+14 -3
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2004-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -19,7 +19,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -192,6 +193,16 @@ public:
if (nodep->filep()) nodep->filep()->iterateChildren(*this);
puts(");\n");
}
virtual void visit(AstReadMem* nodep, AstNUser*) {
putbs(nodep->verilogKwd());
putbs(" (");
if (nodep->filenamep()) nodep->filenamep()->iterateChildren(*this);
putbs(",");
if (nodep->memp()) nodep->memp()->iterateChildren(*this);
if (nodep->lsbp()) { putbs(","); nodep->lsbp()->iterateChildren(*this); }
if (nodep->msbp()) { putbs(","); nodep->msbp()->iterateChildren(*this); }
puts(");\n");
}
virtual void visit(AstNodeFor* nodep, AstNUser*) {
puts("for (");
m_suppressSemi = true;
@@ -199,7 +210,7 @@ public:
puts(";");
nodep->condp()->iterateAndNext(*this);
puts(";");
nodep->assignsp()->iterateAndNext(*this);
nodep->incsp()->iterateAndNext(*this);
m_suppressSemi = false;
puts(") {\n");
nodep->bodysp()->iterateAndNext(*this);
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3EMITV_H_
#define _V3EMITV_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+16 -8
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -92,7 +92,7 @@ void FileLine::lineDirective(const char* textp) {
bool FileLine::warnOff(const string& msg, bool flag) {
V3ErrorCode code (msg.c_str());
if (code == V3ErrorCode::ERROR) {
if (code < V3ErrorCode::FIRST_WARN) {
return false;
} else {
warnOff(code, flag);
@@ -168,9 +168,8 @@ void FileLine::v3errorEnd(ostringstream& str) {
void V3Error::init() {
for (int i=0; i<V3ErrorCode::MAX; i++) {
s_describedEachWarn[i] = false;
s_pretendError[i] = false;
s_pretendError[i] = V3ErrorCode(i).pretendError();
}
pretendError(V3ErrorCode::BLKANDNBLK, true);
if (string(V3ErrorCode(V3ErrorCode::MAX).ascii()) != " MAX") {
v3fatalSrc("Enum table in V3ErrorCode::ascii() is munged");
@@ -204,8 +203,9 @@ void V3Error::abortIfErrors() {
string V3Error::msgPrefix(V3ErrorCode code) {
if (code==V3ErrorCode::SUPPRESS) return "-arning-suppressed: ";
else if (code==V3ErrorCode::FATAL) return "%Error: ";
else if (code==V3ErrorCode::ERROR
|| s_pretendError[code]) return "%Error: ";
else if (code==V3ErrorCode::ERROR) return "%Error: ";
else if (code<V3ErrorCode::FIRST_WARN
|| s_pretendError[code]) return "%Error-"+(string)code.ascii()+": ";
else return "%Warning-"+(string)code.ascii()+": ";
}
@@ -236,6 +236,9 @@ void V3Error::v3abort () {
}
void V3Error::v3errorEnd (ostringstream& sstr) {
#ifdef __COVERITY__
if (s_errorCode==V3ErrorCode::FATAL) __coverity_panic__(x);
#endif
if (s_errorCode!=V3ErrorCode::SUPPRESS || debug()) {
cerr<<msgPrefix()<<sstr.str();
if (sstr.str()[sstr.str().length()-1] != '\n') {
@@ -268,8 +271,13 @@ void V3Error::v3errorEnd (ostringstream& sstr) {
}
#endif
}
abort();
// exit(10);
if (V3Error::debugDefault()) {
cerr<<msgPrefix()<<"Aborting since under --debug"<<endl;
abort();
} else {
exit(10);
}
}
}
}
+14 -4
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3ERROR_H_
#define _V3ERROR_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <string>
#include <iostream>
#include <sstream>
@@ -34,9 +35,13 @@ public:
enum en {
SUPPRESS, // Warning suppressed by user
FATAL, // Kill the program
ERROR, // Error out, can't suppress
ERROR, // General error out, can't suppress
// Error codes:
MULTITOP, // Error: Multiple top level modules
TASKNSVAR, // Error: Task I/O not simple
// Warning codes:
FIRST_WARN, // Just a code so the program knows where to start warnings
//
BLKANDNBLK, // Blocked and non-blocking assignments to same variable
CASEINCOMPLETE, // Case statement has missing values
CASEOVERLAP, // Case statements overlap
@@ -45,6 +50,7 @@ public:
COMBDLY, // Combinatorial delayed assignment
GENCLK, // Generated Clock
IMPLICIT, // Implicit wire
IMPURE, // Impure function not being inlined
MULTIDRIVEN, // Driven from multiple blocks
UNDRIVEN, // No drivers
UNOPT, // Unoptimizable block
@@ -66,10 +72,11 @@ public:
const char* names[] = {
// Leading spaces indicate it can't be disabled.
" SUPPRESS", " FATAL", " ERROR",
"MULTITOP", "TASKNSVAR",
" FIRST_WARN",
"BLKANDNBLK",
"CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST",
"COMBDLY", "GENCLK", "IMPLICIT",
"COMBDLY", "GENCLK", "IMPLICIT", "IMPURE",
"MULTIDRIVEN",
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
"VARHIDDEN", "WIDTH",
@@ -79,6 +86,9 @@ public:
};
// Warnings that warn about nasty side effects
bool dangerous() const { return ( m_e==COMBDLY );};
// Warnings we'll present to the user as errors
// Later -Werror- options may make more of these.
bool pretendError() const { return ( m_e==BLKANDNBLK || m_e==IMPURE); };
};
inline bool operator== (V3ErrorCode lhs, V3ErrorCode rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (V3ErrorCode lhs, V3ErrorCode::en rhs) { return (lhs.m_e == rhs); }
+7 -6
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2004-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2004-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -30,7 +30,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -64,11 +65,8 @@ private:
if (nodep->isWide()) {
return V3Number (nodep->fileline(), VL_WORDSIZE, VL_MASK_I(nodep->widthMin()));
} else {
V3Number zero (nodep->fileline(), nodep->widthMin(),0);
V3Number masksmall (nodep->fileline(), nodep->widthMin());
masksmall.opNot(zero);
V3Number mask (nodep->fileline(), longOrQuadWidth(nodep));
mask.opAssign(masksmall);
mask.setMask(nodep->widthMin());
return mask;
}
}
@@ -660,6 +658,9 @@ private:
// Lhs or Rhs may be word, long, or quad.
// newAstWordSelClone nicely abstracts the difference.
int rhsshift = rhsp->rhsp()->widthMin();
// Sometimes doing the words backwards is preferrable.
// When we have x={x,foo} backwards is better, when x={foo,x} forward is better
// However V3Subst tends to rip this up, so not worth optimizing now.
for (int w=0; w<rhsp->widthWords(); w++) {
addWordAssign(nodep, w,
new AstOr (rhsp->fileline(),
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3EXPAND_H_
#define _V3EXPAND_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -19,7 +19,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdarg.h>
#include <sys/stat.h>
#include <unistd.h>
+6 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3FILE_H_
#define _V3FILE_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include <stdio.h>
#include <stack>
@@ -42,6 +43,9 @@ public:
}
static ofstream* new_ofstream(const string& filename, bool append=false) {
addTgtDepend(filename);
return new_ofstream_nodepend (filename, append);
}
static ofstream* new_ofstream_nodepend(const string& filename, bool append=false) {
if (append) {
return new ofstream(filename.c_str(), ios::app);
} else {
+13 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -26,7 +26,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -197,10 +198,18 @@ public:
m_substTreep = NULL;
m_buffersOnly = buffersOnly;
m_lhsVarRef = NULL;
// Iterate
nodep->accept(*this);
// Check results
if (!m_substTreep) {
clearSimple("No assignment found\n");
}
for (GateVarRefList::const_iterator it = rhsVarRefs().begin();
it != rhsVarRefs().end(); ++it) {
if (m_lhsVarRef && m_lhsVarRef->varScopep() == (*it)->varScopep()) {
clearSimple("Circular logic\n"); // Oh my, we'll get a UNOPTFLAT much later.
}
}
if (debug()>=9 && !m_isSimple) {
nodep->dumpTree(cout,"\tgate!Ok: ");
}
@@ -223,6 +232,7 @@ private:
//Entire netlist:
// AstVarScope::userp -> GateVarVertex* for usage var, 0=not set yet
// {statement}Node::userp -> GateLogicVertex* for this statement
// STATE
V3Graph m_graph; // Scoreboard of var usages/dependencies
GateLogicVertex* m_logicVertexp; // Current statement being tracked, NULL=ignored
@@ -457,6 +467,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
}
}
}
// Process it
if (!doit) {
if (allowMultiIn && (debug()>=9)) {
UINFO(9, "Not ok simp"<<okVisitor.isSimple()<<" mi"<<multiInputs
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3GATE_H_
#define _V3GATE_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -24,7 +24,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3GENCLK_H_
#define _V3GENCLK_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -22,7 +22,8 @@
#ifndef _V3GLOBAL_H_
#define _V3GLOBAL_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <string>
#include "V3Error.h"
+8 -3
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -19,7 +19,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -179,6 +180,7 @@ void V3Graph::userClearVertices() {
// the extra code on each read of user() would probably slow things down more then help.
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
vertexp->user(0);
vertexp->userp(NULL); // Its a union, but might be different size then user()
}
}
@@ -186,7 +188,8 @@ void V3Graph::userClearEdges() {
// Clear user() in all of tree
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
edgep->userp(NULL);
edgep->user(0);
edgep->userp(NULL); // Its a union, but might be different size then user()
}
}
}
@@ -252,6 +255,8 @@ void V3Graph::dumpDotFile(const string& filename, bool colorAsSubgraph) {
*logp<<"digraph v3graph {\n";
*logp<<"\trankdir="<<dotRankDir()<<"\n";
*logp<<"\tsize="<<"\"7.5,10\""<<"\n";
*logp<<"\tnTITLE\t[fontsize=20 label=\""<<filename<<"\", shape=box, style=bold, color=black];\n";
*logp<<"\n";
// List of all possible subgraphs
typedef multimap<string,V3GraphVertex*> SubgraphMmap;
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3GRAPH_H_
#define _V3GRAPH_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3List.h"
#include <vector>
+11 -6
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -19,7 +19,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -36,6 +37,7 @@
// Break the minimal number of backward edges to make the graph acyclic
class GraphAcycVertex : public V3GraphVertex {
// user() is used for various sub-algorithm pieces
V3GraphVertex* m_origVertexp; // Pointer to first vertex this represents
protected:
friend class GraphAcyc;
@@ -307,6 +309,9 @@ void GraphAcyc::simplifyOne (GraphAcycVertex* avertexp) {
avertexp->setDelete(); // Mark so we won't delete it twice
// Make a new edge connecting the two vertices directly
// If both are breakable, we pick the one with less weight, else it's arbitrary
// We can forget about the origEdge list for the "non-selected" set of edges,
// as we need to break only one set or the other set of edges, not both.
// (This is why we must give preference to the cutable set.)
V3GraphEdge* templateEdgep = ( (inEdgep->cutable()
&& (!outEdgep->cutable()
|| inEdgep->weight()<outEdgep->weight() ))
@@ -352,7 +357,7 @@ void GraphAcyc::simplifyDup (GraphAcycVertex* avertexp) {
if (avertexp->isDelete()) return;
// Clear marks
for (V3GraphEdge* edgep = avertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
edgep->top()->user(false);
edgep->top()->userp(NULL);
}
// Mark edges and detect duplications
for (V3GraphEdge* nextp, *edgep = avertexp->outBeginp(); edgep; edgep=nextp) {
@@ -363,16 +368,16 @@ void GraphAcyc::simplifyDup (GraphAcycVertex* avertexp) {
if (!prevEdgep->cutable()) {
// !cutable duplicates prev !cutable: we can ignore it, redundant
// cutable duplicates prev !cutable: know it's not a relevant loop, ignore it
UINFO(8," DelDupEdge "<<avertexp<<endl);
UINFO(8," DelDupEdge "<<avertexp<<" -> "<<edgep->top()<<endl);
edgep->unlinkDelete(); edgep = NULL;
} else if (!edgep->cutable()) {
// !cutable duplicates prev cutable: delete the earlier cutable
UINFO(8," DelDupPrev "<<avertexp<<endl);
UINFO(8," DelDupPrev "<<avertexp<<" -> "<<prevEdgep->top()<<endl);
prevEdgep->unlinkDelete(); prevEdgep = NULL;
outVertexp->userp(edgep);
} else {
// cutable duplicates prev cutable: combine weights
UINFO(8," DelDupComb "<<avertexp<<endl);
UINFO(8," DelDupComb "<<avertexp<<" -> "<<edgep->top()<<endl);
prevEdgep->weight (prevEdgep->weight() + edgep->weight());
addOrigEdgep (prevEdgep, edgep);
edgep->unlinkDelete(); edgep = NULL;
+4 -3
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -19,7 +19,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -85,7 +86,7 @@ private:
void vertexIterate(V3GraphVertex* vertexp) {
// Clear marks
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
edgep->top()->user(false);
edgep->top()->userp(NULL);
}
// Mark edges and detect duplications
for (V3GraphEdge* nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) {
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3GRAPHALG_H_
#define _V3GRAPHALG_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Global.h"
#include "V3Graph.h"
+4 -3
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -19,7 +19,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -64,7 +65,7 @@ class GraphNfaToDfa : GraphAlg {
private:
// TYPES
typedef deque<DfaVertex*> DfaStates;
typedef multimap<uint64_t,DfaVertex*> HashMap;
typedef multimap<vluint64_t,DfaVertex*> HashMap;
// MEMBERS
uint32_t m_step; // Processing step, so we can avoid clearUser all the time
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3GRAPHDFA_H_
#define _V3GRAPHDFA_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <vector>
#include "V3Global.h"
+32 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -19,7 +19,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -310,6 +311,34 @@ public:
gp->dfaReduce();
}
};
//======================================================================
class V3GraphTestImport : public V3GraphTest {
void dotImport();
public:
virtual string name() { return "import"; }
virtual void runTest() {
DfaGraph* gp = &m_graph;
if (V3GraphTest::debug()) gp->debug(9);
dotImport();
dump();
gp->acyclic(&V3GraphEdge::followAlwaysTrue);
dump();
gp->rank(&V3GraphEdge::followAlwaysTrue);
dump();
}
};
#if 0
# include "graph_export.cpp"
#else
void V3GraphTestImport::dotImport() {
}
#endif
//======================================================================
void V3Graph::test() {
@@ -319,5 +348,6 @@ void V3Graph::test() {
{ V3GraphTestAcyc test; test.run(); }
{ V3GraphTestVars test; test.run(); }
{ V3GraphTestDfa test; test.run(); }
{ V3GraphTestImport test; test.run(); }
if (V3GraphTest::debug()) v3fatalSrc("Exiting due to graph testing enabled");
}
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -26,7 +26,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3HASHED_H_
#define _V3HASHED_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+6 -7
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -29,7 +29,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -111,7 +112,6 @@ private:
nodep->name(), nodep->modp()->origName());
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
// Create assignments to the pins
AstNode* assignlistsp = NULL;
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
UINFO(6," Pin change from "<<pinp->modVarp()<<endl);
// First, simplify it
@@ -142,13 +142,11 @@ private:
// Cleanup var names, etc, to not conflict
m_cellp = nodep;
newmodp->iterateAndNext(*this);
if (assignlistsp) assignlistsp->iterateAndNext(*this); // And cleanup any varrefs under assigns we created...
m_cellp = NULL;
// Move statements to top module
if (debug()>=9) { newmodp->dumpTree(cout,"fixmod:"); }
AstNode* stmtsp = newmodp->stmtsp();
if (stmtsp) stmtsp->unlinkFrBackWithNext();
if (assignlistsp) m_modp->addStmtp(assignlistsp);
if (stmtsp) m_modp->addStmtp(stmtsp);
// Remove the cell
newmodp->deleteTree(); newmodp=NULL; // Clear any leftover ports, etc
@@ -237,8 +235,8 @@ private:
}
virtual void visit(AstDisplay* nodep, AstNUser*) {
// If there's a %m in the display text, we add a special node that will contain the name()
if (m_cellp
&& nodep->name().find("%m") != string::npos) {
// Similar code in V3Begin
if (m_cellp && nodep->needScopeTracking()) {
// To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext();
@@ -353,6 +351,7 @@ private:
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
// Cleanup link until V3LinkDot can correct it
nodep->taskp(NULL);
nodep->iterateChildren(*this);
}
// Nop's to speed up the loop
virtual void visit(AstAlways* nodep, AstNUser*) {
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3INLINE_H_
#define _V3INLINE_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+18 -9
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -26,7 +26,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -79,7 +80,7 @@ private:
// or ASSIGNW(expr,VARXREF(p)) (if sub's output)
UINFO(4," PIN "<<nodep<<endl);
if (debug()>=9) nodep->dumpTree(cout," Pin_oldb: ");
if (nodep->modVarp()->isOutput() && nodep->exprp()->castConst())
if (nodep->modVarp()->isOutOnly() && nodep->exprp()->castConst())
nodep->v3error("Output pin is assigned to a constant, electrical short");
// Use userp on the PIN to indicate we created an assign for this pin
if (!nodep->user()) {
@@ -90,7 +91,9 @@ private:
AstNode* exprp = nodep->exprp()->cloneTree(false);
if (nodep->width() != nodep->modVarp()->width())
nodep->v3fatalSrc("Width mismatch, should have been handled in pinReconnectSimple\n");
if (nodep->modVarp()->isOutput()) {
if (nodep->modVarp()->isInout()) {
nodep->v3fatalSrc("Unsupported: Verilator is a 2-state simulator");
} else if (nodep->modVarp()->isOutput()) {
AstNode* rhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
rhsp->widthSignedFrom(nodep);
AstAssignW* assp = new AstAssignW (exprp->fileline(), exprp, rhsp);
@@ -157,7 +160,11 @@ private:
nodep->addNextHere(newp);
// Remove ranging and fix name
newp->rangep()->unlinkFrBack()->deleteTree();
newp->name(newp->name()+"__"+cvtToStr(m_instNum));
// Somewhat illogically, we need to rename the orignal name of the cell too.
// as that is the name users expect for dotting
// The spec says we add [x], but that won't work in C...
newp->name(newp->name()+"__BRA__"+cvtToStr(m_instNum)+"__KET__");
newp->origName(newp->origName()+"__BRA__"+cvtToStr(m_instNum)+"__KET__");
// Fixup pins
newp->pinsp()->iterateAndNext(*this);
if (debug()==9) { newp->dumpTree(cout,"newcell: "); cout<<endl; }
@@ -194,7 +201,7 @@ private:
}
// Save some time
virtual void visit(AstNodeStmt*, AstNUser*) {}
virtual void visit(AstNodeMath*, AstNUser*) {}
//--------------------
// Default: Just iterate
virtual void visit(AstNode* nodep, AstNUser*) {
@@ -232,12 +239,14 @@ void V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstModule* modp) {
} else {
// Make a new temp wire
//if (1||debug()>=9) { pinp->dumpTree(cout,"in_pin:"); }
AstAssignW* assignp;
AstAssignW* assignp = NULL;
AstNode* pinexprp = pinp->exprp()->unlinkFrBack();
string newvarname = "__Vcellinp__"+cellp->name()+"__"+pinp->name();
AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp);
modp->addStmtp(newvarp);
if (pinVarp->isOutput()) {
if (pinVarp->isInout()) {
pinVarp->v3fatalSrc("Unsupported: Inout connections to pins must be direct one-to-one connection (without any expression)");
} else if (pinVarp->isOutput()) {
// See also V3Inst
AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, false);
if (pinp->width() > rhsp->width()) {
@@ -261,7 +270,7 @@ void V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstModule* modp) {
pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, false));
}
pinp->widthSignedFrom(pinp->exprp());
modp->addStmtp(assignp);
if (assignp) modp->addStmtp(assignp);
//if (1||debug()) { pinp->dumpTree(cout," out:"); }
//if (1||debug()) { assignp->dumpTree(cout," aout:"); }
}
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3INST_H_
#define _V3INST_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2005-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2005-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3LANGUAGEWORDS_H_
#define _V3LANGUAGEWORDS_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <map>
//============================================================================
+300 -138
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -28,7 +28,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
@@ -38,152 +39,243 @@
#include "V3Life.h"
#include "V3Stats.h"
#include "V3Ast.h"
#include "V3Const.h"
//######################################################################
// Life state, as a visitor of each AstNode
// Structure for global state
class LifeVarEntry {
AstNode* m_assignp; // Last assignment to this varscope
bool m_firstSet; // True if creation was a set (and thus block above may have a set that can be deleted
class LifeState {
// STATE
public:
LifeVarEntry() { // Construction for when a var is used
clearAssign();
m_firstSet = false;
V3Double0 m_statAssnDel; // Statistic tracking
V3Double0 m_statAssnCon; // Statistic tracking
public:
LifeState() {}
~LifeState() {
V3Stats::addStat("Optimizations, Lifetime assign deletions", m_statAssnDel);
V3Stats::addStat("Optimizations, Lifetime constant prop", m_statAssnCon);
}
LifeVarEntry(AstNode* assp) { // Construction for when a var is set
m_assignp = assp;
m_firstSet = true;
}
LifeVarEntry(bool) { // Construction for when a var is set, but ass isn't
m_assignp = NULL;
m_firstSet = true;
}
AstNode* assignp() const { return m_assignp; }
bool firstSet() const { return m_firstSet; }
void clearAssign() { m_assignp = NULL; }
void newerAssign(AstNode* assp) { m_assignp = assp; }
};
class LifeVisitor : public AstNVisitor {
private:
// NODE STATE
// AstVarScope::user() -> int. Used in combining to detect duplicates
//######################################################################
// Structure for each variable encountered
// STATE
//static int debug() { return 9; }
int m_ifCount; // If counter
V3Double0 m_statAssnDel; // Statistic tracking
class LifeVarEntry {
AstNodeAssign* m_assignp; // Last assignment to this varscope, NULL if no longer relevant
AstConst* m_constp; // Known constant value
bool m_setBeforeUse; // First access was a set (and thus block above may have a set that can be deleted
bool m_everSet; // Was ever assigned (and thus above block may not preserve constant propagation)
inline void init (bool setBeforeUse) {
m_assignp = NULL;
m_constp = NULL;
m_setBeforeUse = setBeforeUse;
m_everSet = false;
}
public:
class SIMPLEASSIGN {};
class COMPLEXASSIGN {};
class CONSUMED {};
LifeVarEntry(SIMPLEASSIGN, AstNodeAssign* assp) {
init(true); simpleAssign(assp);
}
LifeVarEntry(COMPLEXASSIGN) {
init(false); complexAssign();
}
LifeVarEntry(CONSUMED) {
init(false); consumed();
}
~LifeVarEntry() {}
inline void simpleAssign(AstNodeAssign* assp) { // New simple A=.... assignment
m_assignp = assp;
m_constp = NULL;
m_everSet = true;
if (assp->rhsp()->castConst()) m_constp = assp->rhsp()->castConst();
}
inline void complexAssign() { // A[x]=... or some complicated assignment
m_assignp = NULL;
m_constp = NULL;
m_everSet = true;
}
inline void consumed() { // Rvalue read of A
m_assignp = NULL;
}
AstNodeAssign* assignp() const { return m_assignp; }
AstConst* constNodep() const { return m_constp; }
bool setBeforeUse() const { return m_setBeforeUse; }
bool everSet() const { return m_everSet; }
};
//######################################################################
// Structure for all variables under a given meta-basic block
class LifeBlock {
// NODE STATE
// Cleared each AstIf:
// AstVarScope::user() -> int. Used in combining to detect duplicates
// LIFE MAP
// For each basic block, we'll make a new map of what variables that if/else is changing
typedef std::map<AstVarScope*, LifeVarEntry> LifeMap;
LifeMap *m_lifep; // Current active lifetime map for current scope
LifeMap m_map; // Current active lifetime map for current scope
LifeBlock* m_aboveLifep; // Upper life, or NULL
LifeState* m_statep; // Current global state
public:
LifeBlock(LifeBlock* aboveLifep, LifeState* statep) {
m_aboveLifep = aboveLifep; // Null if top
m_statep = statep;
}
~LifeBlock() {}
// METHODS
void checkRemoveAssign(LifeVarEntry* entp) {
// Check the var entry, and remove if appropriate
if (AstNode* oldassp = entp->assignp()) {
UINFO(7," PREV: "<<oldassp<<endl);
// Redundant assignment, in same level block
if (debug()>4) oldassp->dumpTree(cout, " REMOVE/SAMEBLK ");
entp->clearAssign();
oldassp->unlinkFrBack();
pushDeletep(oldassp);
m_statAssnDel++;
void checkRemoveAssign(const LifeMap::iterator& it) {
AstVar* varp = it->first->varp();
LifeVarEntry* entp = &(it->second);
if (!varp->isSigPublic()) {
// Rather then track what sigs AstUCFunc/AstUCStmt may change,
// we just don't optimize any public sigs
// Check the var entry, and remove if appropriate
if (AstNode* oldassp = entp->assignp()) {
UINFO(7," PREV: "<<oldassp<<endl);
// Redundant assignment, in same level block
if (debug()>4) oldassp->dumpTree(cout, " REMOVE/SAMEBLK ");
entp->complexAssign();
oldassp->unlinkFrBack()->deleteTree(); oldassp=NULL;
m_statep->m_statAssnDel++;
}
}
}
void setLast(AstVarScope* nodep, AstNode* assp) {
void simpleAssign(AstVarScope* nodep, AstNodeAssign* assp) {
// Do we have a old assignment we can nuke?
UINFO(4," ASSIGNof: "<<nodep<<endl);
UINFO(7," new: "<<assp<<endl);
LifeMap::iterator iter = m_lifep->find(nodep);
if (iter != m_lifep->end()) {
checkRemoveAssign(&(iter->second));
iter->second.newerAssign(assp);
LifeMap::iterator it = m_map.find(nodep);
if (it != m_map.end()) {
checkRemoveAssign(it);
it->second.simpleAssign(assp);
} else {
m_lifep->insert(make_pair(nodep,LifeVarEntry(assp)));
m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::SIMPLEASSIGN(), assp)));
}
//lifeDump();
}
void clearLastAssign(AstVarScope* nodep) {
void complexAssign(AstVarScope* nodep) {
UINFO(4," clearof: "<<nodep<<endl);
LifeMap::iterator iter = m_lifep->find(nodep);
if (iter != m_lifep->end()) {
iter->second.clearAssign();
LifeMap::iterator it = m_map.find(nodep);
if (it != m_map.end()) {
it->second.complexAssign();
} else {
m_lifep->insert(make_pair(nodep,LifeVarEntry()));
m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::COMPLEXASSIGN())));
}
}
void lifeDump(LifeMap* lifep) {
void varUsageReplace (AstVarScope* nodep, AstVarRef* varrefp) {
// Variable rvalue. If it references a constant, we can simply replace it
LifeMap::iterator it = m_map.find(nodep);
if (it != m_map.end()) {
if (AstConst* constp = it->second.constNodep()) {
if (!varrefp->varp()->isSigPublic()) {
// Aha, variable is constant; substitute in.
// We'll later constant propagate
UINFO(4," replaceconst: "<<varrefp<<endl);
varrefp->replaceWith(constp->cloneTree(false));
varrefp->deleteTree(); varrefp=NULL;
m_statep->m_statAssnCon++;
return; // **DONE, no longer a var reference**
}
}
UINFO(4," usage: "<<nodep<<endl);
it->second.consumed();
} else {
m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::CONSUMED())));
}
}
void complexAssignFind(AstVarScope* nodep) {
LifeMap::iterator it = m_map.find(nodep);
if (it != m_map.end()) {
UINFO(4," casfind: "<<it->first<<endl);
it->second.complexAssign();
} else {
m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::COMPLEXASSIGN())));
}
}
void consumedFind(AstVarScope* nodep) {
LifeMap::iterator it = m_map.find(nodep);
if (it != m_map.end()) {
it->second.consumed();
} else {
m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::CONSUMED())));
}
}
void lifeToAbove() {
// Any varrefs under a if/else branch affect statements outside and after the if/else
if (!m_aboveLifep) v3fatalSrc("Pushing life when already at the top level");
for (LifeMap::iterator it = m_map.begin(); it!=m_map.end(); ++it) {
AstVarScope* nodep = it->first;
m_aboveLifep->complexAssignFind(nodep);
if (it->second.everSet()) {
// Record there may be an assignment, so we don't constant propagate across the if.
complexAssignFind(nodep);
} else {
// Record consumption, so we don't eliminate earlier assignments
consumedFind(nodep);
}
}
}
void dualBranch (LifeBlock* life1p, LifeBlock* life2p) {
// Find any common sets on both branches of IF and propagate upwards
//life1p->lifeDump();
//life2p->lifeDump();
AstNode::userClearTree(); // userp() used on entire tree
for (LifeMap::iterator it = life1p->m_map.begin(); it!=life1p->m_map.end(); ++it) {
// When the if branch sets a var before it's used, mark that variable
if (it->second.setBeforeUse()) it->first->user(1);
}
for (LifeMap::iterator it = life2p->m_map.begin(); it!=life2p->m_map.end(); ++it) {
// When the else branch sets a var before it's used
AstVarScope* nodep = it->first;
if (it->second.setBeforeUse() && nodep->user()) {
// Both branches set the var, we can remove the assignment before the IF.
UINFO(4,"DUALBRANCH "<<nodep<<endl);
LifeMap::iterator itab = m_map.find(nodep);
if (itab != m_map.end()) {
checkRemoveAssign(itab);
}
}
}
//this->lifeDump();
}
// DEBUG
void lifeDump() {
UINFO(5, " LifeMap:"<<endl);
for (LifeMap::iterator it = lifep->begin(); it!=lifep->end(); ++it) {
for (LifeMap::iterator it = m_map.begin(); it!=m_map.end(); ++it) {
UINFO(5, " Ent: "
<<(it->second.firstSet()?"[F] ":" ")
<<(it->second.setBeforeUse()?"[F] ":" ")
<<it->first<<endl);
if (it->second.assignp()) {
UINFO(5, " Ass: "<<it->second.assignp()<<endl);
}
}
}
void clearLifeFromSublife (LifeMap* sublifep) {
// Any varrefs under a if/else branch affect statements outside and after the if/else
for (LifeMap::iterator it = sublifep->begin(); it!=sublifep->end(); ++it) {
clearLastAssign(it->first);
}
}
void dualBranch (LifeMap* life1p, LifeMap* life2p) {
// Find any common sets on both branches of IF and propagate upwards
//lifeDump(life1p);
//lifeDump(life2p);
m_ifCount++;
for (LifeMap::iterator it = life1p->begin(); it!=life1p->end(); ++it) {
// When the if branch sets a var before it's used, mark that variable
if (it->second.firstSet()) it->first->user(m_ifCount);
}
for (LifeMap::iterator it = life2p->begin(); it!=life2p->end(); ++it) {
// When the else branch sets a var before it's used
AstVarScope* nodep = it->first;
if (it->second.firstSet()
&& nodep->user()==m_ifCount) { // And the if hit the same var
UINFO(4,"DUALBRANCH "<<nodep<<endl);
LifeMap::iterator iter = m_lifep->find(nodep);
if (iter != m_lifep->end()) {
checkRemoveAssign(&(iter->second));
iter->second.clearAssign();
} else {
m_lifep->insert(make_pair(nodep,LifeVarEntry(true)));
}
}
}
//lifeDump(m_lifep);
}
};
//######################################################################
// Life state, as a visitor of each AstNode
class LifeVisitor : public AstNVisitor {
private:
// STATE
LifeState* m_statep; // Current state
bool m_sideEffect; // Side effects discovered in assign RHS
//static int debug() { return 9; }
// LIFE MAP
// For each basic block, we'll make a new map of what variables that if/else is changing
typedef std::map<AstVarScope*, LifeVarEntry> LifeMap;
LifeBlock* m_lifep; // Current active lifetime map for current scope
// METHODS
// VISITORS
virtual void visit(AstModule* nodep, AstNUser*) {
// Only track the top scopes, not lower level functions
if (nodep->isTop()) nodep->iterateChildren(*this);
}
virtual void visit(AstTopScope* nodep, AstNUser*) {
AstNode::userClearTree(); // userp() used on entire tree
AstNode::user2ClearTree(); // userp() used on entire tree
AstNode::user3ClearTree(); // userp() used on entire tree
AstNode::user4ClearTree(); // userp() used on entire tree
AstScope* scopep = nodep->scopep();
if (!scopep) nodep->v3fatalSrc("TopScope has no scope\n");
AstCFunc* evalp = NULL;
for (AstNode* searchp = scopep->blocksp(); searchp; searchp=searchp->nextp()) {
if (AstCFunc* funcp = searchp->castCFunc()) {
if (funcp->name() == "_eval") {
evalp = funcp;
break;
}
}
}
if (!evalp) nodep->v3fatalSrc("Top _eval entry function not found\n");
evalp->iterateChildren(*this);
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
// Consumption/generation of a variable,
// it's used so can't elim assignment before this use.
@@ -191,44 +283,61 @@ private:
//
AstVarScope* vscp = nodep->varScopep();
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
clearLastAssign(vscp);
if (nodep->lvalue()) {
m_lifep->complexAssign(vscp);
} else {
m_lifep->varUsageReplace(vscp, nodep); nodep=NULL;
}
}
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
// Collect any used variables first, as lhs may also be on rhs
// Similar code in V3Dead
vluint64_t lastEdit = AstNode::editCountGbl(); // When it was last edited
m_sideEffect = false;
nodep->rhsp()->iterateAndNext(*this);
if (lastEdit != AstNode::editCountGbl()) {
// We changed something, try to constant propagate, but don't delete the
// assignment as we still need nodep to remain.
V3Const::constifyTree(nodep->rhsp());
}
// Has to be direct assignment without any EXTRACTing.
if (nodep->lhsp()->castVarRef()) {
if (nodep->lhsp()->castVarRef() && !m_sideEffect) {
AstVarScope* vscp = nodep->lhsp()->castVarRef()->varScopep();
if (!vscp) vscp->v3fatalSrc("Scope lost on variable");
setLast(vscp, nodep);
m_lifep->simpleAssign(vscp, nodep);
} else {
nodep->lhsp()->iterateAndNext(*this);
}
}
virtual void visit(AstAssignDly* nodep, AstNUser*) {
// Don't treat as normal assign; V3Life doesn't understand time sense
nodep->iterateChildren(*this);
}
//---- Track control flow changes
virtual void visit(AstNodeIf* nodep, AstNUser*) {
UINFO(4," IF "<<nodep<<endl);
// Condition is part of PREVIOUS block
nodep->condp()->iterateAndNext(*this);
LifeMap* prevLifeMapp = m_lifep;
LifeMap* ifLifep = new LifeMap;
LifeMap* elseLifep = new LifeMap;
LifeBlock* prevLifep = m_lifep;
LifeBlock* ifLifep = new LifeBlock (prevLifep, m_statep);
LifeBlock* elseLifep = new LifeBlock (prevLifep, m_statep);
{
m_lifep = ifLifep;
nodep->ifsp()->iterateAndNext(*this);
m_lifep = prevLifep;
}
{
m_lifep = elseLifep;
nodep->elsesp()->iterateAndNext(*this);
m_lifep = prevLifep;
}
UINFO(4," join "<<endl);
m_lifep = prevLifeMapp;
// Find sets on both flows
dualBranch (ifLifep, elseLifep);
m_lifep->dualBranch (ifLifep, elseLifep);
// For the next assignments, clear any variables that were read or written in the block
clearLifeFromSublife(ifLifep);
clearLifeFromSublife(elseLifep);
ifLifep->lifeToAbove();
elseLifep->lifeToAbove();
delete ifLifep;
delete elseLifep;
}
@@ -240,24 +349,25 @@ private:
// assignment in the body that's used in the cond. (And otherwise
// would because it only appears used after-the-fact. So, we model
// it as a IF statement, and just don't allow elimination of
// variables in the body.
LifeMap* prevLifeMapp = m_lifep;
LifeMap* condLifep = new LifeMap;
LifeMap* bodyLifep = new LifeMap;
// variables across the body.
LifeBlock* prevLifep = m_lifep;
LifeBlock* condLifep = new LifeBlock (prevLifep, m_statep);
LifeBlock* bodyLifep = new LifeBlock (prevLifep, m_statep);
{
m_lifep = condLifep;
nodep->precondsp()->iterateAndNext(*this);
nodep->condp()->iterateAndNext(*this);
m_lifep = prevLifep;
}
{
m_lifep = bodyLifep;
nodep->bodysp()->iterateAndNext(*this);
m_lifep = prevLifep;
}
UINFO(4," joinfor"<<endl);
m_lifep = prevLifeMapp;
// For the next assignments, clear any variables that were read or written in the block
clearLifeFromSublife(condLifep);
clearLifeFromSublife(bodyLifep);
condLifep->lifeToAbove();
bodyLifep->lifeToAbove();
delete condLifep;
delete bodyLifep;
}
@@ -265,8 +375,15 @@ private:
//UINFO(4," CCALL "<<nodep<<endl);
nodep->iterateChildren(*this);
// Enter the function and trace it
nodep->funcp()->accept(*this);
if (!nodep->funcp()->entryPoint()) { // else is non-inline or public function we optimize separately
nodep->funcp()->accept(*this);
}
}
virtual void visit(AstUCFunc* nodep, AstNUser*) {
m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment
nodep->iterateChildren(*this);
}
virtual void visit(AstVar*, AstNUser*) {} // Don't want varrefs under it
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
@@ -274,15 +391,60 @@ private:
public:
// CONSTRUCTORS
LifeVisitor(AstNetlist* nodep) {
m_ifCount = 1;
m_lifep = new LifeMap;
LifeVisitor(AstNode* nodep, LifeState* statep) {
UINFO(4," LifeVisitor on "<<nodep<<endl);
m_statep = statep;
m_sideEffect = false;
{
m_lifep = new LifeBlock (NULL, m_statep);
nodep->accept(*this);
delete m_lifep; m_lifep=NULL;
}
}
virtual ~LifeVisitor() {}
};
//######################################################################
class LifeTopVisitor : public AstNVisitor {
// Visit all top nodes searching for functions that are entry points we want to start
// finding code within.
private:
// STATE
LifeState* m_statep; // Current state
// VISITORS
virtual void visit(AstCFunc* nodep, AstNUser*) {
if (nodep->entryPoint()) {
// Usage model 1: Simulate all C code, doing lifetime analysis
LifeVisitor visitor (nodep, m_statep);
}
}
virtual void visit(AstAlways* nodep, AstNUser*) {
// Usage model 2: Cleanup basic blocks
LifeVisitor visitor (nodep, m_statep);
}
virtual void visit(AstInitial* nodep, AstNUser*) {
// Usage model 2: Cleanup basic blocks
LifeVisitor visitor (nodep, m_statep);
}
virtual void visit(AstFinal* nodep, AstNUser*) {
// Usage model 2: Cleanup basic blocks
LifeVisitor visitor (nodep, m_statep);
}
virtual void visit(AstVar*, AstNUser*) {} // Accelerate
virtual void visit(AstNodeStmt*, AstNUser*) {} // Accelerate
virtual void visit(AstNodeMath*, AstNUser*) {} // Accelerate
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
public:
// CONSTRUCTORS
LifeTopVisitor(AstNetlist* nodep, LifeState* statep) {
m_statep = statep;
nodep->accept(*this);
delete m_lifep;
}
virtual ~LifeVisitor() {
V3Stats::addStat("Optimizations, Lifetime assign deletions", m_statAssnDel);
}
virtual ~LifeTopVisitor() {}
};
//######################################################################
@@ -290,6 +452,6 @@ public:
void V3Life::lifeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
// Delete lifelicate assignments
LifeVisitor visitor (nodep);
LifeState state;
LifeTopVisitor visitor (nodep, &state);
}
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3LIFE_H_
#define _V3LIFE_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -29,7 +29,8 @@
//
//*************************************************************************
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
+3 -2
View File
@@ -8,7 +8,7 @@
//
//*************************************************************************
//
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
@@ -21,7 +21,8 @@
#ifndef _V3LIFEPOST_H_
#define _V3LIFEPOST_H_ 1
#include "config.h"
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"

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