Compare commits

...
127 Commits
Author SHA1 Message Date
Wilson Snyder daf7f42138 Version bump 2008-09-19 17:23:15 -04:00
Wilson Snyder dd487d4184 Fix t_psl_basic_cover test for new SystemPerl package 2008-09-19 08:00:02 -04:00
Wilson Snyder d90071637d SystemC uint64_t pins are now the default instead of sc_bv<64>.
Use --no-pins64 for backward compatibility.
2008-09-18 09:20:16 -04:00
Wilson Snyder d8efae2aba Rename t_bitsel_loop to t_select_loop to match other tests 2008-09-18 08:05:38 -04:00
Wilson Snyder 22543f3e19 Support arbitrary characters in identifiers and tracing. 2008-09-17 22:22:46 -04:00
Wilson Snyder 6aaef67e73 Fix test_verilated running under ncsim 2008-09-17 20:58:01 -04:00
Wilson Snyder 82a934d6fb Fix missing define to pass coverage down 2008-09-17 11:11:24 -04:00
Wilson Snyder eca6f2ca05 Increase bison max depth to prevent parse error 2008-09-17 11:11:09 -04:00
Wilson Snyder ef69f36403 More renames of asInt/toUInt where deemed correct 2008-09-04 11:03:46 -04:00
Wilson Snyder 99cf981c2f Support coverage under SystemPerl 1.285 and newer. 2008-09-04 09:43:53 -04:00
Wilson Snyder fc7a449f6d Rename asInt/asQuad to indicate signed/unsigned.
Internal code rename, no function change.
2008-09-03 17:40:01 -04:00
Wilson Snyder b7fafdafaa Fix never-true compiler warning [John Sanguinetti] 2008-08-22 17:32:29 -04:00
Wilson Snyder 8e180cfcde make install doesn't need source code 2008-08-20 16:05:24 -04:00
Wilson Snyder 4770fd39d2 Fix stack overflow on large ? : trees. 2008-08-20 15:59:10 -04:00
Wilson Snyder df107628c6 Fix default clocking syntax; covers go outside the block 2008-08-06 17:51:36 -04:00
Wilson Snyder 3463080a71 Fix extra evaluation of pure combo blocks in SystemC output. 2008-08-06 17:09:33 -04:00
Wilson Snyder 500dc2170f Support SystemVerilog "cover property" statements. 2008-08-06 12:52:39 -04:00
Wilson Snyder a76ae67a81 Add bisonpre for simplifing grammar and cleaning output 2008-08-06 12:35:34 -04:00
Wilson Snyder 1d091e49e1 Add VL_TIME_MULTIPLIER to allow sub-timeunit time printing 2008-08-05 14:45:20 -04:00
Wilson Snyder 2b63219cc6 Add IMPERFECTSCH warning, disabled by default. 2008-08-05 13:41:53 -04:00
Wilson Snyder f1b7762bef Add by-design and by-module subtotals to verilator_profcfunc. 2008-08-05 09:59:15 -04:00
Wilson Snyder 043ad86482 When warnings are disabled on signals that are flattened out, disable
the warnings on the signal(s) that replace it.
2008-08-01 15:30:17 -04:00
Wilson Snyder 74ca9578ed VERILATOR_BIN envvar should override adding _dbg to program name 2008-07-25 16:30:18 -04:00
Wilson Snyder d499161446 Fix typo in CASEWITHX 2008-07-23 08:58:48 -04:00
Wilson Snyder 34e8de56bc Version bump 2008-07-23 07:51:32 -04:00
Wilson Snyder 8a7864ebaa Add --Wfuture-, for improving forward compatibility. 2008-07-22 14:27:34 -04:00
Wilson Snyder 9e5fb5467f Add CASEZWITHX lint warning and if disabled fix handling of casez with Xs. 2008-07-22 13:07:19 -04:00
Wilson Snyder fb34bf7222 Fix lvalue errors with public functions; bug25. 2008-07-22 11:15:28 -04:00
Wilson Snyder 4591f35b7c Add --autoflush option 2008-07-16 14:06:08 -04:00
Wilson Snyder f0a06182ca Add --x-assign=fast, and make it the default. 2008-07-16 13:31:21 -04:00
Wilson Snyder d9e47a6293 Add WIDTH warning to etc file descriptors. 2008-07-14 17:15:26 -04:00
Wilson Snyder a555f87705 Fix missing verilator.1 during install. Bug#20. [Holger Wachtler] 2008-07-14 13:41:00 -04:00
Wilson Snyder 826b997166 Add . 2008-07-14 13:16:05 -04:00
Wilson Snyder d34bc6f304 Fix missing config_reg.h error when non-author .git repository 2008-07-14 10:48:57 -04:00
Wilson Snyder 5771ea48ef Fix IMPURE errors due to X-assignment temporary variables. 2008-07-14 10:42:58 -04:00
Wilson Snyder a4f3199427 Add informational warning when -Og is used 2008-07-02 06:48:50 -04:00
Wilson Snyder e6a43fc127 Fix verilator_includer not being installed into where verilated.mk.in expects 2008-07-01 16:10:09 -04:00
Wilson Snyder 701bd38d01 Add support for , . Bug14. 2008-07-01 14:15:10 -04:00
Wilson Snyder 1a8c8bec0d Rework $display/$write to go via new VL_WRITE function instead of
converting to pure C printf call.  This makes the resulting code smaller,
and allows sharing code with future $sprintf support.
2008-06-30 14:31:58 -04:00
Wilson Snyder 20aa21d4b6 Replace stdio.h and stdarg.h with C++ versions 2008-06-30 13:11:25 -04:00
Wilson Snyder 8c6adeb85a Internals: Convert to use common string convert routine 2008-06-30 07:10:23 -04:00
Wilson Snyder 09b7ba1317 Internal rework, no functionality change.
Rework V3EmitC to use a little template language for code to output,
similar to emitVerilog() functions.  Change all emitOperator() to
emitC(), elimate emitWordForm().
2008-06-29 20:02:24 -04:00
Wilson Snyder 0703843ac1 Support , . 2008-06-27 20:04:20 -04:00
Wilson Snyder d962dfe48c One or two digit octal escapes are legal 2008-06-27 17:52:45 -04:00
Wilson Snyder d6884db439 Support . 2008-06-27 11:36:25 -04:00
Wilson Snyder fdcbedef8f Add support 2008-06-27 08:45:05 -04:00
Wilson Snyder 8afd19648f Support 2008-06-26 08:52:02 -04:00
Wilson Snyder 3017f12238 Version bump 2008-06-25 07:50:32 -04:00
Wilson Snyder 23ee0342c6 Fix Makefile to find headers/libraries under prefix. 2008-06-24 14:50:34 -04:00
Wilson Snyder 499f98a51c Fix leading/trailing mixed whitespace 2008-06-12 12:03:47 -04:00
Wilson Snyder 3073db4e81 Add configure check that C++ is working 2008-06-11 21:00:42 -04:00
Wilson Snyder 5703377a5f Fix tracing missing changes on undriven public wires. 2008-06-11 20:33:53 -04:00
Wilson Snyder b85aa872cc Make install now installs verilator_includer and verilator_profcfunc. 2008-06-11 15:13:41 -04:00
Wilson Snyder 5a1a5a7d97 Ignore "// verilator" comments alone on endif lines. 2008-06-11 13:09:36 -04:00
Wilson Snyder 52912c6329 Convert repository to git from svn.
- Change .cvsignore to .gitignore
- Remove Id metacomments
- Cleanup whitespace at end of lines
2008-06-09 21:25:10 -04:00
Wilson Snyder 056f72f27f Fix grammar error exposed with Verilog-Perl rev 55458 ++ -- fix
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1072 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-06-05 20:49:52 +00:00
Wilson Snyder bb038e86a2 Preproc: Fix error when macro call has commas in concatenate.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1071 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-06-04 15:39:44 +00:00
Wilson Snyder cc6c71eb37 Preproc: Fix syntax error when include defname is ifdefed.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1070 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-06-04 14:45:32 +00:00
Wilson Snyder de4358f8d8 Preproc: Fix syntax error when include defname is ifdefed.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1069 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-06-04 14:44:59 +00:00
Wilson Snyder d6e9c72424 Fix compile errors under Fedora 9, GCC 4.3.0.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1068 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-28 19:58:18 +00:00
Wilson Snyder 96608fb18d Fix typo in Changes file
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1064 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-08 16:37:19 +00:00
Wilson Snyder 280b826d6d Fix makefile tar.gz rule
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1061 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-08 16:34:15 +00:00
Wilson Snyder 538d3d46f4 Fix t_dist_manifest when entering/leaving directory
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1060 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-08 15:18:42 +00:00
Wilson Snyder 66b8ec8935 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1059 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-08 14:38:43 +00:00
Wilson Snyder 4f30025aa0 Add test that manifest (tar file) contains all files in repository
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1058 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-08 14:38:07 +00:00
Wilson Snyder faad36a3ef Fix missing bisonfix in kit
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1057 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-08 12:50:17 +00:00
Wilson Snyder 0b461599d1 Change makefile's maintainer-dist to use release script
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1056 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-07 18:32:00 +00:00
Wilson Snyder 0cbab84143 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1053 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-07 18:27:23 +00:00
Wilson Snyder a4e2a770f6 Add DESTDIR to Makefiles to assist RPM construction. [Gunter Dannoritzer]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1052 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-07 17:46:33 +00:00
Wilson Snyder 36e84973ec Fix parallel make running bison twice
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1051 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-06 15:45:41 +00:00
Wilson Snyder f6c8888ee2 Fix comma separated list of primitives. [by Bryan Brady]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1050 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-06 14:52:53 +00:00
Wilson Snyder f2bf6a037b Fix test broken with last commit. Part of last commit.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1049 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-06 14:18:04 +00:00
Wilson Snyder 9dade8fbd9 Fix parametrized defines calling define with comma. [Joshua Wise]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1048 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-06 01:11:21 +00:00
Wilson Snyder d2d38edf06 Fix preprocessor else after series of elsif. [Mark Nodine]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1047 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-05-06 00:50:47 +00:00
Wilson Snyder e0abd238e3 Fix compiler warnings under GCC 4.2.1/ SuSE 10.3
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1046 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-29 14:14:20 +00:00
Wilson Snyder 7edcc08886 Really enable DEFENV by default; didn't truely default it earlier
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1045 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-28 21:14:17 +00:00
Wilson Snyder 0c73b547f1 Fix bug introduced in 3.661 with parametrized defines.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1042 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-25 14:01:50 +00:00
Wilson Snyder 73c3d4bb50 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1041 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-25 12:17:12 +00:00
Wilson Snyder 77f063367a Change website references to veripool.org
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1040 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-25 12:16:55 +00:00
Wilson Snyder 8e812058cb Change website references to veripool.org
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1039 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-25 12:14:27 +00:00
Wilson Snyder 506c36beed Fix ranges on gate primitive instantiations
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1038 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-25 11:48:18 +00:00
Wilson Snyder 0110f0193e Allow /**/ comments in -f option files.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1037 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-24 15:36:46 +00:00
Wilson Snyder 7b870f4b2a Remove old unused vlint script
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1036 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-24 15:14:40 +00:00
Wilson Snyder aa2630f837 Ignore old standard(ish) Verilog-XL defines
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1035 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-24 15:04:01 +00:00
Wilson Snyder e137e93f94 Support optional argument to and .
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1034 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-24 14:32:39 +00:00
Wilson Snyder 215bdfccc2 Use GCC 4 compiler builtins for XORs
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1033 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-24 14:26:01 +00:00
Wilson Snyder 956a0a9c99 Add Verilog 2005 () function.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1032 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-24 13:52:51 +00:00
Wilson Snyder ab83717b7d Fix internal error when params get non-constants. [Johan Wouters]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1031 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-17 15:47:16 +00:00
Wilson Snyder 61e876e4bf Add bookmarks to pdf, and fix date
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1030 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-16 21:52:23 +00:00
Wilson Snyder 9ca3dbc140 Allow defines terminated in EOF, though against spec. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1029 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-15 19:12:25 +00:00
Wilson Snyder a02e2e25bb Fix "always @ ((a) or (b))" syntax error. [by Niranjan Prabhu]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1028 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-14 21:47:39 +00:00
Wilson Snyder a9281f2c37 Fix "output reg name=expr;" syntax error. [Martin Scharrer]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1027 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-14 21:10:34 +00:00
Wilson Snyder 95395a8b87 Fix multiple .v files being read in random order. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1026 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-09 14:17:03 +00:00
Wilson Snyder ecdbd72fa1 Add error message when modules have duplicate names.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1025 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-09 13:56:40 +00:00
Wilson Snyder 3a2f8224e4 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1022 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-04 18:30:51 +00:00
Wilson Snyder 15841fe5f6 Support functions with input
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1021 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-04 18:29:33 +00:00
Wilson Snyder 7e5a7b65a0 Unsized concatenates now give WIDTHCONCAT warnings.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1020 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-02 12:53:53 +00:00
Wilson Snyder 549bf876e4 Ignore delays attached to gate UDPs. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1019 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-04-01 19:26:06 +00:00
Wilson Snyder bd60cf12f8 Match Verilog-Perl: Fix parse error on min:typ:max delay pairs
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1018 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-31 21:03:56 +00:00
Wilson Snyder 61fbab1910 Fix internal error after MSB < LSB error reported to user. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1017 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-31 14:09:52 +00:00
Wilson Snyder 957f495314 Fix task output pin connected to non-variables.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1016 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-28 21:55:23 +00:00
Wilson Snyder 280eb48ba4 Add --language option for supporting older code. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1015 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-28 20:41:21 +00:00
Wilson Snyder ebe5711b40 The --enable-defenv configure option added in 3.660 is now the default.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1014 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-28 19:42:14 +00:00
Wilson Snyder a16477d84f Fix SystemVerilog parameterized defines and whitespace
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1013 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-27 13:21:49 +00:00
Wilson Snyder f6fb2362c6 Fix dropping of backslash quoted-quote at end of .
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1012 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-26 14:58:30 +00:00
Wilson Snyder 170427bba1 Fix r1010; bad prefix default
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1011 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-26 14:53:53 +00:00
Wilson Snyder 93531e520a Add --top-module option to select between multiple tops. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1010 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-25 19:57:41 +00:00
Wilson Snyder aa2db8fdde Fix no-module include files on command line. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1009 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-25 13:42:48 +00:00
Wilson Snyder 7c3c2af90b Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1006 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-23 13:58:27 +00:00
Wilson Snyder 6dca9b4ba4 Add graph dfa complementing; not used yet.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1005 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-23 13:56:06 +00:00
Wilson Snyder ede37bb9d8 Allow assigns to create implicit wires
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1004 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-20 01:40:22 +00:00
Wilson Snyder 4a1729eaab Allow __ in cell names by quoting them in C.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1003 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-20 01:16:33 +00:00
Wilson Snyder b1565f5b89 Add --error-limit option
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1002 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-20 00:14:26 +00:00
Wilson Snyder 4fb8dcfd4e Convert re-defining macro error to warning.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1001 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-19 15:05:08 +00:00
Wilson Snyder 16d1f2b835 Allow multiple .v files on command line. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1000 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-19 14:22:05 +00:00
Wilson Snyder 73594e5aa5 Fix definitions in main file.v, referenced in library. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@999 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-19 00:44:54 +00:00
Wilson Snyder c0a365bd34 With --enable-defenv, support for hard-coding VERILATOR_ROOT etc in the executables
git-svn-id: file://localhost/svn/verilator/trunk/verilator@998 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-18 20:26:37 +00:00
Wilson Snyder 45940ff820 Move most env vars from wrapper to verilator_bin, and wrap in accessor
functions.  The functionallity should be mostly the same as before, except
allow verilator_bin to be in the search-path and VERILATOR_ROOT not set.


git-svn-id: file://localhost/svn/verilator/trunk/verilator@997 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-18 15:21:13 +00:00
Wilson Snyder d545ae242c Fix assignments to inputs inside functions/tasks. [Patricio Kaplan]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@996 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-18 12:41:59 +00:00
Wilson Snyder e862aaf2e1 Fix genvar to be signed, so "< 0" works properly. [Niranjan Prabhu]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@995 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-17 20:58:43 +00:00
Wilson Snyder 30c3540086 Fix compile error in some oses
git-svn-id: file://localhost/svn/verilator/trunk/verilator@992 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-02-25 13:55:06 +00:00
Wilson Snyder 663a084ca4 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@989 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-02-20 16:55:43 +00:00
Wilson Snyder b4d9ccd9af Fix assignments of {a,b,c} = {c,b,a}
git-svn-id: file://localhost/svn/verilator/trunk/verilator@988 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-02-20 16:54:41 +00:00
Wilson Snyder 98fff6a4ce Fix parsing of always @(*)
git-svn-id: file://localhost/svn/verilator/trunk/verilator@987 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-02-14 02:08:10 +00:00
Wilson Snyder 4977a5e1d9 Fix parse error on output reg signed
git-svn-id: file://localhost/svn/verilator/trunk/verilator@986 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-02-08 18:38:47 +00:00
Wilson Snyder e4297486ef Avoid creating obj_dir with --lint-only
git-svn-id: file://localhost/svn/verilator/trunk/verilator@985 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-01-31 14:49:27 +00:00
Wilson Snyder ad591767c9 Make obj_dir only when needed, and use OS calls rather than system to clean up
git-svn-id: file://localhost/svn/verilator/trunk/verilator@984 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-01-31 13:50:06 +00:00
706 changed files with 8834 additions and 3125 deletions
+1 -1
View File
@@ -7,7 +7,7 @@
*.1 *.1
*.tmp *.tmp
*.tex *.tex
Makefile /Makefile
README README
config.cache config.cache
config.status config.status
+173 -2
View File
@@ -3,6 +3,179 @@ 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.671 2008/09/19
** SystemC uint64_t pins are now the default instead of sc_bv<64>.
Use --no-pins64 for backward compatibility.
*** Support SystemVerilog "cover property" statements.
*** When warnings are disabled on signals that are flattened out, disable
the warnings on the signal(s) that replace it.
*** Add by-design and by-module subtotals to verilator_profcfunc.
*** Fix extra evaluation of pure combo blocks in SystemC output.
**** Add IMPERFECTSCH warning, disabled by default.
**** Support coverage under SystemPerl 1.285 and newer.
**** Fix stack overflow on large ? : trees. [John Sanguinetti]
**** Support arbitrary characters in identifiers. [Stephane Laurent]
* Verilator 3.670 2008/07/23
** Add --x-assign=fast option, and make it the default.
This chooses performance over reset debugging. See the manual.
** Add --autoflush, for flushing streams after $display. [Steve Tong]
** Add CASEWITHX lint warning and if disabled fix handling of casez with Xs.
*** Add $feof, $fgetc, $fgets, $fflush, $fscanf, $sscanf. [Holger Waechtler]
*** Add $stime. [Holger Waechtler]
*** Add $random.
*** Add --Wfuture-, for improving forward compatibility.
**** Fix verilator_includer not being installed properly. [Holger Waechtler]
**** Fix IMPURE errors due to X-assignment temporary variables. [Steve Tong]
**** Fix "lvalue" errors with public functions; bug25. [CY Wang]
**** Add WIDTH warning to $fopen etc file descriptors.
**** Internal changes to how $displays get compiled and executed.
* Verilator 3.665 2008/06/25
**** Ignore "// verilator" comments alone on endif lines. [Rodney Sinclair]
**** "Make install" now installs verilator_includer and verilator_profcfunc.
**** Fix tracing missing changes on undriven public wires. [Rodney Sinclair]
**** Fix syntax error when "`include `defname" is ifdefed. [John Dickol]
**** Fix error when macro call has commas in concatenate. [John Dickol]
**** Fix compile errors under Fedora 9, GCC 4.3.0. [by Jeremy Bennett]
**** Fix Makefile to find headers/libraries under prefix. [by Holger Waechtler]
* Verilator 3.664 2008/05/08
**** Fix missing file in kit.
* Verilator 3.663 2008/05/07
**** Add DESTDIR to Makefiles to assist RPM construction. [Gunter Dannoritzer]
**** Fix compiler warnings under GCC 4.2.1.
**** Fix preprocessor `else after series of `elsif. [Mark Nodine]
**** Fix parametrized defines calling define with comma. [Joshua Wise]
**** Fix comma separated list of primitives. [by Bryan Brady]
* Verilator 3.662 2008/04/25
*** Add Verilog 2005 $clog2() function.
This is useful in calculating bus-widths from parameters.
*** Support /**/ comments in -f option files. [Stefan Thiede]
**** Add error message when modules have duplicate names. [Stefan Thiede]
**** Support defines terminated in EOF, though against spec. [Stefan Thiede]
**** Support optional argument to $finish and $stop. [by Stefan Thiede]
**** Support ranges on gate primitive instantiations. [Stefan Thiede]
**** Ignore old standard(ish) Verilog-XL defines. [by Stefan Thiede]
**** Fix "always @ ((a) or (b))" syntax error. [by Niranjan Prabhu]
**** Fix "output reg name=expr;" syntax error. [Martin Scharrer]
**** Fix multiple .v files being read in random order. [Stefan Thiede]
**** Fix internal error when params get non-constants. [Johan Wouters]
**** Fix bug introduced in 3.661 with parametrized defines.
* Verilator 3.661 2008/04/04
*** The --enable-defenv configure option added in 3.660 is now the default.
This hard-codes a default for VERILATOR_ROOT etc in the executables.
*** Add --language option for supporting older code. [Stefan Thiede]
*** Add --top-module option to select between multiple tops. [Stefan Thiede]
*** Unsized concatenates now give WIDTHCONCAT warnings. [Jonathan Kimmitt]
Previously they threw fatal errors, which in most cases is correct
according to spec, but can be incorrect in presence of parameter values.
**** Support functions with "input integer". [Johan Wouters]
**** Ignore delays attached to gate UDPs. [Stefan Thiede]
**** Fix SystemVerilog parameterized defines with `` expansion,
and fix extra whitespace inserted on substitution. [Vladimir Matveyenko]
**** Fix no-module include files on command line. [Stefan Thiede]
**** Fix dropping of backslash quoted-quote at end of $display.
**** Fix task output pin connected to non-variables. [Jonathan Kimmitt]
**** Fix missing test_v in install datadir. [Holger Waechtler]
**** Fix internal error after MSB < LSB error reported to user. [Stefan Thiede]
* Verilator 3.660 2008/03/23
*** Add support for hard-coding VERILATOR_ROOT etc in the executables,
to enable easier use of Verilator RPMs. [Gunter Dannoritzer]
*** Allow multiple .v files on command line. [Stefan Thiede]
*** Convert re-defining macro error to warning. [Stefan Thiede]
*** Add --error-limit option. [Stefan Thiede]
*** Allow __ in cell names by quoting them in C. [Stefan Thiede]
**** Fix genvar to be signed, so "< 0" works properly. [Niranjan Prabhu]
**** Fix assignments to inputs inside functions/tasks. [Patricio Kaplan]
**** Fix definitions in main file.v, referenced in library. [Stefan Thiede]
**** Fix undefined assigns to be implicit warnings. [Stefan Thiede]
* Verilator 3.658 2008/02/25
**** Fix unistd compile error in 3.657. [Patricio Kaplan, Jonathan Kimmitt]
* Verilator 3.657 2008/02/20
**** Fix assignments of {a,b,c} = {c,b,a}. [Jonathan Kimmitt]
**** Fix Perl warning with --lint-only. [by Ding Xiaoliang]
**** Avoid creating obj_dir with --lint-only. [Ding Xiaoliang]
**** Fix parsing of always @(*). [Patricio Kaplan]
* Verilator 3.656 2008/01/18 * Verilator 3.656 2008/01/18
**** Wide VL_CONST_W_#X functions are now made automatically. [Bernard Deadman] **** Wide VL_CONST_W_#X functions are now made automatically. [Bernard Deadman]
@@ -1128,8 +1301,6 @@ of input ports exists for tracing.
**** First code written. **** First code written.
---------------------------------------------------------------------- ----------------------------------------------------------------------
$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].
+28
View File
@@ -0,0 +1,28 @@
^CVS/
/CVS/
\.git/
\.svn/
\.(bak|old)/
\.(bak|old)$
\bMakefile$
\.tar\.
.*\.tgz
.*\.log
.*\.tmp
.*\.tex
.*\.key
.*\.vcd
/obj_dir/
/obj_dbg/
/obj_opt/
/INCA_libs/
/cov_work/
/logs/
Makefile
src/Makefile_obj
include/verilated.mk
config.cache
config.status
verilator_bin.*
autom4te\.cache/
nodist/
+80 -40
View File
@@ -1,24 +1,23 @@
# $Id$
#***************************************************************************** #*****************************************************************************
# DESCRIPTION: Verilator top level: Makefile pre-configure version # DESCRIPTION: Verilator top level: Makefile pre-configure version
# #
# This file is part of Verilator. # This file is part of Verilator.
# #
# Author: Wilson Snyder <[email protected]> # Author: Wilson Snyder <[email protected]>
# #
# Code available from: http://www.veripool.com/verilator # Code available from: http://www.veripool.org/verilator
# #
#***************************************************************************** #*****************************************************************************
# #
# Copyright 2003-2008 by Wilson Snyder. This program is free software; you can # Copyright 2003-2008 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.
# #
# 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
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
#****************************************************************************/ #****************************************************************************/
# #
# make all to compile and build Verilator. # make all to compile and build Verilator.
@@ -38,7 +37,7 @@
# source and built the program without creating any other files, # source and built the program without creating any other files,
# `make distclean' should leave only the files that were in the # `make distclean' should leave only the files that were in the
# distribution. # distribution.
# #
# make maintainer-clean # make maintainer-clean
# Delete everything from the current directory that can be # Delete everything from the current directory that can be
# reconstructed with this Makefile. This typically includes # reconstructed with this Makefile. This typically includes
@@ -61,6 +60,9 @@ MAKEINFO = makeinfo
TEXI2DVI = texi2dvi TEXI2DVI = texi2dvi
PERL = @PERL@ PERL = @PERL@
# Destination prefix for RPMs
DESTDIR =
#### Don't edit: You're much better using configure switches to set these #### Don't edit: You're much better using configure switches to set these
prefix = @prefix@ prefix = @prefix@
exec_prefix = @exec_prefix@ exec_prefix = @exec_prefix@
@@ -78,8 +80,12 @@ datadir = @datadir@
infodir = @infodir@ infodir = @infodir@
# Directory in which to install package specific files # Directory in which to install package specific files
# Generally ${prefix}/share/verilator
pkgdatadir = @pkgdatadir@ pkgdatadir = @pkgdatadir@
# Directory in which to install data across multiple architectures
datarootdir = @datarootdir@
#### End of system configuration section. #### #### End of system configuration section. ####
###################################################################### ######################################################################
@@ -94,26 +100,34 @@ DISTDEP = info Makefile
# Files to distribute. # Files to distribute.
DISTBIN = $(wildcard bin/verilator-*) DISTBIN = $(wildcard bin/verilator-*)
DISTFILES_INC = $(INFOS) .cvsignore COPYING *.in *.ac \ DISTFILES_INC = $(INFOS) .gitignore COPYING *.in *.ac \
Changes README TODO \ Changes README TODO \
MANIFEST.SKIP \
bin/* \ bin/* \
install-sh configure mkinstalldirs *.texi \ install-sh configure mkinstalldirs *.texi \
include/verilated.[chv]* \ include/verilated.[chv]* \
include/verilatedos.[chv]* \ include/verilatedos.[chv]* \
include/*.in \ include/*.in \
src/.cvsignore src/*.in src/*.cpp src/*.[chly] src/astgen src/flexfix \ include/.*ignore \
.*attributes */.*attributes */*/.*attributes \
src/.*ignore src/*.in src/*.cpp src/*.[chly] src/astgen src/bisonpre src/*fix \
src/*.pl \ src/*.pl \
test_*/.cvsignore test_*/Makefile* test_*/*.cpp \ test_*/.*ignore test_*/Makefile* test_*/*.cpp \
test_*/*.pl test_*/*.v test_*/*.vc test_*/vlint \ test_*/*.pl test_*/*.v test_*/*.vc test_*/vlint \
test_verilated/vgen*.pl \ test_verilated/vgen*.pl \
test_regress/t/*.v* \ test_regress/t/*.cpp \
test_regress/t/*.pl \ test_regress/t/*.h \
test_regress/t/*.dat \
test_regress/t/*.mem \
test_regress/t/*.out \ test_regress/t/*.out \
test_regress/t/*.pl \
test_regress/t/*.v* \
verilator.* \ verilator.* \
INST_PROJ_FILES = \ INST_PROJ_FILES = \
bin/verilator \ bin/verilator \
bin/verilator_includer \ bin/verilator_includer \
bin/verilator_profcfunc \
include/verilated.[chv]* \ include/verilated.[chv]* \
include/verilated.mk \ include/verilated.mk \
include/verilatedos.[chv]* \ include/verilatedos.[chv]* \
@@ -124,8 +138,10 @@ INST_PROJ_BIN_FILES = \
DISTFILES := $(DISTFILES_INC) DISTFILES := $(DISTFILES_INC)
VL_INST_MAN_FILES = verilator.1
all: all_nomsg msg_test all: all_nomsg msg_test
all_nomsg: verilator_exe all_nomsg: verilator_exe $(VL_INST_MAN_FILES)
.PHONY:verilator_exe .PHONY:verilator_exe
verilator_exe verilator_bin verilator_bin_dbg: verilator_exe verilator_bin verilator_bin_dbg:
@@ -140,6 +156,7 @@ msg_test:
@echo "Type 'make test' to test." @echo "Type 'make test' to test."
@echo @echo
.PHONY:test
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
test: test_vcs test_c test_sc test_sp test_verilated test_regress test: test_vcs test_c test_sc test_sp test_verilated test_regress
else else
@@ -184,16 +201,18 @@ verilator.html: bin/verilator
verilator.pdf: bin/verilator $(DISTCONFIG) verilator.pdf: bin/verilator $(DISTCONFIG)
pod2latex --full --out verilator.tex bin/verilator pod2latex --full --out verilator.tex bin/verilator
cat < verilator.tex \ cat < verilator.tex \
| sed 's/\\begin{document}/\\usepackage[left=1.7in,right=1.7in,top=1.3in,bottom=1.3in]{geometry}\n\\begin{document}/' \
| sed 's/\\begin{document}/\\usepackage[pdftex,bookmarks=true,bookmarksnumbered=true,hypertexnames=false,breaklinks=true,linkbordercolor={0 0 1}]{hyperref}\n\\begin{document}/' \
| sed 's/\\begin{document}/\\usepackage{fancyhdr} \\pagestyle{fancy}\n\\begin{document}/' \ | sed 's/\\begin{document}/\\usepackage{fancyhdr} \\pagestyle{fancy}\n\\begin{document}/' \
| sed 's/\\begin{document}/\\setlength{\\parindent}{0pt} \\setlength{\\parskip}{\\baselineskip}\n\\begin{document}/' \ | sed 's/\\begin{document}/\\setlength{\\parindent}{0pt} \\setlength{\\parskip}{\\baselineskip}\n\\begin{document}/' \
| sed 's/\\begin{document}/\\title{$(DISTTITLE)} \\date{${DISTDATE}} \\author{Wilson Snyder\\\\ http:\/\/www.veripool.com}\n\\begin{document}/' \ | sed 's/\\begin{document}/\\title{$(DISTTITLE)} \\date{${DISTDATE}} \\author{Wilson Snyder\\\\ http:\/\/www.veripool.org}\n\\begin{document}/' \
| sed 's/\\begin{document}/\\lhead[$(DISTTITLE)]{$(DISTTITLE)}\n\\begin{document}/' \ | sed 's/\\begin{document}/\\lhead[$(DISTTITLE)]{$(DISTTITLE)}\n\\begin{document}/' \
| sed 's/\\tableofcontents/\\begin{titlepage} \\maketitle \\end{titlepage}\n\\tableofcontents/' \ | sed 's/\\tableofcontents/\\begin{titlepage} \\maketitle \\end{titlepage}\n\\tableofcontents/' \
> verilator2.tex > verilator2.tex
mv verilator2.tex verilator.tex mv verilator2.tex verilator.tex
pdflatex verilator.tex pdflatex verilator.tex
pdflatex verilator.tex pdflatex verilator.tex
-rm -f verilator.toc verilator.aux verilator.idx -rm -f verilator.toc verilator.aux verilator.idx verilator.out
INSTALL: install.texi INSTALL: install.texi
$(MAKEINFO) -I$(srcdir) $(srcdir)/install.texi --output=$@ \ $(MAKEINFO) -I$(srcdir) $(srcdir)/install.texi --output=$@ \
@@ -203,21 +222,37 @@ README: readme.texi
$(MAKEINFO) -I$(srcdir) $(srcdir)/readme.texi --output=$@ \ $(MAKEINFO) -I$(srcdir) $(srcdir)/readme.texi --output=$@ \
--no-headers --no-validate --no-headers --no-validate
installdirs:
$(SHELL) ${srcdir}/mkinstalldirs $(bindir) $(infodir)
# See uninstall also # See uninstall also
VL_INST_BIN_FILES = verilator VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg \
verilator_includer verilator_profcfunc
# Some scripts go into both the search path and pkgdatadir,
# so they can be found by the user, and under $VERILATOR_ROOT.
installbin: installbin:
( cd bin ; $(INSTALL_PROGRAM) verilator $(bindir)/verilator ) $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir)
( cd bin ; $(INSTALL_PROGRAM) verilator $(DESTDIR)$(bindir)/verilator )
( cd bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(bindir)/verilator_includer )
( cd bin ; $(INSTALL_PROGRAM) verilator_profcfunc $(DESTDIR)$(bindir)/verilator_profcfunc )
( $(INSTALL_PROGRAM) verilator_bin $(DESTDIR)$(bindir)/verilator_bin )
( $(INSTALL_PROGRAM) verilator_bin_dbg $(DESTDIR)$(bindir)/verilator_bin_dbg )
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/bin
( cd bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer )
VL_INST_MAN_FILES = verilator.1
installman: installman:
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(mandir)/man1
for p in $(VL_INST_MAN_FILES) ; do \ for p in $(VL_INST_MAN_FILES) ; do \
$(INSTALL_PROGRAM) $$p $(mandir)/man1/$$p; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(mandir)/man1/$$p; \
done done
install: all_nomsg installdirs installbin installman install-msg installdata:
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples
cp -r include $(DESTDIR)$(pkgdatadir)
cp -r test_c $(DESTDIR)$(pkgdatadir)/examples
cp -r test_sc $(DESTDIR)$(pkgdatadir)/examples
cp -r test_sp $(DESTDIR)$(pkgdatadir)/examples
cp -r test_v $(DESTDIR)$(pkgdatadir)/examples
VL_INST_DATA_FILES = verilator.1
install: all_nomsg installbin installman installdata install-msg
install-here: installman ftp install-here: installman ftp
@@ -232,8 +267,8 @@ install-project: dist
for p in verilator.1 ; do \ for p in verilator.1 ; do \
$(INSTALL_PROGRAM) -m 0666 $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \ $(INSTALL_PROGRAM) -m 0666 $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \
done done
$(INST_PROJ_CVS) $(DISTNAME).tar.gz $(DIRPROJECT)/hw/utils/verilator/verilator.tgz $(INST_PROJ_CVS) $(DISTNAME).tgz $(DIRPROJECT)/hw/utils/verilator/verilator.tgz
rm $(DISTNAME).tar.gz rm $(DISTNAME).tgz
install-project-quick: install-project-quick:
@echo "Install-project-quick (no strip) to $(DIRPROJECT)" @echo "Install-project-quick (no strip) to $(DIRPROJECT)"
@@ -246,9 +281,6 @@ install-project-quick:
endif endif
ftp: info ftp: info
echo "http://www.veripool.com/verilator3.html"
cp verilator.html verilator_man.html
ftp_tree --password $(VERIPOOL_PW) --user $(VERIPOOL_USER) verilator_man.html webftp.veripool.com:/web
install-msg: install-msg:
@echo "Installed!" @echo "Installed!"
@@ -261,8 +293,9 @@ install-msg:
@echo @echo
uninstall: uninstall:
-cd $(mandir)/man1 && rm -f $(VL_INST_MAN_FILES) -cd $(DESTDIR)$(mandir)/man1 && rm -f $(VL_INST_MAN_FILES)
-cd $(bindir) && rm -f $(VL_INST_BIN_FILES) -cd $(DESTDIR)$(bindir) && rm -f $(VL_INST_BIN_FILES)
-rm -f $(DESTDIR)$(pkgdatadir)
# autoheader might not change config_build.h.in, so touch a stamp file. # autoheader might not change config_build.h.in, so touch a stamp file.
IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in ${srcdir}/*/*/*.in \ IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in ${srcdir}/*/*/*.in \
@@ -287,7 +320,7 @@ configure: configure.ac
maintainer-clean:: maintainer-clean::
@echo "This command is intended for maintainers to use;" @echo "This command is intended for maintainers to use;"
@echo "rebuilding the deleted files requires makeinfo." @echo "rebuilding the deleted files requires makeinfo."
rm -f *.info* $(INFOS) faq.html verilator.html configure bin/* rm -f *.info* $(INFOS) faq.html verilator.html configure
clean mostlyclean distclean maintainer-clean maintainer-copy:: clean mostlyclean distclean maintainer-clean maintainer-copy::
for dir in $(SUBDIRS); do \ for dir in $(SUBDIRS); do \
@@ -296,7 +329,7 @@ clean mostlyclean distclean maintainer-clean maintainer-copy::
done done
clean mostlyclean distclean maintainer-clean:: clean mostlyclean distclean maintainer-clean::
rm -f $(SCRIPTS) *.tmp rm -f $(SCRIPTS) *.tmp
rm -f *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys *.log rm -f *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys *.log
rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs *.idx rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs *.idx
rm -f *.ev *.evs *.ov *.ovs *.cv *.cvs *.ma *.mas rm -f *.ev *.evs *.ov *.ovs *.cv *.cvs *.ma *.mas
@@ -312,6 +345,13 @@ TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/[a-z]*.in \
TAGS: $(TAGFILES) TAGS: $(TAGFILES)
etags $(TAGFILES) etags $(TAGFILES)
######################################################################
# Test targets
dist-file-list:
@echo "begin-dist-file-list:"; # Scripts look for this
@echo $(wildcard $(DISTFILES))
@echo "end-dist-file-list:"; # Scripts look for this
###################################################################### ######################################################################
# Distributions # Distributions
@@ -320,7 +360,7 @@ DISTCONFIG = src/config_build.h.in
DISTTITLE := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e 's/v/V/' -e q $(DISTCONFIG)) DISTTITLE := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e 's/v/V/' -e q $(DISTCONFIG))
DISTNAME := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e q $(DISTCONFIG)) DISTNAME := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e q $(DISTCONFIG))
DISTDATEPRE := $(shell sed -e '/DTVERSION/!d' -e 's/.*\([0-3]\?[0-9].[0-3]\?[0-9].[1-2][0-9][0-9][0-9]\).*/\1/' -e q $(DISTCONFIG)) DISTDATEPRE := $(shell sed -e '/DTVERSION/!d' -e 's/.*\([1-2][0-9][0-9][0-9].[0-9]*[0-9].[0-9]*[0-9]\).*/\1/' -e q $(DISTCONFIG))
DISTTAGNAME := $(subst .,_,$(subst -,_,$(DISTNAME))) DISTTAGNAME := $(subst .,_,$(subst -,_,$(DISTNAME)))
DISTDATE := $(subst /,-,$(DISTDATEPRE)) DISTDATE := $(subst /,-,$(DISTDATEPRE))
@@ -339,14 +379,14 @@ dist: $(DISTDEP) maintainer-copy
chmod -R a+r $(DISTNAME) chmod -R a+r $(DISTNAME)
tar chf $(DISTNAME).tar $(DISTNAME) tar chf $(DISTNAME).tar $(DISTNAME)
gzip --force --best $(DISTNAME).tar gzip --force --best $(DISTNAME).tar
mv $(DISTNAME).tar.gz $(DISTNAME).tgz
rm -fr $(DISTNAME) rm -fr $(DISTNAME)
maintainer-diff: maintainer-diff:
svnorcvs diff $(DISTTAGNAME) svnorcvs diff $(DISTTAGNAME)
preexist: preexist:
test ! -r ~/src/kits/$(DISTNAME).tar.gz svnorcvs nexists $(DISTTAGNAME)
maintainer-dist: preexist dist tag maintainer-dist: preexist dist tag
cp *.gz ~/backpack svnorcvs release $(DISTNAME).tgz
cp *.gz ~/src/kits
+12 -9
View File
@@ -1,4 +1,3 @@
// $Id$
// DESCRIPTION: Verilator: List of To Do issues. // DESCRIPTION: Verilator: List of To Do issues.
// //
// Copyright 2004-2008 by Wilson Snyder. This program is free software; you can // Copyright 2004-2008 by Wilson Snyder. This program is free software; you can
@@ -7,7 +6,7 @@
Features: Features:
Finish 3.400 new ordering fixes Finish 3.400 new ordering fixes
Latch optimizations {Need here} Latch optimizations {Need here}
Task I/Os connecting to non-simple variables. Task I/Os connecting to non-simple variables.
Fix nested casez statements expanding into to huge C++. [JeanPaul Vanitegem] Fix nested casez statements expanding into to huge C++. [JeanPaul Vanitegem]
@@ -50,7 +49,11 @@ Testing:
Usability: Usability:
Better reporting of unopt problems, including what lines of code Better reporting of unopt problems, including what lines of code
Report more errors (all of them?) before exiting [Eugene Weber] Report more errors (all of them?) before exiting [Eugene Weber]
Internal Code:
Eliminate the AstNUser* passed to all visitors; its only needed in V3Width,
and removing it will speed up and simplify all the other code.
Performance: Performance:
Constant propagation Constant propagation
@@ -65,7 +68,7 @@ Performance:
Multithreaded execution Multithreaded execution
Bit-multiply for faster bit swapping and a=b[1,3,2] random bit reorderings. Bit-multiply for faster bit swapping and a=b[1,3,2] random bit reorderings.
Move _last sets and all other combo logic inside master Move _last sets and all other combo logic inside master
if() that triggers on all possible sense items if() that triggers on all possible sense items
Rewrite and combine V3Life, V3Subst Rewrite and combine V3Life, V3Subst
If block temp only ever set in one place to constant, propagate it If block temp only ever set in one place to constant, propagate it
Used in t_mem for array delayed assignments Used in t_mem for array delayed assignments
@@ -135,15 +138,15 @@ Selectable SystemC types based on widths (see notes below)
c) a conditional whose possible values are (a) or (b) c) a conditional whose possible values are (a) or (b)
2) One can lose that fact that a node is a tristate node. This happens 2) One can lose that fact that a node is a tristate node. This happens
if a tristate node is assigned to a 'standard' node, or is used on if a tristate node is assigned to a 'standard' node, or is used on
RHS of a conditional. The following infer tristate signals: RHS of a conditional. The following infer tristate signals:
a) inout <SIGNAL> a) inout <SIGNAL>
b) tri <SIGNAL> b) tri <SIGNAL>
c) assigning to 'Z' (maybe through a conditional) c) assigning to 'Z' (maybe through a conditional)
Note: tristate-ness of an output port determined only by Note: tristate-ness of an output port determined only by
statements in the module (not the instances it calls) statements in the module (not the instances it calls)
4) Tristate variables can't be multidimensional arrays 4) Tristate variables can't be multidimensional arrays
5) Only check tristate contention between modules (not within!) 5) Only check tristate contention between modules (not within!)
6) Only simple compares with 'Z' are allowed (===) 6) Only simple compares with 'Z' are allowed (===)
+269 -122
View File
@@ -1,7 +1,6 @@
: # -*-Mode: perl;-*- use perl, wherever it is : # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}' eval 'exec perl -wS $0 ${1+"$@"}'
if 0; if 0;
# $Id$
###################################################################### ######################################################################
# #
# Copyright 2003-2008 by Wilson Snyder. This program is free software; you can # Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
@@ -34,27 +33,7 @@ use Config;
use Cwd qw(abs_path getcwd); use Cwd qw(abs_path getcwd);
use strict; use strict;
use vars qw ($Debug %Vars $Opt $Opt_Make_Dir $Opt_Sp @Opt_Verilator_Sw use vars qw ($Debug @Opt_Verilator_Sw);
$Opt_Trace
%Modules
);
#######################################################################
# Global constants -- Configuration info
# Where to find real executables
# We could find it by using $RealBin, but we require this path
# so that when the user runs make, they will have it and not get strange error.
$ENV{VERILATOR_ROOT} or die "%Error: verilator: VERILATOR_ROOT needs to be in environment\n";
print "export VERILATOR_ROOT=$ENV{VERILATOR_ROOT}\n" if $Debug;
# Read by verilator for populating makefile
if (!defined $ENV{SYSTEMC_ARCH}) {
$ENV{SYSTEMC_ARCH} ||= (($Config{osname} =~ /solaris/i && "gccsparcOS5")
|| ($Config{osname} =~ /cygwin/i && "cygwin")
|| "linux");
print "export SYSTEMC_ARCH=$ENV{SYSTEMC_ARCH}\n" if $Debug;
}
####################################################################### #######################################################################
####################################################################### #######################################################################
@@ -65,7 +44,6 @@ autoflush STDERR 1;
$Debug = 0; $Debug = 0;
my $opt_gdb; my $opt_gdb;
$Opt_Sp = undef;
# No arguments can't do anything useful. Give help # No arguments can't do anything useful. Give help
if ($#ARGV < 0) { if ($#ARGV < 0) {
@@ -84,33 +62,15 @@ if (! GetOptions (
# Major operating modes # Major operating modes
"help" => \&usage, "help" => \&usage,
"debug:s" => \&debug, "debug:s" => \&debug,
"version!" => \&version, # "version!" => \&version, # Also passthru'ed
# Switches # Switches
"gdb=s" => \$opt_gdb, # Undocumented debugging "gdb=s" => \$opt_gdb, # Undocumented debugging
"trace!" => \$Opt_Trace,
"sp!" => sub {$Opt_Sp = 'sp';},
"sc!" => sub {$Opt_Sp = 'sc';},
"cc!" => sub {$Opt_Sp = 0;},
#"ignc!" => ..., # Undocumented debugging, disable $c but don't complain
# Additional parameters # Additional parameters
"<>" => sub {}, # Ignored "<>" => sub {}, # Ignored
)) { )) {
pod2usage(-exitstatus=>2, -verbose=>0); pod2usage(-exitstatus=>2, -verbose=>0);
} }
# Check configuration
if ($Opt_Sp) {
(defined $ENV{SYSTEMC}) or die "%Error: verilator: Need \$SYSTEMC in environment\nProbably System-C isn't installed, see http://www.systemc.org\n";
}
if ($Opt_Sp eq 'sp' || $Opt_Trace) {
if (!defined $ENV{SYSTEMPERL}) {
my $try = "$ENV{W}/hw/utils/perltools/SystemC";
$ENV{SYSTEMPERL} = $try if -d $try;
}
(defined $ENV{SYSTEMPERL}) or die "%Error: verilator: Need \$SYSTEMPERL in environment for --sp or --trace\nProbably System-Perl isn't installed, see http://www.veripool.com/systemperl.html\n";
(-d "$ENV{SYSTEMPERL}/src") or die "%Error: verilator: \$SYSTEMPERL environment var doesn't seem to point to System-Perl kit\n";
}
# Determine runtime flags # Determine runtime flags
my $vcmd =(($opt_gdb?"$opt_gdb ":"") my $vcmd =(($opt_gdb?"$opt_gdb ":"")
.verilator_bin() .verilator_bin()
@@ -123,8 +83,6 @@ run ($vcmd);
#---------------------------------------------------------------------- #----------------------------------------------------------------------
sub usage { sub usage {
bin_version();
print '$Revision$$Date$ ', "\n";
pod2usage(-exitstatus=>2, -verbose=>2); pod2usage(-exitstatus=>2, -verbose=>2);
} }
@@ -134,23 +92,16 @@ sub debug {
$Debug = $level||3; $Debug = $level||3;
} }
sub version {
bin_version();
exit (0);
}
sub bin_version {
($ENV{VERILATOR_ROOT}) or print "%Warning: Unknown rev: VERILATOR_ROOT undefined\n";
run (verilator_bin()." --version");
}
####################################################################### #######################################################################
####################################################################### #######################################################################
# Builds # Builds
sub verilator_bin { sub verilator_bin {
my $bin = "$ENV{VERILATOR_ROOT}/".($ENV{VERILATOR_BIN}||"verilator_bin"); my $bin = "";
if ($Debug && -x "${bin}_dbg") { $bin = "${bin}_dbg"; } # Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
$bin .= $ENV{VERILATOR_ROOT}."/" if defined($ENV{VERILATOR_ROOT});
$bin .= ($ENV{VERILATOR_BIN}
|| ($Debug ? "verilator_bin_dbg" : "verilator_bin"));
return $bin; return $bin;
} }
@@ -165,8 +116,11 @@ sub run {
system($command); system($command);
my $status = $?; my $status = $?;
if ($status) { if ($status) {
if ($! =~ /no such file or directory/i) {
warn "%Error: verilator: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
}
if ($Debug) { # For easy rerunning if ($Debug) { # For easy rerunning
warn "%Error: export VERILATOR_ROOT=$ENV{VERILATOR_ROOT}\n"; warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
warn "%Error: $command\n"; warn "%Error: $command\n";
} }
die "%Error: Command Failed $command\n"; die "%Error: Command Failed $command\n";
@@ -205,7 +159,7 @@ code, lints it, and optionally adds coverage and waveform tracing code.
For C++ and SystemC formats, it outputs .cpp and .h files. For SystemPerl For C++ and SystemC formats, it outputs .cpp and .h files. For SystemPerl
format, it outputs .sp files for the SystemPerl preprocessor, which greatly format, it outputs .sp files for the SystemPerl preprocessor, which greatly
simplifies writing SystemC code and is available at simplifies writing SystemC code and is available at
L<http://www.veripool.com>. L<http://www.veripool.org>.
The files created by Verilator are then compiled with C++. The user writes The files created by Verilator are then compiled with C++. The user writes
a little C++ wrapper file, which instantiates the top level module, and a little C++ wrapper file, which instantiates the top level module, and
@@ -223,6 +177,7 @@ descriptions in the next sections for more information.
{file.c/cc/cpp} Optional C++ files to link in {file.c/cc/cpp} Optional C++ files to link in
--assert Enable all assertions --assert Enable all assertions
--autoflush Flush streams after all $displays
--bin <filename> Override Verilator binary --bin <filename> Override Verilator binary
--cc Create C++ output --cc Create C++ output
--compiler <compiler-name> Tune for specified C++ compiler --compiler <compiler-name> Tune for specified C++ compiler
@@ -234,24 +189,26 @@ descriptions in the next sections for more information.
--debug-check Enable debugging assertions --debug-check Enable debugging assertions
--dump-tree Enable dumping .tree files --dump-tree Enable dumping .tree files
-E Preprocess, but do not compile -E Preprocess, but do not compile
--error-limit <value> Abort after this number of errors
--exe Link to create executable --exe Link to create executable
-f <file> Parse options from a file -f <file> Parse options from a file
--help Display this help. --help Display this help.
-I<dir> Directory to search for includes -I<dir> Directory to search for includes
--inhibit-sim Create function to turn off sim --inhibit-sim Create function to turn off sim
--inline-mult <value> Tune module inlining --inline-mult <value> Tune module inlining
--language <lang> Language standard to parse
--lint-only Lint, but do not make output --lint-only Lint, but do not make output
--MMD Create .d dependency files --MMD Create .d dependency files
--MP Create phony dependency targets --MP Create phony dependency targets
--Mdir <directory> Name of output object directory --Mdir <directory> Name of output object directory
--mod-prefix <topname> Name to prepend to lower classes --mod-prefix <topname> Name to prepend to lower classes
--no-pins64 Don't use uint64_t's for 33-64 bit sigs
--no-skip-identical Disable skipping identical output --no-skip-identical Disable skipping identical output
-O0 Disable optimizations -O0 Disable optimizations
-O3 High performance optimizations -O3 High performance optimizations
-O<optimization-letter> Selectable optimizations -O<optimization-letter> Selectable optimizations
--output-split <bytes> Split .cpp files into pieces --output-split <bytes> Split .cpp files into pieces
--output-split-cfuncs <statements> Split .ccp functions --output-split-cfuncs <statements> Split .ccp functions
--pins64 Use uint64_t's for 33-64 bit sigs
--prefix <topname> Name of top level class --prefix <topname> Name of top level class
--profile-cfuncs Name functions for profiling --profile-cfuncs Name functions for profiling
--private Debugging; see docs --private Debugging; see docs
@@ -260,12 +217,14 @@ descriptions in the next sections for more information.
--sc Create SystemC output --sc Create SystemC output
--sp Create SystemPerl output --sp Create SystemPerl output
--stats Create statistics file --stats Create statistics file
--top-module <topname> Name of top level input module
--trace Enable waveform creation --trace Enable waveform creation
--trace-depth <levels> Depth of tracing --trace-depth <levels> Depth of tracing
-U<var> Undefine preprocessor define -U<var> Undefine preprocessor define
--underline-zero Zero signals with leading _'s --underline-zero Zero signals with leading _'s
-v <filename> Verilog library -v <filename> Verilog library
-Werror-<message> Convert warning to error -Werror-<message> Convert warning to error
-Wfuture-<message> Disable unknown message warnings
-Wno-<message> Disable warning -Wno-<message> Disable warning
-x-assign <mode> Initially assign Xs to this value -x-assign <mode> Initially assign Xs to this value
-y <dir> Directory to search for modules -y <dir> Directory to search for modules
@@ -295,6 +254,14 @@ linking with make rules you write yourself.
Enable all assertions, includes enabling the --psl flag. (If psl is not Enable all assertions, includes enabling the --psl flag. (If psl is not
desired, but other assertions are, use --assert --nopsl.) desired, but other assertions are, use --assert --nopsl.)
See also --x-assign; setting "--x-assign unique" may be desirable.
=item --autoflush
After every $display or $fdisplay, flush the output stream. This insures
that messages will appear immediately but may reduce performance. Defaults
off, which will buffer output as provided by the normal C stdio calls.
=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
@@ -329,7 +296,7 @@ functions to avoid error C1061.
=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.
=item --coverage-line =item --coverage-line
@@ -341,10 +308,6 @@ 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.
After running multiple tests, the vcoverage utility (from the SystemPerl
package) is executed. Vcoverage reads the logs/coverage.pl file(s), and
creates an annotated source code listing showing code coverage details.
Verilator automatically disables coverage of branches that have a $stop in Verilator automatically disables coverage of branches that have a $stop in
them, as it is assumed $stop branches contain an error check that should them, as it is assumed $stop branches contain an error check that should
not occur. A /*verilator coverage_block_off*/ comment will perform a not occur. A /*verilator coverage_block_off*/ comment will perform a
@@ -354,10 +317,6 @@ Note Verilator may over-count combinatorial (non-clocked) blocks when those
blocks receive signals which have had the UNOPTFLAT warning disabled; for blocks receive signals which have had the UNOPTFLAT warning disabled; for
most accurate results do not disable this warning when using coverage. most accurate results do not disable this warning when using coverage.
For an example, after running 'make test' in the Verilator distribution,
see the test_sp/logs/coverage_source directory. Grep for lines starting
with '%' to see what lines Verilator believes need more coverage.
=item --coverage-user =item --coverage-user
Enables user inserted functional coverage. Currently, all functional Enables user inserted functional coverage. Currently, all functional
@@ -392,6 +351,11 @@ Preprocess the source code, but do not compile, as with 'gcc -E'. Output
is written to standard out. Beware of enabling debugging messages, as they is written to standard out. Beware of enabling debugging messages, as they
will also go to standard out. will also go to standard out.
=item --error-limit <value>
After this number of errors or warnings are encountered, exit. Defaults to
50.
=item --exe =item --exe
Generate a executable. You will also need to pass additional .cpp files on Generate a executable. You will also need to pass additional .cpp files on
@@ -417,6 +381,14 @@ values, or a value <= 1 will inline everything, will lead to longer compile
times, but potentially faster runtimes. This setting is ignored for very times, but potentially faster runtimes. This setting is ignored for very
small modules; they will always be inlined, if allowed. small modules; they will always be inlined, if allowed.
=item --language I<value>
Select the language to be used when first processing each Verilog file.
The language value must be "1364-1995", "1364-2001", "1364-2001",
"1364-2005", or "1800-2005". This should only be used for legacy code, as
the preferable option is to edit the code to repair new keywords, or add
appropriate `begin_keywords.
=item --lint-only =item --lint-only
Check the files for lint violations only, do not create any other output. Check the files for lint violations only, do not create any other output.
@@ -434,13 +406,19 @@ to gcc -MP option.
=item --Mdir I<directory> =item --Mdir I<directory>
Specifies the name of the Make object directory. All generated files will Specifies the name of the Make object directory. All generated files will
be placed in this directory. be placed in this directory. If not specified, "obj_dir" is used.
=item --mod-prefix I<topname> =item --mod-prefix I<topname>
Specifies the name to prepend to all lower level classes. Defaults to Specifies the name to prepend to all lower level classes. Defaults to
the same as --prefix. the same as --prefix.
=item --no-pins64
Specifies SystemC outputs of 33-64 bits wide should use sc_bv's instead of
uint64_t's. Uint64's are faster, but sc_bvs were the default until
Verilator 3.671.
=item --no-skip-identical =item --no-skip-identical
Rarely needed. Disables skipping execution of Verilator if all source Rarely needed. Disables skipping execution of Verilator if all source
@@ -482,15 +460,11 @@ operations, a new function will be created. With --output-split, this will
enable GCC to compile faster, at a small loss in performance that increases enable GCC to compile faster, at a small loss in performance that increases
with smaller statement values. with smaller statement values.
=item --pins64
Specifies SystemC outputs of 33-64 bits wide should use uint64_t instead of
the backward-compatible default of sc_bv's.
=item --prefix I<topname> =item --prefix I<topname>
Specifies the name of the top level class. Defaults to the name of the top Specifies the name of the top level class and makefile. Defaults to V
level Verilog module. prepended to the name of the --top-module switch, or V prepended to the
first Verilog filename passed on the command line.
=item --profile-cfuncs =item --profile-cfuncs
@@ -536,11 +510,22 @@ Specifies SystemPerl output mode; see also --cc and -sc.
Creates a dump file with statistics on the design in {prefix}__stats.txt. Creates a dump file with statistics on the design in {prefix}__stats.txt.
=item --top-module I<topname>
When the input Verilog contains more than one top level module, specifies
the name of the top level Verilog module to become the top, and sets the
default for if --prefix is not used. This is not needed with standard
designs with only one top.
=item --trace =item --trace
Adds waveform tracing code to the model, this will create additional Adds waveform tracing code to the model. Verilator will generate
{prefix}__Trace*.cpp files you will need to add to your Makefiles, if additional {prefix}__Trace*.cpp files that will need to be compiled. In
you're not using the ones generated for you. addition Sp.cpp (for SystemC traces) or SpTraceVcdC.c (for C++ only) from
the SystemPerl kit's src directory must be compiled and linked in. If
using the Verilator generated Makefiles, these will be added as source
targets for you. If you're not using the Verilator makefiles, you will
need to add these to your Makefile manually.
Having tracing compiled in may result in some small performance losses, Having tracing compiled in may result in some small performance losses,
even when waveforms are not turned on during model execution. even when waveforms are not turned on during model execution.
@@ -565,6 +550,14 @@ Convert the specified warning message into a error message. This is
generally to discourage users from violating important site-wide rules, for generally to discourage users from violating important site-wide rules, for
example C<-Werror-NOUNOPTFLAT>. example C<-Werror-NOUNOPTFLAT>.
=item -Wfuture-I<message>
Suppress unknown Verilator comments or warning messages with the given
message code. This is used to allow code written with pragmas for a later
version of Verilator to run under a older version; add -Wfuture- arguments
for each message code or comment that the new version supports which the
older version does not support.
=item -Wno-I<message> =item -Wno-I<message>
Disable the specified warning message. Disable the specified warning message.
@@ -572,26 +565,34 @@ Disable the specified warning message.
=item -Wno-lint =item -Wno-lint
Disable all lint related warning messages. This is equivelent to Disable all lint related warning messages. This is equivelent to
"-Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX -Wno-CMPCONST "-Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX -Wno-CASEWITHX
-Wno-IMPLICIT -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED -Wno-VARHIDDEN -Wno-CMPCONST -Wno-IMPLICIT -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED
-Wno-WIDTH". -Wno-VARHIDDEN -Wno-WIDTH".
It is strongly recommended you cleanup your code rather than using this It is strongly recommended you cleanup your code rather than using this
option, it is only intended to be use when running test-cases of code option, it is only intended to be use when running test-cases of code
received from third parties. received from third parties.
=item -Wwarn-I<message>
Enables the specified warning message.
=item -x-assign 0 =item -x-assign 0
=item -x-assign 1 =item -x-assign 1
=item -x-assign unique (default) =item -x-assign fast (default)
=item -x-assign unique
Controls the two-state value that is replaced when an assignment to X is Controls the two-state value that is replaced when an assignment to X is
encountered. -x-assign=0 converts all Xs to 0s, this is the fastest. encountered. -x-assign=fast, the default, converts all Xs to whatever is
-x-assign=1 converts all Xs to 1s, this is nearly as fast, but more likely best for performance. -x-assign=0 converts all Xs to 0s, and is also fast.
to find reset bugs as active high logic will fire. The default, -x-assign=1 converts all Xs to 1s, this is nearly as fast as 0, but more
-x-assign=func will call a function to determine the value, this allows likely to find reset bugs as active high logic will fire. -x-assign=unique
randomization of all Xs and is the slowest, but safest. will call a function to determine the value, this allows randomization of
all Xs to find reset bugs and is the slowest, but safest for finding reset
bugs in code.
=back =back
@@ -765,10 +766,10 @@ the test_sp directory in the distribution for an example.
=head1 BENCHMARKING & OPTIMIZATION =head1 BENCHMARKING & OPTIMIZATION
For best performance, run Verilator with the "-O3 -x-assign=0 --noassert" For best performance, run Verilator with the "-O3 -x-assign=fast
flags. The -O3 flag will require longer compile times, and -x-assign=0 may --noassert" flags. The -O3 flag will require longer compile times, and
increase the risk of reset bugs in trade for performance; see the above -x-assign=fast may increase the risk of reset bugs in trade for
documentation for these flags. performance; see the above documentation for these flags.
Minor Verilog code changes can also give big wins. You should not have any Minor Verilog code changes can also give big wins. You should not have any
UNOPTFLAT warnings from Verilator. Fixing these warnings can result in UNOPTFLAT warnings from Verilator. Fixing these warnings can result in
@@ -871,14 +872,16 @@ After running Make, the C++ compiler should produce the following:
Required for SystemC output mode. If set, specifies the directory Required for SystemC output mode. If set, specifies the directory
containing the SystemC distribution. This is used to find the SystemC containing the SystemC distribution. This is used to find the SystemC
include files. include files. If not specified, it will come from a default optionally
specified at configure time (before Verilator was compiled).
=item SYSTEMC_ARCH =item SYSTEMC_ARCH
Specifies the architecture name used by the SystemC kit. This is the part Specifies the architecture name used by the SystemC kit. This is the part
after the dash in the lib-{...} directory name created by a 'make' in the after the dash in the lib-{...} directory name created by a 'make' in the
SystemC distribution. If not set, Verilator will try to intuit the proper SystemC distribution. If not set, Verilator will try to intuit the proper
setting. setting, or use the default optionally specified at configure time (before
Verilator was compiled). .
=item SYSTEMC_CXX_FLAGS =item SYSTEMC_CXX_FLAGS
@@ -888,7 +891,9 @@ building the SystemC model.
=item SYSTEMPERL =item SYSTEMPERL
Specifies the directory containing the Verilog-Perl distribution kit. This Specifies the directory containing the Verilog-Perl distribution kit. This
is used to find the Verilog-Perl library and include files. is used to find the Verilog-Perl library and include files. If not
specified, it will come from a default optionally specified at configure
time (before Verilator was compiled).
=item VCS_HOME =item VCS_HOME
@@ -904,7 +909,9 @@ for debugging and selecting between multiple operating system builds.
=item VERILATOR_ROOT =item VERILATOR_ROOT
Specifies the directory containing the distribution kit. This is used to Specifies the directory containing the distribution kit. This is used to
find the executable, Perl library, and include files. find the executable, Perl library, and include files. If not specified, it
will come from a default optionally specified at configure time (before
Verilator was compiled).
=back =back
@@ -929,7 +936,7 @@ example:
unsigned int main_time = 0; // Current simulation time unsigned int main_time = 0; // Current simulation time
double sc_time_stamp () { // Called by $time in Verilog double sc_time_stamp () { // Called by $time in Verilog
return main_time; return main_time;
} }
int main() { int main() {
@@ -971,7 +978,7 @@ following type conversions: Pins of a single bit become bool, unless they
are marked with `systemc_clock, in which case they become sc_clock's (for are marked with `systemc_clock, in which case they become sc_clock's (for
SystemC 1.2, not needed in SystemC 2.0). Pins 2-32 bits wide become SystemC 1.2, not needed in SystemC 2.0). Pins 2-32 bits wide become
uint32_t's. Pins 33-64 bits wide become sc_bv's or uint64_t's depending on uint32_t's. Pins 33-64 bits wide become sc_bv's or uint64_t's depending on
the -pins64 switch. Wider pins become sc_bv's. the --no-pins64 switch. Wider pins become sc_bv's.
Lower modules are not pure SystemC code. This is a feature, as using the Lower modules are not pure SystemC code. This is a feature, as using the
SystemC pin interconnect scheme everywhere would reduce performance by an SystemC pin interconnect scheme everywhere would reduce performance by an
@@ -1017,6 +1024,8 @@ declarations inside port lists.
Verilator supports the `begin_keywords and `end_keywords compiler Verilator supports the `begin_keywords and `end_keywords compiler
directives. directives.
Verilator supports $clog2.
Verilator partially supports the uwire keyword. Verilator partially supports the uwire keyword.
=head1 SYSTEMVERILOG (IEEE 1800-2005) SUPPORT =head1 SYSTEMVERILOG (IEEE 1800-2005) SUPPORT
@@ -1034,7 +1043,8 @@ always_ff, always_latch, do-while, and final.
It also supports .name and .* interconnection. It also supports .name and .* interconnection.
Verilator partially supports assert. Verilator partially supports concurrent assert and cover statements; see
the enclosed coverage tests for the syntax which is allowed.
=head1 SUGAR/PSL SUPPORT =head1 SUGAR/PSL SUPPORT
@@ -1308,10 +1318,9 @@ Wide variables over 64 bits cannot be function returns, to avoid exposing
complexities. However, wide variables can be input/outputs; they will be complexities. However, wide variables can be input/outputs; they will be
passed as references to an array of 32 bit numbers. passed as references to an array of 32 bit numbers.
This feature is still somewhat experimental. Generally, only the values of Generally, only the values of stored state (flops) should be written, as
stored state (flops) should be written, as the model will NOT notice the model will NOT notice changes made to variables in these functions.
changes made to variables in these functions. (Same as when a signal is (Same as when a signal is declared public.)
declared public.)
=item /*verilator public_flat*/ (variable) =item /*verilator public_flat*/ (variable)
@@ -1545,8 +1554,8 @@ Verilator does not perform warning checking on uwires, it treats the uwire
keyword as if it were the normal wire keyword. keyword as if it were the normal wire keyword.
=item $bits, $countones, $error, $fatal, $finish, $info, $isunknown, =item $bits, $countones, $error, $fatal, $finish, $info, $isunknown,
$onehot, $onehot0, $readmemb, $readmemh, $signed, $stop, $time, $unsigned, $onehot, $onehot0, $readmemb, $readmemh, $signed, $stime, $stop, $time,
$warning. $unsigned, $warning.
Generally supported. Generally supported.
@@ -1560,7 +1569,11 @@ argument (as with C's printf), you cannot simply list variables standalone.
The sized display functions are rarely used and so not supported. Replace The sized display functions are rarely used and so not supported. Replace
them with a $write with the appropriate format specifier. them with a $write with the appropriate format specifier.
=item $fopen, $fclose, $fdisplay, $fwrite =item $finish, $stop
The rarely used optional parameter to $finish and $stop is ignored.
=item $fopen, $fclose, $fdisplay, $feof, $fflush, $fgetc, $fgets, $fscanf, $fwrite
File descriptors passed to the file PLI calls must be file descriptors, not File descriptors passed to the file PLI calls must be file descriptors, not
MCDs, which includes the mode parameter to $fopen being mandatory. MCDs, which includes the mode parameter to $fopen being mandatory.
@@ -1570,11 +1583,22 @@ are 32 bits while FILE*s may be 64 bits, the descriptor must be stored in a
reg [63:0] rather than an integer. The define `verilator_file_descriptor in reg [63:0] rather than an integer. The define `verilator_file_descriptor in
verilated.v can be used to hide this difference. verilated.v can be used to hide this difference.
=item $fscanf, $sscanf
Only integer formats are supported; %e, %f, %m, %r, %v, and %z are not
supported.
=item $fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal, =item $fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal,
$setup, $setuphold, $skew, $timeskew, $width $setup, $setuphold, $skew, $timeskew, $width
All specify blocks and timing checks are ignored. All specify blocks and timing checks are ignored.
=item $random
$random does not support the optional argument to set the seed. Use the
srand function in C to accomplish this, and note there is only one random
number generator (not one per module).
=item $readmemb, $readmemh =item $readmemb, $readmemh
Read memory commands should work properly. Note Verilator and the Verilog Read memory commands should work properly. Note Verilator and the Verilog
@@ -1659,6 +1683,16 @@ L<http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_
Ignoring this warning will only suppress the lint check, it will simulate Ignoring this warning will only suppress the lint check, it will simulate
correctly. correctly.
=item CASEWITHX
Warns that a case statement contains a constant with a C<x>. Verilator is
two-state so interpret such items as always false. Note a common error is
to use a C<X> in a case or casez statement item; often what the user
instead insteaded is to use a casez with C<?>.
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.
@@ -1692,6 +1726,13 @@ additional ones.)
Ignoring this warning may make Verilator simulations differ from other Ignoring this warning may make Verilator simulations differ from other
simulators. simulators.
=item IMPERFECTSCH
Warns that the scheduling of the model is not absolutely perfect, and some
manual code edits may result in faster performance. This warning defaults
to off, and must be turned on explicitly before the top module statement is
processed.
=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
@@ -1699,7 +1740,7 @@ output from a sub-module.) While legal in Verilog, implicit declarations
only work for single bit wide signals (not buses), do not allow using a only work for single bit wide signals (not buses), do not allow using a
signal before it is implicitly declared by a cell, and can lead to dangling 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.org/>
Ignoring this warning will only suppress the lint check, it will simulate Ignoring this warning will only suppress the lint check, it will simulate
correctly. correctly.
@@ -1733,6 +1774,23 @@ 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 unique file by the same name. Otherwise, make sure all library files are
read in as libraries with -v, instead of automatically with -y. read in as libraries with -v, instead of automatically with -y.
=item REDEFMACRO
Warns that you have redefined the same macro with a different value, for
example:
`define MACRO def1
//...
`define MACRO otherdef
The best solution is to use a different name for the second macro. If this
is not possible, add a undef to indicate the code is overriding the value:
`define MACRO def1
//...
`undef MACRO
`define MACRO otherdef
=item STMTDLY =item STMTDLY
Warns that you have a statement with a delayed time in front of it, for Warns that you have a statement with a delayed time in front of it, for
@@ -1890,6 +1948,24 @@ The best fix, which clarifies intent and will also make all tools happy is:
Ignoring this warning will only suppress the lint check, it will simulate Ignoring this warning will only suppress the lint check, it will simulate
correctly. correctly.
=item WIDTHCONCAT
Warns that based on width rules of Verilog, a concatenate or replication
has a undeterminate width. In most cases this violates the Verilog rule
that widths inside concatenates and replicates must be sized, and should be
fixed in the code.
wire [63:0] concat = {1,2};
An example where this is technically legal (though still bad form) is:
parameter PAR = 1;
wire [63:0] concat = {PAR,PAR};
The correct fix is to either size the 1 ("32'h1"), or add the width to the
parameter definition ("parameter [31:0]"), or add the width to the
parameter usage ("{PAR[31:0],PAR[31:0]}".
=back =back
The following describes the less obvious errors: The following describes the less obvious errors:
@@ -1943,11 +2019,14 @@ Visual C++ Version 7 or newer, but this is not tested by the author.
=item Can you provide binaries? =item Can you provide binaries?
At this time I'd prefer to get patches out quickly than have to generate Verilator is available as a RPM for SuSE and perhaps other systems; this is
myriad binaries for many different OS flavors. People have generally done by porters and may slightly lag the primary distribution. If there
requested binaries when they are having problems with their C++ isn't a binary build for your distribution, how about you set one up?
compiler. Alas, binaries won't help this, as in the end a fully working C++ Please contact the authors for assistance.
compiler is required to compile the output of Verilator.
Note people sometimes request binaries when they are having problems with
their C++ compiler. Alas, binaries won't help this, as in the end a fully
working C++ compiler is required to compile the output of Verilator.
=item How can it be faster than (name-the-simulator)? =item How can it be faster than (name-the-simulator)?
@@ -2017,6 +2096,24 @@ Verilator makes standard VCD (Value Change Dump) files. They are viewable
with the public domain Dinotrace or GtkWave programs, or any of the many with the public domain Dinotrace or GtkWave programs, or any of the many
commercial offerings. commercial offerings.
=item How do I do coverage analysis?
Verilator supports both block (line) coverage and user inserted functional
coverage. First, run verilator with the --coverage option. If you're
using your own makefile, compile the model with the GCC flag
-DSP_COVERAGE_ENABLE (if using Verilator's, it will do this for you.)
Run your tests in different directories. Each test will create a
logs/coverage.pl file.
After running all of your tests, the vcoverage utility (from the SystemPerl
package) is executed. Vcoverage reads the logs/coverage.pl file(s), and
creates an annotated source code listing showing code coverage details.
For an example, after running 'make test' in the Verilator distribution,
see the test_sp/logs/coverage_source directory. Grep for lines starting
with '%' to see what lines Verilator believes need more coverage.
=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
@@ -2030,15 +2127,24 @@ the "verilator" define for you, so just wrap the code in a ifndef region:
=item Why do I get "unexpected `do'" or "unexpected `bit'" errors? =item Why do I get "unexpected `do'" or "unexpected `bit'" errors?
Do, bit, ref, and other words are now SystemVerilog keywords. You should Do, bit, ref, return, and other words are now SystemVerilog keywords. You
change your code to not use them to insure it works with newer tools. should change your code to not use them to insure it works with newer
Alternatively, surround them by the Verilog 2005/SystemVerilog tools. Alternatively, surround them by the Verilog 2005/SystemVerilog
begin_keywords pragma to indicate Verilog 2001 code. begin_keywords pragma to indicate Verilog 2001 code.
`begin_keywords "1364-2001" `begin_keywords "1364-2001"
integer bit; initial bit = 1; integer bit; initial bit = 1;
`end_keywords `end_keywords
If you want the whole file to be parsed as Verilog 2001, just create a
file with
`begin_keywords "1364-2001"
and add it before other Verilog files on the command line. (Note this will
also change the default for --prefix, so if you're not using --prefix, you
will now need to.)
=item How do I prevent my assertions from firing during reset? =item How do I prevent my assertions from firing during reset?
Call Verilated::assertOn(false) before you first call the model, then turn Call Verilated::assertOn(false) before you first call the model, then turn
@@ -2078,7 +2184,7 @@ use GCC 2.95, or GCC 3.4 you'll have faster builds. Two ways to cheat are
to compile on parallel machines and avoid compilations altogether. See the to compile on parallel machines and avoid compilations altogether. See the
--output-split option, and the web for the ccache, distcc and icecream --output-split option, and the web for the ccache, distcc and icecream
packages, and the Make::Cache package available from packages, and the Make::Cache package available from
L<http://www.veripool.com/>. Make::Cache will skip GCC runs between L<http://www.veripool.org/>. Make::Cache will skip GCC runs between
identical source builds, even across different users. identical source builds, even across different users.
=item Why do so many files need to recompile when I add a signal? =item Why do so many files need to recompile when I add a signal?
@@ -2088,11 +2194,49 @@ uses one large symbol table, as that results in 2-3 less assembly
instructions for each signal access. This makes the execution time 10-15% instructions for each signal access. This makes the execution time 10-15%
faster, but can result in more compilations when something changes. faster, but can result in more compilations when something changes.
=item How do I access functions/tasks in C?
Write a Verilog function or task with input/outputs that match what you
want to call in with C. Then mark that function public.
Verilog inputs of one bit become C++ bool inputs. Inputs 32 bits or
smaller become C uint32_t inputs, 64-32 bits become C uint64_t inputs, and
wider signals become arrays of 32 bits. Outputs are passed as references
to bool, uint32_t, uint64_t or uint32_t[] arrays.
Signals wider than 64 bits are passed as an array of 32-bit uint32_t's.
Thus to read bits 31:0, access signal[0], and for bits 63:32, access
signal[1]. Unused bits (for example bit numbers 65-96 of a 65 bit vector)
will always be zero. if you change the value you must make sure to pack
zeros in the unused bits or core-dumps may result. (Because Verilator
strips array bound checks where it believes them to be unnecessary.)
In the SYSTEMC example above, if you had in our.v:
task publicSetBool;
// verilator public
input in_bool;
var_bool = in_bool;
endtask
From the sc_main.cpp file, you'd then:
#include "Vour.h"
#include "Vour_our.h"
top->v->publicSetBool(value);
See additional notes under the /*verilator public*/ section.
=item How do I access signals in C? =item How do I access signals in C?
First, declare the signals you will be accessing with a /*verilator The best thing is to make a Verilator public task or function accessor that
public*/ comment before the closing semicolon. Then scope into the C++ can read or write that signal, as described in the previous FAQ. This will
class to read the value of the signal, as you would any other member variable. allow Verilator to better optimize the model.
If you really want raw access to the signals, declare the signals you will
be accessing with a /*verilator public*/ comment before the closing
semicolon. Then scope into the C++ class to read the value of the signal,
as you would any other member variable.
Signals are the smallest of 8 bit chars, 16 bit shorts, 32 bit longs, or 64 Signals are the smallest of 8 bit chars, 16 bit shorts, 32 bit longs, or 64
bit long longs that fits the width of the signal. Generally, you can use bit long longs that fits the width of the signal. Generally, you can use
@@ -2114,7 +2258,7 @@ From the sc_main.cpp file, you'd then:
#include "Vour.h" #include "Vour.h"
#include "Vour_our.h" #include "Vour_our.h"
cout << "clock is " << top->v.clk << endl; cout << "clock is " << top->v->clk << endl;
In this example, clk is a bool you can read or set as any other variable. In this example, clk is a bool you can read or set as any other variable.
The value of normal signals may be set, though clocks shouldn't be changed The value of normal signals may be set, though clocks shouldn't be changed
@@ -2163,7 +2307,10 @@ outputs. Now, the following should fail:
cd test_regress cd test_regress
t/t_BUG.pl t/t_BUG.pl
Finally, Mail the bug report to C<[email protected]>. Finally, report the bug using the bug tracker at
L<http://www.veripool.org/verilator>. The bug will become publicly
visible; if this is unacceptable, mail the bug report to
C<[email protected]>.
=head1 HISTORY =head1 HISTORY
@@ -2216,7 +2363,7 @@ Eugene Weber, Leon Wildman, and Mat Zeno.
=head1 DISTRIBUTION =head1 DISTRIBUTION
The latest version is available from L<http://www.veripool.com/>. The latest version is available from L<http://www.veripool.org/>.
Copyright 2003-2008 by Wilson Snyder. Verilator is free software; you can Copyright 2003-2008 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
+2 -4
View File
@@ -1,7 +1,6 @@
: # -*-Mode: perl;-*- use perl, wherever it is : # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}' eval 'exec perl -wS $0 ${1+"$@"}'
if 0; if 0;
# $Id$
###################################################################### ######################################################################
# #
# Copyright 2005-2008 by Wilson Snyder <[email protected]>. This # Copyright 2005-2008 by Wilson Snyder <[email protected]>. This
@@ -115,7 +114,6 @@ sub filter {
#---------------------------------------------------------------------- #----------------------------------------------------------------------
sub usage { sub usage {
print '$Id$ ', "\n";
pod2usage(-verbose=>2, -exitval => 2); pod2usage(-verbose=>2, -exitval => 2);
exit (1); exit (1);
} }
@@ -130,7 +128,7 @@ sub parameter {
$Opt_A = $param; $Opt_A = $param;
} elsif (!defined $Opt_B) { } elsif (!defined $Opt_B) {
$Opt_B = $param; $Opt_B = $param;
} else { } else {
die "%Error: Unknown parameter: $param\n"; die "%Error: Unknown parameter: $param\n";
} }
} }
@@ -178,7 +176,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION =head1 DISTRIBUTION
The latest version is available from L<http://www.veripool.com/>. The latest version is available from L<http://www.veripool.org/verilator>.
Copyright 2005-2008 by Wilson Snyder. This package is free software; you Copyright 2005-2008 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
-1
View File
@@ -1,7 +1,6 @@
: # -*-Mode: perl;-*- use perl, wherever it is : # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}' eval 'exec perl -wS $0 ${1+"$@"}'
if 0; if 0;
# $Id$
# DESCRIPTION: Print include statements for each ARGV # DESCRIPTION: Print include statements for each ARGV
# #
# Copyright 2003-2008 by Wilson Snyder. This program is free software; you can # Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
+44 -27
View File
@@ -1,19 +1,7 @@
: # -*-Mode: perl;-*- use perl, wherever it is : # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}' eval 'exec perl -wS $0 ${1+"$@"}'
if 0; if 0;
# $Id$ # See copyright, etc in below POD section.
######################################################################
#
# Copyright 2007-2008 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; require 5.006_001;
@@ -21,6 +9,7 @@ use warnings;
use Getopt::Long; use Getopt::Long;
use IO::File; use IO::File;
use Pod::Usage; use Pod::Usage;
eval { use Data::Dumper; $Data::Dumper::Indent = 1; }; # Debug, ok if missing
use strict; use strict;
use vars qw ($Debug); use vars qw ($Debug);
@@ -50,7 +39,6 @@ profcfunc($Opt_File);
#---------------------------------------------------------------------- #----------------------------------------------------------------------
sub usage { sub usage {
print '$Id$ ', "\n";
pod2usage(-verbose=>2, -exitval => 2); pod2usage(-verbose=>2, -exitval => 2);
exit (1); exit (1);
} }
@@ -63,7 +51,7 @@ sub parameter {
my $param = shift; my $param = shift;
if (!defined $Opt_File) { if (!defined $Opt_File) {
$Opt_File = $param; $Opt_File = $param;
} else { } else {
die "%Error: Unknown parameter: $param\n"; die "%Error: Unknown parameter: $param\n";
} }
} }
@@ -78,7 +66,8 @@ sub profcfunc {
my %funcs; my %funcs;
while (defined (my $line=$fh->getline())) { while (defined (my $line=$fh->getline())) {
if ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+.*\s+(\S+)\s*$/) { # %time cumesec selfsec calls {stuff} name
if ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$/) {
my $pct=$1; my $sec=$2; my $calls=$3; my $func=$4; my $pct=$1; my $sec=$2; my $calls=$3; my $func=$4;
$funcs{$func}{pct} += $pct; $funcs{$func}{pct} += $pct;
$funcs{$func}{sec} += $sec; $funcs{$func}{sec} += $sec;
@@ -88,47 +77,75 @@ sub profcfunc {
$fh->close; $fh->close;
# Find modules # Find modules
my %pointer_mods;
my %verilated_mods; my %verilated_mods;
foreach my $func (keys %funcs) { foreach my $func (keys %funcs) {
if ($func =~ /(.*)::_eval\(.*__Syms.*\)$/) { if ($func =~ /(.*)::_eval\(([a-zA-Z_0-9]+__Syms).*\)$/) {
$verilated_mods{$1} = qr/^$1/; $verilated_mods{$1} = qr/^$1/;
$pointer_mods{$2} = $1;
} }
} }
#print Dumper(\%pointer_mods, \%verilated_mods);
# Resort by Verilog name # Resort by Verilog name
my %vfuncs; my %vfuncs;
my %groups; my %groups;
foreach my $func (keys %funcs) { foreach my $func (keys %funcs) {
my $pct = $funcs{$func}{pct};
my $vfunc = $func; my $vfunc = $func;
my $design; my $design;
if ($func =~ /\(([a-zA-Z_0-9]+__Syms)/) {
$design = $pointer_mods{$1};
}
foreach my $vde (keys %verilated_mods) { foreach my $vde (keys %verilated_mods) {
last if $design;
if ($func =~ /$verilated_mods{$vde}/) { if ($func =~ /$verilated_mods{$vde}/) {
$design=$vde; $design=$vde;
last; last;
} }
} }
if ($vfunc =~ /__PROF__([a-zA-Z_0-9]+)__([0-9]+)\(/) { if ($vfunc =~ /__PROF__([a-zA-Z_0-9]+)__([0-9]+)\(/) {
$vfunc = sprintf("VBlock %s:%d", $1, $2); $vfunc = sprintf("VBlock %s:%d", $1, $2);
$groups{"Verilog Blocks under $design"} += $funcs{$func}{pct}; $groups{type}{"Verilog Blocks under $design"} += $pct;
$groups{design}{$design} += $pct;
$groups{module}{$1} += $pct;
} else { } else {
if ($design) { if ($design) {
$vfunc = sprintf("VCommon %s", $func); $vfunc = sprintf("VCommon %s", $func);
$groups{"Common code under $design"} += $funcs{$func}{pct}; $groups{type}{"Common code under $design"} += $pct;
$groups{design}{$design} += $pct;
$groups{module}{$design." common code"} += $pct;
} else { } else {
$vfunc = sprintf("C++ %s", $func); $vfunc = sprintf("C++ %s", $func);
$groups{'C++'} += $funcs{$func}{pct}; $groups{type}{'C++'} += $pct;
$groups{design}{'C++'} += $pct;
$groups{module}{'C++'} += $pct;
} }
} }
$vfuncs{$vfunc} = $funcs{$func}; $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");
foreach my $type qw(type design module) {
my $missing = 100;
foreach (sort (keys %{$groups{$type}})) {
$missing -= $groups{$type}{$_};
}
if ($missing) {
$groups{$type}{"\377Unaccounted for/rounding error"} = $missing;
}
print("Overall summary by $type:\n");
printf(" %-6s %s\n","% time",$type);
foreach my $what (sort (keys %{$groups{$type}})) {
(my $pwhat = $what) =~ s/^\377//; # Just used to establish sort order
printf(" %6.2f %s\n", $groups{$type}{$what}, $pwhat);
}
print("\n");
}
print("Verilog code profile:\n"); print("Verilog code profile:\n");
print(" These are split into three categories:\n"); print(" These are split into three categories:\n");
@@ -189,7 +206,7 @@ Displays this message and program version and exits.
=head1 DISTRIBUTION =head1 DISTRIBUTION
The latest version is available from L<http://www.veripool.com/>. The latest version is available from L<http://www.veripool.org/>.
Copyright 2007-2008 by Wilson Snyder. This package is free software; you Copyright 2007-2008 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
+19 -3
View File
@@ -1,20 +1,36 @@
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-2008 by Wilson Snyder. This program is free software; you can dnl Copyright 2003-2008 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.
AC_REVISION($Revision$)dnl
AC_INIT(src/Verilator.cpp) AC_INIT(src/Verilator.cpp)
AC_CONFIG_HEADER(src/config_build.h) AC_CONFIG_HEADER(src/config_build.h)
dnl Special Substitutions dnl Special Substitutions
AC_ARG_ENABLE(defenv,
[AS_HELP_STRING([--disable-defenv], [disable hardcoded default environment variables])],
CFG_WITH_DEFENV=$enableval,
CFG_WITH_DEFENV=yes)
AC_SUBST(CFG_WITH_DEFENV)
dnl Compiler flags
CXX=g++
CFLAGS=-I${includedir}
CPPFLAGS=-I${includedir}
CXXFLAGS=-I${includedir}
LDFLAGS=-L${libdir}
dnl Checks for programs. dnl Checks for programs.
CXX=g++
AC_PROG_CC AC_PROG_CC
AC_PROG_CXX AC_PROG_CXX
AC_PROG_INSTALL AC_PROG_INSTALL
AC_LANG_PUSH(C++)
AC_MSG_CHECKING([that C++ compiler can compile simple program])
AC_TRY_RUN([int main() { return 0; }],
AC_MSG_RESULT(yes),
AC_MSG_RESULT(no);AC_MSG_ERROR([a working C++ compiler is required]))
AC_PATH_PROG(PERL,perl) AC_PATH_PROG(PERL,perl)
if test "x$PERL" = "x" ; then if test "x$PERL" = "x" ; then
AC_MSG_ERROR([Cannot find "perl" in your PATH, please install it]) AC_MSG_ERROR([Cannot find "perl" in your PATH, please install it])
+484 -96
View File
@@ -1,4 +1,4 @@
// $Id$ -*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// //
// Copyright 2003-2008 by Wilson Snyder. This program is free software; you can // Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
@@ -9,7 +9,7 @@
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
//========================================================================= //=========================================================================
/// ///
/// \file /// \file
@@ -18,13 +18,12 @@
/// This file must be compiled and linked against all objects /// This file must be compiled and linked against all objects
/// created from Verilator. /// created from Verilator.
/// ///
/// Code available from: http://www.veripool.com/verilator /// Code available from: http://www.veripool.org/verilator
/// ///
//========================================================================= //=========================================================================
#include "verilated.h" #include "verilated.h"
#include <string.h> #include <cctype>
#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
@@ -80,23 +79,43 @@ IData VL_RAND32() {
#endif #endif
} }
IData VL_RAND_RESET_I(int outBits) { IData VL_RANDOM_I(int obits) {
return VL_RAND32() & VL_MASK_I(obits);
}
QData VL_RANDOM_Q(int obits) {
QData data = ((QData)VL_RAND32()<<VL_ULL(32)) | (QData)VL_RAND32();
return data & VL_MASK_Q(obits);
}
WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) {
for (int i=0; i<VL_WORDS_I(obits); i++) {
if (i<(VL_WORDS_I(obits)-1)) {
outwp[i] = VL_RAND32();
} else {
outwp[i] = VL_RAND32() & VL_MASK_I(obits);
}
}
return outwp;
}
IData VL_RAND_RESET_I(int obits) {
if (Verilated::randReset()==0) return 0; if (Verilated::randReset()==0) return 0;
IData data = ~0; IData data = ~0;
if (Verilated::randReset()!=1) { // if 2, randomize if (Verilated::randReset()!=1) { // if 2, randomize
data = VL_RAND32(); data = VL_RANDOM_I(obits);
} }
if (outBits<32) data &= VL_MASK_I(outBits); if (obits<32) data &= VL_MASK_I(obits);
return data; return data;
} }
QData VL_RAND_RESET_Q(int outBits) { QData VL_RAND_RESET_Q(int obits) {
if (Verilated::randReset()==0) return 0; if (Verilated::randReset()==0) return 0;
QData data = VL_ULL(~0); QData data = VL_ULL(~0);
if (Verilated::randReset()!=1) { // if 2, randomize if (Verilated::randReset()!=1) { // if 2, randomize
data = ((QData)VL_RAND32()<<VL_ULL(32)) | (QData)VL_RAND32(); data = VL_RANDOM_Q(obits);
} }
if (outBits<64) data &= VL_MASK_Q(outBits); if (obits<64) data &= VL_MASK_Q(obits);
return data; return data;
} }
@@ -119,94 +138,368 @@ WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) {
//=========================================================================== //===========================================================================
// Formatting // Formatting
const char* VL_VALUE_FORMATTED_Q(int obits, char fmt, bool drop0, QData ld) { // Do a va_arg returning a quad, assuming input argument is anything less than wide
// Convert value into %b/%o/%x/%s/%u/%d formatted string #define _VL_VA_ARG_Q(ap, bits) (((bits) <= VL_WORDSIZE) ? va_arg(ap,IData) : va_arg(ap,QData))
// Note uses a single buffer; presumes only one call per printf
static VL_THREAD char str[VL_VALUE_STRING_MAX_WIDTH]; void _vl_vsformat(string& output, const char* formatp, va_list ap) {
char* strp = &str[0]; // Format a Verilog $write style format into the output list
int lsb=obits-1; // The format must be pre-processed (and lower cased) by Verilator
if (drop0) while (lsb && !VL_BITISSET_Q(ld,lsb)) lsb--; // Arguments are in "width, arg-value (or WDataIn* if wide)" form
switch (fmt) { //
case 'd': // Note uses a single buffer internally; presumes only one usage per printf
sprintf(str,"%lld",(vlsint64_t)(VL_EXTENDS_QQ(obits,obits,ld))); // Note also assumes variables < 64 are not wide, this assumption is
return str; // sometimes not true in low-level routines written here in verilated.cpp
case 'u': static VL_THREAD char tmp[VL_VALUE_STRING_MAX_WIDTH];
sprintf(str,"%llu",ld); bool inPct = false;
return str; bool widthSet = false;
case 's': int width = 0;
for (; lsb>=0; lsb--) { const char* pos = formatp;
lsb = (lsb / 8) * 8; // Next digit for (; *pos; ++pos) {
IData charval = (ld>>VL_BITBIT_Q(lsb)) & 0xff; if (!inPct && pos[0]=='%') {
*strp++ = (charval==0)?' ':charval; inPct = true;
widthSet = false;
width = 0;
} else if (!inPct) { // Normal text
// Fast-forward to next escape and add to output
const char *ep = pos;
while (ep[0] && ep[0]!='%') ep++;
if (ep != pos) {
output += string(pos, ep-pos);
pos += ep-pos-1;
}
} else { // Format character
inPct = false;
char fmt = pos[0];
switch (fmt) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
inPct = true; // Get more digits
widthSet = true;
width = width*10 + (fmt - '0');
break;
case '%':
output += '%';
break;
case 'S': { // "C" string
const char* cstrp = va_arg(ap, const char*);
output += cstrp;
break;
}
default: {
// Deal with all read-and-print somethings
const int lbits = va_arg(ap, int);
QData ld = 0;
WDataInP lwp;
if (lbits <= VL_QUADSIZE) {
WData qlwp[2];
ld = _VL_VA_ARG_Q(ap, lbits);
VL_SET_WQ(qlwp,ld);
lwp = qlwp;
} else {
lwp = va_arg(ap,WDataInP);
ld = lwp[0];
if (fmt == 'u' || fmt == 'd') fmt = 'x'; // Not supported, but show something
}
int lsb=lbits-1;
if (widthSet && width==0) while (lsb && !VL_BITISSET_W(lwp,lsb)) lsb--;
switch (fmt) {
case 'c': {
IData charval = ld & 0xff;
output += charval;
break;
}
case 's':
for (; lsb>=0; lsb--) {
lsb = (lsb / 8) * 8; // Next digit
IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xff;
output += (charval==0)?' ':charval;
}
break;
case 'd': { // Signed decimal
int digits=sprintf(tmp,"%lld",(vlsint64_t)(VL_EXTENDS_QQ(lbits,lbits,ld)));
int needmore = width-digits;
if (needmore>0) output.append(needmore,' '); // Pre-pad spaces
output += tmp;
break;
}
case 'u': { // Unsigned decimal
int digits=sprintf(tmp,"%llu",ld);
int needmore = width-digits;
if (needmore>0) output.append(needmore,' '); // Pre-pad spaces
output += tmp;
break;
}
case 't': { // Time
int digits;
if (VL_TIME_MULTIPLIER==1) {
digits=sprintf(tmp,"%llu",ld);
} else if (VL_TIME_MULTIPLIER==1000) {
digits=sprintf(tmp,"%llu.%03llu",
(QData)(ld/VL_TIME_MULTIPLIER),
(QData)(ld%VL_TIME_MULTIPLIER));
} else {
vl_fatal(__FILE__,__LINE__,"","%%Error: Unsupported VL_TIME_MULTIPLIER");
}
int needmore = width-digits;
if (needmore>0) output.append(needmore,' '); // Pre-pad spaces
output += tmp;
break;
}
case 'b':
for (; lsb>=0; lsb--) {
output += ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) + '0';
}
break;
case 'o':
for (; lsb>=0; lsb--) {
lsb = (lsb / 3) * 3; // Next digit
// Octal numbers may span more than one wide word,
// so we need to grab each bit separately and check for overrun
// Octal is rare, so we'll do it a slow simple way
output += ('0'
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+0)) ? 1 : 0)
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+1)) ? 2 : 0)
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+2)) ? 4 : 0));
}
break;
case 'x':
for (; lsb>=0; lsb--) {
lsb = (lsb / 4) * 4; // Next digit
IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xf;
output += "0123456789abcdef"[charval];
}
break;
default:
string msg = string("%%Error: Unknown _vl_vsformat code: ")+pos[0]+"\n";
vl_fatal(__FILE__,__LINE__,"",msg.c_str());
break;
} // switch
}
} // switch
} }
*strp++ = '\0';
return str;
case 'b':
for (; lsb>=0; lsb--) {
*strp++ = ((ld>>VL_BITBIT_Q(lsb)) & 1) + '0';
}
*strp++ = '\0';
return str;
case 'o':
for (; lsb>=0; lsb--) {
lsb = (lsb / 3) * 3; // Next digit
*strp++ = ((ld>>VL_BITBIT_Q(lsb)) & 7) + '0';
}
*strp++ = '\0';
return str;
default:
for (; lsb>=0; lsb--) {
lsb = (lsb / 4) * 4; // Next digit
IData charval = (ld>>VL_BITBIT_Q(lsb)) & 0xf;
*strp++ = (charval + ((charval < 10) ? '0':('a'-10)));
}
*strp++ = '\0';
return str;
} }
*strp++ = '\0';
return str;
} }
const char* VL_VALUE_FORMATTED_W(int obits, char fmt, bool drop0, WDataInP lwp) { static inline bool _vl_vsss_eof(FILE* fp, int& floc) {
// Convert value into %b/%o/%x/%s/%u/%d formatted string return fp ? feof(fp) : (floc<0);
// Note uses a single buffer; presumes only one call per printf }
static VL_THREAD char str[VL_VALUE_STRING_MAX_WIDTH]; static inline void _vl_vsss_advance(FILE* fp, int& floc) {
char* strp = &str[0]; if (fp) fgetc(fp);
int lsb=obits-1; else floc -= 8;
if (drop0) while (lsb && !VL_BITISSET_W(lwp,lsb)) lsb--; }
switch (fmt) { static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp) {
case 's': // Get a character without advancing
for (; lsb>=0; lsb--) { if (fp) {
lsb = (lsb / 8) * 8; // Next digit int data = fgetc(fp);
IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xff; if (data == EOF) return EOF;
*strp++ = (charval==0)?' ':charval; ungetc(data,fp);
} return data;
*strp++ = '\0'; } else {
return str; if (floc < 0) return EOF;
case 'b': floc = floc & ~7; // Align to closest character
for (; lsb>=0; lsb--) { int data = (fromp[VL_BITWORD_I(floc)] >> VL_BITBIT_I(floc)) & 0xff;
*strp++ = ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) + '0'; return data;
}
*strp++ = '\0';
return str;
case 'o':
for (; lsb>=0; lsb--) {
lsb = (lsb / 3) * 3; // Next digit
*strp++ = ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 7) + '0';
}
*strp++ = '\0';
return str;
default:
for (; lsb>=0; lsb--) {
lsb = (lsb / 4) * 4; // Next digit
IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xf;
*strp++ = (charval + ((charval < 10) ? '0':('a'-10)));
}
*strp++ = '\0';
return str;
} }
*strp++ = '\0'; }
return str; static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp) {
while (1) {
int c = _vl_vsss_peek(fp, floc, fromp);
if (c==EOF || !isspace(c)) return;
_vl_vsss_advance(fp, floc);
}
}
static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp,
char* tmpp, const char* acceptp) {
// Read into tmp, consisting of characters from acceptp list
char* cp = tmpp;
while (1) {
int c = _vl_vsss_peek(fp, floc, fromp);
if (c==EOF || isspace(c)) break;
if (acceptp!=NULL // String - allow anything
&& NULL==strchr(acceptp, c)) break;
if (acceptp!=NULL) c = tolower(c); // Non-strings we'll simplify
*cp++ = c;
_vl_vsss_advance(fp, floc);
}
*cp++ = '\0';
//VL_PRINTF("\t_read got='%s'\n", tmpp);
}
static inline void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb, int nbits, IData ld) {
for (; nbits && lsb<obits; nbits--, lsb++, ld>>=1) {
VL_ASSIGNBIT_WI(0, lsb, owp, ld & 1);
}
}
IData _vl_vsscanf(FILE* fp, // If a fscanf
int fbits, WDataInP fromp, // Else if a sscanf
const char* formatp, va_list ap) {
// Read a Verilog $sscanf/$fscanf style format into the output list
// The format must be pre-processed (and lower cased) by Verilator
// Arguments are in "width, arg-value (or WDataIn* if wide)" form
static VL_THREAD char tmp[VL_VALUE_STRING_MAX_WIDTH];
int floc = fbits - 1;
IData got = 0;
bool inPct = false;
const char* pos = formatp;
for (; *pos && !_vl_vsss_eof(fp,floc); ++pos) {
//VL_PRINTF("_vlscan fmt='%c' floc=%d file='%c'\n", pos[0], floc, _vl_vsss_peek(fp,floc,fromp));
if (!inPct && pos[0]=='%') {
inPct = true;
} else if (!inPct && isspace(pos[0])) { // Format spaces
while (isspace(pos[1])) pos++;
_vl_vsss_skipspace(fp,floc,fromp);
} else if (!inPct) { // Expected Format
_vl_vsss_skipspace(fp,floc,fromp);
int c = _vl_vsss_peek(fp,floc,fromp);
if (c != pos[0]) goto done;
else _vl_vsss_advance(fp,floc);
} else { // Format character
// Skip loading spaces
inPct = false;
char fmt = pos[0];
switch (fmt) {
case '%': {
int c = _vl_vsss_peek(fp,floc,fromp);
if (c != '%') goto done;
else _vl_vsss_advance(fp,floc);
break;
}
default: {
// Deal with all read-and-scan somethings
// Note LSBs are preserved if there's an overflow
const int obits = va_arg(ap, int);
int lsb = 0;
WData qowp[2];
WDataOutP owp = qowp;
if (obits > VL_QUADSIZE) {
owp = va_arg(ap,WDataOutP);
}
for (int i=0; i<VL_WORDS_I(obits); i++) owp[i] = 0;
switch (fmt) {
case 'c': {
int c = _vl_vsss_peek(fp,floc,fromp);
if (c==EOF) goto done;
else _vl_vsss_advance(fp,floc);
owp[0] = c;
break;
}
case 's': {
_vl_vsss_skipspace(fp,floc,fromp);
_vl_vsss_read(fp,floc,fromp, tmp, NULL);
if (!tmp[0]) goto done;
int pos = strlen(tmp)-1;
for (int i=0; i<obits && pos>=0; pos--) {
_vl_vsss_setbit(owp,obits,lsb, 8, tmp[pos]); lsb+=8;
}
break;
}
case 'd': { // Signed decimal
_vl_vsss_skipspace(fp,floc,fromp);
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789+-xz?_");
if (!tmp[0]) goto done;
vlsint64_t ld;
sscanf(tmp,"%lld",&ld);
VL_SET_WQ(owp,ld);
break;
}
case 't': // FALLTHRU // Time
case 'u': { // Unsigned decimal
_vl_vsss_skipspace(fp,floc,fromp);
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789+-xz?_");
if (!tmp[0]) goto done;
QData ld;
sscanf(tmp,"%llu",&ld);
VL_SET_WQ(owp,ld);
break;
}
case 'b': {
_vl_vsss_skipspace(fp,floc,fromp);
_vl_vsss_read(fp,floc,fromp, tmp, "01xz?_");
if (!tmp[0]) goto done;
int pos = strlen(tmp)-1;
for (int i=0; i<obits && pos>=0; pos--) {
switch(tmp[pos]) {
case 'x': case 'z': case '?': //FALLTHRU
case '0': lsb++; break;
case '1': _vl_vsss_setbit(owp,obits,lsb, 1, 1); lsb++; break;
case '_': break;
}
}
break;
}
case 'o': {
_vl_vsss_skipspace(fp,floc,fromp);
_vl_vsss_read(fp,floc,fromp, tmp, "01234567xz?_");
if (!tmp[0]) goto done;
int pos = strlen(tmp)-1;
for (int i=0; i<obits && pos>=0; pos--) {
switch(tmp[pos]) {
case 'x': case 'z': case '?': //FALLTHRU
case '0': lsb+=3; break;
case '1': _vl_vsss_setbit(owp,obits,lsb, 3, 1); lsb+=3; break;
case '2': _vl_vsss_setbit(owp,obits,lsb, 3, 2); lsb+=3; break;
case '3': _vl_vsss_setbit(owp,obits,lsb, 3, 3); lsb+=3; break;
case '4': _vl_vsss_setbit(owp,obits,lsb, 3, 4); lsb+=3; break;
case '5': _vl_vsss_setbit(owp,obits,lsb, 3, 5); lsb+=3; break;
case '6': _vl_vsss_setbit(owp,obits,lsb, 3, 6); lsb+=3; break;
case '7': _vl_vsss_setbit(owp,obits,lsb, 3, 7); lsb+=3; break;
case '_': break;
}
}
break;
}
case 'x': {
_vl_vsss_skipspace(fp,floc,fromp);
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789abcdefxz?_");
if (!tmp[0]) goto done;
int pos = strlen(tmp)-1;
for (int i=0; i<obits && pos>=0; pos--) {
switch(tmp[pos]) {
case 'x': case 'z': case '?': //FALLTHRU
case '0': lsb+=4; break;
case '1': _vl_vsss_setbit(owp,obits,lsb, 4, 1); lsb+=4; break;
case '2': _vl_vsss_setbit(owp,obits,lsb, 4, 2); lsb+=4; break;
case '3': _vl_vsss_setbit(owp,obits,lsb, 4, 3); lsb+=4; break;
case '4': _vl_vsss_setbit(owp,obits,lsb, 4, 4); lsb+=4; break;
case '5': _vl_vsss_setbit(owp,obits,lsb, 4, 5); lsb+=4; break;
case '6': _vl_vsss_setbit(owp,obits,lsb, 4, 6); lsb+=4; break;
case '7': _vl_vsss_setbit(owp,obits,lsb, 4, 7); lsb+=4; break;
case '8': _vl_vsss_setbit(owp,obits,lsb, 4, 8); lsb+=4; break;
case '9': _vl_vsss_setbit(owp,obits,lsb, 4, 9); lsb+=4; break;
case 'a': _vl_vsss_setbit(owp,obits,lsb, 4, 10); lsb+=4; break;
case 'b': _vl_vsss_setbit(owp,obits,lsb, 4, 11); lsb+=4; break;
case 'c': _vl_vsss_setbit(owp,obits,lsb, 4, 12); lsb+=4; break;
case 'd': _vl_vsss_setbit(owp,obits,lsb, 4, 13); lsb+=4; break;
case 'e': _vl_vsss_setbit(owp,obits,lsb, 4, 14); lsb+=4; break;
case 'f': _vl_vsss_setbit(owp,obits,lsb, 4, 15); lsb+=4; break;
case '_': break;
}
}
break;
}
default:
string msg = string("%%Error: Unknown _vl_vsscanf code: ")+pos[0]+"\n";
vl_fatal(__FILE__,__LINE__,"",msg.c_str());
break;
} // switch
got++;
// Reload data if non-wide (if wide, we put it in the right place directly)
if (obits <= VL_BYTESIZE) {
CData* p = va_arg(ap,CData*); *p = owp[0];
} else if (obits <= VL_SHORTSIZE) {
SData* p = va_arg(ap,SData*); *p = owp[0];
} else if (obits <= VL_WORDSIZE) {
IData* p = va_arg(ap,IData*); *p = owp[0];
} else if (obits <= VL_QUADSIZE) {
QData* p = va_arg(ap,QData*); *p = VL_SET_QW(owp);
}
}
} // switch
}
}
done:
return got;
} }
//=========================================================================== //===========================================================================
@@ -228,6 +521,40 @@ void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) {
while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0'; // Drop trailing spaces while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0'; // Drop trailing spaces
} }
void _VL_STRING_TO_VINT(int obits, void* destp, int srclen, const char* srcp) {
// Convert C string to Verilog format
int bytes = VL_BYTES_I(obits);
char* op = ((char*)(destp));
if (srclen > bytes) srclen = bytes; // Don't overflow destination
int i;
for (i=0; i<srclen; i++) { *op++ = srcp[srclen-1-i]; }
for (; i<bytes; i++) { *op++ = 0; }
}
IData VL_FGETS_IXQ(int obits, void* destp, QData fpq) {
FILE* fp = VL_CVT_Q_FP(fpq);
if (VL_UNLIKELY(!fp)) return 0;
// The string needs to be padded with 0's in unused spaces in front of
// any read data. This means we can't know in what location the first
// character will finally live, so we need to copy. Yuk.
IData bytes = VL_BYTES_I(obits);
char buffer[bytes];
// We don't use fgets, as we must read \0s.
IData got = 0;
char* cp = buffer;
while (got < bytes) {
int c = getc(fp);
if (c==EOF) break;
*cp++ = c; got++;
if (c=='\n') break;
}
_VL_STRING_TO_VINT(obits, destp, got, buffer);
return got;
}
QData VL_FOPEN_QI(QData filename, IData mode) { QData VL_FOPEN_QI(QData filename, IData mode) {
IData fnw[2]; VL_SET_WQ(fnw, filename); IData fnw[2]; VL_SET_WQ(fnw, filename);
return VL_FOPEN_WI(2, fnw, mode); return VL_FOPEN_WI(2, fnw, mode);
@@ -240,6 +567,67 @@ 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_WRITEF(const char* formatp, ...) {
va_list ap;
va_start(ap,formatp);
string output;
_vl_vsformat(output, formatp, ap);
va_end(ap);
// Users can redefine VL_PRINTF if they wish.
VL_PRINTF("%s", output.c_str());
}
void VL_FWRITEF(QData fpq, const char* formatp, ...) {
FILE* fp = VL_CVT_Q_FP(fpq);
if (VL_UNLIKELY(!fp)) return;
va_list ap;
va_start(ap,formatp);
string output;
_vl_vsformat(output, formatp, ap);
va_end(ap);
fputs(output.c_str(), fp);
}
IData VL_FSCANF_IX(QData fpq, const char* formatp, ...) {
FILE* fp = VL_CVT_Q_FP(fpq);
if (VL_UNLIKELY(!fp)) return 0;
va_list ap;
va_start(ap,formatp);
IData got = _vl_vsscanf(fp, 0, NULL, formatp, ap);
va_end(ap);
return got;
}
IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) {
IData fnw[2]; VL_SET_WI(fnw, ld);
va_list ap;
va_start(ap,formatp);
IData got = _vl_vsscanf(NULL, lbits, fnw, formatp, ap);
va_end(ap);
return got;
}
IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...) {
IData fnw[2]; VL_SET_WQ(fnw, ld);
va_list ap;
va_start(ap,formatp);
IData got = _vl_vsscanf(NULL, lbits, fnw, formatp, ap);
va_end(ap);
return got;
}
IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...) {
va_list ap;
va_start(ap,formatp);
IData got = _vl_vsscanf(NULL, lbits, lwp, formatp, ap);
va_end(ap);
return got;
}
void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int, void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int,
QData ofilename, void* memp, IData start, IData end) { QData ofilename, void* memp, IData start, IData end) {
IData fnw[2]; VL_SET_WQ(fnw, ofilename); IData fnw[2]; VL_SET_WQ(fnw, ofilename);
@@ -276,7 +664,7 @@ void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
else if (c=='\t' || c==' ' || c=='\r' || c=='\f') { 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 // Skip // comments and detect /* comments
else if (ignore_to_cmt && lastc=='*' && c=='/') { else if (ignore_to_cmt && lastc=='*' && c=='/') {
ignore_to_cmt = false; if (innum) reading_addr=false; innum=false; ignore_to_cmt = false; if (innum) reading_addr=false; innum=false;
} else if (!ignore_to_eol && !ignore_to_cmt) { } else if (!ignore_to_eol && !ignore_to_cmt) {
if (lastc=='/' && c=='*') { ignore_to_cmt = true; } if (lastc=='/' && c=='*') { ignore_to_cmt = true; }
else if (lastc=='/' && c=='/') { ignore_to_eol = true; } else if (lastc=='/' && c=='/') { ignore_to_eol = true; }
@@ -355,7 +743,7 @@ const char* Verilated::catName(const char* n1, const char* n2) {
// Used by symbol table creation to make module names // Used by symbol table creation to make module names
static char* strp = NULL; static char* strp = NULL;
static int len = -1; static int len = -1;
int newlen = strlen(n1)+strlen(n2)+2; int newlen = strlen(n1)+strlen(n2)+2;
if (newlen > len) { if (newlen > len) {
if (strp) delete [] strp; if (strp) delete [] strp;
strp = new char[newlen]; strp = new char[newlen];
+114 -50
View File
@@ -1,4 +1,4 @@
// $Id$ -*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// //
// Copyright 2003-2008 by Wilson Snyder. This program is free software; you can // Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
@@ -9,7 +9,7 @@
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
//************************************************************************* //*************************************************************************
/// ///
/// \file /// \file
@@ -19,7 +19,7 @@
/// all C++ files it generates. It contains standard macros and /// all C++ files it generates. It contains standard macros and
/// classes required by the Verilated code. /// classes required by the Verilated code.
/// ///
/// Code available from: http://www.veripool.com/verilator /// Code available from: http://www.veripool.org/verilator
/// ///
//************************************************************************* //*************************************************************************
@@ -29,11 +29,11 @@
#include "verilatedos.h" #include "verilatedos.h"
#include <assert.h> #include <cassert>
#include <stdarg.h> #include <cstdarg>
#include <stdio.h> #include <cstdio>
#include <stdlib.h> #include <cstdlib>
#include <string.h> #include <cstring>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
@@ -129,7 +129,7 @@ struct Verilated {
// Extern Vars // Extern Vars
// Below two are used as bool, but having as uint32_t avoids conversion time // Below two are used as bool, but having as uint32_t avoids conversion time
private: private:
static int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random static int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
static int s_debug; ///< See accessors... only when VL_DEBUG set static int s_debug; ///< See accessors... only when VL_DEBUG set
static bool s_calcUnusedSigs; ///< Waves file on, need all signals calculated static bool s_calcUnusedSigs; ///< Waves file on, need all signals calculated
static bool s_gotFinish; ///< A $finish statement executed static bool s_gotFinish; ///< A $finish statement executed
@@ -152,7 +152,7 @@ public:
#endif #endif
/// Internal: Create a new module name by concatenating two strings /// Internal: Create a new module name by concatenating two strings
static const char* catName(const char* n1, const char* n2); // Returns new'ed data static const char* catName(const char* n1, const char* n2); // Returns new'ed data
/// Enable calculation of unused signals /// Enable calculation of unused signals
static void calcUnusedSigs(bool flag) { s_calcUnusedSigs=flag; } static void calcUnusedSigs(bool flag) { s_calcUnusedSigs=flag; }
static bool calcUnusedSigs() { return s_calcUnusedSigs; } ///< Return calcUnusedSigs value static bool calcUnusedSigs() { return s_calcUnusedSigs; } ///< Return calcUnusedSigs value
/// Did the simulation $finish? /// Did the simulation $finish?
@@ -165,7 +165,7 @@ public:
/// Enable/disable assertions /// Enable/disable assertions
static void assertOn(bool flag) { s_assertOn=flag; } static void assertOn(bool flag) { s_assertOn=flag; }
static bool assertOn() { return s_assertOn; } static bool assertOn() { return s_assertOn; }
}; };
//========================================================================= //=========================================================================
// Extern functions -- User may override -- See verilated.cpp // Extern functions -- User may override -- See verilated.cpp
@@ -179,21 +179,21 @@ extern void vl_fatal (const char* filename, int linenum, const char* hier,
const char* msg); const char* msg);
//========================================================================= //=========================================================================
// Extern functions -- Init time only, so slow is fine // Extern functions -- Slow path
extern IData VL_RANDOM_I(int obits); ///< Randomize a signal
extern QData VL_RANDOM_Q(int obits); ///< Randomize a signal
extern WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp); ///< Randomize a signal
/// Init time only, so slow is fine
extern IData VL_RAND_RESET_I(int obits); ///< Random reset a signal extern IData VL_RAND_RESET_I(int obits); ///< Random reset a signal
extern QData VL_RAND_RESET_Q(int obits); ///< Random reset a signal extern QData VL_RAND_RESET_Q(int obits); ///< Random reset a signal
extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp); ///< Random reset a signal extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp); ///< Random reset a signal
extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp); ///< Zero reset a signal extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp); ///< Zero reset a signal
/// Return string with formated Verilog value
extern const char* VL_VALUE_FORMATTED_W(int obits, char fmt, bool drop0, WDataInP lwp);
extern const char* VL_VALUE_FORMATTED_Q(int obits, char fmt, bool drop0, QData ld);
inline const char* VL_VALUE_FORMATTED_I(int obits, char fmt, bool drop0, IData ld) {
return VL_VALUE_FORMATTED_Q(obits,fmt,drop0,ld);
}
/// File I/O /// File I/O
extern IData VL_FGETS_IXQ(int sbits, void* strgp, QData fpq);
extern QData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode); extern QData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
extern QData VL_FOPEN_QI(QData ofilename, IData mode); extern QData VL_FOPEN_QI(QData ofilename, IData mode);
inline QData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); } inline QData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); }
@@ -206,6 +206,14 @@ inline void VL_READMEM_I(bool hex, int width, int depth, int array_lsb, int fnwo
IData ofilename, void* memp, IData start, IData end) { IData ofilename, void* memp, IData start, IData end) {
VL_READMEM_Q(hex, width,depth,array_lsb,fnwords, ofilename,memp,start,end); } VL_READMEM_Q(hex, width,depth,array_lsb,fnwords, ofilename,memp,start,end); }
extern void VL_WRITEF(const char* formatp, ...);
extern void VL_FWRITEF(QData fpq, const char* formatp, ...);
extern IData VL_FSCANF_IX(QData fpq, const char* formatp, ...);
extern IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...);
extern IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...);
extern IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...);
//========================================================================= //=========================================================================
// Base macros // Base macros
@@ -213,9 +221,12 @@ inline void VL_READMEM_I(bool hex, int width, int depth, int array_lsb, int fnwo
#define VL_BITISSET_I(data,bit) (data & (VL_UL(1)<<VL_BITBIT_I(bit))) #define VL_BITISSET_I(data,bit) (data & (VL_UL(1)<<VL_BITBIT_I(bit)))
#define VL_BITISSET_Q(data,bit) (data & (VL_ULL(1)<<VL_BITBIT_Q(bit))) #define VL_BITISSET_Q(data,bit) (data & (VL_ULL(1)<<VL_BITBIT_Q(bit)))
#define VL_BITISSET_W(data,bit) (data[VL_BITWORD_I(bit)] & (VL_UL(1)<<VL_BITBIT_I(bit))) #define VL_BITISSET_W(data,bit) (data[VL_BITWORD_I(bit)] & (VL_UL(1)<<VL_BITBIT_I(bit)))
#define VL_BITISSETLIMIT_W(data,width,bit) (((bit)<(width)) && data[VL_BITWORD_I(bit)] & (VL_UL(1)<<VL_BITBIT_I(bit)))
/// Create two 32-bit words from quadword /// Create two 32-bit words from quadword
#define VL_SET_WQ(decl,data) { decl[0]=(data); decl[1]=((data)>>VL_WORDSIZE); } #define VL_SET_WQ(owp,data) { owp[0]=(data); owp[1]=((data)>>VL_WORDSIZE); }
#define VL_SET_WI(owp,data) { owp[0]=(data); owp[1]=0; }
#define VL_SET_QW(lwp) ( ((QData)(lwp[0])) | ((QData)(lwp[1])<<((QData)(VL_WORDSIZE)) ))
// Use a union to avoid cast-to-different-size warnings // Use a union to avoid cast-to-different-size warnings
/// Return FILE* from QData /// Return FILE* from QData
@@ -236,7 +247,7 @@ static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) { return (-((lhs)&(VL
// Debugging prints // Debugging prints
static inline void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp) { static inline void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp) {
printf(" Data: w%d: ", lbits); printf(" Data: w%d: ", lbits);
for (int i=VL_WORDS_I(lbits)-1; i>=0; i--) { printf("%08x ",iwp[i]); } for (int i=VL_WORDS_I(lbits)-1; i>=0; i--) { printf("%08x ",iwp[i]); }
printf("\n"); printf("\n");
} }
@@ -244,13 +255,17 @@ static inline void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp) {
//========================================================================= //=========================================================================
// Pli macros // Pli macros
#ifndef VL_TIME_MULTIPLIER
# define VL_TIME_MULTIPLIER 1
#endif
/// Return current simulation time /// Return current simulation time
#if defined(SYSTEMC_VERSION) && (SYSTEMC_VERSION>20011000) #if defined(SYSTEMC_VERSION) && (SYSTEMC_VERSION>20011000)
# define VL_TIME_I(ign) ((IData)sc_time_stamp().to_default_time_units()) # define VL_TIME_I(ign) ((IData)(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER))
# define VL_TIME_Q(ign) ((QData)sc_time_stamp().to_default_time_units()) # define VL_TIME_Q(ign) ((QData)(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER))
#else #else
# define VL_TIME_I(ign) ((IData)sc_time_stamp()) # define VL_TIME_I(ign) ((IData)(sc_time_stamp()*VL_TIME_MULTIPLIER))
# define VL_TIME_Q(ign) ((QData)sc_time_stamp()) # define VL_TIME_Q(ign) ((QData)(sc_time_stamp()*VL_TIME_MULTIPLIER))
extern double sc_time_stamp(); extern double sc_time_stamp();
#endif #endif
@@ -460,43 +475,92 @@ static inline IData VL_REDOR_W(int words, WDataInP lwp) {
} }
// EMIT_RULE: VL_REDXOR: oclean=dirty; obits=1; // EMIT_RULE: VL_REDXOR: oclean=dirty; obits=1;
static inline IData VL_REDXOR_W(int words, WDataInP lwp) {
IData r = lwp[0];
for (int i=1; i < words; i++) r ^= lwp[i];
r=(r^(r>>1));
r=(r^(r>>2));
r=(r^(r>>4));
r=(r^(r>>8));
r=(r^(r>>16));
return r;
}
static inline IData VL_REDXOR_2(IData r) { static inline IData VL_REDXOR_2(IData r) {
// Experiments show VL_REDXOR_2 is faster than __builtin_parityl
r=(r^(r>>1)); r=(r^(r>>1));
return r; return r;
} }
static inline IData VL_REDXOR_4(IData r) { static inline IData VL_REDXOR_4(IData r) {
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS)
return __builtin_parityl(r);
#else
r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>1)); r=(r^(r>>2));
return r; return r;
#endif
} }
static inline IData VL_REDXOR_8(IData r) { static inline IData VL_REDXOR_8(IData r) {
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS)
return __builtin_parityl(r);
#else
r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4));
return r; return r;
#endif
} }
static inline IData VL_REDXOR_16(IData r) { static inline IData VL_REDXOR_16(IData r) {
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS)
return __builtin_parityl(r);
#else
r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>8)); r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>8));
return r; return r;
#endif
} }
static inline IData VL_REDXOR_32(IData r) { static inline IData VL_REDXOR_32(IData r) {
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS)
return __builtin_parityl(r);
#else
r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>8)); r=(r^(r>>16)); r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>8)); r=(r^(r>>16));
return r; return r;
#endif
} }
static inline IData VL_REDXOR_64(QData r) { static inline IData VL_REDXOR_64(QData r) {
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS)
return __builtin_parityll(r);
#else
r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>8)); r=(r^(r>>16)); r=(r^(r>>32)); r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>8)); r=(r^(r>>16)); r=(r^(r>>32));
return r; return r;
#endif
}
static inline IData VL_REDXOR_W(int words, WDataInP lwp) {
IData r = lwp[0];
for (int i=1; i < words; i++) r ^= lwp[i];
return VL_REDXOR_32(r);
}
static inline IData VL_CLOG2_I(IData lhs) {
// Perhaps can do better using fls GCC4 builtins
int n=1;
IData chk;
if (!lhs) return 0;
chk = lhs >> VL_UL(16); if (chk) { n += 16; lhs = chk; }
chk = lhs >> VL_UL(8); if (chk) { n += 8; lhs = chk; }
chk = lhs >> VL_UL(4); if (chk) { n += 4; lhs = chk; }
chk = lhs >> VL_UL(2); if (chk) { n += 2; lhs = chk; }
chk = lhs >> VL_UL(1); if (chk) { n += 1; lhs = chk; }
return n;
}
static inline IData VL_CLOG2_Q(QData lhs) {
// Perhaps can do better using fls GCC4 builtins
int n=1;
QData chk;
if (!lhs) return 0;
chk = lhs >> VL_ULL(32); if (chk) { n += 32; lhs = chk; }
chk = lhs >> VL_ULL(16); if (chk) { n += 16; lhs = chk; }
chk = lhs >> VL_ULL(8); if (chk) { n += 8; lhs = chk; }
chk = lhs >> VL_ULL(4); if (chk) { n += 4; lhs = chk; }
chk = lhs >> VL_ULL(2); if (chk) { n += 2; lhs = chk; }
chk = lhs >> VL_ULL(1); if (chk) { n += 1; lhs = chk; }
return n;
}
static inline IData VL_CLOG2_W(int words, WDataInP lwp) {
for (int i=words-1; i>=0; i--) {
if (lwp[i]) return VL_CLOG2_I(lwp[i])+i*VL_WORDSIZE;
}
return 0;
} }
// EMIT_RULE: VL_COUNTONES_II: oclean = false; lhs clean // EMIT_RULE: VL_COUNTONES_II: oclean = false; lhs clean
static inline IData VL_COUNTONES_I(IData lhs) { static inline IData VL_COUNTONES_I(IData lhs) {
// This is faster than __builtin_popcountl
IData r = lhs - ((lhs >> 1) & 033333333333) - ((lhs >> 2) & 011111111111); IData r = lhs - ((lhs >> 1) & 033333333333) - ((lhs >> 2) & 011111111111);
r = (r + (r>>3)) & 030707070707; r = (r + (r>>3)) & 030707070707;
r = (r + (r>>6)); r = (r + (r>>6));
@@ -829,7 +893,7 @@ static inline IData VL_POW_III(int, int, int rbits, IData lhs, IData rhs) {
return out; return out;
} }
#define VL_POW_QQI(obits,lbits,rbits,lhs,rhs) VL_POW_QQQ(obits,lbits,rbits,lhs,rhs) #define VL_POW_QQI(obits,lbits,rbits,lhs,rhs) VL_POW_QQQ(obits,lbits,rbits,lhs,rhs)
static inline QData VL_POW_QQQ(int, int, int rbits, QData lhs, QData rhs) { static inline QData VL_POW_QQQ(int, int, int rbits, QData lhs, QData rhs) {
if (lhs==0) return 0; if (lhs==0) return 0;
@@ -847,23 +911,23 @@ static inline QData VL_POW_QQQ(int, int, int rbits, QData lhs, QData rhs) {
// INTERNAL: Stuff LHS bit 0++ into OUTPUT at specified offset // INTERNAL: Stuff LHS bit 0++ into OUTPUT at specified offset
// ld may be "dirty", output is clean // ld may be "dirty", output is clean
static inline void _VL_INSERT_II(int, CData& lhsr, IData ld, int hbit, int lbit) { static inline void _VL_INSERT_II(int, CData& lhsr, IData ld, int hbit, int lbit) {
IData insmask = (VL_MASK_I(hbit-lbit+1))<<lbit; IData insmask = (VL_MASK_I(hbit-lbit+1))<<lbit;
lhsr = (lhsr & ~insmask) | ((ld<<lbit) & insmask); lhsr = (lhsr & ~insmask) | ((ld<<lbit) & insmask);
} }
static inline void _VL_INSERT_II(int, SData& lhsr, IData ld, int hbit, int lbit) { static inline void _VL_INSERT_II(int, SData& lhsr, IData ld, int hbit, int lbit) {
IData insmask = (VL_MASK_I(hbit-lbit+1))<<lbit; IData insmask = (VL_MASK_I(hbit-lbit+1))<<lbit;
lhsr = (lhsr & ~insmask) | ((ld<<lbit) & insmask); lhsr = (lhsr & ~insmask) | ((ld<<lbit) & insmask);
} }
static inline void _VL_INSERT_II(int, IData& lhsr, IData ld, int hbit, int lbit) { static inline void _VL_INSERT_II(int, IData& lhsr, IData ld, int hbit, int lbit) {
IData insmask = (VL_MASK_I(hbit-lbit+1))<<lbit; IData insmask = (VL_MASK_I(hbit-lbit+1))<<lbit;
lhsr = (lhsr & ~insmask) | ((ld<<lbit) & insmask); lhsr = (lhsr & ~insmask) | ((ld<<lbit) & insmask);
} }
static inline void _VL_INSERT_QQ(int, QData& lhsr, QData ld, int hbit, int lbit) { static inline void _VL_INSERT_QQ(int, QData& lhsr, QData ld, int hbit, int lbit) {
QData insmask = (VL_MASK_Q(hbit-lbit+1))<<lbit; QData insmask = (VL_MASK_Q(hbit-lbit+1))<<lbit;
lhsr = (lhsr & ~insmask) | ((ld<<lbit) & insmask); lhsr = (lhsr & ~insmask) | ((ld<<lbit) & insmask);
} }
static inline void _VL_INSERT_WI(int, WDataOutP owp, IData ld, int hbit, int lbit) { static inline void _VL_INSERT_WI(int, WDataOutP owp, IData ld, int hbit, int lbit) {
int hoffset = VL_BITBIT_I(hbit); int hoffset = VL_BITBIT_I(hbit);
int loffset = VL_BITBIT_I(lbit); int loffset = VL_BITBIT_I(lbit);
if (hoffset==VL_SIZEBITS_I && loffset==0) { if (hoffset==VL_SIZEBITS_I && loffset==0) {
@@ -888,7 +952,7 @@ static inline void _VL_INSERT_WI(int, WDataOutP owp, IData ld, int hbit, int lbi
// INTERNAL: Stuff large LHS bit 0++ into OUTPUT at specified offset // INTERNAL: Stuff large LHS bit 0++ into OUTPUT at specified offset
// lwp may be "dirty" // lwp may be "dirty"
static inline void _VL_INSERT_WW(int, WDataOutP owp, WDataInP lwp, int hbit, int lbit) { static inline void _VL_INSERT_WW(int, WDataOutP owp, WDataInP lwp, int hbit, int lbit) {
int hoffset = hbit & VL_SIZEBITS_I; int hoffset = hbit & VL_SIZEBITS_I;
int loffset = lbit & VL_SIZEBITS_I; int loffset = lbit & VL_SIZEBITS_I;
int lword = VL_BITWORD_I(lbit); int lword = VL_BITWORD_I(lbit);
@@ -934,7 +998,7 @@ static inline void _VL_INSERT_WW(int, WDataOutP owp, WDataInP lwp, int hbit, int
} }
} }
static inline void _VL_INSERT_WQ(int obits, WDataOutP owp, QData ld, int hbit, int lbit) { static inline void _VL_INSERT_WQ(int obits, WDataOutP owp, QData ld, int hbit, int lbit) {
WData lwp[2]; VL_SET_WQ(lwp,ld); WData lwp[2]; VL_SET_WQ(lwp,ld);
_VL_INSERT_WW(obits,owp,lwp,hbit,lbit); _VL_INSERT_WW(obits,owp,lwp,hbit,lbit);
} }
@@ -1214,7 +1278,7 @@ static inline QData VL_SEL_QWII(int, int lbits, int, int, WDataInP lwp, IData ls
static inline WDataOutP VL_SEL_WWII(int obits,int lbits,int,int,WDataOutP owp,WDataInP lwp, IData lsb, IData width) { static inline WDataOutP VL_SEL_WWII(int obits,int lbits,int,int,WDataOutP owp,WDataInP lwp, IData lsb, IData width) {
int msb = lsb+width-1; int msb = lsb+width-1;
int word_shift = VL_BITWORD_I(lsb); int word_shift = VL_BITWORD_I(lsb);
if (msb>lbits) { // Outside bounds, if (msb>lbits) { // Outside bounds,
for (int i=0; i<VL_WORDS_I(obits)-1; i++) owp[i] = ~0; for (int i=0; i<VL_WORDS_I(obits)-1; i++) owp[i] = ~0;
owp[VL_WORDS_I(obits)-1] = VL_MASK_I(obits); owp[VL_WORDS_I(obits)-1] = VL_MASK_I(obits);
} else if (VL_BITBIT_I(lsb)==0) { } else if (VL_BITBIT_I(lsb)==0) {
@@ -1311,32 +1375,32 @@ static inline WDataOutP VL_CONST_W_3X(int obits, WDataOutP o,
o[0]=d0; o[1]=d1; o[2]=d2; o[0]=d0; o[1]=d1; o[2]=d2;
_END(obits,3); } _END(obits,3); }
#define VL_HAVE_CONST_W_4X #define VL_HAVE_CONST_W_4X
static inline WDataOutP VL_CONST_W_4X(int obits, WDataOutP o, static inline WDataOutP VL_CONST_W_4X(int obits, WDataOutP o,
I d3,I d2,I d1,I d0) { I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3;
_END(obits,4); } _END(obits,4); }
#define VL_HAVE_CONST_W_5X #define VL_HAVE_CONST_W_5X
static inline WDataOutP VL_CONST_W_5X(int obits, WDataOutP o, static inline WDataOutP VL_CONST_W_5X(int obits, WDataOutP o,
I d4,I d3,I d2,I d1,I d0) { I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4;
_END(obits,5); } _END(obits,5); }
#define VL_HAVE_CONST_W_6X #define VL_HAVE_CONST_W_6X
static inline WDataOutP VL_CONST_W_6X(int obits, WDataOutP o, static inline WDataOutP VL_CONST_W_6X(int obits, WDataOutP o,
I d5,I d4,I d3,I d2,I d1,I d0) { I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5;
_END(obits,6); } _END(obits,6); }
#define VL_HAVE_CONST_W_7X #define VL_HAVE_CONST_W_7X
static inline WDataOutP VL_CONST_W_7X(int obits, WDataOutP o, static inline WDataOutP VL_CONST_W_7X(int obits, WDataOutP o,
I d6,I d5,I d4,I d3,I d2,I d1,I d0) { I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6;
_END(obits,7); } _END(obits,7); }
#define VL_HAVE_CONST_W_8X #define VL_HAVE_CONST_W_8X
static inline WDataOutP VL_CONST_W_8X(int obits, WDataOutP o, static inline WDataOutP VL_CONST_W_8X(int obits, WDataOutP o,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) { I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7; o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
_END(obits,8); } _END(obits,8); }
#define VL_HAVE_CONST_W_9X #define VL_HAVE_CONST_W_9X
static inline WDataOutP VL_CONST_W_9X(int obits, WDataOutP o, static inline WDataOutP VL_CONST_W_9X(int obits, WDataOutP o,
I d8, I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) { I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7; o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
+5 -4
View File
@@ -1,4 +1,4 @@
# $Id$ -*- Makefile -*- # -*- Makefile -*-
###################################################################### ######################################################################
# DESCRIPTION: Makefile commands for all verilated target files # DESCRIPTION: Makefile commands for all verilated target files
# #
@@ -28,6 +28,7 @@ VK_CPPFLAGS_ALWAYS += \
-I$(VERILATOR_ROOT)/include \ -I$(VERILATOR_ROOT)/include \
-DVL_PRINTF=printf \ -DVL_PRINTF=printf \
-DVM_TRACE=$(VM_TRACE) \ -DVM_TRACE=$(VM_TRACE) \
-DVM_COVERAGE=$(VM_COVERAGE) \
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
VK_CPPFLAGS_WALL += -Wall \ VK_CPPFLAGS_WALL += -Wall \
@@ -44,7 +45,7 @@ CPPFLAGS += -I. $(VK_CPPFLAGS_ALWAYS) $(VK_CPPFLAGS_WALL)
VPATH += .. VPATH += ..
VPATH += $(VERILATOR_ROOT)/include VPATH += $(VERILATOR_ROOT)/include
#OPT = -ggdb -DPRINTINITSTR -DDETECTCHANGE #OPT = -ggdb -DPRINTINITSTR -DDETECTCHANGE
#OPT = -ggdb -DPRINTINITSTR #OPT = -ggdb -DPRINTINITSTR
CPPFLAGS += $(OPT) CPPFLAGS += $(OPT)
@@ -59,11 +60,11 @@ 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.
#OPT_SLOW = #OPT_SLOW =
# Fast path optimizations. Most time is spent in these classes. # Fast path optimizations. Most time is spent in these classes.
#OPT_FAST = -O2 -fstrict-aliasing #OPT_FAST = -O2 -fstrict-aliasing
#OPT_FAST = -O #OPT_FAST = -O
#OPT_FAST = #OPT_FAST =
####################################################################### #######################################################################
##### Aggregates ##### Aggregates
+4 -4
View File
@@ -1,7 +1,7 @@
// $Id$ -*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
//************************************************************************* //*************************************************************************
// //
@@ -13,7 +13,7 @@
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
//========================================================================= //=========================================================================
// //
// DESCRIPTION: Verilator: Include in verilog files to hide verilator defines // DESCRIPTION: Verilator: Include in verilog files to hide verilator defines
@@ -25,7 +25,7 @@
`ifdef verilator `else `ifdef verilator `else
`define coverage_block_off `define coverage_block_off
`endif `endif
// Hide file descriptor difference // Hide file descriptor difference
`ifdef verilator `ifdef verilator
`define verilator_file_descriptor reg [63:0] `define verilator_file_descriptor reg [63:0]
+12 -8
View File
@@ -1,4 +1,4 @@
// $Id$ -*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// //
// Copyright 2003-2008 by Wilson Snyder. This program is free software; you can // Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
@@ -9,7 +9,7 @@
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
//************************************************************************* //*************************************************************************
/// ///
/// \file /// \file
@@ -21,7 +21,7 @@
/// config_build.h.in, code needed by Verilated code only goes into /// config_build.h.in, code needed by Verilated code only goes into
/// verilated.h, and code needed by both goes here (verilatedos.h). /// verilated.h, and code needed by both goes here (verilatedos.h).
/// ///
/// Code available from: http://www.veripool.com/verilator /// Code available from: http://www.veripool.org/verilator
/// ///
//************************************************************************* //*************************************************************************
@@ -84,7 +84,7 @@ typedef unsigned char vluint8_t; ///< 8-bit unsigned type
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
typedef long vlsint32_t; ///< 32-bit signed type 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) && !defined(__MINGW32__) #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)
@@ -92,28 +92,32 @@ typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward co
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility) typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility)
typedef unsigned char vluint8_t; ///< 8-bit unsigned type typedef unsigned char vluint8_t; ///< 8-bit unsigned type
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
typedef int vlsint32_t; ///< 32-bit signed type typedef int vlsint32_t; ///< 32-bit signed type
typedef unsigned int vluint32_t; ///< 32-bit unsigned type typedef unsigned int vluint32_t; ///< 32-bit unsigned type
typedef __int64 vlsint64_t; ///< 64-bit signed type typedef __int64 vlsint64_t; ///< 64-bit signed type
typedef unsigned __int64 vluint64_t; ///< 64-bit unsigned type typedef unsigned __int64 vluint64_t; ///< 64-bit unsigned type
#else // Linux or compliant Unix flavors, -m64 #else // Linux or compliant Unix flavors, -m64
# include <stdint.h> // Linux and most flavors # include <stdint.h> // Linux and most flavors
# include <inttypes.h> // Solaris # include <inttypes.h> // Solaris
typedef uint8_t vluint8_t; ///< 32-bit unsigned type typedef uint8_t vluint8_t; ///< 32-bit unsigned type
typedef uint16_t vluint16_t; ///< 32-bit unsigned type typedef uint16_t vluint16_t; ///< 32-bit unsigned type
typedef int vlsint32_t; ///< 32-bit signed type typedef int vlsint32_t; ///< 32-bit signed type
typedef uint32_t vluint32_t; ///< 32-bit signed type typedef uint32_t vluint32_t; ///< 32-bit signed 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
#endif #endif
//========================================================================= //=========================================================================
// Integer size macros // Integer size macros
#define VL_BYTESIZE 8 ///< Bits in a byte
#define VL_SHORTSIZE 16 ///< Bits in a short
#define VL_WORDSIZE 32 ///< Bits in a word #define VL_WORDSIZE 32 ///< Bits in a word
#define VL_QUADSIZE 64 ///< Bits in a quadword #define VL_QUADSIZE 64 ///< Bits in a quadword
#define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE) #define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE)
/// Bytes this number of bits needs (1 bit=1 byte)
#define VL_BYTES_I(nbits) (((nbits)+(VL_BYTESIZE-1))/VL_BYTESIZE)
/// Words this number of bits needs (1 bit=1 word) /// Words this number of bits needs (1 bit=1 word)
#define VL_WORDS_I(nbits) (((nbits)+(VL_WORDSIZE-1))/VL_WORDSIZE) #define VL_WORDS_I(nbits) (((nbits)+(VL_WORDSIZE-1))/VL_WORDSIZE)
+1 -1
View File
@@ -115,7 +115,7 @@ fi
if [ x"$dir_arg" != x ]; then if [ x"$dir_arg" != x ]; then
dst=$src dst=$src
src="" src=""
if [ -d $dst ]; then if [ -d $dst ]; then
instcmd=: instcmd=:
else else
-2
View File
@@ -4,8 +4,6 @@
# Created: 1993-05-16 # Created: 1993-05-16
# Public domain # Public domain
# $Id:$
errstatus=0 errstatus=0
for file for file
+3 -4
View File
@@ -1,5 +1,4 @@
#!/usr/bin/perl -w #!/usr/bin/perl -w
#$Id$
###################################################################### ######################################################################
# #
# Copyright 2007-2008 by Wilson Snyder. # Copyright 2007-2008 by Wilson Snyder.
@@ -7,16 +6,16 @@
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of either the GNU General Public License or the
# Perl Artistic License. # Perl Artistic License.
# #
# This program is distributed in the hope that it will be useful, # This program 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
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the Perl Artistic License # You should have received a copy of the Perl Artistic License
# along with this module; see the file COPYING. If not, see # along with this module; see the file COPYING. If not, see
# www.cpan.org # www.cpan.org
# #
###################################################################### ######################################################################
# DESCRIPTION: Debugging of bison output # DESCRIPTION: Debugging of bison output
+2 -15
View File
@@ -1,17 +1,5 @@
#!/usr/bin/perl -w #!/usr/bin/perl -w
# $Id$ # See copyright, etc in below POD section.
######################################################################
#
# Copyright 2005-2008 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; require 5.006_001;
@@ -50,7 +38,6 @@ cwrite ("graph_export.cpp");
#---------------------------------------------------------------------- #----------------------------------------------------------------------
sub usage { sub usage {
print '$Id$ ', "\n";
pod2usage(-verbose=>2, -exitval => 2); pod2usage(-verbose=>2, -exitval => 2);
exit (1); exit (1);
} }
@@ -120,7 +107,7 @@ sub cwrite {
foreach my $edge (@Edges) { foreach my $edge (@Edges) {
$fh->printf(" new V3GraphEdge(gp, %s, %s, %s, %s);\n", $fh->printf(" new V3GraphEdge(gp, %s, %s, %s, %s);\n",
$edge->{from}, $edge->{to}, $edge->{from}, $edge->{to},
$edge->{weight}, $edge->{cutable}?"true":"false"); $edge->{weight}, $edge->{cutable}?"true":"false");
} }
$fh->print("}\n"); $fh->print("}\n");
} }
+2 -15
View File
@@ -1,17 +1,5 @@
#!/usr/bin/perl -w #!/usr/bin/perl -w
# $Id$ # See copyright, etc in below POD section.
######################################################################
#
# Copyright 2005-2008 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; require 5.006_001;
@@ -55,7 +43,6 @@ dotwrite();
#---------------------------------------------------------------------- #----------------------------------------------------------------------
sub usage { sub usage {
print '$Id$ ', "\n";
pod2usage(-verbose=>2, -exitval => 2); pod2usage(-verbose=>2, -exitval => 2);
exit (1); exit (1);
} }
@@ -175,7 +162,7 @@ __END__
=head1 NAME =head1 NAME
dot_pruner - dot_pruner -
=head1 SYNOPSIS =head1 SYNOPSIS
+58
View File
@@ -0,0 +1,58 @@
#!/usr/bin/perl -w
# See copyright, etc in below POD section.
######################################################################
require 5.006_001;
use strict;
#======================================================================
# main
delete $ENV{MODULE_VERSION};
_setup_modules();
module('add','cadence_verif');
exec('iccr',@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_iccr - Invoke tool under "modules" command
=head1 SYNOPSIS
invoke_iccr {ncv arguments}
=head1 DESCRIPTION
=head1 DISTRIBUTION
Copyright 2007-2008 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_iccr -help"
### End:
+1 -13
View File
@@ -1,17 +1,5 @@
#!/usr/bin/perl -w #!/usr/bin/perl -w
# $Id$ # See copyright, etc in below POD section.
######################################################################
#
# Copyright 2007-2008 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; require 5.006_001;
+4
View File
@@ -0,0 +1,4 @@
export GLIBCPP_FORCE_NEW=1
compile with -DVL_LEAK_CHECKS
valgrind --tool=memcheck --leak-check=yes /home/wsnyder/src/verilator/v4/verilator/verilator_bin_dbg -MMD --bin /home/wsnyder/src/verilator/v4/verilator/verilator_bin_dbg --cc -f /home/wsnyder/src/verilator/v4/verilator/test_c/../test_v/input.vc top.v --no-skip-identical 2>&1 | tee ~/d/aa
valgrind --tool=memcheck --leak-check=yes /home/wsnyder/src/verilator/v4/verilator/verilator_bin_dbg -MMD --bin /home/wsnyder/src/verilator/v4/verilator/verilator_bin_dbg --cc /home/wsnyder/src/verilator/v4/verilator/test_regress/t/t_case_huge.v --no-skip-identical -I/home/wsnyder/src/verilator/v4/verilator/test_regress/t 2>&1 | tee ~/d/aa
+3 -16
View File
@@ -1,17 +1,5 @@
#!/usr/bin/perl -w #!/usr/bin/perl -w
# $Id$ # See copyright, etc in below POD section.
######################################################################
#
# Copyright 2005-2008 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; require 5.006_001;
@@ -52,7 +40,6 @@ print '(query-replace-regexp "(\\([0-9a-z_]+\\))" "\\1" nil nil nil)',"\n";
#---------------------------------------------------------------------- #----------------------------------------------------------------------
sub usage { sub usage {
print '$Id$ ', "\n";
pod2usage(-verbose=>2, -exitval => 2); pod2usage(-verbose=>2, -exitval => 2);
exit (1); exit (1);
} }
@@ -292,7 +279,7 @@ sub p_var {
} }
p "\t"; p "\t";
{ {
local $Avoid_Hex=1; local $Avoid_Hex=1;
t1; t1;
} }
p "\t"; p "\t";
@@ -322,7 +309,7 @@ __END__
=head1 NAME =head1 NAME
vtree_importer - vtree_importer -
=head1 SYNOPSIS =head1 SYNOPSIS
+17 -12
View File
@@ -1,6 +1,5 @@
\input texinfo @c -*-texinfo-*- \input texinfo @c -*-texinfo-*-
@c %**start of header @c %**start of header
$c $Id$
@setfilename readme.info @setfilename readme.info
@settitle Verilator Installation @settitle Verilator Installation
@c %**end of header @c %**end of header
@@ -15,13 +14,13 @@ $c $Id$
This is the Verilator Package. This is the Verilator Package.
@menu @menu
* Copyright:: * Copyright::
* Description:: * Description::
* Obtaining Distribution:: * Obtaining Distribution::
* Directory Structure:: * Directory Structure::
* Supported Systems:: * Supported Systems::
* Installation:: * Installation::
* Limitations:: * Limitations::
@end menu @end menu
@node Copyright, Description, Top, Top @node Copyright, Description, Top, Top
@@ -45,7 +44,7 @@ Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It
reads the specified Verilog code, lints it, and optionally adds coverage reads the specified Verilog code, lints it, and optionally adds coverage
code. For C++ format, it outputs .cpp and .h files. For SystemC format, code. For C++ format, it outputs .cpp and .h files. For SystemC format,
it outputs .sp files for the SystemPerl preprocessor available at it outputs .sp files for the SystemPerl preprocessor available at
http://veripool.com. http://www.veripool.org.
The resulting files are then compiled with C++. The user writes a little The resulting files are then compiled with C++. The user writes a little
C++ wrapper file, which instantiates the top level module. This is C++ wrapper file, which instantiates the top level module. This is
@@ -56,11 +55,11 @@ The resulting executable will perform the actual simulation.
@node Obtaining Distribution, Directory Structure, Description, Top @node Obtaining Distribution, Directory Structure, Description, Top
@section Obtaining Distribution @section Obtaining Distribution
The latest version is available at The latest version is available at
@uref{http://veripool.com/verilator.htm} @uref{http://www.veripool.org/verilator}
Download the latest package from that site, and decompress. Download the latest package from that site, and decompress.
@samp{gunzip verilator_version.tar.gz ; tar xvf verilator_version.tar} @samp{tar xvzf verilator_version.tgz}
@node Directory Structure, Supported Systems, Obtaining Distribution, Top @node Directory Structure, Supported Systems, Obtaining Distribution, Top
@section Directory Structure @section Directory Structure
@@ -126,6 +125,12 @@ do a @code{make sc_patch}.
@item @item
Type @samp{./configure} to configure Verilator for your system. Type @samp{./configure} to configure Verilator for your system.
If you are configuring Verilator to be part of a RPM or other
distribution package system, you may want to use the --enable-defenv
configure flag. This will take the current value of VERILATOR_ROOT,
SYSTEMC, SYSTEMC_ARCH, and SYSTEMPERL and build them as defaults into
the executable.
@item @item
Type @samp{make} to compile Verilator. Type @samp{make} to compile Verilator.
View File
+9 -5
View File
@@ -1,9 +1,9 @@
# $Id$ */ # -*- Makefile -*-
#***************************************************************************** #*****************************************************************************
# #
# DESCRIPTION: Verilator: Makefile for verilog source # DESCRIPTION: Verilator: Makefile for verilog source
# #
# Code available from: http://www.veripool.com/verilator # Code available from: http://www.veripool.org/verilator
# #
#***************************************************************************** #*****************************************************************************
# #
@@ -40,12 +40,16 @@ export OBJCACHE_HOSTS := $(shell rschedule --no-allow-reserved --similar hostnam
endif endif
ifeq ($(OBJCACHE_HOSTS),) ifeq ($(OBJCACHE_HOSTS),)
export OBJCACHE := export OBJCACHE :=
else else
export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)") export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)")
export OBJCACHE := @objcache --read --write export OBJCACHE := @objcache --read --write
endif endif
UNDER_GIT = $(wildcard ../.git)
#*********************************************************************
obj_opt: obj_opt:
mkdir $@ mkdir $@
obj_dbg: obj_dbg:
@@ -71,10 +75,10 @@ dbg: ../verilator_bin_dbg
prefiles:: prefiles::
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users ifneq ($(UNDER_GIT),) # If local git tree... Else don't burden users
prefiles:: config_rev.h prefiles:: config_rev.h
# This output goes into srcdir, as we need to distribute it as part of the kit. # This output goes into srcdir, as we need to distribute it as part of the kit.
config_rev.h: config_rev.pl .svn/entries config_rev.h: config_rev.pl ../.git/index
$(PERL) config_rev.pl . >$@ $(PERL) config_rev.pl . >$@
endif endif
+40 -12
View File
@@ -1,9 +1,9 @@
# $Id$ -*- Makefile -*- # -*- Makefile -*-
#***************************************************************************** #*****************************************************************************
# #
# DESCRIPTION: Verilator: Makefile for verilog source # DESCRIPTION: Verilator: Makefile for verilog source
# #
# Code available from: http://www.veripool.com/verilator # Code available from: http://www.veripool.org/verilator
# #
#***************************************************************************** #*****************************************************************************
# #
@@ -23,11 +23,27 @@
srcdir = .. srcdir = ..
incdir = ../../include incdir = ../../include
PERL = @PERL@ # Programs
CC = @CC@ CC = @CC@
CXX = @CXX@ CXX = @CXX@
LINK = @CXX@ LINK = @CXX@
LEX = @LEX@
LFLAGS = -d
PERL = @PERL@
YACC = @YACC@
prefix = @prefix@
# Directory in which to install data across multiple architectures
datarootdir = @datarootdir@
# Directory in which to install package specific files
# Generally ${prefix}/share/verilator
pkgdatadir = @pkgdatadir@
# Compile options
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
CPPFLAGSNOWALL += @CPPFLAGS@
LDFLAGS += @LDFLAGS@ LDFLAGS += @LDFLAGS@
#### End of system configuration section. #### #### End of system configuration section. ####
@@ -48,17 +64,12 @@ COPT = -ggdb -DVL_DEBUG
endif endif
################# #################
LEX = @LEX@
LFLAGS = -d
YACC = @YACC@
YFLAGS = -y -d -v
#LIBS += -ldl #LIBS += -ldl
#CCMALLOC = /usr/local/lib/ccmalloc-gcc.o -lccmalloc -ldl #CCMALLOC = /usr/local/lib/ccmalloc-gcc.o -lccmalloc -ldl
LIBS = -lm -lfl LIBS = -lm -lfl
CPPFLAGSNOWALL = -MMD CPPFLAGSNOWALL += -MMD
CPPFLAGSNOWALL += -I. -I$(srcdir) -I$(incdir) CPPFLAGSNOWALL += -I. -I$(srcdir) -I$(incdir)
CPPFLAGSNOWALL += -DYYDEBUG # Required to get nice error messages CPPFLAGSNOWALL += -DYYDEBUG # Required to get nice error messages
#CPPFLAGSNOWALL += -DVL_LEAK_CHECKS # If running valgrind or other hunting tool #CPPFLAGSNOWALL += -DVL_LEAK_CHECKS # If running valgrind or other hunting tool
@@ -70,9 +81,23 @@ CPPFLAGS += -W -Wall -Wno-unused-parameter -Wno-char-subscripts -Werror
#CPPFLAGS += -pedantic-errors #CPPFLAGS += -pedantic-errors
endif endif
# Allow RPM builds to specify hardcoded data directories
# To do this:
ifeq ($(CFG_WITH_DEFENV),yes)
CPPFLAGS += -DDEFENV_SYSTEMC=\"$(SYSTEMC)\"
CPPFLAGS += -DDEFENV_SYSTEMC_ARCH=\"$(SYSTEMC_ARCH)\"
CPPFLAGS += -DDEFENV_SYSTEMPERL=\"$(SYSTEMPERL)\"
ifeq ($(VERILATOR_ROOT),) # Use what we're given, or intuit
CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(pkgdatadir)\"
else
CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(VERILATOR_ROOT)\"
endif
endif
HEADERS = $(wildcard V*.h v*.h) HEADERS = $(wildcard V*.h v*.h)
ASTGEN = $(srcdir)/astgen ASTGEN = $(srcdir)/astgen
BISONPRE = $(srcdir)/bisonpre
###################################################################### ######################################################################
#### Top level #### Top level
@@ -221,14 +246,17 @@ V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp
#### Generated files #### Generated files
# Target rule called before parallel build to make generated files # Target rule called before parallel build to make generated files
serial:: V3Ast__gen_classes.h serial:: V3Ast__gen_classes.h y.tab.c
V3Ast__gen_classes.h : $(ASTGEN) V3Ast.h V3AstNodes.h V3Ast__gen_classes.h : $(ASTGEN) V3Ast.h V3AstNodes.h
$(PERL) $(ASTGEN) -I$(srcdir) --classes $(PERL) $(ASTGEN) -I$(srcdir) --classes
y.tab.c y.tab.h: verilog.y $(HEADERS) y.tab.h: y.tab.c
# Have only one output file in this rule to prevent parallel make issues
y.tab.c: verilog.y $(HEADERS) bisonpre
@echo "If you get errors from verilog.y below, try upgrading bison to version 1.875 or newer." @echo "If you get errors from verilog.y below, try upgrading bison to version 1.875 or newer."
${YACC} ${YFLAGS} $< $(PERL) $(BISONPRE) --yacc ${YACC} -d -v -o y.tab.c $<
V3Lexer_pregen.yy.cpp: verilog.l y.tab.h $(HEADERS) V3Lexer_pregen.yy.cpp: verilog.l y.tab.h $(HEADERS)
${LEX} ${LFLAGS} -o$@ $< ${LEX} ${LFLAGS} -o$@ $<
+4 -5
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity active domains // DESCRIPTION: Verilator: Break always into sensitivity active domains
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3Active's Transformations: // V3Active's Transformations:
// //
// Note this can be called multiple times. // Note this can be called multiple times.
// Create a IACTIVE(initial), SACTIVE(combo) // Create a IACTIVE(initial), SACTIVE(combo)
// ALWAYS: Remove any-edges from sense list // ALWAYS: Remove any-edges from sense list
@@ -33,8 +32,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <map> #include <map>
#include <algorithm> #include <algorithm>
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity block domains // DESCRIPTION: Verilator: Break always into sensitivity block domains
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+4 -5
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity active domains // DESCRIPTION: Verilator: Break always into sensitivity active domains
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3Active's Transformations: // V3Active's Transformations:
// //
// Note this can be called multiple times. // Note this can be called multiple times.
// Across all ACTIVES // Across all ACTIVES
// SenTrees are now under each ACTIVE statement, we want them global: // SenTrees are now under each ACTIVE statement, we want them global:
@@ -30,8 +29,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity block domains // DESCRIPTION: Verilator: Break always into sensitivity block domains
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+25 -8
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Collect and print statistics // DESCRIPTION: Verilator: Collect and print statistics
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,8 +20,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <map> #include <map>
#include <iomanip> #include <iomanip>
@@ -44,6 +43,7 @@ private:
// STATE // STATE
AstModule* m_modp; // Last module AstModule* m_modp; // Last module
AstBegin* m_beginp; // Last begin
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
@@ -101,12 +101,14 @@ private:
return bodysp; return bodysp;
} }
void newPslAssertion(AstNode* nodep, AstNode* propp, AstSenTree* sentreep, const string& message) { void newPslAssertion(AstNode* nodep, AstNode* propp, AstSenTree* sentreep,
AstNode* stmtsp, const string& message) {
propp->unlinkFrBack(); propp->unlinkFrBack();
sentreep->unlinkFrBack(); sentreep->unlinkFrBack();
if (stmtsp) stmtsp->unlinkFrBack();
// //
AstNode* bodysp = NULL; AstNode* bodysp = NULL;
bool selfDestruct = false; bool selfDestruct = false;
if (AstPslCover* snodep = nodep->castPslCover()) { if (AstPslCover* snodep = nodep->castPslCover()) {
if (!v3Global.opt.coverageUser()) { if (!v3Global.opt.coverageUser()) {
selfDestruct = true; selfDestruct = true;
@@ -127,6 +129,7 @@ private:
} else { } else {
nodep->v3fatalSrc("Unknown node type"); nodep->v3fatalSrc("Unknown node type");
} }
if (stmtsp) bodysp = bodysp->addNext(stmtsp);
AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL); AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL);
bodysp = ifp; bodysp = ifp;
if (nodep->castPslAssert()) ifp->branchPred(AstBranchPred::UNLIKELY); if (nodep->castPslAssert()) ifp->branchPred(AstBranchPred::UNLIKELY);
@@ -233,12 +236,15 @@ private:
virtual void visit(AstPslCover* nodep, AstNUser*) { virtual void visit(AstPslCover* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(), nodep->name()); nodep=NULL; if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name());
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
nodep->stmtsp(), 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);
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(), nodep->name()); nodep=NULL; newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
NULL, nodep->name()); nodep=NULL;
m_statAsPsl++; m_statAsPsl++;
} }
virtual void visit(AstVAssert* nodep, AstNUser*) { virtual void visit(AstVAssert* nodep, AstNUser*) {
@@ -254,6 +260,16 @@ private:
// Reset defaults // Reset defaults
m_modp = NULL; m_modp = NULL;
} }
virtual void visit(AstBegin* nodep, AstNUser*) {
// This code is needed rather than a visitor in V3Begin,
// because V3Assert is called before V3Begin
AstBegin* lastp = m_beginp;
{
m_beginp = nodep;
nodep->iterateChildren(*this);
}
m_beginp = lastp;
}
// VISITORS //========== Temporal Layer // VISITORS //========== Temporal Layer
@@ -269,6 +285,7 @@ private:
public: public:
// CONSTRUCTORS // CONSTRUCTORS
AssertVisitor(AstNetlist* nodep) { AssertVisitor(AstNetlist* nodep) {
m_beginp = NULL;
m_modp = NULL; m_modp = NULL;
// Process // Process
AstNode::userClearTree(); // userp() used on entire tree AstNode::userClearTree(); // userp() used on entire tree
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Assertion expansion // DESCRIPTION: Verilator: Assertion expansion
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+39 -14
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Collect and print statistics // DESCRIPTION: Verilator: Collect and print statistics
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -24,8 +23,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <map> #include <map>
#include <iomanip> #include <iomanip>
@@ -57,10 +56,17 @@ private:
// Return NULL for always // Return NULL for always
AstSenTree* newp = NULL; AstSenTree* newp = NULL;
AstSenItem* senip = m_senip ? m_senip : m_seniDefaultp; AstSenItem* senip = m_senip ? m_senip : m_seniDefaultp;
if (senip) newp = new AstSenTree(nodep->fileline(), senip->cloneTree(true)); if (!senip) {
if (!senip) nodep->v3error("Unsupported: Unclocked assertion"); nodep->v3error("Unsupported: Unclocked assertion");
newp = new AstSenTree(nodep->fileline(), NULL);
} else {
newp = new AstSenTree(nodep->fileline(), senip->cloneTree(true));
}
return newp; return newp;
} }
void clearAssertInfo() {
m_senip = NULL;
}
// VISITORS //========== Statements // VISITORS //========== Statements
virtual void visit(AstPslDefClock* nodep, AstNUser*) { virtual void visit(AstPslDefClock* nodep, AstNUser*) {
@@ -71,28 +77,47 @@ private:
nodep->unlinkFrBack(); nodep->unlinkFrBack();
pushDeletep(nodep); nodep=NULL; pushDeletep(nodep); nodep=NULL;
} }
virtual void visit(AstClocking* nodep, AstNUser*) {
UINFO(8," CLOCKING"<<nodep<<endl);
// Store the new default clock, reset on new module
m_seniDefaultp = nodep->sensesp();
// Trash it, keeping children
if (nodep->bodysp()) {
nodep->replaceWith(nodep->bodysp()->unlinkFrBack());
} else {
nodep->unlinkFrBack();
}
pushDeletep(nodep); nodep=NULL;
}
virtual void visit(AstPslCover* nodep, AstNUser*) { virtual void visit(AstPslCover* nodep, AstNUser*) {
// Prep if (nodep->sentreep()) return; // Already processed
m_senip = NULL; clearAssertInfo();
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
nodep->sentreep(newSenTree(nodep)); nodep->sentreep(newSenTree(nodep));
m_senip = NULL; clearAssertInfo();
} }
virtual void visit(AstPslAssert* nodep, AstNUser*) { virtual void visit(AstPslAssert* nodep, AstNUser*) {
// Prep if (nodep->sentreep()) return; // Already processed
m_senip = NULL; clearAssertInfo();
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
nodep->sentreep(newSenTree(nodep)); nodep->sentreep(newSenTree(nodep));
m_senip = NULL; clearAssertInfo();
} }
virtual void visit(AstPslClocked* nodep, AstNUser*) { virtual void visit(AstPslClocked* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
if (m_senip) { if (m_senip) {
nodep->v3error("Unsupported: Only one PSL clock allowed per assertion\n"); nodep->v3error("Unsupported: Only one PSL clock allowed per assertion\n");
} }
// Unlink and just keep a pointer to it, convert to sentree as needed // Block is the new expression to evaluate
AstNode* blockp = nodep->propp()->unlinkFrBack(); AstNode* blockp = nodep->propp()->unlinkFrBack();
if (nodep->disablep()) {
blockp = new AstAnd(nodep->disablep()->fileline(),
new AstNot(nodep->disablep()->fileline(),
nodep->disablep()->unlinkFrBack()),
blockp);
}
// Unlink and just keep a pointer to it, convert to sentree as needed
m_senip = nodep->sensesp(); m_senip = nodep->sensesp();
nodep->replaceWith(blockp); nodep->replaceWith(blockp);
pushDeletep(nodep); nodep=NULL; pushDeletep(nodep); nodep=NULL;
@@ -109,8 +134,8 @@ private:
public: public:
// CONSTRUCTORS // CONSTRUCTORS
AssertPreVisitor(AstNetlist* nodep) { AssertPreVisitor(AstNetlist* nodep) {
m_senip = NULL;
m_seniDefaultp = NULL; m_seniDefaultp = NULL;
clearAssertInfo();
// Process // Process
nodep->accept(*this); nodep->accept(*this);
} }
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Assertion pre-expansion // DESCRIPTION: Verilator: Assertion pre-expansion
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+74 -25
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Ast node structures // DESCRIPTION: Verilator: Ast node structures
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,8 +18,8 @@
// //
//************************************************************************* //*************************************************************************
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>
#include <memory> #include <memory>
@@ -83,6 +82,35 @@ void AstNode::init() {
m_user5Cnt = 0; m_user5Cnt = 0;
} }
string AstNode::encodeName(const string& namein) {
string name2 = namein;
string out;
const char* start = name2.c_str();
for (const char* pos = start; *pos; pos++) {
if ((pos==start) ? isalpha(pos[0]) // digits can't lead identifiers
: isalnum(pos[0])) {
out += pos[0];
} else if (pos[0]=='_') {
if (pos[1]=='_') {
out += "_"; out += "__5F"; // hex(_) = 0x5F
pos++;
} else {
out += pos[0];
}
} else if (pos[0]=='.') {
out += "__DOT__";
} else if (pos[0]=='[') {
out += "__BRA__";
} else if (pos[0]==']') {
out += "__KET__";
} else {
char hex[10]; sprintf(hex,"%02X",pos[0]);
out += "__"; out += hex;
}
}
return out;
}
string AstNode::shortName() const { string AstNode::shortName() const {
string pretty = name(); string pretty = name();
string::size_type pos; string::size_type pos;
@@ -103,16 +131,37 @@ string AstNode::dedotName(const string& namein) {
} }
string AstNode::prettyName(const string& namein) { string AstNode::prettyName(const string& namein) {
string pretty = namein; string pretty;
string::size_type pos; string name2 = namein;
while ((pos=pretty.find("__BRA__")) != string::npos) { pretty = "";
pretty.replace(pos, 7, "["); for (const char* pos = name2.c_str(); *pos; ) {
} if (0==strncmp(pos,"__BRA__",7)) {
while ((pos=pretty.find("__KET__")) != string::npos) { pretty += "[";
pretty.replace(pos, 7, "]"); pos += 7;
} }
while ((pos=pretty.find("__PVT__")) != string::npos) { else if (0==strncmp(pos,"__KET__",7)) {
pretty.replace(pos, 7, ""); pretty += "]";
pos += 7;
}
else if (0==strncmp(pos,"__DOT__",7)) {
pretty += ".";
pos += 7;
}
else if (0==strncmp(pos,"__PVT__",7)) {
pretty += "";
pos += 7;
}
else if (pos[0]=='_' && pos[1]=='_' && isxdigit(pos[2]) && isxdigit(pos[3])) {
char value = 0;
value += 16*(isdigit(pos[2]) ? (pos[2]-'0') : (tolower(pos[2])-'a'+10));
value += (isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10));
pretty += value;
pos += 4;
}
else {
pretty += pos[0];
pos++;
}
} }
return AstNode::dedotName(pretty); return AstNode::dedotName(pretty);
} }
@@ -238,8 +287,8 @@ void AstNode::addNextHere(AstNode* newp) {
void AstNode::setOp1p(AstNode* newp) { void AstNode::setOp1p(AstNode* newp) {
UASSERT(newp,"Null item passed to setOp1p\n"); UASSERT(newp,"Null item passed to setOp1p\n");
UDEBUGONLY(if (m_op1p) this->v3fatalSrc("Adding to non-empty, non-list op1");); UDEBUGONLY(if (m_op1p) this->v3fatalSrc("Adding to non-empty, non-list op1"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node");); UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op1");); UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op1"););
this->debugTreeChange("-setOp1pThs: ", __LINE__, false); this->debugTreeChange("-setOp1pThs: ", __LINE__, false);
newp->debugTreeChange("-setOp1pNew: ", __LINE__, true); newp->debugTreeChange("-setOp1pNew: ", __LINE__, true);
m_op1p = newp; m_op1p = newp;
@@ -251,8 +300,8 @@ void AstNode::setOp1p(AstNode* newp) {
void AstNode::setOp2p(AstNode* newp) { void AstNode::setOp2p(AstNode* newp) {
UASSERT(newp,"Null item passed to setOp2p\n"); UASSERT(newp,"Null item passed to setOp2p\n");
UDEBUGONLY(if (m_op2p) this->v3fatalSrc("Adding to non-empty, non-list op2");); UDEBUGONLY(if (m_op2p) this->v3fatalSrc("Adding to non-empty, non-list op2"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node");); UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op2");); UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op2"););
this->debugTreeChange("-setOp2pThs: ", __LINE__, false); this->debugTreeChange("-setOp2pThs: ", __LINE__, false);
newp->debugTreeChange("-setOp2pNew: ", __LINE__, true); newp->debugTreeChange("-setOp2pNew: ", __LINE__, true);
m_op2p = newp; m_op2p = newp;
@@ -264,8 +313,8 @@ void AstNode::setOp2p(AstNode* newp) {
void AstNode::setOp3p(AstNode* newp) { void AstNode::setOp3p(AstNode* newp) {
UASSERT(newp,"Null item passed to setOp3p\n"); UASSERT(newp,"Null item passed to setOp3p\n");
UDEBUGONLY(if (m_op3p) this->v3fatalSrc("Adding to non-empty, non-list op3");); UDEBUGONLY(if (m_op3p) this->v3fatalSrc("Adding to non-empty, non-list op3"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node");); UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op3");); UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op3"););
this->debugTreeChange("-setOp3pThs: ", __LINE__, false); this->debugTreeChange("-setOp3pThs: ", __LINE__, false);
newp->debugTreeChange("-setOp3pNew: ", __LINE__, true); newp->debugTreeChange("-setOp3pNew: ", __LINE__, true);
m_op3p = newp; m_op3p = newp;
@@ -277,8 +326,8 @@ void AstNode::setOp3p(AstNode* newp) {
void AstNode::setOp4p(AstNode* newp) { void AstNode::setOp4p(AstNode* newp) {
UASSERT(newp,"Null item passed to setOp4p\n"); UASSERT(newp,"Null item passed to setOp4p\n");
UDEBUGONLY(if (m_op4p) this->v3fatalSrc("Adding to non-empty, non-list op4");); UDEBUGONLY(if (m_op4p) this->v3fatalSrc("Adding to non-empty, non-list op4"););
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node");); UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op4");); UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op4"););
this->debugTreeChange("-setOp4pThs: ", __LINE__, false); this->debugTreeChange("-setOp4pThs: ", __LINE__, false);
newp->debugTreeChange("-setOp4pNew: ", __LINE__, true); newp->debugTreeChange("-setOp4pNew: ", __LINE__, true);
m_op4p = newp; m_op4p = newp;
@@ -627,7 +676,7 @@ void AstNode::iterateListBackwards(AstNVisitor& v, AstNUser* vup) {
while (nodep->m_nextp) nodep=nodep->m_nextp; while (nodep->m_nextp) nodep=nodep->m_nextp;
while (nodep) { while (nodep) {
// Edits not supported: nodep->m_iterpp = &nodep; // Edits not supported: nodep->m_iterpp = &nodep;
nodep->accept(v, vup); nodep->accept(v, vup);
if (nodep->backp()->m_nextp == nodep) nodep=nodep->backp(); if (nodep->backp()->m_nextp == nodep) nodep=nodep->backp();
else nodep = NULL; // else: backp points up the tree. else nodep = NULL; // else: backp points up the tree.
} }
@@ -648,7 +697,7 @@ void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
for (AstNode* nodep=this; nodep;) { for (AstNode* nodep=this; nodep;) {
AstNode* niterp = nodep; AstNode* niterp = nodep;
niterp->m_iterpp = &niterp; niterp->m_iterpp = &niterp;
niterp->accept(v, vup); niterp->accept(v, vup);
// accept may do a replaceNode and change niterp on us... // accept may do a replaceNode and change niterp on us...
if (!niterp) return; if (!niterp) return;
niterp->m_iterpp = NULL; niterp->m_iterpp = NULL;
@@ -665,7 +714,7 @@ void AstNode::iterateAndNextIgnoreEdit(AstNVisitor& v, AstNUser* vup) {
if (!this) return; if (!this) return;
for (AstNode* nodep=this; nodep; ) { for (AstNode* nodep=this; nodep; ) {
AstNode* nnextp = nodep->m_nextp; AstNode* nnextp = nodep->m_nextp;
nodep->accept(v, vup); nodep->accept(v, vup);
nodep = nnextp; nodep = nnextp;
} }
} }
+28 -8
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Ast node structure // DESCRIPTION: Verilator: Ast node structure
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -197,7 +197,8 @@ public:
TRIWIRE, TRIWIRE,
BLOCKTEMP, BLOCKTEMP,
MODULETEMP, MODULETEMP,
STMTTEMP STMTTEMP,
XTEMP
}; };
enum en m_e; enum en m_e;
inline AstVarType () {}; inline AstVarType () {};
@@ -209,7 +210,7 @@ public:
"?","GPARAM","LPARAM","GENVAR", "?","GPARAM","LPARAM","GENVAR",
"INTEGER","INPUT","OUTPUT","INOUT", "INTEGER","INPUT","OUTPUT","INOUT",
"SUPPLY0","SUPPLY1","WIRE","IMPLICIT","REG","TRIWIRE", "SUPPLY0","SUPPLY1","WIRE","IMPLICIT","REG","TRIWIRE",
"BLOCKTEMP","MODULETEMP","STMTTEMP"}; "BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP"};
return names[m_e];}; return names[m_e];};
}; };
inline bool operator== (AstVarType lhs, AstVarType rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (AstVarType lhs, AstVarType rhs) { return (lhs.m_e == rhs.m_e); }
@@ -250,6 +251,25 @@ public:
//###################################################################### //######################################################################
class AstCaseType {
public:
enum en {
CASE,
CASEX,
CASEZ
};
enum en m_e;
inline AstCaseType () {};
inline AstCaseType (en _e) : m_e(_e) {};
explicit inline AstCaseType (int _e) : m_e(static_cast<en>(_e)) {};
operator en () const { return m_e; };
};
inline bool operator== (AstCaseType lhs, AstCaseType rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstCaseType lhs, AstCaseType::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstCaseType::en lhs, AstCaseType rhs) { return (lhs == rhs.m_e); }
//######################################################################
class AstDisplayType { class AstDisplayType {
public: public:
enum en { enum en {
@@ -558,6 +578,7 @@ public:
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 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
static string encodeName(const string& namein); // Encode user name into internal C representation
string prettyName() const { return prettyName(name()); } string prettyName() const { return prettyName(name()); }
FileLine* fileline() const { return m_fileline; } FileLine* fileline() const { return m_fileline; }
int width() const { return m_width; } int width() const { return m_width; }
@@ -650,7 +671,6 @@ public:
virtual bool same(AstNode* otherp) const { return true; } virtual bool same(AstNode* otherp) const { return true; }
virtual bool maybePointedTo() const { return false; } // Another AstNode* may have a pointer into this node, other then normal front/back/etc. virtual bool maybePointedTo() const { return false; } // Another AstNode* may have a pointer into this node, other then normal front/back/etc.
virtual bool broken() const { return false; } virtual bool broken() const { return false; }
virtual bool emitWordForm() { return false; }
// INVOKERS // INVOKERS
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) = 0; virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) = 0;
@@ -681,7 +701,7 @@ struct AstNodeMath : public AstNode {
virtual ~AstNodeMath() {} virtual ~AstNodeMath() {}
// METHODS // METHODS
virtual string emitVerilog() = 0; /// Format string for verilog writing; see V3EmitV virtual string emitVerilog() = 0; /// Format string for verilog writing; see V3EmitV
virtual string emitOperator() = 0; virtual string emitC() = 0;
virtual string emitSimpleOperator() { return ""; } virtual string emitSimpleOperator() { return ""; }
virtual bool cleanOut() = 0; // True if output has extra upper bits zero virtual bool cleanOut() = 0; // True if output has extra upper bits zero
}; };
@@ -783,7 +803,7 @@ struct AstNodeCond : public AstNodeTriop {
AstNode* expr1p() const { return op2p()->castNode(); } // op2 = If true... AstNode* expr1p() const { return op2p()->castNode(); } // op2 = If true...
AstNode* expr2p() const { return op3p()->castNode(); } // op3 = If false... AstNode* expr2p() const { return op3p()->castNode(); } // op3 = If false...
virtual string emitVerilog() { return "%k(%l %k? %r %k: %t)"; } virtual string emitVerilog() { return "%k(%l %k? %r %k: %t)"; }
virtual string emitOperator() { return "VL_COND"; } virtual string emitC() { return "VL_COND_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri, %ti)"; }
virtual bool cleanOut() { return false; } // clean if e1 & e2 clean virtual bool cleanOut() { return false; } // clean if e1 & e2 clean
virtual bool cleanLhs() { return true; } virtual bool cleanLhs() { return true; }
virtual bool cleanRhs() { return false; } virtual bool cleanThs() { return false; } // Propagates up virtual bool cleanRhs() { return false; } virtual bool cleanThs() { return false; } // Propagates up
@@ -1008,7 +1028,7 @@ public:
AstNodeFTaskRef(FileLine* fl, AstNode* namep, AstNode* pinsp) AstNodeFTaskRef(FileLine* fl, AstNode* namep, AstNode* pinsp)
:AstNode(fl) :AstNode(fl)
, m_taskp(NULL) { , m_taskp(NULL) {
setOp1p(namep); addNOp2p(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(); }
+11 -4
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Ast node structures // DESCRIPTION: Verilator: Ast node structures
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,8 +20,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>
#include <vector> #include <vector>
@@ -304,6 +303,10 @@ void AstCellInline::dump(ostream& str) {
this->AstNode::dump(str); this->AstNode::dump(str);
str<<" -> "<<origModName(); str<<" -> "<<origModName();
} }
void AstDisplay::dump(ostream& str) {
this->AstNode::dump(str);
//str<<" "<<displayType().ascii();
}
void AstPin::dump(ostream& str) { 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); }
@@ -414,3 +417,7 @@ void AstCCall::dump(ostream& str) {
funcp()->dump(str); funcp()->dump(str);
} }
} }
void AstCFunc::dump(ostream& str) {
this->AstNode::dump(str);
if (slow()) str<<" [SLOW]";
}
+287 -126
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Ast node structure // DESCRIPTION: Verilator: Ast node structure
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -50,12 +50,13 @@ public:
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 name() const { return num().ascii(); } // * = Value virtual string name() const { return num().ascii(); } // * = Value
virtual const V3Number& num() const { return m_num; } // * = Value virtual const V3Number& num() const { return m_num; } // * = Value
uint32_t asInt() const { return num().asInt(); } uint32_t asInt() const { return num().asInt(); } // Old, should be removed
vluint64_t asQuad() const { return num().asQuad(); } uint32_t toUInt() const { return num().toUInt(); }
vluint64_t toUQuad() const { return num().toUQuad(); }
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() { return true; } virtual bool cleanOut() { return true; }
virtual V3Hash sameHash() const { return V3Hash(num().asHash()); } virtual V3Hash sameHash() const { return V3Hash(num().toHash()); }
virtual bool same(AstNode* samep) const { virtual bool same(AstNode* samep) const {
return num().isCaseEq(samep->castConst()->num()); } return num().isCaseEq(samep->castConst()->num()); }
virtual int instrCount() const { return widthInstrs(); } virtual int instrCount() const { return widthInstrs(); }
@@ -81,7 +82,7 @@ struct AstRange : public AstNode {
int msbConst() const { AstConst* constp=msbp()->castConst(); return (constp?constp->asInt():0); } int msbConst() const { AstConst* constp=msbp()->castConst(); return (constp?constp->asInt():0); }
int lsbConst() const { AstConst* constp=lsbp()->castConst(); return (constp?constp->asInt():0); } int lsbConst() const { AstConst* constp=lsbp()->castConst(); return (constp?constp->asInt():0); }
int elementsConst() const { return msbConst()-lsbConst()+1; } int elementsConst() const { return msbConst()-lsbConst()+1; }
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; }
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; }
}; };
@@ -100,7 +101,7 @@ struct AstArraySel : public AstNodeSel {
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) {
V3ERROR_NA; /* How can from be a const? */ } V3ERROR_NA; /* How can from be a const? */ }
virtual string emitVerilog() { return "%k(%l%k[%r])"; } virtual string emitVerilog() { return "%k(%l%k[%r])"; }
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() { return "%li%k[%ri]"; }
virtual bool cleanOut() { return true; } virtual bool cleanOut() { return true; }
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return false;} 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;}
@@ -133,7 +134,7 @@ struct AstWordSel : public AstNodeSel {
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 void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit) { V3ERROR_NA; } virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit) { V3ERROR_NA; }
virtual string emitVerilog() { return "%k(%l[%r])"; } // Not %k, as usually it's a small constant rhsp virtual string emitVerilog() { return "%k(%l[%r])"; } // Not %k, as usually it's a small constant rhsp
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() { return "%li[%ri]"; } // Not %k, as usually it's a small constant rhsp
virtual bool cleanOut() { return true; } virtual bool cleanOut() { return true; }
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;}
@@ -206,7 +207,10 @@ struct AstSel : public AstNodeTriop {
virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit, const V3Number& width) { virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit, const V3Number& width) {
out.opRange(from, bit.asInt()+width.asInt()-1, bit.asInt()); } out.opRange(from, bit.asInt()+width.asInt()-1, bit.asInt()); }
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() {
return this->widthp()->isOne()
? "VL_BITSEL_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri)"
: "VL_SEL_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri, %ti)"; }
virtual bool cleanOut() { return false; } virtual bool cleanOut() { return false; }
virtual bool cleanLhs() { return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() { return true;} virtual bool cleanRhs() {return true;}
virtual bool cleanThs() {return true;} virtual bool cleanThs() {return true;}
@@ -219,7 +223,7 @@ struct AstSel : public AstNodeTriop {
AstNode* lsbp() const { return op2p()->castNode(); } // op2 = Msb selection expression AstNode* lsbp() const { return op2p()->castNode(); } // op2 = Msb selection expression
AstNode* widthp() const { return op3p()->castNode(); } // op3 = Width AstNode* widthp() const { return op3p()->castNode(); } // op3 = Width
uint32_t lsbConst() const { return lsbp()->castConst()->asInt(); } uint32_t lsbConst() const { return lsbp()->castConst()->asInt(); }
uint32_t widthConst() const { return widthp()->castConst()->asInt(); } uint32_t widthConst() const { return widthp()->castConst()->toUInt(); }
uint32_t msbConst() const { return lsbConst()+widthConst()-1; } uint32_t msbConst() const { return lsbConst()+widthConst()-1; }
}; };
@@ -254,7 +258,7 @@ private:
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_sigModPublic=false; m_sigPublic=false; m_sigModPublic=false;
m_funcLocal=false; m_funcReturn=false; m_funcLocal=false; m_funcReturn=false;
m_attrClockEn=false; m_attrIsolateAssign=false; m_attrClockEn=false; m_attrIsolateAssign=false;
m_fileDescr=false; m_isConst=false; m_isStatic=false; m_fileDescr=false; m_isConst=false; m_isStatic=false;
m_trace=false; m_trace=false;
@@ -332,9 +336,10 @@ public:
bool isSignal() const { return (varType()==AstVarType::WIRE || varType()==AstVarType::IMPLICIT bool isSignal() const { return (varType()==AstVarType::WIRE || varType()==AstVarType::IMPLICIT
|| varType()==AstVarType::REG || varType()==AstVarType::INTEGER); } || varType()==AstVarType::REG || varType()==AstVarType::INTEGER); }
bool isTemp() const { return (varType()==AstVarType::BLOCKTEMP || varType()==AstVarType::MODULETEMP bool isTemp() const { return (varType()==AstVarType::BLOCKTEMP || varType()==AstVarType::MODULETEMP
|| varType()==AstVarType::STMTTEMP); } || varType()==AstVarType::STMTTEMP || varType()==AstVarType::XTEMP); }
bool isStatementTemp() const { return (varType()==AstVarType::STMTTEMP); } bool isStatementTemp() const { return (varType()==AstVarType::STMTTEMP); }
bool isMovableToBlock() const { return (varType()==AstVarType::BLOCKTEMP || isFuncLocal()); } bool isMovableToBlock() const { return (varType()==AstVarType::BLOCKTEMP || isFuncLocal()); }
bool isPure() const { return (varType()==AstVarType::XTEMP); }
bool isParam() const { return (varType()==AstVarType::LPARAM || varType()==AstVarType::GPARAM); } bool isParam() const { return (varType()==AstVarType::LPARAM || varType()==AstVarType::GPARAM); }
bool isGParam() const { return (varType()==AstVarType::GPARAM); } bool isGParam() const { return (varType()==AstVarType::GPARAM); }
bool isGenVar() const { return (varType()==AstVarType::GENVAR); } bool isGenVar() const { return (varType()==AstVarType::GENVAR); }
@@ -531,7 +536,7 @@ public:
&& varp()->name()==samep->castVarRef()->varp()->name()); } && varp()->name()==samep->castVarRef()->varp()->name()); }
virtual int instrCount() const { return widthInstrs()*(lvalue()?1:instrCountLd()); } virtual int instrCount() const { return widthInstrs()*(lvalue()?1:instrCountLd()); }
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() { return true; } virtual bool cleanOut() { return true; }
}; };
@@ -554,12 +559,12 @@ public:
virtual AstNode* clone() { return new AstVarXRef(*this);} virtual AstNode* clone() { return new AstVarXRef(*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 void dump(ostream& str); virtual void dump(ostream& str);
string dotted() const { return m_dotted; } string dotted() const { return m_dotted; }
string prettyDotted() const { return prettyName(dotted()); } string prettyDotted() const { return prettyName(dotted()); }
string inlinedDots() const { return m_inlinedDots; } string inlinedDots() const { return m_inlinedDots; }
void inlinedDots(const string& flag) { m_inlinedDots = flag; } void inlinedDots(const string& flag) { m_inlinedDots = flag; }
virtual string emitVerilog() { V3ERROR_NA; return ""; } virtual string emitVerilog() { V3ERROR_NA; return ""; }
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() { return true; } virtual bool cleanOut() { return true; }
virtual int instrCount() const { return widthInstrs(); } virtual int instrCount() const { return widthInstrs(); }
virtual V3Hash sameHash() const { return V3Hash(V3Hash(varp()),V3Hash(dotted())); } virtual V3Hash sameHash() const { return V3Hash(V3Hash(varp()),V3Hash(dotted())); }
@@ -755,7 +760,7 @@ public:
AstNode* stmtsp() const { return op1p()->castNode(); } // op1 = List of statements AstNode* stmtsp() const { return op1p()->castNode(); } // op1 = List of statements
void addStmtp(AstNode* nodep) { addOp1p(nodep); } void addStmtp(AstNode* nodep) { addOp1p(nodep); }
}; };
struct AstGenerate : public AstNode { struct AstGenerate : public AstNode {
// A Generate/end block // A Generate/end block
// Parents: MODULE // Parents: MODULE
@@ -792,7 +797,7 @@ public:
virtual V3Hash sameHash() const { return V3Hash(m_expect); } virtual V3Hash sameHash() const { return V3Hash(m_expect); }
virtual bool same(AstNode* samep) const { return expect() == samep->castParseRef()->expect(); } virtual bool same(AstNode* samep) const { return expect() == samep->castParseRef()->expect(); }
virtual string emitVerilog() { V3ERROR_NA; return ""; } virtual string emitVerilog() { V3ERROR_NA; return ""; }
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; }
AstParseRefExp expect() const { return m_expect; } AstParseRefExp expect() const { return m_expect; }
// op1 = Components // op1 = Components
AstNode* lhsp() const { return op1p(); } // op1 = List of statements AstNode* lhsp() const { return op1p(); } // op1 = List of statements
@@ -808,7 +813,7 @@ struct AstDot : public AstNode {
virtual AstNode* clone() { return new AstDot(*this);} virtual AstNode* clone() { return new AstDot(*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 emitVerilog() { V3ERROR_NA; return ""; } virtual string emitVerilog() { V3ERROR_NA; return ""; }
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; }
AstNode* lhsp() const { return op1p(); } AstNode* lhsp() const { return op1p(); }
AstNode* rhsp() const { return op2p(); } AstNode* rhsp() const { return op2p(); }
}; };
@@ -1117,7 +1122,7 @@ private:
public: public:
AstCoverDecl(FileLine* fl, int column, const string& type, const string& comment) AstCoverDecl(FileLine* fl, int column, const string& type, const string& comment)
: AstNodeStmt(fl) { : AstNodeStmt(fl) {
m_text = comment; m_typeText = type; m_column = column; m_text = comment; m_typeText = type; m_column = column;
} }
virtual ~AstCoverDecl() {} virtual ~AstCoverDecl() {}
virtual AstType type() const { return AstType::COVERDECL;} virtual AstType type() const { return AstType::COVERDECL;}
@@ -1191,11 +1196,11 @@ struct AstCase : public AstNodeCase {
// exprp Children: MATHs // exprp Children: MATHs
// casesp Children: CASEITEMs // casesp Children: CASEITEMs
private: private:
bool m_casex; // True if casex instead of normal case. AstCaseType m_casex; // 0=case, 1=casex, 2=casez
bool m_fullPragma; // Synthesis full_case bool m_fullPragma; // Synthesis full_case
bool m_parallelPragma; // Synthesis parallel_case bool m_parallelPragma; // Synthesis parallel_case
public: public:
AstCase(FileLine* fileline, bool casex, AstNode* exprp, AstNode* casesp) AstCase(FileLine* fileline, AstCaseType casex, AstNode* exprp, AstNode* casesp)
: AstNodeCase(fileline, exprp, casesp) { : AstNodeCase(fileline, exprp, casesp) {
m_casex=casex; m_casex=casex;
m_fullPragma=false; m_parallelPragma=false; m_fullPragma=false; m_parallelPragma=false;
@@ -1204,11 +1209,14 @@ public:
virtual AstType type() const { return AstType::CASE;} virtual AstType type() const { return AstType::CASE;}
virtual AstNode* clone() { return new AstCase(*this); } virtual AstNode* clone() { return new AstCase(*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 casex()?"casex":"case"; } virtual string verilogKwd() const { return casez()?"casez":casex()?"casex":"case"; }
bool casex() const { return m_casex; } virtual bool same(AstNode* samep) const {
return m_casex==samep->castCase()->m_casex; }
bool casex() const { return m_casex==AstCaseType::CASEX; }
bool casez() const { return m_casex==AstCaseType::CASEZ; }
bool fullPragma() const { return m_fullPragma; } bool fullPragma() const { return m_fullPragma; }
bool parallelPragma() const { return m_parallelPragma; }
void fullPragma(bool flag) { m_fullPragma=flag; } void fullPragma(bool flag) { m_fullPragma=flag; }
bool parallelPragma() const { return m_parallelPragma; }
void parallelPragma(bool flag) { m_parallelPragma=flag; } void parallelPragma(bool flag) { m_parallelPragma=flag; }
}; };
@@ -1254,6 +1262,7 @@ public:
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 void dump(ostream& str);
virtual string verilogKwd() const { return (filep() ? (string)"$f"+(string)displayType().ascii() virtual string verilogKwd() const { return (filep() ? (string)"$f"+(string)displayType().ascii()
: (string)"$"+(string)displayType().ascii()); } : (string)"$"+(string)displayType().ascii()); }
virtual bool isGateOptimizable() const { return false; } virtual bool isGateOptimizable() const { return false; }
@@ -1322,6 +1331,101 @@ struct AstFOpen : public AstNodeStmt {
AstNode* modep() const { return op3p(); } AstNode* modep() const { return op3p(); }
}; };
struct AstFFlush : public AstNodeStmt {
// Parents: stmtlist
// Children: file which must be a varref
AstFFlush(FileLine* fileline, AstNode* filep)
: AstNodeStmt (fileline) {
setNOp2p(filep);
}
virtual ~AstFFlush() {}
virtual AstType type() const { return AstType::FFLUSH;}
virtual AstNode* clone() { return new AstFFlush(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual string verilogKwd() const { return "$fflush"; };
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 true; }
AstNode* filep() const { return op2p(); }
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
};
struct AstFScanF : public AstNodeMath {
// Parents: expr
// Children: file which must be a varref
// Children: varrefs to load
private:
string m_text;
public:
AstFScanF(FileLine* fileline, const string& text, AstNode* filep, AstNode* exprsp)
: AstNodeMath (fileline), m_text(text) {
addNOp1p(exprsp);
setNOp2p(filep);
}
virtual ~AstFScanF() {}
virtual AstType type() const { return AstType::FSCANF;}
virtual AstNode* clone() { return new AstFScanF(*this); }
virtual string name() const { return m_text; }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual string verilogKwd() const { return "$fscanf"; }
virtual string emitVerilog() { V3ERROR_NA; return ""; }
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool isGateOptimizable() const { return false; }
virtual bool isPredictOptimizable() const { return false; }
virtual bool isSplittable() const { return false; } // SPECIAL: has 'visual' ordering
virtual bool isOutputter() const { return true; } // SPECIAL: makes output
virtual bool cleanOut() { return false; }
virtual V3Hash sameHash() const { return V3Hash(text()); }
virtual bool same(AstNode* samep) const {
return text()==samep->castFScanF()->text(); }
AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
string text() const { return m_text; } // * = Text to display
void text(const string& text) { m_text=text; }
AstNode* filep() const { return op2p(); }
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
};
struct AstSScanF : public AstNodeMath {
// Parents: expr
// Children: file which must be a varref
// Children: varrefs to load
private:
string m_text;
public:
AstSScanF(FileLine* fileline, const string& text, AstNode* fromp, AstNode* exprsp)
: AstNodeMath (fileline), m_text(text) {
addNOp1p(exprsp);
setOp2p(fromp);
}
virtual ~AstSScanF() {}
virtual AstType type() const { return AstType::SSCANF;}
virtual AstNode* clone() { return new AstSScanF(*this); }
virtual string name() const { return m_text; }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual string verilogKwd() const { return "$sscanf"; }
virtual string emitVerilog() { V3ERROR_NA; return ""; }
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool isGateOptimizable() const { return false; }
virtual bool isPredictOptimizable() const { return false; }
virtual bool isSplittable() const { return false; } // SPECIAL: has 'visual' ordering
virtual bool isOutputter() const { return true; } // SPECIAL: makes output
virtual bool cleanOut() { return false; }
virtual V3Hash sameHash() const { return V3Hash(text()); }
virtual bool same(AstNode* samep) const {
return text()==samep->castSScanF()->text(); }
AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
string text() const { return m_text; } // * = Text to display
void text(const string& text) { m_text=text; }
AstNode* fromp() const { return op2p(); }
void fromp(AstNode* nodep) { setOp2p(nodep); }
};
struct AstReadMem : public AstNodeStmt { struct AstReadMem : public AstNodeStmt {
private: private:
bool m_isHex; // readmemh, not readmemb bool m_isHex; // readmemh, not readmemb
@@ -1450,9 +1554,8 @@ struct AstChangeXor : public AstNodeBiComAsv {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opChangeXor(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opChangeXor(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l ^ %r)"; } virtual string emitVerilog() { return "%k(%l ^ %r)"; }
virtual string emitOperator() { return "VL_CHANGEXOR"; } virtual string emitC() { return "VL_CHANGEXOR_%li(%lw, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "^"; } virtual string emitSimpleOperator() { return "^"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return false;} // Lclean && Rclean virtual bool cleanOut() {return false;} // Lclean && Rclean
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;}
@@ -1744,14 +1847,21 @@ struct AstScopeName : public AstNode {
struct AstRand : public AstNodeTermop { struct AstRand : public AstNodeTermop {
// Return a random number, based upon width() // Return a random number, based upon width()
AstRand(FileLine* fl, int wwidth) : AstNodeTermop(fl) { private:
width(wwidth,wwidth); } bool m_reset; // Random reset, versus always random
public:
AstRand(FileLine* fl, int wwidth, bool reset) : AstNodeTermop(fl) {
width(wwidth,wwidth); m_reset=reset; }
AstRand(FileLine* fl) : AstNodeTermop(fl), m_reset(false) { }
virtual ~AstRand() {} virtual ~AstRand() {}
virtual AstType type() const { return AstType::RAND;} virtual AstType type() const { return AstType::RAND;}
virtual AstNode* clone() { return new AstRand(*this); } virtual AstNode* clone() { return new AstRand(*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 emitVerilog() { return "$random"; } virtual string emitVerilog() { return "$random"; }
virtual string emitOperator() { return "VL_RAND_RESET"; } virtual string emitC() {
return (m_reset ?
"VL_RAND_RESET_%nq(%nw, %P)"
:"VL_RANDOM_%nq(%nw, %P)"); }
virtual bool cleanOut() { return true; } virtual bool cleanOut() { return true; }
virtual bool isGateOptimizable() const { return false; } virtual bool isGateOptimizable() const { return false; }
virtual bool isPredictOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; }
@@ -1768,7 +1878,7 @@ struct AstTime : public AstNodeTermop {
virtual AstNode* clone() { return new AstTime(*this); } virtual AstNode* clone() { return new AstTime(*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 emitVerilog() { return "$time"; } virtual string emitVerilog() { return "$time"; }
virtual string emitOperator() { return "VL_TIME"; } virtual string emitC() { return "VL_TIME_%nq()"; }
virtual bool cleanOut() { return true; } virtual bool cleanOut() { return true; }
virtual bool isGateOptimizable() const { return false; } virtual bool isGateOptimizable() const { return false; }
virtual bool isPredictOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; }
@@ -1790,7 +1900,7 @@ public:
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 bool cleanOut() { return false; } virtual bool cleanOut() { return false; }
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; }
AstNode* bodysp() const { return op1p()->castNode(); } // op1= expressions to print AstNode* bodysp() const { return op1p()->castNode(); } // op1= expressions to print
virtual bool isSplittable() const { return false; } // SPECIAL: User may order w/other sigs virtual bool isSplittable() const { return false; } // SPECIAL: User may order w/other sigs
virtual bool isOutputter() const { return true; } virtual bool isOutputter() const { return true; }
@@ -1814,8 +1924,7 @@ struct AstUnaryMin : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opUnaryMin(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opUnaryMin(lhs); }
virtual string emitVerilog() { return "%k(- %l)"; } virtual string emitVerilog() { return "%k(- %l)"; }
virtual string emitOperator() { return "VL_UNARYMIN"; } virtual string emitC() { return "VL_UNARYMIN_%lq(%lW, %P, %li)"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;}
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersLhs() {return true;}
}; };
@@ -1828,7 +1937,7 @@ struct AstRedAnd : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedAnd(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedAnd(lhs); }
virtual string emitVerilog() { return "%k(& %l)"; } virtual string emitVerilog() { return "%k(& %l)"; }
virtual string emitOperator() { return "VL_REDAND"; } virtual string emitC() { return "VL_REDAND_%nq%lq(%nw,%lw, %P, %li)"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersLhs() {return false;}
}; };
@@ -1841,8 +1950,7 @@ struct AstRedOr : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedOr(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedOr(lhs); }
virtual string emitVerilog() { return "%k(| %l)"; } virtual string emitVerilog() { return "%k(| %l)"; }
virtual string emitOperator() { return "VL_REDOR"; } virtual string emitC() { return "VL_REDOR_%lq(%lW, %P, %li)"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersLhs() {return false;}
}; };
@@ -1855,8 +1963,7 @@ struct AstRedXor : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXor(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXor(lhs); }
virtual string emitVerilog() { return "%k(^ %l)"; } virtual string emitVerilog() { return "%k(^ %l)"; }
virtual string emitOperator() { return "VL_REDXOR"; } virtual string emitC() { return "VL_REDXOR_%lq(%lW, %P, %li)"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return (lhsp()->width()!=1 && lhsp()->width()!=2 && lhsp()->width()!=4 virtual bool cleanLhs() {return (lhsp()->width()!=1 && lhsp()->width()!=2 && lhsp()->width()!=4
&& lhsp()->width()!=8 && lhsp()->width()!=16);} && lhsp()->width()!=8 && lhsp()->width()!=16);}
@@ -1873,8 +1980,7 @@ struct AstRedXnor : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXnor(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXnor(lhs); }
virtual string emitVerilog() { return "%k(~^ %l)"; } virtual string emitVerilog() { return "%k(~^ %l)"; }
virtual string emitOperator() { v3fatalSrc("REDXNOR should have became REDXOR"); return ""; } virtual string emitC() { v3fatalSrc("REDXNOR should have became REDXOR"); return ""; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersLhs() {return false;}
virtual int instrCount() const { return 1+V3Number::log2b(width()); } virtual int instrCount() const { return 1+V3Number::log2b(width()); }
@@ -1889,7 +1995,7 @@ struct AstLogNot : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opLogNot(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opLogNot(lhs); }
virtual string emitVerilog() { return "%k(! %l)"; } virtual string emitVerilog() { return "%k(! %l)"; }
virtual string emitOperator() { return "VL_LOGNOT"; } virtual string emitC() { return "VL_LOGNOT_%nq%lq(%nw,%lw, %P, %li)"; }
virtual string emitSimpleOperator() { return "!"; } virtual string emitSimpleOperator() { return "!"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersLhs() {return false;}
@@ -1903,9 +2009,8 @@ struct AstNot : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opNot(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opNot(lhs); }
virtual string emitVerilog() { return "%k(~ %l)"; } virtual string emitVerilog() { return "%k(~ %l)"; }
virtual string emitOperator() { return "VL_NOT"; } virtual string emitC() { return "VL_NOT_%lq(%lW, %P, %li)"; }
virtual string emitSimpleOperator() { return "~"; } virtual string emitSimpleOperator() { return "~"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;}
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersLhs() {return true;}
}; };
@@ -1918,7 +2023,7 @@ struct AstExtend : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); }
virtual string emitVerilog() { return "%l"; } virtual string emitVerilog() { return "%l"; }
virtual string emitOperator() { return "VL_EXTEND"; } virtual string emitC() { return "VL_EXTEND_%nq%lq(%nw,%lw, %P, %li)"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;} // Because the EXTEND operator self-casts virtual bool sizeMattersLhs() {return false;} // Because the EXTEND operator self-casts
virtual int instrCount() const { return 0; } virtual int instrCount() const { return 0; }
@@ -1932,7 +2037,7 @@ struct AstExtendS : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opExtendS(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opExtendS(lhs); }
virtual string emitVerilog() { return "%l"; } virtual string emitVerilog() { return "%l"; }
virtual string emitOperator() { return "VL_EXTENDS"; } virtual string emitC() { return "VL_EXTENDS_%nq%lq(%nw,%lw, %P, %li)"; }
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;} // Because the EXTEND operator self-casts virtual bool sizeMattersLhs() {return false;} // Because the EXTEND operator self-casts
virtual int instrCount() const { return 0; } virtual int instrCount() const { return 0; }
@@ -1949,7 +2054,7 @@ struct AstSigned : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); }
virtual string emitVerilog() { return "%k$signed(%l)"; } virtual string emitVerilog() { return "%k$signed(%l)"; }
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters
virtual bool sizeMattersLhs() {return true;} // Eliminated before matters virtual bool sizeMattersLhs() {return true;} // Eliminated before matters
virtual int instrCount() const { return 0; } virtual int instrCount() const { return 0; }
@@ -1965,11 +2070,24 @@ struct AstUnsigned : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); }
virtual string emitVerilog() { return "%k$unsigned(%l)"; } virtual string emitVerilog() { return "%k$unsigned(%l)"; }
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters
virtual bool sizeMattersLhs() {return true;} // Eliminated before matters virtual bool sizeMattersLhs() {return true;} // Eliminated before matters
virtual int instrCount() const { return 0; } virtual int instrCount() const { return 0; }
}; };
struct AstCLog2 : public AstNodeUniop {
AstCLog2(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
virtual ~AstCLog2() {}
virtual AstType type() const { return AstType::CLOG2;}
virtual AstNode* clone() { return new AstCLog2(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opCLog2(lhs); }
virtual string emitVerilog() { return "%k$clog2(%l)"; }
virtual string emitC() { return "VL_CLOG2_%lq(%lW, %P, %li)"; }
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;}
virtual int instrCount() const { return widthInstrs()*16; }
};
struct AstCountOnes : public AstNodeUniop { struct AstCountOnes : public AstNodeUniop {
// Number of bits set in vector // Number of bits set in vector
AstCountOnes(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {} AstCountOnes(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
@@ -1979,8 +2097,7 @@ struct AstCountOnes : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opCountOnes(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opCountOnes(lhs); }
virtual string emitVerilog() { return "%k$countones(%l)"; } virtual string emitVerilog() { return "%k$countones(%l)"; }
virtual bool emitWordForm() { return true; } virtual string emitC() { return "VL_COUNTONES_%lq(%lW, %P, %li)"; }
virtual string emitOperator() { return "VL_COUNTONES"; }
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;} virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersLhs() {return false;}
virtual int instrCount() const { return widthInstrs()*16; } virtual int instrCount() const { return widthInstrs()*16; }
@@ -1995,7 +2112,7 @@ struct AstIsUnknown : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opIsUnknown(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opIsUnknown(lhs); }
virtual string emitVerilog() { return "%k$isunknown(%l)"; } virtual string emitVerilog() { return "%k$isunknown(%l)"; }
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersLhs() {return false;}
}; };
@@ -2009,8 +2126,7 @@ struct AstOneHot : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opOneHot(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opOneHot(lhs); }
virtual string emitVerilog() { return "%k$onehot(%l)"; } virtual string emitVerilog() { return "%k$onehot(%l)"; }
virtual bool emitWordForm() { return true; } virtual string emitC() { return "VL_ONEHOT_%lq(%lW, %P, %li)"; }
virtual string emitOperator() { return "VL_ONEHOT"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersLhs() {return false;}
virtual int instrCount() const { return widthInstrs()*4; } virtual int instrCount() const { return widthInstrs()*4; }
@@ -2025,8 +2141,7 @@ struct AstOneHot0 : public AstNodeUniop {
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opOneHot0(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opOneHot0(lhs); }
virtual string emitVerilog() { return "%k$onehot0(%l)"; } virtual string emitVerilog() { return "%k$onehot0(%l)"; }
virtual bool emitWordForm() { return true; } virtual string emitC() { return "VL_ONEHOT0_%lq(%lW, %P, %li)"; }
virtual string emitOperator() { return "VL_ONEHOT0"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersLhs() {return false;}
virtual int instrCount() const { return widthInstrs()*3; } virtual int instrCount() const { return widthInstrs()*3; }
@@ -2051,7 +2166,7 @@ public:
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 void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); }
virtual string emitVerilog() { return "%k$_CAST(%l)"; } virtual string emitVerilog() { return "%k$_CAST(%l)"; }
virtual string emitOperator() { return "VL_CAST"; } virtual string emitC() { return "VL_CAST_%nq%lq(%nw,%lw, %P, %li)"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;} // Special cased in V3Cast virtual bool sizeMattersLhs() {return false;} // Special cased in V3Cast
virtual V3Hash sameHash() const { return V3Hash(size()); } virtual V3Hash sameHash() const { return V3Hash(size()); }
@@ -2061,6 +2176,37 @@ public:
int size() const { return m_size; } int size() const { return m_size; }
}; };
struct AstFEof : public AstNodeUniop {
AstFEof(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
virtual ~AstFEof() {}
virtual AstType type() const { return AstType::FEOF;}
virtual AstNode* clone() { return new AstFEof(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; }
virtual string emitVerilog() { return "%k$feof(%l)"; }
virtual string emitC() { return "(%li ? feof(VL_CVT_Q_FP(%li)) : true)"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;}
virtual int instrCount() const { return widthInstrs()*16; }
AstNode* filep() const { return lhsp(); }
};
struct AstFGetC : public AstNodeUniop {
AstFGetC(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
virtual ~AstFGetC() {}
virtual AstType type() const { return AstType::FEOF;}
virtual AstNode* clone() { return new AstFGetC(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; }
virtual string emitVerilog() { return "%k$fgetc(%l)"; }
// Non-existant filehandle returns EOF
virtual string emitC() { return "(%li ? fgetc(VL_CVT_Q_FP(%li)) : -1)"; }
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
virtual bool sizeMattersLhs() {return false;}
virtual int instrCount() const { return widthInstrs()*64; }
AstNode* filep() const { return lhsp(); }
};
//====================================================================== //======================================================================
// Binary ops // Binary ops
@@ -2073,7 +2219,7 @@ struct AstLogOr : public AstNodeBiComAsv {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogOr(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogOr(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k|| %r)"; } virtual string emitVerilog() { return "%k(%l %k|| %r)"; }
virtual string emitOperator() { return "VL_LOGOR"; } virtual string emitC() { return "VL_LOGOR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "||"; } virtual string emitSimpleOperator() { return "||"; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
@@ -2089,7 +2235,7 @@ struct AstLogAnd : public AstNodeBiComAsv {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogAnd(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogAnd(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k&& %r)"; } virtual string emitVerilog() { return "%k(%l %k&& %r)"; }
virtual string emitOperator() { return "VL_LOGAND"; } virtual string emitC() { return "VL_LOGAND_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "&&"; } virtual string emitSimpleOperator() { return "&&"; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
@@ -2105,7 +2251,7 @@ struct AstLogIf : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
virtual string emitVerilog() { return "%k(%l %k-> %r)"; } virtual string emitVerilog() { return "%k(%l %k-> %r)"; }
virtual string emitOperator() { return "VL_LOGIF"; } virtual string emitC() { return "VL_LOGIF_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "->"; } virtual string emitSimpleOperator() { return "->"; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
@@ -2121,7 +2267,7 @@ struct AstLogIff : public AstNodeBiCom {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
virtual string emitVerilog() { return "%k(%l %k<-> %r)"; } virtual string emitVerilog() { return "%k(%l %k<-> %r)"; }
virtual string emitOperator() { return "VL_LOGIFF"; } virtual string emitC() { return "VL_LOGIFF_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "<->"; } virtual string emitSimpleOperator() { return "<->"; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
@@ -2137,9 +2283,8 @@ struct AstOr : public AstNodeBiComAsv {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opOr(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opOr(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k| %r)"; } virtual string emitVerilog() { return "%k(%l %k| %r)"; }
virtual string emitOperator() { return "VL_OR"; } virtual string emitC() { return "VL_OR_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "|"; } virtual string emitSimpleOperator() { return "|"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {V3ERROR_NA; return false;} // Lclean && Rclean virtual bool cleanOut() {V3ERROR_NA; return false;} // Lclean && Rclean
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
@@ -2153,9 +2298,8 @@ struct AstAnd : public AstNodeBiComAsv {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAnd(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAnd(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k& %r)"; } virtual string emitVerilog() { return "%k(%l %k& %r)"; }
virtual string emitOperator() { return "VL_AND"; } virtual string emitC() { return "VL_AND_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "&"; } virtual string emitSimpleOperator() { return "&"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {V3ERROR_NA; return false;} // Lclean || Rclean virtual bool cleanOut() {V3ERROR_NA; return false;} // Lclean || Rclean
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
@@ -2169,9 +2313,8 @@ struct AstXor : public AstNodeBiComAsv {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opXor(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opXor(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k^ %r)"; } virtual string emitVerilog() { return "%k(%l %k^ %r)"; }
virtual string emitOperator() { return "VL_XOR"; } virtual string emitC() { return "VL_XOR_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "^"; } virtual string emitSimpleOperator() { return "^"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return false;} // Lclean && Rclean virtual bool cleanOut() {return false;} // Lclean && Rclean
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
@@ -2185,9 +2328,8 @@ struct AstXnor : public AstNodeBiComAsv {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opXnor(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opXnor(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k^ ~ %r)"; } virtual string emitVerilog() { return "%k(%l %k^ ~ %r)"; }
virtual string emitOperator() { return "VL_XNOR"; } virtual string emitC() { return "VL_XNOR_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "^ ~"; } virtual string emitSimpleOperator() { return "^ ~"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
@@ -2201,9 +2343,8 @@ struct AstEq : public AstNodeBiCom {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEq(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k== %r)"; } virtual string emitVerilog() { return "%k(%l %k== %r)"; }
virtual string emitOperator() { return "VL_EQ"; } virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "=="; } virtual string emitSimpleOperator() { return "=="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2217,9 +2358,8 @@ struct AstNeq : public AstNodeBiCom {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeq(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k!= %r)"; } virtual string emitVerilog() { return "%k(%l %k!= %r)"; }
virtual string emitOperator() { return "VL_NEQ"; } virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "!="; } virtual string emitSimpleOperator() { return "!="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2233,9 +2373,8 @@ struct AstLt : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLt(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLt(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k< %r)"; } virtual string emitVerilog() { return "%k(%l %k< %r)"; }
virtual string emitOperator() { return "VL_LT"; } virtual string emitC() { return "VL_LT_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "<"; } virtual string emitSimpleOperator() { return "<"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2249,9 +2388,8 @@ struct AstLtS : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtS(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k< %r)"; } virtual string emitVerilog() { return "%k(%l %k< %r)"; }
virtual string emitOperator() { return "VL_LTS"; } virtual string emitC() { return "VL_LTS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return ""; } virtual string emitSimpleOperator() { return ""; }
virtual bool emitWordForm() { return false; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2266,9 +2404,8 @@ struct AstGt : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGt(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGt(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k> %r)"; } virtual string emitVerilog() { return "%k(%l %k> %r)"; }
virtual string emitOperator() { return "VL_GT"; } virtual string emitC() { return "VL_GT_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return ">"; } virtual string emitSimpleOperator() { return ">"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2282,9 +2419,8 @@ struct AstGtS : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtS(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k> %r)"; } virtual string emitVerilog() { return "%k(%l %k> %r)"; }
virtual string emitOperator() { return "VL_GTS"; } virtual string emitC() { return "VL_GTS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return ""; } virtual string emitSimpleOperator() { return ""; }
virtual bool emitWordForm() { return false; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2299,9 +2435,8 @@ struct AstGte : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGte(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGte(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k>= %r)"; } virtual string emitVerilog() { return "%k(%l %k>= %r)"; }
virtual string emitOperator() { return "VL_GTE"; } virtual string emitC() { return "VL_GTE_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return ">="; } virtual string emitSimpleOperator() { return ">="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2315,9 +2450,8 @@ struct AstGteS : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteS(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k>= %r)"; } virtual string emitVerilog() { return "%k(%l %k>= %r)"; }
virtual string emitOperator() { return "VL_GTES"; } virtual string emitC() { return "VL_GTES_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return ""; } virtual string emitSimpleOperator() { return ""; }
virtual bool emitWordForm() { return false; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2332,9 +2466,8 @@ struct AstLte : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLte(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLte(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k<= %r)"; } virtual string emitVerilog() { return "%k(%l %k<= %r)"; }
virtual string emitOperator() { return "VL_LTE"; } virtual string emitC() { return "VL_LTE_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "<="; } virtual string emitSimpleOperator() { return "<="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2348,9 +2481,8 @@ struct AstLteS : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteS(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k<= %r)"; } virtual string emitVerilog() { return "%k(%l %k<= %r)"; }
virtual string emitOperator() { return "VL_LTES"; } virtual string emitC() { return "VL_LTES_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return ""; } virtual string emitSimpleOperator() { return ""; }
virtual bool emitWordForm() { return false; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2367,7 +2499,7 @@ struct AstShiftL : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftL(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftL(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k<< %r)"; } virtual string emitVerilog() { return "%k(%l %k<< %r)"; }
virtual string emitOperator() { return "VL_SHIFTL"; } virtual string emitC() { return "VL_SHIFTL_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "<<"; } virtual string emitSimpleOperator() { return "<<"; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return true;}
@@ -2384,7 +2516,7 @@ struct AstShiftR : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftR(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftR(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k>> %r)"; } virtual string emitVerilog() { return "%k(%l %k>> %r)"; }
virtual string emitOperator() { return "VL_SHIFTR"; } virtual string emitC() { return "VL_SHIFTR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return ">>"; } virtual string emitSimpleOperator() { return ">>"; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
@@ -2401,7 +2533,7 @@ struct AstShiftRS : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftRS(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftRS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k>>> %r)"; } virtual string emitVerilog() { return "%k(%l %k>>> %r)"; }
virtual string emitOperator() { return "VL_SHIFTRS"; } virtual string emitC() { return "VL_SHIFTRS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return ""; } virtual string emitSimpleOperator() { return ""; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
@@ -2417,9 +2549,8 @@ struct AstAdd : public AstNodeBiComAsv {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAdd(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAdd(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k+ %r)"; } virtual string emitVerilog() { return "%k(%l %k+ %r)"; }
virtual string emitOperator() { return "VL_ADD"; } virtual string emitC() { return "VL_ADD_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "+"; } virtual string emitSimpleOperator() { return "+"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
@@ -2433,9 +2564,8 @@ struct AstSub : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opSub(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opSub(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k- %r)"; } virtual string emitVerilog() { return "%k(%l %k- %r)"; }
virtual string emitOperator() { return "VL_SUB"; } virtual string emitC() { return "VL_SUB_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "-"; } virtual string emitSimpleOperator() { return "-"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;} virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
@@ -2449,9 +2579,8 @@ struct AstMul : public AstNodeBiComAsv {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMul(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMul(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k* %r)"; } virtual string emitVerilog() { return "%k(%l %k* %r)"; }
virtual string emitOperator() { return "VL_MUL"; } virtual string emitC() { return "VL_MUL_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "*"; } virtual string emitSimpleOperator() { return "*"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
@@ -2466,9 +2595,8 @@ struct AstMulS : public AstNodeBiComAsv {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMulS(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMulS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k* %r)"; } virtual string emitVerilog() { return "%k(%l %k* %r)"; }
virtual string emitOperator() { return "VL_MULS"; } virtual string emitC() { return "VL_MULS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return ""; } virtual string emitSimpleOperator() { return ""; }
virtual bool emitWordForm() { return false; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
@@ -2484,8 +2612,7 @@ struct AstDiv : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDiv(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDiv(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k/ %r)"; } virtual string emitVerilog() { return "%k(%l %k/ %r)"; }
virtual string emitOperator() { return "VL_DIV"; } virtual string emitC() { return "VL_DIV_%lq(%lW, %P, %li, %ri)"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
@@ -2500,8 +2627,7 @@ struct AstDivS : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDivS(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDivS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k/ %r)"; } virtual string emitVerilog() { return "%k(%l %k/ %r)"; }
virtual string emitOperator() { return "VL_DIVS"; } virtual string emitC() { return "VL_DIVS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual bool emitWordForm() { return false; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
@@ -2517,8 +2643,7 @@ struct AstModDiv : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opModDiv(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opModDiv(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k%% %r)"; } virtual string emitVerilog() { return "%k(%l %k%% %r)"; }
virtual string emitOperator() { return "VL_MODDIV"; } virtual string emitC() { return "VL_MODDIV_%lq(%lW, %P, %li, %ri)"; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
@@ -2533,8 +2658,7 @@ struct AstModDivS : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opModDivS(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opModDivS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k%% %r)"; } virtual string emitVerilog() { return "%k(%l %k%% %r)"; }
virtual string emitOperator() { return "VL_MODDIVS"; } virtual string emitC() { return "VL_MODDIVS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual bool emitWordForm() { return false; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
@@ -2550,8 +2674,7 @@ struct AstPow : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPow(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPow(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k** %r)"; } virtual string emitVerilog() { return "%k(%l %k** %r)"; }
virtual string emitOperator() { return "VL_POW"; } virtual string emitC() { return "VL_POW_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual bool emitWordForm() { return false; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;}
@@ -2566,8 +2689,7 @@ struct AstPowS : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowS(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowS(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k** %r)"; } virtual string emitVerilog() { return "%k(%l %k** %r)"; }
virtual string emitOperator() { return "VL_POWS"; } virtual string emitC() { return "VL_POWS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual bool emitWordForm() { return false; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;} virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;}
@@ -2583,9 +2705,8 @@ struct AstEqCase : public AstNodeBiCom {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseEq(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseEq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k=== %r)"; } virtual string emitVerilog() { return "%k(%l %k=== %r)"; }
virtual string emitOperator() { return "VL_EQ"; } // Until have 4 state anyways virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "=="; } virtual string emitSimpleOperator() { return "=="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2599,9 +2720,8 @@ struct AstNeqCase : public AstNodeBiCom {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseNeq(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseNeq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k!== %r)"; } virtual string emitVerilog() { return "%k(%l %k!== %r)"; }
virtual string emitOperator() { return "VL_NEQ"; } // Until have 4 state anyways virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "!="; } virtual string emitSimpleOperator() { return "!="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2616,9 +2736,8 @@ struct AstEqWild : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildEq(lhs,rhs); } 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 emitVerilog() { return "%k(%l %k==? %r)"; }
virtual string emitOperator() { return "VL_EQ"; } // Until have 4 state anyways virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "=="; } virtual string emitSimpleOperator() { return "=="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2632,9 +2751,8 @@ struct AstNeqWild : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildNeq(lhs,rhs); } 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 emitVerilog() { return "%k(%l %k!=? %r)"; }
virtual string emitOperator() { return "VL_NEQ"; } // Until have 4 state anyways virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; }
virtual string emitSimpleOperator() { return "!="; } virtual string emitSimpleOperator() { return "!="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2650,7 +2768,7 @@ struct AstConcat : public AstNodeBiop {
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 emitVerilog() { return "%k{%l, %k%r}"; } virtual string emitVerilog() { return "%k{%l, %k%r}"; }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opConcat(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opConcat(lhs,rhs); }
virtual string emitOperator() { return "VL_CONCAT"; } virtual string emitC() { return "VL_CONCAT_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual bool cleanOut() {return true;} virtual bool cleanOut() {return true;}
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;}
@@ -2666,12 +2784,28 @@ struct AstReplicate : public AstNodeBiop {
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 void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opRepl(lhs,rhs); } virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opRepl(lhs,rhs); }
virtual string emitVerilog() { return "%k{%l{%k%r}}"; } virtual string emitVerilog() { return "%k{%l{%k%r}}"; }
virtual string emitOperator() { return "VL_REPLICATE"; } virtual string emitC() { return "VL_REPLICATE_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
virtual bool cleanOut() {return false;} virtual bool cleanOut() {return false;}
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;}
virtual int instrCount() const { return widthInstrs()*2; } virtual int instrCount() const { return widthInstrs()*2; }
}; };
struct AstFGetS : public AstNodeBiop {
AstFGetS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {}
virtual ~AstFGetS() {}
virtual AstType type() const { return AstType::FEOF;}
virtual AstNode* clone() { return new AstFGetS(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
virtual string emitVerilog() { return "%k$fgets(%l,%r)"; }
virtual string emitC() { return "VL_FGETS_%nqX%rq(%lw, %P, &(%li), %ri)"; }
virtual bool cleanOut() {return false;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
virtual int instrCount() const { return widthInstrs()*64; }
AstNode* strgp() const { return lhsp(); }
AstNode* filep() const { return rhsp(); }
};
//====================================================================== //======================================================================
// SysVerilog assertions // SysVerilog assertions
@@ -2697,6 +2831,27 @@ struct AstVAssert : public AstNodeStmt {
AstNode* failsp() const { return op3p(); } // op3 = if fails AstNode* failsp() const { return op3p(); } // op3 = if fails
}; };
//======================================================================
// Assertions
struct AstClocking : public AstNode {
// Set default clock region
// Parents: MODULE
// Children: Assertions
public:
AstClocking(FileLine* fl, AstSenItem* sensesp, AstNode* bodysp)
: AstNode(fl) {
addOp1p(sensesp);
addNOp2p(bodysp);
}
virtual ~AstClocking() {}
virtual AstType type() const { return AstType::CLOCKING;}
virtual AstNode* clone() { return new AstClocking(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
AstSenItem* sensesp() const { return op1p()->castSenItem(); } // op1 = Sensitivity list
AstNode* bodysp() const { return op2p(); } // op2 = Body
};
//====================================================================== //======================================================================
// PSL // PSL
@@ -2721,17 +2876,19 @@ struct AstPslClocked : public AstNode {
// Parents: ASSERT|COVER (property) // Parents: ASSERT|COVER (property)
// Children: SENITEM, Properties // Children: SENITEM, Properties
public: public:
AstPslClocked(FileLine* fl, AstSenItem* sensesp, AstNode* propp) AstPslClocked(FileLine* fl, AstSenItem* sensesp, AstNode* disablep, AstNode* propp)
: AstNode(fl) { : AstNode(fl) {
addNOp1p(sensesp); addNOp1p(sensesp);
addOp2p(propp); addNOp2p(disablep);
addOp3p(propp);
} }
virtual ~AstPslClocked() {} virtual ~AstPslClocked() {}
virtual AstType type() const { return AstType::PSLCLOCKED;} virtual AstType type() const { return AstType::PSLCLOCKED;}
virtual AstNode* clone() { return new AstPslClocked(*this); } virtual AstNode* clone() { return new AstPslClocked(*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); }
AstSenItem* sensesp() const { return op1p()->castSenItem(); } // op1 = Sensitivity list AstSenItem* sensesp() const { return op1p()->castSenItem(); } // op1 = Sensitivity list
AstNode* propp() const { return op2p(); } // op2 = property AstNode* disablep() const { return op2p(); } // op2 = disable
AstNode* propp() const { return op3p(); } // op3 = property
}; };
struct AstPslAssert : public AstNodeStmt { struct AstPslAssert : public AstNodeStmt {
@@ -2765,10 +2922,11 @@ struct AstPslCover : public AstNodeStmt {
private: private:
string m_name; // Name to report string m_name; // Name to report
public: public:
AstPslCover(FileLine* fl, AstNode* propp, const string& name="") AstPslCover(FileLine* fl, AstNode* propp, AstNode* stmtsp, const string& name="")
: AstNodeStmt(fl) : AstNodeStmt(fl)
, m_name(name) { , m_name(name) {
addOp1p(propp); addOp1p(propp);
addNOp4p(stmtsp);
} }
virtual ~AstPslCover() {} virtual ~AstPslCover() {}
virtual AstType type() const { return AstType::PSLCOVER;} virtual AstType type() const { return AstType::PSLCOVER;}
@@ -2777,11 +2935,13 @@ public:
virtual string name() const { return m_name; } // * = Var name virtual string name() const { return m_name; } // * = Var name
virtual V3Hash sameHash() const { return V3Hash(name()); } virtual V3Hash sameHash() const { return V3Hash(name()); }
virtual bool same(AstNode* samep) const { return samep->name() == name(); } virtual bool same(AstNode* samep) const { return samep->name() == name(); }
void name(const string& flag) { m_name = flag; }
AstNode* propp() const { return op1p(); } // op1 = property AstNode* propp() const { return op1p(); } // op1 = property
AstSenTree* sentreep() const { return op2p()->castSenTree(); } // op2 = clock domain AstSenTree* sentreep() const { return op2p()->castSenTree(); } // op2 = clock domain
void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain
AstNode* coverincp() const { return op3p(); } // op3 = coverage node AstNode* coverincp() const { return op3p(); } // op3 = coverage node
void coverincp(AstCoverInc* nodep) { addOp3p(nodep); } // op3 = coverage node void coverincp(AstCoverInc* nodep) { addOp3p(nodep); } // op3 = coverage node
AstNode* stmtsp() const { return op4p(); } // op4 = statements
}; };
//====================================================================== //======================================================================
@@ -2984,6 +3144,7 @@ public:
virtual string name() const { return m_name; } virtual string name() const { return m_name; }
virtual bool broken() const { return ( (m_scopep && !m_scopep->brokeExists())); } virtual bool broken() const { return ( (m_scopep && !m_scopep->brokeExists())); }
virtual bool maybePointedTo() const { return true; } virtual bool maybePointedTo() const { return true; }
virtual void dump(ostream& str=cout);
virtual V3Hash sameHash() const { return V3Hash(); } virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return ((funcType()==samep->castCFunc()->funcType()) virtual bool same(AstNode* samep) const { return ((funcType()==samep->castCFunc()->funcType())
&& (rtnTypeVoid()==samep->castCFunc()->rtnTypeVoid()) && (rtnTypeVoid()==samep->castCFunc()->rtnTypeVoid())
@@ -3140,7 +3301,7 @@ struct AstCMath : public AstNodeMath {
virtual bool isPredictOptimizable() const { return false; } virtual bool isPredictOptimizable() const { return false; }
virtual bool cleanOut() { return true; } virtual bool cleanOut() { return true; }
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
virtual string emitOperator() { V3ERROR_NA; return ""; } virtual string emitC() { V3ERROR_NA; return ""; }
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; }
}; };
+5 -5
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Removal of named begin blocks // DESCRIPTION: Verilator: Removal of named begin blocks
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3Begin's Transformations: // V3Begin's Transformations:
// //
// Each module: // Each module:
// Look for BEGINs // Look for BEGINs
// BEGIN(VAR...) -> VAR ... {renamed} // BEGIN(VAR...) -> VAR ... {renamed}
@@ -29,9 +28,10 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <cstring>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Removal of named begin blocks // DESCRIPTION: Verilator: Removal of named begin blocks
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+3 -4
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Branch prediction // DESCRIPTION: Verilator: Branch prediction
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -27,8 +26,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <map> #include <map>
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Branch prediction // DESCRIPTION: Verilator: Branch prediction
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+4 -5
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Find broken links in tree // DESCRIPTION: Verilator: Find broken links in tree
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3Broken's Transformations: // V3Broken's Transformations:
// //
// Entire netlist // Entire netlist
// Mark all nodes // Mark all nodes
// Check all links point to marked nodes // Check all links point to marked nodes
@@ -28,8 +27,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
#include <map> #include <map>
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Find broken links in tree // DESCRIPTION: Verilator: Find broken links in tree
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+54 -26
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Break case statements up and add Unknown assigns // DESCRIPTION: Verilator: Break case statements up and add Unknown assigns
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3Case's Transformations: // V3Case's Transformations:
// //
// Each module: // Each module:
// TBD: Eliminate tristates by adding __in, __inen, __en wires in parallel // TBD: Eliminate tristates by adding __in, __inen, __en wires in parallel
// Need __en in changed list if a signal is on the LHS of a assign // Need __en in changed list if a signal is on the LHS of a assign
@@ -40,8 +39,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
@@ -74,7 +73,7 @@ private:
} }
// Check for X/Z in non-casex statements // Check for X/Z in non-casex statements
if (!nodep->castCase() || !nodep->castCase()->casex()) { {
m_caseExprp = nodep; m_caseExprp = nodep;
nodep->exprp()->accept(*this); nodep->exprp()->accept(*this);
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
@@ -84,11 +83,18 @@ private:
} }
} }
virtual void visit(AstConst* nodep, AstNUser*) { virtual void visit(AstConst* nodep, AstNUser*) {
// See also neverItem
if (m_caseExprp && nodep->num().isFourState()) { if (m_caseExprp && nodep->num().isFourState()) {
if (m_caseExprp->castGenCase()) { if (m_caseExprp->castGenCase()) {
nodep->v3error("Use of x/? constant in generate case statement, (no such thing as 'generate casez')"); nodep->v3error("Use of x/? constant in generate case statement, (no such thing as 'generate casez')");
} else if (m_caseExprp->castCase() && m_caseExprp->castCase()->casex()) {
// Don't sweat it, we already complained about casex in general
} else if (m_caseExprp->castCase() && m_caseExprp->castCase()->casez()) {
if (nodep->num().isUnknown()) {
nodep->v3warn(CASEWITHX, "Use of x constant in casez statement, (perhaps intended ?/z in constant)");
}
} else { } else {
nodep->v3error("Use of x/? constant in case statement, (perhaps intended casex/casez)"); nodep->v3warn(CASEWITHX, "Use of x/? constant in case statement, (perhaps intended casex/casez)");
} }
} }
} }
@@ -153,20 +159,24 @@ private:
//if (debug()>=9) icondp->dumpTree(cout," caseitem: "); //if (debug()>=9) icondp->dumpTree(cout," caseitem: ");
AstConst* iconstp = icondp->castConst(); AstConst* iconstp = icondp->castConst();
if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this\n"); if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this\n");
V3Number nummask (itemp->fileline(), iconstp->width()); if (neverItem(nodep, iconstp)) {
nummask.opBitsNonX(iconstp->num()); // X in casez can't ever be executed
uint32_t mask = nummask.asInt(); } else {
V3Number numval (itemp->fileline(), iconstp->width()); V3Number nummask (itemp->fileline(), iconstp->width());
numval.opBitsOne(iconstp->num()); nummask.opBitsNonX(iconstp->num());
uint32_t val = numval.asInt(); uint32_t mask = nummask.toUInt();
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) { V3Number numval (itemp->fileline(), iconstp->width());
if ((i & mask) == val) { numval.opBitsOne(iconstp->num());
if (!m_valueItem[i]) { uint32_t val = numval.toUInt();
m_valueItem[i] = itemp; for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
} else if (!itemp->ignoreOverlap() && !bitched) { if ((i & mask) == val) {
itemp->v3warn(CASEOVERLAP,"Case values overlap (example pattern 0x"<<hex<<i<<")"); if (!m_valueItem[i]) {
bitched = true; m_valueItem[i] = itemp;
m_caseNoOverlapsAllCovered = false; } else if (!itemp->ignoreOverlap() && !bitched) {
itemp->v3warn(CASEOVERLAP,"Case values overlap (example pattern 0x"<<hex<<i<<")");
bitched = true;
m_caseNoOverlapsAllCovered = false;
}
} }
} }
} }
@@ -235,7 +245,7 @@ private:
// new AstConst(cexprp->fileline(), nummask)); // new AstConst(cexprp->fileline(), nummask));
AstNode* and1p = new AstSel(cexprp->fileline(), cexprp->cloneTree(false), AstNode* and1p = new AstSel(cexprp->fileline(), cexprp->cloneTree(false),
msb, 1); msb, 1);
AstNode* eqp = new AstNeq(cexprp->fileline(), AstNode* eqp = new AstNeq(cexprp->fileline(),
new AstConst(cexprp->fileline(), 0), new AstConst(cexprp->fileline(), 0),
and1p); and1p);
AstIf* ifp = new AstIf(cexprp->fileline(), eqp, tree1p, tree0p); AstIf* ifp = new AstIf(cexprp->fileline(), eqp, tree1p, tree0p);
@@ -293,19 +303,26 @@ private:
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondNextp) { for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondNextp) {
icondNextp = icondp->nextp(); icondNextp = icondp->nextp();
icondp->unlinkFrBack(); icondp->unlinkFrBack();
AstNode* and1p; AstNode* and1p;
AstNode* and2p; AstNode* and2p;
AstConst* iconstp = icondp->castConst(); AstConst* iconstp = icondp->castConst();
if (iconstp && iconstp->num().isFourState() if (iconstp && neverItem(nodep, iconstp)) {
&& nodep->casex()) { // X in casez can't ever be executed
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
// For simplicity, make expression that is not equal, and let later
// optimizations remove it
and1p = new AstConst(itemp->fileline(), V3Number(itemp->fileline(),1,0));
and2p = new AstConst(itemp->fileline(), V3Number(itemp->fileline(),1,1));
} else if (iconstp && iconstp->num().isFourState()
&& (nodep->casex() || nodep->casez())) {
V3Number nummask (itemp->fileline(), iconstp->width()); V3Number nummask (itemp->fileline(), iconstp->width());
nummask.opBitsNonX(iconstp->num()); nummask.opBitsNonX(iconstp->num());
V3Number numval (itemp->fileline(), iconstp->width()); V3Number numval (itemp->fileline(), iconstp->width());
numval.opBitsOne(iconstp->num()); numval.opBitsOne(iconstp->num());
and1p = new AstAnd(itemp->fileline(), cexprp->cloneTree(false), and1p = new AstAnd(itemp->fileline(), cexprp->cloneTree(false),
new AstConst(itemp->fileline(), nummask)); new AstConst(itemp->fileline(), nummask));
and2p = new AstAnd(itemp->fileline(), and2p = new AstAnd(itemp->fileline(),
new AstConst(itemp->fileline(), numval), new AstConst(itemp->fileline(), numval),
new AstConst(itemp->fileline(), nummask)); new AstConst(itemp->fileline(), nummask));
icondp->deleteTree(); icondp=NULL; iconstp=NULL; icondp->deleteTree(); icondp=NULL; iconstp=NULL;
@@ -395,6 +412,17 @@ private:
} }
} }
bool neverItem(AstCase* casep, AstConst* itemp) {
// Xs in case or casez are impossible due to two state simulations
if (casep->casex()) {
} else if (casep->casez()) {
if (itemp->num().isUnknown()) return true;
} else {
if (itemp->num().isFourState()) return true;
}
return false;
}
// VISITORS // VISITORS
virtual void visit(AstCase* nodep, AstNUser*) { virtual void visit(AstCase* nodep, AstNUser*) {
V3Case::caseLint(nodep); V3Case::caseLint(nodep);
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Break case statements up and add Unknown assigns // DESCRIPTION: Verilator: Break case statements up and add Unknown assigns
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+5 -6
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Add C++ casts across expression size changes // DESCRIPTION: Verilator: Add C++ casts across expression size changes
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3Cast's Transformations: // V3Cast's Transformations:
// //
// Each module: // Each module:
// For each math operator, if above operator requires 32 bits, // For each math operator, if above operator requires 32 bits,
// and this isn't, cast to 32 bits. // and this isn't, cast to 32 bits.
@@ -44,8 +43,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
@@ -148,7 +147,7 @@ private:
&& nodep->backp()->width() && nodep->backp()->width()
&& castSize(nodep) != castSize(nodep->varp())) { && castSize(nodep) != castSize(nodep->varp())) {
// Cast vars to IData first, else below has upper bits wrongly set // Cast vars to IData first, else below has upper bits wrongly set
// CData x=3; out = (QData)(x<<30); // CData x=3; out = (QData)(x<<30);
insertCast (nodep, castSize(nodep)); insertCast (nodep, castSize(nodep));
} }
nodep->user(1); nodep->user(1);
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Add C++ casts across expression size changes // DESCRIPTION: Verilator: Add C++ casts across expression size changes
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+5 -5
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Add temporaries, such as for changed nodes // DESCRIPTION: Verilator: Add temporaries, such as for changed nodes
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3Changed's Transformations: // V3Changed's Transformations:
// //
// Each module: // Each module:
// Each combo block // Each combo block
// For each variable that comes from combo block and is generated AFTER a usage // For each variable that comes from combo block and is generated AFTER a usage
@@ -33,8 +32,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
#include <set> #include <set>
@@ -64,6 +63,7 @@ private:
vscp->v3fatalSrc("Not applicable\n"); vscp->v3fatalSrc("Not applicable\n");
#endif #endif
AstVar* varp = vscp->varp(); AstVar* varp = vscp->varp();
vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<<vscp);
if (varp->arraysp()) { if (varp->arraysp()) {
vscp->v3error("Unsupported: Can't detect changes on arrayed variable (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName()); vscp->v3error("Unsupported: Can't detect changes on arrayed variable (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName());
} else { } else {
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Pre C-Emit stage changes // DESCRIPTION: Verilator: Pre C-Emit stage changes
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+5 -6
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Add temporaries, such as for clean nodes // DESCRIPTION: Verilator: Add temporaries, such as for clean nodes
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3Clean's Transformations: // V3Clean's Transformations:
// //
// Each module: // Each module:
// For each math operator, if it requires a clean operand, // For each math operator, if it requires a clean operand,
// and the operand is dirty, insert a CLEAN node. // and the operand is dirty, insert a CLEAN node.
@@ -30,8 +29,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
@@ -55,7 +54,7 @@ private:
// ENUMS // ENUMS
enum CleanState { UNKNOWN, CLEAN, DIRTY }; enum CleanState { UNKNOWN, CLEAN, DIRTY };
// METHODS // METHODS
// Width resetting // Width resetting
int cppWidth(AstNode* nodep) { int cppWidth(AstNode* nodep) {
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Pre C-Emit stage changes // DESCRIPTION: Verilator: Pre C-Emit stage changes
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+7 -8
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Clocking POS/NEGEDGE insertion // DESCRIPTION: Verilator: Clocking POS/NEGEDGE insertion
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3Clock's Transformations: // V3Clock's Transformations:
// //
// Top Scope: // Top Scope:
// Check created ACTIVEs // Check created ACTIVEs
// Compress adjacent ACTIVEs with same sensitivity list // Compress adjacent ACTIVEs with same sensitivity list
@@ -34,8 +33,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
@@ -245,12 +244,12 @@ private:
//UINFO(4," MOD "<<nodep<<endl); //UINFO(4," MOD "<<nodep<<endl);
m_modp = nodep; m_modp = nodep;
m_stableNum = 0; m_stableNum = 0;
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
} }
virtual void visit(AstScope* nodep, AstNUser*) { virtual void visit(AstScope* nodep, AstNUser*) {
//UINFO(4," SCOPE "<<nodep<<endl); //UINFO(4," SCOPE "<<nodep<<endl);
m_scopep = nodep; m_scopep = nodep;
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
if (AstNode* movep = nodep->finalClksp()) { if (AstNode* movep = nodep->finalClksp()) {
if (!m_topScopep) nodep->v3fatalSrc("Final clocks under non-top scope"); if (!m_topScopep) nodep->v3fatalSrc("Final clocks under non-top scope");
movep->unlinkFrBackWithNext(); movep->unlinkFrBackWithNext();
@@ -416,7 +415,7 @@ private:
new AstConst(fl, 1))); new AstConst(fl, 1)));
preUntilp->addNext(new AstAssign(fl, new AstVarRef(fl, countVarp, true), preUntilp->addNext(new AstAssign(fl, new AstVarRef(fl, countVarp, true),
new AstConst(fl, 0))); new AstConst(fl, 0)));
// Add stable variables & preinits // Add stable variables & preinits
AstNode* setChglastp = NULL; AstNode* setChglastp = NULL;
for (AstVarRef* varrefp = nodep->stablesp(); varrefp; varrefp=varrefp->nextp()->castVarRef()) { for (AstVarRef* varrefp = nodep->stablesp(); varrefp; varrefp=varrefp->nextp()->castVarRef()) {
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Clocking POS/NEGEDGE insertion // DESCRIPTION: Verilator: Clocking POS/NEGEDGE insertion
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+6 -7
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Combine common code into functions // DESCRIPTION: Verilator: Combine common code into functions
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3Combine's Transformations: // V3Combine's Transformations:
// //
// For every function that we spit out // For every function that we spit out
// Examine code to find largest common blocks // Examine code to find largest common blocks
// Hash each node depth first // Hash each node depth first
@@ -32,13 +31,13 @@
// Make new function // Make new function
// Move common block to function // Move common block to function
// Replace each common block ref with funccall // Replace each common block ref with funccall
// //
//************************************************************************* //*************************************************************************
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
@@ -392,7 +391,7 @@ private:
m_hashed.clear(); m_hashed.clear();
// Compute hash of all statement trees in the function // Compute hash of all statement trees in the function
m_state = STATE_HASH; m_state = STATE_HASH;
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
m_state = STATE_IDLE; m_state = STATE_IDLE;
// Walk the hashes removing empty functions // Walk the hashes removing empty functions
if (emptyFunctionDeletion()) { if (emptyFunctionDeletion()) {
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Combine common code into functions // DESCRIPTION: Verilator: Combine common code into functions
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+127 -24
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Constant folding // DESCRIPTION: Verilator: Constant folding
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -27,8 +26,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <map> #include <map>
@@ -39,18 +38,70 @@
#include "V3Width.h" #include "V3Width.h"
#include "V3Signed.h" #include "V3Signed.h"
//######################################################################
// Utilities
class ConstVarMarkVisitor : public AstNVisitor {
// NODE STATE
// AstVar::userp -> bool, Var marked, 0=not set yet
private:
// VISITORS
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (nodep->varp()) nodep->varp()->user(1);
}
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
ConstVarMarkVisitor(AstNode* nodep) {
AstNode::userClearTree();
nodep->iterateAndNext(*this, NULL);
}
virtual ~ConstVarMarkVisitor() {}
};
class ConstVarFindVisitor : public AstNVisitor {
// NODE STATE
// AstVar::userp -> bool, input from ConstVarMarkVisitor
// MEMBERS
bool m_found;
private:
// VISITORS
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (nodep->varp() && nodep->varp()->user()) m_found = true;
}
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
ConstVarFindVisitor(AstNode* nodep) {
m_found = false;
nodep->iterateAndNext(*this, NULL);
}
virtual ~ConstVarFindVisitor() {}
// METHODS
bool found() const { return m_found; }
};
//###################################################################### //######################################################################
// Const state, as a visitor of each AstNode // Const state, as a visitor of each AstNode
class ConstVisitor : public AstNVisitor { class ConstVisitor : public AstNVisitor {
private: private:
// NODE STATE
// ** only when m_warn is set. If state is needed other times,
// ** must track down everywhere V3Const is called and make sure no overlaps.
// AstVar::userp -> Used by ConstVarMarkVisitor/ConstVarFindVisitor
// STATE // STATE
bool m_params; // If true, propogate parameterized and true numbers only bool m_params; // If true, propogate parameterized and true numbers only
bool m_required; // If true, must become a constant bool m_required; // If true, must become a constant
bool m_wremove; // Inside scope, no assignw removal bool m_wremove; // Inside scope, no assignw removal
bool m_warn; // Output warnings bool m_warn; // Output warnings
bool m_cpp; // C++ conversions only bool m_cpp; // C++ conversions only
AstModule* m_modp; // Current module AstModule* m_modp; // Current module
AstNode* m_scopep; // Current scope AstNode* m_scopep; // Current scope
//int debug() { return 9; } //int debug() { return 9; }
@@ -91,8 +142,8 @@ private:
} }
bool operandIsTwo(AstNode* nodep) { bool operandIsTwo(AstNode* nodep) {
return (nodep->castConst() return (nodep->castConst()
&& nodep->width() <= VL_QUADSIZE && nodep->width() <= VL_QUADSIZE
&& nodep->castConst()->asQuad()==2); && nodep->castConst()->toUQuad()==2);
} }
bool operandIsTwostate(AstNode* nodep) { bool operandIsTwostate(AstNode* nodep) {
return (nodep->castConst() return (nodep->castConst()
@@ -129,7 +180,7 @@ private:
return (nodep->rhsp()->castConst() return (nodep->rhsp()->castConst()
&& nodep->fromp()->castNodeVarRef() && nodep->fromp()->castNodeVarRef()
&& !nodep->fromp()->castNodeVarRef()->lvalue() && !nodep->fromp()->castNodeVarRef()->lvalue()
&& ((int)(nodep->rhsp()->castConst()->asInt()) && ((int)(nodep->rhsp()->castConst()->toUInt())
>= nodep->fromp()->castNodeVarRef()->varp()->widthWords())); >= nodep->fromp()->castNodeVarRef()->varp()->widthWords()));
} }
bool operandSelFull(AstSel* nodep) { bool operandSelFull(AstSel* nodep) {
@@ -443,7 +494,7 @@ private:
&&(con2p->asInt() != con1p->asInt() + sel1p->width())) return false; &&(con2p->asInt() != con1p->asInt() + sel1p->width())) return false;
bool lsbFirstAssign = (con1p->asInt() < con2p->asInt()); bool lsbFirstAssign = (con1p->asInt() < con2p->asInt());
// If the user already has nice 32-bit divisions, keep them to aid later subdivision // If the user already has nice 32-bit divisions, keep them to aid later subdivision
//if (VL_BITBIT_I(con1p->asInt()) == 0) return false; //if (VL_BITBIT_I(con1p->toUInt()) == 0) return false;
UINFO(4,"replaceAssignMultiSel "<<nodep<<endl); UINFO(4,"replaceAssignMultiSel "<<nodep<<endl);
UINFO(4," && "<<nextp<<endl); UINFO(4," && "<<nextp<<endl);
//nodep->dumpTree(cout, "comb1: "); //nodep->dumpTree(cout, "comb1: ");
@@ -466,7 +517,7 @@ private:
return true; return true;
} }
bool varNotReferenced(AstNode* nodep, AstVar* varp, bool level=0) { bool varNotReferenced(AstNode* nodep, AstVar* varp, int level=0) {
// Return true if varp never referenced under node. // Return true if varp never referenced under node.
// Return false if referenced, or tree too deep to be worth it // Return false if referenced, or tree too deep to be worth it
if (!nodep) return true; if (!nodep) return true;
@@ -494,10 +545,26 @@ private:
} }
} }
else if (!m_cpp && nodep->lhsp()->castConcat()) { else if (!m_cpp && nodep->lhsp()->castConcat()) {
UINFO(4," ASSI "<<nodep<<endl); bool need_temp = false;
if (m_warn && !nodep->castAssignDly()) { // Is same var on LHS and RHS?
ConstVarMarkVisitor mark(nodep->lhsp());
ConstVarFindVisitor find(nodep->rhsp());
if (find.found()) need_temp = true;
}
if (need_temp) {
// The first time we constify, there may be the same variable on the LHS
// and RHS. In that case, we must use temporaries, or {a,b}={b,a} will break.
UINFO(4," ASSITEMP "<<nodep<<endl);
// ASSIGN(CONCAT(lc1,lc2),rhs) -> ASSIGN(temp1,SEL(rhs,{size})),
// ASSIGN(temp2,SEL(newrhs,{size}))
// ASSIGN(lc1,temp1),
// ASSIGN(lc2,temp2)
} else {
UINFO(4," ASSI "<<nodep<<endl);
// ASSIGN(CONCAT(lc1,lc2),rhs) -> ASSIGN(lc1,SEL(rhs,{size})),
// ASSIGN(lc2,SEL(newrhs,{size}))
}
if (debug()>=9) nodep->dumpTree(cout," Ass_old: "); if (debug()>=9) nodep->dumpTree(cout," Ass_old: ");
// ASSIGN(CONCAT(lc1,lc2),rhs) -> ASSIGN(lc1,SEL(rhs,{size})),
// ASSIGN(lc2,SEL(newrhs,{size}))
// Unlink the stuff // Unlink the stuff
AstNode* lc1p = nodep->lhsp()->castConcat()->lhsp()->unlinkFrBack(); AstNode* lc1p = nodep->lhsp()->castConcat()->lhsp()->unlinkFrBack();
AstNode* lc2p = nodep->lhsp()->castConcat()->rhsp()->unlinkFrBack(); AstNode* lc2p = nodep->lhsp()->castConcat()->rhsp()->unlinkFrBack();
@@ -517,14 +584,50 @@ private:
sel2p->width(msb2-lsb2+1,msb2-lsb2+1); sel2p->width(msb2-lsb2+1,msb2-lsb2+1);
// Make new assigns of same flavor as old one // Make new assigns of same flavor as old one
//*** Not cloneTree; just one node. //*** Not cloneTree; just one node.
AstNodeAssign* asn1p=nodep->cloneType(lc1p, sel1p)->castNodeAssign(); AstNode* newp = NULL;
AstNodeAssign* asn2p=nodep->cloneType(lc2p, sel2p)->castNodeAssign(); if (!need_temp) {
asn1p->width(msb1-lsb1+1,msb1-lsb1+1); AstNodeAssign* asn1ap=nodep->cloneType(lc1p, sel1p)->castNodeAssign();
asn2p->width(msb2-lsb2+1,msb2-lsb2+1); AstNodeAssign* asn2ap=nodep->cloneType(lc2p, sel2p)->castNodeAssign();
nodep->addNextHere(asn1p); asn1ap->width(msb1-lsb1+1,msb1-lsb1+1);
nodep->addNextHere(asn2p); asn2ap->width(msb2-lsb2+1,msb2-lsb2+1);
if (debug()>=9) asn1p->dumpTree(cout," _new: "); newp = newp->addNext(asn1ap);
if (debug()>=9) asn2p->dumpTree(cout," _new: "); newp = newp->addNext(asn2ap);
} else {
if (!m_modp) nodep->v3fatalSrc("Not under module");
// We could create just one temp variable, but we'll get better optimization
// if we make one per term.
string name1 = ((string)"__Vconcswap__"+cvtToStr(m_modp->varNumGetInc()));
string name2 = ((string)"__Vconcswap__"+cvtToStr(m_modp->varNumGetInc()));
AstVar* temp1p = new AstVar(sel1p->fileline(), AstVarType::BLOCKTEMP, name1,
new AstRange(sel1p->fileline(), msb1-lsb1, 0));
AstVar* temp2p = new AstVar(sel2p->fileline(), AstVarType::BLOCKTEMP, name2,
new AstRange(sel2p->fileline(), msb2-lsb2, 0));
m_modp->addStmtp(temp1p);
m_modp->addStmtp(temp2p);
AstNodeAssign* asn1ap=nodep->cloneType
(new AstVarRef(sel1p->fileline(), temp1p, true),
sel1p)->castNodeAssign();
AstNodeAssign* asn2ap=nodep->cloneType
(new AstVarRef(sel2p->fileline(), temp2p, true),
sel2p)->castNodeAssign();
AstNodeAssign* asn1bp=nodep->cloneType
(lc1p, new AstVarRef(sel1p->fileline(), temp1p, false))
->castNodeAssign();
AstNodeAssign* asn2bp=nodep->cloneType
(lc2p, new AstVarRef(sel2p->fileline(), temp2p, false))
->castNodeAssign();
asn1ap->width(msb1-lsb1+1,msb1-lsb1+1);
asn1bp->width(msb1-lsb1+1,msb1-lsb1+1);
asn2ap->width(msb2-lsb2+1,msb2-lsb2+1);
asn2bp->width(msb2-lsb2+1,msb2-lsb2+1);
// This order matters
newp = newp->addNext(asn1ap);
newp = newp->addNext(asn2ap);
newp = newp->addNext(asn1bp);
newp = newp->addNext(asn2bp);
}
if (debug()>=9) newp->dumpTreeAndNext(cout," _new: ");
nodep->addNextHere(newp);
// Cleanup // Cleanup
nodep->unlinkFrBack()->deleteTree(); nodep=NULL; nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
conp->deleteTree(); conp=NULL; conp->deleteTree(); conp=NULL;
@@ -641,7 +744,7 @@ private:
// Recurse rather then calling node->iterate to prevent 2^n recursion! // Recurse rather then calling node->iterate to prevent 2^n recursion!
if (operandConcatMove(abConcp)) moveConcat(abConcp); if (operandConcatMove(abConcp)) moveConcat(abConcp);
bcConcp->deleteTree(); bcConcp=NULL; bcConcp->deleteTree(); bcConcp=NULL;
} else { } else {
AstConcat* abConcp = nodep->lhsp()->castConcat(); abConcp->unlinkFrBack(); AstConcat* abConcp = nodep->lhsp()->castConcat(); abConcp->unlinkFrBack();
AstNode* ap = abConcp->lhsp()->unlinkFrBack(); AstNode* ap = abConcp->lhsp()->unlinkFrBack();
AstNode* bp = abConcp->rhsp()->unlinkFrBack(); AstNode* bp = abConcp->rhsp()->unlinkFrBack();
@@ -913,7 +1016,7 @@ private:
&& nodep->ifsp() && nodep->elsesp()) { && nodep->ifsp() && nodep->elsesp()) {
UINFO(4,"IF(NOT {x}) => IF(x) swapped if/else"<<nodep<<endl); UINFO(4,"IF(NOT {x}) => IF(x) swapped if/else"<<nodep<<endl);
AstNode* condp = nodep->condp()->castNot()->lhsp()->unlinkFrBackWithNext(); AstNode* condp = nodep->condp()->castNot()->lhsp()->unlinkFrBackWithNext();
AstNode* ifsp = nodep->ifsp()->unlinkFrBackWithNext(); AstNode* ifsp = nodep->ifsp()->unlinkFrBackWithNext();
AstNode* elsesp = nodep->elsesp()->unlinkFrBackWithNext(); AstNode* elsesp = nodep->elsesp()->unlinkFrBackWithNext();
AstIf* ifp = new AstIf(nodep->fileline(), condp, elsesp, ifsp); AstIf* ifp = new AstIf(nodep->fileline(), condp, elsesp, ifsp);
ifp->branchPred(nodep->branchPred().invert()); ifp->branchPred(nodep->branchPred().invert());
@@ -934,7 +1037,7 @@ private:
nodep->deleteTree(); nodep=NULL; nodep->deleteTree(); nodep=NULL;
} }
else if (0 // Disabled, as vpm assertions are faster without due to short-circuiting else if (0 // Disabled, as vpm assertions are faster without due to short-circuiting
&& operandIfIf(nodep)) { && operandIfIf(nodep)) {
UINFO(0,"IF({a}) IF({b}) => IF({a} && {b})"<<endl); UINFO(0,"IF({a}) IF({b}) => IF({a} && {b})"<<endl);
AstNodeIf* lowerIfp = nodep->ifsp()->castNodeIf(); AstNodeIf* lowerIfp = nodep->ifsp()->castNodeIf();
AstNode* condp = nodep->condp()->unlinkFrBack(); AstNode* condp = nodep->condp()->unlinkFrBack();
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Propagate constants across AST // DESCRIPTION: Verilator: Propagate constants across AST
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+5 -6
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Netlist (top level) functions // DESCRIPTION: Verilator: Netlist (top level) functions
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -31,8 +30,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <map> #include <map>
@@ -53,7 +52,7 @@ private:
bool m_checkBlock; // Should this block get covered? bool m_checkBlock; // Should this block get covered?
AstModule* m_modp; // Current module to add statement to AstModule* m_modp; // Current module to add statement to
FileMap m_fileps; // Column counts for each fileline FileMap m_fileps; // Column counts for each fileline
//int debug() { return 9; } //int debug() { return 9; }
// METHODS // METHODS
@@ -66,7 +65,7 @@ private:
column = (it->second)++; column = (it->second)++;
} }
AstCoverDecl* declp = new AstCoverDecl(fl, column, type, comment); AstCoverDecl* declp = new AstCoverDecl(fl, column, type, comment);
m_modp->addStmtp(declp); m_modp->addStmtp(declp);
return new AstCoverInc(fl, declp); return new AstCoverInc(fl, declp);
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Coverage modules/signals together // DESCRIPTION: Verilator: Coverage modules/signals together
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+4 -5
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Dead code elimination // DESCRIPTION: Verilator: Dead code elimination
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,13 +20,13 @@
// DEAD TRANSFORMATIONS: // DEAD TRANSFORMATIONS:
// Remove any unreferenced modules // Remove any unreferenced modules
// Remove any unreferenced variables // Remove any unreferenced variables
// //
//************************************************************************* //*************************************************************************
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <vector> #include <vector>
#include <map> #include <map>
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Dead branch elimination // DESCRIPTION: Verilator: Dead branch elimination
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+9 -10
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Add temporaries, such as for delayed nodes // DESCRIPTION: Verilator: Add temporaries, such as for delayed nodes
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,9 +18,9 @@
// //
//************************************************************************* //*************************************************************************
// V3Delayed's Transformations: // V3Delayed's Transformations:
// //
// Each module: // Each module:
// Replace ASSIGNDLY var, exp // Replace ASSIGNDLY var, exp
// With ASSIGNDLY newvar, exp // With ASSIGNDLY newvar, exp
// At top of block: VAR newvar // At top of block: VAR newvar
// At bottom of block: ASSIGNW var newvar // At bottom of block: ASSIGNW var newvar
@@ -54,8 +53,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
#include <map> #include <map>
@@ -269,7 +268,7 @@ private:
AstAlwaysPost* finalp = varrefp->varScopep()->user4p()->castNode()->castAlwaysPost(); AstAlwaysPost* finalp = varrefp->varScopep()->user4p()->castNode()->castAlwaysPost();
if (!finalp) { if (!finalp) {
finalp = new AstAlwaysPost(nodep->fileline(), NULL/*sens*/, NULL/*body*/); finalp = new AstAlwaysPost(nodep->fileline(), NULL/*sens*/, NULL/*body*/);
UINFO(9," Created "<<finalp<<endl); UINFO(9," Created "<<finalp<<endl);
m_activep->addStmtsp(finalp); m_activep->addStmtsp(finalp);
varrefp->varScopep()->user4p(finalp); varrefp->varScopep()->user4p(finalp);
} }
@@ -284,7 +283,7 @@ private:
new AstVarRef(nodep->fileline(), setvscp, false), new AstVarRef(nodep->fileline(), setvscp, false),
NULL, NULL,
NULL); NULL);
UINFO(9," Created "<<postLogicp<<endl); UINFO(9," Created "<<postLogicp<<endl);
finalp->addBodysp(postLogicp); finalp->addBodysp(postLogicp);
finalp->user5p(setvscp); // Remember IF's vset variable finalp->user5p(setvscp); // Remember IF's vset variable
finalp->user4p(postLogicp); // and the associated IF, as we may be able to reuse it finalp->user4p(postLogicp); // and the associated IF, as we may be able to reuse it
@@ -347,7 +346,7 @@ private:
virtual void visit(AstVarRef* nodep, AstNUser*) { virtual void visit(AstVarRef* nodep, AstNUser*) {
if (!nodep->user2()) { // Not done yet if (!nodep->user2()) { // Not done yet
nodep->user2(true); nodep->user2(true);
if (m_inDly && nodep->lvalue()) { if (m_inDly && nodep->lvalue()) {
UINFO(4,"AssignDlyVar: "<<nodep<<endl); UINFO(4,"AssignDlyVar: "<<nodep<<endl);
markVarUsage(nodep->varp(), VU_DLY); markVarUsage(nodep->varp(), VU_DLY);
@@ -401,7 +400,7 @@ private:
m_activep->sensesp()); m_activep->sensesp());
newactp->addStmtsp(prep); // Add to FRONT of statements newactp->addStmtsp(prep); // Add to FRONT of statements
newactp->addStmtsp(postp); newactp->addStmtsp(postp);
m_activep->addNext(newactp); m_activep->addNext(newactp);
dlyvscp->user2p(newactp); dlyvscp->user2p(newactp);
} }
AstVarRef* newrefp = new AstVarRef(nodep->fileline(), dlyvscp, true); AstVarRef* newrefp = new AstVarRef(nodep->fileline(), dlyvscp, true);
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Pre C-Emit stage changes // DESCRIPTION: Verilator: Pre C-Emit stage changes
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+5 -6
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Prevent very deep expressions // DESCRIPTION: Verilator: Prevent very deep expressions
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3Depth's Transformations: // V3Depth's Transformations:
// //
// Each module: // Each module:
// For each wide OP, assign a temporary variable. // For each wide OP, assign a temporary variable.
// For each deep expression, assign expression to temporary. // For each deep expression, assign expression to temporary.
@@ -30,8 +29,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
@@ -111,7 +110,7 @@ private:
// We have some operator defines that use 2 parens, so += 2. // We have some operator defines that use 2 parens, so += 2.
m_depth += 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 -= 2; m_depth -= 2;
if (m_stmtp if (m_stmtp
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Prevent very deep expressions // DESCRIPTION: Verilator: Prevent very deep expressions
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+4 -5
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Prevent very deep expressions // DESCRIPTION: Verilator: Prevent very deep expressions
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3DepthBlock's Transformations: // V3DepthBlock's Transformations:
// //
// Each module: // Each module:
// For each deep block, create cfunc including that block. // For each deep block, create cfunc including that block.
// //
@@ -27,8 +26,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Prevent very deep expressions // DESCRIPTION: Verilator: Prevent very deep expressions
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+4 -5
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Rename scope references to module-local references // DESCRIPTION: Verilator: Rename scope references to module-local references
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -24,13 +23,13 @@
// Change varref name() to be relative to current module // Change varref name() to be relative to current module
// Remove varScopep() // Remove varScopep()
// This allows for better V3Combine'ing. // This allows for better V3Combine'ing.
// //
//************************************************************************* //*************************************************************************
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <map> #include <map>
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Rename scope references to module-local references // DESCRIPTION: Verilator: Rename scope references to module-local references
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+270 -216
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Emit C++ for tree // DESCRIPTION: Verilator: Emit C++ for tree
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,10 +20,10 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <math.h> #include <cmath>
#include <map> #include <map>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
@@ -79,10 +78,10 @@ public:
//int debug() { return 9; } //int debug() { return 9; }
// METHODS // METHODS
void displayEmit(AstDisplay* nodep); void displayNode(AstNode* nodep, const string& vformat, AstNode* exprsp, bool isScan);
string displayFormat(AstNode* widthNode, string in, void displayEmit(AstNode* nodep, bool isScan);
char fmtLetter, bool padZero, bool reallyString); void displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
void displayArg(AstDisplay* dispp, AstNode** elistp, string fmt, char fmtLetter); string vfmt, char fmtLetter);
void emitVarDecl(AstVar* nodep, const string& prefixIfImp); void emitVarDecl(AstVar* nodep, const string& prefixIfImp);
typedef enum {EVL_IO, EVL_SIG, EVL_TEMP, EVL_STATIC, EVL_ALL} EisWhich; typedef enum {EVL_IO, EVL_SIG, EVL_TEMP, EVL_STATIC, EVL_ALL} EisWhich;
@@ -92,7 +91,8 @@ public:
void emitIQW(AstNode* nodep) { void emitIQW(AstNode* nodep) {
puts (nodep->isWide()?"W":(nodep->isQuad()?"Q":"I")); puts (nodep->isWide()?"W":(nodep->isQuad()?"Q":"I"));
} }
void emitOpName(AstNode* nodep, const string& name); void emitOpName(AstNode* nodep, const string& format,
AstNode* lhsp, AstNode* rhsp, AstNode* thsp);
string cFuncArgs(AstCFunc* nodep) { string cFuncArgs(AstCFunc* nodep) {
// Return argument list for given C function // Return argument list for given C function
@@ -212,7 +212,7 @@ public:
} }
virtual void visit(AstCoverDecl* nodep, AstNUser*) { virtual void visit(AstCoverDecl* nodep, AstNUser*) {
puts("__vlCoverInsert("); // As Declared in emitCoverageDecl puts("__vlCoverInsert("); // As Declared in emitCoverageDecl
puts("&__Vcoverage["); puts("&__Vcoverage[");
puts(cvtToStr(m_coverIds.remap(nodep))); puts("]"); puts(cvtToStr(m_coverIds.remap(nodep))); puts("]");
puts(", \""); puts(nodep->fileline()->filebasename()); puts("\""); puts(", \""); puts(nodep->fileline()->filebasename()); puts("\"");
puts(", "); puts(cvtToStr(nodep->fileline()->lineno())); puts(", "); puts(cvtToStr(nodep->fileline()->lineno()));
@@ -231,7 +231,23 @@ public:
nodep->lhsp()->iterateAndNext(*this); nodep->lhsp()->iterateAndNext(*this);
puts(");\n"); puts(");\n");
} }
virtual void visit(AstDisplay* nodep, AstNUser*); // BELOW virtual void visit(AstDisplay* nodep, AstNUser*) {
string text = nodep->text();
if (nodep->addNewline()) text += "\\n";
displayNode(nodep, text, nodep->exprsp(), false);
}
virtual void visit(AstFScanF* nodep, AstNUser*) {
displayNode(nodep, nodep->text(), nodep->exprsp(), true);
}
virtual void visit(AstSScanF* nodep, AstNUser*) {
displayNode(nodep, nodep->text(), nodep->exprsp(), true);
}
void checkMaxWords(AstNode* nodep) {
if (nodep->widthWords() > VL_TO_STRING_MAX_WORDS) {
nodep->v3error("String of "<<nodep->width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h\n");
}
}
virtual void visit(AstFOpen* nodep, AstNUser*) { virtual void visit(AstFOpen* nodep, AstNUser*) {
nodep->filep()->iterateAndNext(*this); nodep->filep()->iterateAndNext(*this);
puts(" = VL_FOPEN_"); puts(" = VL_FOPEN_");
@@ -243,9 +259,7 @@ public:
puts(cvtToStr(nodep->filenamep()->widthWords())); puts(cvtToStr(nodep->filenamep()->widthWords()));
putbs(", "); putbs(", ");
} }
if (nodep->filenamep()->widthWords() > VL_TO_STRING_MAX_WORDS) { checkMaxWords(nodep->filenamep());
nodep->v3error("String of "<<nodep->filenamep()->width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h\n");
}
nodep->filenamep()->iterateAndNext(*this); nodep->filenamep()->iterateAndNext(*this);
putbs(", "); putbs(", ");
nodep->modep()->iterateAndNext(*this); nodep->modep()->iterateAndNext(*this);
@@ -272,9 +286,7 @@ public:
puts(cvtToStr(array_lsb)); puts(cvtToStr(array_lsb));
putbs(","); putbs(",");
puts(cvtToStr(nodep->filenamep()->widthWords())); puts(cvtToStr(nodep->filenamep()->widthWords()));
if (nodep->filenamep()->widthWords() > VL_TO_STRING_MAX_WORDS) { checkMaxWords(nodep->filenamep());
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(", ");
@@ -293,6 +305,17 @@ public:
nodep->filep()->iterateAndNext(*this); // For saftey, so user doesn't later WRITE with it. nodep->filep()->iterateAndNext(*this); // For saftey, so user doesn't later WRITE with it.
puts("=0; }\n"); puts("=0; }\n");
} }
virtual void visit(AstFFlush* nodep, AstNUser*) {
if (!nodep->filep()) {
puts("fflush (stdout);\n");
} else {
puts("if (");
nodep->filep()->iterateAndNext(*this);
puts(") { fflush (VL_CVT_Q_FP(");
nodep->filep()->iterateAndNext(*this);
puts(")); }\n");
}
}
virtual void visit(AstWhile* nodep, AstNUser*) { virtual void visit(AstWhile* nodep, AstNUser*) {
nodep->precondsp()->iterateAndNext(*this); nodep->precondsp()->iterateAndNext(*this);
puts("while ("); puts("while (");
@@ -354,26 +377,24 @@ public:
// Operators // Operators
virtual void visit(AstNodeTermop* nodep, AstNUser*) { virtual void visit(AstNodeTermop* nodep, AstNUser*) {
emitOpName(nodep,nodep->emitOperator()); emitOpName(nodep, nodep->emitC(), NULL, NULL, NULL);
puts(")");
} }
virtual void visit(AstNodeUniop* nodep, AstNUser*) { virtual void visit(AstNodeUniop* nodep, AstNUser*) {
if (emitSimpleOk(nodep)) { if (emitSimpleOk(nodep)) {
putbs("("); puts(nodep->emitSimpleOperator()); puts(" "); putbs("("); puts(nodep->emitSimpleOperator()); puts(" ");
nodep->lhsp()->iterateAndNext(*this); puts(")");
} else { } else {
emitOpName(nodep,nodep->emitOperator()); emitOpName(nodep, nodep->emitC(), nodep->lhsp(), NULL, NULL);
} }
nodep->lhsp()->iterateAndNext(*this); puts(")");
} }
virtual void visit(AstNodeBiop* nodep, AstNUser*) { virtual void visit(AstNodeBiop* nodep, AstNUser*) {
if (emitSimpleOk(nodep)) { if (emitSimpleOk(nodep)) {
putbs("("); nodep->lhsp()->iterateAndNext(*this); putbs("("); nodep->lhsp()->iterateAndNext(*this);
puts(" "); putbs(nodep->emitSimpleOperator()); puts(" "); puts(" "); putbs(nodep->emitSimpleOperator()); puts(" ");
nodep->rhsp()->iterateAndNext(*this); puts(")");
} else { } else {
emitOpName(nodep,nodep->emitOperator()); emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), NULL);
nodep->lhsp()->iterateAndNext(*this); puts(", ");
} }
nodep->rhsp()->iterateAndNext(*this); puts(")");
} }
virtual void visit(AstRedXor* nodep, AstNUser* vup) { virtual void visit(AstRedXor* nodep, AstNUser* vup) {
if (nodep->lhsp()->isWide()) { if (nodep->lhsp()->isWide()) {
@@ -405,10 +426,7 @@ public:
virtual void visit(AstNodeCond* nodep, AstNUser*) { virtual void visit(AstNodeCond* nodep, AstNUser*) {
// Widths match up already, so we'll just use C++'s operator w/o any temps. // Widths match up already, so we'll just use C++'s operator w/o any temps.
if (nodep->expr1p()->isWide()) { if (nodep->expr1p()->isWide()) {
emitOpName(nodep,nodep->emitOperator()); emitOpName(nodep, nodep->emitC(), nodep->condp(), nodep->expr1p(), nodep->expr2p());
nodep->condp()->iterateAndNext(*this); puts(", ");
nodep->expr1p()->iterateAndNext(*this); puts(", ");
nodep->expr2p()->iterateAndNext(*this); puts(")");
} else { } else {
putbs("("); putbs("(");
nodep->condp()->iterateAndNext(*this); putbs(" ? "); nodep->condp()->iterateAndNext(*this); putbs(" ? ");
@@ -418,20 +436,11 @@ public:
} }
virtual void visit(AstSel* nodep, AstNUser*) { virtual void visit(AstSel* nodep, AstNUser*) {
// Note ASSIGN checks for this on a LHS // Note ASSIGN checks for this on a LHS
if (nodep->widthp()->isOne()) { emitOpName(nodep, nodep->emitC(), nodep->fromp(), nodep->lsbp(), nodep->thsp());
emitOpName(nodep,"VL_BITSEL");
nodep->fromp()->iterateAndNext(*this); puts(", ");
nodep->lsbp()->iterateAndNext(*this); puts(")");
} else {
emitOpName(nodep,"VL_SEL");
nodep->fromp()->iterateAndNext(*this); puts(", ");
nodep->lsbp()->iterateAndNext(*this); puts(", ");
nodep->widthp()->iterateAndNext(*this); puts(")");
}
} }
virtual void visit(AstReplicate* nodep, AstNUser*) { virtual void visit(AstReplicate* nodep, AstNUser*) {
if (nodep->lhsp()->widthMin() == 1 && !nodep->isWide()) { if (nodep->lhsp()->widthMin() == 1 && !nodep->isWide()) {
if (((int)nodep->rhsp()->castConst()->asInt() if (((int)nodep->rhsp()->castConst()->toUInt()
* nodep->lhsp()->widthMin()) != nodep->widthMin()) * nodep->lhsp()->widthMin()) != nodep->widthMin())
nodep->v3fatalSrc("Replicate non-constant or width miscomputed"); nodep->v3fatalSrc("Replicate non-constant or width miscomputed");
puts("VL_REPLICATE_"); puts("VL_REPLICATE_");
@@ -441,24 +450,16 @@ public:
if (nodep->lhsp()) { puts(","+cvtToStr(nodep->lhsp()->widthMin())); } if (nodep->lhsp()) { puts(","+cvtToStr(nodep->lhsp()->widthMin())); }
if (nodep->rhsp()) { puts(","+cvtToStr(nodep->rhsp()->widthMin())); } if (nodep->rhsp()) { puts(","+cvtToStr(nodep->rhsp()->widthMin())); }
puts(","); puts(",");
nodep->lhsp()->iterateAndNext(*this); puts(", ");
nodep->rhsp()->iterateAndNext(*this); puts(")");
} else { } else {
emitOpName(nodep,nodep->emitOperator()); emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), NULL);
} }
nodep->lhsp()->iterateAndNext(*this); puts(", ");
nodep->rhsp()->iterateAndNext(*this); puts(")");
}
virtual void visit(AstArraySel* nodep, AstNUser*) {
nodep->fromp()->iterateAndNext(*this); putbs("[");
nodep->bitp()->iterateAndNext(*this); puts("]");
}
virtual void visit(AstWordSel* nodep, AstNUser*) {
nodep->fromp()->iterateAndNext(*this); puts("["); // Not putbs, as usually it's a small constant next
nodep->bitp()->iterateAndNext(*this); puts("]");
} }
// Terminals // Terminals
virtual void visit(AstVarRef* nodep, AstNUser*) { virtual void visit(AstVarRef* nodep, AstNUser*) {
puts(nodep->hiername()); puts(nodep->hiername());
puts(nodep->varp()->name()); puts(nodep->varp()->name());
} }
void emitConstant(AstConst* nodep, AstVarRef* assigntop, const string& assignString) { void emitConstant(AstConst* nodep, AstVarRef* assigntop, const string& assignString) {
// Put out constant set to the specified variable, or given variable in a string // Put out constant set to the specified variable, or given variable in a string
@@ -483,11 +484,11 @@ public:
} }
ofp()->printf(",0x%08x)", nodep->num().dataWord(0)); ofp()->printf(",0x%08x)", nodep->num().dataWord(0));
} else if (nodep->isQuad()) { } else if (nodep->isQuad()) {
vluint64_t num = nodep->asQuad(); vluint64_t num = nodep->toUQuad();
if (num<10) ofp()->printf("VL_ULL(%lld)", (long long)num); if (num<10) ofp()->printf("VL_ULL(%lld)", (long long)num);
else ofp()->printf("VL_ULL(0x%llx)", (long long)num); else ofp()->printf("VL_ULL(0x%llx)", (long long)num);
} else { } else {
uint32_t num = nodep->asInt(); uint32_t num = nodep->toUInt();
if (num<10) puts(cvtToStr(num)); if (num<10) puts(cvtToStr(num));
else ofp()->printf("0x%x", num); else ofp()->printf("0x%x", num);
//Unneeded-Causes %lx format warnings: //Unneeded-Causes %lx format warnings:
@@ -639,7 +640,7 @@ class EmitCImp : EmitCStmts {
puts(modClassName(m_modp)+"::"+nodep->name() puts(modClassName(m_modp)+"::"+nodep->name()
+"("+cFuncArgs(nodep)+") {\n"); +"("+cFuncArgs(nodep)+") {\n");
puts("VL_DEBUG_IF(cout<<\" "); puts("VL_DEBUG_IF(cout<<\" ");
for (int i=0;i<m_modp->level();i++) { puts(" "); } for (int i=0;i<m_modp->level();i++) { puts(" "); }
puts(modClassName(m_modp)+"::"+nodep->name() puts(modClassName(m_modp)+"::"+nodep->name()
+"\"<<endl; );\n"); +"\"<<endl; );\n");
@@ -853,33 +854,95 @@ bool EmitCStmts::emitSimpleOk(AstNodeMath* nodep) {
return true; return true;
} }
void EmitCStmts::emitOpName(AstNode* nodep, const string& opname) { void EmitCStmts::emitOpName(AstNode* nodep, const string& format,
putbs(opname+"_"); AstNode* lhsp, AstNode* rhsp, AstNode* thsp) {
if (nodep->emitWordForm()) { // Look at emitOperator() format for term/uni/dual/triops,
emitIQW(nodep->op1p()); // and write out appropriate text.
puts("("); // %n* node
if (nodep->op1p()->isWide()) { // %nq emitIQW on the [node]
puts(cvtToStr(nodep->op1p()->widthWords())); // %nw width in bits
puts(", "); // %nW width in words
// %ni iterate
// %l* lhsp - if appropriate, then second char as above
// %r* rhsp - if appropriate, then second char as above
// %t* thsp - if appropriate, then second char as above
// %k Potential line break
// %P Wide temporary name
// , Commas suppressed if the previous field is suppressed
string nextComma;
bool needComma = false;
#define COMMA { if (nextComma!="") { puts(nextComma); nextComma=""; } }
putbs("");
for (string::const_iterator pos = format.begin(); pos != format.end(); ++pos) {
if (pos[0]==',') {
// Remember we need to add one, but don't do yet to avoid ",)"
if (needComma) {
if (pos[1]==' ') { nextComma=", "; }
else nextComma = ",";
needComma = false;
}
if (pos[1]==' ') { ++pos; } // Must do even if no nextComma
}
else if (pos[0]=='%') {
++pos;
bool detail = false;
AstNode* detailp = NULL;
switch (pos[0]) {
case '%': puts("%"); break;
case 'k': putbs(""); break;
case 'n': detail = true; detailp = nodep; break;
case 'l': detail = true; detailp = lhsp; break;
case 'r': detail = true; detailp = rhsp; break;
case 't': detail = true; detailp = thsp; break;
case 'P':
if (nodep->isWide()) {
if (!m_wideTempRefp) nodep->v3fatalSrc("Wide Op w/ no temp, perhaps missing op in V3EmitC?");
COMMA;
puts(m_wideTempRefp->hiername());
puts(m_wideTempRefp->varp()->name());
m_wideTempRefp = NULL;
needComma = true;
}
break;
default:
nodep->v3fatalSrc("Unknown emitOperator format code: %"<<pos[0]);
break;
}
if (detail) {
// Get next letter of %[nlrt]
++pos;
switch (pos[0]) {
case 'q': emitIQW(detailp); break;
case 'w':
COMMA;
puts(cvtToStr(detailp->widthMin()));
needComma = true;
break;
case 'W':
if (lhsp->isWide()) {
COMMA;
puts(cvtToStr(lhsp->widthWords()));
needComma = true;
}
break;
case 'i':
COMMA;
if (!detailp) { nodep->v3fatalSrc("emitOperator() references undef node"); }
else detailp->iterateAndNext(*this);
needComma = true;
break;
default:
nodep->v3fatalSrc("Unknown emitOperator format code: %[nlrt]"<<pos[0]);
break;
}
}
} else {
// Normal text
if (pos[0] == ')') nextComma="";
COMMA;
string s; s+=pos[0]; puts(s);
} }
} else {
emitIQW(nodep);
if (nodep->op1p()) { emitIQW(nodep->op1p()); }
if (nodep->op2p()) { emitIQW(nodep->op2p()); }
if (nodep->op3p()) { emitIQW(nodep->op3p()); }
puts("(");
puts(cvtToStr(nodep->widthMin()));
if (nodep->op1p()) { puts(","+cvtToStr(nodep->op1p()->widthMin())); }
if (nodep->op2p()) { puts(","+cvtToStr(nodep->op2p()->widthMin())); }
if (nodep->op3p()) { puts(","+cvtToStr(nodep->op3p()->widthMin())); }
if (nodep->op1p() || nodep->isWide()) puts(", ");
}
if (nodep->isWide()) {
if (!m_wideTempRefp) nodep->v3fatalSrc("Wide Op w/ no temp, perhaps missing op in V3EmitC?");
puts(m_wideTempRefp->hiername());
puts(m_wideTempRefp->varp()->name());
m_wideTempRefp = NULL;
if (nodep->op1p()) puts(", ");
} }
} }
@@ -889,13 +952,11 @@ void EmitCStmts::emitOpName(AstNode* nodep, const string& opname) {
// We only do one display at once, so can just use static state // We only do one display at once, so can just use static state
struct EmitDispState { struct EmitDispState {
bool m_wide; // Put out a wide func that needs string buffer
string m_format; // "%s" and text from user string m_format; // "%s" and text from user
vector<AstNode*> m_argsp; // Each argument to be printed vector<AstNode*> m_argsp; // Each argument to be printed
vector<string> m_argsFunc; // Function before each argument to be printed vector<string> m_argsFunc; // Function before each argument to be printed
EmitDispState() { clear(); } EmitDispState() { clear(); }
void clear() { void clear() {
m_wide = false;
m_format = ""; m_format = "";
m_argsp.clear(); m_argsp.clear();
m_argsFunc.clear(); m_argsFunc.clear();
@@ -907,18 +968,40 @@ struct EmitDispState {
} }
} emitDispState; } emitDispState;
void EmitCStmts::displayEmit(AstDisplay* nodep) { void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
if (emitDispState.m_format != "") { if (emitDispState.m_format == ""
&& nodep->castDisplay()) { // not fscanf etc, as they need to return value
// NOP
} else {
// Format // Format
if (nodep->filep()) { bool isStmt;
puts("if ("); if (AstFScanF* dispp = nodep->castFScanF()) {
nodep->filep()->iterate(*this); // Check if closed, to avoid core dump isStmt = false;
puts(") fprintf(VL_CVT_Q_FP("); puts("VL_FSCANF_IX(");
nodep->filep()->iterate(*this); dispp->filep()->iterate(*this);
puts("),\""); puts(",");
} else if (AstSScanF* dispp = nodep->castSScanF()) {
isStmt = false;
checkMaxWords(dispp->fromp());
puts("VL_SSCANF_I"); emitIQW(dispp->fromp()); puts("X(");
puts(cvtToStr(dispp->fromp()->widthMin()));
puts(",");
dispp->fromp()->iterate(*this);
puts(",");
} else if (AstDisplay* dispp = nodep->castDisplay()) {
isStmt = true;
if (dispp->filep()) {
puts("VL_FWRITEF(");
dispp->filep()->iterate(*this);
puts(",");
} else {
puts("VL_WRITEF(");
}
} else { } else {
puts("VL_PRINTF(\""); isStmt = true;
nodep->v3fatalSrc("Unknown displayEmit node type");
} }
puts("\"");
ofp()->putsNoTracking(emitDispState.m_format); ofp()->putsNoTracking(emitDispState.m_format);
puts("\""); puts("\"");
// Arguments // Arguments
@@ -929,162 +1012,133 @@ void EmitCStmts::displayEmit(AstDisplay* nodep) {
ofp()->indentInc(); ofp()->indentInc();
ofp()->putbs(""); ofp()->putbs("");
if (func!="") puts(func); if (func!="") puts(func);
if (argp) argp->iterate(*this); if (argp) {
if (func!="") puts(")"); if (isScan) puts("&(");
argp->iterate(*this);
if (isScan) puts(")");
}
ofp()->indentDec(); ofp()->indentDec();
} }
// End // End
puts(");\n"); puts(")");
if (isStmt) puts(";\n");
else puts(" ");
// Prep for next // Prep for next
emitDispState.clear(); emitDispState.clear();
} }
} }
string EmitCStmts::displayFormat(AstNode* widthNodep, string in, void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
char fmtLetter, bool padZero, bool reallyString) { string vfmt, char fmtLetter) {
if (fmtLetter=='s') padZero = false;
if (widthNodep && widthNodep->isWide()
&& (fmtLetter=='d'||fmtLetter=='u')) {
widthNodep->v3error("Unsupported: $display of dec format of > 64 bit results (use hex format instead)");
}
if (widthNodep && widthNodep->widthMin()>8 && fmtLetter=='c') {
widthNodep->v3error("$display of char format of > 8 bit result");
}
string fmt;
if (in == "") {
// Size naturally
if (widthNodep == NULL) fmt=""; // Out of args, will get error
if (fmtLetter=='u' || fmtLetter=='d') { // Decimal. Spec says leading spaces, not zeros
double mantissabits = widthNodep->widthMin() - ((fmtLetter=='d')?1:0);
double maxval = pow(2.0, mantissabits);
double dchars = log10(maxval)+1.0;
if (fmtLetter=='d') dchars++; // space for sign
int nchars = int(dchars);
fmt=cvtToStr(nchars);
} else if (fmtLetter!='s' && fmtLetter!='c') { // Strings/chars don't get padding
int bitsPerChar = (fmtLetter=='b'?1 : fmtLetter=='o'?3 : 4);
int nchars = (widthNodep->widthMin() + bitsPerChar-1)/bitsPerChar;
if (padZero) fmt=(string)("0")+cvtToStr(nchars);
else fmt=cvtToStr(nchars);
}
} else if (in == "0") {
fmt=""; // No width
} else {
fmt=in;
}
return fmt;
}
void EmitCStmts::displayArg(AstDisplay* dispp, AstNode** elistp, string fmt, char fmtLetter) {
// Print display argument, edits elistp // Print display argument, edits elistp
if (!*elistp) { AstNode* argp = *elistp;
dispp->v3error("Missing arguments for $display format"); if (!argp) {
// expectDisplay() checks this first, so internal error if found here
dispp->v3error("Internal: Missing arguments for $display format");
return; return;
} }
if ((*elistp)->widthMin() > VL_VALUE_STRING_MAX_WIDTH) { if (argp->widthMin() > VL_VALUE_STRING_MAX_WIDTH) {
dispp->v3error("Exceeded limit of 1024 bits for any display arguments"); dispp->v3error("Exceeded limit of 1024 bits for any display arguments");
} }
if (argp && argp->isWide()
if ((*elistp)->isWide() // Have to use our own function for wide, && (fmtLetter=='d'||fmtLetter=='u')) {
|| fmtLetter=='s' // ... Verilog strings argp->v3error("Unsupported: "<<dispp->verilogKwd()<<" of dec format of > 64 bit results (use hex format instead)");
|| fmtLetter=='b' // ... binary, no printf %b in C
|| fmtLetter=='d') { // ... Signed decimal
// We use a single static string, so must only have one call per VL_PRINT
if (emitDispState.m_wide) { displayEmit(dispp); }
emitDispState.m_wide = true;
string nfmt = displayFormat(*elistp, fmt, fmtLetter, false, true);
string pfmt = "%"+nfmt+"s";
string func = "VL_VALUE_FORMATTED_";
func += ((*elistp)->isWide()) ? "W(" : ((*elistp)->isQuad()) ? "Q(" : "I(";
func += (cvtToStr((*elistp)->widthMin())
+",'"+fmtLetter+"'"
+","+(fmt=="0"?"true":"false")+",");
emitDispState.pushFormat(pfmt);
emitDispState.pushArg(*elistp,func);
} else {
string func;
string nfmt = displayFormat(*elistp, fmt, fmtLetter, true, false);
// We don't need to check for fmtLetter=='d', as it is above.
if ((*elistp)->isQuad() && (fmtLetter=='u'||fmtLetter=='o'||fmtLetter=='x')) {
nfmt+="ll";
func="(unsigned long long)("; // Must match %ull to avoid warnings
}
string pfmt = "%"+nfmt+fmtLetter;
emitDispState.pushFormat(pfmt);
emitDispState.pushArg(*elistp,func);
} }
if (argp && argp->widthMin()>8 && fmtLetter=='c') {
// Technically legal, but surely not what the user intended.
argp->v3error(dispp->verilogKwd()<<" of char format of > 8 bit result");
}
//string pfmt = "%"+displayFormat(argp, vfmt, fmtLetter)+fmtLetter;
string pfmt;
if ((fmtLetter=='u' || fmtLetter=='d' || fmtLetter=='t')
&& !isScan
&& vfmt == "") { // Size decimal output. Spec says leading spaces, not zeros
double mantissabits = argp->widthMin() - ((fmtLetter=='d')?1:0);
double maxval = pow(2.0, mantissabits);
double dchars = log10(maxval)+1.0;
if (fmtLetter=='d') dchars++; // space for sign
int nchars = int(dchars);
pfmt = string("%") + cvtToStr(nchars) + fmtLetter;
} else {
pfmt = string("%") + vfmt + fmtLetter;
}
emitDispState.pushFormat(pfmt);
emitDispState.pushArg(NULL,cvtToStr(argp->widthMin()));
emitDispState.pushArg(argp,"");
// Next parameter // Next parameter
*elistp = (*elistp)->nextp(); *elistp = (*elistp)->nextp();
} }
void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) { void EmitCStmts::displayNode(AstNode* nodep, const string& vformat, AstNode* exprsp,
string vformat = nodep->text(); bool isScan) {
AstNode* elistp = nodep->exprsp(); AstNode* elistp = exprsp;
// Convert Verilog display to C printf formats // Convert Verilog display to C printf formats
// "%0t" becomes "%d" // "%0t" becomes "%d"
emitDispState.clear(); emitDispState.clear();
string fmt = ""; string vfmt = "";
string::iterator pos = vformat.begin(); string::const_iterator pos = vformat.begin();
if (*pos == '"') pos++;
bool inPct = false; bool inPct = false;
for (; pos != vformat.end(); ++pos) { for (; pos != vformat.end(); ++pos) {
if (pos[0]=='"' && (pos+1)==vformat.end()) break; //UINFO(1,"Parse '"<<*pos<<"' IP"<<inPct<<" List "<<(void*)(elistp)<<endl);
if (inPct && pos[0]=='%') { if (!inPct && pos[0]=='%') {
emitDispState.pushFormat("%%"); // We're printf'ing it, so need to quote the %
inPct = false;
} else if (pos[0]=='%') {
inPct = true; inPct = true;
fmt = ""; vfmt = "";
} else if (!inPct) { // Normal text } else if (!inPct) { // Normal text
//char text[2]; text[0]=*pos; text[1]='\0';
emitDispState.pushFormat(*pos); emitDispState.pushFormat(*pos);
} else { // Format character } else { // Format character
if (isdigit(pos[0])) { inPct = false;
switch (tolower(pos[0])) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
// Digits, like %5d, etc. // Digits, like %5d, etc.
fmt += pos[0]; vfmt += pos[0];
} else { inPct = true; // Get more digits
inPct = false; break;
switch (tolower(pos[0])) { case '%':
// Special codes emitDispState.pushFormat("%%"); // We're printf'ing it, so need to quote the %
case '~': displayArg(nodep,&elistp,fmt,'d'); break; // Signed decimal break;
// Spec: h d o b c l // Special codes
case 'b': displayArg(nodep,&elistp,fmt,'b'); break; case '~': displayArg(nodep,&elistp,isScan, vfmt,'d'); break; // Signed decimal
case 'c': displayArg(nodep,&elistp,fmt,'c'); break; // Spec: h d o b c l
case 't': case 'b': displayArg(nodep,&elistp,isScan, vfmt,'b'); break;
case 'd': displayArg(nodep,&elistp,fmt,'u'); break; // Unsigned decimal case 'c': displayArg(nodep,&elistp,isScan, vfmt,'c'); break;
case 'o': displayArg(nodep,&elistp,fmt,'o'); break; case 't': displayArg(nodep,&elistp,isScan, vfmt,'t'); break;
case 'h': case 'd': displayArg(nodep,&elistp,isScan, vfmt,'u'); break; // Unsigned decimal
case 'x': displayArg(nodep,&elistp,fmt,'x'); break; case 'o': displayArg(nodep,&elistp,isScan, vfmt,'o'); break;
case 's': displayArg(nodep,&elistp,fmt,'s'); break; case 'h':
case 'm': { case 'x': displayArg(nodep,&elistp,isScan, vfmt,'x'); break;
emitDispState.pushFormat("%s"); case 's': displayArg(nodep,&elistp,isScan, vfmt,'s'); break;
emitDispState.pushArg(NULL, "vlSymsp->name("); case 'm': {
if (!nodep->scopeNamep()) nodep->v3fatalSrc("Display with %m but no AstScopeName"); emitDispState.pushFormat("%S");
for (AstText* textp=nodep->scopeNamep()->scopeAttrp(); textp; textp=textp->nextp()->castText()) { emitDispState.pushArg(NULL, "vlSymsp->name()");
emitDispState.pushFormat(textp->text()); if (!nodep->castDisplay()) nodep->v3fatalSrc("Non-Display with %m");
} AstScopeName* scopenamep = nodep->castDisplay()->scopeNamep();
break; if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName");
} for (AstText* textp=scopenamep->scopeAttrp(); textp; textp=textp->nextp()->castText()) {
case 'u': emitDispState.pushFormat(textp->text());
case 'z':
case 'l':
case 'v':
nodep->v3error("Unsupported: $display format code: %"<<pos[0]);
break;
default:
nodep->v3error("Unknown $display format code: %"<<pos[0]);
break;
} }
break;
}
case 'u':
case 'z':
case 'l':
case 'v':
nodep->v3error("Unsupported: $display format code: %"<<pos[0]);
break;
default:
nodep->v3error("Unknown $display format code: %"<<pos[0]);
break;
} }
} }
} }
if (elistp != NULL) { if (elistp != NULL) {
nodep->v3error("Extra arguments for $display format\n"); // expectFormat also checks this, and should have found it first, so internal
elistp->v3error("Internal: Extra arguments for $display format\n");
} }
if (nodep->addNewline()) emitDispState.pushFormat("\\n"); displayEmit(nodep, isScan);
displayEmit(nodep);
} }
//###################################################################### //######################################################################
@@ -1680,7 +1734,7 @@ void EmitCImp::main(AstModule* modp, bool slow, bool fast) {
} }
emitImp (modp); emitImp (modp);
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) { for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstCFunc* funcp = nodep->castCFunc()) { if (AstCFunc* funcp = nodep->castCFunc()) {
if (v3Global.opt.outputSplit() > 1 && splitSize() if (v3Global.opt.outputSplit() > 1 && splitSize()
@@ -1741,7 +1795,7 @@ class EmitCTrace : EmitCStmts {
puts("if (!Verilated::calcUnusedSigs()) vl_fatal(__FILE__,__LINE__,__FILE__,\"Turning on wave traces requires Verilated::traceEverOn(true) call before time 0.\");\n"); puts("if (!Verilated::calcUnusedSigs()) vl_fatal(__FILE__,__LINE__,__FILE__,\"Turning on wave traces requires Verilated::traceEverOn(true) call before time 0.\");\n");
puts("t->traceInitThis (vlSymsp, vcdp, code);\n"); puts("t->traceInitThis (vlSymsp, vcdp, code);\n");
puts("}\n"); puts("}\n");
puts("void "+topClassName()+"::traceFull(SpTraceVcd* vcdp, void* userthis, uint32_t code) {\n"); puts("void "+topClassName()+"::traceFull(SpTraceVcd* vcdp, void* userthis, uint32_t code) {\n");
puts("// Callback from vcd->dump()\n"); puts("// Callback from vcd->dump()\n");
puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n"); puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n");
@@ -1911,7 +1965,7 @@ class EmitCTrace : EmitCStmts {
} }
virtual void visit(AstCoverInc* nodep, AstNUser*) { virtual void visit(AstCoverInc* nodep, AstNUser*) {
} }
public: public:
EmitCTrace(bool slow) { EmitCTrace(bool slow) {
m_funcp = NULL; m_funcp = NULL;
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Emit C++ code for module tree // DESCRIPTION: Verilator: Emit C++ code for module tree
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+5 -5
View File
@@ -1,8 +1,8 @@
// $Id$ -*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Emit C++ for tree // DESCRIPTION: Verilator: Emit C++ for tree
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -24,10 +24,10 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <math.h> #include <cmath>
#include "V3Global.h" #include "V3Global.h"
#include "V3File.h" #include "V3File.h"
+4 -5
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Emit C++ for tree // DESCRIPTION: Verilator: Emit C++ for tree
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,10 +20,10 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <math.h> #include <cmath>
#include <map> #include <map>
#include <vector> #include <vector>
+5 -6
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Emit C++ for tree // DESCRIPTION: Verilator: Emit C++ for tree
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,10 +20,10 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <math.h> #include <cmath>
#include <map> #include <map>
#include <set> #include <set>
#include <vector> #include <vector>
@@ -68,7 +67,7 @@ class EmitCSyms : EmitCBaseVisitor {
virtual void visit(AstNetlist* nodep, AstNUser*) { virtual void visit(AstNetlist* nodep, AstNUser*) {
// Collect list of scopes // Collect list of scopes
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
// Sort m_scopes by scope name // Sort m_scopes by scope name
sort(m_scopes.begin(), m_scopes.end(), CmpName()); sort(m_scopes.begin(), m_scopes.end(), CmpName());
// Output // Output
+9 -9
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Emit Makefile // DESCRIPTION: Verilator: Emit Makefile
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,10 +20,10 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <math.h> #include <cmath>
#include <map> #include <map>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
@@ -47,6 +46,7 @@ public:
of.putsHeader(); of.putsHeader();
of.puts("\n"); of.puts("\n");
of.puts("VM_COVERAGE = "); of.puts(v3Global.opt.coverage()?"1":"0"); of.puts("\n");
of.puts("VM_TRACE = "); of.puts(v3Global.opt.trace()?"1":"0"); of.puts("\n"); of.puts("VM_TRACE = "); of.puts(v3Global.opt.trace()?"1":"0"); of.puts("\n");
of.puts("\n"); of.puts("\n");
@@ -79,16 +79,16 @@ public:
of.puts("default: "+v3Global.opt.prefix()+"__ALL.a\n"); of.puts("default: "+v3Global.opt.prefix()+"__ALL.a\n");
} }
of.puts("\n# Constants...\n"); of.puts("\n# Constants...\n");
of.puts("PERL = "+V3Options::getenvStr("PERL","perl")+"\n"); of.puts("PERL = "+V3Options::getenvPERL()+"\n");
of.puts("VERILATOR_ROOT = "+V3Options::getenvStr("VERILATOR_ROOT","")+"\n"); of.puts("VERILATOR_ROOT = "+V3Options::getenvVERILATOR_ROOT()+"\n");
of.puts("SYSTEMPERL = "+V3Options::getenvStr("SYSTEMPERL","")+"\n"); of.puts("SYSTEMPERL = "+V3Options::getenvSYSTEMPERL()+"\n");
of.puts("\n# Switches...\n"); of.puts("\n# Switches...\n");
of.puts(string("VM_SP = ")+(v3Global.opt.systemPerl()?"1":"0")+"\n"); of.puts(string("VM_SP = ")+(v3Global.opt.systemPerl()?"1":"0")+"\n");
of.puts(string("VM_SC = ")+((v3Global.opt.systemC()&&!v3Global.opt.systemPerl())?"1":"0")+"\n"); of.puts(string("VM_SC = ")+((v3Global.opt.systemC()&&!v3Global.opt.systemPerl())?"1":"0")+"\n");
of.puts(string("VM_SP_OR_SC = ")+(v3Global.opt.systemC()?"1":"0")+"\n"); of.puts(string("VM_SP_OR_SC = ")+(v3Global.opt.systemC()?"1":"0")+"\n");
of.puts(string("VM_PCLI = ")+(v3Global.opt.systemC()?"0":"1")+"\n"); of.puts(string("VM_PCLI = ")+(v3Global.opt.systemC()?"0":"1")+"\n");
of.puts(string("VM_SC_TARGET_ARCH = ")+V3Options::getenvStr("SYSTEMC_ARCH","")+"\n"); of.puts(string("VM_SC_TARGET_ARCH = ")+V3Options::getenvSYSTEMC_ARCH()+"\n");
of.puts("\n# Vars...\n"); of.puts("\n# Vars...\n");
of.puts(string("VM_PREFIX = ")+v3Global.opt.prefix()+"\n"); of.puts(string("VM_PREFIX = ")+v3Global.opt.prefix()+"\n");
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Emit Makefile // DESCRIPTION: Verilator: Emit Makefile
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+27 -11
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Emit Verilog from tree // DESCRIPTION: Verilator: Emit Verilog from tree
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,10 +20,10 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <math.h> #include <cmath>
#include <map> #include <map>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
@@ -164,19 +163,30 @@ public:
virtual void visit(AstCoverInc*, AstNUser*) { virtual void visit(AstCoverInc*, AstNUser*) {
// N/A // N/A
} }
virtual void visit(AstDisplay* nodep, AstNUser*) {
void visitNodeDisplay(AstNode* nodep, AstNode* filep, const string& text, AstNode* exprsp) {
putbs(nodep->verilogKwd()); putbs(nodep->verilogKwd());
putbs(" ("); putbs(" (");
if (nodep->filep()) { nodep->filep()->iterateAndNext(*this); putbs(","); } if (filep) { filep->iterateAndNext(*this); putbs(","); }
puts("\""); puts("\"");
ofp()->putsNoTracking(nodep->text()); ofp()->putsNoTracking(text);
puts("\""); puts("\"");
for (AstNode* expp=nodep->exprsp(); expp; expp = expp->nextp()) { for (AstNode* expp=exprsp; expp; expp = expp->nextp()) {
puts(","); puts(",");
expp->iterateAndNext(*this); expp->iterateAndNext(*this);
} }
puts(");\n"); puts(");\n");
} }
virtual void visit(AstDisplay* nodep, AstNUser*) {
visitNodeDisplay(nodep, nodep->filep(), nodep->text(), nodep->exprsp());
}
virtual void visit(AstFScanF* nodep, AstNUser*) {
visitNodeDisplay(nodep, nodep->filep(), nodep->text(), nodep->exprsp());
}
virtual void visit(AstSScanF* nodep, AstNUser*) {
visitNodeDisplay(nodep, nodep->fromp(), nodep->text(), nodep->exprsp());
}
virtual void visit(AstFOpen* nodep, AstNUser*) { virtual void visit(AstFOpen* nodep, AstNUser*) {
putbs(nodep->verilogKwd()); putbs(nodep->verilogKwd());
putbs(" ("); putbs(" (");
@@ -193,6 +203,12 @@ public:
if (nodep->filep()) nodep->filep()->iterateChildren(*this); if (nodep->filep()) nodep->filep()->iterateChildren(*this);
puts(");\n"); puts(");\n");
} }
virtual void visit(AstFFlush* nodep, AstNUser*) {
putbs(nodep->verilogKwd());
putbs(" (");
if (nodep->filep()) nodep->filep()->iterateChildren(*this);
puts(");\n");
}
virtual void visit(AstReadMem* nodep, AstNUser*) { virtual void visit(AstReadMem* nodep, AstNUser*) {
putbs(nodep->verilogKwd()); putbs(nodep->verilogKwd());
putbs(" ("); putbs(" (");
@@ -368,12 +384,12 @@ public:
// Terminals // Terminals
virtual void visit(AstVarRef* nodep, AstNUser*) { virtual void visit(AstVarRef* nodep, AstNUser*) {
puts(nodep->hiername()); puts(nodep->hiername());
puts(nodep->varp()->name()); puts(nodep->varp()->name());
} }
virtual void visit(AstVarXRef* nodep, AstNUser*) { virtual void visit(AstVarXRef* nodep, AstNUser*) {
puts(nodep->dotted()); puts(nodep->dotted());
puts("."); puts(".");
puts(nodep->varp()->name()); puts(nodep->varp()->name());
} }
virtual void visit(AstConst* nodep, AstNUser*) { virtual void visit(AstConst* nodep, AstNUser*) {
puts(nodep->num().ascii(true,true)); puts(nodep->num().ascii(true,true));
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- //-*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Emit Verilog code for module tree // DESCRIPTION: Verilator: Emit Verilog code for module tree
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+37 -12
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Error handling // DESCRIPTION: Verilator: Error handling
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,9 +18,9 @@
// //
//************************************************************************* //*************************************************************************
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <string.h> #include <cstring>
#include <set> #include <set>
#include "V3Error.h" #include "V3Error.h"
#ifndef _V3ERROR_NO_GLOBAL_ #ifndef _V3ERROR_NO_GLOBAL_
@@ -47,7 +46,7 @@ bool V3Error::s_pretendError[V3ErrorCode::MAX];
struct v3errorIniter { struct v3errorIniter {
v3errorIniter() { V3Error::init(); }; v3errorIniter() { V3Error::init(); };
}; };
v3errorIniter v3errorInit; v3errorIniter v3errorInit;
//###################################################################### //######################################################################
// ErrorCode class functions // ErrorCode class functions
@@ -66,6 +65,17 @@ V3ErrorCode::V3ErrorCode(const char* msgp) {
//###################################################################### //######################################################################
// FileLine class functions // FileLine class functions
FileLine::FileLine(FileLine::EmptySecret) {
m_lineno=0;
m_filename="COMMAND_LINE";
m_warnOff=0;
for (int codei=V3ErrorCode::FIRST_WARN; codei<V3ErrorCode::MAX; codei++) {
V3ErrorCode code = (V3ErrorCode)codei;
if (code.defaultsOff()) warnOff(code, true);
}
}
void FileLine::lineDirective(const char* textp) { void FileLine::lineDirective(const char* textp) {
// Handle `line directive // Handle `line directive
// Skip `line // Skip `line
@@ -154,13 +164,23 @@ ostream& operator<<(ostream& os, FileLine* fileline) {
return(os); return(os);
} }
bool FileLine::warnIsOff(V3ErrorCode code) { bool FileLine::warnIsOff(V3ErrorCode code) const {
if (m_warnOff.test(code)) return true; if (m_warnOff.test(code)) return true;
// UNOPTFLAT implies UNOPT // UNOPTFLAT implies UNOPT
if (code==V3ErrorCode::UNOPT && m_warnOff.test(V3ErrorCode::UNOPTFLAT)) return true; if (code==V3ErrorCode::UNOPT && m_warnOff.test(V3ErrorCode::UNOPTFLAT)) return true;
return false; return false;
} }
void FileLine::warnStateInherit(const FileLine& from) {
// Any warnings that are off in "from", become off in "this".
for (int codei=V3ErrorCode::FIRST_WARN; codei<V3ErrorCode::MAX; codei++) {
V3ErrorCode code = (V3ErrorCode)codei;
if (from.warnIsOff(code)) {
this->warnOff(code, true);
}
}
}
void FileLine::v3errorEnd(ostringstream& str) { void FileLine::v3errorEnd(ostringstream& str) {
if (this && m_lineno) { if (this && m_lineno) {
ostringstream nsstr; ostringstream nsstr;
@@ -203,7 +223,7 @@ void FileLine::deleteAllRemaining() {
while (1) { while (1) {
FileLineCheckSet::iterator it=fileLineLeakChecks.begin(); FileLineCheckSet::iterator it=fileLineLeakChecks.begin();
if (it==fileLineLeakChecks.end()) break; if (it==fileLineLeakChecks.end()) break;
delete *it; delete *it;
// Operator delete will remove the iterated object from the list. // Operator delete will remove the iterated object from the list.
// Eventually the list will be empty and terminate the loop. // Eventually the list will be empty and terminate the loop.
} }
@@ -243,8 +263,8 @@ void V3Error::incWarnings() {
void V3Error::incErrors() { void V3Error::incErrors() {
s_errCount++; s_errCount++;
if (errorCount() == MAX_ERRORS) { // Not >= as would otherwise recurse if (errorCount() == v3Global.opt.errorLimit()) { // Not >= as would otherwise recurse
v3fatal ("Exiting due to too many errors encountered\n"); v3fatal ("Exiting due to too many errors encountered; --error-limit="<<errorCount()<<endl);
} }
} }
@@ -262,6 +282,7 @@ void V3Error::abortIfWarnings() {
bool V3Error::isError(V3ErrorCode code) { bool V3Error::isError(V3ErrorCode code) {
if (code==V3ErrorCode::SUPPRESS) return false; if (code==V3ErrorCode::SUPPRESS) return false;
else if (code==V3ErrorCode::INFO) return false;
else if (code==V3ErrorCode::FATAL) return true; else if (code==V3ErrorCode::FATAL) return true;
else if (code==V3ErrorCode::ERROR) return true; else if (code==V3ErrorCode::ERROR) return true;
else if (code<V3ErrorCode::FIRST_WARN else if (code<V3ErrorCode::FIRST_WARN
@@ -271,6 +292,7 @@ bool V3Error::isError(V3ErrorCode code) {
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::INFO) return "-Info: ";
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 (isError(code)) return "%Error-"+(string)code.ascii()+": "; else if (isError(code)) return "%Error-"+(string)code.ascii()+": ";
@@ -307,12 +329,15 @@ void V3Error::v3errorEnd (ostringstream& sstr) {
#ifdef __COVERITY__ #ifdef __COVERITY__
if (s_errorCode==V3ErrorCode::FATAL) __coverity_panic__(x); if (s_errorCode==V3ErrorCode::FATAL) __coverity_panic__(x);
#endif #endif
if (s_errorCode!=V3ErrorCode::SUPPRESS || debug()) { if (s_errorCode!=V3ErrorCode::SUPPRESS
// On debug, show only non default-off warning to prevent pages of warnings
|| (debug() && !s_errorCode.defaultsOff())) {
cerr<<msgPrefix()<<sstr.str(); cerr<<msgPrefix()<<sstr.str();
if (sstr.str()[sstr.str().length()-1] != '\n') { if (sstr.str()[sstr.str().length()-1] != '\n') {
cerr<<endl; cerr<<endl;
} }
if (s_errorCode!=V3ErrorCode::SUPPRESS) { if (s_errorCode!=V3ErrorCode::SUPPRESS
&& s_errorCode!=V3ErrorCode::INFO) {
if (!s_describedEachWarn[s_errorCode] if (!s_describedEachWarn[s_errorCode]
&& !s_pretendError[s_errorCode]) { && !s_pretendError[s_errorCode]) {
s_describedEachWarn[s_errorCode] = true; s_describedEachWarn[s_errorCode] = true;
+20 -10
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Error handling // DESCRIPTION: Verilator: Error handling
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -34,6 +34,7 @@ class V3ErrorCode {
public: public:
enum en { enum en {
SUPPRESS, // Warning suppressed by user SUPPRESS, // Warning suppressed by user
INFO, // General information out
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:
@@ -45,14 +46,17 @@ public:
BLKANDNBLK, // Blocked and non-blocking assignments to same variable BLKANDNBLK, // Blocked and non-blocking assignments to same variable
CASEINCOMPLETE, // Case statement has missing values CASEINCOMPLETE, // Case statement has missing values
CASEOVERLAP, // Case statements overlap CASEOVERLAP, // Case statements overlap
CASEWITHX, // Case with X values
CASEX, // Casex CASEX, // Casex
CMPCONST, // Comparison is constant due to limited range CMPCONST, // Comparison is constant due to limited range
COMBDLY, // Combinatorial delayed assignment COMBDLY, // Combinatorial delayed assignment
STMTDLY, // Delayed statement STMTDLY, // Delayed statement
GENCLK, // Generated Clock GENCLK, // Generated Clock
IMPERFECTSCH, // Imperfect schedule (disabled by default)
IMPLICIT, // Implicit wire IMPLICIT, // Implicit wire
IMPURE, // Impure function not being inlined IMPURE, // Impure function not being inlined
MULTIDRIVEN, // Driven from multiple blocks MULTIDRIVEN, // Driven from multiple blocks
REDEFMACRO, // Redefining existing define macro
UNDRIVEN, // No drivers UNDRIVEN, // No drivers
UNOPT, // Unoptimizable block UNOPT, // Unoptimizable block
UNOPTFLAT, // Unoptimizable block after flattening UNOPTFLAT, // Unoptimizable block after flattening
@@ -60,6 +64,7 @@ public:
UNUSED, // No receivers UNUSED, // No receivers
VARHIDDEN, // Hiding variable VARHIDDEN, // Hiding variable
WIDTH, // Width mismatch WIDTH, // Width mismatch
WIDTHCONCAT, // Unsized numbers/parameters in concatenations
MAX MAX
// ***Add new elements below also*** // ***Add new elements below also***
}; };
@@ -72,19 +77,21 @@ public:
const char* ascii() const { const char* ascii() const {
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", " INFO", " FATAL", " ERROR",
"MULTITOP", "TASKNSVAR", "MULTITOP", "TASKNSVAR",
" FIRST_WARN", " FIRST_WARN",
"BLKANDNBLK", "BLKANDNBLK",
"CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST", "CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CMPCONST",
"COMBDLY", "STMTDLY", "GENCLK", "IMPLICIT", "IMPURE", "COMBDLY", "STMTDLY", "GENCLK", "IMPERFECTSCH", "IMPLICIT", "IMPURE",
"MULTIDRIVEN", "MULTIDRIVEN", "REDEFMACRO",
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
"VARHIDDEN", "WIDTH", "VARHIDDEN", "WIDTH", "WIDTHCONCAT",
" MAX" " MAX"
}; };
return names[m_e]; return names[m_e];
}; };
// Warnings that default to off
bool defaultsOff() const { return ( m_e==IMPERFECTSCH );};
// Warnings that warn about nasty side effects // Warnings that warn about nasty side effects
bool dangerous() const { return ( m_e==COMBDLY );}; bool dangerous() const { return ( m_e==COMBDLY );};
// Warnings we'll present to the user as errors // Warnings we'll present to the user as errors
@@ -92,7 +99,8 @@ public:
bool pretendError() const { return ( m_e==BLKANDNBLK || m_e==IMPURE); }; bool pretendError() const { return ( m_e==BLKANDNBLK || m_e==IMPURE); };
// Warnings that are lint only // Warnings that are lint only
bool lintError() const { return ( m_e==CASEINCOMPLETE || m_e==CASEOVERLAP bool lintError() const { return ( m_e==CASEINCOMPLETE || m_e==CASEOVERLAP
|| m_e==CASEX || m_e==CMPCONST || m_e==CASEWITHX || m_e==CASEX
|| m_e==CMPCONST
|| m_e==IMPLICIT || m_e==IMPLICIT
|| m_e==UNDRIVEN || m_e==UNSIGNED || m_e==UNDRIVEN || m_e==UNSIGNED
|| m_e==UNUSED || m_e==VARHIDDEN || m_e==UNUSED || m_e==VARHIDDEN
@@ -157,6 +165,7 @@ inline void v3errorEnd(ostringstream& sstr) { V3Error::v3errorEnd(sstr); }
// These allow errors using << operators: v3error("foo"<<"bar"); // These allow errors using << operators: v3error("foo"<<"bar");
// Careful, you can't put () around msg, as you would in most macro definitions // Careful, you can't put () around msg, as you would in most macro definitions
#define v3info(msg) v3errorEnd(((V3Error::v3errorPrep(V3ErrorCode::INFO)<<msg),V3Error::v3errorStr()));
#define v3fatal(msg) v3errorEnd(((V3Error::v3errorPrep(V3ErrorCode::FATAL)<<msg),V3Error::v3errorStr())); #define v3fatal(msg) v3errorEnd(((V3Error::v3errorPrep(V3ErrorCode::FATAL)<<msg),V3Error::v3errorStr()));
#define v3error(msg) v3errorEnd(((V3Error::v3errorPrep(V3ErrorCode::ERROR)<<msg),V3Error::v3errorStr())); #define v3error(msg) v3errorEnd(((V3Error::v3errorPrep(V3ErrorCode::ERROR)<<msg),V3Error::v3errorStr()));
#define v3warn(code,msg) v3errorEnd(((V3Error::v3errorPrep(V3ErrorCode::code)<<msg),V3Error::v3errorStr())); #define v3warn(code,msg) v3errorEnd(((V3Error::v3errorPrep(V3ErrorCode::code)<<msg),V3Error::v3errorStr()));
@@ -201,7 +210,7 @@ protected:
public: public:
FileLine (const string& filename, int lineno) { m_lineno=lineno; m_filename = filename; m_warnOff=s_defaultFileLine.m_warnOff; } FileLine (const string& filename, int lineno) { m_lineno=lineno; m_filename = filename; m_warnOff=s_defaultFileLine.m_warnOff; }
FileLine (FileLine* fromp) { m_lineno=fromp->lineno(); m_filename = fromp->filename(); m_warnOff=fromp->m_warnOff; } FileLine (FileLine* fromp) { m_lineno=fromp->lineno(); m_filename = fromp->filename(); m_warnOff=fromp->m_warnOff; }
FileLine (EmptySecret) { m_lineno=0; m_filename="COMMAND_LINE"; m_warnOff=0; } FileLine (EmptySecret);
~FileLine() { } ~FileLine() { }
#ifdef VL_LEAK_CHECKS #ifdef VL_LEAK_CHECKS
static void* operator new(size_t size); static void* operator new(size_t size);
@@ -216,9 +225,10 @@ public:
const string profileFuncname() const; const string profileFuncname() const;
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) const;
void warnLintOff(bool flag); void warnLintOff(bool flag);
void warnStateFrom(const FileLine& from) { m_warnOff=from.m_warnOff; } void warnStateFrom(const FileLine& from) { m_warnOff=from.m_warnOff; }
void warnStateInherit(const FileLine& from);
void warnResetDefault() { warnStateFrom(s_defaultFileLine); } void warnResetDefault() { warnStateFrom(s_defaultFileLine); }
void v3errorEnd(ostringstream& str); void v3errorEnd(ostringstream& str);
+21 -22
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Add temporaries, such as for expand nodes // DESCRIPTION: Verilator: Add temporaries, such as for expand nodes
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3Expand's Transformations: // V3Expand's Transformations:
// //
// Each module: // Each module:
// Expand verilated.h macros into internal micro optimizations (RTL) // Expand verilated.h macros into internal micro optimizations (RTL)
// this will enable later optimizations. // this will enable later optimizations.
@@ -32,8 +31,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
@@ -168,7 +167,7 @@ private:
} }
return newp; return newp;
} }
AstNode* newSelBitWord(AstNode* lsbp, int wordAdder) { AstNode* newSelBitWord(AstNode* lsbp, int wordAdder) {
// Return equation to get the VL_BITWORD of a constant or non-constant // Return equation to get the VL_BITWORD of a constant or non-constant
if (lsbp->castConst()) { if (lsbp->castConst()) {
@@ -355,7 +354,7 @@ private:
AstNode* lowwordp = new AstWordSel (nodep->fromp()->fileline(), AstNode* lowwordp = new AstWordSel (nodep->fromp()->fileline(),
nodep->fromp()->cloneTree(true), nodep->fromp()->cloneTree(true),
newSelBitWord(nodep->lsbp(), 0)); newSelBitWord(nodep->lsbp(), 0));
if (nodep->isQuad() && !lowwordp->isQuad()) lowwordp = new AstCast(nodep->fileline(), lowwordp, nodep); if (nodep->isQuad() && !lowwordp->isQuad()) lowwordp = new AstCast(nodep->fileline(), lowwordp, nodep);
AstNode* lowp = new AstShiftR (nodep->fileline(), AstNode* lowp = new AstShiftR (nodep->fileline(),
lowwordp, lowwordp,
newSelBitBit(nodep->lsbp()), newSelBitBit(nodep->lsbp()),
@@ -368,7 +367,7 @@ private:
new AstWordSel (nodep->fromp()->fileline(), new AstWordSel (nodep->fromp()->fileline(),
nodep->fromp()->cloneTree(true), nodep->fromp()->cloneTree(true),
newSelBitWord(nodep->lsbp(), 1)); newSelBitWord(nodep->lsbp(), 1));
if (nodep->isQuad() && !midwordp->isQuad()) midwordp = new AstCast(nodep->fileline(), midwordp, nodep); if (nodep->isQuad() && !midwordp->isQuad()) midwordp = new AstCast(nodep->fileline(), midwordp, nodep);
// If we're selecting bit zero, then all 32 bits in word 1 get shifted << by 32 bits // If we're selecting bit zero, then all 32 bits in word 1 get shifted << by 32 bits
// else we need to form the lower word, so we << by 31 or less // else we need to form the lower word, so we << by 31 or less
// nbitsfromlow <= (lsb==0) ? 64-bitbit(lsb) : 32-bitbit(lsb) // nbitsfromlow <= (lsb==0) ? 64-bitbit(lsb) : 32-bitbit(lsb)
@@ -406,7 +405,7 @@ private:
new AstWordSel (nodep->fromp()->fileline(), new AstWordSel (nodep->fromp()->fileline(),
nodep->fromp()->cloneTree(true), nodep->fromp()->cloneTree(true),
newSelBitWord(nodep->lsbp(), 2)); newSelBitWord(nodep->lsbp(), 2));
if (nodep->isQuad() && !hiwordp->isQuad()) hiwordp = new AstCast(nodep->fileline(), hiwordp, nodep); if (nodep->isQuad() && !hiwordp->isQuad()) hiwordp = new AstCast(nodep->fileline(), hiwordp, nodep);
AstNode* himayp = AstNode* himayp =
new AstShiftL (nodep->fileline(), new AstShiftL (nodep->fileline(),
hiwordp, hiwordp,
@@ -434,7 +433,7 @@ private:
UINFO(8," SEL->SHIFT "<<nodep<<endl); UINFO(8," SEL->SHIFT "<<nodep<<endl);
AstNode* fromp = nodep->fromp()->unlinkFrBack(); AstNode* fromp = nodep->fromp()->unlinkFrBack();
AstNode* lsbp = nodep->lsbp()->unlinkFrBack(); AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
if (nodep->isQuad() && !fromp->isQuad()) fromp = new AstCast(nodep->fileline(), fromp, nodep); if (nodep->isQuad() && !fromp->isQuad()) fromp = new AstCast(nodep->fileline(), fromp, nodep);
AstNode* newp = new AstShiftR (nodep->fileline(), AstNode* newp = new AstShiftR (nodep->fileline(),
fromp, fromp,
dropCondBound(lsbp), dropCondBound(lsbp),
@@ -504,7 +503,7 @@ private:
bool destwide = lhsp->fromp()->isWide(); bool destwide = lhsp->fromp()->isWide();
bool ones = nodep->rhsp()->isAllOnesV(); bool ones = nodep->rhsp()->isAllOnesV();
if (lhsp->lsbp()->castConst()) { if (lhsp->lsbp()->castConst()) {
// The code should work without this constant test, but it won't // The code should work without this constant test, but it won't
// constify as nicely as we'd like. // constify as nicely as we'd like.
AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
AstNode* destp = lhsp->fromp()->unlinkFrBack(); AstNode* destp = lhsp->fromp()->unlinkFrBack();
@@ -592,7 +591,7 @@ private:
// For wide destp, we can either form a equation for every destination word, // For wide destp, we can either form a equation for every destination word,
// with the appropriate long equation of if it's being written or not. // with the appropriate long equation of if it's being written or not.
// Or, we can use a LHS variable arraysel with non-constant index to set the vector. // Or, we can use a LHS variable arraysel with non-constant index to set the vector.
// Doing the variable arraysel is better for globals and large arrays, // Doing the variable arraysel is better for globals and large arrays,
// doing every word is better for temporaries and if we're setting most words // doing every word is better for temporaries and if we're setting most words
// since it may result in better substitution optimizations later. // since it may result in better substitution optimizations later.
// This results in so much code, we're better off leaving a function call. // This results in so much code, we're better off leaving a function call.
@@ -630,7 +629,7 @@ private:
//newp->dumpTree(cout,"- new: "); //newp->dumpTree(cout,"- new: ");
insertBefore(nodep,newp); insertBefore(nodep,newp);
return true; return true;
} }
} }
} }
@@ -641,10 +640,10 @@ private:
} else { } else {
UINFO(8," CONCAT "<<nodep<<endl); UINFO(8," CONCAT "<<nodep<<endl);
AstNode* lhsp = nodep->lhsp()->unlinkFrBack(); AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
int rhsshift = rhsp->widthMin(); int rhsshift = rhsp->widthMin();
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCast(nodep->fileline(), lhsp, nodep); if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCast(nodep->fileline(), lhsp, nodep);
if (nodep->isQuad() && !rhsp->isQuad()) rhsp = new AstCast(nodep->fileline(), rhsp, nodep); if (nodep->isQuad() && !rhsp->isQuad()) rhsp = new AstCast(nodep->fileline(), rhsp, nodep);
AstNode* newp = new AstOr (nodep->fileline(), AstNode* newp = new AstOr (nodep->fileline(),
new AstShiftL (nodep->fileline(), new AstShiftL (nodep->fileline(),
lhsp, lhsp,
@@ -657,7 +656,7 @@ private:
} }
bool expandWide (AstNodeAssign* nodep, AstConcat* rhsp) { bool expandWide (AstNodeAssign* nodep, AstConcat* rhsp) {
UINFO(8," Wordize ASSIGN(CONCAT) "<<nodep<<endl); UINFO(8," Wordize ASSIGN(CONCAT) "<<nodep<<endl);
// Lhs or Rhs may be word, long, or quad. // Lhs or Rhs may be word, long, or quad.
// newAstWordSelClone nicely abstracts the difference. // newAstWordSelClone nicely abstracts the difference.
int rhsshift = rhsp->rhsp()->widthMin(); int rhsshift = rhsp->rhsp()->widthMin();
// Sometimes doing the words backwards is preferrable. // Sometimes doing the words backwards is preferrable.
@@ -670,7 +669,7 @@ private:
rhsp->lhsp(), rhsshift), rhsp->lhsp(), rhsshift),
newAstWordSelClone (rhsp->rhsp(), w))); newAstWordSelClone (rhsp->rhsp(), w)));
} }
return true; return true;
} }
virtual void visit(AstReplicate* nodep, AstNUser*) { virtual void visit(AstReplicate* nodep, AstNUser*) {
@@ -689,8 +688,8 @@ private:
UINFO(8," REPLICATE "<<nodep<<endl); UINFO(8," REPLICATE "<<nodep<<endl);
AstConst* constp = nodep->rhsp()->castConst(); AstConst* constp = nodep->rhsp()->castConst();
if (!constp) nodep->v3fatalSrc("Replication value isn't a constant. Checked earlier!"); if (!constp) nodep->v3fatalSrc("Replication value isn't a constant. Checked earlier!");
uint32_t times = constp->asInt(); uint32_t times = constp->toUInt();
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCast(nodep->fileline(), lhsp, nodep); if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCast(nodep->fileline(), lhsp, nodep);
newp = lhsp->cloneTree(true); newp = lhsp->cloneTree(true);
for (unsigned repnum=1; repnum<times; repnum++) { for (unsigned repnum=1; repnum<times; repnum++) {
int rhsshift = repnum*lhswidth; int rhsshift = repnum*lhswidth;
@@ -714,7 +713,7 @@ private:
int lhswidth = lhsp->widthMin(); int lhswidth = lhsp->widthMin();
AstConst* constp = rhsp->rhsp()->castConst(); AstConst* constp = rhsp->rhsp()->castConst();
if (!constp) rhsp->v3fatalSrc("Replication value isn't a constant. Checked earlier!"); if (!constp) rhsp->v3fatalSrc("Replication value isn't a constant. Checked earlier!");
uint32_t times = constp->asInt(); uint32_t times = constp->toUInt();
for (int w=0; w<rhsp->widthWords(); w++) { for (int w=0; w<rhsp->widthWords(); w++) {
AstNode* newp; AstNode* newp;
if (lhswidth==1) { if (lhswidth==1) {
@@ -731,7 +730,7 @@ private:
} }
addWordAssign(nodep, w, newp); addWordAssign(nodep, w, newp);
} }
return true; return true;
} }
virtual void visit(AstChangeXor* nodep, AstNUser*) { virtual void visit(AstChangeXor* nodep, AstNUser*) {
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Expansion of wide operator macros to C operators // DESCRIPTION: Verilator: Expansion of wide operator macros to C operators
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+14 -5
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: File stream wrapper that understands indentation // DESCRIPTION: Verilator: File stream wrapper that understands indentation
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,8 +20,9 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdarg.h> #include <cstdarg>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <iomanip> #include <iomanip>
#include <memory> #include <memory>
@@ -232,12 +232,21 @@ bool V3File::checkTimes(const string& filename, const string& cmdline) {
return dependImp.checkTimes(filename, cmdline); return dependImp.checkTimes(filename, cmdline);
} }
void V3File::createMakeDir() {
static bool created = false;
if (!created) {
created = true;
mkdir(v3Global.opt.makeDir().c_str(), 0777);
}
}
//###################################################################### //######################################################################
// V3OutFile: A class for printing to a file, with automatic indentation of C++ code. // V3OutFile: A class for printing to a file, with automatic indentation of C++ code.
V3OutFile::V3OutFile(const string& filename) V3OutFile::V3OutFile(const string& filename)
: m_lineno(1), m_column(0), m_nobreak(false), m_prependIndent(true), m_indentLevel(0) : m_filename(filename), m_lineno(1), m_column(0)
, m_declSAlign(0), m_declNSAlign(0), m_declPadNum(0) { , m_nobreak(false), m_prependIndent(true), m_indentLevel(0)
, m_declSAlign(0), m_declNSAlign(0), m_declPadNum(0) {
if ((m_fp = V3File::new_fopen_w(filename.c_str())) == NULL) { if ((m_fp = V3File::new_fopen_w(filename.c_str())) == NULL) {
v3fatal("Cannot write "<<filename); v3fatal("Cannot write "<<filename);
} }
+13 -5
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: File stream wrapper that understands indentation // DESCRIPTION: Verilator: File stream wrapper that understands indentation
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -24,7 +24,7 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include "V3Error.h" #include "V3Error.h"
#include <stdio.h> #include <cstdio>
#include <stack> #include <stack>
#include <set> #include <set>
#include <fstream> #include <fstream>
@@ -46,6 +46,7 @@ public:
return new_ofstream_nodepend (filename, append); return new_ofstream_nodepend (filename, append);
} }
static ofstream* new_ofstream_nodepend(const string& filename, bool append=false) { static ofstream* new_ofstream_nodepend(const string& filename, bool append=false) {
if (filename != "/dev/null") createMakeDir();
if (append) { if (append) {
return new ofstream(filename.c_str(), ios::app); return new ofstream(filename.c_str(), ios::app);
} else { } else {
@@ -53,15 +54,20 @@ public:
} }
} }
static FILE* new_fopen_w(const string& filename) { static FILE* new_fopen_w(const string& filename) {
if (filename != "/dev/null") createMakeDir();
addTgtDepend(filename); addTgtDepend(filename);
return fopen(filename.c_str(),"w"); return fopen(filename.c_str(),"w");
} }
// Dependencies // Dependencies
static void addSrcDepend(const string& filename); static void addSrcDepend(const string& filename);
static void addTgtDepend(const string& filename); static void addTgtDepend(const string& filename);
static void writeDepend(const string& filename); static void writeDepend(const string& filename);
static void writeTimes(const string& filename, const string& cmdline); static void writeTimes(const string& filename, const string& cmdline);
static bool checkTimes(const string& filename, const string& cmdline); static bool checkTimes(const string& filename, const string& cmdline);
// Directory utilities
static void createMakeDir();
}; };
//============================================================================ //============================================================================
@@ -81,6 +87,7 @@ public:
private: private:
// MEMBERS // MEMBERS
FILE* m_fp; FILE* m_fp;
string m_filename;
int m_lineno; int m_lineno;
int m_column; int m_column;
int m_nobreak; // Basic operator or begin paren, don't break next int m_nobreak; // Basic operator or begin paren, don't break next
@@ -114,8 +121,9 @@ public:
bool tokenStart(const char* cp, const char* cmp); bool tokenStart(const char* cp, const char* cmp);
bool tokenEnd(const char* cp); bool tokenEnd(const char* cp);
void indentInc() { m_indentLevel += INDBLK; }; void indentInc() { m_indentLevel += INDBLK; };
void indentDec() { m_indentLevel -= INDBLK; void indentDec() {
UASSERT(m_indentLevel>=0,"Underflow of indentation\n"); m_indentLevel -= INDBLK;
UASSERT(m_indentLevel>=0, ": "<<m_filename<<": Underflow of indentation\n");
} }
void blockInc() { m_parenVec.push(m_indentLevel + INDBLK); } void blockInc() { m_parenVec.push(m_indentLevel + INDBLK); }
void blockDec() { if (!m_parenVec.empty()) m_parenVec.pop(); } void blockDec() { if (!m_parenVec.empty()) m_parenVec.pop(); }
+7 -8
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Gate optimizations, such as wire elimination // DESCRIPTION: Verilator: Gate optimizations, such as wire elimination
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -19,7 +18,7 @@
// //
//************************************************************************* //*************************************************************************
// V3Gate's Transformations: // V3Gate's Transformations:
// //
// Extract a graph of the *entire* netlist with cells expanded // Extract a graph of the *entire* netlist with cells expanded
// Perform constant optimization across the graph // Perform constant optimization across the graph
// Create VARSCOPEs for any variables we can rip out // Create VARSCOPEs for any variables we can rip out
@@ -28,8 +27,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
#include <iomanip> #include <iomanip>
@@ -170,7 +169,7 @@ private:
// V3Const cleans up any NOTs by flipping the edges for us // V3Const cleans up any NOTs by flipping the edges for us
if (m_buffersOnly if (m_buffersOnly
&& !(nodep->rhsp()->castVarRef() && !(nodep->rhsp()->castVarRef()
// Until NEW_ORDERING, avoid making non-clocked logic into clocked, // Until NEW_ORDERING, avoid making non-clocked logic into clocked,
// as it slows down the verilator_sim_benchmark // as it slows down the verilator_sim_benchmark
|| (nodep->rhsp()->castNot() || (nodep->rhsp()->castNot()
&& nodep->rhsp()->castNot()->lhsp()->castVarRef() && nodep->rhsp()->castNot()->lhsp()->castVarRef()
@@ -343,7 +342,7 @@ private:
UINFO(5," VARREF to "<<varscp<<endl); UINFO(5," VARREF to "<<varscp<<endl);
// We use weight of one; if we ref the var more than once, when we simplify, // We use weight of one; if we ref the var more than once, when we simplify,
// the weight will increase // the weight will increase
if (nodep->lvalue()) { if (nodep->lvalue()) {
new V3GraphEdge(&m_graph, m_logicVertexp, varvertexp, 1); new V3GraphEdge(&m_graph, m_logicVertexp, varvertexp, 1);
} else { } else {
new V3GraphEdge(&m_graph, varvertexp, m_logicVertexp, 1); new V3GraphEdge(&m_graph, varvertexp, m_logicVertexp, 1);
@@ -490,7 +489,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
if (debug()>=5) substp->dumpTree(cout,"\t subst: "); if (debug()>=5) substp->dumpTree(cout,"\t subst: ");
m_statSigs++; m_statSigs++;
while (V3GraphEdge* edgep = vvertexp->outBeginp()) { while (V3GraphEdge* edgep = vvertexp->outBeginp()) {
GateLogicVertex* consumeVertexp = dynamic_cast<GateLogicVertex*>(edgep->top()); GateLogicVertex* consumeVertexp = dynamic_cast<GateLogicVertex*>(edgep->top());
AstNode* consumerp = consumeVertexp->nodep(); AstNode* consumerp = consumeVertexp->nodep();
optimizeElimVar(vvertexp->varScp(), substp, consumerp); optimizeElimVar(vvertexp->varScp(), substp, consumerp);
// If the new replacement referred to a signal, // If the new replacement referred to a signal,
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity block domains // DESCRIPTION: Verilator: Break always into sensitivity block domains
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+6 -7
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Generated Clock repairs // DESCRIPTION: Verilator: Generated Clock repairs
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,13 +20,13 @@
// GENCLK TRANSFORMATIONS: // GENCLK TRANSFORMATIONS:
// Follow control-flow graph with assignments and var usages // Follow control-flow graph with assignments and var usages
// ASSIGNDLY to variable later used as clock requires change detect // ASSIGNDLY to variable later used as clock requires change detect
// //
//************************************************************************* //*************************************************************************
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include "V3Global.h" #include "V3Global.h"
@@ -93,7 +92,7 @@ private:
} }
//---- //----
virtual void visit(AstVarRef* nodep, AstNUser*) { virtual void visit(AstVarRef* nodep, AstNUser*) {
// Consumption/generation of a variable, // Consumption/generation of a variable,
AstVarScope* vscp = nodep->varScopep(); AstVarScope* vscp = nodep->varScopep();
if (!vscp) nodep->v3fatalSrc("Scope not assigned"); if (!vscp) nodep->v3fatalSrc("Scope not assigned");
if (m_activep && !nodep->user3()) { if (m_activep && !nodep->user3()) {
@@ -172,7 +171,7 @@ private:
//---- //----
virtual void visit(AstVarRef* nodep, AstNUser*) { virtual void visit(AstVarRef* nodep, AstNUser*) {
// Consumption/generation of a variable, // Consumption/generation of a variable,
AstVarScope* vscp = nodep->varScopep(); AstVarScope* vscp = nodep->varScopep();
if (!vscp) nodep->v3fatalSrc("Scope not assigned"); if (!vscp) nodep->v3fatalSrc("Scope not assigned");
if (m_activep) { if (m_activep) {
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- //-*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Generated Clock Repairs // DESCRIPTION: Verilator: Generated Clock Repairs
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Common headers // DESCRIPTION: Verilator: Common headers
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+5 -5
View File
@@ -1,8 +1,8 @@
// $Id$ // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Graph optimizations // DESCRIPTION: Verilator: Graph optimizations
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,8 +21,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
@@ -106,7 +106,7 @@ ostream& operator<<(ostream& os, V3GraphVertex* vertexp) {
//###################################################################### //######################################################################
// Edges // Edges
V3GraphEdge::V3GraphEdge(V3Graph* graphp, V3GraphEdge::V3GraphEdge(V3Graph* graphp,
V3GraphVertex* fromp, V3GraphVertex* top, int weight, V3GraphVertex* fromp, V3GraphVertex* top, int weight,
bool cutable) { bool cutable) {
UASSERT(fromp, "Null from pointer\n"); UASSERT(fromp, "Null from pointer\n");
+3 -3
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- //-*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Graph optimizations // DESCRIPTION: Verilator: Graph optimizations
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -67,7 +67,7 @@ public:
virtual ~V3Graph(); virtual ~V3Graph();
static void debug(int level) { s_debug = level; } static void debug(int level) { s_debug = level; }
virtual string dotRankDir() { return "TB"; } // rankdir for dot plotting virtual string dotRankDir() { return "TB"; } // rankdir for dot plotting
// METHODS // METHODS
void clear(); // Empty it of all vertices/edges, as if making a new object void clear(); // Empty it of all vertices/edges, as if making a new object
+3 -4
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Graph acyclic algorithm // DESCRIPTION: Verilator: Graph acyclic algorithm
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,8 +20,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
+4 -5
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Graph optimizations // DESCRIPTION: Verilator: Graph optimizations
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,8 +20,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
@@ -345,7 +344,7 @@ private:
if (m_done) return; if (m_done) return;
m_callTrace.reserve(currentRank+10); // Leave slop for speed m_callTrace.reserve(currentRank+10); // Leave slop for speed
m_callTrace[currentRank++] = vertexp; m_callTrace[currentRank++] = vertexp;
if (vertexp->user() == 1) { if (vertexp->user() == 1) {
for (unsigned i=0; i<currentRank; i++) { for (unsigned i=0; i<currentRank; i++) {
+2 -2
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Graph algorithm base class // DESCRIPTION: Verilator: Graph algorithm base class
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
+104 -11
View File
@@ -1,8 +1,7 @@
// $Id$
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Graph optimizations // DESCRIPTION: Verilator: Graph optimizations
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -21,8 +20,8 @@
#include "config_build.h" #include "config_build.h"
#include "verilatedos.h" #include "verilatedos.h"
#include <stdio.h> #include <cstdio>
#include <stdarg.h> #include <cstdarg>
#include <unistd.h> #include <unistd.h>
#include <stack> #include <stack>
#include <map> #include <map>
@@ -224,7 +223,7 @@ private:
} }
} }
} }
void main() { void main() {
UINFO(5,"Dfa to Nfa conversion...\n"); UINFO(5,"Dfa to Nfa conversion...\n");
// Vertex::color() begin: 1 indicates vertex on DFA graph, 0=NFA graph // Vertex::color() begin: 1 indicates vertex on DFA graph, 0=NFA graph
@@ -236,7 +235,7 @@ private:
// Find NFA start // Find NFA start
DfaVertex* nfaStartp = graphp()->findStart(); DfaVertex* nfaStartp = graphp()->findStart();
// Create new DFA State (start state) from the NFA states // Create new DFA State (start state) from the NFA states
DfaVertex* dfaStartp = newDfaVertex(nfaStartp); DfaVertex* dfaStartp = newDfaVertex(nfaStartp);
@@ -267,7 +266,7 @@ private:
} }
} }
if (debug()>=6) m_graphp->dumpDotFilePrefixed("dfa_start"); if (debug()>=6) m_graphp->dumpDotFilePrefixed("dfa_start");
insertDfaOrigins(dfaStartp); insertDfaOrigins(dfaStartp);
int i=0; int i=0;
UINFO(5,"Main state conversion...\n"); UINFO(5,"Main state conversion...\n");
@@ -293,7 +292,7 @@ private:
} }
} }
} }
// Foreach input state (NFA inputs of this DFA state) // Foreach input state (NFA inputs of this DFA state)
for (set<DfaInput>::const_iterator inIt=inputs.begin(); inIt!=inputs.end(); ++inIt) { for (set<DfaInput>::const_iterator inIt=inputs.begin(); inIt!=inputs.end(); ++inIt) {
DfaInput input = *inIt; DfaInput input = *inIt;
@@ -303,7 +302,7 @@ private:
// Find all states reachable for given input // Find all states reachable for given input
DfaStates nfasWithInput; DfaStates nfasWithInput;
findNfasWithInput(dfaStatep, input, nfasWithInput/*ref*/); findNfasWithInput(dfaStatep, input, nfasWithInput/*ref*/);
// nfasWithInput now maps to the DFA we want a transition to. // nfasWithInput now maps to the DFA we want a transition to.
// Does a DFA already exist with this, and only this subset of NFA's? // Does a DFA already exist with this, and only this subset of NFA's?
DfaVertex* toDfaStatep = findDfaOrigins(nfasWithInput); DfaVertex* toDfaStatep = findDfaOrigins(nfasWithInput);
@@ -317,7 +316,7 @@ private:
new DfaEdge (graphp(), toDfaStatep, *nfaIt, DfaEdge::NA()); new DfaEdge (graphp(), toDfaStatep, *nfaIt, DfaEdge::NA());
if ((*nfaIt)->accepting()) toDfaStatep->accepting(true); if ((*nfaIt)->accepting()) toDfaStatep->accepting(true);
} }
insertDfaOrigins(toDfaStatep); insertDfaOrigins(toDfaStatep);
} }
// Add input transition // Add input transition
new DfaEdge (graphp(), dfaStatep, toDfaStatep, input); new DfaEdge (graphp(), dfaStatep, toDfaStatep, input);
@@ -375,7 +374,7 @@ private:
} }
void optimize_accepting_out() { void optimize_accepting_out() {
// Delete outbound edges from accepting states // Delete outbound edges from accepting states
// (As once we've accepted, we no longer care about anything else.) // (As once we've accepted, we no longer care about anything else.)
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) { if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
@@ -480,3 +479,97 @@ public:
void DfaGraph::dfaReduce() { void DfaGraph::dfaReduce() {
DfaGraphReduce (this, &V3GraphEdge::followAlwaysTrue); DfaGraphReduce (this, &V3GraphEdge::followAlwaysTrue);
} }
//######################################################################
//######################################################################
// Algorithms - complement a DFA
//
// The traditional algorithm is to make a rejecting state, add edges to
// reject from all missing values, then swap accept and reject. Rather
// than swap at the end, it's faster if we swap up front, then do the edge
// changes.
//
// 1. Since we didn't log rejecting states, make a temp state (this will be
// the old accept, and new reject).
//
// 2. All vertexes except start/accept get edges to NEW accept for any
// non-existing case. Weedely we don't have a nice way of representing
// this so we just create a edge for each case and mark it "complemented."
//
// 3. Delete temp vertex (old accept/new reject) and related edges.
// The user's old accept is now the new accept. This is imporant as
// we want the virtual type of it to be intact.
class DfaGraphComplement : GraphAlg {
private:
// MEMBERS
DfaVertex* m_tempNewerReject;
// METHODS
int debug() { return 9; }
DfaGraph* graphp() { return static_cast<DfaGraph*>(m_graphp); }
void add_complement_edges() {
// Find accepting vertex
DfaVertex* acceptp = NULL;
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
if (vvertexp->accepting()) {
acceptp = vvertexp;
break;
}
}
}
if (!acceptp) v3fatalSrc("No accepting vertex in DFA\n");
// Remap edges
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
//UINFO(9, " on vertex "<<vvertexp->name()<<endl);
if (!vvertexp->accepting() && vvertexp != m_tempNewerReject) {
for (V3GraphEdge* nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) {
nextp = edgep->outNextp();
if (!edgep->user()) { // Not processed
// Old edges to accept now go to new reject
DfaEdge* vedgep = static_cast<DfaEdge*>(edgep);
DfaVertex* tovertexp = static_cast<DfaVertex*>(edgep->top());
if (tovertexp->accepting()) {
new DfaEdge(graphp(), vvertexp, m_tempNewerReject, vedgep);
edgep->unlinkDelete(); edgep=NULL;
}
// NOT of all values goes to accept
// We make a edge for each value to OR, IE
// edge(complemented,a) edge(complemented,b) means !(a | b)
if (!tovertexp->accepting()) { // Note we must include edges moved above to reject
DfaEdge* newp = new DfaEdge (graphp(), vvertexp, acceptp, vedgep);
newp->complement(!newp->complement());
newp->user(1);
}
}
}
}
}
}
}
public:
DfaGraphComplement(V3Graph* dfagraphp, V3EdgeFuncP edgeFuncp)
: GraphAlg(dfagraphp, edgeFuncp) {
if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_in");
// Vertex::m_user begin: 1 indicates new edge, no more processing
m_graphp->userClearEdges();
m_tempNewerReject = new DfaVertex(graphp());
add_complement_edges();
if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_preswap");
m_tempNewerReject->unlinkDelete(graphp()); m_tempNewerReject=NULL;
if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_out");
}
~DfaGraphComplement() {}
};
void DfaGraph::dfaComplement() {
DfaGraphComplement (this, &V3GraphEdge::followAlwaysTrue);
}
+29 -11
View File
@@ -1,8 +1,8 @@
// $Id$ //-*- C++ -*- // -*- C++ -*-
//************************************************************************* //*************************************************************************
// DESCRIPTION: Verilator: Graph automata base class // DESCRIPTION: Verilator: Graph automata base class
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.org/verilator
// //
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
// //
@@ -43,16 +43,18 @@ class DfaEdge;
/// or epsilon, represented as a empty list of inputs. /// or epsilon, represented as a empty list of inputs.
/// ///
/// We're only looking for matches, so the only accepting states are /// We're only looking for matches, so the only accepting states are
/// at the end of the transformations. /// at the end of the transformations. (If we want the complement, we
/// /// call complement and the algorithm makes a REJECT state, then flips
/// accept and reject for you.)
///
/// Common transforms: /// Common transforms:
/// ///
/// "*": DfaVertex(START) --> [epsilon] -->DfaVertex(ACCEPT) /// "*": DfaVertex(START) --> [epsilon] -->DfaVertex(ACCEPT)
/// ///
/// "L": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT) /// "L": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT)
/// ///
/// "LR": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx() /// "LR": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT)
/// ->[ON_R]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT) /// ->[ON_R]-->DfaVtx-->[epsilon]-/
/// ///
/// "L|R": ...->DfaVtx-->[epsilon]-->DfaVtx-->[ON_L]-->DfaVtx()->[epsilon]-->DfaVtx(ACCEPT) /// "L|R": ...->DfaVtx-->[epsilon]-->DfaVtx-->[ON_L]-->DfaVtx()->[epsilon]-->DfaVtx(ACCEPT)
/// \->[epsilon]-->DfaVtx-->[ON_R]-->DfaVtx()->[epsilon]-/ /// \->[epsilon]-->DfaVtx-->[ON_R]-->DfaVtx()->[epsilon]-/
@@ -76,13 +78,16 @@ public:
/// Simplify a DFA automata /// Simplify a DFA automata
void dfaReduce(); void dfaReduce();
/// Complement result (must already be dfa)
void dfaComplement();
}; };
//============================================================================= //=============================================================================
// Vertex // Vertex
class DfaVertex : public V3GraphVertex { class DfaVertex : public V3GraphVertex {
// Each DFA state is captured in this vertex. // Each DFA state is captured in this vertex.
// Start and accepting are members, rather than the more intuitive // Start and accepting are members, rather than the more intuitive
// subclasses, as subclassing them would make it harder to inherit from here. // subclasses, as subclassing them would make it harder to inherit from here.
bool m_start; // Start state bool m_start; // Start state
@@ -93,7 +98,7 @@ public:
: V3GraphVertex(graphp) : V3GraphVertex(graphp)
, m_start(start), m_accepting(accepting) {} , m_start(start), m_accepting(accepting) {}
virtual DfaVertex* clone(DfaGraph* graphp) { virtual DfaVertex* clone(DfaGraph* graphp) {
return new DfaVertex(graphp, start(), accepting()); } return new DfaVertex(graphp, start(), accepting()); }
virtual ~DfaVertex() {} virtual ~DfaVertex() {}
// ACCESSORS // ACCESSORS
virtual string dotShape() const { return (accepting()?"doublecircle":""); } virtual string dotShape() const { return (accepting()?"doublecircle":""); }
@@ -113,20 +118,33 @@ typedef AstNUser* DfaInput;
class DfaEdge : public V3GraphEdge { class DfaEdge : public V3GraphEdge {
DfaInput m_input; DfaInput m_input;
bool m_complement; // Invert value when doing compare
public: public:
static DfaInput EPSILON() { return NULL; } static DfaInput EPSILON() { return NULL; }
static DfaInput NA() { return AstNUser::fromInt(1); } // as in not-applicable static DfaInput NA() { return AstNUser::fromInt(1); } // as in not-applicable
// CONSTRUCTORS // CONSTRUCTORS
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, DfaInput input) DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, DfaInput input)
: V3GraphEdge(graphp, fromp, top, 1) : V3GraphEdge(graphp, fromp, top, 1)
, m_input(input) {} , m_input(input), m_complement(false) {}
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, const DfaEdge* copyfrom)
: V3GraphEdge(graphp, fromp, top, copyfrom->weight())
, m_input(copyfrom->input()), m_complement(copyfrom->complement()) {}
virtual ~DfaEdge() {} virtual ~DfaEdge() {}
// METHODS // METHODS
virtual string dotColor() const { return na()?"yellow":epsilon()?"green":"black"; } virtual string dotColor() const {
virtual string dotLabel() const { return na()?"":epsilon()?"e":cvtToStr((void*)(input())); } return (na() ? "yellow"
: epsilon() ? "green"
: "black"); }
virtual string dotLabel() const {
return (na() ? ""
: epsilon() ? "e"
: complement() ? ("not "+cvtToStr((void*)(input())))
: cvtToStr((void*)(input()))); }
virtual string dotStyle() const { return (na()||cutable())?"dashed":""; } virtual string dotStyle() const { return (na()||cutable())?"dashed":""; }
bool epsilon() const { return input()==EPSILON(); } bool epsilon() const { return input()==EPSILON(); }
bool na() const { return input()==NA(); } bool na() const { return input()==NA(); }
bool complement() const { return m_complement; }
void complement(bool value) { m_complement=value; }
DfaInput input() const { return m_input; } DfaInput input() const { return m_input; }
}; };

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