Compare commits

...
18 Commits
Author SHA1 Message Date
Wilson Snyder f23203dc96 Make __Inlines.h file so we can build VL_CONST_W_#X funcs automatically
git-svn-id: file://localhost/svn/verilator/trunk/verilator@974 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-11-30 22:38:21 +00:00
Wilson Snyder a94f1c779b Spelling fixes
git-svn-id: file://localhost/svn/verilator/trunk/verilator@973 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-11-30 22:12:53 +00:00
Wilson Snyder 6412aff82d Version bump, commentary
git-svn-id: file://localhost/svn/verilator/trunk/verilator@970 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-11-27 16:52:19 +00:00
Wilson Snyder 99bc1f92c9 Declare lex %tokens so user doesn't see yP_UGLYNAMES.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@969 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-11-05 21:38:20 +00:00
Wilson Snyder 891edad53a Fixed generate for loops with constant zero conditions.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@968 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-11-05 14:09:22 +00:00
Wilson Snyder 98e35b02ad Leak repairs and node leak detection
git-svn-id: file://localhost/svn/verilator/trunk/verilator@967 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-11-02 11:23:03 +00:00
Wilson Snyder 8075372675 Add -Wno-lint
git-svn-id: file://localhost/svn/verilator/trunk/verilator@966 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-31 21:17:23 +00:00
Wilson Snyder 10e34ca48e Support "#delay <statement>;" with associated STMTDLY warning.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@965 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-31 20:29:07 +00:00
Wilson Snyder 329808afff Misc updates to match Verilog-Perl
git-svn-id: file://localhost/svn/verilator/trunk/verilator@964 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-31 20:11:59 +00:00
Wilson Snyder 7fc3e6c168 Fix missing CAST required above some CONSTs
git-svn-id: file://localhost/svn/verilator/trunk/verilator@963 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-31 19:22:26 +00:00
Wilson Snyder 199b32709c Fix div by zero in constant propagation
git-svn-id: file://localhost/svn/verilator/trunk/verilator@962 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-30 22:58:47 +00:00
Wilson Snyder 1775da5f43 Track verilog-perl: Add static keyword; track IEEE BNF
git-svn-id: file://localhost/svn/verilator/trunk/verilator@961 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-26 14:58:26 +00:00
Wilson Snyder 45c202f78f Match Verilog-Perl operator names
git-svn-id: file://localhost/svn/verilator/trunk/verilator@960 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-23 20:54:29 +00:00
Wilson Snyder a77b58dba9 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@957 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-18 16:32:16 +00:00
Wilson Snyder c300ab6dd9 Match up with Verilog-Perl: add specify operators
git-svn-id: file://localhost/svn/verilator/trunk/verilator@956 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-18 16:29:19 +00:00
Wilson Snyder 9ac0f1accb Fix parsing system functions with empty parens
git-svn-id: file://localhost/svn/verilator/trunk/verilator@955 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-09-17 17:54:02 +00:00
Wilson Snyder 7990e5d4b1 Fix parsing module #(parameter x,y) declarations.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@954 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-09-11 13:35:02 +00:00
Wilson Snyder fb2cb3c49d Don't exit early if many warnings but no errors are found. [Stan Mayer]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@953 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-08-23 13:21:58 +00:00
66 changed files with 1189 additions and 418 deletions
+102 -77
View File
@@ -3,11 +3,36 @@ 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.655 ***
**** Wide VL_CONST_W_#X functions are now made automatically. [Bernard Deadman]
In such cases, a new {prefix}__Inlines.h file will be built and included.
* Verilator 3.655 11/27/2007
*** Support "#delay <statement>;" with associated STMTDLY warning.
**** Fixed generate for loops with constant zero conditions. [Rodney Sinclair]
**** Fixed divide-by-zero errors in constant propagator. [Rodney Sinclair]
**** Fixed wrong result with obscure signed-shift underneath a "? :".
**** Fixed many internal memory leaks, and added leak detector.
* Verilator 3.654 10/18/2007
**** Don't exit early if many warnings but no errors are found. [Stan Mayer]
**** Fixed parsing module #(parameter x,y) declarations. [Oleg Rodionov]
**** Fixed parsing system functions with empty parens. [Oleg Rodionov]
* Verilator 3.653 8/1/2007 * Verilator 3.653 8/1/2007
**** Support SystemVerilog ==? and !=? operators. **** Support SystemVerilog ==? and !=? operators.
**** Fix SC_LIBS missing from generated makefiles. [Ding Xiaoliang] **** Fixed SC_LIBS missing from generated makefiles. [Ding Xiaoliang]
* Verilator 3.652 6/21/2007 * Verilator 3.652 6/21/2007
@@ -19,7 +44,7 @@ indicates the contributor was also the author of the fix; Thanks!
**** Optimize constant $display arguments. **** Optimize constant $display arguments.
**** Fix Preprocessor dropping some `line directives. [Mark Nodine] **** Fixed Preprocessor dropping some `line directives. [Mark Nodine]
* Verilator 3.651 5/22/2007 * Verilator 3.651 5/22/2007
@@ -54,11 +79,11 @@ indicates the contributor was also the author of the fix; Thanks!
*** Add USER_CPPFLAGS and USER_LDFLAGS to Makefiles. [Gerald Williams] *** Add USER_CPPFLAGS and USER_LDFLAGS to Makefiles. [Gerald Williams]
**** Fix compile errors under Windows MINGW compiler. [Gerald Williams] **** Fixed compile errors under Windows MINGW compiler. [Gerald Williams]
**** Fix dotted bit reference to local memory. [Eugene Weber] **** Fixed dotted bit reference to local memory. [Eugene Weber]
**** Fix 3.640 `verilog forcing IEEE 1364-1995 only. [David Hewson] **** Fixed 3.640 `verilog forcing IEEE 1364-1995 only. [David Hewson]
* Verilator 3.640 3/12/2007 * Verilator 3.640 3/12/2007
@@ -70,13 +95,13 @@ indicates the contributor was also the author of the fix; Thanks!
**** Try all +libext's in the exact order given. [Michael Shinkarovsky] **** Try all +libext's in the exact order given. [Michael Shinkarovsky]
**** Fix elimination of public signals assigned to constants. [Eugene Weber] **** Fixed elimination of public signals assigned to constants. [Eugene Weber]
**** Fix internal error when public for loop has empty body. [David Addison] **** Fixed internal error when public for loop has empty body. [David Addison]
**** Fix "Loops detected" assertion when model exceeds 4GB. [David Hewson] **** Fixed "Loops detected" assertion when model exceeds 4GB. [David Hewson]
**** Fix display %m names inside named blocks. **** Fixed display %m names inside named blocks.
* Verilator 3.633 2/7/2007 * Verilator 3.633 2/7/2007
@@ -84,11 +109,11 @@ indicates the contributor was also the author of the fix; Thanks!
*** With VL_DEBUG, show wires causing convergence errors. [Mike Shinkarovsky] *** With VL_DEBUG, show wires causing convergence errors. [Mike Shinkarovsky]
**** Fix isolate_assignments when many signals per always. [Mike Shinkarovsky] **** Fixed isolate_assignments when many signals per always. [Mike Shinkarovsky]
**** Fix isolate_assignments across task/func temporaries. [Mike Shinkarovsky] **** Fixed isolate_assignments across task/func temporaries. [Mike Shinkarovsky]
**** Fix $display's with array select followed by wide AND. [David Hewson] **** Fixed $display's with array select followed by wide AND. [David Hewson]
* Verilator 3.632 1/17/2007 * Verilator 3.632 1/17/2007
@@ -99,11 +124,11 @@ indicates the contributor was also the author of the fix; Thanks!
** Support standard NAME[#] for cells created by arraying or generate for. ** Support standard NAME[#] for cells created by arraying or generate for.
This replaces the non-standard name__# syntax used in earlier versions. This replaces the non-standard name__# syntax used in earlier versions.
**** Fix again dotted references into generate cells. [David Hewson] **** Fixed again dotted references into generate cells. [David Hewson]
Verilator no longer accepts duplicated variables inside unique Verilator no longer accepts duplicated variables inside unique
generate blocks as this is illegal according to the specification. generate blocks as this is illegal according to the specification.
**** Fix $readmem* with filenames < 8 characters. [Emerson Suguimoto] **** Fixed $readmem* with filenames < 8 characters. [Emerson Suguimoto]
* Verilator 3.630 12/19/2006 * Verilator 3.630 12/19/2006
@@ -115,21 +140,21 @@ indicates the contributor was also the author of the fix; Thanks!
*** Reduce depth of priority encoded case statements. [Eugene Weber] *** Reduce depth of priority encoded case statements. [Eugene Weber]
**** Fix dotted references inside generated cells. [David Hewson] **** Fixed dotted references inside generated cells. [David Hewson]
**** Fix missed split optimization points underneath other re-split blocks. **** Fixed missed split optimization points underneath other re-split blocks.
* Verilator 3.623 12/05/2006 * Verilator 3.623 12/05/2006
*** Add --output-split-cfuncs for accelerating GCC compile. [Eugene Weber] *** Add --output-split-cfuncs for accelerating GCC compile. [Eugene Weber]
**** Fix $signed mis-extending when input has a WIDTH violation. [Eugene Weber] **** Fixed $signed mis-extending when input has a WIDTH violation. [Eugene Weber]
**** Add M32 make variable to support -m32 compiles. [Eugene Weber] **** Add M32 make variable to support -m32 compiles. [Eugene Weber]
* Verilator 3.622 10/17/2006 Stable * Verilator 3.622 10/17/2006 Stable
**** Fix --skip-identical without --debug, broken in 3.621. [Andy Meier] **** Fixed --skip-identical without --debug, broken in 3.621. [Andy Meier]
* Verilator 3.621 10/11/2006 Beta * Verilator 3.621 10/11/2006 Beta
@@ -139,11 +164,11 @@ indicates the contributor was also the author of the fix; Thanks!
**** Remove .vpp intermediate files when not under --debug. **** Remove .vpp intermediate files when not under --debug.
**** Fix link error when using --exe with --trace. [Eugene Weber] **** Fixed link error when using --exe with --trace. [Eugene Weber]
**** Fix mis-optimization of wide concats with constants. **** Fixed mis-optimization of wide concats with constants.
**** Fix core dump on printing error when not under --debug. [Allan Cochrane] **** Fixed core dump on printing error when not under --debug. [Allan Cochrane]
* Verilator 3.620 10/04/2006 Stable * Verilator 3.620 10/04/2006 Stable
@@ -158,9 +183,9 @@ indicates the contributor was also the author of the fix; Thanks!
**** Optimize additional boolean identities (a|a = a, etc.) **** Optimize additional boolean identities (a|a = a, etc.)
**** Fix coredump when dotted cross-ref inside task call. [Eugene Weber] **** Fixed coredump when dotted cross-ref inside task call. [Eugene Weber]
**** Fix dotted variables in always sensitivity lists. [Allan Cochrane] **** Fixed dotted variables in always sensitivity lists. [Allan Cochrane]
* Verilator 3.610 09/20/2006 Stable * Verilator 3.610 09/20/2006 Stable
@@ -170,13 +195,13 @@ indicates the contributor was also the author of the fix; Thanks!
**** Removed coverage request variable; see Coverage limitations in docs. **** Removed coverage request variable; see Coverage limitations in docs.
**** Fix DOS carriage returns in multiline defines. [Ralf Karge] **** Fixed DOS carriage returns in multiline defines. [Ralf Karge]
**** Fix printf format warnings on 64-bit linux. **** Fixed printf format warnings on 64-bit linux.
* Verilator 3.602 09/11/2006 Stable * Verilator 3.602 09/11/2006 Stable
**** Fix function references under top inlined module. [David Hewson] **** Fixed function references under top inlined module. [David Hewson]
* Verilator 3.601 09/06/2006 Beta * Verilator 3.601 09/06/2006 Beta
@@ -189,15 +214,15 @@ indicates the contributor was also the author of the fix; Thanks!
*** Changed how internal functions are invoked to reduce aliasing. *** Changed how internal functions are invoked to reduce aliasing.
Useful when using GCC's -O2 or -fstrict-aliasing, to gain another ~4%. Useful when using GCC's -O2 or -fstrict-aliasing, to gain another ~4%.
**** Fix memory leak when destroying modules. [John Stroebel] **** Fixed memory leak when destroying modules. [John Stroebel]
**** Fix coredump when unused modules have unused cells. [David Hewson] **** Fixed coredump when unused modules have unused cells. [David Hewson]
**** Fix 3.600 internal error with arrayed instances. [David Hewson] **** Fixed 3.600 internal error with arrayed instances. [David Hewson]
**** Fix 3.600 internal error with non-unrolled function loops. [David Hewson] **** Fixed 3.600 internal error with non-unrolled function loops. [David Hewson]
**** Fix $display %m name not matching Verilog name inside SystemC modules. **** Fixed $display %m name not matching Verilog name inside SystemC modules.
**** Declare optimized lookup tables as 'static', to reduce D-Cache miss rate. **** Declare optimized lookup tables as 'static', to reduce D-Cache miss rate.
@@ -207,17 +232,17 @@ indicates the contributor was also the author of the fix; Thanks!
**** Lint for x's in generate case statements. **** Lint for x's in generate case statements.
**** Fix line numbers being off by one when first file starts with newline. **** Fixed line numbers being off by one when first file starts with newline.
**** Fix naming of generate for blocks to prevent non-inline name conflict. **** Fixed naming of generate for blocks to prevent non-inline name conflict.
**** Fix redundant statements remaining after table optimization. **** Fixed redundant statements remaining after table optimization.
* Verilator 3.542 08/11/2006 Stable * Verilator 3.542 08/11/2006 Stable
**** Fix extraneous UNSIGNED warning when comparing genvars. [David Hewson] **** Fixed extraneous UNSIGNED warning when comparing genvars. [David Hewson]
**** Fix extra white space in $display %c. [by David Addison] **** Fixed extra white space in $display %c. [by David Addison]
**** vl_finish and vl_fatal now print via VL_PRINTF rather then cerr/cout. **** vl_finish and vl_fatal now print via VL_PRINTF rather then cerr/cout.
@@ -225,15 +250,15 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.541 07/05/2006 Beta * Verilator 3.541 07/05/2006 Beta
*** Fix "// verilator lint_on" not re-enabling warnings. [David Hewson] *** Fixed "// verilator lint_on" not re-enabling warnings. [David Hewson]
*** Fix 3.540's multiple memory assignments to same block. [David Hewson] *** Fixed 3.540's multiple memory assignments to same block. [David Hewson]
**** Add warning on changeDetect to arrayed structures. [David Hewson] **** Add warning on changeDetect to arrayed structures. [David Hewson]
**** Fix non-zero start number for arrayed instantiations. [Jae Hossell] **** Fixed non-zero start number for arrayed instantiations. [Jae Hossell]
**** Fix GCC 4.0 header file warnings. **** Fixed GCC 4.0 header file warnings.
* Verilator 3.540 06/27/2006 Beta * Verilator 3.540 06/27/2006 Beta
@@ -241,27 +266,27 @@ indicates the contributor was also the author of the fix; Thanks!
**** Optimize delayed assignments to memories inside loops, ~0-5% faster. **** Optimize delayed assignments to memories inside loops, ~0-5% faster.
**** Fix mis-width warning on bit selects of memories. [David Hewson] **** Fixed mis-width warning on bit selects of memories. [David Hewson]
**** Fix mis-width warning on dead generate-if branches. [Jae Hossell] **** Fixed mis-width warning on dead generate-if branches. [Jae Hossell]
* Verilator 3.533 06/05/2006 Stable * Verilator 3.533 06/05/2006 Stable
*** Add PDF user manual, verilator.pdf. *** Add PDF user manual, verilator.pdf.
**** Fix delayed bit-selected arrayed assignments. [David Hewson] **** Fixed delayed bit-selected arrayed assignments. [David Hewson]
**** Fix execution path to Perl. [Shanshan Xu] **** Fixed execution path to Perl. [Shanshan Xu]
**** Fix Bison compile errors in verilog.y. [by Ben Jackson] **** Fixed Bison compile errors in verilog.y. [by Ben Jackson]
* Verilator 3.531 05/10/2006 Stable * Verilator 3.531 05/10/2006 Stable
*** Support $c routines which return 64 bit values. *** Support $c routines which return 64 bit values.
**** Fix `include `DEFINE. **** Fixed `include `DEFINE.
**** Fix Verilator core dump when have empty public function. [David.Hewson] **** Fixed Verilator core dump when have empty public function. [David.Hewson]
* Verilator 3.530 04/24/2006 Stable * Verilator 3.530 04/24/2006 Stable
@@ -270,11 +295,11 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.523 03/06/2006 Stable * Verilator 3.523 03/06/2006 Stable
**** Fix error line numbers being off due to multi-line defines. [Mat Zeno] **** Fixed error line numbers being off due to multi-line defines. [Mat Zeno]
**** Fix GCC sign extending (uint64_t)(a<b). [David Hewson] **** Fixed GCC sign extending (uint64_t)(a<b). [David Hewson]
**** Fix `systemc_imp_header "undefined macro" error. **** Fixed `systemc_imp_header "undefined macro" error.
* Verilator 3.522 02/23/2006 Beta * Verilator 3.522 02/23/2006 Beta
@@ -286,7 +311,7 @@ indicates the contributor was also the author of the fix; Thanks!
**** Added SystemVerilog 'x,'z,'0,'1, and new string literals. **** Added SystemVerilog 'x,'z,'0,'1, and new string literals.
**** Fix public module's parent still getting inlined. **** Fixed public module's parent still getting inlined.
* Verilator 3.520 01/14/2006 Stable * Verilator 3.520 01/14/2006 Stable
@@ -299,28 +324,28 @@ indicates the contributor was also the author of the fix; Thanks!
This adds a small ~2% performance penalty if traces are compiled in, This adds a small ~2% performance penalty if traces are compiled in,
but not turned on. For best non-tracing performance, do not use --trace. but not turned on. For best non-tracing performance, do not use --trace.
**** Fix $'s in specify delays causing bad PLI errors. [Mat Zeno] **** Fixed $'s in specify delays causing bad PLI errors. [Mat Zeno]
**** Fix public functions not setting up proper symbol table. [Mat Zeno] **** Fixed public functions not setting up proper symbol table. [Mat Zeno]
**** Fix genvars generating trace compile errors. [Mat Zeno] **** Fixed genvars generating trace compile errors. [Mat Zeno]
**** Fix VL_MULS_WWW compile error with MSVC++. [Wim Michiels] **** Fixed VL_MULS_WWW compile error with MSVC++. [Wim Michiels]
* Verilator 3.502 11/30/2005 Stable * Verilator 3.502 11/30/2005 Stable
**** Fix local non-IO variables in public functions and tasks. **** Fixed local non-IO variables in public functions and tasks.
**** Fix bad lifetime optimization when same signal is assigned multiple **** Fixed bad lifetime optimization when same signal is assigned multiple
times in both branch of a if. [Danny Ding] times in both branch of a if. [Danny Ding]
* Verilator 3.501 11/16/2005 Stable * Verilator 3.501 11/16/2005 Stable
*** Add --profile-cfuncs for correlating profiles back to Verilog. *** Add --profile-cfuncs for correlating profiles back to Verilog.
**** Fix functions where regs are declared before inputs. [Danny Ding] **** Fixed functions where regs are declared before inputs. [Danny Ding]
**** Fix bad deep expressions with bit-selects and rotate. [Prabhat Gupta] **** Fixed bad deep expressions with bit-selects and rotate. [Prabhat Gupta]
* Verilator 3.500 10/30/2005 Stable * Verilator 3.500 10/30/2005 Stable
@@ -334,15 +359,15 @@ indicates the contributor was also the author of the fix; Thanks!
** With --assert, generate assertions for synthesis parallel_case and full_case. ** With --assert, generate assertions for synthesis parallel_case and full_case.
**** Fix generate if's with empty if/else blocks. [Mat Zeno] **** Fixed generate if's with empty if/else blocks. [Mat Zeno]
**** Fix generate for cell instantiations with same name. [Mat Zeno] **** Fixed generate for cell instantiations with same name. [Mat Zeno]
* Verilator 3.481 10/12/2005 Stable * Verilator 3.481 10/12/2005 Stable
*** Add /*verilator tracing_on/off*/ for waveform control. *** Add /*verilator tracing_on/off*/ for waveform control.
**** Fix split optimization reordering $display statements. **** Fixed split optimization reordering $display statements.
* Verilator 3.480 9/27/2005 Beta * Verilator 3.480 9/27/2005 Beta
@@ -367,9 +392,9 @@ indicates the contributor was also the author of the fix; Thanks!
**** Add GCC branch prediction hints on generated if statements. **** Add GCC branch prediction hints on generated if statements.
**** Fix bad simulation when same function called twice in same expression. **** Fixed bad simulation when same function called twice in same expression.
**** Fix preprocessor substitution of quoted parameterized defines. **** Fixed preprocessor substitution of quoted parameterized defines.
* Verilator 3.464 8/24/2005 Stable * Verilator 3.464 8/24/2005 Stable
@@ -377,7 +402,7 @@ indicates the contributor was also the author of the fix; Thanks!
*** Add --stats option to dump design statistics. *** Add --stats option to dump design statistics.
**** Fix core dump with clock inversion optimizations. **** Fixed core dump with clock inversion optimizations.
* Verilator 3.463 8/5/2005 Stable * Verilator 3.463 8/5/2005 Stable
@@ -385,15 +410,15 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.462 8/3/2005 Stable * Verilator 3.462 8/3/2005 Stable
*** Fix reordering of delayed assignments to same memory index. [Wim Michiels] *** Fixed reordering of delayed assignments to same memory index. [Wim Michiels]
**** Fix compile error with Flex 2.5.1. [Jens Arm] **** Fixed compile error with Flex 2.5.1. [Jens Arm]
**** Fix multiply-instantiated public tasks generating non-compilable code. **** Fixed multiply-instantiated public tasks generating non-compilable code.
* Verilator 3.461 7/28/2005 Beta * Verilator 3.461 7/28/2005 Beta
**** Fix compile error with older versions of bison. [Jeff Dutton] **** Fixed compile error with older versions of bison. [Jeff Dutton]
* Verilator 3.460 7/27/2005 Beta * Verilator 3.460 7/27/2005 Beta
@@ -406,13 +431,13 @@ indicates the contributor was also the author of the fix; Thanks!
*** When issuing unoptimizable warning, show an example path. *** When issuing unoptimizable warning, show an example path.
**** Fix false warning when a clock is constant. **** Fixed false warning when a clock is constant.
**** Fix X/Z in decimal numbers. [Wim Michiels] **** Fixed X/Z in decimal numbers. [Wim Michiels]
**** Fix genvar statements in non-named generate blocks. **** Fixed genvar statements in non-named generate blocks.
**** Fix core dump when missing newline in `define. [David van der bokke] **** Fixed core dump when missing newline in `define. [David van der bokke]
**** Internal tree dumps now indicate edit number that changed the node. **** Internal tree dumps now indicate edit number that changed the node.
@@ -429,7 +454,7 @@ indicates the contributor was also the author of the fix; Thanks!
*** Add support for SystemVerilog keywords $bits, $countones, $isunknown, *** Add support for SystemVerilog keywords $bits, $countones, $isunknown,
$onehot, $onehot0, always_comb, always_ff, always_latch, finish. $onehot, $onehot0, always_comb, always_ff, always_latch, finish.
**** Fix "=== 1'bx" to always be false, instead of random. **** Fixed "=== 1'bx" to always be false, instead of random.
* Verilator 3.440 6/28/2005 Stable * Verilator 3.440 6/28/2005 Stable
@@ -437,7 +462,7 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.431 6/24/2005 Stable * Verilator 3.431 6/24/2005 Stable
*** Fix selection bugs introduced in 3.430 beta. *** Fixed selection bugs introduced in 3.430 beta.
* Verilator 3.430 6/22/2005 Beta * Verilator 3.430 6/22/2005 Beta
@@ -1069,7 +1094,7 @@ of input ports exists for tracing.
** [Versions 0 to 1.8 were by Paul Wasson] ** [Versions 0 to 1.8 were by Paul Wasson]
**** Fix single bit in concat from instance output incorrect offset bug. **** Fixed single bit in concat from instance output incorrect offset bug.
* Verilator 1.7 5/20/1996 * Verilator 1.7 5/20/1996
@@ -1084,7 +1109,7 @@ of input ports exists for tracing.
*** Pass structure pointer into translated code, *** Pass structure pointer into translated code,
so multiple instances can use same functions. so multiple instances can use same functions.
**** Fix static value concat on casex items. **** Fixed static value concat on casex items.
* Verilator 1.1 3/30/1995 * Verilator 1.1 3/30/1995
+1
View File
@@ -25,6 +25,7 @@ Features:
Coverage Coverage
Points should be per-scope like everything else rather then per-module Points should be per-scope like everything else rather then per-module
Expression coverage (see notes) Expression coverage (see notes)
Constant functions for widths, etc, IE "input [log2(PARAM):0] xx;"
More Verilog 2001 Support More Verilog 2001 Support
(* *) Attributes (just ignore -- preprocessor?) (* *) Attributes (just ignore -- preprocessor?)
Real numbers (NEVER) Real numbers (NEVER)
+52 -17
View File
@@ -411,7 +411,7 @@ change the SystemC modules instantiated.
=item --inline-mult I<value> =item --inline-mult I<value>
Tune the inlining of modules. The default value of 2000 specifies that up Tune the inlining of modules. The default value of 2000 specifies that up
to 2000 new operations may be added to the model by inlining, if more then to 2000 new operations may be added to the model by inlining, if more than
this number of operations would result, the module is not inlined. Larger this number of operations would result, the module is not inlined. Larger
values, or a value <= 1 will inline everything, will lead to longer compile 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
@@ -566,6 +566,17 @@ example C<-Werror-NOUNOPTFLAT>.
Disable the specified warning message. Disable the specified warning message.
=item -Wno-lint
Disable all lint related warning messages. This is equivelent to
"-Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX -Wno-CMPCONST
-Wno-IMPLICIT -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED -Wno-VARHIDDEN
-Wno-WIDTH".
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
received from third parties.
=item -x-assign 0 =item -x-assign 0
=item -x-assign 1 =item -x-assign 1
@@ -827,6 +838,7 @@ For -sp mode, instead of .cpp and .h it creates:
In certain optimization modes, it also creates: In certain optimization modes, it also creates:
{prefix}__Inlines.h // Inline support functions
{prefix}__Slow.cpp // Constructors and infrequent routines {prefix}__Slow.cpp // Constructors and infrequent routines
{prefix}__Syms.cpp // Global symbol table C++ {prefix}__Syms.cpp // Global symbol table C++
{prefix}__Syms.h // Global symbol table header {prefix}__Syms.h // Global symbol table header
@@ -983,7 +995,7 @@ To support this, none of the files that Verilator produces will reference
any configure generated build-system specific files, such as config.h any configure generated build-system specific files, such as config.h
(which is renamed in Verilator to config_build.h to reduce confusion.) The (which is renamed in Verilator to config_build.h to reduce confusion.) The
disadvantage of this approach is that include/verilatedos.h must disadvantage of this approach is that include/verilatedos.h must
self-detect the requirements of the target system, rather then using self-detect the requirements of the target system, rather than using
configure. configure.
The target system may also require edits to the Makefiles, the simple The target system may also require edits to the Makefiles, the simple
@@ -1098,7 +1110,7 @@ call C++ functions from your Verilog code.
String arguments will be put directly into the output C++ code. Expression String arguments will be put directly into the output C++ code. Expression
arguments will have the code to evaluate the expression inserted. Thus to arguments will have the code to evaluate the expression inserted. Thus to
call a C++ function, $c("func(",a,")") will result in 'func(a)' in the call a C++ function, $c("func(",a,")") will result in 'func(a)' in the
output C++ code. For input arguments, rather then hard-coding variable output C++ code. For input arguments, rather than hard-coding variable
names in the string $c("func(a)"), instead pass the variable as an names in the string $c("func(a)"), instead pass the variable as an
expression $c("func(",a,")"). This will allow the call to work inside expression $c("func(",a,")"). This will allow the call to work inside
Verilog functions where the variable is flattened out, and also enable Verilog functions where the variable is flattened out, and also enable
@@ -1465,7 +1477,7 @@ When initializing an array, you need to use non-delayed assignments. This
is done in the interest of speed; if delayed assignments were used, the is done in the interest of speed; if delayed assignments were used, the
simulator would have to copy large arrays every cycle. (In smaller loops, simulator would have to copy large arrays every cycle. (In smaller loops,
loop unrolling allows the delayed assignment to work, though it's a bit loop unrolling allows the delayed assignment to work, though it's a bit
slower then a non-delayed assignment.) Here's an example slower than a non-delayed assignment.) Here's an example
always @ (posedge clk) always @ (posedge clk)
if (~reset_l) begin if (~reset_l) begin
@@ -1552,7 +1564,7 @@ MCDs, which includes the mode parameter to $fopen being mandatory.
Verilator will convert the integer used to hold the file descriptor into a Verilator will convert the integer used to hold the file descriptor into a
internal FILE*. To prevent core dumps due to mis-use, and because integers internal FILE*. To prevent core dumps due to mis-use, and because integers
are 32 bits while FILE*s may be 64 bits, the descriptor must be stored in a are 32 bits while FILE*s may be 64 bits, the descriptor must be stored in a
reg [63:0] rather then an integer. The define `verilator_file_descriptor in 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 $fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal, =item $fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal,
@@ -1718,6 +1730,16 @@ 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 STMTDLY
Warns that you have a statement with a delayed time in front of it, for
example:
#100 $finish;
Ignoring this warning may make Verilator simulations differ from other
simulators.
=item TASKNSVAR =item TASKNSVAR
Error when a call to a task or function has a output from that task tied to Error when a call to a task or function has a output from that task tied to
@@ -1849,7 +1871,7 @@ correctly.
Warns that based on width rules of Verilog, two operands have different Warns that based on width rules of Verilog, two operands have different
widths. Verilator generally can intuit the common usages of widths, and widths. Verilator generally can intuit the common usages of widths, and
you shouldn't need to disable this message like you do with most lint you shouldn't need to disable this message like you do with most lint
programs. Generally other then simple mistakes, you have two solutions: programs. Generally other than simple mistakes, you have two solutions:
If it's a constant 0 that's 32 bits or less, simply leave it If it's a constant 0 that's 32 bits or less, simply leave it
unwidthed. Verilator considers zero to be any width needed. unwidthed. Verilator considers zero to be any width needed.
@@ -1918,13 +1940,13 @@ 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 then have to generate At this time I'd prefer to get patches out quickly than have to generate
myriad binaries for many different OS flavors. People have generally myriad binaries for many different OS flavors. People have generally
requested binaries when they are having problems with their C++ requested 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. Alas, binaries won't help this, as in the end a fully working C++
compiler is required to compile the output of Verilator. compiler is required to compile the output of Verilator.
=item How can it be faster then (name-the-simulator)? =item How can it be faster than (name-the-simulator)?
Generally, the implied part of the question is "... with all of their Generally, the implied part of the question is "... with all of their
manpower they can put into it." manpower they can put into it."
@@ -1950,16 +1972,16 @@ does not require you release your Verilog or generated code.
=item Why is running Verilator so slow? =item Why is running Verilator so slow?
Verilator needs more memory then the resulting simulator will require, as Verilator needs more memory than the resulting simulator will require, as
Verilator creates internally all of the state of the resulting simulator in Verilator creates internally all of the state of the resulting simulator in
order to optimize it. If it takes more then a minute or so (and you're not order to optimize it. If it takes more than a minute or so (and you're not
using --debug), see if your machine is paging; most likely you need to run using --debug), see if your machine is paging; most likely you need to run
it on a machine with more memory. Verilator is a full 64 bit application it on a machine with more memory. Verilator is a full 64 bit application
and may use more then 4GB, but about 1GB is the maximum typically needed. and may use more than 4GB, but about 1GB is the maximum typically needed.
=item How do I generate waveforms (traces) in C++? =item How do I generate waveforms (traces) in C++?
See the next question for SystemC mode. See the next question for tracing in SystemC mode.
Add the --trace switch to Verilator, and make sure the SystemPerl package Add the --trace switch to Verilator, and make sure the SystemPerl package
is installed. SystemC itself does not need to be installed for C++ only is installed. SystemC itself does not need to be installed for C++ only
@@ -1968,8 +1990,10 @@ the SystemPerl kit and point the SYSTEMPERL environment variable to the
untarred directory. untarred directory.
In your top level C code, call Verilated::traceEverOn(true). Then create a In your top level C code, call Verilated::traceEverOn(true). Then create a
SpTraceVcdC object. For an example, see the call to SpTraceVcdC in the SpTraceVcdC object, and in your main loop call "trace_object->dump(time)"
test_c/sc_main.cpp file of the distribution. every time step, and finally call "trace_object->close()". For an example,
see the call to SpTraceVcdC in the test_c/sim_main.cpp file of the
distribution.
You also need to compile SpTraceVcdC.cpp and add it to your link. This is You also need to compile SpTraceVcdC.cpp and add it to your link. This is
done for you if using the Verilator --exe flag. done for you if using the Verilator --exe flag.
@@ -2001,6 +2025,17 @@ the "verilator" define for you, so just wrap the code in a ifndef region:
Something_Verilator_Dislikes; Something_Verilator_Dislikes;
`endif `endif
=item Why do I get "unexpected `do'" or "unexpected `bit'" errors?
Do, bit, ref, and other words are now SystemVerilog keywords. You should
change your code to not use them to insure it works with newer tools.
Alternatively, surround them by the Verilog 2005/SystemVerilog
begin_keywords pragma to indicate Verilog 2001 code.
`begin_keywords "1364-2001"
integer bit; initial bit = 1;
`end_keywords
=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
@@ -2061,7 +2096,7 @@ bit long longs that fits the width of the signal. Generally, you can use
just uint32_t's for 1 to 32 bits, or uint64_t for 1 to 64 bits, and the just uint32_t's for 1 to 32 bits, or uint64_t for 1 to 64 bits, and the
compiler will properly up-convert smaller entities. compiler will properly up-convert smaller entities.
Signals wider then 64 bits are stored as an array of 32-bit uint32_t's. Signals wider than 64 bits are stored as an array of 32-bit uint32_t's.
Thus to read bits 31:0, access signal[0], and for bits 63:32, access 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) 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 will always be zero. if you change the value you must make sure to pack
@@ -2152,8 +2187,8 @@ scratch in C++. This added many optimizations, yielding about a 2-5x
performance gain. performance gain.
Currently, various language features and performance enhancements are added Currently, various language features and performance enhancements are added
as the need arises. Verilator is now about 2x faster then in 2002, and is as the need arises. Verilator is now about 2x faster than in 2002, and is
faster then many popular commercial simulators. faster than many popular commercial simulators.
=head1 CONTRIBUTORS =head1 CONTRIBUTORS
+24 -87
View File
@@ -210,9 +210,9 @@ inline void VL_READMEM_I(bool hex, int width, int depth, int array_lsb, int fnwo
// Base macros // Base macros
/// Return true if data[bit] set /// Return true if data[bit] set
#define VL_BITISSET_I(data,bit) (data & (1UL<<VL_BITBIT_I(bit))) #define VL_BITISSET_I(data,bit) (data & (VL_UL(1)<<VL_BITBIT_I(bit)))
#define VL_BITISSET_Q(data,bit) (data & (VL_ULL(1)<<VL_BITBIT_Q(bit))) #define VL_BITISSET_Q(data,bit) (data & (VL_ULL(1)<<VL_BITBIT_Q(bit)))
#define VL_BITISSET_W(data,bit) (data[VL_BITWORD_I(bit)] & (1UL<<VL_BITBIT_I(bit))) #define VL_BITISSET_W(data,bit) (data[VL_BITWORD_I(bit)] & (VL_UL(1)<<VL_BITBIT_I(bit)))
/// Create two 32-bit words from quadword /// 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(decl,data) { decl[0]=(data); decl[1]=((data)>>VL_WORDSIZE); }
@@ -225,13 +225,13 @@ static inline QData VL_CVT_FP_Q(FILE* fp) { union { FILE* fp; QData q; } u; u.q
// Sign extend such that if MSB set, we get ffff_ffff, else 0s // Sign extend such that if MSB set, we get ffff_ffff, else 0s
// (Requires clean input) // (Requires clean input)
#define VL_SIGN_I(nbits,lhs) ((lhs) >> VL_BITBIT_I((nbits) - 1UL)) #define VL_SIGN_I(nbits,lhs) ((lhs) >> VL_BITBIT_I((nbits) - VL_UL(1)))
#define VL_SIGN_Q(nbits,lhs) ((lhs) >> VL_BITBIT_Q((nbits) - VL_ULL(1))) #define VL_SIGN_Q(nbits,lhs) ((lhs) >> VL_BITBIT_Q((nbits) - VL_ULL(1)))
#define VL_SIGNONES_I(nbits,lhs) (-(VL_SIGN_I(nbits,lhs))) #define VL_SIGNONES_I(nbits,lhs) (-(VL_SIGN_I(nbits,lhs)))
// Sign bit extended up to MSB, doesn't include unsigned portion // Sign bit extended up to MSB, doesn't include unsigned portion
// Optimization bug in GCC 3.3 returns different bitmasks to later states for // Optimization bug in GCC 3.3 returns different bitmasks to later states for
static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) { return (-((lhs)&(1UL<<(lbits-1)))); } static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) { return (-((lhs)&(VL_UL(1)<<(lbits-1)))); }
static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) { return (-((lhs)&(VL_ULL(1)<<(lbits-1)))); } static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) { return (-((lhs)&(VL_ULL(1)<<(lbits-1)))); }
// Debugging prints // Debugging prints
@@ -304,15 +304,15 @@ static inline WDataOutP VL_ASSIGN_W(int obits, WDataOutP owp,WDataInP lwp){
// EMIT_RULE: VL_ASSIGNBIT: rclean=clean; // EMIT_RULE: VL_ASSIGNBIT: rclean=clean;
static inline void VL_ASSIGNBIT_II(int, int bit, CData& lhsr, IData rhs) { static inline void VL_ASSIGNBIT_II(int, int bit, CData& lhsr, IData rhs) {
lhsr = ((lhsr & ~(1UL<<VL_BITBIT_I(bit))) lhsr = ((lhsr & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
| (rhs<<VL_BITBIT_I(bit))); | (rhs<<VL_BITBIT_I(bit)));
} }
static inline void VL_ASSIGNBIT_II(int, int bit, SData& lhsr, IData rhs) { static inline void VL_ASSIGNBIT_II(int, int bit, SData& lhsr, IData rhs) {
lhsr = ((lhsr & ~(1UL<<VL_BITBIT_I(bit))) lhsr = ((lhsr & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
| (rhs<<VL_BITBIT_I(bit))); | (rhs<<VL_BITBIT_I(bit)));
} }
static inline void VL_ASSIGNBIT_II(int, int bit, IData& lhsr, IData rhs) { static inline void VL_ASSIGNBIT_II(int, int bit, IData& lhsr, IData rhs) {
lhsr = ((lhsr & ~(1UL<<VL_BITBIT_I(bit))) lhsr = ((lhsr & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
| (rhs<<VL_BITBIT_I(bit))); | (rhs<<VL_BITBIT_I(bit)));
} }
static inline void VL_ASSIGNBIT_QI(int, int bit, QData& lhsr, QData rhs) { static inline void VL_ASSIGNBIT_QI(int, int bit, QData& lhsr, QData rhs) {
@@ -321,25 +321,25 @@ static inline void VL_ASSIGNBIT_QI(int, int bit, QData& lhsr, QData rhs) {
} }
static inline void VL_ASSIGNBIT_WI(int, int bit, WDataOutP owp, IData rhs) { static inline void VL_ASSIGNBIT_WI(int, int bit, WDataOutP owp, IData rhs) {
IData orig = owp[VL_BITWORD_I(bit)]; IData orig = owp[VL_BITWORD_I(bit)];
owp[VL_BITWORD_I(bit)] = (orig & ~(1UL<<VL_BITBIT_I(bit)) owp[VL_BITWORD_I(bit)] = (orig & ~(VL_UL(1)<<VL_BITBIT_I(bit))
| (rhs<<VL_BITBIT_I(bit))); | (rhs<<VL_BITBIT_I(bit)));
} }
// Alternative form that is an instruction faster when rhs is constant one. // Alternative form that is an instruction faster when rhs is constant one.
static inline void VL_ASSIGNBIT_IO(int, int bit, CData& lhsr, IData) { static inline void VL_ASSIGNBIT_IO(int, int bit, CData& lhsr, IData) {
lhsr = (lhsr | (1UL<<VL_BITBIT_I(bit))); lhsr = (lhsr | (VL_UL(1)<<VL_BITBIT_I(bit)));
} }
static inline void VL_ASSIGNBIT_IO(int, int bit, SData& lhsr, IData) { static inline void VL_ASSIGNBIT_IO(int, int bit, SData& lhsr, IData) {
lhsr = (lhsr | (1UL<<VL_BITBIT_I(bit))); lhsr = (lhsr | (VL_UL(1)<<VL_BITBIT_I(bit)));
} }
static inline void VL_ASSIGNBIT_IO(int, int bit, IData& lhsr, IData) { static inline void VL_ASSIGNBIT_IO(int, int bit, IData& lhsr, IData) {
lhsr = (lhsr | (1UL<<VL_BITBIT_I(bit))); lhsr = (lhsr | (VL_UL(1)<<VL_BITBIT_I(bit)));
} }
static inline void VL_ASSIGNBIT_QO(int, int bit, QData& lhsr, IData) { static inline void VL_ASSIGNBIT_QO(int, int bit, QData& lhsr, IData) {
lhsr = (lhsr | (VL_ULL(1)<<VL_BITBIT_Q(bit))); lhsr = (lhsr | (VL_ULL(1)<<VL_BITBIT_Q(bit)));
} }
static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) { static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
IData orig = owp[VL_BITWORD_I(bit)]; IData orig = owp[VL_BITWORD_I(bit)];
owp[VL_BITWORD_I(bit)] = (orig | (1UL<<VL_BITBIT_I(bit))); owp[VL_BITWORD_I(bit)] = (orig | (VL_UL(1)<<VL_BITBIT_I(bit)));
} }
//=================================================================== //===================================================================
@@ -1164,7 +1164,7 @@ static inline IData VL_BITSEL_IWII(int, int lbits, int, int, WDataInP lwp, IData
int word = VL_BITWORD_I(rd); int word = VL_BITWORD_I(rd);
if ((int)rd>lbits) { if ((int)rd>lbits) {
return ~0; // Spec says you can go outside the range of a array. Don't coredump if so. return ~0; // Spec says you can go outside the range of a array. Don't coredump if so.
// We return all 1's as that's more likely to find bugs (?) then 0's. // We return all 1's as that's more likely to find bugs (?) than 0's.
} else { } else {
return (lwp[word]>>VL_BITBIT_I(rd)); return (lwp[word]>>VL_BITBIT_I(rd));
} }
@@ -1288,123 +1288,60 @@ static inline WDataOutP VL_COND_WIWW(int obits, int, int, int,
// VL_CONST_W_#X(int obits, WDataOutP owp, IData data0, .... IData data(#-1)) // VL_CONST_W_#X(int obits, WDataOutP owp, IData data0, .... IData data(#-1))
// Sets wide vector words to specified constant words, zeros upper data. // Sets wide vector words to specified constant words, zeros upper data.
// If changing the number of functions here, also change EMITCINLINES_NUM_CONSTW
#define I IData #define I IData
#define _END(obits,wordsSet) \ #define _END(obits,wordsSet) \
for(int i=(wordsSet);i<VL_WORDS_I(obits);i++) o[i] = (IData)0x0; \ for(int i=(wordsSet);i<VL_WORDS_I(obits);i++) o[i] = (IData)0x0; \
return o return o
#define VL_HAVE_CONST_W_1X
static inline WDataOutP VL_CONST_W_1X(int obits, WDataOutP o, static inline WDataOutP VL_CONST_W_1X(int obits, WDataOutP o,
I d0) { I d0) {
o[0]=d0; o[0]=d0;
_END(obits,1); } _END(obits,1); }
#define VL_HAVE_CONST_W_2X
static inline WDataOutP VL_CONST_W_2X(int obits, WDataOutP o, static inline WDataOutP VL_CONST_W_2X(int obits, WDataOutP o,
I d1,I d0) { I d1,I d0) {
o[0]=d0; o[1]=d1; o[0]=d0; o[1]=d1;
_END(obits,2); } _END(obits,2); }
#define VL_HAVE_CONST_W_3X
static inline WDataOutP VL_CONST_W_3X(int obits, WDataOutP o, static inline WDataOutP VL_CONST_W_3X(int obits, WDataOutP o,
I d2,I d1,I d0) { I d2,I d1,I d0) {
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
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
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
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
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
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
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;
o[8]=d8; o[8]=d8;
_END(obits,9); } _END(obits,9); }
static inline WDataOutP VL_CONST_W_10X(int obits, WDataOutP o,
I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9;
_END(obits,10); }
static inline WDataOutP VL_CONST_W_11X(int obits, WDataOutP o,
I d10,I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10;
_END(obits,11); }
static inline WDataOutP VL_CONST_W_12X(int obits, WDataOutP o,
I d11,I d10,I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11;
_END(obits,12); }
static inline WDataOutP VL_CONST_W_16X(int obits, WDataOutP o,
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
_END(obits,16); }
static inline WDataOutP VL_CONST_W_17X(int obits, WDataOutP o,
I d16,
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
o[16]=d16;
_END(obits,17); }
static inline WDataOutP VL_CONST_W_18X(int obits, WDataOutP o,
I d17,I d16,
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
o[16]=d16; o[17]=d17;
_END(obits,18); }
static inline WDataOutP VL_CONST_W_19X(int obits, WDataOutP o,
I d18,I d17,I d16,
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
o[16]=d16; o[17]=d17; o[18]=d18;
_END(obits,19); }
static inline WDataOutP VL_CONST_W_20X(int obits, WDataOutP o,
I d19,I d18,I d17,I d16,
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
o[16]=d16; o[17]=d17; o[18]=d18; o[19]=d19;
_END(obits,20); }
static inline WDataOutP VL_CONST_W_24X(int obits, WDataOutP o,
I d23,I d22,I d21,I d20,I d19,I d18,I d17,I d16,
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
o[16]=d16; o[17]=d17; o[18]=d18; o[19]=d19; o[20]=d20; o[21]=d21; o[22]=d22; o[23]=d23;
_END(obits,24); }
static inline WDataOutP VL_CONST_W_28X(int obits, WDataOutP o,
I d27,I d26,I d25,I d24,
I d23,I d22,I d21,I d20,I d19,I d18,I d17,I d16,
I d15,I d14,I d13,I d12,I d11,I d10,I d9,I d8,
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8; o[9]=d9; o[10]=d10; o[11]=d11; o[12]=d12; o[13]=d13; o[14]=d14; o[15]=d15;
o[16]=d16; o[17]=d17; o[18]=d18; o[19]=d19; o[20]=d20; o[21]=d21; o[22]=d22; o[23]=d23;
o[24]=d24; o[25]=d25; o[26]=d26; o[27]=d27;
_END(obits,28); }
#undef _END #undef _END
#undef I #undef I
+5 -2
View File
@@ -46,8 +46,8 @@
# define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment # define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment
# define VL_ATTR_NORETURN ///< Function does not ever return # define VL_ATTR_NORETURN ///< Function does not ever return
# define VL_ATTR_UNUSED ///< Function that may be never used # define VL_ATTR_UNUSED ///< Function that may be never used
# define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true then false # define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true than false
# define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false then true # define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false than true
# define VL_PREFETCH_RD(p) ///< Prefetch data with read intent # define VL_PREFETCH_RD(p) ///< Prefetch data with read intent
# define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent # define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent
#endif #endif
@@ -68,6 +68,9 @@
# define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant # define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant
#endif #endif
// This is not necessarily the same as #UL, depending on what the IData typedef is.
#define VL_UL(c) ((IData)(c##UL)) ///< Add appropriate suffix to 32-bit constant
//========================================================================= //=========================================================================
// Basic integer types // Basic integer types
+1
View File
@@ -121,6 +121,7 @@ RAW_OBJS = \
V3DepthBlock.o \ V3DepthBlock.o \
V3Descope.o \ V3Descope.o \
V3EmitC.o \ V3EmitC.o \
V3EmitCInlines.o \
V3EmitCSyms.o \ V3EmitCSyms.o \
V3EmitMk.o \ V3EmitMk.o \
V3EmitV.o \ V3EmitV.o \
+21 -2
View File
@@ -134,6 +134,7 @@ inline void AstNode::debugTreeChange(const char* prefix, int lineno, bool next)
// Called on all major tree changers. // Called on all major tree changers.
// Only for use for those really nasty bugs relating to internals // Only for use for those really nasty bugs relating to internals
// Note this may be null. // Note this may be null.
//if (debug()) cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<": "<<(void*)this<<endl;
//if (debug()) { //if (debug()) {
// cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<endl; // cout<<"-treeChange: V3Ast.cpp:"<<lineno<<" Tree Change for "<<prefix<<endl;
// v3Global.rootp()->dumpTree(cout,"-treeChange: "); // v3Global.rootp()->dumpTree(cout,"-treeChange: ");
@@ -458,7 +459,7 @@ void AstNode::relink(AstNRelinker* linkerp) {
if (linkerp->m_iterpp) { if (linkerp->m_iterpp) {
// If we're iterating over a next() link, we need to follow links off the // If we're iterating over a next() link, we need to follow links off the
// NEW node. Thus we pass iteration information via a pointer in the node. // NEW node. Thus we pass iteration information via a pointer in the node.
// This adds a unfortunate 4 bytes to every AstNode, but is faster then passing // This adds a unfortunate 4 bytes to every AstNode, but is faster than passing
// across every function. // across every function.
// If anyone has a cleaner way, I'd be grateful. // If anyone has a cleaner way, I'd be grateful.
*(linkerp->m_iterpp) = newp; *(linkerp->m_iterpp) = newp;
@@ -586,11 +587,29 @@ void AstNode::deleteTree() {
// unlinkFromBack or unlinkFromBackWithNext as appropriate before calling this. // unlinkFromBack or unlinkFromBackWithNext as appropriate before calling this.
if (!this) return; if (!this) return;
UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n"); UASSERT(m_backp==NULL,"Delete called on node with backlink still set\n");
this->debugTreeChange("-delete: ", __LINE__, true); this->debugTreeChange("-delTree: ", __LINE__, true);
// MUST be depth first! // MUST be depth first!
deleteTreeIter(); deleteTreeIter();
} }
//======================================================================
// Memory checks
#ifdef VL_LEAK_CHECKS
void* AstNode::operator new(size_t size) {
AstNode* objp = static_cast<AstNode*>(::operator new(size));
V3Broken::addNewed(objp);
return objp;
}
void AstNode::operator delete(void* objp, size_t size) {
if (!objp) return;
AstNode* nodep = static_cast<AstNode*>(objp);
V3Broken::deleted(nodep);
::operator delete(objp);
}
#endif
//====================================================================== //======================================================================
// Iterators // Iterators
+4
View File
@@ -538,6 +538,10 @@ public:
// CONSTRUCTORS // CONSTRUCTORS
virtual ~AstNode(); virtual ~AstNode();
#ifdef VL_LEAK_CHECKS
static void* operator new(size_t size);
static void operator delete(void* obj, size_t size);
#endif
// CONSTANT ACCESSORS // CONSTANT ACCESSORS
static int instrCountBranch() { return 4; } ///< Instruction cycles to branch static int instrCountBranch() { return 4; } ///< Instruction cycles to branch
+1 -1
View File
@@ -21,7 +21,7 @@
// BRANCH TRANSFORMATIONS: // BRANCH TRANSFORMATIONS:
// At each IF/(IF else). // At each IF/(IF else).
// Count underneath $display/$stop statements. // Count underneath $display/$stop statements.
// If more on if then else, this branch is unlikely, or vice-versa. // If more on if than else, this branch is unlikely, or vice-versa.
// //
//************************************************************************* //*************************************************************************
+102 -16
View File
@@ -32,7 +32,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <unistd.h> #include <unistd.h>
#include <algorithm> #include <algorithm>
#include <set> #include <map>
#include "V3Global.h" #include "V3Global.h"
#include "V3Broken.h" #include "V3Broken.h"
@@ -45,19 +45,100 @@ class BrokenTable : public AstNVisitor {
private: private:
// MEMBERS // MEMBERS
// For each node, we keep if it exists or not. // For each node, we keep if it exists or not.
typedef set<const AstNode*> NodeSet; typedef map<const AstNode*,int> NodeMap;
static NodeSet s_nodes; // Set of all nodes that exist static NodeMap s_nodes; // Set of all nodes that exist
// BITMASK
static const int FLAG_ALLOCATED = 0x01; // new() and not delete()ed
static const int FLAG_IN_TREE = 0x02; // Is in netlist tree
static const int FLAG_LINKABLE = 0x04; // Is in netlist tree, can be linked to
static const int FLAG_LEAKED = 0x08; // Known to have been leaked
public: public:
// METHODS // METHODS
static void add(const AstNode* nodep) { static void deleted(const AstNode* nodep) {
s_nodes.insert(nodep); // Called by operator delete on any node - only if VL_LEAK_CHECKS
if (debug()) cout<<"-nodeDel: "<<(void*)(nodep)<<endl;
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter==s_nodes.end() || !(iter->second & FLAG_ALLOCATED)) {
((AstNode*)(nodep))->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted\n");
}
if (iter!=s_nodes.end()) s_nodes.erase(iter);
} }
static bool exists(const AstNode* nodep) { static void addNewed(const AstNode* nodep) {
NodeSet::iterator iter = s_nodes.find(nodep); // Called by operator new on any node - only if VL_LEAK_CHECKS
return (iter != s_nodes.end()); if (debug()) cout<<"-nodeNew: "<<(void*)(nodep)<<endl;
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter!=s_nodes.end() || (iter->second & FLAG_ALLOCATED)) {
((AstNode*)(nodep))->v3fatalSrc("Newing AstNode object that is already allocated\n");
}
if (iter == s_nodes.end()) {
s_nodes.insert(make_pair(nodep,FLAG_ALLOCATED));
}
} }
static void clear() { static void addInTree(AstNode* nodep, bool linkable) {
#ifndef VL_LEAK_CHECKS
if (!linkable) return; // save some time, else the map will get huge!
#endif
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter == s_nodes.end()) {
#ifdef VL_LEAK_CHECKS
nodep->v3fatalSrc("AstNode is in tree, but not allocated\n");
#endif
} else {
if (!(iter->second & FLAG_ALLOCATED)) {
#ifdef VL_LEAK_CHECKS
nodep->v3fatalSrc("AstNode is in tree, but not allocated\n");
#endif
}
if (iter->second & FLAG_IN_TREE) {
nodep->v3fatalSrc("AstNode is already in tree at another location\n");
}
}
int or_flags = FLAG_IN_TREE | (linkable?FLAG_LINKABLE:0);
if (iter == s_nodes.end()) {
s_nodes.insert(make_pair(nodep,or_flags));
} else {
iter->second |= or_flags;
}
}
static bool okIfLinkedTo(const AstNode* nodep) {
// Someone has a pointer to this node. Is it kosher?
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter == s_nodes.end()) return false;
#ifdef VL_LEAK_CHECKS
if (!(iter->second & FLAG_ALLOCATED)) return false;
#endif
if (!(iter->second & FLAG_IN_TREE)) return false;
if (!(iter->second & FLAG_LINKABLE)) return false;
return true;
}
static void prepForTree() {
#ifndef VL_LEAK_CHECKS
s_nodes.clear(); s_nodes.clear();
#endif
for (NodeMap::iterator it = s_nodes.begin(); it != s_nodes.end(); ++it) {
it->second &= ~FLAG_IN_TREE;
it->second &= ~FLAG_LINKABLE;
}
}
static void doneWithTree() {
for (int backs=0; backs<2; backs++) { // Those with backp() are probably under one leaking without
for (NodeMap::iterator it = s_nodes.begin(); it != s_nodes.end(); ++it) {
if ((it->second & FLAG_ALLOCATED)
&& !(it->second & FLAG_IN_TREE)
&& !(it->second & FLAG_LEAKED)
&& (it->first->backp() ? backs==1 : backs==0)) {
// Use only AstNode::dump instead of the virtual one, as there
// may be varp() and other cross links that are bad.
if (debug()) {
cout<<"%Error: LeakedNode"<<(it->first->backp()?"Back: ":": ");
((AstNode*)(it->first))->AstNode::dump(cout);
cout<<endl;
V3Error::incErrors();
}
it->second |= FLAG_LEAKED;
}
}
}
} }
public: public:
// CONSTUCTORS // CONSTUCTORS
@@ -65,11 +146,11 @@ public:
virtual ~BrokenTable() {} virtual ~BrokenTable() {}
}; };
BrokenTable::NodeSet BrokenTable::s_nodes; BrokenTable::NodeMap BrokenTable::s_nodes;
bool AstNode::brokeExists() const { bool AstNode::brokeExists() const {
// Called by node->broken() routines to do table lookup // Called by node->broken() routines to do table lookup
return BrokenTable::exists(this); return BrokenTable::okIfLinkedTo(this);
} }
//###################################################################### //######################################################################
@@ -82,9 +163,7 @@ private:
// // so userp and friends may not be used // // so userp and friends may not be used
// VISITORS // VISITORS
virtual void visit(AstNode* nodep, AstNUser*) { virtual void visit(AstNode* nodep, AstNUser*) {
if (nodep->maybePointedTo()) { BrokenTable::addInTree(nodep, nodep->maybePointedTo());
BrokenTable::add(nodep);
}
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
} }
public: public:
@@ -127,8 +206,15 @@ public:
void V3Broken::brokenAll(AstNetlist* nodep) { void V3Broken::brokenAll(AstNetlist* nodep) {
//UINFO(9,__FUNCTION__<<": "<<endl); //UINFO(9,__FUNCTION__<<": "<<endl);
BrokenTable::clear(); BrokenTable::prepForTree();
BrokenMarkVisitor mvisitor (nodep); BrokenMarkVisitor mvisitor (nodep);
BrokenCheckVisitor cvisitor (nodep); BrokenCheckVisitor cvisitor (nodep);
BrokenTable::clear(); BrokenTable::doneWithTree();
}
void V3Broken::addNewed(AstNode* nodep) {
BrokenTable::addNewed(nodep);
}
void V3Broken::deleted(AstNode* nodep) {
BrokenTable::deleted(nodep);
} }
+2
View File
@@ -31,6 +31,8 @@
class V3Broken { class V3Broken {
public: public:
static void brokenAll(AstNetlist* nodep); static void brokenAll(AstNetlist* nodep);
static void addNewed(AstNode* nodep);
static void deleted(AstNode* nodep);
}; };
#endif // Guard #endif // Guard
+9 -3
View File
@@ -218,7 +218,10 @@ private:
a++, b++) { a++, b++) {
if (m_valueItem[a] != m_valueItem[b]) { same=false; break; } if (m_valueItem[a] != m_valueItem[b]) { same=false; break; }
} }
if (same) return tree0p; if (same) {
tree1p->deleteTree(); tree1p=NULL;
return tree0p;
}
// Must have differing logic, so make a selection // Must have differing logic, so make a selection
@@ -245,8 +248,7 @@ private:
// CASEx(cexpr,.... // CASEx(cexpr,....
// -> tree of IF(msb, IF(msb-1, 11, 10) // -> tree of IF(msb, IF(msb-1, 11, 10)
// IF(msb-1, 01, 00)) // IF(msb-1, 01, 00))
AstNode* cexprp = nodep->exprp(); AstNode* cexprp = nodep->exprp()->unlinkFrBack();
cexprp->unlinkFrBack();
if (debug()>=9) { if (debug()>=9) {
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) { for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
@@ -264,6 +266,8 @@ private:
if (ifrootp) nodep->replaceWith(ifrootp); if (ifrootp) nodep->replaceWith(ifrootp);
else nodep->unlinkFrBack(); else nodep->unlinkFrBack();
nodep->deleteTree(); nodep=NULL;
cexprp->deleteTree(); cexprp=NULL;
if (debug()>=9) ifrootp->dumpTree(cout," _simp: "); if (debug()>=9) ifrootp->dumpTree(cout," _simp: ");
} }
@@ -304,6 +308,7 @@ private:
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;
} else { } else {
// Not a caseX mask, we can simply build CASEEQ(cexpr icond) // Not a caseX mask, we can simply build CASEEQ(cexpr icond)
and1p = cexprp->cloneTree(false); and1p = cexprp->cloneTree(false);
@@ -320,6 +325,7 @@ private:
itemp->condsp(ifexprp); itemp->condsp(ifexprp);
} }
} }
cexprp->deleteTree(); cexprp=NULL;
if (!hadDefault) { if (!hadDefault) {
// If there was no default, add a empty one, this greatly simplifies below code // If there was no default, add a empty one, this greatly simplifies below code
// and constant propagation will just eliminate it for us later. // and constant propagation will just eliminate it for us later.
+20 -1
View File
@@ -60,6 +60,7 @@ class CastVisitor : public AstNVisitor {
private: private:
// NODE STATE // NODE STATE
// Entire netlist: // Entire netlist:
// AstNode::user() // bool. Indicates node is of known size
// STATE // STATE
//int debug() { return 9; } //int debug() { return 9; }
@@ -76,6 +77,7 @@ private:
//if (debug()>8) castp->dumpTree(cout,"-castins: "); //if (debug()>8) castp->dumpTree(cout,"-castins: ");
// //
insureLower32Cast(castp); insureLower32Cast(castp);
nodep->user(1); // Now must be of known size
} }
int castSize (AstNode* nodep) { int castSize (AstNode* nodep) {
if (nodep->isQuad()) return VL_QUADSIZE; if (nodep->isQuad()) return VL_QUADSIZE;
@@ -84,7 +86,8 @@ private:
else return VL_WORDSIZE; else return VL_WORDSIZE;
} }
void insureCast(AstNode* nodep) { void insureCast(AstNode* nodep) {
if (castSize(nodep->backp()) != castSize(nodep)) { if (castSize(nodep->backp()) != castSize(nodep)
|| !nodep->user()) {
insertCast(nodep, castSize(nodep->backp())); insertCast(nodep, castSize(nodep->backp()));
} }
} }
@@ -102,15 +105,21 @@ private:
// VISITORS // VISITORS
virtual void visit(AstNodeUniop* nodep, AstNUser*) { virtual void visit(AstNodeUniop* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
nodep->user(nodep->lhsp()->user());
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp()); if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
} }
virtual void visit(AstNodeBiop* nodep, AstNUser*) { virtual void visit(AstNodeBiop* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
nodep->user(nodep->lhsp()->user()
| nodep->rhsp()->user());
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp()); if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp()); if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
} }
virtual void visit(AstNodeTriop* nodep, AstNUser*) { virtual void visit(AstNodeTriop* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
nodep->user(nodep->lhsp()->user()
| nodep->rhsp()->user()
| nodep->thsp()->user());
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp()); if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp()); if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
if (nodep->sizeMattersThs()) insureCast(nodep->thsp()); if (nodep->sizeMattersThs()) insureCast(nodep->thsp());
@@ -118,9 +127,11 @@ private:
virtual void visit(AstCast* nodep, AstNUser*) { virtual void visit(AstCast* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
insureLower32Cast(nodep); insureLower32Cast(nodep);
nodep->user(1);
} }
virtual void visit(AstUnaryMin* nodep, AstNUser*) { virtual void visit(AstUnaryMin* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
nodep->user(nodep->lhsp()->user());
if (nodep->lhsp()->widthMin()==1) { if (nodep->lhsp()->widthMin()==1) {
// We want to avoid a GCC "converting of negative value" warning // We want to avoid a GCC "converting of negative value" warning
// from our expansion of // from our expansion of
@@ -140,6 +151,13 @@ private:
// 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);
}
virtual void visit(AstConst* nodep, AstNUser*) {
// Constants are of unknown size if smaller than 33 bits, becase
// we're too lazy to wrap every constant in the universe in
// ((IData)#).
nodep->user(nodep->isQuad() || nodep->isWide());
} }
// NOPs // NOPs
@@ -154,6 +172,7 @@ private:
public: public:
// CONSTUCTORS // CONSTUCTORS
CastVisitor(AstNetlist* nodep) { CastVisitor(AstNetlist* nodep) {
AstNode::userClearTree();
nodep->accept(*this); nodep->accept(*this);
} }
virtual ~CastVisitor() {} virtual ~CastVisitor() {}
+11 -4
View File
@@ -384,6 +384,8 @@ private:
int shift1 = shift1p->castConst()->asInt(); if (lhsp->castShiftR()) shift1=-shift1; int shift1 = shift1p->castConst()->asInt(); if (lhsp->castShiftR()) shift1=-shift1;
int shift2 = shift2p->castConst()->asInt(); if (nodep->castShiftR()) shift2=-shift2; int shift2 = shift2p->castConst()->asInt(); if (nodep->castShiftR()) shift2=-shift2;
int newshift = shift1+shift2; int newshift = shift1+shift2;
shift1p->deleteTree(); shift1p=NULL;
shift2p->deleteTree(); shift1p=NULL;
AstNode* newp; AstNode* newp;
V3Number mask1 (nodep->fileline(), nodep->width()); V3Number mask1 (nodep->fileline(), nodep->width());
V3Number ones (nodep->fileline(), nodep->width()); V3Number ones (nodep->fileline(), nodep->width());
@@ -524,7 +526,8 @@ private:
if (debug()>=9) asn1p->dumpTree(cout," _new: "); if (debug()>=9) asn1p->dumpTree(cout," _new: ");
if (debug()>=9) asn2p->dumpTree(cout," _new: "); if (debug()>=9) asn2p->dumpTree(cout," _new: ");
// Cleanup // Cleanup
nodep->unlinkFrBack()->deleteTree(); nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
conp->deleteTree(); conp=NULL;
// Further reduce, either node may have more reductions. // Further reduce, either node may have more reductions.
return true; return true;
} }
@@ -637,6 +640,7 @@ private:
// If bp was a concat, then we have this exact same form again! // If bp was a concat, then we have this exact same form again!
// 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;
} 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();
@@ -647,6 +651,7 @@ private:
nodep->lhsp(ap); nodep->lhsp(ap);
nodep->rhsp(bcConcp); nodep->rhsp(bcConcp);
if (operandConcatMove(bcConcp)) moveConcat(bcConcp); if (operandConcatMove(bcConcp)) moveConcat(bcConcp);
abConcp->deleteTree(); abConcp=NULL;
} }
} }
@@ -677,6 +682,8 @@ private:
if (lsb1p->castConst() && lsb2p->castConst()) { if (lsb1p->castConst() && lsb2p->castConst()) {
newlsbp = new AstConst(lsb1p->fileline(), newlsbp = new AstConst(lsb1p->fileline(),
lsb1p->castConst()->asInt() + lsb2p->castConst()->asInt()); lsb1p->castConst()->asInt() + lsb2p->castConst()->asInt());
lsb1p->deleteTree(); lsb1p=NULL;
lsb2p->deleteTree(); lsb2p=NULL;
} else { } else {
// Width is important, we need the width of the fromp's // Width is important, we need the width of the fromp's
// expression, not the potentially smaller lsb1p's width // expression, not the potentially smaller lsb1p's width
@@ -860,7 +867,7 @@ private:
new AstAssign(nodep->fileline(), new AstAssign(nodep->fileline(),
varrefp, exprp)); varrefp, exprp));
m_modp->addStmtp(newinitp); m_modp->addStmtp(newinitp);
nodep->unlinkFrBack(); nodep=NULL; nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
// Set the initial value right in the variable so we can constant propagate // Set the initial value right in the variable so we can constant propagate
AstNode* initvaluep = exprp->cloneTree(false); AstNode* initvaluep = exprp->cloneTree(false);
varrefp->varp()->initp(initvaluep); varrefp->varp()->initp(initvaluep);
@@ -1016,7 +1023,7 @@ private:
// Below lines are magic expressions processed by astgen // Below lines are magic expressions processed by astgen
// "AstNODETYPE { # bracket not paren // "AstNODETYPE { # bracket not paren
// $accessor_name, ... // $accessor_name, ...
// # ,, gets replaced with a , rather then && // # ,, gets replaced with a , rather than &&
// }" # bracket not paren // }" # bracket not paren
// ,"function to call" // ,"function to call"
// or ,"AstREPLACEMENT_TYPE{ $accessor }" // or ,"AstREPLACEMENT_TYPE{ $accessor }"
@@ -1197,7 +1204,7 @@ private:
TREEOPV("AstRedXor{$lhsp->castExtend()}", "AstRedXor{$lhsp->castExtend()->lhsp()}"); TREEOPV("AstRedXor{$lhsp->castExtend()}", "AstRedXor{$lhsp->castExtend()->lhsp()}");
TREEOPV("AstOneHot{$lhsp.width1}", "replaceWLhs(nodep)"); TREEOPV("AstOneHot{$lhsp.width1}", "replaceWLhs(nodep)");
TREEOPV("AstOneHot0{$lhsp.width1}", "replaceNum(nodep,1)"); TREEOPV("AstOneHot0{$lhsp.width1}", "replaceNum(nodep,1)");
// Binary AND/OR is faster then logical and/or (usually) // Binary AND/OR is faster than logical and/or (usually)
TREEOPV("AstLogAnd{$lhsp.width1, $rhsp.width1}", "AstAnd{$lhsp,$rhsp}"); TREEOPV("AstLogAnd{$lhsp.width1, $rhsp.width1}", "AstAnd{$lhsp,$rhsp}");
TREEOPV("AstLogOr {$lhsp.width1, $rhsp.width1}", "AstOr{$lhsp,$rhsp}"); TREEOPV("AstLogOr {$lhsp.width1, $rhsp.width1}", "AstOr{$lhsp,$rhsp}");
TREEOPV("AstLogNot{$lhsp.width1}", "AstNot{$lhsp}"); TREEOPV("AstLogNot{$lhsp.width1}", "AstNot{$lhsp}");
+12 -13
View File
@@ -110,18 +110,6 @@ private:
} }
AstVarScope* createVarSc(AstVarScope* oldvarscp, string name, int width/*0==fromoldvar*/) { AstVarScope* createVarSc(AstVarScope* oldvarscp, string name, int width/*0==fromoldvar*/) {
// Because we've already scoped it, we may need to add both the AstVar and the AstVarScope // Because we've already scoped it, we may need to add both the AstVar and the AstVarScope
AstRange* rangep = NULL;
if (width==0) {
rangep = new AstRange(oldvarscp->fileline(),
oldvarscp->varp()->msb(),
oldvarscp->varp()->lsb());
} else if (width==1) {
rangep = NULL;
} else {
rangep = new AstRange(oldvarscp->fileline(),
width-1, 0);
}
if (!oldvarscp->scopep()) oldvarscp->v3fatalSrc("Var unscoped"); if (!oldvarscp->scopep()) oldvarscp->v3fatalSrc("Var unscoped");
AstVar* varp; AstVar* varp;
AstModule* addmodp = oldvarscp->scopep()->modp(); AstModule* addmodp = oldvarscp->scopep()->modp();
@@ -131,6 +119,17 @@ private:
// Created module's AstVar earlier under some other scope // Created module's AstVar earlier under some other scope
varp = iter->second; varp = iter->second;
} else { } else {
AstRange* rangep = NULL;
if (width==0) {
rangep = new AstRange(oldvarscp->fileline(),
oldvarscp->varp()->msb(),
oldvarscp->varp()->lsb());
} else if (width==1) {
rangep = NULL;
} else {
rangep = new AstRange(oldvarscp->fileline(),
width-1, 0);
}
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, rangep); varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, rangep);
if (width==0) varp->widthSignedFrom(oldvarscp); if (width==0) varp->widthSignedFrom(oldvarscp);
addmodp->addStmtp(varp); addmodp->addStmtp(varp);
@@ -226,7 +225,7 @@ private:
if (nodep->user5p()) { if (nodep->user5p()) {
// Simplistic optimization. If the previous statement in same scope was also a =>, // Simplistic optimization. If the previous statement in same scope was also a =>,
// then we told this nodep->user5 we can use its Vdlyvset rather then making a new one. // then we told this nodep->user5 we can use its Vdlyvset rather than making a new one.
// This is good for code like: // This is good for code like:
// for (i=0; i<5; i++) vector[i] <= something; // for (i=0; i<5; i++) vector[i] <= something;
sharedVset = true; sharedVset = true;
+5 -2
View File
@@ -254,7 +254,7 @@ public:
virtual void visit(AstReadMem* nodep, AstNUser*) { virtual void visit(AstReadMem* nodep, AstNUser*) {
puts("VL_READMEM_"); puts("VL_READMEM_");
emitIQW(nodep->filenamep()); emitIQW(nodep->filenamep());
puts(" ("); // We take a void* rather then emitIQW(nodep->memp()); puts(" ("); // We take a void* rather than emitIQW(nodep->memp());
puts(nodep->isHex()?"true":"false"); puts(nodep->isHex()?"true":"false");
putbs(","); putbs(",");
puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width
@@ -1214,7 +1214,7 @@ void EmitCImp::emitConfigureImp(AstModule* modp) {
void EmitCImp::emitCoverageImp(AstModule* modp) { void EmitCImp::emitCoverageImp(AstModule* modp) {
if (m_coverIds.size()) { if (m_coverIds.size()) {
puts("\n// Coverage\n"); puts("\n// Coverage\n");
// Rather then putting out SP_COVER_INSERT calls directly, we do it via this function // Rather than putting out SP_COVER_INSERT calls directly, we do it via this function
// This gets around gcc slowness constructing all of the template arguments // This gets around gcc slowness constructing all of the template arguments
puts("void "+modClassName(m_modp)+"::__vlCoverInsert(SpZeroed<uint32_t>* countp, const char* filename, int lineno, int column,\n"); puts("void "+modClassName(m_modp)+"::__vlCoverInsert(SpZeroed<uint32_t>* countp, const char* filename, int lineno, int column,\n");
puts( "const char* hier, const char* type, const char* comment) {\n"); puts( "const char* hier, const char* type, const char* comment) {\n");
@@ -1428,6 +1428,9 @@ void EmitCImp::emitInt(AstModule* modp) {
if (v3Global.opt.coverage()) { if (v3Global.opt.coverage()) {
puts("#include \"SpCoverage.h\"\n"); puts("#include \"SpCoverage.h\"\n");
} }
if (v3Global.needHInlines()) { // Set by V3EmitCInlines; should have been called before us
puts("#include \""+topClassName()+"__Inlines.h\"\n");
}
// Declare foreign instances up front to make C++ happy // Declare foreign instances up front to make C++ happy
puts("class "+symClassName()+";\n"); puts("class "+symClassName()+";\n");
+1
View File
@@ -31,6 +31,7 @@
class V3EmitC { class V3EmitC {
public: public:
static void emitc(); static void emitc();
static void emitcInlines();
static void emitcSyms(); static void emitcSyms();
static void emitcTrace(); static void emitcTrace();
}; };
+126
View File
@@ -0,0 +1,126 @@
// $Id$
//*************************************************************************
// DESCRIPTION: Verilator: Emit C++ for tree
//
// Code available from: http://www.veripool.com/verilator
//
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
//
//*************************************************************************
//
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// General Public License or the Perl Artistic License.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
#include "config_build.h"
#include "verilatedos.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <math.h>
#include <map>
#include <vector>
#include "V3Global.h"
#include "V3EmitC.h"
#include "V3EmitCBase.h"
#include "V3Stats.h"
#define EMITCINLINES_NUM_CONSTW 10 // Number of VL_CONST_W_*X's in verilated.h (IE VL_CONST_W_9X is last)
//######################################################################
class EmitCInlines : EmitCBaseVisitor {
// STATE
vector<V3Double0> m_wordWidths; // What sizes are used?
// METHODS
void emitInt();
// VISITORS
virtual void visit(AstVar* nodep, AstNUser*) {
// All wide constants load into variables, so we can just hunt for them
if (nodep->widthWords() >= EMITCINLINES_NUM_CONSTW ) {
if (int(m_wordWidths.size()) <= nodep->widthWords()) {
m_wordWidths.resize(nodep->widthWords()+5);
}
++ m_wordWidths.at(nodep->widthWords());
v3Global.needHInlines(true);
}
}
// NOPs
virtual void visit(AstNodeStmt*, AstNUser*) {}
// Default
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
//---------------------------------------
// ACCESSORS
public:
EmitCInlines(AstNetlist* nodep) {
nodep->accept(*this);
if (v3Global.needHInlines()) {
emitInt();
}
}
};
void EmitCInlines::emitInt() {
string filename = v3Global.opt.makeDir()+"/"+topClassName()+"__Inlines.h";
newCFile(filename, false/*slow*/, false/*source*/);
V3OutCFile hf (filename);
m_ofp = &hf;
ofp()->putsHeader();
puts("#ifndef _"+topClassName()+"__Inlines_H_\n");
puts("#define _"+topClassName()+"__Inlines_H_\n");
puts("\n");
puts("#include \"verilated.h\"\n");
puts("\n//======================\n\n");
for (unsigned words=0; words<m_wordWidths.size(); words++) {
if (m_wordWidths.at(words)) {
puts("#ifndef VL_HAVE_CONST_W_"+cvtToStr(words)+"X\n");
puts("# define VL_HAVE_CONST_W_"+cvtToStr(words)+"X\n");
puts("static inline WDataOutP VL_CONST_W_"+cvtToStr(words)+"X(int obits, WDataOutP o\n");
puts("\t");
for (int i=words-1; i>=0; --i) {
puts(",IData d"+cvtToStr(i));
if (i && (i % 8 == 0)) puts("\n\t");
}
puts(") {\n");
puts(" ");
for (int i=words-1; i>=0; --i) {
puts(" o["+cvtToStr(i)+"]=d"+cvtToStr(i)+";");
if (i && (i % 8 == 0)) puts("\n ");
}
puts("\n");
puts(" for(int i="+cvtToStr(words)+";i<VL_WORDS_I(obits);i++) o[i] = (IData)0x0;\n");
puts(" return o;\n");
puts("}\n");
puts("#endif\n");
puts("\n");
}
}
puts("//======================\n\n");
puts("#endif /*guard*/\n");
}
//######################################################################
// EmitC class functions
void V3EmitC::emitcInlines() {
UINFO(2,__FUNCTION__<<": "<<endl);
EmitCInlines syms (v3Global.rootp());
}
+51 -5
View File
@@ -22,6 +22,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <set>
#include "V3Error.h" #include "V3Error.h"
#ifndef _V3ERROR_NO_GLOBAL_ #ifndef _V3ERROR_NO_GLOBAL_
# include "V3Ast.h" # include "V3Ast.h"
@@ -101,9 +102,16 @@ bool FileLine::warnOff(const string& msg, bool flag) {
} }
} }
void FileLine::warnLintOff(bool flag) {
for (int codei=V3ErrorCode::FIRST_WARN; codei<V3ErrorCode::MAX; codei++) {
V3ErrorCode code = (V3ErrorCode)codei;
if (code.lintError()) warnOff(code, flag);
}
}
FileLine* FileLine::copyOrSameFileLine() { FileLine* FileLine::copyOrSameFileLine() {
// Return this, or a copy of this // Return this, or a copy of this
// There are often more then one token per line, thus we use the // There are often more than one token per line, thus we use the
// same pointer as long as we're on the same line. // same pointer as long as we're on the same line.
static FileLine* lastNewp = NULL; static FileLine* lastNewp = NULL;
if (lastNewp && *lastNewp == *this) { if (lastNewp && *lastNewp == *this) {
@@ -163,6 +171,46 @@ void FileLine::v3errorEnd(ostringstream& str) {
V3Error::v3errorEnd(str); V3Error::v3errorEnd(str);
} }
} }
#ifdef VL_LEAK_CHECKS
typedef set<FileLine*> FileLineCheckSet;
FileLineCheckSet fileLineLeakChecks;
void* FileLine::operator new(size_t size) {
FileLine* objp = static_cast<FileLine*>(::operator new(size));
fileLineLeakChecks.insert(objp);
return objp;
}
void FileLine::operator delete(void* objp, size_t size) {
if (!objp) return;
FileLine* flp = static_cast<FileLine*>(objp);
FileLineCheckSet::iterator it = fileLineLeakChecks.find(flp);
if (it != fileLineLeakChecks.end()) {
fileLineLeakChecks.erase(it);
} else {
flp->v3fatalSrc("Deleting FileLine object that was never tracked\n");
}
::operator delete(objp);
}
#endif
void FileLine::deleteAllRemaining() {
#ifdef VL_LEAK_CHECKS
// FileLines are allocated, but never nicely freed, as it's much faster
// that way. Unfortunately this makes our leak checking a big mess, so
// only when leak checking we'll track them all and cleanup.
while (1) {
FileLineCheckSet::iterator it=fileLineLeakChecks.begin();
if (it==fileLineLeakChecks.end()) break;
delete *it;
// Operator delete will remove the iterated object from the list.
// Eventually the list will be empty and terminate the loop.
}
fileLineLeakChecks.clear();
#endif
}
//###################################################################### //######################################################################
// V3Error class functions // V3Error class functions
@@ -190,14 +238,12 @@ string V3Error::lineStr (const char* filename, int lineno) {
void V3Error::incWarnings() { void V3Error::incWarnings() {
s_warnCount++; s_warnCount++;
if (errorOrWarnCount() == MAX_ERRORS) { // Not >= as would otherwise recurse // We don't exit on a lot of warnings.
v3fatal ("Exiting due to too many errors encountered\n");
}
} }
void V3Error::incErrors() { void V3Error::incErrors() {
s_errCount++; s_errCount++;
if (errorOrWarnCount() == MAX_ERRORS) { // Not >= as would otherwise recurse if (errorCount() == MAX_ERRORS) { // Not >= as would otherwise recurse
v3fatal ("Exiting due to too many errors encountered\n"); v3fatal ("Exiting due to too many errors encountered\n");
} }
} }
+22 -6
View File
@@ -48,6 +48,7 @@ public:
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
GENCLK, // Generated Clock GENCLK, // Generated Clock
IMPLICIT, // Implicit wire IMPLICIT, // Implicit wire
IMPURE, // Impure function not being inlined IMPURE, // Impure function not being inlined
@@ -76,7 +77,7 @@ public:
" FIRST_WARN", " FIRST_WARN",
"BLKANDNBLK", "BLKANDNBLK",
"CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST", "CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST",
"COMBDLY", "GENCLK", "IMPLICIT", "IMPURE", "COMBDLY", "STMTDLY", "GENCLK", "IMPLICIT", "IMPURE",
"MULTIDRIVEN", "MULTIDRIVEN",
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
"VARHIDDEN", "WIDTH", "VARHIDDEN", "WIDTH",
@@ -89,6 +90,13 @@ public:
// Warnings we'll present to the user as errors // Warnings we'll present to the user as errors
// Later -Werror- options may make more of these. // Later -Werror- options may make more of these.
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
bool lintError() const { return ( m_e==CASEINCOMPLETE || m_e==CASEOVERLAP
|| m_e==CASEX || m_e==CMPCONST
|| m_e==IMPLICIT
|| m_e==UNDRIVEN || m_e==UNSIGNED
|| m_e==UNUSED || m_e==VARHIDDEN
|| m_e==WIDTH); };
}; };
inline bool operator== (V3ErrorCode lhs, V3ErrorCode rhs) { return (lhs.m_e == rhs.m_e); } inline bool operator== (V3ErrorCode lhs, V3ErrorCode rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (V3ErrorCode lhs, V3ErrorCode::en rhs) { return (lhs.m_e == rhs); } inline bool operator== (V3ErrorCode lhs, V3ErrorCode::en rhs) { return (lhs.m_e == rhs); }
@@ -109,8 +117,6 @@ class V3Error {
static ostringstream s_errorStr; // Error string being formed static ostringstream s_errorStr; // Error string being formed
static V3ErrorCode s_errorCode; // Error string being formed will abort static V3ErrorCode s_errorCode; // Error string being formed will abort
enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors enum MaxErrors { MAX_ERRORS = 50 }; // Fatal after this may errors
static void incErrors();
static void incWarnings();
V3Error() { cerr<<("Static class"); abort(); } V3Error() { cerr<<("Static class"); abort(); }
@@ -124,6 +130,8 @@ class V3Error {
static int warnCount() { return s_warnCount; } static int warnCount() { return s_warnCount; }
static int errorOrWarnCount() { return errorCount()+warnCount(); } static int errorOrWarnCount() { return errorCount()+warnCount(); }
// METHODS // METHODS
static void incErrors();
static void incWarnings();
static void init(); static void init();
static void abortIfErrors(); static void abortIfErrors();
static void abortIfWarnings(); static void abortIfWarnings();
@@ -191,9 +199,14 @@ protected:
void incLineno() { m_lineno++; } void incLineno() { m_lineno++; }
FileLine* copyOrSameFileLine(); FileLine* copyOrSameFileLine();
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; } // Only for static constructor FileLine (EmptySecret) { m_lineno=0; m_filename="COMMAND_LINE"; m_warnOff=0; }
~FileLine() { }
#ifdef VL_LEAK_CHECKS
static void* operator new(size_t size);
static void operator delete(void* obj, size_t size);
#endif
static FileLine& defaultFileLine() { return s_defaultFileLine; } static FileLine& defaultFileLine() { return s_defaultFileLine; }
int lineno () const { return m_lineno; } int lineno () const { return m_lineno; }
string ascii() const; string ascii() const;
@@ -204,11 +217,14 @@ public:
void warnOff(V3ErrorCode code, bool flag) { m_warnOff.set(code,flag); } // Turn on/off warning messages on this line. void warnOff(V3ErrorCode code, bool flag) { m_warnOff.set(code,flag); } // Turn on/off warning messages on this line.
bool warnOff(const string& code, bool flag); // Returns 1 if ok bool warnOff(const string& code, bool flag); // Returns 1 if ok
bool warnIsOff(V3ErrorCode code); bool warnIsOff(V3ErrorCode code);
void warnLintOff(bool flag);
void warnStateFrom(const FileLine& from) { m_warnOff=from.m_warnOff; } void warnStateFrom(const FileLine& from) { m_warnOff=from.m_warnOff; }
void warnResetDefault() { warnStateFrom(s_defaultFileLine); } void warnResetDefault() { warnStateFrom(s_defaultFileLine); }
void v3errorEnd(ostringstream& str); void v3errorEnd(ostringstream& str);
inline bool operator==(FileLine rhs) { return (m_lineno==rhs.m_lineno && m_filename==rhs.m_filename); } inline bool operator==(FileLine rhs) { return (m_lineno==rhs.m_lineno && m_filename==rhs.m_filename); }
static void deleteAllRemaining();
}; };
ostream& operator<<(ostream& os, FileLine* fileline); ostream& operator<<(ostream& os, FileLine* fileline);
+3 -1
View File
@@ -531,6 +531,8 @@ private:
rhsp, lsb))); rhsp, lsb)));
} }
} }
rhsp->deleteTree(); rhsp=NULL;
destp->deleteTree(); destp=NULL;
} else { } else {
UINFO(8," ASSIGNSEL(const,narrow) "<<nodep<<endl); UINFO(8," ASSIGNSEL(const,narrow) "<<nodep<<endl);
if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCast(nodep->fileline(), rhsp, nodep); if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCast(nodep->fileline(), rhsp, nodep);
@@ -803,7 +805,7 @@ private:
for (int w=0; w<nodep->lhsp()->widthWords(); w++) { for (int w=0; w<nodep->lhsp()->widthWords(); w++) {
AstNode* eqp = newAstWordSelClone (nodep->lhsp(), w); AstNode* eqp = newAstWordSelClone (nodep->lhsp(), w);
if (w==nodep->lhsp()->widthWords()-1) { if (w==nodep->lhsp()->widthWords()-1) {
// Rather then doing a (slowish) ==##, we OR in the bits that aren't part of the mask // Rather than doing a (slowish) ==##, we OR in the bits that aren't part of the mask
eqp = new AstOr (nodep->fileline(), eqp = new AstOr (nodep->fileline(),
new AstConst (nodep->fileline(), notWideMask(nodep->lhsp())), new AstConst (nodep->fileline(), notWideMask(nodep->lhsp())),
eqp); eqp);
+2 -2
View File
@@ -341,7 +341,7 @@ private:
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n"); if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n");
GateVarVertex* varvertexp = makeVarVertex(varscp); GateVarVertex* varvertexp = makeVarVertex(varscp);
UINFO(5," VARREF to "<<varscp<<endl); UINFO(5," VARREF to "<<varscp<<endl);
// We use weight of one; if we ref the var more then once, when we simplify, // We use weight of one; if we ref the var more than once, when we simplify,
// the weight will increase // 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);
@@ -433,7 +433,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
} }
} }
else if (!vvertexp->inSize1()) { else if (!vvertexp->inSize1()) {
vvertexp->clearReducible("size!1"); // Can't deal with more then one src vvertexp->clearReducible("size!1"); // Can't deal with more than one src
} }
// Reduce it? // Reduce it?
if (!vvertexp->reducible()) { if (!vvertexp->reducible()) {
+6 -1
View File
@@ -42,8 +42,10 @@ class V3Global {
AstNetlist* m_rootp; // Root of entire netlist AstNetlist* m_rootp; // Root of entire netlist
int m_debugFileNumber; // Number to append to debug files created int m_debugFileNumber; // Number to append to debug files created
bool m_assertWidthsSame; // Tree should have width()==widthMin() bool m_assertWidthsSame; // Tree should have width()==widthMin()
// Options bool m_needHInlines; // Need a __Inlines file
public: public:
// Options
V3Options opt; // All options; let user see them directly V3Options opt; // All options; let user see them directly
public: public:
@@ -52,6 +54,7 @@ public:
m_rootp = new AstNetlist; m_rootp = new AstNetlist;
m_debugFileNumber = 0; m_debugFileNumber = 0;
m_assertWidthsSame = false; m_assertWidthsSame = false;
m_needHInlines = false;
} }
void clear() { void clear() {
if (m_rootp) m_rootp->deleteTree(); m_rootp=NULL; if (m_rootp) m_rootp->deleteTree(); m_rootp=NULL;
@@ -70,6 +73,8 @@ public:
char digits[100]; sprintf(digits, "%02d", m_debugFileNumber); char digits[100]; sprintf(digits, "%02d", m_debugFileNumber);
return opt.makeDir()+"/"+opt.prefix()+"_"+digits+"_"+nameComment; return opt.makeDir()+"/"+opt.prefix()+"_"+digits+"_"+nameComment;
} }
bool needHInlines() const { return m_needHInlines; }
void needHInlines(bool flag) { m_needHInlines=flag; }
}; };
extern V3Global v3Global; extern V3Global v3Global;
+3 -3
View File
@@ -177,10 +177,10 @@ void V3Graph::clear() {
void V3Graph::userClearVertices() { void V3Graph::userClearVertices() {
// Clear user() in all of tree // Clear user() in all of tree
// We may use the userCnt trick in V3Ast later... For now we don't call this often, and // We may use the userCnt trick in V3Ast later... For now we don't call this often, and
// the extra code on each read of user() would probably slow things down more then help. // the extra code on each read of user() would probably slow things down more than help.
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
vertexp->user(0); vertexp->user(0);
vertexp->userp(NULL); // Its a union, but might be different size then user() vertexp->userp(NULL); // Its a union, but might be different size than user()
} }
} }
@@ -189,7 +189,7 @@ void V3Graph::userClearEdges() {
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
edgep->user(0); edgep->user(0);
edgep->userp(NULL); // Its a union, but might be different size then user() edgep->userp(NULL); // Its a union, but might be different size than user()
} }
} }
} }
+1 -1
View File
@@ -440,7 +440,7 @@ void GraphAcyc::place() {
UINFO(4, " Cutable edges = "<<numEdges<<endl); UINFO(4, " Cutable edges = "<<numEdges<<endl);
vector<V3GraphEdge*> edges; // List of all edges to be processed vector<V3GraphEdge*> edges; // List of all edges to be processed
edges.reserve(numEdges+1); // Make the vector properly sized right off the bat -- faster then reallocating edges.reserve(numEdges+1); // Make the vector properly sized right off the bat -- faster than reallocating
for (V3GraphVertex* vertexp = m_breakGraph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { for (V3GraphVertex* vertexp = m_breakGraph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
vertexp->user(0); // Clear in prep of next step vertexp->user(0); // Clear in prep of next step
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
+3 -3
View File
@@ -58,7 +58,7 @@ void V3Graph::deleteCutableOnlyEdges() {
} }
// Pass 2, delete those marked // Pass 2, delete those marked
// Rather then doing a delete() we set the weight to 0 which disconnects the edge. // Rather than doing a delete() we set the weight to 0 which disconnects the edge.
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) { for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
if (vertexp->user()) { if (vertexp->user()) {
//UINFO(7,"Disconnect "<<vertexp->name()<<endl); //UINFO(7,"Disconnect "<<vertexp->name()<<endl);
@@ -99,9 +99,9 @@ private:
} else { // Duplicate } else { // Duplicate
bool saveOld = true; bool saveOld = true;
if (prevEdgep->cutable() && !edgep->cutable()) { if (prevEdgep->cutable() && !edgep->cutable()) {
saveOld = false; // new !cutable more important then old saveOld = false; // new !cutable more important than old
} else if (!prevEdgep->cutable() && edgep->cutable()) { } else if (!prevEdgep->cutable() && edgep->cutable()) {
saveOld = true; // old !cutable more important then new saveOld = true; // old !cutable more important than new
} else { } else {
saveOld = true; saveOld = true;
if (!m_sumWeights && (prevEdgep->weight() < edgep->weight())) { // Keep max weight if (!m_sumWeights && (prevEdgep->weight() < edgep->weight())) { // Keep max weight
+1 -1
View File
@@ -83,7 +83,7 @@ public:
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 then the more intuitive // Start and accepting are members, rather than the more intuitive
// subclasses, as subclassing them would make it harder to inherit from here. // subclasses, as subclassing them would make it harder to inherit from here.
bool m_start; // Start state bool m_start; // Start state
bool m_accepting; // Accepting state? bool m_accepting; // Accepting state?
+3 -3
View File
@@ -151,7 +151,7 @@ private:
// Remove the cell // Remove the cell
newmodp->deleteTree(); newmodp=NULL; // Clear any leftover ports, etc newmodp->deleteTree(); newmodp=NULL; // Clear any leftover ports, etc
nodep->unlinkFrBack(); nodep->unlinkFrBack();
nodep = NULL; pushDeletep(nodep); nodep = NULL;
if (debug()>=9) { m_modp->dumpTree(cout,"donemod:"); } if (debug()>=9) { m_modp->dumpTree(cout,"donemod:"); }
} }
} }
@@ -332,14 +332,14 @@ private:
} else { } else {
m_modp->user(1); m_modp->user(1);
} }
nodep->unlinkFrBack(); nodep=NULL; // Remove so don't propagate to upper cell... nodep->unlinkFrBack()->deleteTree(); nodep=NULL; // Remove so don't propagate to upper cell...
} else if (nodep->pragType() == AstPragmaType::NO_INLINE_MODULE) { } else if (nodep->pragType() == AstPragmaType::NO_INLINE_MODULE) {
if (!m_modp) { if (!m_modp) {
nodep->v3error("Inline pragma not under a module"); nodep->v3error("Inline pragma not under a module");
} else { } else {
cantInline("Pragma NO_INLINE_MODULE"); cantInline("Pragma NO_INLINE_MODULE");
} }
nodep->unlinkFrBack(); nodep=NULL; // Remove so don't propagate to upper cell... nodep->unlinkFrBack()->deleteTree(); nodep=NULL; // Remove so don't propagate to upper cell...
} else { } else {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
} }
+1 -1
View File
@@ -134,7 +134,7 @@ public:
AstVar* varp = it->first->varp(); AstVar* varp = it->first->varp();
LifeVarEntry* entp = &(it->second); LifeVarEntry* entp = &(it->second);
if (!varp->isSigPublic()) { if (!varp->isSigPublic()) {
// Rather then track what sigs AstUCFunc/AstUCStmt may change, // Rather than track what sigs AstUCFunc/AstUCStmt may change,
// we just don't optimize any public sigs // we just don't optimize any public sigs
// Check the var entry, and remove if appropriate // Check the var entry, and remove if appropriate
if (AstNode* oldassp = entp->assignp()) { if (AstNode* oldassp = entp->assignp()) {
+1 -1
View File
@@ -165,7 +165,7 @@ private:
if ((findvarp->isIO() && nodep->isSignal()) if ((findvarp->isIO() && nodep->isSignal())
|| (findvarp->isSignal() && nodep->isIO())) { || (findvarp->isSignal() && nodep->isIO())) {
findvarp->combineType(nodep); findvarp->combineType(nodep);
nodep->unlinkFrBack(); nodep=NULL; nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
} else { } else {
nodep->v3error("Duplicate declaration of signal: "<<nodep->prettyName()); nodep->v3error("Duplicate declaration of signal: "<<nodep->prettyName());
findvarp->v3error("... Location of original declaration"); findvarp->v3error("... Location of original declaration");
+2 -2
View File
@@ -174,8 +174,8 @@ private:
ports.insert(pinp->name(), pinp); ports.insert(pinp->name(), pinp);
} }
} }
// We search ports, rather then in/out declarations as they aren't resolved yet, // We search ports, rather than in/out declarations as they aren't resolved yet,
// and it's easier to do it now then in V3Link when we'd need to repeat steps. // and it's easier to do it now than in V3Link when we'd need to repeat steps.
for (AstNode* portnodep = nodep->modp()->stmtsp(); portnodep; portnodep=portnodep->nextp()) { for (AstNode* portnodep = nodep->modp()->stmtsp(); portnodep; portnodep=portnodep->nextp()) {
if (AstPort* portp = portnodep->castPort()) { if (AstPort* portp = portnodep->castPort()) {
if (!ports.findIdName(portp->name())) { if (!ports.findIdName(portp->name())) {
+1 -1
View File
@@ -72,7 +72,7 @@ private:
UINFO(5," "<<nodep<<endl); UINFO(5," "<<nodep<<endl);
checkExpected(nodep); checkExpected(nodep);
// Due to a need to get the arguments, the ParseRefs are under here, // Due to a need to get the arguments, the ParseRefs are under here,
// rather then the NodeFTaskRef under the ParseRef. // rather than the NodeFTaskRef under the ParseRef.
if (nodep->namep()) { if (nodep->namep()) {
m_exp = AstParseRefExp::FUNC; m_exp = AstParseRefExp::FUNC;
nodep->namep()->accept(*this); // No next, we don't want to do the edit nodep->namep()->accept(*this); // No next, we don't want to do the edit
+5 -1
View File
@@ -721,7 +721,7 @@ V3Number& V3Number::opRepl (const V3Number& lhs, const V3Number& rhs) { // rhs i
V3Number& V3Number::opRepl (const V3Number& lhs, uint32_t rhsval) { // rhs is # of times to replicate V3Number& V3Number::opRepl (const V3Number& lhs, uint32_t rhsval) { // rhs is # of times to replicate
// i op repl, L(i)*value(rhs) bit return // i op repl, L(i)*value(rhs) bit return
setZero(); setZero();
if (rhsval>8192) m_fileline->v3fatal("More then a 8k bit replication is probably wrong: "<<rhsval); if (rhsval>8192) m_fileline->v3fatal("More than a 8k bit replication is probably wrong: "<<rhsval);
int obit = 0; int obit = 0;
for (unsigned times=0; times<rhsval; times++) { for (unsigned times=0; times<rhsval; times++) {
for(int bit=0; bit<lhs.width(); bit++) { for(int bit=0; bit<lhs.width(); bit++) {
@@ -1007,6 +1007,7 @@ V3Number& V3Number::opMulS (const V3Number& lhs, const V3Number& rhs) {
V3Number& V3Number::opDiv (const V3Number& lhs, const V3Number& rhs) { V3Number& V3Number::opDiv (const V3Number& lhs, const V3Number& rhs) {
// i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return // i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX(); if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
if (rhs.isEqZero()) return setAllBitsX();
if (lhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large / math not implemented yet: "<<*this); if (lhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large / math not implemented yet: "<<*this);
if (rhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large / math not implemented yet: "<<*this); if (rhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large / math not implemented yet: "<<*this);
setQuad(lhs.asQuad() / rhs.asQuad()); setQuad(lhs.asQuad() / rhs.asQuad());
@@ -1015,6 +1016,7 @@ V3Number& V3Number::opDiv (const V3Number& lhs, const V3Number& rhs) {
V3Number& V3Number::opDivS (const V3Number& lhs, const V3Number& rhs) { V3Number& V3Number::opDivS (const V3Number& lhs, const V3Number& rhs) {
// Signed divide // Signed divide
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX(); if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
if (rhs.isEqZero()) return setAllBitsX();
V3Number lhsNoSign = lhs; if (lhs.isNegative()) lhsNoSign.opUnaryMin(lhs); V3Number lhsNoSign = lhs; if (lhs.isNegative()) lhsNoSign.opUnaryMin(lhs);
V3Number rhsNoSign = rhs; if (rhs.isNegative()) rhsNoSign.opUnaryMin(rhs); V3Number rhsNoSign = rhs; if (rhs.isNegative()) rhsNoSign.opUnaryMin(rhs);
V3Number qNoSign = opDiv(lhsNoSign,rhsNoSign); V3Number qNoSign = opDiv(lhsNoSign,rhsNoSign);
@@ -1029,6 +1031,7 @@ V3Number& V3Number::opDivS (const V3Number& lhs, const V3Number& rhs) {
V3Number& V3Number::opModDiv (const V3Number& lhs, const V3Number& rhs) { V3Number& V3Number::opModDiv (const V3Number& lhs, const V3Number& rhs) {
// i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return // i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX(); if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
if (rhs.isEqZero()) return setAllBitsX();
if (lhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large % math not implemented yet: "<<*this); if (lhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large % math not implemented yet: "<<*this);
if (rhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large % math not implemented yet: "<<*this); if (rhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large % math not implemented yet: "<<*this);
setQuad(lhs.asQuad() % rhs.asQuad()); setQuad(lhs.asQuad() % rhs.asQuad());
@@ -1037,6 +1040,7 @@ V3Number& V3Number::opModDiv (const V3Number& lhs, const V3Number& rhs) {
V3Number& V3Number::opModDivS (const V3Number& lhs, const V3Number& rhs) { V3Number& V3Number::opModDivS (const V3Number& lhs, const V3Number& rhs) {
// Signed moddiv // Signed moddiv
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX(); if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
if (rhs.isEqZero()) return setAllBitsX();
V3Number lhsNoSign = lhs; if (lhs.isNegative()) lhsNoSign.opUnaryMin(lhs); V3Number lhsNoSign = lhs; if (lhs.isNegative()) lhsNoSign.opUnaryMin(lhs);
V3Number rhsNoSign = rhs; if (rhs.isNegative()) rhsNoSign.opUnaryMin(rhs); V3Number rhsNoSign = rhs; if (rhs.isNegative()) rhsNoSign.opUnaryMin(rhs);
V3Number qNoSign = opModDiv(lhsNoSign,rhsNoSign); V3Number qNoSign = opModDiv(lhsNoSign,rhsNoSign);
+9 -4
View File
@@ -440,9 +440,14 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
V3PreShell::undef (string (sw+strlen("-U"))); V3PreShell::undef (string (sw+strlen("-U")));
} }
else if ( !strncmp (sw, "-Wno-",5) ) { else if ( !strncmp (sw, "-Wno-",5) ) {
string msg = sw+strlen("-Wno-"); if (!strcmp (sw, "-Wno-lint")) {
if (!(FileLine::defaultFileLine().warnOff(msg, true))) { FileLine::defaultFileLine().warnLintOff(true);
fl->v3fatal("Unknown warning disabled: "<<sw); }
else {
string msg = sw+strlen("-Wno-");
if (!(FileLine::defaultFileLine().warnOff(msg, true))) {
fl->v3fatal("Unknown warning disabled: "<<sw);
}
} }
} }
else if ( !strncmp (sw, "-Werror-",strlen("-Werror-")) ) { else if ( !strncmp (sw, "-Werror-",strlen("-Werror-")) ) {
@@ -623,7 +628,7 @@ V3Options::V3Options() {
addLibExt(""); // So include "filename.v" will find the same file addLibExt(""); // So include "filename.v" will find the same file
addLibExt(".v"); addLibExt(".v");
// Default -I // Default -I
addIncDir("."); // Looks better then {long_cwd_path}/... addIncDir("."); // Looks better than {long_cwd_path}/...
} }
V3Options::~V3Options() { V3Options::~V3Options() {
+12 -6
View File
@@ -155,6 +155,9 @@ public:
void movedVertex(OrderVisitor* ovp, OrderMoveVertex* vertexp); // Mark one vertex as finished, remove from ready list if done void movedVertex(OrderVisitor* ovp, OrderMoveVertex* vertexp); // Mark one vertex as finished, remove from ready list if done
// STATIC MEMBERS (for lookup) // STATIC MEMBERS (for lookup)
static void clear() { static void clear() {
for (DomScopeMap::iterator it=s_dsMap.begin(); it!=s_dsMap.end(); ++it) {
delete it->second;
}
s_dsMap.clear(); s_dsMap.clear();
} }
V3List<OrderMoveVertex*>& readyVertices() { return m_readyVertices; } V3List<OrderMoveVertex*>& readyVertices() { return m_readyVertices; }
@@ -426,15 +429,18 @@ private:
m_finder.main(m_topScopep); m_finder.main(m_topScopep);
// ProcessDomainsIterate will use these when it needs to move // ProcessDomainsIterate will use these when it needs to move
// something to a combodomain. This saves a ton of find() operations. // something to a combodomain. This saves a ton of find() operations.
AstSenTree comb (nodep->fileline(), // Gets cloned() so ok if goes out of scope AstSenTree* combp = new AstSenTree (nodep->fileline(), // Gets cloned() so ok if goes out of scope
new AstSenItem(nodep->fileline(), AstSenItem::Combo())); new AstSenItem(nodep->fileline(), AstSenItem::Combo()));
m_comboDomainp = m_finder.getSenTree(nodep->fileline(), &comb); m_comboDomainp = m_finder.getSenTree(nodep->fileline(), combp);
AstSenTree settle (nodep->fileline(), // Gets cloned() so ok if goes out of scope pushDeletep(combp); // Cleanup when done
new AstSenItem(nodep->fileline(), AstSenItem::Settle())); AstSenTree* settlep = new AstSenTree (nodep->fileline(), // Gets cloned() so ok if goes out of scope
m_settleDomainp = m_finder.getSenTree(nodep->fileline(), &settle); new AstSenItem(nodep->fileline(), AstSenItem::Settle()));
m_settleDomainp = m_finder.getSenTree(nodep->fileline(), settlep);
pushDeletep(settlep); // Cleanup when done
// Fake AstSenTree we set domainp to indicate needs deletion // Fake AstSenTree we set domainp to indicate needs deletion
m_deleteDomainp = new AstSenTree (nodep->fileline(), m_deleteDomainp = new AstSenTree (nodep->fileline(),
new AstSenItem(nodep->fileline(), AstSenItem::Settle())); new AstSenItem(nodep->fileline(), AstSenItem::Settle()));
pushDeletep(m_deleteDomainp); // Cleanup when done
UINFO(5," DeleteDomain = "<<m_deleteDomainp<<endl); UINFO(5," DeleteDomain = "<<m_deleteDomainp<<endl);
// Base vertices // Base vertices
m_activeSenVxp = NULL; m_activeSenVxp = NULL;
+4 -4
View File
@@ -57,10 +57,10 @@ protected:
s_preprocp->debug(debug()); s_preprocp->debug(debug());
// Default defines // Default defines
FileLine* prefl = new FileLine("INTERNAL_VERILATOR_DEFINE",0); FileLine* prefl = new FileLine("INTERNAL_VERILATOR_DEFINE",0);
s_preprocp->define(prefl,"verilator", "1"); s_preprocp->define(prefl,"verilator", "1"); // LEAK_OK
s_preprocp->define(prefl,"verilator3", "1"); s_preprocp->define(prefl,"verilator3", "1"); // LEAK_OK
s_preprocp->define(prefl,"systemc_clock", "/*verilator systemc_clock*/"); s_preprocp->define(prefl,"systemc_clock", "/*verilator systemc_clock*/"); // LEAK_OK
s_preprocp->define(prefl,"coverage_block_off", "/*verilator coverage_block_off*/"); s_preprocp->define(prefl,"coverage_block_off", "/*verilator coverage_block_off*/"); // LEAK_OK
} }
} }
+13
View File
@@ -78,6 +78,19 @@ void V3Read::statePop() { s_readp->m_lexerp->statePop(); }
//###################################################################### //######################################################################
// Read class functions // Read class functions
V3Read::~V3Read() {
for (deque<string*>::iterator it = m_stringps.begin(); it != m_stringps.end(); ++it) {
delete (*it);
}
m_stringps.clear();
for (deque<V3Number*>::iterator it = m_numberps.begin(); it != m_numberps.end(); ++it) {
delete (*it);
}
m_numberps.clear();
if (m_lexerp) { delete m_lexerp; m_lexerp = NULL; }
parserClear();
}
void V3Read::readFile(FileLine* fileline, const string& modfilename, bool inLibrary) { void V3Read::readFile(FileLine* fileline, const string& modfilename, bool inLibrary) {
string modname = V3Options::filenameNonExt(modfilename); string modname = V3Options::filenameNonExt(modfilename);
+2 -10
View File
@@ -110,16 +110,8 @@ public:
m_inBeginKwd = 0; m_inBeginKwd = 0;
m_lastVerilogState = stateVerilogRecent(); m_lastVerilogState = stateVerilogRecent();
} }
~V3Read() { ~V3Read();
for (deque<string*>::iterator it = m_stringps.begin(); it != m_stringps.end(); ++it) { void parserClear();
delete (*it);
}
m_stringps.clear();
for (deque<V3Number*>::iterator it = m_numberps.begin(); it != m_numberps.end(); ++it) {
delete (*it);
}
m_numberps.clear();
}
// METHODS // METHODS
// Preprocess and read the Verilog file specified into the netlist database // Preprocess and read the Verilog file specified into the netlist database
+1 -1
View File
@@ -337,7 +337,7 @@ private:
SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p(); SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p();
vvertexp->splitColor(vvertexp->color()); vvertexp->splitColor(vvertexp->color());
uint32_t color = vvertexp->splitColor(); uint32_t color = vvertexp->splitColor();
if (color >= numVertexes) nextp->v3fatalSrc("More colors then vertexes!\n"); if (color >= numVertexes) nextp->v3fatalSrc("More colors than vertexes!\n");
if (!color) nextp->v3fatalSrc("No node color assigned\n"); if (!color) nextp->v3fatalSrc("No node color assigned\n");
if (lastOfColor[color]) { if (lastOfColor[color]) {
new SplitStrictEdge(&m_graph, lastOfColor[color], vvertexp); new SplitStrictEdge(&m_graph, lastOfColor[color], vvertexp);
+1 -1
View File
@@ -165,7 +165,7 @@ private:
virtual void visit(AstAlways* nodep, AstNUser*) { virtual void visit(AstAlways* nodep, AstNUser*) {
// Are there any lvalue references below this? // Are there any lvalue references below this?
// There could be more then one. So, we process the first one found first. // There could be more than one. So, we process the first one found first.
AstVarScope* lastSplitVscp = NULL; AstVarScope* lastSplitVscp = NULL;
while (!nodep->user()) { while (!nodep->user()) {
// Find any splittable variables // Find any splittable variables
+2 -2
View File
@@ -120,14 +120,14 @@ public:
if (!nodep->user3p()) { if (!nodep->user3p()) {
// Save time - kept a list of allocated but unused V3Numbers // Save time - kept a list of allocated but unused V3Numbers
// It would be more efficient to do this by size, but the extra accounting // It would be more efficient to do this by size, but the extra accounting
// slows things down more then we gain. // slows things down more than we gain.
V3Number* nump; V3Number* nump;
if (!m_numFreeps.empty()) { if (!m_numFreeps.empty()) {
//UINFO(7,"Num Reuse "<<nodep->width()<<endl); //UINFO(7,"Num Reuse "<<nodep->width()<<endl);
nump = m_numFreeps.back(); m_numFreeps.pop_back(); nump = m_numFreeps.back(); m_numFreeps.pop_back();
nump->width(nodep->width()); nump->width(nodep->width());
nump->fileline(nodep->fileline()); nump->fileline(nodep->fileline());
nump->setLong(value); // We do support more then 32 bit numbers, just valuep=0 in that case nump->setLong(value); // We do support more than 32 bit numbers, just valuep=0 in that case
} else { } else {
//UINFO(7,"Num New "<<nodep->width()<<endl); //UINFO(7,"Num New "<<nodep->width()<<endl);
nump = new V3Number (nodep->fileline(), nodep->width(), value); nump = new V3Number (nodep->fileline(), nodep->width(), value);
+1
View File
@@ -349,6 +349,7 @@ private:
// Connect to this exact variable // Connect to this exact variable
AstVarScope* localVscp = varrefp->varScopep(); if (!localVscp) varrefp->v3fatalSrc("Null var scope"); AstVarScope* localVscp = varrefp->varScopep(); if (!localVscp) varrefp->v3fatalSrc("Null var scope");
portp->user2p(localVscp); portp->user2p(localVscp);
pushDeletep(pinp);
} else { } else {
pinp->v3warn(TASKNSVAR,"Unsupported: Function/task input argument is not simple variable"); pinp->v3warn(TASKNSVAR,"Unsupported: Function/task input argument is not simple variable");
} }
+1 -1
View File
@@ -37,7 +37,7 @@
// For each CFUNC in graph // For each CFUNC in graph
// Add ASSIGN(SEL(__Vm_funcActivity,activityNumber++),1) // Add ASSIGN(SEL(__Vm_funcActivity,activityNumber++),1)
// Create __Vm_funcActivity vector // Create __Vm_funcActivity vector
// Sort TRACEs by activityNumber(s) they come from (may be more then one) // Sort TRACEs by activityNumber(s) they come from (may be more than one)
// Each set of activityNumbers // Each set of activityNumbers
// Add IF (SEL(__Vm_funcActivity,activityNumber),1) // Add IF (SEL(__Vm_funcActivity,activityNumber),1)
// Add traces under that activity number. // Add traces under that activity number.
+3
View File
@@ -95,6 +95,8 @@ private:
|| (rhsp->castConst() && rhsp->castConst()->num().isFourState()))) { || (rhsp->castConst() && rhsp->castConst()->num().isFourState()))) {
V3Number num (nodep->fileline(), 1, (nodep->castEqCase()?0:1)); V3Number num (nodep->fileline(), 1, (nodep->castEqCase()?0:1));
newp = new AstConst (nodep->fileline(), num); newp = new AstConst (nodep->fileline(), num);
lhsp->deleteTree(); lhsp=NULL;
rhsp->deleteTree(); rhsp=NULL;
} else { } else {
if (nodep->castEqCase()) if (nodep->castEqCase())
newp = new AstEq (nodep->fileline(), lhsp, rhsp); newp = new AstEq (nodep->fileline(), lhsp, rhsp);
@@ -221,6 +223,7 @@ private:
if (debug()>=9) newref1p->dumpTree(cout," _new: "); if (debug()>=9) newref1p->dumpTree(cout," _new: ");
if (debug()>=9) newvarp->dumpTree(cout," _new: "); if (debug()>=9) newvarp->dumpTree(cout," _new: ");
if (debug()>=9) newinitp->dumpTree(cout," _new: "); if (debug()>=9) newinitp->dumpTree(cout," _new: ");
nodep->deleteTree(); nodep=NULL;
} }
} }
} }
+23 -25
View File
@@ -171,7 +171,7 @@ private:
if (((valStop - valInit)/valInc) > v3Global.opt.unrollCount()) if (((valStop - valInit)/valInc) > v3Global.opt.unrollCount())
return cantUnroll(nodep, "too many iterations"); return cantUnroll(nodep, "too many iterations");
// Less then 10 statements in the body? // Less than 10 statements in the body?
int bodySize = 0; int bodySize = 0;
for (AstNode* bodp = precondsp; bodp; bodp=bodp->nextp()) { for (AstNode* bodp = precondsp; bodp; bodp=bodp->nextp()) {
bodySize++; bodySize++;
@@ -198,6 +198,7 @@ private:
constInitp->num(), constInitp->num(),
condBip, constStopp->num(), condBip, constStopp->num(),
incInstrp, constIncp->num()); nodep = NULL; incInstrp, constIncp->num()); nodep = NULL;
// Cleanup
return true; return true;
} }
@@ -229,7 +230,6 @@ private:
loopValue.opAssign(numInit); loopValue.opAssign(numInit);
AstNode* newbodysp = NULL; AstNode* newbodysp = NULL;
AstNode* clonedIncsp = NULL; // Last cloned incp() statements
m_statLoops++; m_statLoops++;
if (stmtsp) { if (stmtsp) {
int times = 0; int times = 0;
@@ -244,25 +244,8 @@ private:
// Replace iterator values with constant. // Replace iterator values with constant.
AstNode* oneloopp = stmtsp->cloneTree(true); AstNode* oneloopp = stmtsp->cloneTree(true);
// A nicer way to propage the loop constant would be to set the variable to the value
// and call a constant-propagator like V3Table, so temp values
// that are calculated propagate down.
// If we do this, we can remove the below
if (nodep->castWhile() && incp) {
if (clonedIncsp) {
// Previous iteration of loop set the variable.
// This set is redundant with this next iteration and can be removed.
if (clonedIncsp == newbodysp) { // Increment was only thing in list
newbodysp = NULL;
} else {
clonedIncsp->unlinkFrBack();
}
clonedIncsp->deleteTree();
}
clonedIncsp = incp->clonep(); if (!clonedIncsp) nodep->v3fatalSrc("inc failed");
}
m_varValuep = new AstConst(nodep->fileline(), loopValue); m_varValuep = new AstConst(nodep->fileline(), loopValue);
m_varModeReplace = true; m_varModeReplace = true;
oneloopp->iterateAndNext(*this); oneloopp->iterateAndNext(*this);
m_varModeReplace = false; m_varModeReplace = false;
@@ -280,6 +263,8 @@ private:
V3Number newnum(nodep->fileline(), m_forVarp->width()); // Can't increment in-place V3Number newnum(nodep->fileline(), m_forVarp->width()); // Can't increment in-place
incInstrp->numberOperate(newnum, loopValue, numInc); incInstrp->numberOperate(newnum, loopValue, numInc);
loopValue.opAssign(newnum); loopValue.opAssign(newnum);
pushDeletep(m_varValuep); m_varValuep=NULL;
} }
} }
} }
@@ -287,6 +272,9 @@ private:
// Replace the FOR() // Replace the FOR()
if (newbodysp) nodep->replaceWith(newbodysp); if (newbodysp) nodep->replaceWith(newbodysp);
else nodep->unlinkFrBack(); else nodep->unlinkFrBack();
if (bodysp) { pushDeletep(bodysp); bodysp=NULL; }
if (precondsp) { pushDeletep(precondsp); precondsp=NULL; }
if (initp) { pushDeletep(initp); initp=NULL; }
if (debug()>=9) newbodysp->dumpTree(cout,"- _new: "); if (debug()>=9) newbodysp->dumpTree(cout,"- _new: ");
} }
@@ -311,7 +299,7 @@ private:
if (forUnrollCheck(nodep, initp, if (forUnrollCheck(nodep, initp,
nodep->precondsp(), nodep->condp(), nodep->precondsp(), nodep->condp(),
incp, nodep->bodysp())) { incp, nodep->bodysp())) {
nodep=NULL; // Did replacement pushDeletep(nodep); nodep=NULL; // Did replacement
} }
} }
} }
@@ -325,10 +313,19 @@ private:
if (nodep->initsp()) V3Const::constifyTree(nodep->initsp()); if (nodep->initsp()) V3Const::constifyTree(nodep->initsp());
if (nodep->condp()) V3Const::constifyTree(nodep->condp()); if (nodep->condp()) V3Const::constifyTree(nodep->condp());
if (nodep->incsp()) V3Const::constifyTree(nodep->incsp()); if (nodep->incsp()) V3Const::constifyTree(nodep->incsp());
if (forUnrollCheck(nodep, nodep->initsp(), if (nodep->condp()->isZero()) {
NULL, nodep->condp(), // We don't need to do any loops. Remove the GenFor,
nodep->incsp(), nodep->bodysp())) { // Genvar's don't care about any initial assignments.
nodep=NULL; // Did replacement //
// Note normal For's can't do exactly this deletion, as
// we'd need to initialize the variable to the initial
// condition, but they'll become while's which can be
// deleted by V3Const.
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
} else if (forUnrollCheck(nodep, nodep->initsp(),
NULL, nodep->condp(),
nodep->incsp(), nodep->bodysp())) {
pushDeletep(nodep); nodep=NULL; // Did replacement
} else { } else {
nodep->v3error("For loop doesn't have genvar index, or is misformed"); nodep->v3error("For loop doesn't have genvar index, or is misformed");
} }
@@ -373,6 +370,7 @@ private:
&& !nodep->lvalue()) { && !nodep->lvalue()) {
AstNode* newconstp = m_varValuep->cloneTree(false); AstNode* newconstp = m_varValuep->cloneTree(false);
nodep->replaceWith(newconstp); nodep->replaceWith(newconstp);
pushDeletep(nodep);
} }
} }
+3 -2
View File
@@ -367,7 +367,7 @@ private:
} }
if (vup->c()->final()) { if (vup->c()->final()) {
nodep->width(vup->c()->width(),vup->c()->widthMin()); // We don't care nodep->width(vup->c()->width(),vup->c()->widthMin()); // We don't care
if (nodep->width()>64) nodep->v3error("Unsupported: $c can't generate wider then 64 bits"); if (nodep->width()>64) nodep->v3error("Unsupported: $c can't generate wider than 64 bits");
} }
// Just let all arguments seek their natural sizes // Just let all arguments seek their natural sizes
nodep->iterateChildren(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->iterateChildren(*this,WidthVP(ANYSIZE,0,BOTH).p());
@@ -535,7 +535,7 @@ private:
nodep->rhsp()->iterateAndNext(*this,WidthVP(awidth,awidth,FINAL).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(awidth,awidth,FINAL).p());
nodep->width(awidth,awidth); // We know the assign will truncate, so rather nodep->width(awidth,awidth); // We know the assign will truncate, so rather
//UINFO(0,"aw "<<awidth<<" w"<<nodep->rhsp()->width()<<" m"<<nodep->rhsp()->widthMin()<<endl); //UINFO(0,"aw "<<awidth<<" w"<<nodep->rhsp()->width()<<" m"<<nodep->rhsp()->widthMin()<<endl);
// then using "width" and have the optimizer truncate the result, we do // than using "width" and have the optimizer truncate the result, we do
// it using the normal width reduction checks. // it using the normal width reduction checks.
widthCheck(nodep,"Assign RHS",nodep->rhsp(),awidth,awidth); widthCheck(nodep,"Assign RHS",nodep->rhsp(),awidth,awidth);
//if (debug()) nodep->dumpTree(cout," AssignPos: "); //if (debug()) nodep->dumpTree(cout," AssignPos: ");
@@ -760,6 +760,7 @@ void WidthVisitor::fixWidthExtend (AstNode* nodep, int expWidth) {
AstNode* newp = new AstConst(nodep->fileline(), num); AstNode* newp = new AstConst(nodep->fileline(), num);
newp->signedFrom(constp); newp->signedFrom(constp);
constp->replaceWith(newp); constp->replaceWith(newp);
pushDeletep(constp); constp=NULL;
nodep=newp; nodep=newp;
} else if (expWidth<nodep->width()) { } else if (expWidth<nodep->width()) {
// Trunc - Extract // Trunc - Extract
+3
View File
@@ -459,6 +459,8 @@ void process () {
// Output the text // Output the text
if (!v3Global.opt.lintOnly()) { if (!v3Global.opt.lintOnly()) {
// emitcInlines is first, as it may set needHInlines which other emitters read
V3EmitC::emitcInlines();
V3EmitC::emitcSyms(); V3EmitC::emitcSyms();
V3EmitC::emitcTrace(); V3EmitC::emitcTrace();
} }
@@ -552,6 +554,7 @@ int main(int argc, char** argv, char** env) {
// Cleanup memory for valgrind leak analysis // Cleanup memory for valgrind leak analysis
v3Global.clear(); v3Global.clear();
#endif #endif
FileLine::deleteAllRemaining();
UINFO(1,"Done, Exiting...\n"); UINFO(1,"Done, Exiting...\n");
} }
+1 -1
View File
@@ -24,7 +24,7 @@
//********************************************************************** //**********************************************************************
//**** Version and host name //**** Version and host name
#define DTVERSION "Verilator 3.653 8/1/2007" #define DTVERSION "Verilator 3.655 11/27/2007"
//********************************************************************** //**********************************************************************
//**** Functions //**** Functions
+31 -3
View File
@@ -324,6 +324,7 @@ escid \\[^ \t\f\r\n]+
"always_latch" {yylval.fileline = CRELINE(); return yALWAYS;} "always_latch" {yylval.fileline = CRELINE(); return yALWAYS;}
"do" {yylval.fileline = CRELINE(); return yDO;} "do" {yylval.fileline = CRELINE(); return yDO;}
"final" {yylval.fileline = CRELINE(); return yFINAL;} "final" {yylval.fileline = CRELINE(); return yFINAL;}
"static" {yylval.fileline = CRELINE(); return ySTATIC;}
/* Generic unsupported warnings */ /* Generic unsupported warnings */
/* Note assert_strobe was in SystemVerilog 3.1, but removed for SystemVerilog 2005 */ /* Note assert_strobe was in SystemVerilog 3.1, but removed for SystemVerilog 2005 */
"alias" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);} "alias" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
@@ -391,7 +392,6 @@ escid \\[^ \t\f\r\n]+
"shortint" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);} "shortint" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"shortreal" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);} "shortreal" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"solve" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);} "solve" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"static" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"string" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);} "string" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"struct" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);} "struct" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
"super" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);} "super" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
@@ -568,6 +568,9 @@ escid \\[^ \t\f\r\n]+
"~&" {yylval.fileline = CRELINE(); return yP_NAND;} "~&" {yylval.fileline = CRELINE(); return yP_NAND;}
"~|" {yylval.fileline = CRELINE(); return yP_NOR;} "~|" {yylval.fileline = CRELINE(); return yP_NOR;}
"->" {yylval.fileline = CRELINE(); return yP_MINUSGT;} "->" {yylval.fileline = CRELINE(); return yP_MINUSGT;}
"=>" {yylval.fileline = CRELINE(); return yP_EQGT; }
"*>" {yylval.fileline = CRELINE(); return yP_ASTGT; }
"&&&" {yylval.fileline = CRELINE(); return yP_ANDANDAND; }
} }
/* Verilog 2001 Operators */ /* Verilog 2001 Operators */
@@ -577,12 +580,33 @@ escid \\[^ \t\f\r\n]+
"**" {yylval.fileline = CRELINE(); return yP_POW;} "**" {yylval.fileline = CRELINE(); return yP_POW;}
"+:" {yylval.fileline = CRELINE(); return yP_PLUSCOLON;} "+:" {yylval.fileline = CRELINE(); return yP_PLUSCOLON;}
"-:" {yylval.fileline = CRELINE(); return yP_MINUSCOLON;} "-:" {yylval.fileline = CRELINE(); return yP_MINUSCOLON;}
".*" {yylval.fileline = CRELINE(); return yP_DOTSTAR;}
} }
/* SystemVerilog Operators */ /* SystemVerilog Operators */
<S05>{ <S05>{
"==?" {yylval.fileline = CRELINE(); return yP_WILDEQUAL;} "==?" {yylval.fileline = CRELINE(); return yP_WILDEQUAL;}
"!=?" {yylval.fileline = CRELINE(); return yP_WILDNOTEQUAL;} "!=?" {yylval.fileline = CRELINE(); return yP_WILDNOTEQUAL;}
"+=" {yylval.fileline = CRELINE(); return yP_PLUSEQ; }
"-=" {yylval.fileline = CRELINE(); return yP_MINUSEQ; }
"*=" {yylval.fileline = CRELINE(); return yP_TIMESEQ; }
"/=" {yylval.fileline = CRELINE(); return yP_DIVEQ; }
"%=" {yylval.fileline = CRELINE(); return yP_MODEQ; }
"&=" {yylval.fileline = CRELINE(); return yP_ANDEQ; }
"|=" {yylval.fileline = CRELINE(); return yP_OREQ; }
"^=" {yylval.fileline = CRELINE(); return yP_XOREQ; }
"<<=" {yylval.fileline = CRELINE(); return yP_SLEFTEQ; }
">>=" {yylval.fileline = CRELINE(); return yP_SRIGHTEQ; }
"<<<=" {yylval.fileline = CRELINE(); return yP_SLEFTEQ; }
">>>=" {yylval.fileline = CRELINE(); return yP_SSRIGHTEQ; }
"->>" {yylval.fileline = CRELINE(); return yP_MINUSGTGT; }
"##" {yylval.fileline = CRELINE(); return yP_POUNDPOUND; }
"@@" {yylval.fileline = CRELINE(); return yP_ATAT; }
"::" {yylval.fileline = CRELINE(); return yP_COLONCOLON; }
":=" {yylval.fileline = CRELINE(); return yP_COLONEQ; }
":/" {yylval.fileline = CRELINE(); return yP_COLONDIV; }
"|->" {yylval.fileline = CRELINE(); return yP_ORMINUSGT; }
"|=>" {yylval.fileline = CRELINE(); return yP_OREQGT; }
} }
/* PSL Operators */ /* PSL Operators */
@@ -596,8 +620,8 @@ escid \\[^ \t\f\r\n]+
"[->" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_MINUS_GT "[->" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_MINUS_GT
"[->]" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_MINUS_GT_KET "[->]" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_MINUS_GT_KET
"[=" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_EQ "[=" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_EQ
"|->" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_OR_MINUS_GT "|->" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_ORMINUSGT
"|=>" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_OR_EQ_GT "|=>" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_OREQGT
} }
/* Identifiers and numbers */ /* Identifiers and numbers */
@@ -647,6 +671,10 @@ escid \\[^ \t\f\r\n]+
yylval.cdouble = 0; /* Only for delays, not used yet */ yylval.cdouble = 0; /* Only for delays, not used yet */
return yaFLOATNUM; return yaFLOATNUM;
} }
[0-9][_0-9]*(\.[_0-9]+)?(fs|ps|ns|us|ms|s|step) {
yylval.cdouble = 0; /* Only for times, not used yet */
return yaFLOATNUM;
}
} }
/************************************************************************/ /************************************************************************/
+226 -83
View File
@@ -66,6 +66,10 @@ public:
nodep->addNext(new AstStop(fileline)); nodep->addNext(new AstStop(fileline));
return nodep; return nodep;
} }
static void setRange(AstRange* rangep) {
if (s_varRangep) { s_varRangep->deleteTree(); s_varRangep=NULL; } // It was cloned, so this is safe.
s_varRangep = rangep;
}
static string deQuote(FileLine* fileline, string text); static string deQuote(FileLine* fileline, string text);
}; };
@@ -88,7 +92,7 @@ AstCase* V3Parse::s_caseAttrp = NULL;
#define VARDECL(type) { V3Parse::s_varDecl = AstVarType::type; } #define VARDECL(type) { V3Parse::s_varDecl = AstVarType::type; }
#define VARIO(type) { V3Parse::s_varIO = AstVarType::type; } #define VARIO(type) { V3Parse::s_varIO = AstVarType::type; }
#define VARSIGNED(value) { V3Parse::s_varSigned = value; } #define VARSIGNED(value) { V3Parse::s_varSigned = value; }
#define VARRANGE(range) { V3Parse::s_varRangep=(range); } #define VARRANGE(rangep) { V3Parse::setRange(rangep); }
#define INSTPREP(modname,paramsp) { V3Parse::s_impliedDecl = true; V3Parse::s_instModule = modname; V3Parse::s_instParamp = paramsp; } #define INSTPREP(modname,paramsp) { V3Parse::s_impliedDecl = true; V3Parse::s_instModule = modname; V3Parse::s_instParamp = paramsp; }
@@ -127,11 +131,19 @@ class AstSenTree;
} }
// Generic lexer tokens, for example a number // Generic lexer tokens, for example a number
// IEEE: real_number
%token<cdouble> yaFLOATNUM "FLOATING-POINT NUMBER" %token<cdouble> yaFLOATNUM "FLOATING-POINT NUMBER"
%token<fileline> yaTIMINGSPEC "TIMING SPEC ELEMENT" // IEEE: identifier, class_identifier, class_variable_identifier,
%token<nump> yaINTNUM "INTEGER NUMBER" // covergroup_variable_identifier, dynamic_array_variable_identifier,
// enum_identifier, interface_identifier, interface_instance_identifier,
// package_identifier, type_identifier, variable_identifier,
%token<strp> yaID "IDENTIFIER" %token<strp> yaID "IDENTIFIER"
// IEEE: integral_number
%token<nump> yaINTNUM "INTEGER NUMBER"
// IEEE: string_literal
%token<strp> yaSTRING "STRING" %token<strp> yaSTRING "STRING"
%token<fileline> yaTIMINGSPEC "TIMING SPEC ELEMENT"
%token<strp> yaSCHDR "`systemc_header BLOCK" %token<strp> yaSCHDR "`systemc_header BLOCK"
%token<strp> yaSCINT "`systemc_ctor BLOCK" %token<strp> yaSCINT "`systemc_ctor BLOCK"
@@ -193,6 +205,7 @@ class AstSenTree;
%token<fileline> ySCALARED "scalared" %token<fileline> ySCALARED "scalared"
%token<fileline> ySIGNED "signed" %token<fileline> ySIGNED "signed"
%token<fileline> ySPECIFY "specify" %token<fileline> ySPECIFY "specify"
%token<fileline> ySTATIC "static"
%token<fileline> ySUPPLY0 "supply0" %token<fileline> ySUPPLY0 "supply0"
%token<fileline> ySUPPLY1 "supply1" %token<fileline> ySUPPLY1 "supply1"
%token<fileline> yTASK "task" %token<fileline> yTASK "task"
@@ -246,39 +259,114 @@ class AstSenTree;
%token<fileline> yVL_TRACING_OFF "/*verilator tracing_off*/" %token<fileline> yVL_TRACING_OFF "/*verilator tracing_off*/"
%token<fileline> yVL_TRACING_ON "/*verilator tracing_on*/" %token<fileline> yVL_TRACING_ON "/*verilator tracing_on*/"
%token<fileline> yP_OROR "||"
%token<fileline> yP_ANDAND "&&"
%token<fileline> yP_NOR "~|"
%token<fileline> yP_XNOR "^~"
%token<fileline> yP_NAND "~&"
%token<fileline> yP_EQUAL "=="
%token<fileline> yP_NOTEQUAL "!="
%token<fileline> yP_CASEEQUAL "==="
%token<fileline> yP_CASENOTEQUAL "!=="
%token<fileline> yP_WILDEQUAL "==?"
%token<fileline> yP_WILDNOTEQUAL "!=?"
%token<fileline> yP_GTE ">="
%token<fileline> yP_LTE "<="
%token<fileline> yP_SLEFT "<<"
%token<fileline> yP_SRIGHT ">>"
%token<fileline> yP_SSRIGHT ">>>"
%token<fileline> yP_POW "**"
%token<fileline> yP_PLUSCOLON "+:" %token<fileline> yP_PLUSCOLON "+:"
%token<fileline> yP_MINUSCOLON "-:" %token<fileline> yP_MINUSCOLON "-:"
%token<fileline> yP_MINUSGT "->"
%token<fileline> yP_MINUSGTGT "->>"
%token<fileline> yP_EQGT "=>"
%token<fileline> yP_ASTGT "*>"
%token<fileline> yP_ANDANDAND "&&&"
%token<fileline> yP_POUNDPOUND "##"
%token<fileline> yP_DOTSTAR ".*"
%token<fileline> yP_ATAT "@@"
%token<fileline> yP_COLONCOLON "::"
%token<fileline> yP_COLONEQ ":="
%token<fileline> yP_COLONDIV ":/"
%token<fileline> yP_ORMINUSGT "|->"
%token<fileline> yP_OREQGT "|=>"
%token<fileline> yP_PLUSEQ "+="
%token<fileline> yP_MINUSEQ "-="
%token<fileline> yP_TIMESEQ "*="
%token<fileline> yP_DIVEQ "/="
%token<fileline> yP_MODEQ "%="
%token<fileline> yP_ANDEQ "&="
%token<fileline> yP_OREQ "|="
%token<fileline> yP_XOREQ "^="
%token<fileline> yP_SLEFTEQ "<<="
%token<fileline> yP_SRIGHTEQ ">>="
%token<fileline> yP_SSRIGHTEQ ">>>="
%token<fileline> yPSL_BRA "{" %token<fileline> yPSL_BRA "{"
%token<fileline> yPSL_KET "}" %token<fileline> yPSL_KET "}"
%token<fileline> yP_LOGIFF
%token<fileline> ';' '=' ',' '(' '.' '!' '~' '[' '@' %token<fileline> '!'
%token<fileline> '#'
%token<fileline> '%'
%token<fileline> '&'
%token<fileline> '('
%token<fileline> ')'
%token<fileline> '*'
%token<fileline> '+'
%token<fileline> ','
%token<fileline> '-'
%token<fileline> '.'
%token<fileline> '/'
%token<fileline> ':'
%token<fileline> ';'
%token<fileline> '<'
%token<fileline> '='
%token<fileline> '>'
%token<fileline> '?'
%token<fileline> '@'
%token<fileline> '['
%token<fileline> ']'
%token<fileline> '^'
%token<fileline> '{'
%token<fileline> '|'
%token<fileline> '}'
%token<fileline> '~'
// [* is not a operator, as "[ * ]" is legal
// [= and [-> could be repitition operators, but to match [* we don't add them.
// '( is not a operator, as "' (" is legal
// '{ could be an operator. More research needed.
//******************** //********************
// PSL op precedence // PSL op precedence
%right<fileline> yP_MINUSGT yP_LOGIFF /* MinusGT == -> == PSL LogIf operator */ %right yP_MINUSGT yP_LOGIFF
%right<fileline> yP_OR_MINUS_GT yP_OR_EQ_GT %right yP_ORMINUSGT yP_OREQGT
%left<fileline> prPSLCLK %left<fileline> prPSLCLK
// Verilog op precedence // Verilog op precedence
%left<fileline> ':' %left ':'
%left<fileline> '?' %left '?'
%left<fileline> yP_OROR %left yP_OROR
%left<fileline> yP_ANDAND %left yP_ANDAND
%left<fileline> '|' yP_NOR %left '|' yP_NOR
%left<fileline> '^' %left '^'
%left<fileline> yP_XNOR %left yP_XNOR
%left<fileline> '&' yP_NAND %left '&' yP_NAND
%left<fileline> yP_EQUAL yP_NOTEQUAL yP_CASEEQUAL yP_CASENOTEQUAL yP_WILDEQUAL yP_WILDNOTEQUAL %left yP_EQUAL yP_NOTEQUAL yP_CASEEQUAL yP_CASENOTEQUAL yP_WILDEQUAL yP_WILDNOTEQUAL
%left<fileline> '>' '<' yP_GTE yP_LTE %left '>' '<' yP_GTE yP_LTE
%left<fileline> yP_SLEFT yP_SRIGHT yP_SSRIGHT %left yP_SLEFT yP_SRIGHT yP_SSRIGHT
%left<fileline> '+' '-' %left '+' '-'
%left<fileline> '*' '/' '%' %left '*' '/' '%'
%left<fileline> yP_POW %left yP_POW
%left<fileline> '{' '}' %left '{' '}'
%left<fileline> prUNARYARITH %left<fileline> prUNARYARITH
%left<fileline> prREDUCTION %left<fileline> prREDUCTION
%left<fileline> prNEGATION %left<fileline> prNEGATION
%nonassoc prLOWER_THAN_ELSE %nonassoc prLOWER_THAN_ELSE
%nonassoc yELSE %nonassoc yELSE
@@ -289,11 +377,13 @@ class AstSenTree;
%type<modulep> modHdr %type<modulep> modHdr
%type<nodep> modPortsE portList port %type<nodep> modPortsE portList port
%type<nodep> portV2kArgs portV2kList portV2kSecond portV2kSig %type<nodep> portV2kArgs portV2kList portV2kSecond portV2kSig
%type<nodep> portV2kDecl ioDecl varDecl %type<nodep> portV2kDecl portDecl varDecl
%type<nodep> modParDecl modParList modParE %type<nodep> modParArgs modParSecond modParDecl modParList modParE
%type<nodep> modItem modItemList modItemListE modOrGenItem %type<nodep> modItem modItemList modItemListE modOrGenItem
%type<nodep> generateRegion
%type<nodep> genItem genItemList genItemBegin genItemBlock genTopBlock genCaseListE genCaseList %type<nodep> genItem genItemList genItemBegin genItemBlock genTopBlock genCaseListE genCaseList
%type<nodep> dlyTerm %type<nodep> dlyTerm
%type<fileline> delay
%type<varp> sigAndAttr sigId sigIdRange sigList regsig regsigList regSigId %type<varp> sigAndAttr sigId sigIdRange sigList regsig regsigList regSigId
%type<varp> netSig netSigList %type<varp> netSig netSigList
%type<rangep> rangeListE regrangeE anyrange rangeList delayrange portRangeE %type<rangep> rangeListE regrangeE anyrange rangeList delayrange portRangeE
@@ -303,8 +393,8 @@ class AstSenTree;
%type<cellp> instnameParen %type<cellp> instnameParen
%type<pinp> cellpinList cellpinItList cellpinItemE instparamListE %type<pinp> cellpinList cellpinItList cellpinItemE instparamListE
%type<nodep> defpList defpOne %type<nodep> defpList defpOne
%type<sentreep> sensitivity %type<sentreep> eventControl
%type<sentreep> sensitivityE %type<sentreep> eventControlE
%type<senitemp> senList senitem senitemEdge senitemVar %type<senitemp> senList senitem senitemEdge senitemVar
%type<nodep> stmtBlock stmtList stmt labeledStmt stateCaseForIf %type<nodep> stmtBlock stmtList stmt labeledStmt stateCaseForIf
%type<nodep> assertStmt %type<nodep> assertStmt
@@ -355,14 +445,19 @@ statePop: /* empty */ { V3Read::statePop(); }
//********************************************************************** //**********************************************************************
// Files // Files
file: mod { } file: description { }
| file mod { } | file description { }
;
// IEEE: description
description: moduleDecl { }
; ;
//********************************************************************** //**********************************************************************
// Module headers // Module headers
mod: modHdr modParE modPortsE ';' modItemListE yENDMODULE endLabelE // IEEE: module_declaration:
moduleDecl: modHdr modParE modPortsE ';' modItemListE yENDMODULE endLabelE
{ $1->modTrace(V3Parse::s_trace); // Stash for implicit wires, etc { $1->modTrace(V3Parse::s_trace); // Stash for implicit wires, etc
if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); } if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); }
; ;
@@ -375,12 +470,20 @@ modHdr: yMODULE { V3Parse::s_trace=v3Global.opt.trace();}
modParE: /* empty */ { $$ = NULL; } modParE: /* empty */ { $$ = NULL; }
| '#' '(' ')' { $$ = NULL; } | '#' '(' ')' { $$ = NULL; }
| '#' '(' modParList ')' { $$ = $3; } | '#' '(' modParArgs ')' { $$ = $3; }
| '#' '(' modParList ';' ')' { $$ = $3; }
; ;
modParList: modParDecl { $$ = $1; } modParArgs: modParDecl { $$ = $1; }
| modParList ';' modParDecl { $$ = $1->addNext($3); } | modParDecl ',' modParList { $$ = $1->addNext($3); }
;
modParList: modParSecond { $$ = $1; }
| modParList ',' modParSecond { $$ = $1->addNext($3); }
;
// Called only after a comma in a v2k list, to allow parsing "parameter a,b, parameter x"
modParSecond: modParDecl { $$ = $1; }
| param { $$ = $1; }
; ;
modPortsE: /* empty */ { $$ = NULL; } modPortsE: /* empty */ { $$ = NULL; }
@@ -423,24 +526,25 @@ regsigList: regsig { $$ = $1; }
| regsigList ',' regsig { $$ = $1;$1->addNext($3); } | regsigList ',' regsig { $$ = $1;$1->addNext($3); }
; ;
portV2kDecl: varRESET varInput varSignedE v2kNetDeclE regrangeE portV2kSig { $$ = $6; } portV2kDecl: varRESET varInput signingE v2kNetDeclE regrangeE portV2kSig { $$ = $6; }
| varRESET varInout varSignedE v2kNetDeclE regrangeE portV2kSig { $$ = $6; } | varRESET varInout signingE v2kNetDeclE regrangeE portV2kSig { $$ = $6; }
| varRESET varOutput varSignedE v2kVarDeclE regrangeE portV2kSig { $$ = $6; } | varRESET varOutput signingE v2kVarDeclE regrangeE portV2kSig { $$ = $6; }
; ;
ioDecl: varRESET varInput varSignedE v2kVarDeclE regrangeE sigList ';' { $$ = $6; } // IEEE: port_declaration - plus ';'
| varRESET varInout varSignedE v2kVarDeclE regrangeE sigList ';' { $$ = $6; } portDecl: varRESET varInput signingE v2kVarDeclE regrangeE sigList ';' { $$ = $6; }
| varRESET varOutput varSignedE v2kVarDeclE regrangeE sigList ';' { $$ = $6; } | varRESET varInout signingE v2kVarDeclE regrangeE sigList ';' { $$ = $6; }
| varRESET varOutput signingE v2kVarDeclE regrangeE sigList ';' { $$ = $6; }
; ;
varDecl: varRESET varReg varSignedE regrangeE regsigList ';' { $$ = $5; } varDecl: varRESET varReg signingE regrangeE regsigList ';' { $$ = $5; }
| varRESET varGParam varSignedE regrangeE paramList ';' { $$ = $5; } | varRESET varGParam signingE regrangeE paramList ';' { $$ = $5; }
| varRESET varLParam varSignedE regrangeE paramList ';' { $$ = $5; } | varRESET varLParam signingE regrangeE paramList ';' { $$ = $5; }
| varRESET varNet varSignedE delayrange netSigList ';' { $$ = $5; } | varRESET varNet signingE delayrange netSigList ';' { $$ = $5; }
| varRESET varGenVar varSignedE regsigList ';' { $$ = $4; } | varRESET varGenVar signingE regsigList ';' { $$ = $4; }
; ;
modParDecl: varRESET varGParam varSignedE regrangeE paramList { $$ = $5; } /* No semicolon*/ modParDecl: varRESET varGParam signingE regrangeE param { $$ = $5; }
; ;
varRESET: /* empty */ { VARRESET(); } varRESET: /* empty */ { VARRESET(); }
@@ -467,7 +571,8 @@ varOutput: yOUTPUT { VARIO(OUTPUT); }
varInout: yINOUT { VARIO(INOUT); } varInout: yINOUT { VARIO(INOUT); }
; ;
varSignedE: /*empty*/ { } // IEEE: signing - plus empty
signingE: /*empty*/ { }
| ySIGNED { VARSIGNED(true); } | ySIGNED { VARSIGNED(true); }
| yUNSIGNED { VARSIGNED(false); } | yUNSIGNED { VARSIGNED(false); }
; ;
@@ -492,7 +597,7 @@ modItemList: modItem { $$ = $1; }
; ;
modItem: modOrGenItem { $$ = $1; } modItem: modOrGenItem { $$ = $1; }
| yGENERATE genTopBlock yENDGENERATE { $$ = new AstGenerate($1, $2); } | generateRegion { $$ = $1; }
| yaSCHDR { $$ = new AstScHdr(CRELINE(),*$1); } | yaSCHDR { $$ = new AstScHdr(CRELINE(),*$1); }
| yaSCINT { $$ = new AstScInt(CRELINE(),*$1); } | yaSCINT { $$ = new AstScInt(CRELINE(),*$1); }
| yaSCIMP { $$ = new AstScImp(CRELINE(),*$1); } | yaSCIMP { $$ = new AstScImp(CRELINE(),*$1); }
@@ -508,7 +613,11 @@ modItem: modOrGenItem { $$ = $1; }
| ySPECIFY yENDSPECIFY { $$ = NULL; } | ySPECIFY yENDSPECIFY { $$ = NULL; }
; ;
modOrGenItem: yALWAYS sensitivityE stmtBlock { $$ = new AstAlways($1,$2,$3); } // IEEE: generate_region
generateRegion: yGENERATE genTopBlock yENDGENERATE { $$ = new AstGenerate($1, $2); }
;
modOrGenItem: yALWAYS eventControlE stmtBlock { $$ = new AstAlways($1,$2,$3); }
| yFINAL stmtBlock { $$ = new AstFinal($1,$2); } | yFINAL stmtBlock { $$ = new AstFinal($1,$2); }
| yINITIAL stmtBlock { $$ = new AstInitial($1,$2); } | yINITIAL stmtBlock { $$ = new AstInitial($1,$2); }
| yASSIGN delayE assignList ';' { $$ = $3; } | yASSIGN delayE assignList ';' { $$ = $3; }
@@ -517,7 +626,7 @@ modOrGenItem: yALWAYS sensitivityE stmtBlock { $$ = new AstAlways($1,$2,$3); }
| taskDecl { $$ = $1; } | taskDecl { $$ = $1; }
| funcDecl { $$ = $1; } | funcDecl { $$ = $1; }
| gateDecl { $$ = $1; } | gateDecl { $$ = $1; }
| ioDecl { $$ = $1; } | portDecl { $$ = $1; }
| varDecl { $$ = $1; } | varDecl { $$ = $1; }
//No: | tableDecl // Unsupported //No: | tableDecl // Unsupported
| pslStmt { $$ = $1; } | pslStmt { $$ = $1; }
@@ -582,10 +691,10 @@ delayE: /* empty */ { }
| delay { } /* ignored */ | delay { } /* ignored */
; ;
delay: '#' dlyTerm { } /* ignored */ delay: '#' dlyTerm { $$ = $1; } /* ignored */
| '#' '(' dlyInParen ')' { } /* ignored */ | '#' '(' dlyInParen ')' { $$ = $1; } /* ignored */
| '#' '(' dlyInParen ',' dlyInParen ')' { } /* ignored */ | '#' '(' dlyInParen ',' dlyInParen ')' { $$ = $1; } /* ignored */
| '#' '(' dlyInParen ',' dlyInParen ',' dlyInParen ')' { } /* ignored */ | '#' '(' dlyInParen ',' dlyInParen ',' dlyInParen ')' { $$ = $1; } /* ignored */
; ;
dlyTerm: yaID { $$ = NULL; } dlyTerm: yaID { $$ = NULL; }
@@ -676,6 +785,7 @@ paramList: param { $$ = $1; }
| paramList ',' param { $$ = $1; $1->addNext($3); } | paramList ',' param { $$ = $1; $1->addNext($3); }
; ;
// IEEE: list_of_defparam_assignments
defpList: defpOne { $$ = $1; } defpList: defpOne { $$ = $1; }
| defpList ',' defpOne { $$ = $1->addNext($3); } | defpList ',' defpOne { $$ = $1->addNext($3); }
; ;
@@ -712,7 +822,7 @@ cellpinItList: cellpinItemE { $$ = $1; }
; ;
cellpinItemE: /* empty: ',,' is legal */ { $$ = NULL; V3Parse::s_pinNum++; } cellpinItemE: /* empty: ',,' is legal */ { $$ = NULL; V3Parse::s_pinNum++; }
| '.' '*' { $$ = NULL; if (V3Parse::s_pinStar) $1->v3error("Duplicate .* in a cell"); V3Parse::s_pinStar=true; } | yP_DOTSTAR { $$ = NULL; if (V3Parse::s_pinStar) $1->v3error("Duplicate .* in a cell"); V3Parse::s_pinStar=true; }
| '.' yaID { $$ = new AstPin($1,V3Parse::s_pinNum++,*$2,new AstVarRef($1,*$2,false)); $$->svImplicit(true);} | '.' yaID { $$ = new AstPin($1,V3Parse::s_pinNum++,*$2,new AstVarRef($1,*$2,false)); $$->svImplicit(true);}
| '.' yaID '(' ')' { $$ = NULL; V3Parse::s_pinNum++; } | '.' yaID '(' ')' { $$ = NULL; V3Parse::s_pinNum++; }
| '.' yaID '(' expr ')' { $$ = new AstPin($1,V3Parse::s_pinNum++,*$2,$4); } | '.' yaID '(' expr ')' { $$ = new AstPin($1,V3Parse::s_pinNum++,*$2,$4); }
@@ -720,19 +830,19 @@ cellpinItemE: /* empty: ',,' is legal */ { $$ = NULL; V3Parse::s_pinNum++; }
; ;
//************************************************ //************************************************
// Sensitivity lists // EventControl lists
sensitivityE: /* empty */ { $$ = NULL; } eventControlE: /* empty */ { $$ = NULL; }
| sensitivity { $$ = $1; } | eventControl { $$ = $1; }
//IEEE: event_control // IEEE: event_control
sensitivity: '@' '(' senList ')' { $$ = new AstSenTree($1,$3); } eventControl: '@' '(' senList ')' { $$ = new AstSenTree($1,$3); }
| '@' senitemVar { $$ = new AstSenTree($1,$2); } /* For events only */ | '@' senitemVar { $$ = new AstSenTree($1,$2); } /* For events only */
| '@' '(' '*' ')' { $$ = NULL; $2->v3error("Use @*. always @ (*) to be depreciated in Verilog 2005.\n"); } | '@' '(' '*' ')' { $$ = NULL; $2->v3error("Use @*. always @ (*) to be depreciated in Verilog 2005.\n"); }
| '@' '*' { $$ = NULL; } /* Verilog 2001 */ | '@' '*' { $$ = NULL; } /* Verilog 2001 */
; ;
//IEEE: event_expression - split over several // IEEE: event_expression - split over several
senList: senitem { $$ = $1; } senList: senitem { $$ = $1; }
| senList yOR senitem { $$ = $1;$1->addNext($3); } | senList yOR senitem { $$ = $1;$1->addNext($3); }
| senList ',' senitem { $$ = $1;$1->addNext($3); } /* Verilog 2001 */ | senList ',' senitem { $$ = $1;$1->addNext($3); } /* Verilog 2001 */
@@ -771,6 +881,8 @@ stmt: ';' { $$ = NULL; }
| labeledStmt { $$ = $1; } | labeledStmt { $$ = $1; }
| yaID ':' labeledStmt { $$ = new AstBegin($2, *$1, $3); } /*S05 block creation rule*/ | yaID ':' labeledStmt { $$ = new AstBegin($2, *$1, $3); } /*S05 block creation rule*/
| delay stmtBlock { $$ = $2; $1->v3warn(STMTDLY,"Ignoring delay on this delayed statement.\n"); }
| varRefDotBit yP_LTE delayE expr ';' { $$ = new AstAssignDly($2,$1,$4); } | varRefDotBit yP_LTE delayE expr ';' { $$ = new AstAssignDly($2,$1,$4); }
| varRefDotBit '=' delayE expr ';' { $$ = new AstAssign($2,$1,$4); } | varRefDotBit '=' delayE expr ';' { $$ = new AstAssign($2,$1,$4); }
| varRefDotBit '=' yD_FOPEN '(' expr ',' expr ')' ';' { $$ = new AstFOpen($3,$1,$5,$7); } | varRefDotBit '=' yD_FOPEN '(' expr ',' expr ')' ';' { $$ = new AstFOpen($3,$1,$5,$7); }
@@ -779,26 +891,26 @@ stmt: ';' { $$ = NULL; }
| '{' concIdList '}' '=' delayE expr ';' { $$ = new AstAssign($4,$2,$6); } | '{' concIdList '}' '=' delayE expr ';' { $$ = new AstAssign($4,$2,$6); }
| yD_C '(' cStrList ')' ';' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); } | yD_C '(' cStrList ')' ';' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); }
| yD_FCLOSE '(' varRefDotBit ')' ';' { $$ = new AstFClose($1, $3); } | yD_FCLOSE '(' varRefDotBit ')' ';' { $$ = new AstFClose($1, $3); }
| yD_FINISH ';' { $$ = new AstFinish($1); } | yD_FINISH parenE ';' { $$ = new AstFinish($1); }
| yD_STOP ';' { $$ = new AstStop($1); } | yD_STOP parenE ';' { $$ = new AstStop($1); }
| yVL_COVER_OFF { $$ = new AstPragma($1,AstPragmaType::COVERAGE_BLOCK_OFF); } | yVL_COVER_OFF { $$ = new AstPragma($1,AstPragmaType::COVERAGE_BLOCK_OFF); }
| stateCaseForIf { $$ = $1; } | stateCaseForIf { $$ = $1; }
| taskRef ';' { $$ = $1; } | taskRef ';' { $$ = $1; }
| yD_DISPLAY ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,"", NULL,NULL); } | yD_DISPLAY parenE ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,"", NULL,NULL); }
| yD_DISPLAY '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,*$3,NULL,$4); } | yD_DISPLAY '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,*$3,NULL,$4); }
| yD_WRITE '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::WRITE, *$3,NULL,$4); } | yD_WRITE '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::WRITE, *$3,NULL,$4); }
| yD_FDISPLAY '(' varRefDotBit ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,*$5,$3,$6); } | yD_FDISPLAY '(' varRefDotBit ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,*$5,$3,$6); }
| yD_FWRITE '(' varRefDotBit ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::WRITE, *$5,$3,$6); } | yD_FWRITE '(' varRefDotBit ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::WRITE, *$5,$3,$6); }
| yD_INFO ';' { $$ = new AstDisplay($1,AstDisplayType::INFO, "", NULL,NULL); } | yD_INFO parenE ';' { $$ = new AstDisplay($1,AstDisplayType::INFO, "", NULL,NULL); }
| yD_INFO '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::INFO, *$3,NULL,$4); } | yD_INFO '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::INFO, *$3,NULL,$4); }
| yD_WARNING ';' { $$ = new AstDisplay($1,AstDisplayType::WARNING,"", NULL,NULL); } | yD_WARNING parenE ';' { $$ = new AstDisplay($1,AstDisplayType::WARNING,"", NULL,NULL); }
| yD_WARNING '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::WARNING,*$3,NULL,$4); } | yD_WARNING '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::WARNING,*$3,NULL,$4); }
| yD_ERROR ';' { $$ = V3Parse::createDisplayError($1); } | yD_ERROR parenE ';' { $$ = V3Parse::createDisplayError($1); }
| yD_ERROR '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::ERROR, *$3,NULL,$4); $$->addNext(new AstStop($1)); } | yD_ERROR '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::ERROR, *$3,NULL,$4); $$->addNext(new AstStop($1)); }
| yD_FATAL ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); } | yD_FATAL parenE ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); }
| yD_FATAL '(' expr ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); } | yD_FATAL '(' expr ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); if ($3) $3->deleteTree(); }
| yD_FATAL '(' expr ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, *$5,NULL,$6); $$->addNext(new AstStop($1)); } | yD_FATAL '(' expr ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, *$5,NULL,$6); $$->addNext(new AstStop($1)); if ($3) $3->deleteTree(); }
| yD_READMEMB '(' expr ',' varRefMem ')' ';' { $$ = new AstReadMem($1,false,$3,$5,NULL,NULL); } | yD_READMEMB '(' expr ',' varRefMem ')' ';' { $$ = new AstReadMem($1,false,$3,$5,NULL,NULL); }
| yD_READMEMB '(' expr ',' varRefMem ',' expr ')' ';' { $$ = new AstReadMem($1,false,$3,$5,$7,NULL); } | yD_READMEMB '(' expr ',' varRefMem ',' expr ')' ';' { $$ = new AstReadMem($1,false,$3,$5,$7,NULL); }
@@ -858,17 +970,19 @@ taskRef: idDotted { $$ = new AstTaskRef(CRELINE(),new AstParseRef($1->fileli
funcRef: idDotted '(' exprList ')' { $$ = new AstFuncRef($2,new AstParseRef($1->fileline(), AstParseRefExp::FUNC, $1), $3); } funcRef: idDotted '(' exprList ')' { $$ = new AstFuncRef($2,new AstParseRef($1->fileline(), AstParseRefExp::FUNC, $1), $3); }
; ;
taskDecl: yTASK taskAutoE yaID funcGuts yENDTASK endLabelE taskDecl: yTASK lifetimeE yaID funcGuts yENDTASK endLabelE
{ $$ = new AstTask ($1,*$3,$4);} { $$ = new AstTask ($1,*$3,$4);}
; ;
funcDecl: yFUNCTION taskAutoE funcTypeE yaID funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$5,$3); } funcDecl: yFUNCTION lifetimeE funcTypeE yaID funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$5,$3); }
| yFUNCTION taskAutoE ySIGNED funcTypeE yaID funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$5,$6,$4); $$->isSigned(true); } | yFUNCTION lifetimeE ySIGNED funcTypeE yaID funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$5,$6,$4); $$->isSigned(true); }
| yFUNCTION taskAutoE funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$6,$3); $$->attrIsolateAssign(true);} | yFUNCTION lifetimeE funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$6,$3); $$->attrIsolateAssign(true);}
| yFUNCTION taskAutoE ySIGNED funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$5,$7,$4); $$->attrIsolateAssign(true); $$->isSigned(true); } | yFUNCTION lifetimeE ySIGNED funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$5,$7,$4); $$->attrIsolateAssign(true); $$->isSigned(true); }
; ;
taskAutoE: /* empty */ { } // IEEE: lifetime - plus empty
lifetimeE: /* empty */ { }
| ySTATIC { $1->v3error("Unsupported: Static in this context\n"); }
| yAUTOMATIC { } | yAUTOMATIC { }
; ;
@@ -889,12 +1003,16 @@ funcVarList: funcVar { $$ = $1; }
| funcVarList funcVar { $$ = $1;$1->addNext($2); } | funcVarList funcVar { $$ = $1;$1->addNext($2); }
; ;
funcVar: ioDecl { $$ = $1; } funcVar: portDecl { $$ = $1; }
| varDecl { $$ = $1; } | varDecl { $$ = $1; }
| yVL_PUBLIC { $$ = new AstPragma($1,AstPragmaType::PUBLIC_TASK); } | yVL_PUBLIC { $$ = new AstPragma($1,AstPragmaType::PUBLIC_TASK); }
| yVL_NO_INLINE_TASK { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_TASK); } | yVL_NO_INLINE_TASK { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_TASK); }
; ;
parenE: /* empty */ { }
| '(' ')' { }
;
//************************************************ //************************************************
// Expressions // Expressions
@@ -1096,6 +1214,7 @@ specifyJunk: dlyTerm {} /* ignored */
| '[' {} | ']' {} | '[' {} | ']' {}
| '|' {} | '|' {}
| '~' {} | '~' {}
| '@' {}
| yIF {} | yIF {}
| yNEGEDGE {} | yNEGEDGE {}
@@ -1118,8 +1237,24 @@ specifyJunk: dlyTerm {} /* ignored */
| yP_LOGIFF {} | yP_LOGIFF {}
| yPSL_BRA {} | yPSL_BRA {}
| yPSL_KET {} | yPSL_KET {}
| yP_OR_MINUS_GT {} | yP_ORMINUSGT {}
| yP_OR_EQ_GT {} | yP_OREQGT {}
| yP_EQGT {} | yP_ASTGT {}
| yP_ANDANDAND {}
| yP_MINUSGTGT {}
| yP_POUNDPOUND {}
| yP_DOTSTAR {}
| yP_ATAT {}
| yP_COLONCOLON {}
| yP_COLONEQ {}
| yP_COLONDIV {}
| yP_PLUSEQ {} | yP_MINUSEQ {}
| yP_TIMESEQ {}
| yP_DIVEQ {} | yP_MODEQ {}
| yP_ANDEQ {} | yP_OREQ {}
| yP_XOREQ {}
| yP_SLEFTEQ {} | yP_SRIGHTEQ {} | yP_SSRIGHTEQ {}
| error {} | error {}
; ;
@@ -1231,11 +1366,16 @@ pslExpr: exprPsl { $$ = new AstPslBool($1->fileline(), $1); }
//********************************************************************** //**********************************************************************
%% %%
void V3Read::parserClear() {
// Clear up any dynamic memory V3Parser required
V3Parse::setRange(NULL);
}
AstNode* V3Parse::createSupplyExpr(FileLine* fileline, string name, int value) { AstNode* V3Parse::createSupplyExpr(FileLine* fileline, string name, int value) {
FileLine* newfl = new FileLine (fileline); FileLine* newfl = new FileLine (fileline);
newfl->warnOff(V3ErrorCode::WIDTH, true); newfl->warnOff(V3ErrorCode::WIDTH, true);
AstNode* nodep = new AstConst(newfl, V3Number(fileline)); AstNode* nodep = new AstConst(newfl, V3Number(fileline));
// Adding a NOT is less work then figuring out how wide to make it // Adding a NOT is less work than figuring out how wide to make it
if (value) nodep = new AstNot(newfl, nodep); if (value) nodep = new AstNot(newfl, nodep);
nodep = new AstAssignW(newfl, new AstVarRef(fileline, name, true), nodep = new AstAssignW(newfl, new AstVarRef(fileline, name, true),
nodep); nodep);
@@ -1245,6 +1385,7 @@ AstNode* V3Parse::createSupplyExpr(FileLine* fileline, string name, int value) {
AstVar* V3Parse::createVariable(FileLine* fileline, string name, AstRange* arrayp) { AstVar* V3Parse::createVariable(FileLine* fileline, string name, AstRange* arrayp) {
AstVarType type = V3Parse::s_varIO; AstVarType type = V3Parse::s_varIO;
AstRange* rangep = V3Parse::s_varRangep; AstRange* rangep = V3Parse::s_varRangep;
AstRange* cleanup_rangep = NULL;
//UINFO(0,"CREVAR "<<fileline->ascii()<<" decl="<<V3Parse::s_varDecl.ascii()<<" io="<<V3Parse::s_varIO.ascii()<<endl); //UINFO(0,"CREVAR "<<fileline->ascii()<<" decl="<<V3Parse::s_varDecl.ascii()<<" io="<<V3Parse::s_varIO.ascii()<<endl);
if (type == AstVarType::UNKNOWN) type = V3Parse::s_varDecl; if (type == AstVarType::UNKNOWN) type = V3Parse::s_varDecl;
if (type == AstVarType::UNKNOWN) fileline->v3fatalSrc("Unknown signal type declared"); if (type == AstVarType::UNKNOWN) fileline->v3fatalSrc("Unknown signal type declared");
@@ -1252,7 +1393,8 @@ AstVar* V3Parse::createVariable(FileLine* fileline, string name, AstRange* array
if (type == AstVarType::INTEGER || V3Parse::s_varDecl == AstVarType::INTEGER if (type == AstVarType::INTEGER || V3Parse::s_varDecl == AstVarType::INTEGER
|| type == AstVarType::GENVAR) { || type == AstVarType::GENVAR) {
if (rangep) fileline->v3error("Integers may not be ranged: "<<name); if (rangep) fileline->v3error("Integers may not be ranged: "<<name);
rangep = new AstRange(fileline, 31, 0); // Integer == REG[31:0] cleanup_rangep = new AstRange(fileline, 31, 0); // Integer == REG[31:0]
rangep = cleanup_rangep;
} }
if (type == AstVarType::GENVAR) { if (type == AstVarType::GENVAR) {
if (arrayp) fileline->v3error("Genvars may not be arrayed: "<<name); if (arrayp) fileline->v3error("Genvars may not be arrayed: "<<name);
@@ -1280,6 +1422,7 @@ AstVar* V3Parse::createVariable(FileLine* fileline, string name, AstRange* array
// Remember the last variable created, so we can attach attributes to it in later parsing // Remember the last variable created, so we can attach attributes to it in later parsing
V3Parse::s_varAttrp = nodep; V3Parse::s_varAttrp = nodep;
if (cleanup_rangep) { cleanup_rangep->deleteTree(); cleanup_rangep=NULL; }
return nodep; return nodep;
} }
+25
View File
@@ -560,6 +560,18 @@ sub _make_main {
print $fh " topp->eval();\n"; print $fh " topp->eval();\n";
$set = "topp->"; $set = "topp->";
} }
my $traceit = ($self->{trace} && !$self->{sp} && !$self->{sc});
if ($traceit) {
$fh->print("\n");
$fh->print("#if VM_TRACE\n");
$fh->print(" Verilated::traceEverOn(true);\n");
$fh->print(" SpTraceVcdCFile* tfp = new SpTraceVcdCFile;\n");
$fh->print(" topp->trace (tfp, 99);\n");
$fh->print(" tfp->open (\"obj_dir/".$self->{name}."_simx.vcd\");\n");
$fh->print("#endif\n");
}
print $fh " ${set}fastclk = true;\n" if $self->{inputs}{fastclk}; print $fh " ${set}fastclk = true;\n" if $self->{inputs}{fastclk};
print $fh " ${set}clk = true;\n" if $self->{inputs}{clk}; print $fh " ${set}clk = true;\n" if $self->{inputs}{clk};
print $fh " while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {\n"; print $fh " while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {\n";
@@ -578,6 +590,11 @@ sub _make_main {
} else { } else {
print $fh " main_time+=1;\n"; print $fh " main_time+=1;\n";
print $fh " ${set}eval();\n" if $action; print $fh " ${set}eval();\n" if $action;
if ($traceit) {
$fh->print("#if VM_TRACE\n");
$fh->print(" tfp->dump (main_time);\n");
$fh->print("#endif //VM_TRACE\n");
}
} }
} }
print $fh " }\n"; print $fh " }\n";
@@ -586,6 +603,14 @@ sub _make_main {
print $fh " }\n"; print $fh " }\n";
print $fh " topp->final();\n"; print $fh " topp->final();\n";
print $fh " SpCoverage::write(\"",$self->{coverage_filename},"\");\n" if $self->{coverage}; print $fh " SpCoverage::write(\"",$self->{coverage_filename},"\");\n" if $self->{coverage};
if ($traceit) {
$fh->print("#if VM_TRACE\n");
$fh->print(" tfp->close();\n");
$fh->print("#endif //VM_TRACE\n");
}
$fh->print("\n");
print $fh " delete topp; topp=NULL;\n"; print $fh " delete topp; topp=NULL;\n";
print $fh " exit(0L);\n"; print $fh " exit(0L);\n";
print $fh "}\n"; print $fh "}\n";
+2 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/perl #!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; } if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id:$ # $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition # DESCRIPTION: Verilator: Verilog Test driver/expect definition
# #
# Copyright 2003 by Wilson Snyder. This program is free software; you can # Copyright 2003 by Wilson Snyder. This program is free software; you can
@@ -8,6 +8,7 @@ if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# General Public License or the Perl Artistic License. # General Public License or the Perl Artistic License.
compile ( compile (
v_flags2 => [$Last_Self->{v3}?'-Wno-STMTDLY':''],
); );
execute ( execute (
+2 -2
View File
@@ -1,4 +1,4 @@
// $Id:$ // $Id$
// DESCRIPTION: Verilator: Verilog Test module // DESCRIPTION: Verilator: Verilog Test module
// //
// This file ONLY is placed into the Public Domain, for any use, // This file ONLY is placed into the Public Domain, for any use,
@@ -30,7 +30,7 @@ module t (/*AUTOARG*/
else if (cyc==3) begin else if (cyc==3) begin
if (dly0 !== 32'h23) $stop; if (dly0 !== 32'h23) $stop;
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");
$finish; #100 $finish;
end end
end end
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
top_filename("t/t_delay.v");
compile (
fails=>1,
expect=>
'%Warning-STMTDLY: t/t_delay.v:\d+: Ignoring delay on this delayed statement.
.*%Error: Exiting due to.*',
) if $Last_Self->{v3};
ok(1);
1;
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
compile (
v_flags2 => [$Last_Self->{v3}?'--Ox':''],
);
execute (
check_finished=>1,
);
ok(1);
1;
+70
View File
@@ -0,0 +1,70 @@
// $Id$
// DESCRIPTION: Verilator: Verilog Test module
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc=0;
reg [63:0] crc;
reg [63:0] sum;
reg [2*32-1:0] w2; initial w2 = {2 {32'h12345678}};
reg [9*32-1:0] w9; initial w9 = {9 {32'h12345678}};
reg [10*32-1:0] w10; initial w10 = {10{32'h12345678}};
reg [11*32-1:0] w11; initial w11 = {11{32'h12345678}};
reg [15*32-1:0] w15; initial w15 = {15{32'h12345678}};
reg [31*32-1:0] w31; initial w31 = {31{32'h12345678}};
reg [47*32-1:0] w47; initial w47 = {47{32'h12345678}};
reg [63*32-1:0] w63; initial w63 = {63{32'h12345678}};
// Aggregate outputs into a single result vector
wire [63:0] result = (w2[63:0]
^ w9[64:1]
^ w10[65:2]
^ w11[66:3]
^ w15[67:4]
^ w31[68:5]
^ w47[69:6]
^ w63[70:7]);
// What checksum will we end up with
`define EXPECTED_SUM 64'h184cb39122d8c6e3
// Test loop
always @ (posedge clk) begin
`ifdef TEST_VERBOSE
$write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result);
`endif
cyc <= cyc + 1;
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
if (cyc==0) begin
// Setup
crc <= 64'h5aef0c8d_d70a4497;
end
else if (cyc<10) begin
sum <= 64'h0;
end
else if (cyc<90) begin
w2 <= w2 >> 1;
w9 <= w9 >> 1;
w10 <= w10 >> 1;
w11 <= w11 >> 1;
w15 <= w15 >> 1;
w31 <= w31 >> 1;
w47 <= w47 >> 1;
w63 <= w63 >> 1;
end
else if (cyc==99) begin
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
if (crc !== 64'hc77bb9b3784ea091) $stop;
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
+21 -1
View File
@@ -13,9 +13,9 @@ module t (/*AUTOARG*/
integer cyc; initial cyc=1; integer cyc; initial cyc=1;
integer j; integer j;
integer hit_count;
reg [63:0] cam_lookup_hit_vector; reg [63:0] cam_lookup_hit_vector;
integer hit_count;
always @(/*AUTOSENSE*/cam_lookup_hit_vector) begin always @(/*AUTOSENSE*/cam_lookup_hit_vector) begin
hit_count = 0; hit_count = 0;
for (j=0; j < 64; j=j+1) begin for (j=0; j < 64; j=j+1) begin
@@ -23,6 +23,22 @@ module t (/*AUTOARG*/
end end
end end
integer hit_count2;
always @(/*AUTOSENSE*/cam_lookup_hit_vector) begin
hit_count2 = 0;
for (j=63; j >= 0; j=j-1) begin
hit_count2 = hit_count2 + {31'h0, cam_lookup_hit_vector[j]};
end
end
integer hit_count3;
always @(/*AUTOSENSE*/cam_lookup_hit_vector) begin
hit_count3 = 0;
for (j=63; j > 0; j=j-1) begin
if (cam_lookup_hit_vector[j]) hit_count3 = hit_count3 + 32'd1;
end
end
reg [127:0] wide_for_index; reg [127:0] wide_for_index;
reg [31:0] wide_for_count; reg [31:0] wide_for_count;
always @(/*AUTOSENSE*/cam_lookup_hit_vector) begin always @(/*AUTOSENSE*/cam_lookup_hit_vector) begin
@@ -64,10 +80,14 @@ module t (/*AUTOARG*/
end end
if (cyc==2) begin if (cyc==2) begin
if (hit_count != 32'd2) $stop; if (hit_count != 32'd2) $stop;
if (hit_count2 != 32'd2) $stop;
if (hit_count3 != 32'd2) $stop;
cam_lookup_hit_vector <= 64'h01010010_00010001; cam_lookup_hit_vector <= 64'h01010010_00010001;
end end
if (cyc==3) begin if (cyc==3) begin
if (hit_count != 32'd5) $stop; if (hit_count != 32'd5) $stop;
if (hit_count2 != 32'd5) $stop;
if (hit_count3 != 32'd4) $stop;
if (wide_for_count != 32'h80) $stop; if (wide_for_count != 32'h80) $stop;
end end
if (cyc==9) begin if (cyc==9) begin
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+48
View File
@@ -0,0 +1,48 @@
// $Id$
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2007 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc=0;
Testit testit (/*AUTOINST*/
// Inputs
.clk (clk));
always @ (posedge clk) begin
cyc <= cyc + 1;
if (cyc==0) begin
end
else if (cyc<10) begin
end
else if (cyc<90) begin
end
else if (cyc==99) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module Testit (clk);
input clk;
genvar igen;
generate
for (igen=0; igen<0; igen=igen+1) begin : test_gen
always @ (posedge clk) begin
$display("igen1 = %d", igen);
$stop;
end
end
endgenerate
endmodule
+2
View File
@@ -85,6 +85,8 @@ module t (/*AUTOARG*/
if (qq !== {61{1'bx}}) $stop; if (qq !== {61{1'bx}}) $stop;
if (rq !== {61{1'bx}}) $stop; if (rq !== {61{1'bx}}) $stop;
`endif `endif
if ({16{1'bx}} !== 16'd1/16'd0) $stop; // No div by zero errors
if ({16{1'bx}} !== 16'd1%16'd0) $stop; // No div by zero errors
end end
if (cyc==19) begin if (cyc==19) begin
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");
+11
View File
@@ -263,6 +263,17 @@ module t (/*AUTOARG*/
//============================================================ //============================================================
reg signed [ 5:0] W123_is_3f ; //=3F
always @(posedge clk) begin
W123_is_3f <= 6'sh3f;
end
always @(posedge clk) begin
if (((~ ((32'sh088d1bcb) <<< W123_is_3f)) >>> 6'sh3f) != 32'shffffffff) if (check) $stop;
end
//============================================================
always @ (posedge clk) begin always @ (posedge clk) begin
if (cyc!=0) begin if (cyc!=0) begin
cyc <= cyc + 1; cyc <= cyc + 1;
+9 -13
View File
@@ -1,4 +1,4 @@
// $Id:$ // $Id$
// DESCRIPTION: Verilator: Verilog Test module // DESCRIPTION: Verilator: Verilog Test module
// //
// This file ONLY is placed into the Public Domain, for any use, // This file ONLY is placed into the Public Domain, for any use,
@@ -11,7 +11,10 @@ module t (/*AUTOARG*/
parameter PAR = 3; parameter PAR = 3;
input clk; input clk;
`ifdef verilator
// Else it becomes a localparam, per IEEE 4.10.1, but we don't check it
defparam m3.FROMDEFP = 19; defparam m3.FROMDEFP = 19;
`endif
m3 #(.P3(PAR), m3 #(.P3(PAR),
.P2(2)) .P2(2))
@@ -29,14 +32,12 @@ module t (/*AUTOARG*/
endmodule endmodule
module m3 module m3
`ifdef verilator
#( #(
parameter UNCH = 99; parameter UNCH = 99,
parameter P1 = 10; parameter P1 = 10,
parameter P2 = 20, parameter P2 = 20,
P3 = 30; P3 = 30
) )
`endif
(/*AUTOARG*/ (/*AUTOARG*/
// Inputs // Inputs
clk clk
@@ -44,13 +45,6 @@ module m3
input clk; input clk;
localparam LOC = 13; localparam LOC = 13;
`ifndef verilator // Vcs not compliant yet
parameter UNCH = 99;
parameter P1 = 10;
parameter P2 = 20;
parameter P3 = 30;
`endif
parameter FROMDEFP = 11; parameter FROMDEFP = 11;
initial begin initial begin
@@ -61,6 +55,8 @@ module m3
if (P1 !== 10) $stop; if (P1 !== 10) $stop;
if (P2 !== 2) $stop; if (P2 !== 2) $stop;
if (P3 !== 3) $stop; if (P3 !== 3) $stop;
`ifdef verilator
if (FROMDEFP !== 19) $stop; if (FROMDEFP !== 19) $stop;
`endif
end end
endmodule endmodule
+1
View File
@@ -18,6 +18,7 @@ execute (
if ($Last_Self->{v3}) { if ($Last_Self->{v3}) {
file_grep ("obj_dir/Vt_trace_ena__Trace__Slow.cpp", qr/c_trace_on\"/x); file_grep ("obj_dir/Vt_trace_ena__Trace__Slow.cpp", qr/c_trace_on\"/x);
file_grep_not ("obj_dir/Vt_trace_ena__Trace__Slow.cpp", qr/_trace_off\"/x); file_grep_not ("obj_dir/Vt_trace_ena__Trace__Slow.cpp", qr/_trace_off\"/x);
file_grep ("obj_dir/t_trace_ena_simx.vcd", qr/\$enddefinitions/x);
} }
ok(1); ok(1);
+1 -1
View File
@@ -58,7 +58,7 @@ module t_arith(/*AUTOARG*/
if (( 1'b0 ? 3'h3 : 1'b0 ? 3'h2 : 1'b1 ? 3'h1 : 3'h0) !== 3'h1) $stop; if (( 1'b0 ? 3'h3 : 1'b0 ? 3'h2 : 1'b1 ? 3'h1 : 3'h0) !== 3'h1) $stop;
// verilator lint_off WIDTH // verilator lint_off WIDTH
// surefire lint_off CNDWID // surefire lint_off CNDWID
if (( 8'h10 + 1'b0 ? 8'he : 8'hf) !== 8'he) $stop; // + is higher then ? if (( 8'h10 + 1'b0 ? 8'he : 8'hf) !== 8'he) $stop; // + is higher than ?
// surefire lint_on CNDWID // surefire lint_on CNDWID
// verilator lint_on WIDTH // verilator lint_on WIDTH