Compare commits

...
105 Commits
Author SHA1 Message Date
Wilson Snyder f23203dc96 Make __Inlines.h file so we can build VL_CONST_W_#X funcs automatically
git-svn-id: file://localhost/svn/verilator/trunk/verilator@974 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-11-30 22:38:21 +00:00
Wilson Snyder a94f1c779b Spelling fixes
git-svn-id: file://localhost/svn/verilator/trunk/verilator@973 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-11-30 22:12:53 +00:00
Wilson Snyder 6412aff82d Version bump, commentary
git-svn-id: file://localhost/svn/verilator/trunk/verilator@970 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-11-27 16:52:19 +00:00
Wilson Snyder 99bc1f92c9 Declare lex %tokens so user doesn't see yP_UGLYNAMES.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@969 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-11-05 21:38:20 +00:00
Wilson Snyder 891edad53a Fixed generate for loops with constant zero conditions.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@968 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-11-05 14:09:22 +00:00
Wilson Snyder 98e35b02ad Leak repairs and node leak detection
git-svn-id: file://localhost/svn/verilator/trunk/verilator@967 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-11-02 11:23:03 +00:00
Wilson Snyder 8075372675 Add -Wno-lint
git-svn-id: file://localhost/svn/verilator/trunk/verilator@966 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-31 21:17:23 +00:00
Wilson Snyder 10e34ca48e Support "#delay <statement>;" with associated STMTDLY warning.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@965 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-31 20:29:07 +00:00
Wilson Snyder 329808afff Misc updates to match Verilog-Perl
git-svn-id: file://localhost/svn/verilator/trunk/verilator@964 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-31 20:11:59 +00:00
Wilson Snyder 7fc3e6c168 Fix missing CAST required above some CONSTs
git-svn-id: file://localhost/svn/verilator/trunk/verilator@963 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-31 19:22:26 +00:00
Wilson Snyder 199b32709c Fix div by zero in constant propagation
git-svn-id: file://localhost/svn/verilator/trunk/verilator@962 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-30 22:58:47 +00:00
Wilson Snyder 1775da5f43 Track verilog-perl: Add static keyword; track IEEE BNF
git-svn-id: file://localhost/svn/verilator/trunk/verilator@961 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-26 14:58:26 +00:00
Wilson Snyder 45c202f78f Match Verilog-Perl operator names
git-svn-id: file://localhost/svn/verilator/trunk/verilator@960 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-23 20:54:29 +00:00
Wilson Snyder a77b58dba9 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@957 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-18 16:32:16 +00:00
Wilson Snyder c300ab6dd9 Match up with Verilog-Perl: add specify operators
git-svn-id: file://localhost/svn/verilator/trunk/verilator@956 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-18 16:29:19 +00:00
Wilson Snyder 9ac0f1accb Fix parsing system functions with empty parens
git-svn-id: file://localhost/svn/verilator/trunk/verilator@955 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-09-17 17:54:02 +00:00
Wilson Snyder 7990e5d4b1 Fix parsing module #(parameter x,y) declarations.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@954 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-09-11 13:35:02 +00:00
Wilson Snyder fb2cb3c49d Don't exit early if many warnings but no errors are found. [Stan Mayer]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@953 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-08-23 13:21:58 +00:00
Wilson Snyder c4b1bc2506 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@950 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-08-01 13:44:45 +00:00
Wilson Snyder 551393d443 Fix SC_LIBS missing from generated makefiles. [Ding Xiaoliang]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@949 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-31 14:47:21 +00:00
Wilson Snyder 79d305f3e8 Match Verilog-Perl: Remove preprocessor adding newlines before `line.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@948 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-30 15:00:21 +00:00
Wilson Snyder 822956e769 Add SystemVerilog end labels
git-svn-id: file://localhost/svn/verilator/trunk/verilator@947 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-18 17:58:53 +00:00
Wilson Snyder a681a6a6d5 Make -> a token to match verilog-perl
git-svn-id: file://localhost/svn/verilator/trunk/verilator@946 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-18 17:26:12 +00:00
Wilson Snyder 5f6d69affd Support SystemVerilog ==? and !=? operators.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@945 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-18 15:01:39 +00:00
Wilson Snyder 4a9bea6980 Version bump; commentary
git-svn-id: file://localhost/svn/verilator/trunk/verilator@942 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-21 21:00:38 +00:00
Wilson Snyder bfddd80f43 Support V2K function/task argument lists.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@941 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-19 23:43:14 +00:00
Wilson Snyder 84a778719a Fix constification removing continuous always blocks
git-svn-id: file://localhost/svn/verilator/trunk/verilator@940 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-15 14:39:52 +00:00
Wilson Snyder 829d80d5b5 Fix display constanting of neg quads. Part of previous checkin
git-svn-id: file://localhost/svn/verilator/trunk/verilator@939 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-14 21:27:40 +00:00
Wilson Snyder d6a5c97f3a Fix last change: percents must be literalized
git-svn-id: file://localhost/svn/verilator/trunk/verilator@938 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-14 18:34:08 +00:00
Wilson Snyder 4ba00bd256 Propagate constants into displays
git-svn-id: file://localhost/svn/verilator/trunk/verilator@937 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-14 17:29:37 +00:00
Wilson Snyder c18f9da400 Put display scope tracking under special node type
git-svn-id: file://localhost/svn/verilator/trunk/verilator@936 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-14 16:41:32 +00:00
Wilson Snyder 5b620a8dc5 Add V3Number display function, unused as yet
git-svn-id: file://localhost/svn/verilator/trunk/verilator@935 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-14 14:24:21 +00:00
Wilson Snyder 9c968c590c Fix Preprocessor dropping some line directives
git-svn-id: file://localhost/svn/verilator/trunk/verilator@934 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-13 17:34:09 +00:00
Wilson Snyder dff5d5c4e4 Report as many warning types as possible before exiting.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@933 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-12 19:39:10 +00:00
Wilson Snyder 1265e8cce8 Support V2K portlists with input a,b,...
git-svn-id: file://localhost/svn/verilator/trunk/verilator@932 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-12 13:58:56 +00:00
Wilson Snyder 2b5d7eeb50 Lesser license for verilated files
git-svn-id: file://localhost/svn/verilator/trunk/verilator@931 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-06-11 17:07:11 +00:00
Wilson Snyder bb9ae89049 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@928 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-22 12:15:01 +00:00
Wilson Snyder 72832a2810 Support empty module declarations
git-svn-id: file://localhost/svn/verilator/trunk/verilator@927 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-18 18:48:22 +00:00
Wilson Snyder 18cb210eac Ignore protect, and allow empty case
git-svn-id: file://localhost/svn/verilator/trunk/verilator@926 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-18 14:03:50 +00:00
Wilson Snyder 2c5a183368 Ignore ctrl-Zs in preprocessor
git-svn-id: file://localhost/svn/verilator/trunk/verilator@925 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-17 16:15:24 +00:00
Wilson Snyder 386f0a75df Support automatic and additional v2k timing statements
git-svn-id: file://localhost/svn/verilator/trunk/verilator@924 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-16 19:27:29 +00:00
Wilson Snyder ea26482154 Support functions which return integers
git-svn-id: file://localhost/svn/verilator/trunk/verilator@923 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-16 18:19:23 +00:00
Wilson Snyder 3aee7f918a More cleanup to match VParse, and support celldefine properly
git-svn-id: file://localhost/svn/verilator/trunk/verilator@922 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-16 12:55:25 +00:00
Wilson Snyder b3dd18b215 More bison cleanup; no functional change
git-svn-id: file://localhost/svn/verilator/trunk/verilator@921 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-14 20:59:58 +00:00
Wilson Snyder a77e331e89 Standardize flex->bison token names. No functional change.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@920 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-12 16:29:25 +00:00
Wilson Snyder 6f414ee9e2 Add unsigned keyword
git-svn-id: file://localhost/svn/verilator/trunk/verilator@919 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-05-12 15:31:04 +00:00
Wilson Snyder 8d56b498d1 Warn if flex is not installed.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@918 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-04-24 17:03:52 +00:00
Wilson Snyder 871c1853bf Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@915 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-04-20 12:43:23 +00:00
Wilson Snyder f8cd3a785c Use LINK for the loader, and add USER_LDFLAGS and USER_CPPFLAGS
git-svn-id: file://localhost/svn/verilator/trunk/verilator@914 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-04-19 18:39:47 +00:00
Wilson Snyder 6a6995187e Add --compiler flags, and break up deep functions
git-svn-id: file://localhost/svn/verilator/trunk/verilator@913 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-04-19 18:20:16 +00:00
Wilson Snyder a216c1e7e4 Add verilator lint_save/lint_restore
git-svn-id: file://localhost/svn/verilator/trunk/verilator@912 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-04-19 14:21:37 +00:00
Wilson Snyder ea8445d187 Convert bad tests to --lint-only
git-svn-id: file://localhost/svn/verilator/trunk/verilator@911 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-04-18 18:45:41 +00:00
Wilson Snyder 77261cce5b Add -lint-only option
git-svn-id: file://localhost/svn/verilator/trunk/verilator@910 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-04-18 18:26:38 +00:00
Wilson Snyder 78db712438 Fix compile errors under Windows MINGW compiler. [Gerald Williams]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@909 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-04-18 17:58:59 +00:00
Wilson Snyder 749302acb8 Fix MSVCC compile warning
git-svn-id: file://localhost/svn/verilator/trunk/verilator@908 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-04-18 17:41:31 +00:00
Wilson Snyder cbf52bb5d0 Fix 3.640 `verilog forcing IEEE 1364-1995 only.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@907 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-16 18:44:17 +00:00
Wilson Snyder d2ce499b59 Support SystemVerilog .name and .* interconnect.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@906 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-14 13:06:08 +00:00
Wilson Snyder 01e9bc4855 Support while and do-while loops.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@905 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-13 18:21:23 +00:00
Wilson Snyder 28d5e425a9 Fix dotted references under other dotteds
git-svn-id: file://localhost/svn/verilator/trunk/verilator@904 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-03-13 17:15:00 +00:00
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
379 changed files with 8624 additions and 2036 deletions
+197 -66
View File
@@ -3,27 +3,158 @@ 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.62***
* Verilator 3.655 ***
**** Wide VL_CONST_W_#X functions are now made automatically. [Bernard Deadman]
In such cases, a new {prefix}__Inlines.h file will be built and included.
* Verilator 3.655 11/27/2007
*** Support "#delay <statement>;" with associated STMTDLY warning.
**** Fixed generate for loops with constant zero conditions. [Rodney Sinclair]
**** Fixed divide-by-zero errors in constant propagator. [Rodney Sinclair]
**** Fixed wrong result with obscure signed-shift underneath a "? :".
**** Fixed many internal memory leaks, and added leak detector.
* Verilator 3.654 10/18/2007
**** Don't exit early if many warnings but no errors are found. [Stan Mayer]
**** Fixed parsing module #(parameter x,y) declarations. [Oleg Rodionov]
**** Fixed parsing system functions with empty parens. [Oleg Rodionov]
* Verilator 3.653 8/1/2007
**** Support SystemVerilog ==? and !=? operators.
**** Fixed SC_LIBS missing from generated makefiles. [Ding Xiaoliang]
* Verilator 3.652 6/21/2007
**** Report as many warning types as possible before exiting.
**** Support V2K portlists with "input a,b,...". [Mark Nodine]
**** Support V2K function/task argument lists.
**** Optimize constant $display arguments.
**** Fixed Preprocessor dropping some `line directives. [Mark Nodine]
* Verilator 3.651 5/22/2007
*** Added verilator_profcfunc utility. [Gene Weber]
*** Treat modules within `celldefine and `endcelldefine as if in library.
*** Support functions which return integers. [Mark Nodine]
**** Warn if flex is not installed. [Ralf Karge]
**** Ignore `protect and `endprotect.
**** Allow empty case/endcase blocks.
* Verilator 3.650 4/20/2007
** Add --compiler msvc option. This is now required when Verilated code
is to be run through MSVC++. This also enables fixing MSVC++ error
C1061, blocks nested too deeply. [Ralf Karge]
** Add --lint-only option, to lint without creating other output.
*** Add /*verilator lint_save*/ and /*verilator lint_restore*/ to allow
friendly control over re-enabling lint messages. [Gerald Williams]
*** Support SystemVerilog .name and .* interconnect.
*** Support while and do-while loops.
*** Use $(LINK) instead of $(CXX) for Makefile link rules. [Gerald Williams]
*** Add USER_CPPFLAGS and USER_LDFLAGS to Makefiles. [Gerald Williams]
**** Fixed compile errors under Windows MINGW compiler. [Gerald Williams]
**** Fixed dotted bit reference to local memory. [Eugene Weber]
**** Fixed 3.640 `verilog forcing IEEE 1364-1995 only. [David Hewson]
* Verilator 3.640 3/12/2007
*** 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]
**** Fixed elimination of public signals assigned to constants. [Eugene Weber]
**** Fixed internal error when public for loop has empty body. [David Addison]
**** Fixed "Loops detected" assertion when model exceeds 4GB. [David Hewson]
**** Fixed 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]
**** Fixed isolate_assignments when many signals per always. [Mike Shinkarovsky]
**** Fixed isolate_assignments across task/func temporaries. [Mike Shinkarovsky]
**** Fixed $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.
**** Fixed 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.
**** Fixed $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.
**** Fix dotted references inside generated cells. [David Hewson]
*** Reduce depth of priority encoded case statements. [Eugene Weber]
**** Fix missed split optimization points underneath other re-split blocks.
**** Fixed dotted references inside generated cells. [David Hewson]
**** Fixed 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]
**** Fixed $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]
**** Fixed --skip-identical without --debug, broken in 3.621. [Andy Meier]
* Verilator 3.621 10/11/2006 Beta
@@ -33,11 +164,11 @@ indicates the contributor was also the author of the fix; Thanks!
**** Remove .vpp intermediate files when not under --debug.
**** Fix link error when using --exe with --trace. [Eugene Weber]
**** Fixed link error when using --exe with --trace. [Eugene Weber]
**** Fix mis-optimization of wide concats with constants.
**** Fixed mis-optimization of wide concats with constants.
**** Fix core dump on printing error when not under --debug. [Allan Cochrane]
**** Fixed core dump on printing error when not under --debug. [Allan Cochrane]
* Verilator 3.620 10/04/2006 Stable
@@ -52,9 +183,9 @@ indicates the contributor was also the author of the fix; Thanks!
**** Optimize additional boolean identities (a|a = a, etc.)
**** Fix coredump when dotted cross-ref inside task call. [Eugene Weber]
**** Fixed coredump when dotted cross-ref inside task call. [Eugene Weber]
**** Fix dotted variables in always sensitivity lists. [Allan Cochrane]
**** Fixed dotted variables in always sensitivity lists. [Allan Cochrane]
* Verilator 3.610 09/20/2006 Stable
@@ -64,34 +195,34 @@ indicates the contributor was also the author of the fix; Thanks!
**** Removed coverage request variable; see Coverage limitations in docs.
**** Fix DOS carrage returns in multiline defines. [Ralf Karge]
**** Fixed DOS carriage returns in multiline defines. [Ralf Karge]
**** Fix printf format warnings on 64-bit linux.
**** Fixed printf format warnings on 64-bit linux.
* Verilator 3.602 09/11/2006 Stable
**** Fix function references under top inlined module. [David Hewson]
**** Fixed 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.
*** 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]
**** Fixed memory leak when destroying modules. [John Stroebel]
**** Fix coredump when unused modules have unused cells. [David Hewson]
**** Fixed coredump when unused modules have unused cells. [David Hewson]
**** Fix 3.600 internal error with arrayed instances. [David Hewson]
**** Fixed 3.600 internal error with arrayed instances. [David Hewson]
**** Fix 3.600 internal error with non-unrolled function loops. [David Hewson]
**** Fixed 3.600 internal error with non-unrolled function loops. [David Hewson]
**** Fix $display %m name not matching Verilog name inside SystemC modules.
**** Fixed $display %m name not matching Verilog name inside SystemC modules.
**** Declare optimized lookup tables as 'static', to reduce D-Cache miss rate.
@@ -101,17 +232,17 @@ indicates the contributor was also the author of the fix; Thanks!
**** Lint for x's in generate case statements.
**** Fix line numbers being off by one when first file starts with newline.
**** Fixed line numbers being off by one when first file starts with newline.
**** Fix naming of generate for blocks to prevent non-inline name conflict.
**** Fixed naming of generate for blocks to prevent non-inline name conflict.
**** Fix redundant statements remaining after table optimization.
**** Fixed redundant statements remaining after table optimization.
* Verilator 3.542 08/11/2006 Stable
**** Fix extraneous UNSIGNED warning when comparing genvars. [David Hewson]
**** Fixed extraneous UNSIGNED warning when comparing genvars. [David Hewson]
**** Fix extra whitespace in $display %c. [by David Addison]
**** Fixed extra white space in $display %c. [by David Addison]
**** vl_finish and vl_fatal now print via VL_PRINTF rather then cerr/cout.
@@ -119,15 +250,15 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.541 07/05/2006 Beta
*** Fix "// verilator lint_on" not re-enabling warnings. [David Hewson]
*** Fixed "// verilator lint_on" not re-enabling warnings. [David Hewson]
*** Fix 3.540's multiple memory assignments to same block. [David Hewson]
*** Fixed 3.540's multiple memory assignments to same block. [David Hewson]
**** Add warning on changeDetect to arrayed structures. [David Hewson]
**** Fix non-zero start number for arrayed instantiations. [Jae Hossell]
**** Fixed non-zero start number for arrayed instantiations. [Jae Hossell]
**** Fix GCC 4.0 header file warnings.
**** Fixed GCC 4.0 header file warnings.
* Verilator 3.540 06/27/2006 Beta
@@ -135,27 +266,27 @@ indicates the contributor was also the author of the fix; Thanks!
**** Optimize delayed assignments to memories inside loops, ~0-5% faster.
**** Fix mis-width warning on bit selects of memories. [David Hewson]
**** Fixed mis-width warning on bit selects of memories. [David Hewson]
**** Fix mis-width warning on dead generate-if branches. [Jae Hossell]
**** Fixed mis-width warning on dead generate-if branches. [Jae Hossell]
* Verilator 3.533 06/05/2006 Stable
*** Add PDF user manual, verilator.pdf.
**** Fix delayed bit-selected arrayed assignments. [David Hewson]
**** Fixed delayed bit-selected arrayed assignments. [David Hewson]
**** Fix execution path to Perl. [Shanshan Xu]
**** Fixed execution path to Perl. [Shanshan Xu]
**** Fix Bison compile errors in verilog.y. [by Ben Jackson]
**** Fixed Bison compile errors in verilog.y. [by Ben Jackson]
* Verilator 3.531 05/10/2006 Stable
*** Support $c routines which return 64 bit values.
**** Fix `include `DEFINE.
**** Fixed `include `DEFINE.
**** Fix Verilator core dump when have empty public function. [David.Hewson]
**** Fixed Verilator core dump when have empty public function. [David.Hewson]
* Verilator 3.530 04/24/2006 Stable
@@ -164,11 +295,11 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.523 03/06/2006 Stable
**** Fix error line numbers being off due to multi-line defines. [Mat Zeno]
**** Fixed error line numbers being off due to multi-line defines. [Mat Zeno]
**** Fix GCC sign extending (uint64_t)(a<b). [David Hewson]
**** Fixed GCC sign extending (uint64_t)(a<b). [David Hewson]
**** Fix `systemc_imp_header "undefined macro" error.
**** Fixed `systemc_imp_header "undefined macro" error.
* Verilator 3.522 02/23/2006 Beta
@@ -180,7 +311,7 @@ indicates the contributor was also the author of the fix; Thanks!
**** Added SystemVerilog 'x,'z,'0,'1, and new string literals.
**** Fix public module's parent still getting inlined.
**** Fixed public module's parent still getting inlined.
* Verilator 3.520 01/14/2006 Stable
@@ -193,28 +324,28 @@ indicates the contributor was also the author of the fix; Thanks!
This adds a small ~2% performance penalty if traces are compiled in,
but not turned on. For best non-tracing performance, do not use --trace.
**** Fix $'s in specify delays causing bad PLI errors. [Mat Zeno]
**** Fixed $'s in specify delays causing bad PLI errors. [Mat Zeno]
**** Fix public functions not setting up proper symbol table. [Mat Zeno]
**** Fixed public functions not setting up proper symbol table. [Mat Zeno]
**** Fix genvars generating trace compile errors. [Mat Zeno]
**** Fixed genvars generating trace compile errors. [Mat Zeno]
**** Fix VL_MULS_WWW compile error with MSVC++. [Wim Michiels]
**** Fixed VL_MULS_WWW compile error with MSVC++. [Wim Michiels]
* Verilator 3.502 11/30/2005 Stable
**** Fix local non-IO variables in public functions and tasks.
**** Fixed local non-IO variables in public functions and tasks.
**** Fix bad lifetime optimization when same signal is assigned multiple
**** Fixed bad lifetime optimization when same signal is assigned multiple
times in both branch of a if. [Danny Ding]
* Verilator 3.501 11/16/2005 Stable
*** Add --profile-cfuncs for correlating profiles back to Verilog.
**** Fix functions where regs are declared before inputs. [Danny Ding]
**** Fixed functions where regs are declared before inputs. [Danny Ding]
**** Fix bad deep expressions with bitselects and rotate. [Prabhat Gupta]
**** Fixed bad deep expressions with bit-selects and rotate. [Prabhat Gupta]
* Verilator 3.500 10/30/2005 Stable
@@ -228,15 +359,15 @@ indicates the contributor was also the author of the fix; Thanks!
** With --assert, generate assertions for synthesis parallel_case and full_case.
**** Fix generate if's with empty if/else blocks. [Mat Zeno]
**** Fixed generate if's with empty if/else blocks. [Mat Zeno]
**** Fix generate for cell instantiations with same name. [Mat Zeno]
**** Fixed generate for cell instantiations with same name. [Mat Zeno]
* Verilator 3.481 10/12/2005 Stable
*** Add /*verilator tracing_on/off*/ for waveform control.
**** Fix split optimization reordering $display statements.
**** Fixed split optimization reordering $display statements.
* Verilator 3.480 9/27/2005 Beta
@@ -261,9 +392,9 @@ indicates the contributor was also the author of the fix; Thanks!
**** Add GCC branch prediction hints on generated if statements.
**** Fix bad simulation when same function called twice in same expression.
**** Fixed bad simulation when same function called twice in same expression.
**** Fix preprocessor substitution of quoted parameterized defines.
**** Fixed preprocessor substitution of quoted parameterized defines.
* Verilator 3.464 8/24/2005 Stable
@@ -271,7 +402,7 @@ indicates the contributor was also the author of the fix; Thanks!
*** Add --stats option to dump design statistics.
**** Fix core dump with clock inversion optimizations.
**** Fixed core dump with clock inversion optimizations.
* Verilator 3.463 8/5/2005 Stable
@@ -279,15 +410,15 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.462 8/3/2005 Stable
*** Fix reordering of delayed assignments to same memory index. [Wim Michiels]
*** Fixed reordering of delayed assignments to same memory index. [Wim Michiels]
**** Fix compile error with Flex 2.5.1. [Jens Arm]
**** Fixed compile error with Flex 2.5.1. [Jens Arm]
**** Fix multiply-instantiated public tasks generating non-compilable code.
**** Fixed multiply-instantiated public tasks generating non-compilable code.
* Verilator 3.461 7/28/2005 Beta
**** Fix compile error with older versions of bison. [Jeff Dutton]
**** Fixed compile error with older versions of bison. [Jeff Dutton]
* Verilator 3.460 7/27/2005 Beta
@@ -300,13 +431,13 @@ indicates the contributor was also the author of the fix; Thanks!
*** When issuing unoptimizable warning, show an example path.
**** Fix false warning when a clock is constant.
**** Fixed false warning when a clock is constant.
**** Fix X/Z in decimal numbers. [Wim Michiels]
**** Fixed X/Z in decimal numbers. [Wim Michiels]
**** Fix genvar statements in non-named generate blocks.
**** Fixed genvar statements in non-named generate blocks.
**** Fix core dump when missing newline in `define. [David van der bokke]
**** Fixed core dump when missing newline in `define. [David van der bokke]
**** Internal tree dumps now indicate edit number that changed the node.
@@ -323,7 +454,7 @@ indicates the contributor was also the author of the fix; Thanks!
*** Add support for SystemVerilog keywords $bits, $countones, $isunknown,
$onehot, $onehot0, always_comb, always_ff, always_latch, finish.
**** Fix "=== 1'bx" to always be false, instead of random.
**** Fixed "=== 1'bx" to always be false, instead of random.
* Verilator 3.440 6/28/2005 Stable
@@ -331,7 +462,7 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.431 6/24/2005 Stable
*** Fix selection bugs introduced in 3.430 beta.
*** Fixed selection bugs introduced in 3.430 beta.
* Verilator 3.430 6/22/2005 Beta
@@ -963,7 +1094,7 @@ of input ports exists for tracing.
** [Versions 0 to 1.8 were by Paul Wasson]
**** Fix single bit in concat from instance output incorrect offset bug.
**** Fixed single bit in concat from instance output incorrect offset bug.
* Verilator 1.7 5/20/1996
@@ -978,7 +1109,7 @@ of input ports exists for tracing.
*** Pass structure pointer into translated code,
so multiple instances can use same functions.
**** Fix static value concat on casex items.
**** Fixed static value concat on casex items.
* Verilator 1.1 3/30/1995
@@ -998,7 +1129,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.
+6 -6
View File
@@ -4,13 +4,13 @@
#
# This file is part of Verilator.
#
# Author: Wilson Snyder <[email protected]> or <[email protected]>
# Author: Wilson Snyder <[email protected]>
#
# Code available from: http://www.veripool.com/verilator
#
#*****************************************************************************
#
# 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.
#
@@ -94,7 +94,7 @@ 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 \
@@ -155,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
+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
+13 -2
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.
@@ -25,12 +25,13 @@ Features:
Coverage
Points should be per-scope like everything else rather then per-module
Expression coverage (see notes)
Constant functions for widths, etc, IE "input [log2(PARAM):0] xx;"
More Verilog 2001 Support
C-style function and task arguments. [Wim Michiels]
(* *) Attributes (just ignore -- preprocessor?)
Real numbers (NEVER)
Recursive functions (NEVER)
Verilog configuration files (NEVER)
DPI to define C/C++ calls from Verilog
Long-term Features
Assertions
@@ -47,6 +48,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))
@@ -99,6 +104,12 @@ Performance:
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)
All of the temp vars that get set, exp pre_ vars and never feedback
(not flops) don't need to be stored in the structs, but instead can
be per-invocation, and even better register-colored-like to reuse
the space. This will greatly reduce the data footprint.
//**********************************************************************
//* Detailed notes on 'todo' features
+529 -117
View File
File diff suppressed because it is too large Load Diff
+7 -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.
@@ -35,17 +35,21 @@ my $Opt_A;
my $Opt_B;
autoflush STDOUT 1;
autoflush STDERR 1;
Getopt::Long::config ("no_auto_abbrev");
if (! GetOptions (
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
)) {
usage();
die "%Error: Bad usage, try 'verilator_difftree --help'\n";
}
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 +180,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.
+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.
######################################################################
+211
View File
@@ -0,0 +1,211 @@
: # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
# $Id$
######################################################################
#
# Copyright 2007-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 warnings;
use Getopt::Long;
use IO::File;
use Pod::Usage;
use strict;
use vars qw ($Debug);
#======================================================================
#======================================================================
# main
$Debug = 0;
my $Opt_File;
autoflush STDOUT 1;
autoflush STDERR 1;
Getopt::Long::config ("no_auto_abbrev");
if (! GetOptions (
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
)) {
die "%Error: Bad usage, try 'verilator_profcfunc --help'\n";
}
defined $Opt_File or die "%Error: No filename given\n";
profcfunc($Opt_File);
#----------------------------------------------------------------------
sub usage {
print '$Id$ ', "\n";
pod2usage(-verbose=>2, -exitval => 2);
exit (1);
}
sub debug {
$Debug = 1;
}
sub parameter {
my $param = shift;
if (!defined $Opt_File) {
$Opt_File = $param;
} else {
die "%Error: Unknown parameter: $param\n";
}
}
#######################################################################
sub profcfunc {
my $filename = shift;
# Remove hex numbers before diffing
my $fh = IO::File->new ($filename) or die "%Error: $! $filename,";
my %funcs;
while (defined (my $line=$fh->getline())) {
if ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+.*\s+(\S+)\s*$/) {
my $pct=$1; my $sec=$2; my $calls=$3; my $func=$4;
$funcs{$func}{pct} += $pct;
$funcs{$func}{sec} += $sec;
$funcs{$func}{calls} += $calls;
}
}
$fh->close;
# Find modules
my %verilated_mods;
foreach my $func (keys %funcs) {
if ($func =~ /(.*)::_eval\(.*__Syms.*\)$/) {
$verilated_mods{$1} = qr/^$1/;
}
}
# Resort by Verilog name
my %vfuncs;
my %groups;
foreach my $func (keys %funcs) {
my $vfunc = $func;
my $design;
foreach my $vde (keys %verilated_mods) {
if ($func =~ /$verilated_mods{$vde}/) {
$design=$vde;
last;
}
}
if ($vfunc =~ /__PROF__([a-zA-Z_0-9]+)__([0-9]+)\(/) {
$vfunc = sprintf("VBlock %s:%d", $1, $2);
$groups{"Verilog Blocks under $design"} += $funcs{$func}{pct};
} else {
if ($design) {
$vfunc = sprintf("VCommon %s", $func);
$groups{"Common code under $design"} += $funcs{$func}{pct};
} else {
$vfunc = sprintf("C++ %s", $func);
$groups{'C++'} += $funcs{$func}{pct};
}
}
$vfuncs{$vfunc} = $funcs{$func};
}
print("Overall summary:\n");
print(" % time\n");
foreach (sort (keys %groups)) {
printf(" %6.2f In all %s\n", $groups{$_}, $_);
}
print("\n");
print("Verilog code profile:\n");
print(" These are split into three categories:\n");
print(" C++: Time in non-Verilated C++ code\n");
print(" VBlock: Time attributable to a block in a Verilog file and line\n");
print(" VCommon: Time in a Verilated module, due to all parts of the design\n");
print("\n");
print(" % cumulative self \n");
print(" time seconds seconds calls type filename and line number\n");
my $cume = 0;
foreach my $func (sort {$vfuncs{$b}{sec} <=> $vfuncs{$a}{sec}
|| $a cmp $b}
(keys %vfuncs)) {
$cume += $vfuncs{$func}{sec};
printf +("%6.2f %9.2f %8.2f %8d %s\n",
$vfuncs{$func}{pct},
$cume, $vfuncs{$func}{sec},
$vfuncs{$func}{calls},
$func);
}
}
#######################################################################
__END__
=pod
=head1 NAME
verilator_profcfunc - Read gprof report created with --profile-cfuncs
=head1 SYNOPSIS
verilator --profile-cfuncs ....
gcc --ggdb -pg ....
{run executable}
gprof
verilator_profcfuncs gprof.out
=head1 DESCRIPTION
Verilator_profcfunc reads a profile report created by gprof. The names of
the functions are then transformed, assuming the user used verilator's
--profile-cfuncs, and a report printed showing the percentage of time, etc,
in each Verilog block.
=head1 ARGUMENTS
=over 4
=item --help
Displays this message and program version and exits.
=back
=head1 DISTRIBUTION
The latest version is available from L<http://www.veripool.com/>.
Copyright 2007-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
C<verilator>
=cut
######################################################################
### Local Variables:
### compile-command: "$V4/bin/verilator_profcfunc $V4/test_c/obj_dir/V*_03_*.tree $V4N/test_c/obj_dir/V*_03_*.tree"
### End:
+11 -2
View File
@@ -1,6 +1,6 @@
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.
@@ -16,8 +16,17 @@ AC_PROG_CC
AC_PROG_CXX
AC_PROG_INSTALL
AC_PATH_PROG(PERL,perl)
AC_PATH_PROG(YACC,bison)
if test "x$PERL" = "x" ; then
AC_MSG_ERROR([Cannot find "perl" in your PATH, please install it])
fi
AC_PATH_PROG(LEX,flex)
if test "x$LEX" = "x" ; then
AC_MSG_ERROR([Cannot find "flex" in your PATH, please install it])
fi
AC_PATH_PROG(YACC,bison)
if test "x$YACC" = "x" ; then
AC_MSG_ERROR([Cannot find "bison" in your PATH, please install it])
fi
dnl Checks for libraries.
+113 -4
View File
@@ -1,9 +1,9 @@
// $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.
// Lesser General Public License or the Perl Artistic License.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -24,13 +24,14 @@
#include "verilated.h"
#include <string.h>
#include <ctype.h>
#define VL_VALUE_STRING_MAX_WIDTH 1024 ///< Max static char array for VL_VALUE_STRING
//===========================================================================
// Global variables
int Verilated::s_randReset = false;
int Verilated::s_randReset = 0;
int Verilated::s_debug = 1;
bool Verilated::s_calcUnusedSigs = false;
bool Verilated::s_gotFinish = false;
@@ -71,7 +72,8 @@ void vl_fatal (const char* filename, int linenum, const char* hier, const char*
// Random reset -- Only called at init time, so don't inline.
IData VL_RAND32() {
#ifdef _MSC_VER
#if defined(_WIN32) && !defined(__CYGWIN__)
// Windows doesn't have lrand48(), although Cygwin does.
return (rand()<<16) | rand();
#else
return (lrand48()<<16) | lrand48();
@@ -238,6 +240,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
+58 -94
View File
@@ -1,9 +1,9 @@
// $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.
// Lesser General Public License or the Perl Artistic License.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -194,17 +194,25 @@ 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
/// Return true if data[bit] set
#define VL_BITISSET_I(data,bit) (data & (1UL<<VL_BITBIT_I(bit)))
#define VL_BITISSET_I(data,bit) (data & (VL_UL(1)<<VL_BITBIT_I(bit)))
#define VL_BITISSET_Q(data,bit) (data & (VL_ULL(1)<<VL_BITBIT_Q(bit)))
#define VL_BITISSET_W(data,bit) (data[VL_BITWORD_I(bit)] & (1UL<<VL_BITBIT_I(bit)))
#define VL_BITISSET_W(data,bit) (data[VL_BITWORD_I(bit)] & (VL_UL(1)<<VL_BITBIT_I(bit)))
/// Create two 32-bit words from quadword
#define VL_SET_WQ(decl,data) { decl[0]=(data); decl[1]=((data)>>VL_WORDSIZE); }
@@ -217,15 +225,22 @@ static inline QData VL_CVT_FP_Q(FILE* fp) { union { FILE* fp; QData q; } u; u.q
// Sign extend such that if MSB set, we get ffff_ffff, else 0s
// (Requires clean input)
#define VL_SIGN_I(nbits,lhs) ((lhs) >> VL_BITBIT_I((nbits) - 1UL))
#define VL_SIGN_I(nbits,lhs) ((lhs) >> VL_BITBIT_I((nbits) - VL_UL(1)))
#define VL_SIGN_Q(nbits,lhs) ((lhs) >> VL_BITBIT_Q((nbits) - VL_ULL(1)))
#define VL_SIGNONES_I(nbits,lhs) (-(VL_SIGN_I(nbits,lhs)))
// Sign bit extended up to MSB, doesn't include unsigned portion
// Optimization bug in GCC 3.3 returns different bitmasks to later states for
static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) { return (-((lhs)&(1UL<<(lbits-1)))); }
static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) { return (-((lhs)&(VL_UL(1)<<(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
@@ -289,15 +304,15 @@ static inline WDataOutP VL_ASSIGN_W(int obits, WDataOutP owp,WDataInP lwp){
// EMIT_RULE: VL_ASSIGNBIT: rclean=clean;
static inline void VL_ASSIGNBIT_II(int, int bit, CData& lhsr, IData rhs) {
lhsr = ((lhsr & ~(1UL<<VL_BITBIT_I(bit)))
lhsr = ((lhsr & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
| (rhs<<VL_BITBIT_I(bit)));
}
static inline void VL_ASSIGNBIT_II(int, int bit, SData& lhsr, IData rhs) {
lhsr = ((lhsr & ~(1UL<<VL_BITBIT_I(bit)))
lhsr = ((lhsr & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
| (rhs<<VL_BITBIT_I(bit)));
}
static inline void VL_ASSIGNBIT_II(int, int bit, IData& lhsr, IData rhs) {
lhsr = ((lhsr & ~(1UL<<VL_BITBIT_I(bit)))
lhsr = ((lhsr & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
| (rhs<<VL_BITBIT_I(bit)));
}
static inline void VL_ASSIGNBIT_QI(int, int bit, QData& lhsr, QData rhs) {
@@ -306,25 +321,25 @@ static inline void VL_ASSIGNBIT_QI(int, int bit, QData& lhsr, QData rhs) {
}
static inline void VL_ASSIGNBIT_WI(int, int bit, WDataOutP owp, IData rhs) {
IData orig = owp[VL_BITWORD_I(bit)];
owp[VL_BITWORD_I(bit)] = (orig & ~(1UL<<VL_BITBIT_I(bit))
owp[VL_BITWORD_I(bit)] = (orig & ~(VL_UL(1)<<VL_BITBIT_I(bit))
| (rhs<<VL_BITBIT_I(bit)));
}
// Alternative form that is an instruction faster when rhs is constant one.
static inline void VL_ASSIGNBIT_IO(int, int bit, CData& lhsr, IData) {
lhsr = (lhsr | (1UL<<VL_BITBIT_I(bit)));
lhsr = (lhsr | (VL_UL(1)<<VL_BITBIT_I(bit)));
}
static inline void VL_ASSIGNBIT_IO(int, int bit, SData& lhsr, IData) {
lhsr = (lhsr | (1UL<<VL_BITBIT_I(bit)));
lhsr = (lhsr | (VL_UL(1)<<VL_BITBIT_I(bit)));
}
static inline void VL_ASSIGNBIT_IO(int, int bit, IData& lhsr, IData) {
lhsr = (lhsr | (1UL<<VL_BITBIT_I(bit)));
lhsr = (lhsr | (VL_UL(1)<<VL_BITBIT_I(bit)));
}
static inline void VL_ASSIGNBIT_QO(int, int bit, QData& lhsr, IData) {
lhsr = (lhsr | (VL_ULL(1)<<VL_BITBIT_Q(bit)));
}
static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
IData orig = owp[VL_BITWORD_I(bit)];
owp[VL_BITWORD_I(bit)] = (orig | (1UL<<VL_BITBIT_I(bit)));
owp[VL_BITWORD_I(bit)] = (orig | (VL_UL(1)<<VL_BITBIT_I(bit)));
}
//===================================================================
@@ -498,10 +513,10 @@ static inline IData VL_COUNTONES_W(int words, WDataInP lwp) {
}
static inline IData VL_ONEHOT_I(IData lhs) {
return ((lhs & (lhs-1))==0 & lhs!=0);
return (((lhs & (lhs-1))==0) & (lhs!=0));
}
static inline IData VL_ONEHOT_Q(QData lhs) {
return ((lhs & (lhs-1))==0 & lhs!=0);
return (((lhs & (lhs-1))==0) & (lhs!=0));
}
static inline IData VL_ONEHOT_W(int words, WDataInP lwp) {
IData one=0;
@@ -1035,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?)
@@ -1137,7 +1164,7 @@ static inline IData VL_BITSEL_IWII(int, int lbits, int, int, WDataInP lwp, IData
int word = VL_BITWORD_I(rd);
if ((int)rd>lbits) {
return ~0; // Spec says you can go outside the range of a array. Don't coredump if so.
// We return all 1's as that's more likely to find bugs (?) then 0's.
// We return all 1's as that's more likely to find bugs (?) than 0's.
} else {
return (lwp[word]>>VL_BITBIT_I(rd));
}
@@ -1261,123 +1288,60 @@ static inline WDataOutP VL_COND_WIWW(int obits, int, int, int,
// VL_CONST_W_#X(int obits, WDataOutP owp, IData data0, .... IData data(#-1))
// Sets wide vector words to specified constant words, zeros upper data.
// If changing the number of functions here, also change EMITCINLINES_NUM_CONSTW
#define I IData
#define _END(obits,wordsSet) \
for(int i=(wordsSet);i<VL_WORDS_I(obits);i++) o[i] = (IData)0x0; \
return o
#define VL_HAVE_CONST_W_1X
static inline WDataOutP VL_CONST_W_1X(int obits, WDataOutP o,
I d0) {
o[0]=d0;
_END(obits,1); }
#define VL_HAVE_CONST_W_2X
static inline WDataOutP VL_CONST_W_2X(int obits, WDataOutP o,
I d1,I d0) {
o[0]=d0; o[1]=d1;
_END(obits,2); }
#define VL_HAVE_CONST_W_3X
static inline WDataOutP VL_CONST_W_3X(int obits, WDataOutP o,
I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2;
_END(obits,3); }
#define VL_HAVE_CONST_W_4X
static inline WDataOutP VL_CONST_W_4X(int obits, WDataOutP o,
I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3;
_END(obits,4); }
#define VL_HAVE_CONST_W_5X
static inline WDataOutP VL_CONST_W_5X(int obits, WDataOutP o,
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;
_END(obits,5); }
#define VL_HAVE_CONST_W_6X
static inline WDataOutP VL_CONST_W_6X(int obits, WDataOutP o,
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;
_END(obits,6); }
#define VL_HAVE_CONST_W_7X
static inline WDataOutP VL_CONST_W_7X(int obits, WDataOutP o,
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;
_END(obits,7); }
#define VL_HAVE_CONST_W_8X
static inline WDataOutP VL_CONST_W_8X(int obits, WDataOutP o,
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;
_END(obits,8); }
#define VL_HAVE_CONST_W_9X
static inline WDataOutP VL_CONST_W_9X(int obits, WDataOutP o,
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;
_END(obits,9); }
static inline WDataOutP VL_CONST_W_10X(int obits, WDataOutP o,
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;
_END(obits,10); }
static inline WDataOutP VL_CONST_W_11X(int obits, WDataOutP o,
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;
_END(obits,11); }
static inline WDataOutP VL_CONST_W_12X(int obits, WDataOutP o,
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;
_END(obits,12); }
static inline WDataOutP VL_CONST_W_16X(int obits, WDataOutP o,
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;
_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,
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; o[20]=d20; o[21]=d21; o[22]=d22; o[23]=d23;
_END(obits,24); }
static inline WDataOutP VL_CONST_W_28X(int obits, WDataOutP o,
I d27,I d26,I d25,I d24,
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,
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; o[20]=d20; o[21]=d21; o[22]=d22; o[23]=d23;
o[24]=d24; o[25]=d25; o[26]=d26; o[27]=d27;
_END(obits,28); }
#undef _END
#undef I
+12 -7
View File
@@ -2,9 +2,9 @@
######################################################################
# 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.
# Lesser General Public License or the Perl Artistic License.
######################################################################
PERL = @PERL@
@@ -49,7 +49,12 @@ VPATH += $(VERILATOR_ROOT)/include
CPPFLAGS += $(OPT)
CPPFLAGS += $(M32)
LDFLAGS += $(M32)
LDFLAGS += $(M32)
# Allow upper level user makefiles to specify flags they want.
# These aren't ever set by Verilator, so users are free to override them.
CPPFLAGS += $(USER_CPPFLAGS)
LDFLAGS += $(USER_LDFLAGS)
# See the benchmarking section of bin/verilator.
# Support class optimizations. This includes the tracing and symbol table.
@@ -84,8 +89,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))
@@ -104,8 +109,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
+2 -2
View File
@@ -5,9 +5,9 @@
//
//*************************************************************************
//
// 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.
// Lesser General Public License or the Perl Artistic License.
//
// This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
+12 -5
View File
@@ -1,9 +1,9 @@
// $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.
// Lesser General Public License or the Perl Artistic License.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -39,13 +39,17 @@
# 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
# define VL_ATTR_NORETURN ///< Function does not ever return
# 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_LIKELY(x) (!!(x)) ///< Boolean expression more often true than false
# define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false than 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
@@ -64,6 +68,9 @@
# define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant
#endif
// This is not necessarily the same as #UL, depending on what the IData typedef is.
#define VL_UL(c) ((IData)(c##UL)) ///< Add appropriate suffix to 32-bit constant
//=========================================================================
// Basic integer types
@@ -79,7 +86,7 @@ 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)
#elif defined(_WIN32) && !defined(__MINGW32__)
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)
+67
View File
@@ -0,0 +1,67 @@
#!/usr/bin/perl -w
#$Id$
######################################################################
#
# Copyright 2007-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.
#
# 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.
#
# You should have received a copy of the Perl Artistic License
# along with this module; see the file COPYING. If not, see
# www.cpan.org
#
######################################################################
# DESCRIPTION: Debugging of bison output
use strict;
my $Debug;
my %declared;
my %used;
my $body = 0;
my $rule = "";
my $lineno = 0;
foreach my $line (<STDIN>) {
$lineno++;
chomp $line;
$line =~ s!//.*$!!g;
$line =~ s!\s+! !g;
next if $line eq '';
if ($line =~ m!^\%\%!) {
$body++;
} elsif ($body == 1) {
$rule .= $line;
if ($line =~ m!^\s*;\s*$!) {
#print "Rule: $rule\n";
($rule =~ /^([a-zA-Z0-9_]+):(.*)$/) or die "%Error: No rule name: $1\n";
my $rulename = $1; my $preaction = $2;
$declared{$rulename} = $lineno;
$preaction =~ s/\{[^\}]*\}/ /g;
#print "RULEN $rulename PA $preaction\n" if $Debug;
$rule = '';
foreach my $ref (split /\s+/, $preaction) {
next if $ref !~ /^[a-zA-Z]/;
next if $ref eq $rulename;
if (!$used{$ref} && $declared{$ref}) {
print " %Warning: $lineno: $ref used by $rulename after declaration\n";
}
$used{$ref} = $lineno;
print " ref $ref\n" if $Debug;
}
}
}
}
# Local Variables:
# compile-command: "./bisonreader < verilog.y"
# End:
+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.
+70
View File
@@ -0,0 +1,70 @@
#!/usr/bin/perl -w
# $Id$
######################################################################
#
# Copyright 2007-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 strict;
#======================================================================
# main
delete $ENV{MODULE_VERSION};
_setup_modules();
module('add','cadence_verif');
exec('ncverilog',@ARGV);
#######################################################################
# Modules package
sub _setup_modules {
# Load the 'module' command into the environment
my $init = "/sicortex/$ENV{DIRPROJECT_ARCH}/lib/Modules/default/init/perl";
(-f $init) or die "%Error: Script not found: $init,";
require $init;
}
#######################################################################
__END__
=pod
=head1 NAME
invoke_ncverilog - Invoke tool under "modules" command
=head1 SYNOPSIS
invoke_ncverilog {ncv arguments}
=head1 DESCRIPTION
=head1 DISTRIBUTION
Copyright 2007-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: "./invoke_ncverilog -help"
### 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.
@@ -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
@@ -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.
#
+6 -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.
#
@@ -118,8 +118,10 @@ RAW_OBJS = \
V3Dead.o \
V3Delayed.o \
V3Depth.o \
V3DepthBlock.o \
V3Descope.o \
V3EmitC.o \
V3EmitCInlines.o \
V3EmitCSyms.o \
V3EmitMk.o \
V3EmitV.o \
@@ -142,6 +144,8 @@ RAW_OBJS = \
V3LinkCells.o \
V3LinkDot.o \
V3LinkLevel.o \
V3LinkLValue.o \
V3LinkParse.o \
V3LinkResolve.o \
V3Localize.o \
V3Name.o \
@@ -154,6 +158,7 @@ RAW_OBJS = \
V3Scope.o \
V3Signed.o \
V3Split.o \
V3SplitAs.o \
V3Stats.o \
V3StatsReport.o \
V3Subst.o \
+1 -1
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.
//
+1 -1
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.
//
+1 -1
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.
//
+1 -1
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 -18
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.
//
@@ -47,28 +47,61 @@ 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);
if (!nodep->scopeNamep() && nodep->name().find("%m") != string::npos) {
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
}
}
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();
//
@@ -114,6 +147,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);
@@ -163,16 +218,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;
@@ -203,6 +276,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);
}
+1 -1
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.
//
+1 -1
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.
//
+1 -1
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.
//
+32 -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.
//
@@ -92,12 +92,19 @@ 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, "[");
}
@@ -107,8 +114,7 @@ string AstNode::prettyName(const string& namein) {
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 {
@@ -128,6 +134,7 @@ inline void AstNode::debugTreeChange(const char* prefix, int lineno, bool next)
// Called on all major tree changers.
// Only for use for those really nasty bugs relating to internals
// Note this may be null.
//if (debug()) cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<": "<<(void*)this<<endl;
//if (debug()) {
// cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<endl;
// v3Global.rootp()->dumpTree(cout,"-treeChange: ");
@@ -452,7 +459,7 @@ void AstNode::relink(AstNRelinker* linkerp) {
if (linkerp->m_iterpp) {
// If we're iterating over a next() link, we need to follow links off the
// NEW node. Thus we pass iteration information via a pointer in the node.
// This adds a unfortunate 4 bytes to every AstNode, but is faster then passing
// This adds a unfortunate 4 bytes to every AstNode, but is faster than passing
// across every function.
// If anyone has a cleaner way, I'd be grateful.
*(linkerp->m_iterpp) = newp;
@@ -580,11 +587,29 @@ void AstNode::deleteTree() {
// unlinkFromBack or unlinkFromBackWithNext as appropriate before calling this.
if (!this) return;
UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n");
this->debugTreeChange("-delete: ", __LINE__, true);
this->debugTreeChange("-delTree: ", __LINE__, true);
// MUST be depth first!
deleteTreeIter();
}
//======================================================================
// Memory checks
#ifdef VL_LEAK_CHECKS
void* AstNode::operator new(size_t size) {
AstNode* objp = static_cast<AstNode*>(::operator new(size));
V3Broken::addNewed(objp);
return objp;
}
void AstNode::operator delete(void* objp, size_t size) {
if (!objp) return;
AstNode* nodep = static_cast<AstNode*>(objp);
V3Broken::deleted(nodep);
::operator delete(objp);
}
#endif
//======================================================================
// Iterators
@@ -783,7 +808,7 @@ 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 {
+74 -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.
//
@@ -248,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
@@ -478,10 +533,15 @@ 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
virtual ~AstNode();
#ifdef VL_LEAK_CHECKS
static void* operator new(size_t size);
static void operator delete(void* obj, size_t size);
#endif
// CONSTANT ACCESSORS
static int instrCountBranch() { return 4; } ///< Instruction cycles to branch
@@ -496,6 +556,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; }
@@ -877,6 +938,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; }
@@ -941,12 +1003,12 @@ private:
AstNodeFTask* m_taskp; // [AfterLink] Pointer to task referenced
string m_name; // Name of variable
string m_dotted; // Dotted part of scope to task or ""
string m_inlinedDots; // Dotted hiearchy flattened out
string m_inlinedDots; // Dotted hierarchy 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(); }
@@ -961,9 +1023,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); }
};
//######################################################################
+9 -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.
//
@@ -298,6 +298,7 @@ void AstCell::dump(ostream& str) {
this->AstNode::dump(str);
if (modp()) { str<<" -> "; modp()->dump(str); }
else { str<<" ->UNLINKED:"<<modName(); }
if (pinStar()) str<<" [.*]";
}
void AstCellInline::dump(ostream& str) {
this->AstNode::dump(str);
@@ -307,6 +308,7 @@ void AstPin::dump(ostream& str) {
this->AstNode::dump(str);
if (modVarp()) { str<<" -> "; modVarp()->dump(str); }
else { str<<" ->UNLINKED"; }
if (svImplicit()) str<<" [.SV]";
}
void AstVarXRef::dump(ostream& str) {
this->AstNode::dump(str);
@@ -350,6 +352,7 @@ void AstVar::dump(ostream& str) {
if (isUsedClock()) str<<" [C]";
if (isSigPublic()) str<<" [P]";
if (attrClockEn()) str<<" [aCLKEN]";
if (attrIsolateAssign()) str<<" [aISO]";
if (attrFileDescr()) str<<" [aFD]";
if (isFuncReturn()) str<<" [FUNCRTN]";
else if (isFuncLocal()) str<<" [FUNC]";
@@ -361,7 +364,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);
+199 -27
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:
@@ -301,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; }
@@ -340,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; }
@@ -348,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(); }
@@ -359,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
@@ -369,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) {
@@ -411,7 +421,7 @@ struct AstScope : public AstNode {
private:
string m_name; // Name
AstScope* m_aboveScopep; // Scope above this one in the hierarchy (NULL if top)
AstCell* m_aboveCellp; // Cell above this in the hiearchy (NULL if top)
AstCell* m_aboveCellp; // Cell above this in the hierarchy (NULL if top)
AstModule* m_modp; // Module scope corresponds to
public:
AstScope(FileLine* fl, AstModule* modp, const string& name,
@@ -530,7 +540,7 @@ struct AstVarXRef : public AstNodeVarRef {
// Includes pin on a cell, as part of a ASSIGN statement to connect I/Os until AstScope
private:
string m_dotted; // Scope name to connected to
string m_inlinedDots; // Dotted hiearchy flattened out
string m_inlinedDots; // Dotted hierarchy flattened out
public:
AstVarXRef(FileLine* fl, const string& name, const string& dotted, bool lvalue)
:AstNodeVarRef(fl, name, NULL, lvalue)
@@ -566,10 +576,11 @@ private:
int m_pinNum; // Pin number
string m_name; // Pin name, or "" for number based interconnect
AstVar* m_modVarp; // Input/output this pin connects to on submodule.
bool m_svImplicit; // Pin is SystemVerilog .name'ed
public:
AstPin(FileLine* fl, int pinNum, const string& name, AstNode* exprp)
:AstNode(fl)
,m_name(name) {
,m_name(name), m_svImplicit(false) {
m_pinNum = pinNum;
m_modVarp = NULL;
setNOp1p(exprp); }
@@ -586,6 +597,8 @@ public:
AstNode* exprp() const { return op1p()->castNode(); } // op1 = Expression connected to pin
AstVar* modVarp() const { return m_modVarp; } // [After Link] Pointer to variable
void modVarp(AstVar* varp) { m_modVarp=varp; }
bool svImplicit() const { return m_svImplicit; }
void svImplicit(bool flag) { m_svImplicit=flag; }
};
struct AstModule : public AstNode {
@@ -642,12 +655,14 @@ private:
string m_name; // Cell name
string m_origName; // Original name before dot addition
string m_modName; // Module the cell instances
bool m_pinStar; // Pin list has .*
AstModule* m_modp; // [AfterLink] Pointer to module instanced
public:
AstCell(FileLine* fl, const string& instName, const string& modName,
AstPin* pinsp, AstPin* paramsp, AstRange* rangep)
: AstNode(fl)
, m_name(instName), m_origName(instName), m_modName(modName), m_modp(NULL) {
, m_name(instName), m_origName(instName), m_modName(modName)
, m_pinStar(false), m_modp(NULL) {
addNOp1p(pinsp); addNOp2p(paramsp); setNOp3p(rangep); }
virtual ~AstCell() {}
virtual AstType type() const { return AstType::CELL;}
@@ -664,6 +679,8 @@ public:
void origName(const string& name) { m_origName = name; }
string modName() const { return m_modName; } // * = Instance name
void modName(const string& name) { m_modName = name; }
bool pinStar() const { return m_pinStar; }
void pinStar(bool flag) { m_pinStar = flag; }
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)
@@ -756,6 +773,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 {
@@ -769,10 +826,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;}
@@ -781,12 +841,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);}
@@ -795,8 +857,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);}
@@ -816,8 +878,11 @@ public:
class Settle {}; // for creator type-overload selection
class Never {}; // for creator type-overload selection
AstSenItem(FileLine* fl, AstEdgeType edgeType, AstNodeVarRef* varrefp)
: AstNode(fl) {
m_edgeType = edgeType;
: 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)
@@ -1167,6 +1232,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; }
@@ -1174,20 +1240,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
@@ -1195,19 +1263,22 @@ 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); }
AstScopeName* scopeNamep() const { return op3p()->castScopeName(); }
void scopeNamep(AstNode* nodep) { setNOp3p(nodep); }
};
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);
}
@@ -1223,7 +1294,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); }
};
@@ -1246,11 +1317,39 @@ 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* incsp, AstNode* bodysp)
@@ -1624,6 +1723,22 @@ public:
int dimension() const { return m_dimension; }
};
struct AstScopeName : public AstNode {
// For display %m
// Parents: DISPLAY
// Children: TEXT
AstScopeName(FileLine* fl)
: AstNode(fl) {}
virtual ~AstScopeName() {}
virtual AstType type() const { return AstType::SCOPENAME;}
virtual AstNode* clone() { return new AstScopeName(*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; }
AstText* scopeAttrp() const { return op1p()->castText(); }
void scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
};
//======================================================================
// non-ary ops
@@ -2491,6 +2606,39 @@ struct AstNeqCase : public AstNodeBiCom {
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
};
struct AstEqWild : public AstNodeBiop {
// Note wildcard operator rhs differs from lhs
AstEqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
width(1,1); }
virtual ~AstEqWild() {}
virtual AstType type() const { return AstType::EQWILD;}
virtual AstNode* clone() { return new AstEqWild(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildEq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k==? %r)"; }
virtual string emitOperator() { return "VL_EQ"; } // Until have 4 state anyways
virtual string emitSimpleOperator() { return "=="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
};
struct AstNeqWild : public AstNodeBiop {
AstNeqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
width(1,1); }
virtual ~AstNeqWild() {}
virtual AstType type() const { return AstType::NEQWILD;}
virtual AstNode* clone() { return new AstNeqWild(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildNeq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k!=? %r)"; }
virtual string emitOperator() { return "VL_NEQ"; } // Until have 4 state anyways
virtual string emitSimpleOperator() { return "!="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
};
struct AstConcat : public AstNodeBiop {
// If you're looking for {#{}}, see AstReplicate
AstConcat(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
@@ -2525,6 +2673,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
+13 -1
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.
//
@@ -131,6 +131,18 @@ private:
nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL;
}
virtual void visit(AstScopeName* nodep, AstNUser*) {
// If there's a %m in the display text, we add a special node that will contain the name()
// Similar code in V3Inline
if (m_beginScope != "") {
// 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);
}
+1 -1
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.
//
+2 -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,7 @@
// BRANCH TRANSFORMATIONS:
// At each IF/(IF else).
// Count underneath $display/$stop statements.
// If more on if then else, this branch is unlikely, or vice-versa.
// If more on if than else, this branch is unlikely, or vice-versa.
//
//*************************************************************************
+1 -1
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.
//
+103 -17
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,7 @@
#include <stdarg.h>
#include <unistd.h>
#include <algorithm>
#include <set>
#include <map>
#include "V3Global.h"
#include "V3Broken.h"
@@ -45,19 +45,100 @@ class BrokenTable : public AstNVisitor {
private:
// MEMBERS
// For each node, we keep if it exists or not.
typedef set<const AstNode*> NodeSet;
static NodeSet s_nodes; // Set of all nodes that exist
typedef map<const AstNode*,int> NodeMap;
static NodeMap s_nodes; // Set of all nodes that exist
// BITMASK
static const int FLAG_ALLOCATED = 0x01; // new() and not delete()ed
static const int FLAG_IN_TREE = 0x02; // Is in netlist tree
static const int FLAG_LINKABLE = 0x04; // Is in netlist tree, can be linked to
static const int FLAG_LEAKED = 0x08; // Known to have been leaked
public:
// METHODS
static void add(const AstNode* nodep) {
s_nodes.insert(nodep);
static void deleted(const AstNode* nodep) {
// Called by operator delete on any node - only if VL_LEAK_CHECKS
if (debug()) cout<<"-nodeDel: "<<(void*)(nodep)<<endl;
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter==s_nodes.end() || !(iter->second & FLAG_ALLOCATED)) {
((AstNode*)(nodep))->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted\n");
}
if (iter!=s_nodes.end()) s_nodes.erase(iter);
}
static bool exists(const AstNode* nodep) {
NodeSet::iterator iter = s_nodes.find(nodep);
return (iter != s_nodes.end());
static void addNewed(const AstNode* nodep) {
// Called by operator new on any node - only if VL_LEAK_CHECKS
if (debug()) cout<<"-nodeNew: "<<(void*)(nodep)<<endl;
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter!=s_nodes.end() || (iter->second & FLAG_ALLOCATED)) {
((AstNode*)(nodep))->v3fatalSrc("Newing AstNode object that is already allocated\n");
}
if (iter == s_nodes.end()) {
s_nodes.insert(make_pair(nodep,FLAG_ALLOCATED));
}
}
static void clear() {
static void addInTree(AstNode* nodep, bool linkable) {
#ifndef VL_LEAK_CHECKS
if (!linkable) return; // save some time, else the map will get huge!
#endif
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter == s_nodes.end()) {
#ifdef VL_LEAK_CHECKS
nodep->v3fatalSrc("AstNode is in tree, but not allocated\n");
#endif
} else {
if (!(iter->second & FLAG_ALLOCATED)) {
#ifdef VL_LEAK_CHECKS
nodep->v3fatalSrc("AstNode is in tree, but not allocated\n");
#endif
}
if (iter->second & FLAG_IN_TREE) {
nodep->v3fatalSrc("AstNode is already in tree at another location\n");
}
}
int or_flags = FLAG_IN_TREE | (linkable?FLAG_LINKABLE:0);
if (iter == s_nodes.end()) {
s_nodes.insert(make_pair(nodep,or_flags));
} else {
iter->second |= or_flags;
}
}
static bool okIfLinkedTo(const AstNode* nodep) {
// Someone has a pointer to this node. Is it kosher?
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter == s_nodes.end()) return false;
#ifdef VL_LEAK_CHECKS
if (!(iter->second & FLAG_ALLOCATED)) return false;
#endif
if (!(iter->second & FLAG_IN_TREE)) return false;
if (!(iter->second & FLAG_LINKABLE)) return false;
return true;
}
static void prepForTree() {
#ifndef VL_LEAK_CHECKS
s_nodes.clear();
#endif
for (NodeMap::iterator it = s_nodes.begin(); it != s_nodes.end(); ++it) {
it->second &= ~FLAG_IN_TREE;
it->second &= ~FLAG_LINKABLE;
}
}
static void doneWithTree() {
for (int backs=0; backs<2; backs++) { // Those with backp() are probably under one leaking without
for (NodeMap::iterator it = s_nodes.begin(); it != s_nodes.end(); ++it) {
if ((it->second & FLAG_ALLOCATED)
&& !(it->second & FLAG_IN_TREE)
&& !(it->second & FLAG_LEAKED)
&& (it->first->backp() ? backs==1 : backs==0)) {
// Use only AstNode::dump instead of the virtual one, as there
// may be varp() and other cross links that are bad.
if (debug()) {
cout<<"%Error: LeakedNode"<<(it->first->backp()?"Back: ":": ");
((AstNode*)(it->first))->AstNode::dump(cout);
cout<<endl;
V3Error::incErrors();
}
it->second |= FLAG_LEAKED;
}
}
}
}
public:
// CONSTUCTORS
@@ -65,11 +146,11 @@ public:
virtual ~BrokenTable() {}
};
BrokenTable::NodeSet BrokenTable::s_nodes;
BrokenTable::NodeMap BrokenTable::s_nodes;
bool AstNode::brokeExists() const {
// Called by node->broken() routines to do table lookup
return BrokenTable::exists(this);
return BrokenTable::okIfLinkedTo(this);
}
//######################################################################
@@ -82,9 +163,7 @@ private:
// // so userp and friends may not be used
// VISITORS
virtual void visit(AstNode* nodep, AstNUser*) {
if (nodep->maybePointedTo()) {
BrokenTable::add(nodep);
}
BrokenTable::addInTree(nodep, nodep->maybePointedTo());
nodep->iterateChildren(*this);
}
public:
@@ -127,8 +206,15 @@ public:
void V3Broken::brokenAll(AstNetlist* nodep) {
//UINFO(9,__FUNCTION__<<": "<<endl);
BrokenTable::clear();
BrokenTable::prepForTree();
BrokenMarkVisitor mvisitor (nodep);
BrokenCheckVisitor cvisitor (nodep);
BrokenTable::clear();
BrokenTable::doneWithTree();
}
void V3Broken::addNewed(AstNode* nodep) {
BrokenTable::addNewed(nodep);
}
void V3Broken::deleted(AstNode* nodep) {
BrokenTable::deleted(nodep);
}
+3 -1
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,6 +31,8 @@
class V3Broken {
public:
static void brokenAll(AstNetlist* nodep);
static void addNewed(AstNode* nodep);
static void deleted(AstNode* nodep);
};
#endif // Guard
+73 -32
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,6 +52,7 @@
#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
//######################################################################
@@ -61,9 +62,6 @@ private:
//int debug() { return 9; }
virtual void visit(AstNodeCase* nodep, AstNUser*) {
// We report a syntax error on empty "case (x) endcase" blocks, so never no items at all
if (!nodep->itemsp()) nodep->v3fatalSrc("No items (not even default) under case statement?\n");
// Detect multiple defaults
bool hitDefault = false;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
@@ -220,7 +218,10 @@ private:
a++, b++) {
if (m_valueItem[a] != m_valueItem[b]) { same=false; break; }
}
if (same) return tree0p;
if (same) {
tree1p->deleteTree(); tree1p=NULL;
return tree0p;
}
// Must have differing logic, so make a selection
@@ -247,8 +248,7 @@ private:
// CASEx(cexpr,....
// -> tree of IF(msb, IF(msb-1, 11, 10)
// IF(msb-1, 01, 00))
AstNode* cexprp = nodep->exprp();
cexprp->unlinkFrBack();
AstNode* cexprp = nodep->exprp()->unlinkFrBack();
if (debug()>=9) {
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
@@ -266,6 +266,8 @@ private:
if (ifrootp) nodep->replaceWith(ifrootp);
else nodep->unlinkFrBack();
nodep->deleteTree(); nodep=NULL;
cexprp->deleteTree(); cexprp=NULL;
if (debug()>=9) ifrootp->dumpTree(cout," _simp: ");
}
@@ -275,21 +277,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;
@@ -312,6 +308,7 @@ private:
and2p = new AstAnd(itemp->fileline(),
new AstConst(itemp->fileline(), numval),
new AstConst(itemp->fileline(), nummask));
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
} else {
// Not a caseX mask, we can simply build CASEEQ(cexpr icond)
and1p = cexprp->cloneTree(false);
@@ -324,24 +321,68 @@ 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);
}
}
cexprp->deleteTree(); cexprp=NULL;
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) {
+1 -1
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 -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.
//
@@ -60,6 +60,7 @@ class CastVisitor : public AstNVisitor {
private:
// NODE STATE
// Entire netlist:
// AstNode::user() // bool. Indicates node is of known size
// STATE
//int debug() { return 9; }
@@ -76,6 +77,7 @@ private:
//if (debug()>8) castp->dumpTree(cout,"-castins: ");
//
insureLower32Cast(castp);
nodep->user(1); // Now must be of known size
}
int castSize (AstNode* nodep) {
if (nodep->isQuad()) return VL_QUADSIZE;
@@ -84,7 +86,8 @@ private:
else return VL_WORDSIZE;
}
void insureCast(AstNode* nodep) {
if (castSize(nodep->backp()) != castSize(nodep)) {
if (castSize(nodep->backp()) != castSize(nodep)
|| !nodep->user()) {
insertCast(nodep, castSize(nodep->backp()));
}
}
@@ -102,15 +105,21 @@ private:
// VISITORS
virtual void visit(AstNodeUniop* nodep, AstNUser*) {
nodep->iterateChildren(*this);
nodep->user(nodep->lhsp()->user());
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
}
virtual void visit(AstNodeBiop* nodep, AstNUser*) {
nodep->iterateChildren(*this);
nodep->user(nodep->lhsp()->user()
| nodep->rhsp()->user());
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
}
virtual void visit(AstNodeTriop* nodep, AstNUser*) {
nodep->iterateChildren(*this);
nodep->user(nodep->lhsp()->user()
| nodep->rhsp()->user()
| nodep->thsp()->user());
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
if (nodep->sizeMattersThs()) insureCast(nodep->thsp());
@@ -118,9 +127,11 @@ private:
virtual void visit(AstCast* nodep, AstNUser*) {
nodep->iterateChildren(*this);
insureLower32Cast(nodep);
nodep->user(1);
}
virtual void visit(AstUnaryMin* nodep, AstNUser*) {
nodep->iterateChildren(*this);
nodep->user(nodep->lhsp()->user());
if (nodep->lhsp()->widthMin()==1) {
// We want to avoid a GCC "converting of negative value" warning
// from our expansion of
@@ -140,6 +151,13 @@ private:
// CData x=3; out = (QData)(x<<30);
insertCast (nodep, castSize(nodep));
}
nodep->user(1);
}
virtual void visit(AstConst* nodep, AstNUser*) {
// Constants are of unknown size if smaller than 33 bits, becase
// we're too lazy to wrap every constant in the universe in
// ((IData)#).
nodep->user(nodep->isQuad() || nodep->isWide());
}
// NOPs
@@ -154,6 +172,7 @@ private:
public:
// CONSTUCTORS
CastVisitor(AstNetlist* nodep) {
AstNode::userClearTree();
nodep->accept(*this);
}
virtual ~CastVisitor() {}
+1 -1
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.
//
+1 -1
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.
//
+1 -1
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.
//
+5 -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.
//
@@ -104,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);
@@ -199,6 +196,9 @@ private:
virtual void visit(AstText* nodep, AstNUser*) {
setClean (nodep, true);
}
virtual void visit(AstScopeName* nodep, AstNUser*) {
setClean (nodep, true);
}
virtual void visit(AstSel* nodep, AstNUser*) {
operandTriop(nodep);
setClean (nodep, nodep->cleanOut());
+1 -1
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.
//
+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.
//
@@ -472,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),
+1 -1
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.
//
+1 -1
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.
//
+1 -1
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.
//
+86 -11
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.
//
@@ -246,9 +246,8 @@ private:
replaceNum(nodep, 0); nodep=NULL;
}
void replaceAllOnes (AstNode* nodep) {
V3Number num (nodep->fileline(), nodep->width(), 0);
V3Number ones (nodep->fileline(), nodep->width());
ones.opNot(num);
V3Number ones (nodep->fileline(), nodep->width(), 0);
ones.setMask(nodep->width());
replaceNum(nodep, ones); nodep=NULL;
}
void replaceConst(AstNodeUniop* nodep) {
@@ -385,10 +384,12 @@ private:
int shift1 = shift1p->castConst()->asInt(); if (lhsp->castShiftR()) shift1=-shift1;
int shift2 = shift2p->castConst()->asInt(); if (nodep->castShiftR()) shift2=-shift2;
int newshift = shift1+shift2;
shift1p->deleteTree(); shift1p=NULL;
shift2p->deleteTree(); shift1p=NULL;
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 {
@@ -525,7 +526,8 @@ private:
if (debug()>=9) asn1p->dumpTree(cout," _new: ");
if (debug()>=9) asn2p->dumpTree(cout," _new: ");
// Cleanup
nodep->unlinkFrBack()->deleteTree();
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
conp->deleteTree(); conp=NULL;
// Further reduce, either node may have more reductions.
return true;
}
@@ -638,6 +640,7 @@ private:
// If bp was a concat, then we have this exact same form again!
// Recurse rather then calling node->iterate to prevent 2^n recursion!
if (operandConcatMove(abConcp)) moveConcat(abConcp);
bcConcp->deleteTree(); bcConcp=NULL;
} else {
AstConcat* abConcp = nodep->lhsp()->castConcat(); abConcp->unlinkFrBack();
AstNode* ap = abConcp->lhsp()->unlinkFrBack();
@@ -648,6 +651,7 @@ private:
nodep->lhsp(ap);
nodep->rhsp(bcConcp);
if (operandConcatMove(bcConcp)) moveConcat(bcConcp);
abConcp->deleteTree(); abConcp=NULL;
}
}
@@ -678,6 +682,8 @@ private:
if (lsb1p->castConst() && lsb2p->castConst()) {
newlsbp = new AstConst(lsb1p->fileline(),
lsb1p->castConst()->asInt() + lsb2p->castConst()->asInt());
lsb1p->deleteTree(); lsb1p=NULL;
lsb2p->deleteTree(); lsb2p=NULL;
} else {
// Width is important, we need the width of the fromp's
// expression, not the potentially smaller lsb1p's width
@@ -757,7 +763,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();
@@ -802,7 +809,12 @@ private:
if (nodep->sensp()->castConst()
|| (nodep->varrefp() && nodep->varrefp()->varp()->isParam())) {
// Constants in sensitivity lists may be removed (we'll simplify later)
AstSenItem* newp = new AstSenItem(nodep->fileline(), AstSenItem::Never());
AstSenItem* newp;
if (nodep->isClocked()) { // A constant can never get a pos/negexge
newp = new AstSenItem(nodep->fileline(), AstSenItem::Never());
} else { // Otherwise it may compute a result that needs to settle out
newp = new AstSenItem(nodep->fileline(), AstSenItem::Combo());
}
nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL;
} else if (nodep->sensp()->castNot()) {
@@ -855,7 +867,7 @@ private:
new AstAssign(nodep->fileline(),
varrefp, exprp));
m_modp->addStmtp(newinitp);
nodep->unlinkFrBack(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
// Set the initial value right in the variable so we can constant propagate
AstNode* initvaluep = exprp->cloneTree(false);
varrefp->varp()->initp(initvaluep);
@@ -938,6 +950,63 @@ private:
}
}
virtual void visit(AstDisplay* nodep, AstNUser*) {
// Substitute constants into displays. The main point of this is to
// simplify assertion methodologies which call functions with display's.
// This eliminates a pile of wide temps, and makes the C a whole lot more readable.
nodep->iterateChildren(*this);
bool anyconst = false;
for (AstNode* argp = nodep->exprsp(); argp; argp=argp->nextp()) {
if (argp->castConst()) { anyconst=true; break; }
}
if (anyconst) {
//UINFO(9," Display in "<<nodep->text()<<endl);
string dispout = "";
string fmt = "";
bool inPct = false;
AstNode* argp = nodep->exprsp();
for (const char* inp = nodep->text().c_str(); *inp; inp++) {
char ch = *inp; // Breaks with iterators...
if (!inPct && ch=='%') {
inPct = true;
fmt = ch;
} else if (inPct && isdigit(ch)) {
fmt += ch;
} else if (inPct) {
inPct = false;
fmt += ch;
switch (tolower(ch)) {
case '%': break; // %% - just output a %
case 'm': break; // %m - auto insert "name"
default: // Most operators, just move to next argument
if (argp) {
AstNode* nextp=argp->nextp();
if (argp && argp->castConst()) { // Convert it
string out = argp->castConst()->num().displayed(fmt);
UINFO(9," DispConst: "<<fmt<<" -> "<<out<<" for "<<argp<<endl);
{ // fmt = out w/ replace % with %% as it must be literal.
fmt = "";
for (string::iterator pos = out.begin(); pos != out.end(); pos++) {
if (*pos == '%') fmt += '%';
fmt += *pos;
}
}
argp->unlinkFrBack()->deleteTree();
}
argp=nextp;
}
break;
} // switch
dispout += fmt;
} else {
dispout += ch;
}
}
nodep->text(dispout);
//UINFO(9," Display out "<<nodep->text()<<endl);
}
}
virtual void visit(AstWhile* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (nodep->condp()->isZero()) {
@@ -954,7 +1023,7 @@ private:
// Below lines are magic expressions processed by astgen
// "AstNODETYPE { # bracket not paren
// $accessor_name, ...
// # ,, gets replaced with a , rather then &&
// # ,, gets replaced with a , rather than &&
// }" # bracket not paren
// ,"function to call"
// or ,"AstREPLACEMENT_TYPE{ $accessor }"
@@ -1048,6 +1117,10 @@ private:
TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase {$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castNeqCase}", "AstEqCase {$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castEqWild, $lhsp.width1}","AstNeqWild{$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castEqWild}", "AstNeqWild{$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castNeqWild, $lhsp.width1}","AstEqWild {$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castNeqWild}", "AstEqWild {$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castEq, $lhsp.width1}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castEq}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castNeq, $lhsp.width1}", "AstEq {$lhsp->op1p(),$lhsp->op2p()}");
@@ -1089,6 +1162,7 @@ private:
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("AstEqWild {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)");
@@ -1099,6 +1173,7 @@ private:
TREEOP("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstNeqCase{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstNeqWild{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
@@ -1129,7 +1204,7 @@ private:
TREEOPV("AstRedXor{$lhsp->castExtend()}", "AstRedXor{$lhsp->castExtend()->lhsp()}");
TREEOPV("AstOneHot{$lhsp.width1}", "replaceWLhs(nodep)");
TREEOPV("AstOneHot0{$lhsp.width1}", "replaceNum(nodep,1)");
// Binary AND/OR is faster then logical and/or (usually)
// Binary AND/OR is faster than logical and/or (usually)
TREEOPV("AstLogAnd{$lhsp.width1, $rhsp.width1}", "AstAnd{$lhsp,$rhsp}");
TREEOPV("AstLogOr {$lhsp.width1, $rhsp.width1}", "AstOr{$lhsp,$rhsp}");
TREEOPV("AstLogNot{$lhsp.width1}", "AstNot{$lhsp}");
+1 -1
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.
//
+1 -1
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.
//
+1 -1
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.
//
+1 -1
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.
//
+1 -1
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.
//
+13 -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.
//
@@ -110,18 +110,6 @@ private:
}
AstVarScope* createVarSc(AstVarScope* oldvarscp, string name, int width/*0==fromoldvar*/) {
// Because we've already scoped it, we may need to add both the AstVar and the AstVarScope
AstRange* rangep = NULL;
if (width==0) {
rangep = new AstRange(oldvarscp->fileline(),
oldvarscp->varp()->msb(),
oldvarscp->varp()->lsb());
} else if (width==1) {
rangep = NULL;
} else {
rangep = new AstRange(oldvarscp->fileline(),
width-1, 0);
}
if (!oldvarscp->scopep()) oldvarscp->v3fatalSrc("Var unscoped");
AstVar* varp;
AstModule* addmodp = oldvarscp->scopep()->modp();
@@ -131,6 +119,17 @@ private:
// Created module's AstVar earlier under some other scope
varp = iter->second;
} else {
AstRange* rangep = NULL;
if (width==0) {
rangep = new AstRange(oldvarscp->fileline(),
oldvarscp->varp()->msb(),
oldvarscp->varp()->lsb());
} else if (width==1) {
rangep = NULL;
} else {
rangep = new AstRange(oldvarscp->fileline(),
width-1, 0);
}
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, rangep);
if (width==0) varp->widthSignedFrom(oldvarscp);
addmodp->addStmtp(varp);
@@ -226,7 +225,7 @@ private:
if (nodep->user5p()) {
// Simplistic optimization. If the previous statement in same scope was also a =>,
// then we told this nodep->user5 we can use its Vdlyvset rather then making a new one.
// then we told this nodep->user5 we can use its Vdlyvset rather than making a new one.
// This is good for code like:
// for (i=0; i<5; i++) vector[i] <= something;
sharedVset = true;
+1 -1
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.
//
+7 -15
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.
//
@@ -40,7 +40,6 @@
#include "V3Ast.h"
//######################################################################
// Depth state, as a visitor of each AstNode
class DepthVisitor : public AstNVisitor {
private:
@@ -55,11 +54,6 @@ private:
//int debug() { return 9; }
// MSVC++ has a limit of 100 parenthesis. We have some operator
// defines that use 2 parens. Thus we can't have a expression deeper
// then 50 operators. We'll add some margin though.
enum en { MAX_EXPR_DEPTH = 40 }; // Expressions deeper then this need temp
// METHODS
void createDeepTemp(AstNode* nodep) {
UINFO(6," Deep "<<nodep<<endl);
@@ -114,13 +108,15 @@ private:
virtual void visit(AstNodeTermop* nodep, AstNUser*) {
}
virtual void visit(AstNodeMath* nodep, AstNUser*) {
m_depth++;
// We have some operator defines that use 2 parens, so += 2.
m_depth += 2;
if (m_depth>m_maxdepth) m_maxdepth=m_depth;
nodep->iterateChildren(*this);
m_depth--;
m_depth -= 2;
if ((m_maxdepth-m_depth) > MAX_EXPR_DEPTH
&& m_stmtp
if (m_stmtp
&& (v3Global.opt.compLimitParens() >= 1) // Else compiler doesn't need it
&& (m_maxdepth-m_depth) > v3Global.opt.compLimitParens()
&& !nodep->backp()->castNodeStmt() // Not much point if we're about to use it
) {
m_maxdepth = m_depth;
@@ -173,14 +169,10 @@ public:
virtual ~DepthVisitor() {}
};
//----------------------------------------------------------------------
// Top loop
//######################################################################
// Depth class functions
void V3Depth::depthAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
// We must do it in bottom-up module
DepthVisitor visitor (nodep);
}
+1 -1
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.
//
+139
View File
@@ -0,0 +1,139 @@
// $Id$
//*************************************************************************
// DESCRIPTION: Verilator: Prevent very deep expressions
//
// Code available from: http://www.veripool.com/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
// V3DepthBlock's Transformations:
//
// Each module:
// For each deep block, create cfunc including that block.
//
//*************************************************************************
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <algorithm>
#include "V3Global.h"
#include "V3DepthBlock.h"
#include "V3Ast.h"
#include "V3EmitCBase.h"
//######################################################################
class DepthBlockVisitor : public AstNVisitor {
private:
// NODE STATE
// STATE
AstModule* m_modp; // Current module
AstCFunc* m_funcp; // Current function
int m_depth; // How deep in an expression
int m_deepNum; // How many functions made
//int debug() { return 9; }
// METHODS
AstCFunc* createDeepFunc(AstNode* nodep) {
AstNRelinker relinkHandle;
nodep->unlinkFrBack(&relinkHandle);
// Create function
string name = m_funcp->name()+"__deep"+cvtToStr(++m_deepNum);
AstCFunc* funcp = new AstCFunc(nodep->fileline(), name, NULL);
funcp->argTypes(EmitCBaseVisitor::symClassVar());
funcp->symProlog(true);
funcp->slow(m_funcp->slow());
funcp->addStmtsp(nodep);
m_modp->addStmtp(funcp);
// Call it at the point where the body was removed from
AstCCall* callp = new AstCCall(nodep->fileline(), funcp);
callp->argTypes("vlSymsp");
UINFO(6," New "<<callp<<endl);
//
relinkHandle.relink(callp);
return funcp;
}
// VISITORS
virtual void visit(AstModule* nodep, AstNUser*) {
UINFO(4," MOD "<<nodep<<endl);
m_modp = nodep;
m_deepNum = 0;
nodep->iterateChildren(*this);
}
virtual void visit(AstCFunc* nodep, AstNUser*) {
// We recurse into this.
int lastDepth = m_depth;
AstCFunc* lastFuncp = m_funcp;
{
m_depth = 0;
m_funcp = nodep;
nodep->iterateChildren(*this);
}
m_depth = lastDepth;
m_funcp = lastFuncp;
}
void visitStmt(AstNodeStmt* nodep) {
m_depth++;
if (m_depth > v3Global.opt.compLimitBlocks()
&& !nodep->castCCall()) { // Already done
UINFO(4, "DeepBlocks "<<m_depth<<" "<<nodep<<endl);
AstNode* backp = nodep->backp(); // Only for debug
if (debug()>=9) backp->dumpTree(cout,"- pre : ");
AstCFunc* funcp = createDeepFunc(nodep);
funcp->accept(*this);
if (debug()>=9) backp->dumpTree(cout,"- post: ");
if (debug()>=9) funcp->dumpTree(cout,"- func: ");
} else {
nodep->iterateChildren(*this);
}
m_depth--;
}
virtual void visit(AstNodeStmt* nodep, AstNUser*) {
visitStmt(nodep);
}
virtual void visit(AstNodeMath* nodep, AstNUser*) {} // Accelerate
//--------------------
// Default: Just iterate
virtual void visit(AstVar* nodep, AstNUser*) {} // Don't hit varrefs under vars
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
DepthBlockVisitor(AstNode* nodep) {
m_modp=NULL;
m_depth=0;
//
nodep->accept(*this);
}
virtual ~DepthBlockVisitor() {}
};
//######################################################################
// DepthBlock class functions
void V3DepthBlock::depthBlockAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DepthBlockVisitor visitor (nodep);
}
+36
View File
@@ -0,0 +1,36 @@
// $Id$ //-*- C++ -*-
//*************************************************************************
// DESCRIPTION: Verilator: Prevent very deep expressions
//
// Code available from: http://www.veripool.com/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
#ifndef _V3DEPTHBLOCK_H_
#define _V3DEPTHBLOCK_H_ 1
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
//============================================================================
class V3DepthBlock {
public:
static void depthBlockAll(AstNetlist* nodep);
};
#endif // Guard
+3 -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.
//
@@ -160,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 {
+1 -1
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.
//
+70 -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.
//
@@ -239,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 than 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*) {
@@ -353,7 +388,7 @@ public:
}
virtual void visit(AstMulS* nodep, AstNUser* vup) {
if (nodep->widthWords() > VL_MULS_MAX_WORDS) {
nodep->v3error("Signed multiply of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h\n");
nodep->v3error("Unsupported: Signed multiply of "<<nodep->width()<<" bits exceeds hardcoded limit VL_MULS_MAX_WORDS in verilatedos.h\n");
}
visit(nodep->castNodeBiop(), vup);
}
@@ -559,7 +594,14 @@ class EmitCImp : EmitCStmts {
if (filenum) filenameNoExt += "__"+cvtToStr(filenum);
filenameNoExt += (slow ? "__Slow":"");
V3OutCFile* ofp = NULL;
if (optSystemPerl()) {
if (v3Global.opt.lintOnly()) {
// Unfortunately we have some lint checks here, so we can't just skip processing.
// We should move them to a different stage.
string filename = "/dev/null";
newCFile(filename, slow, source);
ofp = new V3OutSpFile (filename);
}
else if (optSystemPerl()) {
string filename = filenameNoExt+".sp";
newCFile(filename, slow, source);
ofp = new V3OutSpFile (filename);
@@ -652,6 +694,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; );");
}
}
}
}
@@ -963,7 +1020,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
@@ -996,16 +1052,17 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
// Spec: h d o b c l
case 'b': displayArg(nodep,&elistp,fmt,'b'); break;
case 'c': displayArg(nodep,&elistp,fmt,'c'); break;
case 't':
case 'd': displayArg(nodep,&elistp,fmt,'u'); break; // Unsigned decimal
case 'o': displayArg(nodep,&elistp,fmt,'o'); break;
case 'h':
case 'x': displayArg(nodep,&elistp,fmt,'x'); break;
case 's': displayArg(nodep,&elistp,fmt,'s'); break;
case 't': displayArg(nodep,&elistp,fmt,'u'); break;
case 'm': {
emitDispState.pushFormat("%s");
emitDispState.pushArg(NULL, "vlSymsp->name(");
for (AstText* textp=nodep->scopeTextp(); textp; textp=textp->nextp()->castText()) {
if (!nodep->scopeNamep()) nodep->v3fatalSrc("Display with %m but no AstScopeName");
for (AstText* textp=nodep->scopeNamep()->scopeAttrp(); textp; textp=textp->nextp()->castText()) {
emitDispState.pushFormat(textp->text());
}
break;
@@ -1026,7 +1083,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);
}
@@ -1157,7 +1214,7 @@ void EmitCImp::emitConfigureImp(AstModule* modp) {
void EmitCImp::emitCoverageImp(AstModule* modp) {
if (m_coverIds.size()) {
puts("\n// Coverage\n");
// Rather then putting out SP_COVER_INSERT calls directly, we do it via this function
// Rather than putting out SP_COVER_INSERT calls directly, we do it via this function
// This gets around gcc slowness constructing all of the template arguments
puts("void "+modClassName(m_modp)+"::__vlCoverInsert(SpZeroed<uint32_t>* countp, const char* filename, int lineno, int column,\n");
puts( "const char* hier, const char* type, const char* comment) {\n");
@@ -1371,6 +1428,9 @@ void EmitCImp::emitInt(AstModule* modp) {
if (v3Global.opt.coverage()) {
puts("#include \"SpCoverage.h\"\n");
}
if (v3Global.needHInlines()) { // Set by V3EmitCInlines; should have been called before us
puts("#include \""+topClassName()+"__Inlines.h\"\n");
}
// Declare foreign instances up front to make C++ happy
puts("class "+symClassName()+";\n");
+2 -1
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,6 +31,7 @@
class V3EmitC {
public:
static void emitc();
static void emitcInlines();
static void emitcSyms();
static void emitcTrace();
};
+1 -1
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.
//
+126
View File
@@ -0,0 +1,126 @@
// $Id$
//*************************************************************************
// DESCRIPTION: Verilator: Emit C++ for tree
//
// Code available from: http://www.veripool.com/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// 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.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <math.h>
#include <map>
#include <vector>
#include "V3Global.h"
#include "V3EmitC.h"
#include "V3EmitCBase.h"
#include "V3Stats.h"
#define EMITCINLINES_NUM_CONSTW 10 // Number of VL_CONST_W_*X's in verilated.h (IE VL_CONST_W_9X is last)
//######################################################################
class EmitCInlines : EmitCBaseVisitor {
// STATE
vector<V3Double0> m_wordWidths; // What sizes are used?
// METHODS
void emitInt();
// VISITORS
virtual void visit(AstVar* nodep, AstNUser*) {
// All wide constants load into variables, so we can just hunt for them
if (nodep->widthWords() >= EMITCINLINES_NUM_CONSTW ) {
if (int(m_wordWidths.size()) <= nodep->widthWords()) {
m_wordWidths.resize(nodep->widthWords()+5);
}
++ m_wordWidths.at(nodep->widthWords());
v3Global.needHInlines(true);
}
}
// NOPs
virtual void visit(AstNodeStmt*, AstNUser*) {}
// Default
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
//---------------------------------------
// ACCESSORS
public:
EmitCInlines(AstNetlist* nodep) {
nodep->accept(*this);
if (v3Global.needHInlines()) {
emitInt();
}
}
};
void EmitCInlines::emitInt() {
string filename = v3Global.opt.makeDir()+"/"+topClassName()+"__Inlines.h";
newCFile(filename, false/*slow*/, false/*source*/);
V3OutCFile hf (filename);
m_ofp = &hf;
ofp()->putsHeader();
puts("#ifndef _"+topClassName()+"__Inlines_H_\n");
puts("#define _"+topClassName()+"__Inlines_H_\n");
puts("\n");
puts("#include \"verilated.h\"\n");
puts("\n//======================\n\n");
for (unsigned words=0; words<m_wordWidths.size(); words++) {
if (m_wordWidths.at(words)) {
puts("#ifndef VL_HAVE_CONST_W_"+cvtToStr(words)+"X\n");
puts("# define VL_HAVE_CONST_W_"+cvtToStr(words)+"X\n");
puts("static inline WDataOutP VL_CONST_W_"+cvtToStr(words)+"X(int obits, WDataOutP o\n");
puts("\t");
for (int i=words-1; i>=0; --i) {
puts(",IData d"+cvtToStr(i));
if (i && (i % 8 == 0)) puts("\n\t");
}
puts(") {\n");
puts(" ");
for (int i=words-1; i>=0; --i) {
puts(" o["+cvtToStr(i)+"]=d"+cvtToStr(i)+";");
if (i && (i % 8 == 0)) puts("\n ");
}
puts("\n");
puts(" for(int i="+cvtToStr(words)+";i<VL_WORDS_I(obits);i++) o[i] = (IData)0x0;\n");
puts(" return o;\n");
puts("}\n");
puts("#endif\n");
puts("\n");
}
}
puts("//======================\n\n");
puts("#endif /*guard*/\n");
}
//######################################################################
// EmitC class functions
void V3EmitC::emitcInlines() {
UINFO(2,__FUNCTION__<<": "<<endl);
EmitCInlines syms (v3Global.rootp());
}
+1 -1
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.
//
+2 -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.
//
@@ -138,7 +138,7 @@ public:
of.puts("\n# Link rules...\n");
of.puts(v3Global.opt.prefix()+": $(VK_USER_OBJS) $(SP_SRCS) $(VM_PREFIX)__ALL.a\n");
of.puts("\t$(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) 2>&1 | c++filt\n");
of.puts("\t$(LINK) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) $(SC_LIBS) 2>&1 | c++filt\n");
of.puts("\n");
}
+1 -1
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.
//
+13 -1
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.
//
@@ -193,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;
@@ -236,6 +246,8 @@ public:
virtual void visit(AstText* nodep, AstNUser*) {
ofp()->putsNoTracking(nodep->text());
}
virtual void visit(AstScopeName* nodep, AstNUser*) {
}
virtual void visit(AstCStmt* nodep, AstNUser*) {
putbs("$_CSTMT(");
nodep->bodysp()->iterateAndNext(*this);
+1 -1
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.
//
+77 -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.
//
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <set>
#include "V3Error.h"
#ifndef _V3ERROR_NO_GLOBAL_
# include "V3Ast.h"
@@ -34,7 +35,8 @@
FileLine FileLine::s_defaultFileLine = FileLine(EmptySecret());
int V3Error::s_errcnt = 0;
int V3Error::s_errCount = 0;
int V3Error::s_warnCount = 0;
int V3Error::s_debugDefault = 0;
ostringstream V3Error::s_errorStr; // Error string being formed
V3ErrorCode V3Error::s_errorCode = V3ErrorCode::FATAL;
@@ -100,9 +102,16 @@ bool FileLine::warnOff(const string& msg, bool flag) {
}
}
void FileLine::warnLintOff(bool flag) {
for (int codei=V3ErrorCode::FIRST_WARN; codei<V3ErrorCode::MAX; codei++) {
V3ErrorCode code = (V3ErrorCode)codei;
if (code.lintError()) warnOff(code, flag);
}
}
FileLine* FileLine::copyOrSameFileLine() {
// Return this, or a copy of this
// There are often more then one token per line, thus we use the
// There are often more than one token per line, thus we use the
// same pointer as long as we're on the same line.
static FileLine* lastNewp = NULL;
if (lastNewp && *lastNewp == *this) {
@@ -162,6 +171,46 @@ void FileLine::v3errorEnd(ostringstream& str) {
V3Error::v3errorEnd(str);
}
}
#ifdef VL_LEAK_CHECKS
typedef set<FileLine*> FileLineCheckSet;
FileLineCheckSet fileLineLeakChecks;
void* FileLine::operator new(size_t size) {
FileLine* objp = static_cast<FileLine*>(::operator new(size));
fileLineLeakChecks.insert(objp);
return objp;
}
void FileLine::operator delete(void* objp, size_t size) {
if (!objp) return;
FileLine* flp = static_cast<FileLine*>(objp);
FileLineCheckSet::iterator it = fileLineLeakChecks.find(flp);
if (it != fileLineLeakChecks.end()) {
fileLineLeakChecks.erase(it);
} else {
flp->v3fatalSrc("Deleting FileLine object that was never tracked\n");
}
::operator delete(objp);
}
#endif
void FileLine::deleteAllRemaining() {
#ifdef VL_LEAK_CHECKS
// FileLines are allocated, but never nicely freed, as it's much faster
// that way. Unfortunately this makes our leak checking a big mess, so
// only when leak checking we'll track them all and cleanup.
while (1) {
FileLineCheckSet::iterator it=fileLineLeakChecks.begin();
if (it==fileLineLeakChecks.end()) break;
delete *it;
// Operator delete will remove the iterated object from the list.
// Eventually the list will be empty and terminate the loop.
}
fileLineLeakChecks.clear();
#endif
}
//######################################################################
// V3Error class functions
@@ -187,8 +236,13 @@ string V3Error::lineStr (const char* filename, int lineno) {
return out.str();
}
void V3Error::incWarnings() {
s_warnCount++;
// We don't exit on a lot of warnings.
}
void V3Error::incErrors() {
s_errcnt++;
s_errCount++;
if (errorCount() == MAX_ERRORS) { // Not >= as would otherwise recurse
v3fatal ("Exiting due to too many errors encountered\n");
}
@@ -196,16 +250,30 @@ void V3Error::incErrors() {
void V3Error::abortIfErrors() {
if (errorCount()) {
v3fatal ("Exiting due to "<<dec<<errorCount()<<" warning(s)\n");
v3fatal ("Exiting due to "<<dec<<errorOrWarnCount()<<" warning(s)\n");
}
}
void V3Error::abortIfWarnings() {
if (errorOrWarnCount()) {
v3fatal ("Exiting due to "<<dec<<errorOrWarnCount()<<" warning(s)\n");
}
}
bool V3Error::isError(V3ErrorCode code) {
if (code==V3ErrorCode::SUPPRESS) return false;
else if (code==V3ErrorCode::FATAL) return true;
else if (code==V3ErrorCode::ERROR) return true;
else if (code<V3ErrorCode::FIRST_WARN
|| s_pretendError[code]) return true;
else return false;
}
string V3Error::msgPrefix(V3ErrorCode code) {
if (code==V3ErrorCode::SUPPRESS) return "-arning-suppressed: ";
else if (code==V3ErrorCode::FATAL) return "%Error: ";
else if (code==V3ErrorCode::ERROR) return "%Error: ";
else if (code<V3ErrorCode::FIRST_WARN
|| s_pretendError[code]) return "%Error-"+(string)code.ascii()+": ";
else if (isError(code)) return "%Error-"+(string)code.ascii()+": ";
else return "%Warning-"+(string)code.ascii()+": ";
}
@@ -258,7 +326,8 @@ void V3Error::v3errorEnd (ostringstream& sstr) {
cerr<<msgPrefix()<<"else you may end up with different sim results."<<endl;
}
}
incErrors();
if (isError(s_errorCode)) incErrors();
else incWarnings();
if (s_errorCode==V3ErrorCode::FATAL) {
static bool inFatal = false;
if (!inFatal) {
+34 -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.
//
@@ -37,6 +37,7 @@ public:
FATAL, // Kill the program
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
@@ -47,6 +48,7 @@ public:
CASEX, // Casex
CMPCONST, // Comparison is constant due to limited range
COMBDLY, // Combinatorial delayed assignment
STMTDLY, // Delayed statement
GENCLK, // Generated Clock
IMPLICIT, // Implicit wire
IMPURE, // Impure function not being inlined
@@ -71,11 +73,11 @@ public:
const char* names[] = {
// Leading spaces indicate it can't be disabled.
" SUPPRESS", " FATAL", " ERROR",
"TASKNSVAR",
"MULTITOP", "TASKNSVAR",
" FIRST_WARN",
"BLKANDNBLK",
"CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST",
"COMBDLY", "GENCLK", "IMPLICIT", "IMPURE",
"COMBDLY", "STMTDLY", "GENCLK", "IMPLICIT", "IMPURE",
"MULTIDRIVEN",
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
"VARHIDDEN", "WIDTH",
@@ -88,6 +90,13 @@ public:
// 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); };
// Warnings that are lint only
bool lintError() const { return ( m_e==CASEINCOMPLETE || m_e==CASEOVERLAP
|| m_e==CASEX || m_e==CMPCONST
|| m_e==IMPLICIT
|| m_e==UNDRIVEN || m_e==UNSIGNED
|| m_e==UNUSED || m_e==VARHIDDEN
|| m_e==WIDTH); };
};
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); }
@@ -103,11 +112,11 @@ class V3Error {
static bool s_describedEachWarn[V3ErrorCode::MAX]; // Told user specifics about this warning
static bool s_pretendError[V3ErrorCode::MAX]; // Pretend this warning is an error
static int s_debugDefault; // Default debugging level
static int s_errcnt; // Error count
static int s_errCount; // Error count
static int s_warnCount; // Error count
static ostringstream s_errorStr; // Error string being formed
static V3ErrorCode s_errorCode; // Error string being formed will abort
enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors
static void incErrors();
V3Error() { cerr<<("Static class"); abort(); }
@@ -117,12 +126,18 @@ class V3Error {
static void debugDefault(int level) { s_debugDefault = level; }
static int debugDefault() { return s_debugDefault; }
static string msgPrefix(V3ErrorCode code=s_errorCode); // returns %Error/%Warn
static int errorCount() { return s_errcnt; }
static int errorCount() { return s_errCount; }
static int warnCount() { return s_warnCount; }
static int errorOrWarnCount() { return errorCount()+warnCount(); }
// METHODS
static void incErrors();
static void incWarnings();
static void init();
static void abortIfErrors();
static void abortIfWarnings();
static void suppressThisWarning(); // Suppress next %Warn if user has it off
static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; }
static bool isError(V3ErrorCode code);
static string v3sform (const char* format, ...);
static string lineStr (const char* filename, int lineno);
static V3ErrorCode errorCode() { return s_errorCode; }
@@ -184,9 +199,14 @@ protected:
void incLineno() { m_lineno++; }
FileLine* copyOrSameFileLine();
public:
FileLine (const string& filename, int lineno) { m_lineno=lineno; m_filename = filename; m_warnOff=s_defaultFileLine.m_warnOff;}
FileLine (FileLine* fromp) { m_lineno=fromp->lineno(); m_filename = fromp->filename(); m_warnOff=fromp->m_warnOff;};
FileLine (EmptySecret) { m_lineno=0; m_filename="COMMAND_LINE"; m_warnOff=0; } // Only for static constructor
FileLine (const string& filename, int lineno) { m_lineno=lineno; m_filename = filename; m_warnOff=s_defaultFileLine.m_warnOff; }
FileLine (FileLine* fromp) { m_lineno=fromp->lineno(); m_filename = fromp->filename(); m_warnOff=fromp->m_warnOff; }
FileLine (EmptySecret) { m_lineno=0; m_filename="COMMAND_LINE"; m_warnOff=0; }
~FileLine() { }
#ifdef VL_LEAK_CHECKS
static void* operator new(size_t size);
static void operator delete(void* obj, size_t size);
#endif
static FileLine& defaultFileLine() { return s_defaultFileLine; }
int lineno () const { return m_lineno; }
string ascii() const;
@@ -197,10 +217,14 @@ public:
void warnOff(V3ErrorCode code, bool flag) { m_warnOff.set(code,flag); } // Turn on/off warning messages on this line.
bool warnOff(const string& code, bool flag); // Returns 1 if ok
bool warnIsOff(V3ErrorCode code);
void warnResetDefault() { m_warnOff=s_defaultFileLine.m_warnOff; }
void warnLintOff(bool flag);
void warnStateFrom(const FileLine& from) { m_warnOff=from.m_warnOff; }
void warnResetDefault() { warnStateFrom(s_defaultFileLine); }
void v3errorEnd(ostringstream& str);
inline bool operator==(FileLine rhs) { return (m_lineno==rhs.m_lineno && m_filename==rhs.m_filename); }
static void deleteAllRemaining();
};
ostream& operator<<(ostream& os, FileLine* fileline);
+5 -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.
//
@@ -65,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;
}
}
@@ -534,6 +531,8 @@ private:
rhsp, lsb)));
}
}
rhsp->deleteTree(); rhsp=NULL;
destp->deleteTree(); destp=NULL;
} else {
UINFO(8," ASSIGNSEL(const,narrow) "<<nodep<<endl);
if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCast(nodep->fileline(), rhsp, nodep);
@@ -806,7 +805,7 @@ private:
for (int w=0; w<nodep->lhsp()->widthWords(); w++) {
AstNode* eqp = newAstWordSelClone (nodep->lhsp(), w);
if (w==nodep->lhsp()->widthWords()-1) {
// Rather then doing a (slowish) ==##, we OR in the bits that aren't part of the mask
// Rather than doing a (slowish) ==##, we OR in the bits that aren't part of the mask
eqp = new AstOr (nodep->fileline(),
new AstConst (nodep->fileline(), notWideMask(nodep->lhsp())),
eqp);
+1 -1
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.
//
+1 -1
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.
//
+1 -1
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.
//
+13 -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.
//
@@ -198,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: ");
}
@@ -224,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
@@ -332,7 +341,7 @@ private:
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n");
GateVarVertex* varvertexp = makeVarVertex(varscp);
UINFO(5," VARREF to "<<varscp<<endl);
// We use weight of one; if we ref the var more then once, when we simplify,
// We use weight of one; if we ref the var more than once, when we simplify,
// the weight will increase
if (nodep->lvalue()) {
new V3GraphEdge(&m_graph, m_logicVertexp, varvertexp, 1);
@@ -424,7 +433,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
}
}
else if (!vvertexp->inSize1()) {
vvertexp->clearReducible("size!1"); // Can't deal with more then one src
vvertexp->clearReducible("size!1"); // Can't deal with more than one src
}
// Reduce it?
if (!vvertexp->reducible()) {
@@ -458,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
+1 -1
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.
//
+1 -1
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.
//
+1 -1
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.
//
+7 -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.
//
@@ -42,8 +42,10 @@ class V3Global {
AstNetlist* m_rootp; // Root of entire netlist
int m_debugFileNumber; // Number to append to debug files created
bool m_assertWidthsSame; // Tree should have width()==widthMin()
// Options
bool m_needHInlines; // Need a __Inlines file
public:
// Options
V3Options opt; // All options; let user see them directly
public:
@@ -52,6 +54,7 @@ public:
m_rootp = new AstNetlist;
m_debugFileNumber = 0;
m_assertWidthsSame = false;
m_needHInlines = false;
}
void clear() {
if (m_rootp) m_rootp->deleteTree(); m_rootp=NULL;
@@ -70,6 +73,8 @@ public:
char digits[100]; sprintf(digits, "%02d", m_debugFileNumber);
return opt.makeDir()+"/"+opt.prefix()+"_"+digits+"_"+nameComment;
}
bool needHInlines() const { return m_needHInlines; }
void needHInlines(bool flag) { m_needHInlines=flag; }
};
extern V3Global v3Global;
+7 -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.
//
@@ -177,9 +177,10 @@ void V3Graph::clear() {
void V3Graph::userClearVertices() {
// Clear user() in all of tree
// We may use the userCnt trick in V3Ast later... For now we don't call this often, and
// the extra code on each read of user() would probably slow things down more then help.
// the extra code on each read of user() would probably slow things down more than help.
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
vertexp->user(0);
vertexp->userp(NULL); // Its a union, but might be different size than user()
}
}
@@ -187,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 than user()
}
}
}
@@ -253,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;
+1 -1
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.
//
+10 -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.
//
@@ -37,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;
@@ -308,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() ))
@@ -353,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) {
@@ -364,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;
@@ -436,7 +440,7 @@ void GraphAcyc::place() {
UINFO(4, " Cutable edges = "<<numEdges<<endl);
vector<V3GraphEdge*> edges; // List of all edges to be processed
edges.reserve(numEdges+1); // Make the vector properly sized right off the bat -- faster then reallocating
edges.reserve(numEdges+1); // Make the vector properly sized right off the bat -- faster than reallocating
for (V3GraphVertex* vertexp = m_breakGraph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
vertexp->user(0); // Clear in prep of next step
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
+5 -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.
//
@@ -58,7 +58,7 @@ void V3Graph::deleteCutableOnlyEdges() {
}
// Pass 2, delete those marked
// Rather then doing a delete() we set the weight to 0 which disconnects the edge.
// Rather than doing a delete() we set the weight to 0 which disconnects the edge.
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
if (vertexp->user()) {
//UINFO(7,"Disconnect "<<vertexp->name()<<endl);
@@ -86,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) {
@@ -99,9 +99,9 @@ private:
} else { // Duplicate
bool saveOld = true;
if (prevEdgep->cutable() && !edgep->cutable()) {
saveOld = false; // new !cutable more important then old
saveOld = false; // new !cutable more important than old
} else if (!prevEdgep->cutable() && edgep->cutable()) {
saveOld = true; // old !cutable more important then new
saveOld = true; // old !cutable more important than new
} else {
saveOld = true;
if (!m_sumWeights && (prevEdgep->weight() < edgep->weight())) { // Keep max weight
+1 -1
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.
//
+1 -1
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.
//
+2 -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.
//
@@ -83,7 +83,7 @@ public:
class DfaVertex : public V3GraphVertex {
// Each DFA state is captured in this vertex.
// Start and accepting are members, rather then the more intuitive
// Start and accepting are members, rather than the more intuitive
// subclasses, as subclassing them would make it harder to inherit from here.
bool m_start; // Start state
bool m_accepting; // Accepting state?
+30 -1
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.
//
@@ -311,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() {
@@ -320,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");
}
+1 -1
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.
//
+1 -1
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.
//
+7 -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.
//
@@ -151,7 +151,7 @@ private:
// Remove the cell
newmodp->deleteTree(); newmodp=NULL; // Clear any leftover ports, etc
nodep->unlinkFrBack();
nodep = NULL;
pushDeletep(nodep); nodep = NULL;
if (debug()>=9) { m_modp->dumpTree(cout,"donemod:"); }
}
}
@@ -233,10 +233,10 @@ private:
}
nodep->iterateChildren(*this);
}
virtual void visit(AstDisplay* nodep, AstNUser*) {
virtual void visit(AstScopeName* nodep, AstNUser*) {
// If there's a %m in the display text, we add a special node that will contain the name()
if (m_cellp
&& nodep->name().find("%m") != string::npos) {
// Similar code in V3Begin
if (m_cellp) {
// To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext();
@@ -332,14 +332,14 @@ private:
} else {
m_modp->user(1);
}
nodep->unlinkFrBack(); nodep=NULL; // Remove so don't propagate to upper cell...
nodep->unlinkFrBack()->deleteTree(); nodep=NULL; // Remove so don't propagate to upper cell...
} else if (nodep->pragType() == AstPragmaType::NO_INLINE_MODULE) {
if (!m_modp) {
nodep->v3error("Inline pragma not under a module");
} else {
cantInline("Pragma NO_INLINE_MODULE");
}
nodep->unlinkFrBack(); nodep=NULL; // Remove so don't propagate to upper cell...
nodep->unlinkFrBack()->deleteTree(); nodep=NULL; // Remove so don't propagate to upper cell...
} else {
nodep->iterateChildren(*this);
}
+1 -1
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.
//
+3 -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.
//
@@ -163,8 +163,8 @@ private:
// 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()+"__"+cvtToStr(m_instNum));
newp->origName(newp->origName()+"__"+cvtToStr(m_instNum));
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; }
+1 -1
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.
//

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