Compare commits

...
87 Commits
Author SHA1 Message Date
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
365 changed files with 7541 additions and 1724 deletions
+111 -5
View File
@@ -3,12 +3,118 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...] The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks! indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.62*** * Verilator 3.653 8/1/2007
**** Support SystemVerilog ==? and !=? operators.
**** Fix 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.
**** Fix 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]
**** Fix compile errors under Windows MINGW compiler. [Gerald Williams]
**** Fix dotted bit reference to local memory. [Eugene Weber]
**** Fix 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]
**** Fix elimination of public signals assigned to constants. [Eugene Weber]
**** Fix internal error when public for loop has empty body. [David Addison]
**** Fix "Loops detected" assertion when model exceeds 4GB. [David Hewson]
**** Fix display %m names inside named blocks.
* Verilator 3.633 2/7/2007
*** Add --trace-depth option for minimizing VCD file size. [Emerson Suguimoto]
*** With VL_DEBUG, show wires causing convergence errors. [Mike Shinkarovsky]
**** Fix isolate_assignments when many signals per always. [Mike Shinkarovsky]
**** Fix isolate_assignments across task/func temporaries. [Mike Shinkarovsky]
**** Fix $display's with array select followed by wide AND. [David Hewson]
* Verilator 3.632 1/17/2007
*** Add /*verilator isolate_assignments*/ attribute. [Mike Shinkarovsky]
* Verilator 3.631 1/2/2007
** Support standard NAME[#] for cells created by arraying or generate for.
This replaces the non-standard name__# syntax used in earlier versions.
**** Fix again dotted references into generate cells. [David Hewson]
Verilator no longer accepts duplicated variables inside unique
generate blocks as this is illegal according to the specification.
**** Fix $readmem* with filenames < 8 characters. [Emerson Suguimoto]
* Verilator 3.630 12/19/2006
** Support $readmemb and $readmemh. [Eugene Weber, Arthur Kahlich]
*** Fixed configure and compiling under Solaris. [Bob Farrell] *** Fixed configure and compiling under Solaris. [Bob Farrell]
*** When dotted signal lookup fails, help the user by showing known scopes. *** When dotted signal lookup fails, help the user by showing known scopes.
*** Reduce depth of priority encoded case statements. [Eugene Weber]
**** Fix dotted references inside generated cells. [David Hewson] **** Fix dotted references inside generated cells. [David Hewson]
**** Fix missed split optimization points underneath other re-split blocks. **** Fix missed split optimization points underneath other re-split blocks.
@@ -64,7 +170,7 @@ indicates the contributor was also the author of the fix; Thanks!
**** Removed coverage request variable; see Coverage limitations in docs. **** Removed coverage request variable; see Coverage limitations in docs.
**** Fix DOS carrage returns in multiline defines. [Ralf Karge] **** Fix DOS carriage returns in multiline defines. [Ralf Karge]
**** Fix printf format warnings on 64-bit linux. **** Fix printf format warnings on 64-bit linux.
@@ -76,7 +182,7 @@ indicates the contributor was also the author of the fix; Thanks!
*** Added --inhibit-sim flag for environments using old __Vm_inhibitSim. *** 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. *** Added -MP to make phony dependencies, ala GCC's.
@@ -214,7 +320,7 @@ indicates the contributor was also the author of the fix; Thanks!
**** Fix functions where regs are declared before inputs. [Danny Ding] **** Fix functions where regs are declared before inputs. [Danny Ding]
**** Fix bad deep expressions with bitselects and rotate. [Prabhat Gupta] **** Fix bad deep expressions with bit-selects and rotate. [Prabhat Gupta]
* Verilator 3.500 10/30/2005 Stable * Verilator 3.500 10/30/2005 Stable
@@ -998,7 +1104,7 @@ $Id$
This uses outline mode in Emacs. See C-h m [M-x describe-mode]. 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 you can redistribute it and/or modify it under the terms of either the GNU
General Public License or the Perl Artistic License. General Public License or the Perl Artistic License.
+6 -6
View File
@@ -4,13 +4,13 @@
# #
# This file is part of Verilator. # 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 # 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 # redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License. # General Public License or the Perl Artistic License.
# #
@@ -94,7 +94,7 @@ DISTDEP = info Makefile
# Files to distribute. # Files to distribute.
DISTBIN = $(wildcard bin/verilator-*) DISTBIN = $(wildcard bin/verilator-*)
DISTFILES_INC = $(INFOS) .cvsignore COPYING *.in \ DISTFILES_INC = $(INFOS) .cvsignore COPYING *.in *.ac \
Changes README TODO \ Changes README TODO \
bin/* \ bin/* \
install-sh configure mkinstalldirs *.texi \ install-sh configure mkinstalldirs *.texi \
@@ -155,15 +155,15 @@ test_vcs: all_nomsg
test_c: all_nomsg test_c: all_nomsg
@(cd test_c && $(MAKE)) @(cd test_c && $(MAKE))
test_c_debug: all_nomsg test_c_debug: all_nomsg
@(cd test_c && $(MAKE) debug) @(cd test_c && $(MAKE) test_debug)
test_sc: all_nomsg test_sc: all_nomsg
@(cd test_sc && $(MAKE)) @(cd test_sc && $(MAKE))
test_sc_debug: all_nomsg test_sc_debug: all_nomsg
@(cd test_sc && $(MAKE) debug) @(cd test_sc && $(MAKE) test_debug)
test_sp: all_nomsg test_sp: all_nomsg
@(cd test_sp && $(MAKE)) @(cd test_sp && $(MAKE))
test_sp_debug: all_nomsg test_sp_debug: all_nomsg
@(cd test_sp && $(MAKE) debug) @(cd test_sp && $(MAKE) test_debug)
test_verilated: all_nomsg test_verilated: all_nomsg
@(cd test_verilated && $(MAKE)) @(cd test_verilated && $(MAKE))
test_regress: all_nomsg test_regress: all_nomsg
+1 -1
View File
@@ -6,7 +6,7 @@ This is the Verilator Package.
1.1 Copyright 1.1 Copyright
============= =============
This package is Copyright 2003-2006 by Wilson Snyder This package is Copyright 2003-2007 by Wilson Snyder
<[email protected]>. <[email protected]>.
You may distribute under the terms of either the GNU General Public You may distribute under the terms of either the GNU General Public
+12 -2
View File
@@ -1,7 +1,7 @@
// $Id$ // $Id$
// DESCRIPTION: Verilator: List of To Do issues. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
@@ -26,11 +26,11 @@ Features:
Points should be per-scope like everything else rather then per-module Points should be per-scope like everything else rather then per-module
Expression coverage (see notes) Expression coverage (see notes)
More Verilog 2001 Support More Verilog 2001 Support
C-style function and task arguments. [Wim Michiels]
(* *) Attributes (just ignore -- preprocessor?) (* *) Attributes (just ignore -- preprocessor?)
Real numbers (NEVER) Real numbers (NEVER)
Recursive functions (NEVER) Recursive functions (NEVER)
Verilog configuration files (NEVER) Verilog configuration files (NEVER)
DPI to define C/C++ calls from Verilog
Long-term Features Long-term Features
Assertions Assertions
@@ -47,6 +47,10 @@ Testing:
Better graph viewer with search and zoom Better graph viewer with search and zoom
Port and test against opencores.org code 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: Performance:
Constant propagation Constant propagation
Extra cleaning AND: 1 & ((VARREF >> 1) | ((&VARREF >> 1) & VARREF)) Extra cleaning AND: 1 & ((VARREF >> 1) | ((&VARREF >> 1) & VARREF))
@@ -99,6 +103,12 @@ Performance:
If floped(a) & flopped(b) and no other a&b, then instead flop(a&b). 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) 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 //* Detailed notes on 'todo' features
+480 -103
View File
@@ -4,7 +4,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
# $Id$ # $Id$
###################################################################### ######################################################################
# #
# Copyright 2003-2006 by Wilson Snyder. This program is free software; you can # Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU # redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License. # General Public License or the Perl Artistic License.
# #
@@ -104,10 +104,11 @@ if ($Opt_Sp) {
} }
if ($Opt_Sp eq 'sp' || $Opt_Trace) { if ($Opt_Sp eq 'sp' || $Opt_Trace) {
if (!defined $ENV{SYSTEMPERL}) { if (!defined $ENV{SYSTEMPERL}) {
my $try = "$ENV{W}/hw/utils/perltools/SystemC/src"; my $try = "$ENV{W}/hw/utils/perltools/SystemC";
$ENV{SYSTEMPERL} = $try if -d $try; $ENV{SYSTEMPERL} = $try if -d $try;
} }
(defined $ENV{SYSTEMPERL}) or die "%Error: verilator: Need \$SYSTEMPERL in environment for --sp or --trace\nProbably System-Perl isn't installed, see http://www.veripool.com/systemperl.html\n"; (defined $ENV{SYSTEMPERL}) or die "%Error: verilator: Need \$SYSTEMPERL in environment for --sp or --trace\nProbably System-Perl isn't installed, see http://www.veripool.com/systemperl.html\n";
(-d "$ENV{SYSTEMPERL}/src") or die "%Error: verilator: \$SYSTEMPERL environment var doesn't seem to point to System-Perl kit\n";
} }
# Determine runtime flags # Determine runtime flags
@@ -190,6 +191,7 @@ Verilator - Convert Verilog code to C++/SystemC
verilator --cc [options] [top_level.v] [opt_c_files.cpp/c/cc] verilator --cc [options] [top_level.v] [opt_c_files.cpp/c/cc]
verilator --sc [options] [top_level.v] [opt_c_files.cpp/c/cc] verilator --sc [options] [top_level.v] [opt_c_files.cpp/c/cc]
verilator --sp [options] [top_level.v] [opt_c_files.cpp/c/cc] verilator --sp [options] [top_level.v] [opt_c_files.cpp/c/cc]
verilator --lint-only ...
=head1 DESCRIPTION =head1 DESCRIPTION
@@ -212,6 +214,66 @@ C++, and linked with the Verilated files.
The resulting executable will perform the actual simulation. The resulting executable will perform the actual simulation.
=head1 ARGUMENT SUMMARY
This is a short summary of the arguments to Verilator. See the detailed
descriptions in the next sections for more information.
{file.v} Verilog top level filenames
{file.c/cc/cpp} Optional C++ files to link in
--assert Enable all assertions
--bin <filename> Override Verilator binary
--cc Create C++ output
--compiler <compiler-name> Tune for specified C++ compiler
--coverage Enable all coverage
--coverage-line Enable line coverage
--coverage-user Enable PSL/SVL user coverage
-D<var>[=<value>] Set preprocessor define
--debug Enable debugging
--debug-check Enable debugging assertions
--dump-tree Enable dumping .tree files
-E Preprocess, but do not compile
--exe Link to create executable
-f <file> Parse options from a file
--help Display this help.
-I<dir> Directory to search for includes
--inhibit-sim Create function to turn off sim
--inline-mult <value> Tune module inlining
--lint-only Lint, but do not make output
--MMD Create .d dependency files
--MP Create phony dependency targets
--Mdir <directory> Name of output object directory
--mod-prefix <topname> Name to prepend to lower classes
--no-skip-identical Disable skipping identical output
-O0 Disable optimizations
-O3 High performance optimizations
-O<optimization-letter> Selectable optimizations
--output-split <bytes> Split .cpp files into pieces
--output-split-cfuncs <statements> Split .ccp functions
--pins64 Use uint64_t's for 33-64 bit sigs
--prefix <topname> Name of top level class
--profile-cfuncs Name functions for profiling
--private Debugging; see docs
--psl Enable PSL parsing
--public Debugging; see docs
--sc Create SystemC output
--sp Create SystemPerl output
--stats Create statistics file
--trace Enable waveform creation
--trace-depth <levels> Depth of tracing
-U<var> Undefine preprocessor define
--underline-zero Zero signals with leading _'s
-v <filename> Verilog library
-Werror-<message> Convert warning to error
-Wno-<message> Disable warning
-x-assign <mode> Initially assign Xs to this value
-y <dir> Directory to search for modules
+define+<var>+<value> Set preprocessor define
+incdir+<dir> Directory to search for includes
+libext+<ext>+[ext]... Extensions for finding modules
=head1 ARGUMENTS =head1 ARGUMENTS
=over 4 =over 4
@@ -236,7 +298,7 @@ desired, but other assertions are, use --assert --nopsl.)
=item --bin I<filename> =item --bin I<filename>
Rarely needed. Override the default filename for Verilator itself. When a Rarely needed. Override the default filename for Verilator itself. When a
dependancy (.d) file is created, this filename will become a source dependency (.d) file is created, this filename will become a source
dependency, such that a change in this binary will have make rebuild the dependency, such that a change in this binary will have make rebuild the
output files. output files.
@@ -244,6 +306,27 @@ output files.
Specifies C++ without SystemC output mode; see also --sc and --sp. Specifies C++ without SystemC output mode; see also --sc and --sp.
=item --compiler I<compiler-name>
Enables tunings and work-arounds for the specified C++ compiler.
=over 4
=item gcc
Tune for Gnu C++, although generated code should work on almost any
compliant C++ compiler. Currently the default.
=item msvc
Tune for Microsoft Visual C++. This may reduce execution speed as it
enables several workarounds to avoid silly hardcoded limits in MSVC++.
This includes breaking deeply nested parenthesized expressions into
sub-expressions to avoid error C1009, and breaking deep blocks into
functions to avoid error C1061.
=back
=item --coverage =item --coverage
Enables all forms of coverage, alias for --coverage-line, --coverage-user Enables all forms of coverage, alias for --coverage-line, --coverage-user
@@ -253,7 +336,7 @@ Enables all forms of coverage, alias for --coverage-line, --coverage-user
Specifies basic block line coverage analysis code should be inserted. Specifies basic block line coverage analysis code should be inserted.
Coverage analysis adds statements at each code flow change point, which are Coverage analysis adds statements at each code flow change point, which are
the branches of IF and CASE statements, a superset of normal Verilog Line the branches of IF and CASE statements, a super-set of normal Verilog Line
Coverage. At each such branch a unique counter is incremented. At the end Coverage. At each such branch a unique counter is incremented. At the end
of a test, the counters along with the filename and line number of a test, the counters along with the filename and line number
corresponding to each counter are written into logs/coverage.pl. corresponding to each counter are written into logs/coverage.pl.
@@ -297,6 +380,12 @@ internal assertions, debugging messages, and intermediate form dump files.
Rarely needed. Enable internal debugging assertion checks, without Rarely needed. Enable internal debugging assertion checks, without
changing debug verbosity. Enabled automatically when --debug specified. changing debug verbosity. Enabled automatically when --debug specified.
=item --dump-tree
Rarely needed. Enable writing .tree debug files. This is enabled with
--debug, so "--debug --no-dump-tree" may be useful if the dump files are
large and not desired.
=item -E =item -E
Preprocess the source code, but do not compile, as with 'gcc -E'. Output Preprocess the source code, but do not compile, as with 'gcc -E'. Output
@@ -324,9 +413,13 @@ change the SystemC modules instantiated.
Tune the inlining of modules. The default value of 2000 specifies that up Tune the inlining of modules. The default value of 2000 specifies that up
to 2000 new operations may be added to the model by inlining, if more then to 2000 new operations may be added to the model by inlining, if more then
this number of operations would result, the module is not inlined. Larger this number of operations would result, the module is not inlined. Larger
values, or -1 to inline everything, will lead to longer compile times, but values, or a value <= 1 will inline everything, will lead to longer compile
potentially faster runtimes. This setting is ignored for very small times, but potentially faster runtimes. This setting is ignored for very
modules; they will always be inlined, if allowed. small modules; they will always be inlined, if allowed.
=item --lint-only
Check the files for lint violations only, do not create any other output.
=item --MMD =item --MMD
@@ -422,8 +515,8 @@ enable functional coverage.
=item --public =item --public
This is only for debug, and may result in mis-simulation of generated This is only for historical debug use. Using it may result in
clocks. mis-simulation of generated clocks.
Declares all signals and modules public. This will turn off signal Declares all signals and modules public. This will turn off signal
optimizations as if all signals had a /*verilator public*/ comments and optimizations as if all signals had a /*verilator public*/ comments and
@@ -449,6 +542,13 @@ Adds waveform tracing code to the model. Having tracing compiled in may
result in some small performance losses, even when waveforms are not turned result in some small performance losses, even when waveforms are not turned
on during model execution. on during model execution.
=item --trace-depth I<levels>
Specify the number of levels deep to enable tracing, for example
--trace-level 1 to only see the top level's signals. Defaults to the
entire model. Using a small number will decrease visibility, but greatly
improve runtime and trace file size.
=item --underline-zero =item --underline-zero
Rarely needed. Signals starting with a underline should be initialized to Rarely needed. Signals starting with a underline should be initialized to
@@ -543,6 +643,7 @@ We'll compile this example into C++.
int main(int argc, char **argv, char **env) { int main(int argc, char **argv, char **env) {
Vour* top = new Vour; Vour* top = new Vour;
while (!Verilated::gotFinish()) { top->eval(); } while (!Verilated::gotFinish()) { top->eval(); }
exit(0);
} }
EOF EOF
@@ -596,13 +697,13 @@ This is an example similar to the above, but using SystemPerl.
cat <<EOF >sc_main.cpp cat <<EOF >sc_main.cpp
#include "Vour.h" #include "Vour.h"
#include "systemperl.h"
int sc_main(int argc, char **argv) { int sc_main(int argc, char **argv) {
sc_clock clk ("clk",10, 0.5, 3, true); sc_clock clk ("clk",10, 0.5, 3, true);
Vour* top; Vour* top;
SP_CELL (top, Vour); top = new Vour("top"); // SP_CELL (top, Vour);
SP_PIN (top, clk, clk); top->clk(clk); // SP_PIN (top, clk, clk);
while (!Verilated::gotFinish()) { sc_start(1); } while (!Verilated::gotFinish()) { sc_start(1); }
exit(0);
} }
EOF EOF
@@ -677,11 +778,13 @@ fast path, mostly code that is executed every cycle. OPT_SLOW specifies
optimizations for slow-path files (plus tracing), which execute only optimizations for slow-path files (plus tracing), which execute only
rarely, yet take a long time to compile with optimization on. OPT rarely, yet take a long time to compile with optimization on. OPT
specifies overall optimization and affects all compiles, including those specifies overall optimization and affects all compiles, including those
OPT_FAST and OPT_SLOW affect. For best results, use OPT="-O2". Nearly the OPT_FAST and OPT_SLOW affect. For best results, use OPT="-O2", and link
same results can be had with much better compile times with OPT_FAST="-O1 with "-static". Nearly the same results can be had with much better
-fstrict-aliasing". Unfortunately, using the optimizer with SystemC files compile times with OPT_FAST="-O1 -fstrict-aliasing".
can result in compiles taking several minutes. (The SystemC libraries have
many little inlined functions that drive the compiler nuts.) Unfortunately, using the optimizer with SystemC files can result in
compiles taking several minutes. (The SystemC libraries have many little
inlined functions that drive the compiler nuts.)
For best results, use GCC 3.3 or newer. GCC 3.2 and earlier have For best results, use GCC 3.3 or newer. GCC 3.2 and earlier have
optimization bugs around pointer aliasing detection, which can result in 2x optimization bugs around pointer aliasing detection, which can result in 2x
@@ -693,16 +796,19 @@ feedback driven compilation. With GCC, using -fprofile-arcs, then
You may uncover further tuning possibilities by profiling the Verilog code. You may uncover further tuning possibilities by profiling the Verilog code.
Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run
either oprofile or gprof to see where in the C++ code, and by looking at either oprofile or gprof to see where in the C++ code the time is spent.
the mangled function name where in the Verilog code most of the time is Run the gprof output through verilator_profcfunc and it will tell you what
being spent. Verilog line numbers on which most of the time is being spent.
When done, please let the author know the results. I like to keep tabs on When done, please let the author know the results. I like to keep tabs on
how Verilator compares, and may be able to suggest additional improvements. how Verilator compares, and may be able to suggest additional improvements.
=head1 FILES =head1 FILES
Verilator creates the following files: All output files are placed in the output directory name specified with the
-Mdir option, or "obj_dir" if not specified.
Verilator creates the following files in the output directory:
{prefix}.mk // Make include file for compiling {prefix}.mk // Make include file for compiling
{prefix}_classes.mk // Make include file with class names {prefix}_classes.mk // Make include file with class names
@@ -714,7 +820,7 @@ For -cc and -sc mode, it also creates:
{prefix}{each_verilog_module}.cpp // Lower level internal C++ files {prefix}{each_verilog_module}.cpp // Lower level internal C++ files
{prefix}{each_verilog_module}.h // Lower level internal header files {prefix}{each_verilog_module}.h // Lower level internal header files
For -sp mode, it also creates: For -sp mode, instead of .cpp and .h it creates:
{prefix}.sp // Top level SystemC file {prefix}.sp // Top level SystemC file
{prefix}{each_verilog_module}.sp // Lower level internal SC files {prefix}{each_verilog_module}.sp // Lower level internal SC files
@@ -736,7 +842,8 @@ It also creates internal files that can be mostly ignored:
{prefix}{misc}.dot // Debugging graph files (--debug) {prefix}{misc}.dot // Debugging graph files (--debug)
{prefix}{misc}.tree // Debugging files (--debug) {prefix}{misc}.tree // Debugging files (--debug)
After running Make, the compiler will produce the following: After running Make, the C++ compiler should produce the following:
{prefix} // Final executable (w/--exe argument) {prefix} // Final executable (w/--exe argument)
{prefix}__ALL.a // Library of all Verilated objects {prefix}__ALL.a // Library of all Verilated objects
{prefix}{misc}.o // Intermediate objects {prefix}{misc}.o // Intermediate objects
@@ -857,7 +964,7 @@ order of magnitude.
=head1 CROSS COMPILATION =head1 CROSS COMPILATION
Verilator supports cross-compling Verilated code. This is generally used Verilator supports cross-compiling Verilated code. This is generally used
to run Verilator on a Linux system and produce C++ code that is then compiled to run Verilator on a Linux system and produce C++ code that is then compiled
on Windows. on Windows.
@@ -879,30 +986,52 @@ disadvantage of this approach is that include/verilatedos.h must
self-detect the requirements of the target system, rather then using self-detect the requirements of the target system, rather then using
configure. configure.
=head1 VERILOG 2001 SUPPORT The target system may also require edits to the Makefiles, the simple
Makefiles produced by Verilator presume the target system is the same type
as the build system.
Verilator supports the more common Verilog 2001 language features. This =head1 VERILOG 2001 (IEEE 1364-2001) SUPPORT
Verilator supports almost all Verilog 2001 language features. This
includes signed numbers, "always @*", comma separated sensitivity lists, includes signed numbers, "always @*", comma separated sensitivity lists,
generate statements, multidimensional arrays, localparam, and C-style generate statements, multidimensional arrays, localparam, and C-style
declarations inside port lists. declarations inside port lists.
=head1 SYSTEMVERILOG 3.1 SUPPORT =head1 VERILOG 2005 (IEEE 1364-2005) SUPPORT
Verilator currently has very minimal support for SystemVerilog. Verilator supports the `begin_keywords and `end_keywords compiler
directives.
Verilator implement the full SystemVerilog 3.1 preprocessor subset, Verilator partially supports the uwire keyword.
including function call-like preprocessor defines. Verilator also
implements $bits, $countones, $isunknown, $onehot, and $onehot0, =head1 SYSTEMVERILOG (IEEE 1800-2005) SUPPORT
always_comb, always_ff, always_latch, and final.
Verilator currently has very minimal support for SystemVerilog. As
SystemVerilog features enter common usage they will be added. Contact the
author if a feature you need is missing.
Verilator implements the full SystemVerilog 1800-2005 preprocessor,
including function call-like preprocessor defines.
Verilator supports ==? and !=? operators, $bits, $countones, $error,
$fatal, $info, $isunknown, $onehot, $onehot0, $warning, always_comb,
always_ff, always_latch, do-while, and final.
It also supports .name and .* interconnection.
Verilator partially supports assert.
=head1 SUGAR/PSL SUPPORT =head1 SUGAR/PSL SUPPORT
With the --assert switch, Verilator is just beginning to support the Most future work is being directed towards improving SystemVerilog
Property Specification Language (PSL), specifically the simple subset assertions instead of PSL. If you are using these PSL features, please
without time-branching primitives. Verilator currently only converts PSL contact the author as they may be depreciated in future versions.
With the --assert switch, Verilator enables support of the Property
Specification Language (PSL), specifically the simple PSL subset without
time-branching primitives. Verilator currently only converts PSL
assertions to simple "if (...) error" statements, and coverage statements assertions to simple "if (...) error" statements, and coverage statements
to increment the line counters described in the coverage section. If you to increment the line counters described in the coverage section.
need additional features please contact the author.
Verilator implements these keywords: assert, assume (same as assert), Verilator implements these keywords: assert, assume (same as assert),
default (for clocking), countones, cover, isunknown, onehot, onehot0, default (for clocking), countones, cover, isunknown, onehot, onehot0,
@@ -911,18 +1040,16 @@ report, true.
Verilator implements these operators: -> (logical if). Verilator implements these operators: -> (logical if).
Verilator does not support SEREs yet. All assertion and coverage Verilator does not support SEREs yet. All assertion and coverage
statements must be simple expressions that complete in one cycle. statements must be simple expressions that complete in one cycle. PSL
(Arguably SEREs are the whole point of PSL, but one must start somewhere.) vmode/vprop/vunits are not supported. PSL statements must be in the module
they reference, at the module level where you would put an
PSL vmode/vprop/vunits are not supported. PSL statements must be in the
module they reference, at the module level where you would put an
initial... statement. initial... statement.
Verilator only supports (posedge CLK) or (negedge CLK), where CLK is the Verilator only supports (posedge CLK) or (negedge CLK), where CLK is the
name of a one bit signal. You may not use arbitrary expressions as name of a one bit signal. You may not use arbitrary expressions as
assertion clocks. assertion clocks.
=head1 SYNTHESIS DIRECTIVE ASSERTIONS =head1 SYNTHESIS DIRECTIVE ASSERTION SUPPORT
With the --assert switch, Verilator reads any "//synopsys full_case" or "// With the --assert switch, Verilator reads any "//synopsys full_case" or "//
synopsys parallel_case" directives. The same applies to any "//cadence" or synopsys parallel_case" directives. The same applies to any "//cadence" or
@@ -992,16 +1119,6 @@ Verilog standard, %x prints a number with the natural width, %0x prints a
number with minimum width, however %5x prints 5 digits per the C standard number with minimum width, however %5x prints 5 digits per the C standard
(it's unspecified in Verilog). (it's unspecified in Verilog).
=item $fopen, $fclose, $fdisplay, $fwrite
File descriptors passed to the file PLI calls must be file descriptors, not
MCDs, which includes the mode parameter to $fopen being mandatory.
Verilator will convert the integer used to hold the file descriptor into a
internal FILE*. To prevent core dumps due to mis-use, and because integers
are 32 bits while FILE*s may be 64 bits, the descriptor must be stored in a
reg [63:0] rather then an integer. The define `verilator_file_descriptor in
verilated.v can be used to hide this difference.
=item `coverage_block_off =item `coverage_block_off
Specifies the entire begin/end block should be ignored for coverage analysis. Specifies the entire begin/end block should be ignored for coverage analysis.
@@ -1058,7 +1175,9 @@ around compiler specific constructs.
=item `verilog =item `verilog
Switch back to processing Verilog code, after a `systemc_... mode switch. Switch back to processing Verilog code after a `systemc_... mode switch.
The Verilog code returns to the last language mode specified with
`begin_keywords, or SystemVerilog if none were specified.
=item /*verilator clock_enable*/ =item /*verilator clock_enable*/
@@ -1081,6 +1200,41 @@ submodules will be named I<submodule>__DOT__I<subsignal> as C++ does not
allow "." in signal names. SystemPerl when tracing such signals will allow "." in signal names. SystemPerl when tracing such signals will
replace the __DOT__ with the period. replace the __DOT__ with the period.
=item /*verilator isolate_assignments*/
Used after a signal declaration to indicate the assignments to this signal
in any blocks should be isolated into new blocks. When there is a large
combinatorial block that is resulting in a UNOPTFLAT warning, attaching
this to the signal causing a false loop may clear up the problem.
IE, with the following
reg splitme /* verilator isolate_assignments*/;
always @* begin
if (....) begin
splitme = ....;
other assignments
end
end
Verilator will internally split the block that assigns to "splitme" into
two blocks:
It would then internally break it into (sort of):
// All assignments excluding those to splitme
always @* begin
if (....) begin
other assignments
end
end
// All assignments to splitme
always @* begin
if (....) begin
splitme = ....;
end
end
=item /*verilator lint_off I<msg>*/ =item /*verilator lint_off I<msg>*/
Disable the specified warning message for any warnings following the comment. Disable the specified warning message for any warnings following the comment.
@@ -1089,6 +1243,26 @@ Disable the specified warning message for any warnings following the comment.
Re-enable the specified warning message for any warnings following the comment. Re-enable the specified warning message for any warnings following the comment.
=item /*verilator lint_restore*/
After a /*verilator lint_save*/, pop the stack containing lint message
state. Often this is useful at the bottom of include files.
=item /*verilator lint_save*/
Push the current state of what lint messages are turned on or turned off to
a stack. Later meta-comments may then lint_on or lint_off specific
messages, then return to the earlier message state by using /*verilator
lint_restore*/. For example:
// verilator lint_save
// verilator lint_off SOME_WARNING
... // code needing SOME_WARNING turned off
// verilator lint_restore
If SOME_WARNING was on before the lint_off, it will now be restored to on,
and if it was off before the lint_off it will remain off.
=item /*verilator no_inline_task*/ =item /*verilator no_inline_task*/
Used in a function or task variable definition section to specify the Used in a function or task variable definition section to specify the
@@ -1097,26 +1271,12 @@ reduce the size of the final executable when a task is used a very large
number of times. For this flag to work, the task and tasks below it must number of times. For this flag to work, the task and tasks below it must
be pure; they cannot reference any variables outside the task itself. be pure; they cannot reference any variables outside the task itself.
=item /*verilator sc_clock*/
Used after a input declaration to indicate the signal should be declared in
SystemC as a sc_clock instead of a bool.
=item /*verilator tracing_off*/
Disable waveform tracing for all future signals that are declared in this
module. Often this is placed just after a primitive's module statement, so
that the entire module is not traced.
=item /*verilator tracing_on*/
Re-enable waveform tracing for all future signals that are declared.
=item /*verilator public*/ (variable) =item /*verilator public*/ (variable)
Used after a input, output, register, or wire declaration to indicate the Used after a input, output, register, or wire declaration to indicate the
signal should be declared so that C code may read or write the value signal should be declared so that C code may read or write the value
of the signal. of the signal. This will also declare this module public, otherwise use
/*verilator public_flat*/.
=item /*verilator public*/ (task/function) =item /*verilator public*/ (task/function)
@@ -1138,6 +1298,14 @@ stored state (flops) should be written, as the model will NOT notice
changes made to variables in these functions. (Same as when a signal is changes made to variables in these functions. (Same as when a signal is
declared public.) declared public.)
=item /*verilator public_flat*/ (variable)
Used after a input, output, register, or wire declaration to indicate the
signal should be declared so that C code may read or write the value of the
signal. This will not declare this module public, which means the name of
the signal or path to it may change based upon the module inlining which
takes place.
=item /*verilator public_module*/ =item /*verilator public_module*/
Used after a module statement to indicate the module should not be inlined Used after a module statement to indicate the module should not be inlined
@@ -1146,6 +1314,21 @@ Verilator automatically sets this attribute when the module contains any
public signals or `systemc_ directives. Also set for all modules when public signals or `systemc_ directives. Also set for all modules when
using the --public switch. using the --public switch.
=item /*verilator sc_clock*/
Used after a input declaration to indicate the signal should be declared in
SystemC as a sc_clock instead of a bool.
=item /*verilator tracing_off*/
Disable waveform tracing for all future signals that are declared in this
module. Often this is placed just after a primitive's module statement, so
that the entire module is not traced.
=item /*verilator tracing_on*/
Re-enable waveform tracing for all future signals that are declared.
=back =back
=head1 LANGUAGE LIMITATIONS =head1 LANGUAGE LIMITATIONS
@@ -1175,25 +1358,25 @@ always @* to prevent these issues.)
Verilator supports dotted references to variables, functions and tasks in Verilator supports dotted references to variables, functions and tasks in
different modules. However, references into named blocks and function-local different modules. However, references into named blocks and function-local
variables are not supported. References into arrayed and generated variables are not supported. The portion before the dot must have a
instances work, but still require some work-arounds in the Verilog code: constant value; for example a[2].b is acceptable, while a[x].b is not.
References into arrayed instances use different names from the Verilog References into generated and arrayed instances use the instance names
standard; arrayed instances are named {cellName}__{instanceNumber}. For specified in the Verilog standard; arrayed instances are named
example a[2] is instead a__2. Thus you cannot use a parameter or variable {cellName}[{instanceNumber}] in Verilog, which becomes
to select the index number; expand it into a case statement manually. {cellname}__BRA__{instanceNumber}__KET__ inside the generated C++ code.
References into generate statements also use different names from the Verilator creates numbered "genblk" when a begin: name is not specified
Verilog standard; the top level generate, any begin statement, and any around a block inside a generate statement. These numbers may differ
place where there is a implied begin statement (under each generate-if or between other simulators, but the Verilog specification does not allow
generate-case) adds a hierarchy level named genblkI<instanceNumber>. And users to use these names, so it should not matter.
each generate-for adds genforI<loopCount>. The best bet is to comment out
the references and run with --debug and look in the at the _begin.tree If you are having trouble determining where a dotted path goes wrong, note
file, and see the hierarchy by looking at the names of all of the CELLs in that Verilator will print a list of known scopes to help your debugging.
question. Replace __DOT__ with . in your program. For example most cells
under a for loop would be something like =head2 Floating Point
"genblk__DOT__genfor0__DOT__I<cellname>"; so use genblk.genfor0.I<cellname> to
see inside that cell. Floating Point numbers are not synthesizable, and so not supported.
=head2 Latches =head2 Latches
@@ -1247,17 +1430,12 @@ prepended. (If you don't know what this means, Verilator will do what you
probably expect -- what C does. The default behavior of Verilog is probably expect -- what C does. The default behavior of Verilog is
different.) different.)
=head2 Generate Statements
All instantiations and variables in generate blocks will be placed under
hierarchy that has a name different from that required in the language
specification.
=head2 Generated Clocks =head2 Generated Clocks
Verilator attempts to deal with generated clocks correctly, however new Verilator attempts to deal with generated clocks correctly, however new
cases may turn up bugs in the scheduling algorithm. The safest option is cases may turn up bugs in the scheduling algorithm. The safest option is
to have all clocks as primary inputs to the model. to have all clocks as primary inputs to the model, or wires directly
attached to primary inputs.
=head2 Ranges must be big-bit-endian =head2 Ranges must be big-bit-endian
@@ -1307,11 +1485,93 @@ will give a width warning and wrap around the power-of-2 size. For
non-power-of-2 sizes, it will return a unspecified constant of the non-power-of-2 sizes, it will return a unspecified constant of the
appropriate width. appropriate width.
=head2 Assertions
Verilator is beginning to add support for assertions. Verilator currently
only converts assertions to simple "if (...) error" statements, and
coverage statements to increment the line counters described in the
coverage section.
Verilator does not support SEREs yet. All assertion and coverage
statements must be simple expressions that complete in one cycle.
(Arguably SEREs are much of the point, but one must start somewhere.)
=head1 LANGUAGE KEYWORD LIMITATIONS
This section describes specific limitations for each language keyword.
=over 4
=item `__FILE__, `__LINE__, `begin_keywords, `begin_keywords, `begin_keywords,
`begin_keywords, `begin_keywords, `define, `else, `elsif, `end_keywords,
`endif, `error, `ifdef, `ifndef, `include, `line, `systemc_ctor,
`systemc_dtor, `systemc_header, `systemc_imp_header,
`systemc_implementation, `systemc_interface, `timescale, `undef, `verilog
Fully supported.
=item always, always_comb, always_ff, always_latch, and, assign, begin,
buf, case, casex, casez, default, defparam, do-while, else, end, endcase,
endfunction, endgenerate, endmodule, endspecify, endtask, final, for,
function, generate, genvar, if, initial, inout, input, integer, localparam,
macromodule, module, nand, negedge, nor, not, or, output, parameter,
posedge, reg, scalared, signed, supply0, supply1, task, tri, vectored,
while, wire, xnor, xor
Generally supported.
=item specify specparam
All specify blocks and timing checks are ignored.
=item uwire
Verilator does not perform warning checking on uwires, it treats the uwire
keyword as if it were the normal wire keyword.
=item $bits, $countones, $error, $fatal, $finish, $info, $isunknown,
$onehot, $onehot0, $readmemb, $readmemh, $signed, $stop, $time, $unsigned,
$warning.
Generally supported.
=item $display, $write, $fdisplay, $fwrite =item $display, $write, $fdisplay, $fwrite
$display and friends must have a constant format string as the first $display and friends must have a constant format string as the first
argument (as with C's printf), you cannot simply list variables standalone. argument (as with C's printf), you cannot simply list variables standalone.
=item $displayb, $displayh, $displayo, $writeb, $writeh, $writeo, etc
The sized display functions are rarely used and so not supported. Replace
them with a $write with the appropriate format specifier.
=item $fopen, $fclose, $fdisplay, $fwrite
File descriptors passed to the file PLI calls must be file descriptors, not
MCDs, which includes the mode parameter to $fopen being mandatory.
Verilator will convert the integer used to hold the file descriptor into a
internal FILE*. To prevent core dumps due to mis-use, and because integers
are 32 bits while FILE*s may be 64 bits, the descriptor must be stored in a
reg [63:0] rather then an integer. The define `verilator_file_descriptor in
verilated.v can be used to hide this difference.
=item $fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal,
$setup, $setuphold, $skew, $timeskew, $width
All specify blocks and timing checks are ignored.
=item $readmemb, $readmemh
Read memory commands should work properly. Note Verilator and the Verilog
specification does not include support for readmem to multi-dimensional
arrays.
=item $realtime
Treated as $time.
=back
=head1 ERRORS AND WARNINGS =head1 ERRORS AND WARNINGS
Warnings may be disabled in two ways. First, when the warning is Warnings may be disabled in two ways. First, when the warning is
@@ -1332,6 +1592,29 @@ List of all warnings:
=over 4 =over 4
=item BLKANDNBLK
BLKANDNBLK is an error that a variable comes from a mix of blocked and
non-blocking assignments. Generally, this is caused by a register driven
by both combo logic and a flop:
always @ (posedge clk) foo[0] <= ...
always @* foo[1] = ...
Simply use a different register for the flop:
always @ (posedge clk) foo_flopped[0] <= ...
always @* foo[0] = foo_flopped[0];
always @* foo[1] = ...
This is good coding practice anyways.
It is also possible to disable this error when one of the assignments is
inside a public task.
Ignoring this warning may make Verilator simulations differ from other
simulators.
=item CASEINCOMPLETE =item CASEINCOMPLETE
Warns that inside a case statement there is a stimulus pattern for which Warns that inside a case statement there is a stimulus pattern for which
@@ -1339,6 +1622,9 @@ there is no case item specified. This is bad style, if a case is
impossible, it's better to have a "default: $stop;" or just "default: ;" so impossible, it's better to have a "default: $stop;" or just "default: ;" so
that any design assumption violations will be discovered in simulation. that any design assumption violations will be discovered in simulation.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item CASEOVERLAP =item CASEOVERLAP
Warns that inside a case statement you have case values which are detected Warns that inside a case statement you have case values which are detected
@@ -1346,17 +1632,26 @@ to be overlapping. This is bad style, as moving the order of case values
will cause different behavior. Generally the values can be respecified to will cause different behavior. Generally the values can be respecified to
not overlap. not overlap.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item CASEX =item CASEX
Warns that it is simply better style to use casez, and C<?> in place of Warns that it is simply better style to use casez, and C<?> in place of
C<x>'s. See C<x>'s. See
L<http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf> L<http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf>
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item CMPCONST =item CMPCONST
Warns that you are comparing a value in a way that will always be constant. Warns that you are comparing a value in a way that will always be constant.
For example "X > 1" will always be true when X is a single bit wide. For example "X > 1" will always be true when X is a single bit wide.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item COMBDLY =item COMBDLY
Warns that you have a delayed assignment inside of a combinatorial block. Warns that you have a delayed assignment inside of a combinatorial block.
@@ -1366,6 +1661,9 @@ Verilator, like synthesis, will convert this to a non-delayed assignment,
which may result in logic races or other nasties. See which may result in logic races or other nasties. See
L<http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA_rev1_2.pdf> L<http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA_rev1_2.pdf>
Ignoring this warning may make Verilator simulations differ from other
simulators.
=item GENCLK =item GENCLK
Warns that the specified signal is generated, but is also being used as a Warns that the specified signal is generated, but is also being used as a
@@ -1376,6 +1674,9 @@ generate ALL clocks outside in C++/SystemC and make them primary inputs to
your Verilog model. (However once need to you have even one, don't sweat your Verilog model. (However once need to you have even one, don't sweat
additional ones.) additional ones.)
Ignoring this warning may make Verilator simulations differ from other
simulators.
=item IMPLICIT =item IMPLICIT
Warns that a wire is being implicitly declared (it is a single bit wide Warns that a wire is being implicitly declared (it is a single bit wide
@@ -1385,18 +1686,38 @@ signal before it is implicitly declared by a cell, and can lead to dangling
nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for
Emacs, available from L<http://www.veripool.com/> Emacs, available from L<http://www.veripool.com/>
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item IMPURE =item IMPURE
Warns that a task or function that has been marked with /*verilator Warns that a task or function that has been marked with /*verilator
no_inline_task*/ references variables that are not local to the task. no_inline_task*/ references variables that are not local to the task.
Verilator cannot schedule these variables correctly. Verilator cannot schedule these variables correctly.
Ignoring this warning may make Verilator simulations differ from other
simulators.
=item MULTIDRIVEN =item MULTIDRIVEN
Warns that the specified signal comes from multiple always blocks. This is Warns that the specified signal comes from multiple always blocks. This is
often unsupported by synthesis tools, and is considered bad style. It will often unsupported by synthesis tools, and is considered bad style. It will
also cause longer runtimes due to reduced optimizations. also cause longer runtimes due to reduced optimizations.
Ignoring this warning will only slow simulations, it will simulate
correctly.
=item MULTITOP
Error that there are multiple top level modules, that is modules not
instantiated by any other module. Verilator only supports a single top
level, if you need more, create a module that wraps all of the top modules.
Often this error is because some low level cell is being read in, but is
not really needed. The best solution is to insure that each module is in a
unique file by the same name. Otherwise, make sure all library files are
read in as libraries with -v, instead of automatically with -y.
=item TASKNSVAR =item TASKNSVAR
Error when a call to a task or function has a output from that task tied to Error when a call to a task or function has a output from that task tied to
@@ -1424,6 +1745,9 @@ cases would result in simulator mismatches.
Warns that the specified signal is never sourced. Warns that the specified signal is never sourced.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item UNOPT =item UNOPT
Warns that due to some construct, optimization of the specified signal or Warns that due to some construct, optimization of the specified signal or
@@ -1437,6 +1761,9 @@ blocks in both submodules, even if they are unrelated always blocks. This
affects performance because Verilator would have to evaluate each submodule affects performance because Verilator would have to evaluate each submodule
multiple times to stabilize the signals crossing between the modules. multiple times to stabilize the signals crossing between the modules.
Ignoring this warning will only slow simulations, it will simulate
correctly.
=item UNOPTFLAT =item UNOPTFLAT
Warns that due to some construct, optimization of the specified signal is Warns that due to some construct, optimization of the specified signal is
@@ -1484,16 +1811,29 @@ The UNOPTFLAT warning may also be due to clock enables, identified from the
reported path going through a clock gating cell. To fix these, use the reported path going through a clock gating cell. To fix these, use the
clock_enable meta comment described above. clock_enable meta comment described above.
The UNOPTFLAT warning may also occur where outputs from a block of logic
are independent, but occur in the same always block. To fix this, use the
isolate_assignments meta comment described above.
Ignoring this warning will only slow simulations, it will simulate
correctly.
=item UNSIGNED =item UNSIGNED
Warns that you are comparing a unsigned value in a way that implies it is Warns that you are comparing a unsigned value in a way that implies it is
signed, for example "X < 0" will always be true when X is unsigned. signed, for example "X < 0" will always be true when X is unsigned.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item UNUSED =item UNUSED
Warns that the specified signal is never sinked. This is a future message, Warns that the specified signal is never sinked. This is a future message,
currently Verilator will not produce this warning. currently Verilator will not produce this warning.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item VARHIDDEN =item VARHIDDEN
Warns that a task, function, or begin/end block is declaring a variable by Warns that a task, function, or begin/end block is declaring a variable by
@@ -1501,6 +1841,9 @@ the same name as a variable in the upper level module or begin/end block
(thus hiding the upper variable from being able to be used.) Rename the (thus hiding the upper variable from being able to be used.) Rename the
variable to avoid confusion when reading the code. variable to avoid confusion when reading the code.
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item WIDTH =item WIDTH
Warns that based on width rules of Verilog, two operands have different Warns that based on width rules of Verilog, two operands have different
@@ -1519,6 +1862,9 @@ The best fix, which clarifies intent and will also make all tools happy is:
wire [5:0] plus_one = from[5:0] + 6'd1 + {5'd0,carry[0]}; wire [5:0] plus_one = from[5:0] + 6'd1 + {5'd0,carry[0]};
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=back =back
The following describes the less obvious errors: The following describes the less obvious errors:
@@ -1546,12 +1892,18 @@ For example:
always @ (b) a=b always @ (b) a=b
will toggle forever and thus the executable will give the didn't converge will toggle forever and thus the executable will give the didn't converge
error to prevent an infinite loop. To debug this, compile the Verilated error to prevent an infinite loop.
.cpp files with -DVL_DEBUG, then call Verilated::debug(1) in your main.cpp.
This will cause each module to print a message when it's invoked. From To debug this, run Verilator with --profile-cfuncs. Run make on the
that it should be obvious what routine(s) are part of the infinite loop. generated files with "OPT=-DVL_DEBUG". Then call Verilated::debug(1) in
Then in Gdb, add a break point at the routine entry point and "print *this" your main.cpp.
on each loop so you can see what variables are changing each invocation.
This will cause each change in a variable to print a message. Near the
bottom you'll see the code and variable that causes the problem. For the
program above:
CHANGE: filename.v:1: b
CHANGE: filename.v:2: a
=back =back
@@ -1586,6 +1938,25 @@ so your simulator shouldn't have to be -- and Verilator is closer to the
synthesis interpretation, so this is a good thing for getting working synthesis interpretation, so this is a good thing for getting working
silicon. silicon.
=item May programs I create with Verilator remain under my own copyright?
Yes, it's just like using GCC on your programs. If you change Verilator
itself, you must make the source code available under the GNU Public
License. However, the include and generated files use the GNU Lesser
Public License, which means that files using them are NOT required to be released.
You also have the option of using the Perl Artistic License, which again
does not require you release your Verilog or generated code.
=item Why is running Verilator so slow?
Verilator needs more memory then the resulting simulator will require, as
Verilator creates internally all of the state of the resulting simulator in
order to optimize it. If it takes more then a minute or so (and you're not
using --debug), see if your machine is paging; most likely you need to run
it on a machine with more memory. Verilator is a full 64 bit application
and may use more then 4GB, but about 1GB is the maximum typically needed.
=item How do I generate waveforms (traces) in C++? =item How do I generate waveforms (traces) in C++?
See the next question for SystemC mode. See the next question for SystemC mode.
@@ -1613,6 +1984,12 @@ create a SpTraceFile object as you would create a normal SystemC trace
file. For an example, see the call to SpTraceFile in the file. For an example, see the call to SpTraceFile in the
test_sp/sc_main.cpp file of the distribution. test_sp/sc_main.cpp file of the distribution.
=item How do I view waveforms (traces)?
Verilator makes standard VCD (Value Change Dump) files. They are viewable
with the public domain Dinotrace or GtkWave programs, or any of the many
commercial offerings.
=item Where is the translate_off command? (How do I ignore a construct?) =item Where is the translate_off command? (How do I ignore a construct?)
Translate on/off pragmas are generally a bad idea, as it's easy to have Translate on/off pragmas are generally a bad idea, as it's easy to have
@@ -1788,7 +2165,7 @@ Communications, Sun Microsystems, Nauticus Networks, and SiCortex.
The people who have contributed code or other major functionality are Paul The people who have contributed code or other major functionality are Paul
Wasson, Duane Galbi, and Wilson Snyder. Major testers include Jeff Dutton, Wasson, Duane Galbi, and Wilson Snyder. Major testers include Jeff Dutton,
Ralf Karge and Wim Michiels. Ralf Karge, David Hewson, Wim Michiels, and Gene Weber.
Some of the people who have provided ideas and feedback for Verilator Some of the people who have provided ideas and feedback for Verilator
include Hans Van Antwerpen, Jens Arm, David Black, Gregg Bouchard, Chris include Hans Van Antwerpen, Jens Arm, David Black, Gregg Bouchard, Chris
@@ -1803,7 +2180,7 @@ Eugene Weber, Leon Wildman, and Mat Zeno.
The latest version is available from L<http://www.veripool.com/>. The latest version is available from L<http://www.veripool.com/>.
Copyright 2003-2006 by Wilson Snyder. Verilator is free software; you can Copyright 2003-2007 by Wilson Snyder. Verilator is free software; you can
redistribute it and/or modify it under the terms of either the GNU Lesser redistribute it and/or modify it under the terms of either the GNU Lesser
General Public License or the Perl Artistic License. General Public License or the Perl Artistic License.
@@ -1815,7 +2192,7 @@ Major concepts by Paul Wasson and Duane Galbi.
=head1 SEE ALSO =head1 SEE ALSO
L<systemperl>, L<vcoverage>, L<make> L<verilator_profcfunc>, L<systemperl>, L<vcoverage>, L<make>
=cut =cut
+7 -3
View File
@@ -4,7 +4,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
# $Id$ # $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 # 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 # the terms of either the GNU Lesser General Public License or the Perl
# Artistic License. # Artistic License.
@@ -35,17 +35,21 @@ my $Opt_A;
my $Opt_B; my $Opt_B;
autoflush STDOUT 1; autoflush STDOUT 1;
autoflush STDERR 1; autoflush STDERR 1;
Getopt::Long::config ("no_auto_abbrev");
if (! GetOptions ( if (! GetOptions (
"help" => \&usage, "help" => \&usage,
"debug" => \&debug, "debug" => \&debug,
"<>" => \&parameter, "<>" => \&parameter,
)) { )) {
usage(); die "%Error: Bad usage, try 'verilator_difftree --help'\n";
} }
defined $Opt_A or die "%Error: No old diff filename\n"; defined $Opt_A or die "%Error: No old diff filename\n";
defined $Opt_B or die "%Error: No new 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) { if (-d $Opt_A && -d $Opt_B) {
diff_dir ($Opt_A, $Opt_B); diff_dir ($Opt_A, $Opt_B);
} elsif (-f $Opt_A && -f $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/>. 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 can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License or the Perl Artistic License. Lesser General Public License or the Perl Artistic License.
+1 -1
View File
@@ -4,7 +4,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
# $Id$ # $Id$
# DESCRIPTION: Print include statements for each ARGV # 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 # redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License. # 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 $Id$
dnl DESCRIPTION: Process this file with autoconf to produce a configure script. 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 redistribute it and/or modify it under the terms of either the GNU
dnl General Public License or the Perl Artistic License. dnl General Public License or the Perl Artistic License.
@@ -16,8 +16,17 @@ AC_PROG_CC
AC_PROG_CXX AC_PROG_CXX
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PATH_PROG(PERL,perl) 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) 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. dnl Checks for libraries.
+113 -4
View File
@@ -1,9 +1,9 @@
// $Id$ -*- C++ -*- // $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 // 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, // Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -24,13 +24,14 @@
#include "verilated.h" #include "verilated.h"
#include <string.h> #include <string.h>
#include <ctype.h>
#define VL_VALUE_STRING_MAX_WIDTH 1024 ///< Max static char array for VL_VALUE_STRING #define VL_VALUE_STRING_MAX_WIDTH 1024 ///< Max static char array for VL_VALUE_STRING
//=========================================================================== //===========================================================================
// Global variables // Global variables
int Verilated::s_randReset = false; int Verilated::s_randReset = 0;
int Verilated::s_debug = 1; int Verilated::s_debug = 1;
bool Verilated::s_calcUnusedSigs = false; bool Verilated::s_calcUnusedSigs = false;
bool Verilated::s_gotFinish = 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. // Random reset -- Only called at init time, so don't inline.
IData VL_RAND32() { IData VL_RAND32() {
#ifdef _MSC_VER #if defined(_WIN32) && !defined(__CYGWIN__)
// Windows doesn't have lrand48(), although Cygwin does.
return (rand()<<16) | rand(); return (rand()<<16) | rand();
#else #else
return (lrand48()<<16) | lrand48(); 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)); 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 // Verilated:: Methods
+34 -7
View File
@@ -1,9 +1,9 @@
// $Id$ -*- C++ -*- // $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 // 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, // Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -194,9 +194,17 @@ inline const char* VL_VALUE_FORMATTED_I(int obits, char fmt, bool drop0, IData l
} }
/// File I/O /// File I/O
extern QData VL_FOPEN_WI(int fnwords, WDataInP filename, IData mode); extern QData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
extern QData VL_FOPEN_QI(QData filename, IData mode); extern QData VL_FOPEN_QI(QData ofilename, IData mode);
inline QData VL_FOPEN_II(IData filename, IData mode) { return VL_FOPEN_QI(filename,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 // Base macros
@@ -226,6 +234,13 @@ static inline QData VL_CVT_FP_Q(FILE* fp) { union { FILE* fp; QData q; } u; u.q
static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) { return (-((lhs)&(1UL<<(lbits-1)))); } static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) { return (-((lhs)&(1UL<<(lbits-1)))); }
static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) { return (-((lhs)&(VL_ULL(1)<<(lbits-1)))); } 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 // Pli macros
@@ -498,10 +513,10 @@ static inline IData VL_COUNTONES_W(int words, WDataInP lwp) {
} }
static inline IData VL_ONEHOT_I(IData lhs) { 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) { 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) { static inline IData VL_ONEHOT_W(int words, WDataInP lwp) {
IData one=0; IData one=0;
@@ -1035,6 +1050,18 @@ static inline WDataOutP VL_CONCAT_WWW(int obits,int lbits,int rbits,WDataOutP ow
//=================================================================== //===================================================================
// Shifts // 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; // EMIT_RULE: VL_SHIFTL: oclean=lclean; rclean==clean;
// Important: Unlike most other funcs, the shift might well be a computed // Important: Unlike most other funcs, the shift might well be a computed
// expression. Thus consider this when optimizing. (And perhaps have 2 funcs?) // expression. Thus consider this when optimizing. (And perhaps have 2 funcs?)
+11 -6
View File
@@ -2,9 +2,9 @@
###################################################################### ######################################################################
# DESCRIPTION: Makefile commands for all verilated target files # 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 # 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@ PERL = @PERL@
@@ -51,6 +51,11 @@ CPPFLAGS += $(OPT)
CPPFLAGS += $(M32) 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. # See the benchmarking section of bin/verilator.
# Support class optimizations. This includes the tracing and symbol table. # Support class optimizations. This includes the tracing and symbol table.
# SystemC takes minutes to optimize, thus it is off by default. # SystemC takes minutes to optimize, thus it is off by default.
@@ -84,8 +89,8 @@ endif
##### SystemPerl builds ##### SystemPerl builds
ifeq ($(VM_SP),1) ifeq ($(VM_SP),1)
CPPFLAGS += -I$(SYSTEMPERL) -I$(SYSTEMPERL)/src -DSYSTEMPERL CPPFLAGS += -I$(SYSTEMPERL)/src -DSYSTEMPERL
VPATH += $(SYSTEMPERL) $(SYSTEMPERL)/src VPATH += $(SYSTEMPERL)/src
VK_CLASSES_SP = $(addsuffix .sp, $(VM_CLASSES)) VK_CLASSES_SP = $(addsuffix .sp, $(VM_CLASSES))
@@ -104,8 +109,8 @@ endif
ifeq ($(VM_PCLI),1) ifeq ($(VM_PCLI),1)
LIBS += -lm -lstdc++ LIBS += -lm -lstdc++
ifeq ($(VM_TRACE),1) ifeq ($(VM_TRACE),1)
CPPFLAGS += -I$(SYSTEMPERL) -I$(SYSTEMPERL)/src CPPFLAGS += -I$(SYSTEMPERL)/src
VPATH += $(SYSTEMPERL) $(SYSTEMPERL)/src VPATH += $(SYSTEMPERL)/src
endif endif
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 // 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, // This is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
+7 -3
View File
@@ -1,9 +1,9 @@
// $Id$ -*- C++ -*- // $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 // 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, // Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -39,6 +39,8 @@
# define VL_ATTR_UNUSED __attribute__ ((unused)) # define VL_ATTR_UNUSED __attribute__ ((unused))
# define VL_LIKELY(x) __builtin_expect(!!(x), 1) # define VL_LIKELY(x) __builtin_expect(!!(x), 1)
# define VL_UNLIKELY(x) __builtin_expect(!!(x), 0) # 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 #else
# define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking # define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking
# define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment # define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment
@@ -46,6 +48,8 @@
# define VL_ATTR_UNUSED ///< Function that may be never used # define VL_ATTR_UNUSED ///< Function that may be never used
# define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true then false # 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_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false then true
# define VL_PREFETCH_RD(p) ///< Prefetch data with read intent
# define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent
#endif #endif
#ifdef VL_THREADED #ifdef VL_THREADED
@@ -79,7 +83,7 @@ typedef long vlsint32_t; ///< 32-bit signed type
typedef unsigned long vluint32_t; ///< 32-bit unsigned type typedef unsigned long vluint32_t; ///< 32-bit unsigned type
typedef long long vlsint64_t; ///< 64-bit signed type typedef long long vlsint64_t; ///< 64-bit signed type
typedef unsigned long long vluint64_t; ///< 64-bit unsigned 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 char uint8_t; ///< 8-bit unsigned type (backward compatibility)
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility) typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility) typedef unsigned 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$ # $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 # 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 # the terms of either the GNU Lesser General Public License or the Perl
# Artistic License. # Artistic License.
@@ -197,7 +197,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION =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 can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License or the Perl Artistic License. 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$ # $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 # 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 # the terms of either the GNU Lesser General Public License or the Perl
# Artistic License. # Artistic License.
@@ -344,7 +344,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION =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 can redistribute it and/or modify it under the terms of either the GNU
Lesser General Public License or the Perl Artistic License. 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 @node Copyright, Description, Top, Top
@section Copyright @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 You may distribute under the terms of either the GNU General Public License
or the Artistic License, as specified in the Perl README file. 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 # redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License. # General Public License or the Perl Artistic License.
# #
+5 -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 # redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License. # General Public License or the Perl Artistic License.
# #
@@ -118,6 +118,7 @@ RAW_OBJS = \
V3Dead.o \ V3Dead.o \
V3Delayed.o \ V3Delayed.o \
V3Depth.o \ V3Depth.o \
V3DepthBlock.o \
V3Descope.o \ V3Descope.o \
V3EmitC.o \ V3EmitC.o \
V3EmitCSyms.o \ V3EmitCSyms.o \
@@ -142,6 +143,8 @@ RAW_OBJS = \
V3LinkCells.o \ V3LinkCells.o \
V3LinkDot.o \ V3LinkDot.o \
V3LinkLevel.o \ V3LinkLevel.o \
V3LinkLValue.o \
V3LinkParse.o \
V3LinkResolve.o \ V3LinkResolve.o \
V3Localize.o \ V3Localize.o \
V3Name.o \ V3Name.o \
@@ -154,6 +157,7 @@ RAW_OBJS = \
V3Scope.o \ V3Scope.o \
V3Signed.o \ V3Signed.o \
V3Split.o \ V3Split.o \
V3SplitAs.o \
V3Stats.o \ V3Stats.o \
V3StatsReport.o \ V3StatsReport.o \
V3Subst.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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
+89 -15
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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -47,28 +47,61 @@ private:
V3Double0 m_statAsCover; // Statistic tracking V3Double0 m_statAsCover; // Statistic tracking
V3Double0 m_statAsPsl; // Statistic tracking V3Double0 m_statAsPsl; // Statistic tracking
V3Double0 m_statAsFull; // Statistic tracking V3Double0 m_statAsFull; // Statistic tracking
V3Double0 m_statAsSV; // Statistic tracking
// METHODS // METHODS
AstNode* newFireAssert(AstNode* nodep, const string& message) { string assertDisplayMessage(AstNode* nodep, const string& prefix, const string& message) {
AstNode* bodysp = new AstDisplay return (string("[%0t] "+prefix+": ")+nodep->fileline()->filebasename()
(nodep->fileline(), '\0',
(string("[%0t] %%Error: ")+nodep->fileline()->filebasename()
+":"+cvtToStr(nodep->fileline()->lineno()) +":"+cvtToStr(nodep->fileline()->lineno())
+": Assertion failed in %m" +": Assertion failed in %m"
+((message != "")?": ":"")+message +((message != "")?": ":"")+message
+"\\n"), +"\\n");
NULL, }
new AstTime(nodep->fileline())); void replaceDisplay(AstDisplay* nodep, const string& prefix) {
bodysp->addNext(new AstStop (nodep->fileline())); 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. // 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. // Don't make this a AND term, as it's unlikely to need to test this.
bodysp = new AstIf (nodep->fileline(), return new AstIf (nodep->fileline(),
new AstCMath(nodep->fileline(), "Verilated::assertOn()", 1), // If assertions are off, have constant propagation rip them out later
bodysp, NULL); // 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; 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(); propp->unlinkFrBack();
sentreep->unlinkFrBack(); sentreep->unlinkFrBack();
// //
@@ -114,6 +147,28 @@ private:
pushDeletep(nodep); nodep=NULL; 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 // VISITORS //========== Case assertions
virtual void visit(AstCase* nodep, AstNUser*) { virtual void visit(AstCase* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
@@ -163,16 +218,34 @@ private:
} }
// VISITORS //========== Statements // 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*) { virtual void visit(AstPslCover* nodep, AstNUser*) {
nodep->iterateChildren(*this); 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++; m_statAsCover++;
} }
virtual void visit(AstPslAssert* nodep, AstNUser*) { virtual void visit(AstPslAssert* nodep, AstNUser*) {
nodep->iterateChildren(*this); 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++; 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*) { virtual void visit(AstModule* nodep, AstNUser*) {
m_modp = nodep; m_modp = nodep;
@@ -203,6 +276,7 @@ public:
} }
virtual ~AssertVisitor() { virtual ~AssertVisitor() {
V3Stats::addStat("Assertions, PSL asserts", m_statAsPsl); V3Stats::addStat("Assertions, PSL asserts", m_statAsPsl);
V3Stats::addStat("Assertions, SystemVerilog asserts", m_statAsSV);
V3Stats::addStat("Assertions, cover statements", m_statAsCover); V3Stats::addStat("Assertions, cover statements", m_statAsCover);
V3Stats::addStat("Assertions, full/parallel case", m_statAsFull); 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
+11 -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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -92,12 +92,19 @@ string AstNode::shortName() const {
return pretty; return pretty;
} }
string AstNode::prettyName(const string& namein) { string AstNode::dedotName(const string& namein) {
string pretty = namein; string pretty = namein;
string::size_type pos; string::size_type pos;
while ((pos=pretty.find("__DOT__")) != string::npos) { while ((pos=pretty.find("__DOT__")) != string::npos) {
pretty.replace(pos, 7, "."); 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) { while ((pos=pretty.find("__BRA__")) != string::npos) {
pretty.replace(pos, 7, "["); pretty.replace(pos, 7, "[");
} }
@@ -107,8 +114,7 @@ string AstNode::prettyName(const string& namein) {
while ((pos=pretty.find("__PVT__")) != string::npos) { while ((pos=pretty.find("__PVT__")) != string::npos) {
pretty.replace(pos, 7, ""); pretty.replace(pos, 7, "");
} }
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,""); return AstNode::dedotName(pretty);
return pretty;
} }
int AstNode::widthPow2() const { int AstNode::widthPow2() const {
@@ -783,7 +789,7 @@ void AstNode::dumpTreeFile(const string& filename, bool append) {
if (logsp->fail()) v3fatalSrc("Can't write "<<filename); if (logsp->fail()) v3fatalSrc("Can't write "<<filename);
*logsp<<"Tree Dump from <e"<<dec<<editCountLast()<<">"; *logsp<<"Tree Dump from <e"<<dec<<editCountLast()<<">";
*logsp<<" to <e"<<dec<<editCountGbl()<<">"<<endl; *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<<endl;
*logsp<<"No changes since last dump!\n"; *logsp<<"No changes since last dump!\n";
} else { } else {
+70 -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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 bool operator== (AstBranchPred::en lhs, AstBranchPred rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstBranchPred rhs) { return os<<rhs.ascii(); } inline ostream& operator<<(ostream& os, 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. // AstNUser - Generic pointer base class for AST User nodes.
// - Also used to allow parameter passing up/down iterate calls // - Also used to allow parameter passing up/down iterate calls
@@ -478,6 +533,7 @@ public:
AstNode* op3p() const { return m_op3p; } AstNode* op3p() const { return m_op3p; }
AstNode* op4p() const { return m_op4p; } AstNode* op4p() const { return m_op4p; }
AstNode* clonep() const { return ((m_cloneCnt==s_cloneCntGbl)?m_clonep:NULL); } 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; bool brokeExists() const;
// CONSTRUCTORS // CONSTRUCTORS
@@ -496,6 +552,7 @@ public:
virtual string name() const { return ""; } virtual string name() const { return ""; }
virtual string verilogKwd() const { return ""; } virtual string verilogKwd() const { return ""; }
string shortName() const; // Name with __PVT__ removed for concatenating scopes 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 static string prettyName(const string& namein); // Name for printing out to the user
string prettyName() const { return prettyName(name()); } string prettyName() const { return prettyName(name()); }
FileLine* fileline() const { return m_fileline; } FileLine* fileline() const { return m_fileline; }
@@ -877,6 +934,7 @@ public:
virtual ~AstNodePli() {} virtual ~AstNodePli() {}
virtual string name() const { return m_text; } virtual string name() const { return m_text; }
virtual int instrCount() const { return instrCountPli(); } 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 AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output
string text() const { return m_text; } // * = Text to display string text() const { return m_text; } // * = Text to display
void text(const string& text) { m_text=text; } void text(const string& text) { m_text=text; }
@@ -941,12 +999,12 @@ private:
AstNodeFTask* m_taskp; // [AfterLink] Pointer to task referenced AstNodeFTask* m_taskp; // [AfterLink] Pointer to task referenced
string m_name; // Name of variable string m_name; // Name of variable
string m_dotted; // Dotted part of scope to task or "" 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: public:
AstNodeFTaskRef(FileLine* fl, const string& name, const string& dotted, AstNode* pinsp) AstNodeFTaskRef(FileLine* fl, AstNode* namep, AstNode* pinsp)
:AstNode(fl) :AstNode(fl)
, m_taskp(NULL), m_name(name), m_dotted(dotted) { , m_taskp(NULL) {
addNOp1p(pinsp); setOp1p(namep); addNOp2p(pinsp);
} }
virtual ~AstNodeFTaskRef() {} virtual ~AstNodeFTaskRef() {}
virtual bool broken() const { return m_taskp && !m_taskp->brokeExists(); } virtual bool broken() const { return m_taskp && !m_taskp->brokeExists(); }
@@ -961,9 +1019,13 @@ public:
void inlinedDots(const string& flag) { m_inlinedDots = flag; } void inlinedDots(const string& flag) { m_inlinedDots = flag; }
AstNodeFTask* taskp() const { return m_taskp; } // [After Link] Pointer to variable AstNodeFTask* taskp() const { return m_taskp; } // [After Link] Pointer to variable
void taskp(AstNodeFTask* taskp) { m_taskp=taskp; } void taskp(AstNodeFTask* taskp) { m_taskp=taskp; }
// op1 = Pin interconnection list void name(const string& name) { m_name = name; }
AstNode* pinsp() const { return op1p()->castNode(); } void dotted(const string& name) { m_dotted = name; }
void addPinsp(AstNode* nodep) { addOp1p(nodep); } // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -298,6 +298,7 @@ void AstCell::dump(ostream& str) {
this->AstNode::dump(str); this->AstNode::dump(str);
if (modp()) { str<<" -> "; modp()->dump(str); } if (modp()) { str<<" -> "; modp()->dump(str); }
else { str<<" ->UNLINKED:"<<modName(); } else { str<<" ->UNLINKED:"<<modName(); }
if (pinStar()) str<<" [.*]";
} }
void AstCellInline::dump(ostream& str) { void AstCellInline::dump(ostream& str) {
this->AstNode::dump(str); this->AstNode::dump(str);
@@ -307,6 +308,7 @@ void AstPin::dump(ostream& str) {
this->AstNode::dump(str); this->AstNode::dump(str);
if (modVarp()) { str<<" -> "; modVarp()->dump(str); } if (modVarp()) { str<<" -> "; modVarp()->dump(str); }
else { str<<" ->UNLINKED"; } else { str<<" ->UNLINKED"; }
if (svImplicit()) str<<" [.SV]";
} }
void AstVarXRef::dump(ostream& str) { void AstVarXRef::dump(ostream& str) {
this->AstNode::dump(str); this->AstNode::dump(str);
@@ -350,6 +352,7 @@ void AstVar::dump(ostream& str) {
if (isUsedClock()) str<<" [C]"; if (isUsedClock()) str<<" [C]";
if (isSigPublic()) str<<" [P]"; if (isSigPublic()) str<<" [P]";
if (attrClockEn()) str<<" [aCLKEN]"; if (attrClockEn()) str<<" [aCLKEN]";
if (attrIsolateAssign()) str<<" [aISO]";
if (attrFileDescr()) str<<" [aFD]"; if (attrFileDescr()) str<<" [aFD]";
if (isFuncReturn()) str<<" [FUNCRTN]"; if (isFuncReturn()) str<<" [FUNCRTN]";
else if (isFuncLocal()) str<<" [FUNC]"; else if (isFuncLocal()) str<<" [FUNC]";
@@ -361,7 +364,11 @@ void AstSenTree::dump(ostream& str) {
} }
void AstSenItem::dump(ostream& str) { void AstSenItem::dump(ostream& str) {
this->AstNode::dump(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) { void AstActive::dump(ostream& str) {
this->AstNode::dump(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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -236,11 +236,13 @@ private:
bool m_scClocked:1; // SystemC sc_clk<> needed bool m_scClocked:1; // SystemC sc_clk<> needed
bool m_scSensitive:1;// SystemC sensitive() needed bool m_scSensitive:1;// SystemC sensitive() needed
bool m_sigPublic:1; // User C code accesses this signal 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_usedClock:1; // Signal used as a clock
bool m_usedParam:1; // Parameter is referenced (on link; later signals not setup) bool m_usedParam:1; // Parameter is referenced (on link; later signals not setup)
bool m_funcLocal:1; // Local variable for a function bool m_funcLocal:1; // Local variable for a function
bool m_funcReturn:1; // Return variable for a function bool m_funcReturn:1; // Return variable for a function
bool m_attrClockEn:1;// User clock enable attribute bool m_attrClockEn:1;// User clock enable attribute
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
bool m_fileDescr:1; // File descriptor bool m_fileDescr:1; // File descriptor
bool m_isConst:1; // Table contains constant data bool m_isConst:1; // Table contains constant data
bool m_isStatic:1; // Static variable bool m_isStatic:1; // Static variable
@@ -251,8 +253,10 @@ private:
m_primaryIO=false; m_primaryIO=false;
m_sc=false; m_scClocked=false; m_scSensitive=false; m_sc=false; m_scClocked=false; m_scSensitive=false;
m_usedClock=false; m_usedParam=false; m_usedClock=false; m_usedParam=false;
m_sigPublic=false; m_funcLocal=false; m_funcReturn=false; m_sigPublic=false; m_sigModPublic=false;
m_attrClockEn=false; m_fileDescr=false; m_isConst=false; m_isStatic=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; m_trace=false;
} }
public: public:
@@ -301,9 +305,11 @@ public:
void attrClockEn(bool flag) { m_attrClockEn = flag; } void attrClockEn(bool flag) { m_attrClockEn = flag; }
void attrFileDescr(bool flag) { m_fileDescr = flag; } void attrFileDescr(bool flag) { m_fileDescr = flag; }
void attrScClocked(bool flag) { m_scClocked = flag; } void attrScClocked(bool flag) { m_scClocked = flag; }
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
void usedClock(bool flag) { m_usedClock = flag; } void usedClock(bool flag) { m_usedClock = flag; }
void usedParam(bool flag) { m_usedParam = flag; } void usedParam(bool flag) { m_usedParam = flag; }
void sigPublic(bool flag) { m_sigPublic = flag; } void sigPublic(bool flag) { m_sigPublic = flag; }
void sigModPublic(bool flag) { m_sigModPublic = flag; }
void sc(bool flag) { m_sc = flag; } void sc(bool flag) { m_sc = flag; }
void scSensitive(bool flag) { m_scSensitive = flag; } void scSensitive(bool flag) { m_scSensitive = flag; }
void primaryIO(bool flag) { m_primaryIO = flag; } void primaryIO(bool flag) { m_primaryIO = flag; }
@@ -340,6 +346,7 @@ public:
bool isScWide() const; bool isScWide() const;
bool isScSensitive() const { return m_scSensitive; } bool isScSensitive() const { return m_scSensitive; }
bool isSigPublic() const; bool isSigPublic() const;
bool isSigModPublic() const { return m_sigModPublic; }
bool isTrace() const { return m_trace; } bool isTrace() const { return m_trace; }
bool isConst() const { return m_isConst; } bool isConst() const { return m_isConst; }
bool isStatic() const { return m_isStatic; } bool isStatic() const { return m_isStatic; }
@@ -348,6 +355,7 @@ public:
bool attrClockEn() const { return m_attrClockEn; } bool attrClockEn() const { return m_attrClockEn; }
bool attrFileDescr() const { return m_fileDescr; } bool attrFileDescr() const { return m_fileDescr; }
bool attrScClocked() const { return m_scClocked; } 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 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,... int widthTotalBytes() const; // Width in bytes rounding up 1,2,4,8,12,...
uint32_t msb() const { if (!rangep()) return 0; return rangep()->msbConst(); } uint32_t msb() const { if (!rangep()) return 0; return rangep()->msbConst(); }
@@ -359,6 +367,7 @@ public:
// Note the method below too // Note the method below too
if (fromp->attrClockEn()) attrClockEn(true); if (fromp->attrClockEn()) attrClockEn(true);
if (fromp->attrFileDescr()) attrFileDescr(true); if (fromp->attrFileDescr()) attrFileDescr(true);
if (fromp->attrIsolateAssign()) attrIsolateAssign(true);
} }
bool gateMultiInputOptimizable() const { bool gateMultiInputOptimizable() const {
// Ok to gate optimize; must return false if propagateAttrFrom would do anything // Ok to gate optimize; must return false if propagateAttrFrom would do anything
@@ -369,6 +378,7 @@ public:
propagateAttrFrom(typevarp); propagateAttrFrom(typevarp);
combineType(typevarp->varType()); combineType(typevarp->varType());
if (typevarp->isSigPublic()) sigPublic(true); if (typevarp->isSigPublic()) sigPublic(true);
if (typevarp->isSigModPublic()) sigModPublic(true);
if (typevarp->attrScClocked()) attrScClocked(true); if (typevarp->attrScClocked()) attrScClocked(true);
} }
void inlineAttrReset(const string& name) { void inlineAttrReset(const string& name) {
@@ -411,7 +421,7 @@ struct AstScope : public AstNode {
private: private:
string m_name; // Name string m_name; // Name
AstScope* m_aboveScopep; // Scope above this one in the hierarchy (NULL if top) 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 AstModule* m_modp; // Module scope corresponds to
public: public:
AstScope(FileLine* fl, AstModule* modp, const string& name, 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 // Includes pin on a cell, as part of a ASSIGN statement to connect I/Os until AstScope
private: private:
string m_dotted; // Scope name to connected to string m_dotted; // Scope name to connected to
string m_inlinedDots; // Dotted hiearchy flattened out string m_inlinedDots; // Dotted hierarchy flattened out
public: public:
AstVarXRef(FileLine* fl, const string& name, const string& dotted, bool lvalue) AstVarXRef(FileLine* fl, const string& name, const string& dotted, bool lvalue)
:AstNodeVarRef(fl, name, NULL, lvalue) :AstNodeVarRef(fl, name, NULL, lvalue)
@@ -566,10 +576,11 @@ private:
int m_pinNum; // Pin number int m_pinNum; // Pin number
string m_name; // Pin name, or "" for number based interconnect string m_name; // Pin name, or "" for number based interconnect
AstVar* m_modVarp; // Input/output this pin connects to on submodule. AstVar* m_modVarp; // Input/output this pin connects to on submodule.
bool m_svImplicit; // Pin is SystemVerilog .name'ed
public: public:
AstPin(FileLine* fl, int pinNum, const string& name, AstNode* exprp) AstPin(FileLine* fl, int pinNum, const string& name, AstNode* exprp)
:AstNode(fl) :AstNode(fl)
,m_name(name) { ,m_name(name), m_svImplicit(false) {
m_pinNum = pinNum; m_pinNum = pinNum;
m_modVarp = NULL; m_modVarp = NULL;
setNOp1p(exprp); } setNOp1p(exprp); }
@@ -586,6 +597,8 @@ public:
AstNode* exprp() const { return op1p()->castNode(); } // op1 = Expression connected to pin AstNode* exprp() const { return op1p()->castNode(); } // op1 = Expression connected to pin
AstVar* modVarp() const { return m_modVarp; } // [After Link] Pointer to variable AstVar* modVarp() const { return m_modVarp; } // [After Link] Pointer to variable
void modVarp(AstVar* varp) { m_modVarp=varp; } void modVarp(AstVar* varp) { m_modVarp=varp; }
bool svImplicit() const { return m_svImplicit; }
void svImplicit(bool flag) { m_svImplicit=flag; }
}; };
struct AstModule : public AstNode { struct AstModule : public AstNode {
@@ -642,12 +655,14 @@ private:
string m_name; // Cell name string m_name; // Cell name
string m_origName; // Original name before dot addition string m_origName; // Original name before dot addition
string m_modName; // Module the cell instances string m_modName; // Module the cell instances
bool m_pinStar; // Pin list has .*
AstModule* m_modp; // [AfterLink] Pointer to module instanced AstModule* m_modp; // [AfterLink] Pointer to module instanced
public: public:
AstCell(FileLine* fl, const string& instName, const string& modName, AstCell(FileLine* fl, const string& instName, const string& modName,
AstPin* pinsp, AstPin* paramsp, AstRange* rangep) AstPin* pinsp, AstPin* paramsp, AstRange* rangep)
: AstNode(fl) : 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); } addNOp1p(pinsp); addNOp2p(paramsp); setNOp3p(rangep); }
virtual ~AstCell() {} virtual ~AstCell() {}
virtual AstType type() const { return AstType::CELL;} virtual AstType type() const { return AstType::CELL;}
@@ -664,6 +679,8 @@ public:
void origName(const string& name) { m_origName = name; } void origName(const string& name) { m_origName = name; }
string modName() const { return m_modName; } // * = Instance name string modName() const { return m_modName; } // * = Instance name
void modName(const string& name) { m_modName = 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* pinsp() const { return op1p()->castPin(); } // op1 = List of cell ports
AstPin* paramsp() const { return op2p()->castPin(); } // op2 = List of parameter #(##) values 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) 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); } 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 { struct AstTask : public AstNodeFTask {
@@ -769,10 +826,13 @@ struct AstTask : public AstNodeFTask {
}; };
struct AstFunc : public AstNodeFTask { struct AstFunc : public AstNodeFTask {
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
public:
// A function inside a module // A function inside a module
AstFunc(FileLine* fl, const string& name, AstNode* stmtp, AstNode* fvarsp) AstFunc(FileLine* fl, const string& name, AstNode* stmtp, AstNode* fvarsp)
:AstNodeFTask(fl, name, stmtp) { :AstNodeFTask(fl, name, stmtp) {
addNOp1p(fvarsp); addNOp1p(fvarsp);
m_attrIsolateAssign = false;
} }
virtual ~AstFunc() {} virtual ~AstFunc() {}
virtual AstType type() const { return AstType::FUNC;} virtual AstType type() const { return AstType::FUNC;}
@@ -781,12 +841,14 @@ struct AstFunc : public AstNodeFTask {
// op1 = Range output variable (functions only) // op1 = Range output variable (functions only)
AstNode* fvarp() const { return op1p()->castNode(); } AstNode* fvarp() const { return op1p()->castNode(); }
void addFvarp(AstNode* nodep) { addOp1p(nodep); } void addFvarp(AstNode* nodep) { addOp1p(nodep); }
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
}; };
struct AstTaskRef : public AstNodeFTaskRef { struct AstTaskRef : public AstNodeFTaskRef {
// A reference to a task // A reference to a task
AstTaskRef(FileLine* fl, const string& name, const string& dotted, AstNode* pinsp) AstTaskRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
:AstNodeFTaskRef(fl, name, dotted, pinsp) {} :AstNodeFTaskRef(fl, namep, pinsp) {}
virtual ~AstTaskRef() {} virtual ~AstTaskRef() {}
virtual AstType type() const { return AstType::TASKREF;} virtual AstType type() const { return AstType::TASKREF;}
virtual AstNode* clone() { return new AstTaskRef(*this);} virtual AstNode* clone() { return new AstTaskRef(*this);}
@@ -795,8 +857,8 @@ struct AstTaskRef : public AstNodeFTaskRef {
struct AstFuncRef : public AstNodeFTaskRef { struct AstFuncRef : public AstNodeFTaskRef {
// A reference to a function // A reference to a function
AstFuncRef(FileLine* fl, const string& name, const string& dotted, AstNode* pinsp) AstFuncRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
:AstNodeFTaskRef(fl, name, dotted, pinsp) {} :AstNodeFTaskRef(fl, namep, pinsp) {}
virtual ~AstFuncRef() {} virtual ~AstFuncRef() {}
virtual AstType type() const { return AstType::FUNCREF;} virtual AstType type() const { return AstType::FUNCREF;}
virtual AstNode* clone() { return new AstFuncRef(*this);} virtual AstNode* clone() { return new AstFuncRef(*this);}
@@ -816,8 +878,11 @@ public:
class Settle {}; // for creator type-overload selection class Settle {}; // for creator type-overload selection
class Never {}; // for creator type-overload selection class Never {}; // for creator type-overload selection
AstSenItem(FileLine* fl, AstEdgeType edgeType, AstNodeVarRef* varrefp) AstSenItem(FileLine* fl, AstEdgeType edgeType, AstNodeVarRef* varrefp)
: AstNode(fl) { : AstNode(fl), m_edgeType(edgeType) {
m_edgeType = edgeType; setOp1p(varrefp);
}
AstSenItem(FileLine* fl, AstEdgeType edgeType, AstParseRef* varrefp)
: AstNode(fl), m_edgeType(edgeType) {
setOp1p(varrefp); setOp1p(varrefp);
} }
AstSenItem(FileLine* fl, Combo) AstSenItem(FileLine* fl, Combo)
@@ -1167,6 +1232,7 @@ public:
virtual int instrCount() const { return widthInstrs()+instrCountBranch(); } virtual int instrCount() const { return widthInstrs()+instrCountBranch(); }
AstNode* condsp() const { return op1p()->castNode(); } // op1= list of possible matching expressions AstNode* condsp() const { return op1p()->castNode(); } // op1= list of possible matching expressions
AstNode* bodysp() const { return op2p()->castNode(); } // op2= what to do AstNode* bodysp() const { return op2p()->castNode(); } // op2= what to do
void condsp(AstNode* nodep) { setOp1p(nodep); }
void addBodysp(AstNode* newp) { addOp2p(newp); } void addBodysp(AstNode* newp) { addOp2p(newp); }
bool isDefault() const { return condsp()==NULL; } bool isDefault() const { return condsp()==NULL; }
bool ignoreOverlap() const { return m_ignoreOverlap; } bool ignoreOverlap() const { return m_ignoreOverlap; }
@@ -1174,20 +1240,22 @@ public:
}; };
struct AstDisplay : public AstNodePli { struct AstDisplay : public AstNodePli {
// Parents: stmtlist
// Children: file which must be a varref, MATH to print
private: private:
char m_newline; AstDisplayType m_displayType;
public: 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) { : AstNodePli (fileline, text, exprsp) {
setNOp2p(filep); setNOp2p(filep);
m_newline = newln; m_displayType = dispType;
} }
virtual ~AstDisplay() {} virtual ~AstDisplay() {}
virtual AstType type() const { return AstType::DISPLAY;} virtual AstType type() const { return AstType::DISPLAY;}
virtual AstNode* clone() { return new AstDisplay(*this); } virtual AstNode* clone() { return new AstDisplay(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); } virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual string verilogKwd() const { return (filep() ? ((newline() == '\n')?"$fdisplay":"$fwrite") virtual string verilogKwd() const { return (filep() ? (string)"$f"+(string)displayType().ascii()
: ((newline() == '\n')?"$display":"$write")); }; : (string)"$"+(string)displayType().ascii()); }
virtual bool isGateOptimizable() const { return false; } virtual bool isGateOptimizable() const { return false; }
virtual bool isPredictOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; }
virtual bool isSplittable() const { return false; } // SPECIAL: $display has 'visual' ordering virtual bool isSplittable() const { return false; } // SPECIAL: $display has 'visual' ordering
@@ -1195,19 +1263,22 @@ public:
virtual bool isUnlikely() const { return true; } virtual bool isUnlikely() const { return true; }
virtual V3Hash sameHash() const { return V3Hash(text()); } virtual V3Hash sameHash() const { return V3Hash(text()); }
virtual bool same(AstNode* samep) const { virtual bool same(AstNode* samep) const {
return newline()==samep->castDisplay()->newline() return displayType()==samep->castDisplay()->displayType()
&& text()==samep->castDisplay()->text(); } && text()==samep->castDisplay()->text(); }
// op1 used by AstNodePli // op1 used by AstNodePli
char newline() const { return m_newline; } // * = Add a newline for $display AstDisplayType displayType() const { return m_displayType; }
AstNodeVarRef* filep() const { return op2p()->castVarRef(); } 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); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
AstNode* scopeAttrp() const { return op3p(); } AstScopeName* scopeNamep() const { return op3p()->castScopeName(); }
AstText* scopeTextp() const { return op3p()->castText(); } void scopeNamep(AstNode* nodep) { setNOp3p(nodep); }
void scopeAttrp(AstNode* nodep) { addOp3p(nodep); }
}; };
struct AstFClose : public AstNodeStmt { 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) { : AstNodeStmt (fileline) {
setNOp2p(filep); setNOp2p(filep);
} }
@@ -1223,7 +1294,7 @@ struct AstFClose : public AstNodeStmt {
virtual bool isUnlikely() const { return true; } virtual bool isUnlikely() const { return true; }
virtual V3Hash sameHash() const { return V3Hash(); } virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; } 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); } void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
}; };
@@ -1246,11 +1317,39 @@ struct AstFOpen : public AstNodeStmt {
virtual bool isUnlikely() const { return true; } virtual bool isUnlikely() const { return true; }
virtual V3Hash sameHash() const { return V3Hash(); } virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; } 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* filenamep() const { return op2p(); }
AstNode* modep() const { return op3p(); } 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 { struct AstGenFor : public AstNodeFor {
AstGenFor(FileLine* fileline, AstNode* initsp, AstNode* condp, AstGenFor(FileLine* fileline, AstNode* initsp, AstNode* condp,
AstNode* incsp, AstNode* bodysp) AstNode* incsp, AstNode* bodysp)
@@ -1624,6 +1723,22 @@ public:
int dimension() const { return m_dimension; } 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 // non-ary ops
@@ -2491,6 +2606,39 @@ struct AstNeqCase : public AstNodeBiCom {
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} 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 { struct AstConcat : public AstNodeBiop {
// If you're looking for {#{}}, see AstReplicate // If you're looking for {#{}}, see AstReplicate
AstConcat(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { 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; } 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 // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -131,6 +131,18 @@ private:
nodep->replaceWith(newp); nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL; 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*) { virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this); 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
+63 -28
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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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_OVERLAP_WIDTH 12 // Maximum width we can check for overlaps in
#define CASE_BARF 999999 // Magic width when non-constant #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; } //int debug() { return 9; }
virtual void visit(AstNodeCase* nodep, AstNUser*) { 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 // Detect multiple defaults
bool hitDefault = false; bool hitDefault = false;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
@@ -275,21 +273,15 @@ private:
// IF((EQ (AND MASK cexpr) (AND MASK icond1) // IF((EQ (AND MASK cexpr) (AND MASK icond1)
// ,istmts2, istmts3 // ,istmts2, istmts3
AstNode* cexprp = nodep->exprp()->unlinkFrBack(); AstNode* cexprp = nodep->exprp()->unlinkFrBack();
AstNode* ifrootp = NULL; // We'll do this in two stages. First stage, convert the conditions to
AstNode* ifnextp = NULL; // 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()) { 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()) { if (!itemp->condsp()) {
// Default clause. We reordered in link, so default is always last // Default clause. Just make true, we'll optimize it away later
if (ifnextp) { itemp->condsp(new AstConst(itemp->fileline(), V3Number(itemp->fileline(), 1,1)));
if (istmtsp) ifnextp->castIf()->addElsesp(istmtsp); hadDefault = true;
} else { // Just a empty case default: endcase
ifnextp = istmtsp;
}
if (!ifrootp) ifrootp = istmtsp;
ifnextp = istmtsp;
itemp = NULL; break;
} else { } else {
// Expressioned clause // Expressioned clause
AstNode* icondNextp = NULL; AstNode* icondNextp = NULL;
@@ -324,24 +316,67 @@ private:
ifexprp = new AstLogOr(itemp->fileline(), ifexprp, condp); ifexprp = new AstLogOr(itemp->fileline(), ifexprp, condp);
} }
} }
// Replace expression in tree
// Make the new IF and attach in the tree itemp->condsp(ifexprp);
if (ifexprp) {
AstIf* newp = new AstIf(itemp->fileline(), ifexprp, istmtsp, NULL);
if (ifnextp) {
ifnextp->castIf()->addElsesp(newp);
}
if (!ifrootp) ifrootp = newp;
ifnextp = newp;
} }
} }
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 // Handle any assertions
replaceCaseParallel(nodep, false); replaceCaseParallel(nodep, false);
// Replace the CASE... with IF... // 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(); else nodep->unlinkFrBack();
if (debug()>=9) ifrootp->dumpTree(cout," _new: "); nodep->deleteTree(); nodep=NULL;
} }
void replaceCaseParallel(AstCase* nodep, bool noOverlapsAllCovered) { 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
+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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
+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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -104,11 +104,8 @@ private:
nodep->unlinkFrBack(&relinkHandle); nodep->unlinkFrBack(&relinkHandle);
// //
computeCppWidth(nodep); computeCppWidth(nodep);
V3Number zero (nodep->fileline(), nodep->widthMin(),0);
V3Number masksmall (nodep->fileline(), nodep->widthMin());
masksmall.opNot(zero);
V3Number mask (nodep->fileline(), cppWidth(nodep)); V3Number mask (nodep->fileline(), cppWidth(nodep));
mask.opAssign(masksmall); mask.setMask(nodep->widthMin());
AstNode* cleanp = new AstAnd (nodep->fileline(), AstNode* cleanp = new AstAnd (nodep->fileline(),
new AstConst (nodep->fileline(), mask), new AstConst (nodep->fileline(), mask),
nodep); nodep);
@@ -199,6 +196,9 @@ private:
virtual void visit(AstText* nodep, AstNUser*) { virtual void visit(AstText* nodep, AstNUser*) {
setClean (nodep, true); setClean (nodep, true);
} }
virtual void visit(AstScopeName* nodep, AstNUser*) {
setClean (nodep, true);
}
virtual void visit(AstSel* nodep, AstNUser*) { virtual void visit(AstSel* nodep, AstNUser*) {
operandTriop(nodep); operandTriop(nodep);
setClean (nodep, nodep->cleanOut()); 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -472,7 +472,8 @@ private:
ifstmtp->addNext(new AstIf(fl, ifstmtp->addNext(new AstIf(fl,
new AstLt (fl, new AstConst(fl, 100), new AstLt (fl, new AstConst(fl, 100),
new AstVarRef(fl, countVarp, false)), 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)), ->addNext(new AstStop (fl)),
NULL)); NULL));
untilp->addBodysp(new AstIf(fl, new AstNeq(fl, new AstConst(fl, 0), 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
+75 -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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -246,9 +246,8 @@ private:
replaceNum(nodep, 0); nodep=NULL; replaceNum(nodep, 0); nodep=NULL;
} }
void replaceAllOnes (AstNode* nodep) { void replaceAllOnes (AstNode* nodep) {
V3Number num (nodep->fileline(), nodep->width(), 0); V3Number ones (nodep->fileline(), nodep->width(), 0);
V3Number ones (nodep->fileline(), nodep->width()); ones.setMask(nodep->width());
ones.opNot(num);
replaceNum(nodep, ones); nodep=NULL; replaceNum(nodep, ones); nodep=NULL;
} }
void replaceConst(AstNodeUniop* nodep) { void replaceConst(AstNodeUniop* nodep) {
@@ -388,7 +387,7 @@ private:
AstNode* newp; AstNode* newp;
V3Number mask1 (nodep->fileline(), nodep->width()); V3Number mask1 (nodep->fileline(), nodep->width());
V3Number ones (nodep->fileline(), nodep->width()); V3Number ones (nodep->fileline(), nodep->width());
ones.opNot(mask1); ones.setMask(nodep->width());
if (shift1<0) { if (shift1<0) {
mask1.opShiftR(ones,V3Number(nodep->fileline(),VL_WORDSIZE,-shift1)); mask1.opShiftR(ones,V3Number(nodep->fileline(),VL_WORDSIZE,-shift1));
} else { } else {
@@ -757,7 +756,8 @@ private:
nodep->varp()->initp()->iterateAndNext(*this); nodep->varp()->initp()->iterateAndNext(*this);
if (operandConst(nodep->varp()->initp()) if (operandConst(nodep->varp()->initp())
&& !nodep->lvalue() && !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())) { || nodep->varp()->isParam())) {
AstConst* constp = nodep->varp()->initp()->castConst(); AstConst* constp = nodep->varp()->initp()->castConst();
const V3Number& num = constp->num(); const V3Number& num = constp->num();
@@ -802,7 +802,12 @@ private:
if (nodep->sensp()->castConst() if (nodep->sensp()->castConst()
|| (nodep->varrefp() && nodep->varrefp()->varp()->isParam())) { || (nodep->varrefp() && nodep->varrefp()->varp()->isParam())) {
// Constants in sensitivity lists may be removed (we'll simplify later) // 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->replaceWith(newp);
nodep->deleteTree(); nodep=NULL; nodep->deleteTree(); nodep=NULL;
} else if (nodep->sensp()->castNot()) { } else if (nodep->sensp()->castNot()) {
@@ -938,6 +943,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*) { virtual void visit(AstWhile* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
if (nodep->condp()->isZero()) { if (nodep->condp()->isZero()) {
@@ -1048,6 +1110,10 @@ private:
TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase {$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castNeqCase}", "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()}"); TREEOPV("AstNot {$lhsp.castEq, $lhsp.width1}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castEq}", "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()}"); TREEOPV("AstNot {$lhsp.castNeq, $lhsp.width1}", "AstEq {$lhsp->op1p(),$lhsp->op2p()}");
@@ -1089,6 +1155,7 @@ private:
TREEOP("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X. TREEOP("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("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstEqWild {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
@@ -1099,6 +1166,7 @@ private:
TREEOP("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstNeqCase{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("AstLogAnd {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
TREEOP("AstLogOr {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)"); TREEOP("AstLogOr {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
///=== Verilog operators ///=== Verilog operators
+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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -40,7 +40,6 @@
#include "V3Ast.h" #include "V3Ast.h"
//###################################################################### //######################################################################
// Depth state, as a visitor of each AstNode
class DepthVisitor : public AstNVisitor { class DepthVisitor : public AstNVisitor {
private: private:
@@ -55,11 +54,6 @@ private:
//int debug() { return 9; } //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 // METHODS
void createDeepTemp(AstNode* nodep) { void createDeepTemp(AstNode* nodep) {
UINFO(6," Deep "<<nodep<<endl); UINFO(6," Deep "<<nodep<<endl);
@@ -114,13 +108,15 @@ private:
virtual void visit(AstNodeTermop* nodep, AstNUser*) { virtual void visit(AstNodeTermop* nodep, AstNUser*) {
} }
virtual void visit(AstNodeMath* 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; if (m_depth>m_maxdepth) m_maxdepth=m_depth;
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
m_depth--; m_depth -= 2;
if ((m_maxdepth-m_depth) > MAX_EXPR_DEPTH if (m_stmtp
&& 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 && !nodep->backp()->castNodeStmt() // Not much point if we're about to use it
) { ) {
m_maxdepth = m_depth; m_maxdepth = m_depth;
@@ -173,14 +169,10 @@ public:
virtual ~DepthVisitor() {} virtual ~DepthVisitor() {}
}; };
//----------------------------------------------------------------------
// Top loop
//###################################################################### //######################################################################
// Depth class functions // Depth class functions
void V3Depth::depthAll(AstNetlist* nodep) { void V3Depth::depthAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl); UINFO(2,__FUNCTION__<<": "<<endl);
// We must do it in bottom-up module
DepthVisitor visitor (nodep); 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // 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(), //newfuncp->addStmtsp(new AstDisplay (newfuncp->fileline(), AstDisplayType::DISPLAY,
// '\n', string("%%Error: ")+name+"() called with bad scope", NULL)); // string("%%Error: ")+name+"() called with bad scope", NULL));
//newfuncp->addStmtsp(new AstStop (newfuncp->fileline())); //newfuncp->addStmtsp(new AstStop (newfuncp->fileline()));
if (debug()>=9) newfuncp->dumpTree(cout," newfunc: "); if (debug()>=9) newfuncp->dumpTree(cout," newfunc: ");
} else { } 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
+66 -9
View File
@@ -8,7 +8,7 @@
// //
//************************************************************************* //*************************************************************************
// //
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can // Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -239,14 +239,49 @@ public:
emitIQW(nodep->modep()); emitIQW(nodep->modep());
if (nodep->modep()->width()>4*8) nodep->modep()->v3error("$fopen mode should be <= 4 characters"); if (nodep->modep()->width()>4*8) nodep->modep()->v3error("$fopen mode should be <= 4 characters");
puts("("); puts("(");
if (nodep->filenamep()->isWide()) puts(cvtToStr(nodep->filenamep()->widthWords())); if (nodep->filenamep()->isWide()) {
puts(cvtToStr(nodep->filenamep()->widthWords()));
putbs(", ");
}
if (nodep->filenamep()->widthWords() > VL_TO_STRING_MAX_WORDS) {
nodep->v3error("String of "<<nodep->filenamep()->width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h\n");
}
nodep->filenamep()->iterateAndNext(*this);
putbs(", ");
nodep->modep()->iterateAndNext(*this);
puts(");\n");
}
virtual void visit(AstReadMem* nodep, AstNUser*) {
puts("VL_READMEM_");
emitIQW(nodep->filenamep());
puts(" ("); // We take a void* rather then emitIQW(nodep->memp());
puts(nodep->isHex()?"true":"false");
putbs(",");
puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width
putbs(",");
uint32_t array_lsb = 0;
{
AstVarRef* varrefp = nodep->memp()->castVarRef();
if (!varrefp || !varrefp->varp()->arrayp(0)) { nodep->v3error("Readmem loading non-arrayed variable"); }
else {
puts(cvtToStr(varrefp->varp()->arrayElements()));
array_lsb = varrefp->varp()->arrayp(0)->lsbConst();
}
}
putbs(", ");
puts(cvtToStr(array_lsb));
putbs(",");
puts(cvtToStr(nodep->filenamep()->widthWords()));
if (nodep->filenamep()->widthWords() > VL_TO_STRING_MAX_WORDS) { 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->v3error("String of "<<nodep->filenamep()->width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h\n");
} }
putbs(", "); putbs(", ");
nodep->filenamep()->iterateAndNext(*this); nodep->filenamep()->iterateAndNext(*this);
putbs(", "); 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"); puts(");\n");
} }
virtual void visit(AstFClose* nodep, AstNUser*) { virtual void visit(AstFClose* nodep, AstNUser*) {
@@ -353,7 +388,7 @@ public:
} }
virtual void visit(AstMulS* nodep, AstNUser* vup) { virtual void visit(AstMulS* nodep, AstNUser* vup) {
if (nodep->widthWords() > VL_MULS_MAX_WORDS) { 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); visit(nodep->castNodeBiop(), vup);
} }
@@ -559,7 +594,14 @@ class EmitCImp : EmitCStmts {
if (filenum) filenameNoExt += "__"+cvtToStr(filenum); if (filenum) filenameNoExt += "__"+cvtToStr(filenum);
filenameNoExt += (slow ? "__Slow":""); filenameNoExt += (slow ? "__Slow":"");
V3OutCFile* ofp = NULL; 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"; string filename = filenameNoExt+".sp";
newCFile(filename, slow, source); newCFile(filename, slow, source);
ofp = new V3OutSpFile (filename); ofp = new V3OutSpFile (filename);
@@ -652,6 +694,21 @@ class EmitCImp : EmitCStmts {
if (gotOne) { if (gotOne) {
puts(");\n"); puts(");\n");
//puts("VL_DEBUG_IF( if (__req) cout<<\"\tCLOCKREQ );"); //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*) { void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
string vformat = nodep->text(); string vformat = nodep->text();
bool addNewline = (nodep->newline() == '\n');
AstNode* elistp = nodep->exprsp(); AstNode* elistp = nodep->exprsp();
// Convert Verilog display to C printf formats // Convert Verilog display to C printf formats
@@ -996,16 +1052,17 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
// Spec: h d o b c l // Spec: h d o b c l
case 'b': displayArg(nodep,&elistp,fmt,'b'); break; case 'b': displayArg(nodep,&elistp,fmt,'b'); break;
case 'c': displayArg(nodep,&elistp,fmt,'c'); break; case 'c': displayArg(nodep,&elistp,fmt,'c'); break;
case 't':
case 'd': displayArg(nodep,&elistp,fmt,'u'); break; // Unsigned decimal case 'd': displayArg(nodep,&elistp,fmt,'u'); break; // Unsigned decimal
case 'o': displayArg(nodep,&elistp,fmt,'o'); break; case 'o': displayArg(nodep,&elistp,fmt,'o'); break;
case 'h': case 'h':
case 'x': displayArg(nodep,&elistp,fmt,'x'); break; case 'x': displayArg(nodep,&elistp,fmt,'x'); break;
case 's': displayArg(nodep,&elistp,fmt,'s'); break; case 's': displayArg(nodep,&elistp,fmt,'s'); break;
case 't': displayArg(nodep,&elistp,fmt,'u'); break;
case 'm': { case 'm': {
emitDispState.pushFormat("%s"); emitDispState.pushFormat("%s");
emitDispState.pushArg(NULL, "vlSymsp->name("); 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()); emitDispState.pushFormat(textp->text());
} }
break; break;
@@ -1026,7 +1083,7 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
if (elistp != NULL) { if (elistp != NULL) {
nodep->v3error("Extra arguments for $display format\n"); nodep->v3error("Extra arguments for $display format\n");
} }
if (addNewline) emitDispState.pushFormat("\\n"); if (nodep->addNewline()) emitDispState.pushFormat("\\n");
displayEmit(nodep); displayEmit(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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -138,7 +138,7 @@ public:
of.puts("\n# Link rules...\n"); of.puts("\n# Link rules...\n");
of.puts(v3Global.opt.prefix()+": $(VK_USER_OBJS) $(SP_SRCS) $(VM_PREFIX)__ALL.a\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"); 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -193,6 +193,16 @@ public:
if (nodep->filep()) nodep->filep()->iterateChildren(*this); if (nodep->filep()) nodep->filep()->iterateChildren(*this);
puts(");\n"); 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*) { virtual void visit(AstNodeFor* nodep, AstNUser*) {
puts("for ("); puts("for (");
m_suppressSemi = true; m_suppressSemi = true;
@@ -236,6 +246,8 @@ public:
virtual void visit(AstText* nodep, AstNUser*) { virtual void visit(AstText* nodep, AstNUser*) {
ofp()->putsNoTracking(nodep->text()); ofp()->putsNoTracking(nodep->text());
} }
virtual void visit(AstScopeName* nodep, AstNUser*) {
}
virtual void visit(AstCStmt* nodep, AstNUser*) { virtual void visit(AstCStmt* nodep, AstNUser*) {
putbs("$_CSTMT("); putbs("$_CSTMT(");
nodep->bodysp()->iterateAndNext(*this); 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
+31 -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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -34,7 +34,8 @@
FileLine FileLine::s_defaultFileLine = FileLine(EmptySecret()); 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; int V3Error::s_debugDefault = 0;
ostringstream V3Error::s_errorStr; // Error string being formed ostringstream V3Error::s_errorStr; // Error string being formed
V3ErrorCode V3Error::s_errorCode = V3ErrorCode::FATAL; V3ErrorCode V3Error::s_errorCode = V3ErrorCode::FATAL;
@@ -187,25 +188,46 @@ string V3Error::lineStr (const char* filename, int lineno) {
return out.str(); return out.str();
} }
void V3Error::incWarnings() {
s_warnCount++;
if (errorOrWarnCount() == MAX_ERRORS) { // Not >= as would otherwise recurse
v3fatal ("Exiting due to too many errors encountered\n");
}
}
void V3Error::incErrors() { void V3Error::incErrors() {
s_errcnt++; s_errCount++;
if (errorCount() == MAX_ERRORS) { // Not >= as would otherwise recurse if (errorOrWarnCount() == MAX_ERRORS) { // Not >= as would otherwise recurse
v3fatal ("Exiting due to too many errors encountered\n"); v3fatal ("Exiting due to too many errors encountered\n");
} }
} }
void V3Error::abortIfErrors() { void V3Error::abortIfErrors() {
if (errorCount()) { 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) { string V3Error::msgPrefix(V3ErrorCode code) {
if (code==V3ErrorCode::SUPPRESS) return "-arning-suppressed: "; if (code==V3ErrorCode::SUPPRESS) return "-arning-suppressed: ";
else if (code==V3ErrorCode::FATAL) return "%Error: "; else if (code==V3ErrorCode::FATAL) return "%Error: ";
else if (code==V3ErrorCode::ERROR) return "%Error: "; else if (code==V3ErrorCode::ERROR) return "%Error: ";
else if (code<V3ErrorCode::FIRST_WARN else if (isError(code)) return "%Error-"+(string)code.ascii()+": ";
|| s_pretendError[code]) return "%Error-"+(string)code.ascii()+": ";
else return "%Warning-"+(string)code.ascii()+": "; else return "%Warning-"+(string)code.ascii()+": ";
} }
@@ -258,7 +280,8 @@ void V3Error::v3errorEnd (ostringstream& sstr) {
cerr<<msgPrefix()<<"else you may end up with different sim results."<<endl; 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) { if (s_errorCode==V3ErrorCode::FATAL) {
static bool inFatal = false; static bool inFatal = false;
if (!inFatal) { if (!inFatal) {
+13 -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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -37,6 +37,7 @@ public:
FATAL, // Kill the program FATAL, // Kill the program
ERROR, // General error out, can't suppress ERROR, // General error out, can't suppress
// Error codes: // Error codes:
MULTITOP, // Error: Multiple top level modules
TASKNSVAR, // Error: Task I/O not simple TASKNSVAR, // Error: Task I/O not simple
// Warning codes: // Warning codes:
FIRST_WARN, // Just a code so the program knows where to start warnings FIRST_WARN, // Just a code so the program knows where to start warnings
@@ -71,7 +72,7 @@ public:
const char* names[] = { const char* names[] = {
// Leading spaces indicate it can't be disabled. // Leading spaces indicate it can't be disabled.
" SUPPRESS", " FATAL", " ERROR", " SUPPRESS", " FATAL", " ERROR",
"TASKNSVAR", "MULTITOP", "TASKNSVAR",
" FIRST_WARN", " FIRST_WARN",
"BLKANDNBLK", "BLKANDNBLK",
"CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST", "CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST",
@@ -103,11 +104,13 @@ class V3Error {
static bool s_describedEachWarn[V3ErrorCode::MAX]; // Told user specifics about this warning 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 bool s_pretendError[V3ErrorCode::MAX]; // Pretend this warning is an error
static int s_debugDefault; // Default debugging level 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 ostringstream s_errorStr; // Error string being formed
static V3ErrorCode s_errorCode; // Error string being formed will abort static V3ErrorCode s_errorCode; // Error string being formed will abort
enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors
static void incErrors(); static void incErrors();
static void incWarnings();
V3Error() { cerr<<("Static class"); abort(); } V3Error() { cerr<<("Static class"); abort(); }
@@ -117,12 +120,16 @@ class V3Error {
static void debugDefault(int level) { s_debugDefault = level; } static void debugDefault(int level) { s_debugDefault = level; }
static int debugDefault() { return s_debugDefault; } static int debugDefault() { return s_debugDefault; }
static string msgPrefix(V3ErrorCode code=s_errorCode); // returns %Error/%Warn 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 // METHODS
static void init(); static void init();
static void abortIfErrors(); static void abortIfErrors();
static void abortIfWarnings();
static void suppressThisWarning(); // Suppress next %Warn if user has it off static void suppressThisWarning(); // Suppress next %Warn if user has it off
static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; } static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; }
static bool isError(V3ErrorCode code);
static string v3sform (const char* format, ...); static string v3sform (const char* format, ...);
static string lineStr (const char* filename, int lineno); static string lineStr (const char* filename, int lineno);
static V3ErrorCode errorCode() { return s_errorCode; } static V3ErrorCode errorCode() { return s_errorCode; }
@@ -197,7 +204,8 @@ public:
void warnOff(V3ErrorCode code, bool flag) { m_warnOff.set(code,flag); } // Turn on/off warning messages on this line. 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 warnOff(const string& code, bool flag); // Returns 1 if ok
bool warnIsOff(V3ErrorCode code); bool warnIsOff(V3ErrorCode code);
void warnResetDefault() { m_warnOff=s_defaultFileLine.m_warnOff; } void warnStateFrom(const FileLine& from) { m_warnOff=from.m_warnOff; }
void warnResetDefault() { warnStateFrom(s_defaultFileLine); }
void v3errorEnd(ostringstream& str); void v3errorEnd(ostringstream& str);
inline bool operator==(FileLine rhs) { return (m_lineno==rhs.m_lineno && m_filename==rhs.m_filename); } inline bool operator==(FileLine rhs) { return (m_lineno==rhs.m_lineno && m_filename==rhs.m_filename); }
+2 -5
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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -65,11 +65,8 @@ private:
if (nodep->isWide()) { if (nodep->isWide()) {
return V3Number (nodep->fileline(), VL_WORDSIZE, VL_MASK_I(nodep->widthMin())); return V3Number (nodep->fileline(), VL_WORDSIZE, VL_MASK_I(nodep->widthMin()));
} else { } else {
V3Number zero (nodep->fileline(), nodep->widthMin(),0);
V3Number masksmall (nodep->fileline(), nodep->widthMin());
masksmall.opNot(zero);
V3Number mask (nodep->fileline(), longOrQuadWidth(nodep)); V3Number mask (nodep->fileline(), longOrQuadWidth(nodep));
mask.opAssign(masksmall); mask.setMask(nodep->widthMin());
return mask; return mask;
} }
} }
+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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
+11 -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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -198,10 +198,18 @@ public:
m_substTreep = NULL; m_substTreep = NULL;
m_buffersOnly = buffersOnly; m_buffersOnly = buffersOnly;
m_lhsVarRef = NULL; m_lhsVarRef = NULL;
// Iterate
nodep->accept(*this); nodep->accept(*this);
// Check results
if (!m_substTreep) { if (!m_substTreep) {
clearSimple("No assignment found\n"); 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) { if (debug()>=9 && !m_isSimple) {
nodep->dumpTree(cout,"\tgate!Ok: "); nodep->dumpTree(cout,"\tgate!Ok: ");
} }
@@ -224,6 +232,7 @@ private:
//Entire netlist: //Entire netlist:
// AstVarScope::userp -> GateVarVertex* for usage var, 0=not set yet // AstVarScope::userp -> GateVarVertex* for usage var, 0=not set yet
// {statement}Node::userp -> GateLogicVertex* for this statement // {statement}Node::userp -> GateLogicVertex* for this statement
// STATE // STATE
V3Graph m_graph; // Scoreboard of var usages/dependencies V3Graph m_graph; // Scoreboard of var usages/dependencies
GateLogicVertex* m_logicVertexp; // Current statement being tracked, NULL=ignored GateLogicVertex* m_logicVertexp; // Current statement being tracked, NULL=ignored
@@ -458,6 +467,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
} }
} }
} }
// Process it
if (!doit) { if (!doit) {
if (allowMultiIn && (debug()>=9)) { if (allowMultiIn && (debug()>=9)) {
UINFO(9, "Not ok simp"<<okVisitor.isSimple()<<" mi"<<multiInputs 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
+6 -2
View File
@@ -8,7 +8,7 @@
// //
//************************************************************************* //*************************************************************************
// //
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can // Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -180,6 +180,7 @@ void V3Graph::userClearVertices() {
// 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 then help.
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
vertexp->user(0); vertexp->user(0);
vertexp->userp(NULL); // Its a union, but might be different size then user()
} }
} }
@@ -187,7 +188,8 @@ void V3Graph::userClearEdges() {
// Clear user() in all of tree // Clear user() in all of tree
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
edgep->userp(NULL); edgep->user(0);
edgep->userp(NULL); // Its a union, but might be different size then user()
} }
} }
} }
@@ -253,6 +255,8 @@ void V3Graph::dumpDotFile(const string& filename, bool colorAsSubgraph) {
*logp<<"digraph v3graph {\n"; *logp<<"digraph v3graph {\n";
*logp<<"\trankdir="<<dotRankDir()<<"\n"; *logp<<"\trankdir="<<dotRankDir()<<"\n";
*logp<<"\tsize="<<"\"7.5,10\""<<"\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 // List of all possible subgraphs
typedef multimap<string,V3GraphVertex*> SubgraphMmap; 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
+9 -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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -37,6 +37,7 @@
// Break the minimal number of backward edges to make the graph acyclic // Break the minimal number of backward edges to make the graph acyclic
class GraphAcycVertex : public V3GraphVertex { class GraphAcycVertex : public V3GraphVertex {
// user() is used for various sub-algorithm pieces
V3GraphVertex* m_origVertexp; // Pointer to first vertex this represents V3GraphVertex* m_origVertexp; // Pointer to first vertex this represents
protected: protected:
friend class GraphAcyc; friend class GraphAcyc;
@@ -308,6 +309,9 @@ void GraphAcyc::simplifyOne (GraphAcycVertex* avertexp) {
avertexp->setDelete(); // Mark so we won't delete it twice avertexp->setDelete(); // Mark so we won't delete it twice
// Make a new edge connecting the two vertices directly // Make a new edge connecting the two vertices directly
// If both are breakable, we pick the one with less weight, else it's arbitrary // 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() V3GraphEdge* templateEdgep = ( (inEdgep->cutable()
&& (!outEdgep->cutable() && (!outEdgep->cutable()
|| inEdgep->weight()<outEdgep->weight() )) || inEdgep->weight()<outEdgep->weight() ))
@@ -353,7 +357,7 @@ void GraphAcyc::simplifyDup (GraphAcycVertex* avertexp) {
if (avertexp->isDelete()) return; if (avertexp->isDelete()) return;
// Clear marks // Clear marks
for (V3GraphEdge* edgep = avertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { for (V3GraphEdge* edgep = avertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
edgep->top()->user(false); edgep->top()->userp(NULL);
} }
// Mark edges and detect duplications // Mark edges and detect duplications
for (V3GraphEdge* nextp, *edgep = avertexp->outBeginp(); edgep; edgep=nextp) { for (V3GraphEdge* nextp, *edgep = avertexp->outBeginp(); edgep; edgep=nextp) {
@@ -364,16 +368,16 @@ void GraphAcyc::simplifyDup (GraphAcycVertex* avertexp) {
if (!prevEdgep->cutable()) { if (!prevEdgep->cutable()) {
// !cutable duplicates prev !cutable: we can ignore it, redundant // !cutable duplicates prev !cutable: we can ignore it, redundant
// cutable duplicates prev !cutable: know it's not a relevant loop, ignore it // 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; edgep->unlinkDelete(); edgep = NULL;
} else if (!edgep->cutable()) { } else if (!edgep->cutable()) {
// !cutable duplicates prev cutable: delete the earlier 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; prevEdgep->unlinkDelete(); prevEdgep = NULL;
outVertexp->userp(edgep); outVertexp->userp(edgep);
} else { } else {
// cutable duplicates prev cutable: combine weights // cutable duplicates prev cutable: combine weights
UINFO(8," DelDupComb "<<avertexp<<endl); UINFO(8," DelDupComb "<<avertexp<<" -> "<<edgep->top()<<endl);
prevEdgep->weight (prevEdgep->weight() + edgep->weight()); prevEdgep->weight (prevEdgep->weight() + edgep->weight());
addOrigEdgep (prevEdgep, edgep); addOrigEdgep (prevEdgep, edgep);
edgep->unlinkDelete(); edgep = NULL; edgep->unlinkDelete(); edgep = NULL;
+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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -86,7 +86,7 @@ private:
void vertexIterate(V3GraphVertex* vertexp) { void vertexIterate(V3GraphVertex* vertexp) {
// Clear marks // Clear marks
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
edgep->top()->user(false); edgep->top()->userp(NULL);
} }
// Mark edges and detect duplications // Mark edges and detect duplications
for (V3GraphEdge* nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) { for (V3GraphEdge* nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) {
+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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
+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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -311,6 +311,34 @@ public:
gp->dfaReduce(); 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() { void V3Graph::test() {
@@ -320,5 +348,6 @@ void V3Graph::test() {
{ V3GraphTestAcyc test; test.run(); } { V3GraphTestAcyc test; test.run(); }
{ V3GraphTestVars test; test.run(); } { V3GraphTestVars test; test.run(); }
{ V3GraphTestDfa test; test.run(); } { V3GraphTestDfa test; test.run(); }
{ V3GraphTestImport test; test.run(); }
if (V3GraphTest::debug()) v3fatalSrc("Exiting due to graph testing enabled"); 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
+4 -4
View File
@@ -8,7 +8,7 @@
// //
//************************************************************************* //*************************************************************************
// //
// Copyright 2003-2006 by Wilson Snyder. This program is free software; you can // Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //
@@ -233,10 +233,10 @@ private:
} }
nodep->iterateChildren(*this); 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 there's a %m in the display text, we add a special node that will contain the name()
if (m_cellp // Similar code in V3Begin
&& nodep->name().find("%m") != string::npos) { if (m_cellp) {
// To keep correct visual order, must add before other Text's // To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp(); AstNode* afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext(); if (afterp) afterp->unlinkFrBackWithNext();
+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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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. // Somewhat illogically, we need to rename the orignal name of the cell too.
// as that is the name users expect for dotting // as that is the name users expect for dotting
// The spec says we add [x], but that won't work in C... // The spec says we add [x], but that won't work in C...
newp->name(newp->name()+"__"+cvtToStr(m_instNum)); newp->name(newp->name()+"__BRA__"+cvtToStr(m_instNum)+"__KET__");
newp->origName(newp->origName()+"__"+cvtToStr(m_instNum)); newp->origName(newp->origName()+"__BRA__"+cvtToStr(m_instNum)+"__KET__");
// Fixup pins // Fixup pins
newp->pinsp()->iterateAndNext(*this); newp->pinsp()->iterateAndNext(*this);
if (debug()==9) { newp->dumpTree(cout,"newcell: "); cout<<endl; } 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // 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 // redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License. // General Public License or the Perl Artistic License.
// //

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