[Pkg-electronics-commits] [verilator] 02/06: Imported Upstream version 3.864

أحمد المحمودي (Ahmed El-Mahmoudy) aelmahmoudy at sabily.org
Sun Sep 28 11:57:57 UTC 2014


This is an automated email from the git hooks/post-receive script.

aelmahmoudy-guest pushed a commit to branch master
in repository verilator.

commit 4aad86fc4cae1f1c03145475bbbcf2f83566dc1f
Author: أحمد المحمودي (Ahmed El-Mahmoudy) <aelmahmoudy at sabily.org>
Date:   Sun Sep 28 11:55:18 2014 +0200

    Imported Upstream version 3.864
---
 Changes                                            |  25 +
 README.pdf                                         | Bin 112696 -> 112602 bytes
 bin/verilator                                      |  10 +-
 bin/verilator_profcfunc                            |  16 +-
 configure                                          |  86 ++-
 configure.ac                                       |   6 +-
 include/verilated.cpp                              |   3 +
 include/verilated.mk.in                            |   5 +-
 include/verilated_config.h                         |   2 +-
 include/verilated_vcd_c.cpp                        |   2 +-
 include/verilated_vpi.h                            |  22 +-
 internals.pdf                                      | Bin 197981 -> 197894 bytes
 src/V3Assert.cpp                                   |   9 +-
 src/V3Ast.h                                        |  70 ++-
 src/V3AstNodes.cpp                                 |  18 +
 src/V3AstNodes.h                                   | 656 +++++++++++++--------
 src/V3EmitC.cpp                                    |   6 +-
 src/V3EmitV.cpp                                    |   3 +-
 src/V3Expand.cpp                                   |   6 +-
 src/V3File.cpp                                     |   2 +-
 src/V3GraphDfa.h                                   |   1 +
 src/V3Inline.cpp                                   |   4 +
 src/V3Number.h                                     |   2 +-
 src/V3Param.cpp                                    |   3 +-
 src/V3Premit.cpp                                   |  67 ++-
 src/V3Scope.cpp                                    |   4 +
 src/V3Split.cpp                                    |   1 -
 src/V3TraceDecl.cpp                                |   1 -
 src/V3Width.cpp                                    |  15 +-
 src/config_build.h                                 |   2 +-
 src/config_rev.h                                   |   2 +-
 src/verilog.y                                      |  33 +-
 test_regress/driver.pl                             |   2 +-
 test_regress/t/t_EXAMPLE.v                         |   4 +-
 test_regress/t/t_assert_basic.v                    |   2 +-
 test_regress/t/t_case_huge.pl                      |  10 +-
 test_regress/t/t_case_huge_prof.pl                 |  44 ++
 test_regress/t/t_dpi_context.v                     |  14 +
 test_regress/t/t_dpi_context_c.cpp                 |   7 +
 test_regress/t/t_flag_ldflags.pl                   |   6 +-
 test_regress/t/t_math_real.v                       |   2 +
 test_regress/t/t_math_trig.v                       |   2 +
 test_regress/t/t_param.v                           |   4 +-
 .../t/{t_case_huge.pl => t_struct_anon.pl}         |  16 +-
 test_regress/t/t_struct_anon.v                     |  26 +
 .../t/{t_case_huge.pl => t_struct_unaligned.pl}    |  15 +-
 test_regress/t/t_struct_unaligned.v                |  35 ++
 .../t/{t_case_huge.pl => t_trace_param.pl}         |  17 +-
 test_regress/t/t_trace_param.v                     |  36 ++
 .../t/{t_case_huge.pl => t_var_assign_landr.pl}    |  12 +-
 .../t/{t_EXAMPLE.v => t_var_assign_landr.v}        |  56 +-
 test_regress/t/t_vpi_get.cpp                       |   2 +-
 test_regress/t/t_vpi_memory.cpp                    |   4 +-
 verilator.1                                        |  12 +-
 verilator.html                                     |  10 +-
 verilator.pdf                                      | Bin 388262 -> 388497 bytes
 verilator.txt                                      |  10 +-
 veripool-logo.png                                  | Bin 885 -> 0 bytes
 58 files changed, 993 insertions(+), 437 deletions(-)

diff --git a/Changes b/Changes
index b9cf8d7..5d56f16 100644
--- a/Changes
+++ b/Changes
@@ -3,6 +3,31 @@ Revision history for Verilator
 The contributors that suggested a given feature are shown in [].  [by ...]
 indicates the contributor was also the author of the fix; Thanks!
 
+* Verilator 3.864 2014-09-21
+
+***   Support power operator with real, bug809. [Jonathon Donaldson]
+
+****  Improve verilator_profcfunc time attributions. [Jonathon Donaldson]
+
+****  Fix duplicate anonymous structures in $root, bug788. [Bob Newgard]
+
+****  Fix mis-optimization of bit-swap in wide signal, bug800. [Jie Xu]
+
+****  Fix error when tracing public parameters, bug722. [Jonathon Donaldson]
+
+****  Fix dpiGetContext in dotted scopes, bug740. [Geoff Barrett]
+
+****  Fix over-shift structure optimization error, bug803. [Jeff Bush]
+
+****  Fix optional parameter keyword in module #(), bug810. [Iztok Jeras]
+
+****  Fix $warning/$error multi-argument ordering, bug816. [Jonathon Donaldson]
+
+****  Fix clang warnings, bug818. [Iztok Jeras]
+
+****  Fix string formats under deep expressions, bug820. [Iztok Jeras]
+
+
 * Verilator 3.862 2014-06-10
 
 ***   Using command line -Wno-{WARNING} now overrides file-local lint_on.
diff --git a/README.pdf b/README.pdf
index 73fa7b4..3157273 100644
Binary files a/README.pdf and b/README.pdf differ
diff --git a/bin/verilator b/bin/verilator
index 3e58b7c..004a2ce 100755
--- a/bin/verilator
+++ b/bin/verilator
@@ -782,8 +782,10 @@ Disables optimization of the model.
 
 =item -O3
 
-Enables slow optimizations.  This may reduce simulation runtimes at the
-cost of compile time.  This currently sets --inline-mult -1.
+Enables slow optimizations for the code Verilator itself generates (as
+opposed to "-CFLAGS -O3" which effects the C compiler's optimization.  -O3
+may reduce simulation runtimes at the cost of compile time.  This currently
+sets --inline-mult -1.
 
 =item -OI<optimization-letter>
 
@@ -2968,8 +2970,8 @@ simulators.
 Warns that an `include filename specifies an absolute path.  This means the
 code will not work on any other system with a different file system layout.
 Instead of using absolute paths, relative paths (preferably without any
-directory specified whatever) should be used, and +include used on the
-command line to specify the top include source directory.
+directory specified whatever) should be used, and +incdir used on the
+command line to specify the top include source directories.
 
 Disabled by default as this is a code style warning; it will simulate
 correctly.
diff --git a/bin/verilator_profcfunc b/bin/verilator_profcfunc
index 46d253a..ac1d163 100755
--- a/bin/verilator_profcfunc
+++ b/bin/verilator_profcfunc
@@ -118,6 +118,18 @@ sub profcfunc {
 		$groups{type}{"Common code under $design"} += $pct;
 		$groups{design}{$design} += $pct;
 		$groups{module}{$design." common code"} += $pct;
+	    } elsif ($func =~ /^VL_[A-Z0-9_]+/
+		     || $func =~ /^_?vl_[a-zA-Z0-9_]+/
+		     || $func =~ /^verilated/i) {
+		$vfunc = sprintf("VLib      %s", $func);
+		$groups{type}{'VLib'} += $pct;
+		$groups{design}{'VLib'} += $pct;
+		$groups{module}{'VLib'} += $pct;
+	    } elsif ($func =~ /^_mcount_private/) {
+		$vfunc = sprintf("Prof      %s", $func);
+		$groups{type}{'Prof'} += $pct;
+		$groups{design}{'Prof'} += $pct;
+		$groups{module}{'Prof'} += $pct;
 	    } else {
 		$vfunc = sprintf("C++       %s", $func);
 		$groups{type}{'C++'} += $pct;
@@ -129,7 +141,7 @@ sub profcfunc {
     }
 
 
-    foreach my $type qw(type design module) {
+    foreach my $type (qw(type design module)) {
 	my $missing = 100;
 	foreach (sort (keys %{$groups{$type}})) {
 	    $missing -= $groups{$type}{$_};
@@ -150,8 +162,10 @@ sub profcfunc {
     print("Verilog code profile:\n");
     print("   These are split into three categories:\n");
     print("      C++:     Time in non-Verilated C++ code\n");
+    print("      Prof:    Time in profile overhead\n");
     print("      VBlock:  Time attributable to a block in a Verilog file and line\n");
     print("      VCommon: Time in a Verilated module, due to all parts of the design\n");
+    print("      VLib:    Time in Verilated common libraries, called by the Verilated code\n");
     print("\n");
 
     print("  %   cumulative   self              \n");
diff --git a/configure b/configure
index 4a1664b..7ac9203 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for Verilator 3.862 2014-06-10.
+# Generated by GNU Autoconf 2.68 for Verilator 3.864 2014-09-21.
 #
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -557,8 +557,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='Verilator'
 PACKAGE_TARNAME='verilator'
-PACKAGE_VERSION='3.862 2014-06-10'
-PACKAGE_STRING='Verilator 3.862 2014-06-10'
+PACKAGE_VERSION='3.864 2014-09-21'
+PACKAGE_STRING='Verilator 3.864 2014-09-21'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1223,7 +1223,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures Verilator 3.862 2014-06-10 to adapt to many kinds of systems.
+\`configure' configures Verilator 3.864 2014-09-21 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1284,7 +1284,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Verilator 3.862 2014-06-10:";;
+     short | recursive ) echo "Configuration of Verilator 3.864 2014-09-21:";;
    esac
   cat <<\_ACEOF
 
@@ -1376,7 +1376,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Verilator configure 3.862 2014-06-10
+Verilator configure 3.864 2014-09-21
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -1633,7 +1633,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by Verilator $as_me 3.862 2014-06-10, which was
+It was created by Verilator $as_me 3.864 2014-09-21, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3883,6 +3883,36 @@ $as_echo "$_my_result" >&6; }
     fi
     CXXFLAGS="$ACO_SAVE_CXXFLAGS"
 
+# _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options
+    ACO_SAVE_CXXFLAGS="$CXXFLAGS"
+    # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems
+    CXXFLAGS="$CXXFLAGS -Wno-parentheses-equality -Werror"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-parentheses-equality" >&5
+$as_echo_n "checking whether $CXX accepts -Wno-parentheses-equality... " >&6; }
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  _my_result=yes
+else
+  _my_result=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5
+$as_echo "$_my_result" >&6; }
+    if test "$_my_result" = "yes" ; then
+       CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-parentheses-equality"
+    fi
+    CXXFLAGS="$ACO_SAVE_CXXFLAGS"
+
 # Random code often does / 0.  Unfortunately VL_DIV_I(0,0) will warn
 # without this flag, even though there's a conditional to prevent the divide.
 # We still don't add no-div-by-zero as it throws message to stdout, though doesn't die.
@@ -3950,6 +3980,36 @@ $as_echo "$_my_result" >&6; }
 # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options
     ACO_SAVE_CXXFLAGS="$CXXFLAGS"
     # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems
+    CXXFLAGS="$CXXFLAGS -Wno-unused-but-set-variable -Werror"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-unused-but-set-variable" >&5
+$as_echo_n "checking whether $CXX accepts -Wno-unused-but-set-variable... " >&6; }
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  _my_result=yes
+else
+  _my_result=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5
+$as_echo "$_my_result" >&6; }
+    if test "$_my_result" = "yes" ; then
+       CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-unused-but-set-variable"
+    fi
+    CXXFLAGS="$ACO_SAVE_CXXFLAGS"
+
+# _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options
+    ACO_SAVE_CXXFLAGS="$CXXFLAGS"
+    # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems
     CXXFLAGS="$CXXFLAGS -Wno-unused-parameter -Werror"
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-unused-parameter" >&5
 $as_echo_n "checking whether $CXX accepts -Wno-unused-parameter... " >&6; }
@@ -4010,9 +4070,9 @@ $as_echo "$_my_result" >&6; }
 # _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options
     ACO_SAVE_CXXFLAGS="$CXXFLAGS"
     # -Werror needed otherwise unknown -Wno-div-by-zero won't report problems
-    CXXFLAGS="$CXXFLAGS -Wno-unused-but-set-variable -Werror"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -Wno-unused-but-set-variable" >&5
-$as_echo_n "checking whether $CXX accepts -Wno-unused-but-set-variable... " >&6; }
+    CXXFLAGS="$CXXFLAGS -fbracket-depth=4096 -Werror"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -fbracket-depth=4096" >&5
+$as_echo_n "checking whether $CXX accepts -fbracket-depth=4096... " >&6; }
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -4033,7 +4093,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_my_result" >&5
 $as_echo "$_my_result" >&6; }
     if test "$_my_result" = "yes" ; then
-       CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -Wno-unused-but-set-variable"
+       CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED -fbracket-depth=4096"
     fi
     CXXFLAGS="$ACO_SAVE_CXXFLAGS"
 
@@ -4565,7 +4625,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by Verilator $as_me 3.862 2014-06-10, which was
+This file was extended by Verilator $as_me 3.864 2014-09-21, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -4627,7 +4687,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-Verilator config.status 3.862 2014-06-10
+Verilator config.status 3.864 2014-09-21
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 262fe4c..3f4c4bc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,7 +6,7 @@
 
 #AC_INIT([Verilator],[#.### YYYY-MM-DD])
 #AC_INIT([Verilator],[#.### devel])
-AC_INIT([Verilator],[3.862 2014-06-10])
+AC_INIT([Verilator],[3.864 2014-09-21])
 AC_CONFIG_HEADER(src/config_build.h)
 AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h)
 
@@ -122,15 +122,17 @@ AC_DEFUN([_MY_CXX_CHECK_OPT],
 
 # For example, -Wno-div-by-zero isn't in 4.1.2
 _MY_CXX_CHECK_OPT(-Wno-char-subscripts)
+_MY_CXX_CHECK_OPT(-Wno-parentheses-equality)
 # Random code often does / 0.  Unfortunately VL_DIV_I(0,0) will warn
 # without this flag, even though there's a conditional to prevent the divide.
 # We still don't add no-div-by-zero as it throws message to stdout, though doesn't die.
 #_MY_CXX_CHECK_OPT(-Wno-div-by-zero)
 _MY_CXX_CHECK_OPT(-Wno-sign-compare)
 _MY_CXX_CHECK_OPT(-Wno-uninitialized)
+_MY_CXX_CHECK_OPT(-Wno-unused-but-set-variable)
 _MY_CXX_CHECK_OPT(-Wno-unused-parameter)
 _MY_CXX_CHECK_OPT(-Wno-unused-variable)
-_MY_CXX_CHECK_OPT(-Wno-unused-but-set-variable)
+_MY_CXX_CHECK_OPT(-fbracket-depth=4096)
 AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
 
 # Checks for library functions.
diff --git a/include/verilated.cpp b/include/verilated.cpp
index ce1bcdc..eca6b49 100644
--- a/include/verilated.cpp
+++ b/include/verilated.cpp
@@ -74,6 +74,9 @@ void vl_fatal (const char* filename, int linenum, const char* hier, const char*
     Verilated::gotFinish(true);
     VL_PRINTF("%%Error: %s:%d: %s\n", filename, linenum, msg);
     Verilated::flushCall();
+
+    VL_PRINTF("Aborting...\n");
+    Verilated::flushCall();  // Second flush in case VL_PRINTF does something needing a flush
     abort();
 }
 #endif
diff --git a/include/verilated.mk.in b/include/verilated.mk.in
index f609460..87feb6d 100644
--- a/include/verilated.mk.in
+++ b/include/verilated.mk.in
@@ -43,14 +43,14 @@ VK_CPPFLAGS_ALWAYS += \
 		-DVL_PRINTF=printf \
 		-DVM_TRACE=$(VM_TRACE) \
 		-DVM_COVERAGE=$(VM_COVERAGE) \
+		$(CFG_CXXFLAGS_NO_UNUSED) \
 
 ifeq ($(CFG_WITH_CCWARN),yes)	# Local... Else don't burden users
 VK_CPPFLAGS_WALL += -Wall \
-		$(CFG_CXXFLAGS_NO_UNUSED) \
 		-Werror
 endif
 
-CPPFLAGS += -I. $(VK_CPPFLAGS_ALWAYS) $(VK_CPPFLAGS_WALL)
+CPPFLAGS += -I. $(VK_CPPFLAGS_WALL) $(VK_CPPFLAGS_ALWAYS)
 
 VPATH += ..
 VPATH += $(VERILATOR_ROOT)/include
@@ -195,6 +195,7 @@ debug-make::
 	@echo VM_SUPPORT_SLOW: $(VM_SUPPORT_SLOW)
 	@echo VM_GLOBAL_FAST: $(VM_GLOBAL_FAST)
 	@echo VM_GLOBAL_SLOW: $(VM_GLOBAL_SLOW)
+	@echo CPPFLAGS: $(CPPFLAGS)
 	@echo
 
 ######################################################################
diff --git a/include/verilated_config.h b/include/verilated_config.h
index e398f0d..ef38823 100644
--- a/include/verilated_config.h
+++ b/include/verilated_config.h
@@ -25,4 +25,4 @@
 
 // Autoconf substitutes this with the strings from AC_INIT.
 #define VERILATOR_PRODUCT    "Verilator"
-#define VERILATOR_VERSION    "3.862 2014-06-10"
+#define VERILATOR_VERSION    "3.864 2014-09-21"
diff --git a/include/verilated_vcd_c.cpp b/include/verilated_vcd_c.cpp
index d0fb450..3919c40 100644
--- a/include/verilated_vcd_c.cpp
+++ b/include/verilated_vcd_c.cpp
@@ -703,5 +703,5 @@ main() {
 
 //********************************************************************
 // Local Variables:
-// compile-command: "mkdir -p ../test_dir && cd ../test_dir && g++ -DVERILATED_VCD_TEST ../src/verilated_vcd_c.cpp -o verilated_vcd_c && ./verilated_vcd_c && cat test.vcd"
+// compile-command: "mkdir -p ../test_dir && cd ../test_dir && c++ -DVERILATED_VCD_TEST ../src/verilated_vcd_c.cpp -o verilated_vcd_c && ./verilated_vcd_c && cat test.vcd"
 // End:
diff --git a/include/verilated_vpi.h b/include/verilated_vpi.h
index eb6cae5..74fdaf6 100644
--- a/include/verilated_vpi.h
+++ b/include/verilated_vpi.h
@@ -97,8 +97,8 @@ public:
     virtual const char* fullname() { return "<null>"; }
     virtual const char* defname() { return "<null>"; }
     virtual const vluint32_t type() { return 0; }
-    virtual const vluint32_t size() { return 0; }
-    virtual const VerilatedRange* rangep() { return 0; }
+    virtual const vluint32_t size() const { return 0; }
+    virtual const VerilatedRange* rangep() const { return NULL; }
     virtual vpiHandle dovpi_scan() { return 0; }
 };
 
@@ -136,7 +136,7 @@ public:
 
 class VerilatedVpioRange : public VerilatedVpio {
     const VerilatedRange* m_range;
-    bool	m_iteration;
+    vlsint32_t                  m_iteration;
 public:
     VerilatedVpioRange(const VerilatedRange* range) : m_range(range), m_iteration(0) {}
     virtual ~VerilatedVpioRange() {}
@@ -182,7 +182,7 @@ class VerilatedVpioVar : public VerilatedVpio {
 protected:
     void*			m_varDatap;	// varp()->datap() adjusted for array entries
     vlsint32_t			m_index;
-    const VerilatedRange&	get_range() {
+    const VerilatedRange&	get_range() const {
 	// Determine number of dimensions and return outermost
 	return (m_varp->dims()>1) ? m_varp->array() : m_varp->range();
     }
@@ -208,8 +208,8 @@ public:
       if (varp()->vldir() != vpiNoDirection) return vpiPort;
       return (varp()->dims()>1) ? vpiMemory : vpiReg; /* but might be wire, logic */
     }
-    virtual const vluint32_t size() { return get_range().elements(); }
-    virtual const VerilatedRange* rangep() { return &get_range(); }
+    virtual const vluint32_t size() const { return get_range().elements(); }
+    virtual const VerilatedRange* rangep() const { return &get_range(); }
     virtual const char* name() { return m_varp->name(); }
     virtual const char* fullname() {
 	VL_STATIC_OR_THREAD string out;
@@ -237,8 +237,8 @@ public:
     virtual ~VerilatedVpioMemoryWord() {}
     static inline VerilatedVpioMemoryWord* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioMemoryWord*>((VerilatedVpio*)h); }
     virtual const vluint32_t type() { return vpiMemoryWord; }
-    virtual const vluint32_t size() { return varp()->range().elements(); }
-    virtual const VerilatedRange* rangep() { return &(varp()->range()); }
+    virtual const vluint32_t size() const { return varp()->range().elements(); }
+    virtual const VerilatedRange* rangep() const { return &(varp()->range()); }
     virtual const char* fullname() {
 	VL_STATIC_OR_THREAD string out;
 	char num[20]; sprintf(num,"%d",m_index);
@@ -919,9 +919,9 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
 	    value_p->value.str = outStr;
 	    switch (vop->varp()->vltype()) {
 	    // outStrSz does not include NULL termination so add one
-	    case VLVT_UINT8 : snprintf(outStr, outStrSz+1, "%hhu", (unsigned  int)*((CData*)(vop->varDatap()))); return;
-	    case VLVT_UINT16: snprintf(outStr, outStrSz+1, "%hu",  (unsigned  int)*((SData*)(vop->varDatap()))); return;
-	    case VLVT_UINT32: snprintf(outStr, outStrSz+1, "%u",   (unsigned  int)*((IData*)(vop->varDatap()))); return;
+	    case VLVT_UINT8 : snprintf(outStr, outStrSz+1, "%hhu", (unsigned char )*((CData*)(vop->varDatap()))); return;
+	    case VLVT_UINT16: snprintf(outStr, outStrSz+1, "%hu",  (unsigned short)*((SData*)(vop->varDatap()))); return;
+	    case VLVT_UINT32: snprintf(outStr, outStrSz+1, "%u",   (unsigned int  )*((IData*)(vop->varDatap()))); return;
 	    case VLVT_UINT64: snprintf(outStr, outStrSz+1, "%llu",  (unsigned long long)*((QData*)(vop->varDatap()))); return;
 	    default:
                 strcpy(outStr, "-1");
diff --git a/internals.pdf b/internals.pdf
index b70552c..051d857 100644
Binary files a/internals.pdf and b/internals.pdf differ
diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp
index 752eb0e..4163c28 100644
--- a/src/V3Assert.cpp
+++ b/src/V3Assert.cpp
@@ -61,10 +61,13 @@ private:
     void replaceDisplay(AstDisplay* nodep, const string& prefix) {
 	nodep->displayType(AstDisplayType::DT_WRITE);
 	nodep->fmtp()->text(assertDisplayMessage(nodep, prefix, nodep->fmtp()->text()));
-	AstNode* timesp = nodep->fmtp()->exprsp(); if (timesp) timesp->unlinkFrBack();
 	// cppcheck-suppress nullPointer
-	timesp = timesp->addNext(new AstTime(nodep->fileline()));
-	nodep->fmtp()->exprsp(timesp);
+	AstNode* timenewp = new AstTime(nodep->fileline());
+	if (AstNode* timesp = nodep->fmtp()->exprsp()) {
+	    timesp->unlinkFrBackWithNext();
+	    timenewp->addNext(timesp);
+	}
+	nodep->fmtp()->exprsp(timenewp);
 	if (!nodep->fmtp()->scopeNamep() && nodep->fmtp()->formatScopeTracking()) {
 	    nodep->fmtp()->scopeNamep(new AstScopeName(nodep->fileline()));
 	}
diff --git a/src/V3Ast.h b/src/V3Ast.h
index 9600dae..c3bbc62 100644
--- a/src/V3Ast.h
+++ b/src/V3Ast.h
@@ -1216,8 +1216,9 @@ inline void AstNRelinker::relink(AstNode* newp) { newp->AstNode::relink(this); }
     virtual ~Ast ##name() {} \
     Ast ##name * cloneTree(bool cloneNext) { return AstNode::cloneTree(cloneNext)->cast ##name(); }
 
-struct AstNodeMath : public AstNode {
+class AstNodeMath : public AstNode {
     // Math -- anything that's part of an expression tree
+public:
     AstNodeMath(FileLine* fl)
 	: AstNode(fl) {}
     ASTNODE_BASE_FUNCS(NodeMath)
@@ -1232,8 +1233,9 @@ struct AstNodeMath : public AstNode {
     bool isOpaque() { return castCvtPackString()!=NULL; }
 };
 
-struct AstNodeTermop : public AstNodeMath {
+class AstNodeTermop : public AstNodeMath {
     // Terminal operator -- a operator with no "inputs"
+public:
     AstNodeTermop(FileLine* fl)
 	: AstNodeMath(fl) {}
     ASTNODE_BASE_FUNCS(NodeTermop)
@@ -1243,8 +1245,9 @@ struct AstNodeTermop : public AstNodeMath {
     void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
 };
 
-struct AstNodeUniop : public AstNodeMath {
+class AstNodeUniop : public AstNodeMath {
     // Unary math
+public:
     AstNodeUniop(FileLine* fl, AstNode* lhsp)
 	: AstNodeMath(fl) {
 	dtypeFrom(lhsp);
@@ -1263,8 +1266,9 @@ struct AstNodeUniop : public AstNodeMath {
     virtual bool same(AstNode*) const { return true; }
 };
 
-struct AstNodeBiop : public AstNodeMath {
+class AstNodeBiop : public AstNodeMath {
     // Binary math
+public:
     AstNodeBiop(FileLine* fl, AstNode* lhs, AstNode* rhs)
 	: AstNodeMath(fl) {
 	setOp1p(lhs); setOp2p(rhs); }
@@ -1286,8 +1290,9 @@ struct AstNodeBiop : public AstNodeMath {
     virtual bool same(AstNode*) const { return true; }
 };
 
-struct AstNodeTriop : public AstNodeMath {
+class AstNodeTriop : public AstNodeMath {
     // Trinary math
+public:
     AstNodeTriop(FileLine* fl, AstNode* lhs, AstNode* rhs, AstNode* ths)
 	: AstNodeMath(fl) {
 	setOp1p(lhs); setOp2p(rhs); setOp3p(ths); }
@@ -1311,20 +1316,23 @@ struct AstNodeTriop : public AstNodeMath {
     virtual bool same(AstNode*) const { return true; }
 };
 
-struct AstNodeBiCom : public AstNodeBiop {
+class AstNodeBiCom : public AstNodeBiop {
     // Binary math with commutative properties
+public:
     AstNodeBiCom(FileLine* fl, AstNode* lhs, AstNode* rhs)
 	: AstNodeBiop(fl, lhs, rhs) {}
     ASTNODE_BASE_FUNCS(NodeBiCom)
 };
 
-struct AstNodeBiComAsv : public AstNodeBiCom {
+class AstNodeBiComAsv : public AstNodeBiCom {
     // Binary math with commutative & associative properties
+public:
     AstNodeBiComAsv(FileLine* fl, AstNode* lhs, AstNode* rhs)
 	: AstNodeBiCom(fl, lhs, rhs) {}
     ASTNODE_BASE_FUNCS(NodeBiComAsv)
 };
-struct AstNodeCond : public AstNodeTriop {
+class AstNodeCond : public AstNodeTriop {
+public:
     AstNodeCond(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p)
 	: AstNodeTriop(fl, condp, expr1p, expr2p) {
 	if (expr1p) dtypeFrom(expr1p);
@@ -1346,8 +1354,9 @@ struct AstNodeCond : public AstNodeTriop {
     virtual int instrCount()	const { return instrCountBranch(); }
 };
 
-struct AstNodePreSel : public AstNode {
+class AstNodePreSel : public AstNode {
     // Something that becomes an AstSel
+public:
     AstNodePreSel(FileLine* fl, AstNode* lhs, AstNode* rhs, AstNode* ths)
 	: AstNode(fl) {
 	setOp1p(lhs); setOp2p(rhs); setNOp3p(ths); }
@@ -1366,8 +1375,9 @@ struct AstNodePreSel : public AstNode {
     virtual bool same(AstNode*) const { return true; }
 };
 
-struct AstNodeStmt : public AstNode {
+class AstNodeStmt : public AstNode {
     // Statement -- anything that's directly under a function
+public:
     AstNodeStmt(FileLine* fl)
 	: AstNode(fl) {}
     ASTNODE_BASE_FUNCS(NodeStmt)
@@ -1376,7 +1386,8 @@ struct AstNodeStmt : public AstNode {
     virtual void addBeforeStmt(AstNode* newp, AstNode* belowp);  // Stop statement searchback here
 };
 
-struct AstNodeAssign : public AstNodeStmt {
+class AstNodeAssign : public AstNodeStmt {
+public:
     AstNodeAssign(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
 	: AstNodeStmt(fl) {
 	setOp1p(rhsp); setOp2p(lhsp);
@@ -1397,7 +1408,8 @@ struct AstNodeAssign : public AstNodeStmt {
     virtual string verilogKwd() const { return "="; }
 };
 
-struct AstNodeFor : public AstNodeStmt {
+class AstNodeFor : public AstNodeStmt {
+public:
     AstNodeFor(FileLine* fileline, AstNode* initsp, AstNode* condp,
 	       AstNode* incsp, AstNode* bodysp)
 	: AstNodeStmt(fileline) {
@@ -1414,7 +1426,7 @@ struct AstNodeFor : public AstNodeStmt {
     virtual bool same(AstNode* samep) const { return true; }
 };
 
-struct AstNodeIf : public AstNodeStmt {
+class AstNodeIf : public AstNodeStmt {
 private:
     AstBranchPred	m_branchPred;	// Branch prediction as taken/untaken?
 public:
@@ -1438,7 +1450,8 @@ public:
     AstBranchPred branchPred() const { return m_branchPred; }
 };
 
-struct AstNodeCase : public AstNodeStmt {
+class AstNodeCase : public AstNodeStmt {
+public:
     AstNodeCase(FileLine* fl, AstNode* exprp, AstNode* casesp)
 	: AstNodeStmt(fl) {
 	setOp1p(exprp); addNOp2p(casesp);
@@ -1452,8 +1465,9 @@ struct AstNodeCase : public AstNodeStmt {
     void addNotParallelp(AstNode* nodep) { setOp3p(nodep); }
 };
 
-struct AstNodeSenItem : public AstNode {
+class AstNodeSenItem : public AstNode {
     // An AstSenItem or AstSenGate
+public:
     AstNodeSenItem(FileLine* fl) : AstNode(fl) {}
     ASTNODE_BASE_FUNCS(NodeSenItem)
     virtual bool isClocked() const = 0;
@@ -1511,7 +1525,7 @@ public:
     void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
 };
 
-struct AstNodeText : public AstNode {
+class AstNodeText : public AstNode {
 private:
     string	m_text;
 public:
@@ -1528,11 +1542,11 @@ public:
     const string& text() const { return m_text; }
 };
 
-struct AstNodeDType : public AstNode {
-private:
+class AstNodeDType : public AstNode {
     // Ideally width() would migrate to BasicDType as that's where it makes sense,
     // but it's currently so prevalent in the code we leave it here.
     // Note the below members are included in AstTypeTable::Key lookups
+private:
     int		m_width;	// (also in AstTypeTable::Key) Bit width of operation
     int		m_widthMin;	// (also in AstTypeTable::Key) If unsized, bitwidth of minimum implementation
     AstNumeric	m_numeric;	// (also in AstTypeTable::Key) Node is signed
@@ -1581,7 +1595,7 @@ public:
     static int uniqueNumInc() { return ++s_uniqueNum; }
 };
 
-struct AstNodeClassDType : public AstNodeDType {
+class AstNodeClassDType : public AstNodeDType {
 private:
     // TYPES
     typedef map<string,AstMemberDType*> MemberNameMap;
@@ -1620,7 +1634,7 @@ public:
     VNumRange declRange() const { return VNumRange(msb(), lsb(), false); }
 };
 
-struct AstNodeArrayDType : public AstNodeDType {
+class AstNodeArrayDType : public AstNodeDType {
     // Array data type, ie "some_dtype var_name [2:0]"
     // Children: DTYPE (moved to refDTypep() in V3Width)
     // Children: RANGE (array bounds)
@@ -1666,8 +1680,9 @@ public:
     VNumRange declRange() const;
 };
 
-struct AstNodeSel : public AstNodeBiop {
+class AstNodeSel : public AstNodeBiop {
     // Single bit range extraction, perhaps with non-constant selection or array selection
+public:
     AstNodeSel(FileLine* fl, AstNode* fromp, AstNode* bitp)
 	:AstNodeBiop(fl, fromp, bitp) {}
     ASTNODE_BASE_FUNCS(NodeSel)
@@ -1679,8 +1694,9 @@ struct AstNodeSel : public AstNodeBiop {
     virtual bool hasDType() const { return true; }
 };
 
-struct AstNodeStream : public AstNodeBiop {
+class AstNodeStream : public AstNodeBiop {
     // Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp()
+public:
     AstNodeStream(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	if (lhsp->dtypep()) {
 	    dtypeSetLogicSized(lhsp->dtypep()->width(), lhsp->dtypep()->width(), AstNumeric::UNSIGNED);
@@ -1692,7 +1708,7 @@ struct AstNodeStream : public AstNodeBiop {
 //######################################################################
 // Tasks/functions common handling
 
-struct AstNodeFTask : public AstNode {
+class AstNodeFTask : public AstNode {
 private:
     string	m_name;		// Name of task
     string	m_cname;	// Name of task if DPI import
@@ -1750,7 +1766,7 @@ public:
     bool	pure() const { return m_pure; }
 };
 
-struct AstNodeFTaskRef : public AstNode {
+class AstNodeFTaskRef : public AstNode {
     // A reference to a task (or function)
 private:
     AstNodeFTask*	m_taskp;	// [AfterLink] Pointer to task referenced
@@ -1796,7 +1812,7 @@ public:
     void 	scopeNamep(AstNode* nodep) { setNOp3p(nodep); }
 };
 
-struct AstNodeModule : public AstNode {
+class AstNodeModule : public AstNode {
     // A module, package, program or interface declaration;
     // something that can live directly under the TOP,
     // excluding $unit package stuff
@@ -1810,12 +1826,13 @@ private:
     bool	m_internal:1;	// Internally created
     int		m_level;	// 1=top module, 2=cell off top module, ...
     int		m_varNum;	// Incrementing variable number
+    int		m_typeNum;	// Incrementing implicit type number
 public:
     AstNodeModule(FileLine* fl, const string& name)
 	: AstNode (fl)
 	,m_name(name), m_origName(name)
 	,m_modPublic(false), m_modTrace(false), m_inLibrary(false), m_dead(false), m_internal(false)
-	,m_level(0), m_varNum(0) { }
+	,m_level(0), m_varNum(0), m_typeNum(0) { }
     ASTNODE_BASE_FUNCS(NodeModule)
     virtual void dump(ostream& str);
     virtual bool maybePointedTo() const { return true; }
@@ -1835,6 +1852,7 @@ public:
     int  level() const		{ return m_level; }
     bool isTop() const		{ return level()==1; }
     int  varNumGetInc() 	{ return ++m_varNum; }
+    int  typeNumGetInc() 	{ return ++m_typeNum; }
     void modPublic(bool flag) 	{ m_modPublic = flag; }
     bool modPublic() const 	{ return m_modPublic; }
     void modTrace(bool flag) 	{ m_modTrace = flag; }
diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp
index 24d9b6c..c1fac9d 100644
--- a/src/V3AstNodes.cpp
+++ b/src/V3AstNodes.cpp
@@ -515,6 +515,24 @@ string AstScopeName::scopeSymName() const {
     return out;
 }
 
+string AstScopeName::scopeDpiName() const {
+    string out;
+    for (AstText* textp=scopeEntrp(); textp; textp=textp->nextp()->castText()) {
+	out += textp->text();
+    }
+    if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
+    if (out.substr(0,7) == "__DOT__") out.replace(0,7,"");
+    if (out.substr(0,1) == ".") out.replace(0,1,"");
+    string::size_type pos;
+    while ((pos=out.find(".")) != string::npos) {
+	out.replace(pos, 1, "__");
+    }
+    while ((pos=out.find("__DOT__")) != string::npos) {
+	out.replace(pos, 7, "__");
+    }
+    return out;
+}
+
 bool AstSenTree::hasClocked() {
     if (!sensesp()) this->v3fatalSrc("SENTREE without any SENITEMs under it");
     for (AstNodeSenItem* senp = sensesp(); senp; senp=senp->nextp()->castNodeSenItem()) {
diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h
index ae8c04b..a11a5cc 100644
--- a/src/V3AstNodes.h
+++ b/src/V3AstNodes.h
@@ -39,7 +39,7 @@
 //=== Ast* : Specific types
 // Netlist interconnect
 
-struct AstConst : public AstNodeMath {
+class AstConst : public AstNodeMath {
     // A constant
 private:
     V3Number	m_num;		// Constant value
@@ -100,7 +100,7 @@ public:
     bool isEqAllOnesV() const { return num().isEqAllOnes(widthMin()); }
 };
 
-struct AstConstString : public AstNodeMath {
+class AstConstString : public AstNodeMath {
     // A constant string
 private:
     string	m_name;
@@ -128,7 +128,7 @@ public:
     void name(const string& flag) { m_name = flag; rewidth(); }
 };
 
-struct AstRange : public AstNode {
+class AstRange : public AstNode {
     // Range specification, for use under variables and cells
 private:
     bool	m_littleEndian:1;	// Bit vector is little endian
@@ -163,8 +163,9 @@ public:
     virtual bool same(AstNode* samep) const { return true; }
 };
 
-struct AstGatePin : public AstNodeMath {
+class AstGatePin : public AstNodeMath {
     // Possibly expand a gate primitive input pin value to match the range of the gate primitive
+public:
     AstGatePin(FileLine* fl, AstNode* lhsp, AstRange* rangep) : AstNodeMath(fl) {
 	setOp1p(lhsp); setOp2p(rangep);
     }
@@ -179,7 +180,7 @@ struct AstGatePin : public AstNodeMath {
 //######################################################################
 //==== Data Types
 
-struct AstTypedef : public AstNode {
+class AstTypedef : public AstNode {
 private:
     string	m_name;
 public:
@@ -200,7 +201,7 @@ public:
     void name(const string& flag) { m_name = flag; }
 };
 
-struct AstTypedefFwd : public AstNode {
+class AstTypedefFwd : public AstNode {
     // Forward declaration of a type; stripped after netlist parsing is complete
 private:
     string	m_name;
@@ -212,7 +213,7 @@ public:
     virtual string name() const { return m_name; }
 };
 
-struct AstDefImplicitDType : public AstNodeDType {
+class AstDefImplicitDType : public AstNodeDType {
     // For parsing enum/struct/unions that are declared with a variable rather than typedef
     // This allows "var enum {...} a,b" to share the enum definition for both variables
     // After link, these become typedefs
@@ -221,7 +222,7 @@ private:
     void*	m_containerp;	// In what scope is the name unique, so we can know what are duplicate definitions (arbitrary value)
     int		m_uniqueNum;
 public:
-    AstDefImplicitDType(FileLine* fl, const string& name, AstNode* containerp,
+    AstDefImplicitDType(FileLine* fl, const string& name, void* containerp,
 			VFlagChildDType, AstNodeDType* dtp)
 	: AstNodeDType(fl), m_name(name), m_containerp(containerp) {
 	childDTypep(dtp);  // Only for parser
@@ -247,7 +248,7 @@ public:
     void name(const string& flag) { m_name = flag; }
 };
 
-struct AstPackArrayDType : public AstNodeArrayDType {
+class AstPackArrayDType : public AstNodeArrayDType {
     // Array data type, ie "some_dtype var_name [2:0]"
     // Children: DTYPE (moved to refDTypep() in V3Width)
     // Children: RANGE (array bounds)
@@ -272,7 +273,7 @@ public:
     ASTNODE_NODE_FUNCS(PackArrayDType, PACKARRAYDTYPE)
 };
 
-struct AstUnpackArrayDType : public AstNodeArrayDType {
+class AstUnpackArrayDType : public AstNodeArrayDType {
     // Array data type, ie "some_dtype var_name [2:0]"
     // Children: DTYPE (moved to refDTypep() in V3Width)
     // Children: RANGE (array bounds)
@@ -297,7 +298,7 @@ public:
     ASTNODE_NODE_FUNCS(UnpackArrayDType, UNPACKARRAYDTYPE)
 };
 
-struct AstBasicDType : public AstNodeDType {
+class AstBasicDType : public AstNodeDType {
     // Builtin atomic/vectored data type
     // Children: RANGE (converted to constant in V3Width)
 private:
@@ -410,7 +411,7 @@ public:
     }
 };
 
-struct AstConstDType : public AstNodeDType {
+class AstConstDType : public AstNodeDType {
     // const data type, ie "const some_dtype var_name [2:0]"
     // ConstDType are removed in V3LinkLValue and become AstVar::isConst.
     // When more generic types are supported AstConstDType will be propagated further.
@@ -448,7 +449,7 @@ public:
     virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); }
 };
 
-struct AstIfaceRefDType : public AstNodeDType {
+class AstIfaceRefDType : public AstNodeDType {
     // Reference to an interface, either for a port, or inside parent cell
 private:
     string		m_cellName;	// "" = no cell, such as when connects to 'input' iface
@@ -491,7 +492,7 @@ public:
     bool isModport() { return !m_modportName.empty(); }
 };
 
-struct AstRefDType : public AstNodeDType {
+class AstRefDType : public AstNodeDType {
 private:
     AstNodeDType* m_refDTypep;	// data type pointed to, BELOW the AstTypedef
     string	m_name;		// Name of an AstTypedef
@@ -541,14 +542,16 @@ public:
     void packagep(AstPackage* nodep) { m_packagep=nodep; }
 };
 
-struct AstStructDType : public AstNodeClassDType {
+class AstStructDType : public AstNodeClassDType {
+public:
     AstStructDType(FileLine* fl, AstNumeric numericUnpack)
 	: AstNodeClassDType(fl,numericUnpack) {}
     ASTNODE_NODE_FUNCS(StructDType, STRUCTDTYPE)
     virtual string verilogKwd() const { return "struct"; };
 };
 
-struct AstUnionDType : public AstNodeClassDType {
+class AstUnionDType : public AstNodeClassDType {
+public:
     //UNSUP: bool isTagged;
     AstUnionDType(FileLine* fl, AstNumeric numericUnpack)
 	: AstNodeClassDType(fl,numericUnpack) {}
@@ -556,7 +559,7 @@ struct AstUnionDType : public AstNodeClassDType {
     virtual string verilogKwd() const { return "union"; };
 };
 
-struct AstMemberDType : public AstNodeDType {
+class AstMemberDType : public AstNodeDType {
     // A member of a struct/union
     // PARENT: AstClassDType
 private:
@@ -604,7 +607,7 @@ public:
     void lsb(int lsb) { m_lsb=lsb; }
 };
 
-struct AstEnumItem : public AstNode {
+class AstEnumItem : public AstNode {
 private:
     string	m_name;
 public:
@@ -623,7 +626,7 @@ public:
     void valuep(AstNode* nodep) { addOp2p(nodep); }
 };
 
-struct AstEnumItemRef : public AstNodeMath {
+class AstEnumItemRef : public AstNodeMath {
 private:
     AstEnumItem* m_itemp;	// [AfterLink] Pointer to item
     AstPackage*	m_packagep;	// Package hierarchy
@@ -648,7 +651,7 @@ public:
     void packagep(AstPackage* nodep) { m_packagep=nodep; }
 };
 
-struct AstEnumDType : public AstNodeDType {
+class AstEnumDType : public AstNodeDType {
     // Parents: TYPEDEF/MODULE
     // Children: ENUMVALUEs
 private:
@@ -691,7 +694,7 @@ public:
 
 //######################################################################
 
-struct AstArraySel : public AstNodeSel {
+class AstArraySel : public AstNodeSel {
     // Parents: math|stmt
     // Children: varref|arraysel, math
 private:
@@ -734,8 +737,9 @@ public:
     virtual void dump(ostream& str);
 };
 
-struct AstWordSel : public AstNodeSel {
+class AstWordSel : public AstNodeSel {
     // Select a single word from a multi-word wide value
+public:
     AstWordSel(FileLine* fl, AstNode* fromp, AstNode* bitp)
 	:AstNodeSel(fl, fromp, bitp) {
 	dtypeSetUInt32(); // Always used on IData arrays so returns word entities
@@ -751,8 +755,9 @@ struct AstWordSel : public AstNodeSel {
     virtual bool same(AstNode* samep) const { return true; }
 };
 
-struct AstSelExtract : public AstNodePreSel {
+class AstSelExtract : public AstNodePreSel {
     // Range extraction, gets replaced with AstSel
+public:
     AstSelExtract(FileLine* fl, AstNode* fromp, AstNode* msbp, AstNode* lsbp)
 	: AstNodePreSel(fl, fromp, msbp, lsbp) {}
     ASTNODE_NODE_FUNCS(SelExtract, SELEXTRACT)
@@ -760,9 +765,10 @@ struct AstSelExtract : public AstNodePreSel {
     AstNode*	lsbp() const { return thsp(); }
 };
 
-struct AstSelBit : public AstNodePreSel {
+class AstSelBit : public AstNodePreSel {
     // Single bit range extraction, perhaps with non-constant selection or array selection
     // Gets replaced during link with AstArraySel or AstSel
+public:
     AstSelBit(FileLine* fl, AstNode* fromp, AstNode* bitp)
 	:AstNodePreSel(fl, fromp, bitp, NULL) {
 	if (v3Global.assertDTypesResolved()) { v3fatalSrc("not coded to create after dtypes resolved"); }
@@ -771,9 +777,10 @@ struct AstSelBit : public AstNodePreSel {
     AstNode*	bitp() const { return rhsp(); }
 };
 
-struct AstSelPlus : public AstNodePreSel {
+class AstSelPlus : public AstNodePreSel {
     // +: range extraction, perhaps with non-constant selection
     // Gets replaced during link with AstSel
+public:
     AstSelPlus(FileLine* fl, AstNode* fromp, AstNode* bitp, AstNode* widthp)
 	:AstNodePreSel(fl, fromp, bitp, widthp) {}
     ASTNODE_NODE_FUNCS(SelPlus, SELPLUS)
@@ -781,9 +788,10 @@ struct AstSelPlus : public AstNodePreSel {
     AstNode*	widthp() const { return thsp(); }
 };
 
-struct AstSelMinus : public AstNodePreSel {
+class AstSelMinus : public AstNodePreSel {
     // -: range extraction, perhaps with non-constant selection
     // Gets replaced during link with AstSel
+public:
     AstSelMinus(FileLine* fl, AstNode* fromp, AstNode* bitp, AstNode* widthp)
 	:AstNodePreSel(fl, fromp, bitp, widthp) {}
     ASTNODE_NODE_FUNCS(SelMinus, SELMINUS)
@@ -791,7 +799,7 @@ struct AstSelMinus : public AstNodePreSel {
     AstNode*	widthp() const { return thsp(); }
 };
 
-struct AstSel : public AstNodeTriop {
+class AstSel : public AstNodeTriop {
     // Multiple bit range extraction
     // Parents: math|stmt
     // Children: varref|arraysel, math, constant math
@@ -845,7 +853,7 @@ public:
     void declElWidth(int flag) { m_declElWidth = flag; }
 };
 
-struct AstMemberSel : public AstNodeMath {
+class AstMemberSel : public AstNodeMath {
     // Parents: math|stmt
     // Children: varref|arraysel, math
 private:
@@ -876,7 +884,7 @@ public:
     void fromp(AstNode* nodep) { setOp1p(nodep); }
 };
 
-struct AstVar : public AstNode {
+class AstVar : public AstNode {
     // A variable (in/out/wire/reg/param) inside a module
 private:
     string	m_name;		// Name of variable
@@ -1099,7 +1107,7 @@ public:
     }
 };
 
-struct AstDefParam : public AstNode {
+class AstDefParam : public AstNode {
     // A defparam assignment
     // Parents: MODULE
     // Children: math
@@ -1122,9 +1130,10 @@ public:
     string   path()		const { return m_path; }
 };
 
-struct AstImplicit : public AstNode {
+class AstImplicit : public AstNode {
     // Create implicit wires and do nothing else, for gates that are ignored
     // Parents: MODULE
+public:
     AstImplicit(FileLine* fl, AstNode* exprsp)
 	: AstNode(fl) {
 	addNOp1p(exprsp);
@@ -1133,7 +1142,7 @@ struct AstImplicit : public AstNode {
     AstNode* exprsp() const { return op1p()->castNode(); }	// op1 = Assign from
 };
 
-struct AstScope : public AstNode {
+class AstScope : public AstNode {
     // A particular usage of a cell
     // Parents: MODULE
     // Children: NODEBLOCK
@@ -1168,11 +1177,12 @@ public:
     bool isTop() const { return aboveScopep()==NULL; }  // At top of hierarchy
 };
 
-struct AstTopScope : public AstNode {
+class AstTopScope : public AstNode {
     // In the top level netlist, a complete scope tree
     // There may be two of these, when we support "rare" and "usual" splitting
     // Parents: topMODULE
     // Children: SCOPEs
+public:
     AstTopScope(FileLine* fl, AstScope* ascopep)
 	:AstNode(fl)
 	{addNOp2p(ascopep);}
@@ -1182,7 +1192,7 @@ struct AstTopScope : public AstNode {
     AstScope* scopep()		const { return op2p()->castScope(); }	// op1 = AstVarScope's
 };
 
-struct AstVarScope : public AstNode {
+class AstVarScope : public AstNode {
     // A particular scoped usage of a variable
     // That is, as a module is used under multiple cells, we get a different varscope for each var in the module
     // Parents: MODULE
@@ -1218,8 +1228,9 @@ public:
     void	circular(bool flag) { m_circular = flag; }
 };
 
-struct AstVarRef : public AstNodeVarRef {
+class AstVarRef : public AstNodeVarRef {
     // A reference to a variable (lvalue or rvalue)
+public:
     AstVarRef(FileLine* fl, const string& name, bool lvalue)
 	:AstNodeVarRef(fl, name, NULL, lvalue) {}
     AstVarRef(FileLine* fl, AstVar* varp, bool lvalue)  // This form only allowed post-link
@@ -1248,7 +1259,7 @@ struct AstVarRef : public AstNodeVarRef {
     virtual bool cleanOut() { return true; }
 };
 
-struct AstVarXRef : public AstNodeVarRef {
+class AstVarXRef : public AstNodeVarRef {
     // A VarRef to something in another module before AstScope.
     // Includes pin on a cell, as part of a ASSIGN statement to connect I/Os until AstScope
 private:
@@ -1281,7 +1292,7 @@ public:
 		&& dotted()==samep->castVarXRef()->dotted()); }
 };
 
-struct AstPin : public AstNode {
+class AstPin : public AstNode {
     // A pin on a cell
 private:
     int		m_pinNum;	// Pin number
@@ -1324,7 +1335,7 @@ public:
     void        svImplicit(bool flag) { m_svImplicit=flag; }
 };
 
-struct AstArg : public AstNode {
+class AstArg : public AstNode {
     // An argument to a function/task
 private:
     string	m_name;		// Pin name, or "" for number based interconnect
@@ -1343,24 +1354,27 @@ public:
     bool	emptyConnectNoNext() const { return !exprp() && name()=="" && !nextp(); }
 };
 
-struct AstModule : public AstNodeModule {
+class AstModule : public AstNodeModule {
     // A module declaration
+public:
     AstModule(FileLine* fl, const string& name)
 	: AstNodeModule (fl,name) {}
     ASTNODE_NODE_FUNCS(Module, MODULE)
     virtual string verilogKwd() const { return "module"; }
 };
 
-struct AstNotFoundModule : public AstNodeModule {
+class AstNotFoundModule : public AstNodeModule {
     // A missing module declaration
+public:
     AstNotFoundModule(FileLine* fl, const string& name)
 	: AstNodeModule (fl,name) {}
     ASTNODE_NODE_FUNCS(NotFoundModule, NOTFOUNDMODULE)
     virtual string verilogKwd() const { return "/*not-found-*/ module"; }
 };
 
-struct AstPackage : public AstNodeModule {
+class AstPackage : public AstNodeModule {
     // A package declaration
+public:
     AstPackage(FileLine* fl, const string& name)
 	: AstNodeModule (fl,name) {}
     ASTNODE_NODE_FUNCS(Package, PACKAGE)
@@ -1369,15 +1383,16 @@ struct AstPackage : public AstNodeModule {
     bool isDollarUnit() const { return name() == dollarUnitName(); }
 };
 
-struct AstPrimitive : public AstNodeModule {
+class AstPrimitive : public AstNodeModule {
     // A primitive declaration
+public:
     AstPrimitive(FileLine* fl, const string& name)
 	: AstNodeModule (fl,name) {}
     ASTNODE_NODE_FUNCS(Primitive, PRIMITIVE)
     virtual string verilogKwd() const { return "primitive"; }
 };
 
-struct AstPackageImport : public AstNode {
+class AstPackageImport : public AstNode {
 private:
     // A package import declaration
     string	m_name;
@@ -1394,14 +1409,15 @@ public:
     void packagep(AstPackage* nodep) { m_packagep=nodep; }
 };
 
-struct AstIface : public AstNodeModule {
+class AstIface : public AstNodeModule {
     // A module declaration
+public:
     AstIface(FileLine* fl, const string& name)
 	: AstNodeModule (fl,name) { }
     ASTNODE_NODE_FUNCS(Iface, IFACE)
 };
 
-struct AstModportFTaskRef : public AstNode {
+class AstModportFTaskRef : public AstNode {
     // An import/export referenced under a modport
     // The storage for the function itself is inside the interface/instantiator, thus this is a reference
     // PARENT: AstModport
@@ -1423,7 +1439,7 @@ public:
     void ftaskp(AstNodeFTask* ftaskp) { m_ftaskp=ftaskp; }
 };
 
-struct AstModportVarRef : public AstNode {
+class AstModportVarRef : public AstNode {
     // A input/output/etc variable referenced under a modport
     // The storage for the variable itself is inside the interface, thus this is a reference
     // PARENT: AstModport
@@ -1446,7 +1462,7 @@ public:
     void varp(AstVar* varp) { m_varp=varp; }
 };
 
-struct AstModport : public AstNode {
+class AstModport : public AstNode {
     // A modport in an interface
 private:
     string	m_name;		// Name of the modport
@@ -1460,7 +1476,7 @@ public:
     AstNode* varsp() const { return op1p(); }	// op1 = List of Vars
 };
 
-struct AstCell : public AstNode {
+class AstCell : public AstNode {
     // A instantiation cell or interface call (don't know which until link)
 private:
     string	m_name;		// Cell name
@@ -1498,7 +1514,7 @@ public:
     void hasIfaceVar(bool flag) { m_hasIfaceVar = flag; }
 };
 
-struct AstCellInline : public AstNode {
+class AstCellInline : public AstNode {
     // A instantiation cell that was removed by inlining
     // For communication between V3Inline and V3LinkDot only
     // Children: When 2 levels inlined, other CellInline under this
@@ -1517,7 +1533,7 @@ public:
     virtual void name(const string& name) { m_name = name; }
 };
 
-struct AstBind : public AstNode {
+class AstBind : public AstNode {
     // Parents: MODULE
     // Children: CELL
 private:
@@ -1536,7 +1552,7 @@ public:
     AstNode* cellsp() const { return op1p(); }	// op1= cells
 };
 
-struct AstPort : public AstNode {
+class AstPort : public AstNode {
     // A port (in/out/inout) on a module
 private:
     int		m_pinNum;	// Pin number
@@ -1553,10 +1569,11 @@ public:
 
 //######################################################################
 
-struct AstGenerate : public AstNode {
+class AstGenerate : public AstNode {
     // A Generate/end block
     // Parents: MODULE
     // Children: modItems
+public:
     AstGenerate(FileLine* fileline, AstNode* stmtsp)
 	: AstNode(fileline) {
 	addNOp1p(stmtsp);
@@ -1567,7 +1584,7 @@ struct AstGenerate : public AstNode {
     void addStmtp(AstNode* nodep) { addOp1p(nodep); }
 };
 
-struct AstParseRef : public AstNode {
+class AstParseRef : public AstNode {
     // A reference to a variable, function or task
     // We don't know which at parse time due to bison constraints
     // The link stages will replace this with AstVarRef, or AstTaskRef, etc.
@@ -1597,7 +1614,7 @@ public:
     void ftaskrefp(AstNodeFTaskRef* nodep) { setNOp2p(nodep); }	// op2 = Function/task reference
 };
 
-struct AstPackageRef : public AstNode {
+class AstPackageRef : public AstNode {
 private:
     AstPackage*	m_packagep;	// Package hierarchy
 public:
@@ -1617,7 +1634,7 @@ public:
     void packagep(AstPackage* nodep) { m_packagep=nodep; }
 };
 
-struct AstDot : public AstNode {
+class AstDot : public AstNode {
     // A dot separating paths in an AstXRef, AstFuncRef or AstTaskRef
     // These are eliminated in the link stage
 public:
@@ -1637,15 +1654,17 @@ public:
 
 //######################################################################
 
-struct AstTask : public AstNodeFTask {
+class AstTask : public AstNodeFTask {
     // A task inside a module
+public:
     AstTask(FileLine* fl, const string& name, AstNode* stmtp)
 	:AstNodeFTask(fl, name, stmtp) {}
     ASTNODE_NODE_FUNCS(Task, TASK)
 };
 
-struct AstFunc : public AstNodeFTask {
+class AstFunc : public AstNodeFTask {
     // A function inside a module
+public:
     AstFunc(FileLine* fl, const string& name, AstNode* stmtp, AstNode* fvarsp)
 	:AstNodeFTask(fl, name, stmtp) {
 	addNOp1p(fvarsp);
@@ -1654,8 +1673,9 @@ struct AstFunc : public AstNodeFTask {
     virtual bool hasDType() const { return true; }
 };
 
-struct AstTaskRef : public AstNodeFTaskRef {
+class AstTaskRef : public AstNodeFTaskRef {
     // A reference to a task
+public:
     AstTaskRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
 	:AstNodeFTaskRef(fl, namep, pinsp) {}
     AstTaskRef(FileLine* fl, const string& name, AstNode* pinsp)
@@ -1663,8 +1683,9 @@ struct AstTaskRef : public AstNodeFTaskRef {
     ASTNODE_NODE_FUNCS(TaskRef, TASKREF)
 };
 
-struct AstFuncRef : public AstNodeFTaskRef {
+class AstFuncRef : public AstNodeFTaskRef {
     // A reference to a function
+public:
     AstFuncRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
 	:AstNodeFTaskRef(fl, namep, pinsp) {}
     AstFuncRef(FileLine* fl, const string& name, AstNode* pinsp)
@@ -1673,7 +1694,7 @@ struct AstFuncRef : public AstNodeFTaskRef {
     virtual bool hasDType() const { return true; }
 };
 
-struct AstDpiExport : public AstNode {
+class AstDpiExport : public AstNode {
     // We could put an AstNodeFTaskRef instead of the verilog function name,
     // however we're not *calling* it, so that seems somehow wrong.
     // (Probably AstNodeFTaskRef should be renamed AstNodeFTaskCall and have-a AstNodeFTaskRef)
@@ -1692,7 +1713,7 @@ public:
 
 //######################################################################
 
-struct AstSenItem : public AstNodeSenItem {
+class AstSenItem : public AstNodeSenItem {
     // Parents:  SENTREE
     // Children: (optional) VARREF SENGATE
 private:
@@ -1740,11 +1761,12 @@ public:
     bool hasVar() const { return !(isCombo()||isInitial()||isSettle()||isNever()); }
 };
 
-struct AstSenGate : public AstNodeSenItem {
+class AstSenGate : public AstNodeSenItem {
     // Parents:  SENTREE
     // Children: SENITEM expr
     // AND as applied to a sensitivity list and a gating expression
     // Performing this gating is optional; it may be removed by later optimizations
+public:
     AstSenGate(FileLine* fl, AstSenItem* sensesp, AstNode* rhsp) : AstNodeSenItem(fl) {
 	dtypeSetLogicBool(); addOp1p(sensesp); setOp2p(rhsp);
     }
@@ -1762,7 +1784,7 @@ struct AstSenGate : public AstNodeSenItem {
     virtual bool isNever() const { return false; }
 };
 
-struct AstSenTree : public AstNode {
+class AstSenTree : public AstNode {
     // A list of senitems
     // Parents:  MODULE | SBLOCK
     // Children: SENITEM list
@@ -1787,7 +1809,7 @@ public:
     bool hasCombo();	// Includes a COMBO SenItem
 };
 
-struct AstAlways : public AstNode {
+class AstAlways : public AstNode {
     VAlwaysKwd m_keyword;
 public:
     AstAlways(FileLine* fl, VAlwaysKwd keyword, AstSenTree* sensesp, AstNode* bodysp)
@@ -1805,9 +1827,10 @@ public:
     bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); }
 };
 
-struct AstAlwaysPublic : public AstNodeStmt {
+class AstAlwaysPublic : public AstNodeStmt {
     // "Fake" sensitivity created by /*verilator public_flat_rw @(edgelist)*/
     // Body statements are just AstVarRefs to the public signals
+public:
     AstAlwaysPublic(FileLine* fl, AstSenTree* sensesp, AstNode* bodysp)
 	: AstNodeStmt(fl) {
 	addNOp1p(sensesp); addNOp2p(bodysp);
@@ -1823,8 +1846,9 @@ struct AstAlwaysPublic : public AstNodeStmt {
     bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); }
 };
 
-struct AstAlwaysPost : public AstNode {
+class AstAlwaysPost : public AstNode {
     // Like always but post assignments for memory assignment IFs
+public:
     AstAlwaysPost(FileLine* fl, AstSenTree* sensesp, AstNode* bodysp)
 	: AstNode(fl) {
 	addNOp1p(sensesp); addNOp2p(bodysp);
@@ -1835,7 +1859,8 @@ struct AstAlwaysPost : public AstNode {
     void	addBodysp(AstNode* newp)	{ addOp2p(newp); }
 };
 
-struct AstAssign : public AstNodeAssign {
+class AstAssign : public AstNodeAssign {
+public:
     AstAssign(FileLine* fileline, AstNode* lhsp, AstNode* rhsp)
 	: AstNodeAssign(fileline, lhsp, rhsp) {
 	dtypeFrom(lhsp);
@@ -1844,16 +1869,18 @@ struct AstAssign : public AstNodeAssign {
     virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssign(this->fileline(), lhsp, rhsp); }
 };
 
-struct AstAssignAlias : public AstNodeAssign {
+class AstAssignAlias : public AstNodeAssign {
     // Like AstAssignW, but a true bidirect interconnection alias
     // If both sides are wires, there's no LHS vs RHS,
+public:
     AstAssignAlias(FileLine* fileline, AstVarRef* lhsp, AstVarRef* rhsp)
 	: AstNodeAssign(fileline, lhsp, rhsp) {}
     ASTNODE_NODE_FUNCS(AssignAlias, ASSIGNALIAS)
     virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { V3ERROR_NA; return NULL; }
 };
 
-struct AstAssignDly : public AstNodeAssign {
+class AstAssignDly : public AstNodeAssign {
+public:
     AstAssignDly(FileLine* fileline, AstNode* lhsp, AstNode* rhsp)
 	: AstNodeAssign(fileline, lhsp, rhsp) {}
     ASTNODE_NODE_FUNCS(AssignDly, ASSIGNDLY)
@@ -1862,8 +1889,9 @@ struct AstAssignDly : public AstNodeAssign {
     virtual string verilogKwd() const { return "<="; }
 };
 
-struct AstAssignW : public AstNodeAssign {
+class AstAssignW : public AstNodeAssign {
     // Like assign, but wire/assign's in verilog, the only setting of the specified variable
+public:
     AstAssignW(FileLine* fileline, AstNode* lhsp, AstNode* rhsp)
 	: AstNodeAssign(fileline, lhsp, rhsp) { }
     ASTNODE_NODE_FUNCS(AssignW, ASSIGNW)
@@ -1878,8 +1906,9 @@ struct AstAssignW : public AstNodeAssign {
     }
 };
 
-struct AstAssignVarScope : public AstNodeAssign {
+class AstAssignVarScope : public AstNodeAssign {
     // Assign two VarScopes to each other
+public:
     AstAssignVarScope(FileLine* fileline, AstNode* lhsp, AstNode* rhsp)
 	: AstNodeAssign(fileline, lhsp, rhsp) {
 	dtypeFrom(rhsp);
@@ -1888,7 +1917,7 @@ struct AstAssignVarScope : public AstNodeAssign {
     virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignVarScope(this->fileline(), lhsp, rhsp); }
 };
 
-struct AstPull : public AstNode {
+class AstPull : public AstNode {
 private:
     bool m_direction;
 public:
@@ -1905,23 +1934,25 @@ public:
     uint32_t direction() const { return (uint32_t) m_direction; }
 };
 
-struct AstAssignPre : public AstNodeAssign {
+class AstAssignPre : public AstNodeAssign {
     // Like Assign, but predelayed assignment requiring special order handling
+public:
     AstAssignPre(FileLine* fileline, AstNode* lhsp, AstNode* rhsp)
 	: AstNodeAssign(fileline, lhsp, rhsp) {}
     ASTNODE_NODE_FUNCS(AssignPre, ASSIGNPRE)
     virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignPre(this->fileline(), lhsp, rhsp); }
 };
 
-struct AstAssignPost : public AstNodeAssign {
+class AstAssignPost : public AstNodeAssign {
     // Like Assign, but predelayed assignment requiring special order handling
+public:
     AstAssignPost(FileLine* fileline, AstNode* lhsp, AstNode* rhsp)
 	: AstNodeAssign(fileline, lhsp, rhsp) {}
     ASTNODE_NODE_FUNCS(AssignPost, ASSIGNPOST)
     virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignPost(this->fileline(), lhsp, rhsp); }
 };
 
-struct AstComment : public AstNodeStmt {
+class AstComment : public AstNodeStmt {
     // Some comment to put into the output stream
     // Parents:  {statement list}
     // Children: none
@@ -1937,25 +1968,27 @@ public:
     virtual bool same(AstNode* samep) const { return true; }  // Ignore name in comments
 };
 
-struct AstCond : public AstNodeCond {
+class AstCond : public AstNodeCond {
     // Conditional ?: statement
     // Parents:  MATH
     // Children: MATH
+public:
     AstCond(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p)
 	: AstNodeCond(fl, condp, expr1p, expr2p) {}
     ASTNODE_NODE_FUNCS(Cond, COND)
 };
 
-struct AstCondBound : public AstNodeCond {
+class AstCondBound : public AstNodeCond {
     // Conditional ?: statement, specially made for saftey checking of array bounds
     // Parents:  MATH
     // Children: MATH
+public:
     AstCondBound(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p)
 	: AstNodeCond(fl, condp, expr1p, expr2p) {}
     ASTNODE_NODE_FUNCS(CondBound, CONDBOUND)
 };
 
-struct AstCoverDecl : public AstNodeStmt {
+class AstCoverDecl : public AstNodeStmt {
     // Coverage analysis point declaration
     // Parents:  {statement list}
     // Children: none
@@ -2003,7 +2036,7 @@ public:
     AstCoverDecl*	dataDeclThisp() { return dataDeclNullp()?dataDeclNullp():this; }
 };
 
-struct AstCoverInc : public AstNodeStmt {
+class AstCoverInc : public AstNodeStmt {
     // Coverage analysis point; increment coverage count
     // Parents:  {statement list}
     // Children: none
@@ -2029,10 +2062,11 @@ public:
     AstCoverDecl*	declp() const { return m_declp; }	// Where defined
 };
 
-struct AstCoverToggle : public AstNodeStmt {
+class AstCoverToggle : public AstNodeStmt {
     // Toggle analysis of given signal
     // Parents:  MODULE
     // Children: AstCoverInc, orig var, change det var
+public:
     AstCoverToggle(FileLine* fl, AstCoverInc* incp, AstNode* origp, AstNode* changep)
 	: AstNodeStmt(fl) {
 	setOp1p(incp);
@@ -2053,18 +2087,19 @@ struct AstCoverToggle : public AstNodeStmt {
     AstNode* changep() const { return op3p(); }
 };
 
-struct AstGenCase : public AstNodeCase {
+class AstGenCase : public AstNodeCase {
     // Generate Case statement
     // Parents:  {statement list}
     // exprp Children:  MATHs
     // casesp Children: CASEITEMs
+public:
     AstGenCase(FileLine* fileline, AstNode* exprp, AstNode* casesp)
 	: AstNodeCase(fileline, exprp, casesp) {
     }
     ASTNODE_NODE_FUNCS(GenCase, GENCASE)
 };
 
-struct AstCase : public AstNodeCase {
+class AstCase : public AstNodeCase {
     // Case statement
     // Parents:  {statement list}
     // exprp Children:  MATHs
@@ -2104,7 +2139,7 @@ public:
     void	priorityPragma(bool flag) { m_priorityPragma=flag; }
 };
 
-struct AstCaseItem : public AstNode {
+class AstCaseItem : public AstNode {
     // Single item of a case statement
     // Parents:  CASE
     // condsp Children: MATH  (Null condition used for default block)
@@ -2128,7 +2163,7 @@ public:
     void	ignoreOverlap(bool flag) { m_ignoreOverlap = flag; }
 };
 
-struct AstSFormatF : public AstNode {
+class AstSFormatF : public AstNode {
     // Convert format to string, generally under an AstDisplay or AstSFormat
     // Also used as "real" function for /*verilator sformat*/ functions
     string	m_text;
@@ -2154,7 +2189,7 @@ public:
     bool hidden() const { return m_hidden; }
 };
 
-struct AstDisplay : public AstNodeStmt {
+class AstDisplay : public AstNodeStmt {
     // Parents: stmtlist
     // Children: file which must be a varref
     // Children: SFORMATF to generate print string
@@ -2189,12 +2224,13 @@ public:
     void 	filep(AstNodeVarRef* nodep) { setNOp3p(nodep); }
 };
 
-struct AstSFormat : public AstNode {
+class AstSFormat : public AstNodeStmt {
     // Parents: statement container
     // Children: string to load
     // Children: SFORMATF to generate print string
+public:
     AstSFormat(FileLine* fileline, AstNode* lhsp, const string& text, AstNode* exprsp)
-	: AstNode (fileline) {
+	: AstNodeStmt (fileline) {
 	setOp1p(new AstSFormatF(fileline,text,true,exprsp));
 	setOp3p(lhsp);
     }
@@ -2217,9 +2253,10 @@ struct AstSFormat : public AstNode {
     void 	lhsp(AstNode* nodep) { setOp3p(nodep); }
 };
 
-struct AstSysIgnore : public AstNodeStmt {
+class AstSysIgnore : public AstNodeStmt {
     // Parents: stmtlist
     // Children: varrefs or exprs
+public:
     AstSysIgnore(FileLine* fileline, AstNode* exprsp)
 	: AstNodeStmt (fileline) { addNOp1p(exprsp); }
     ASTNODE_NODE_FUNCS(SysIgnore, SYSIGNORE)
@@ -2233,9 +2270,10 @@ struct AstSysIgnore : public AstNodeStmt {
     void 	exprsp(AstNode* nodep)	{ addOp1p(nodep); }	// op1 = Expressions to output
 };
 
-struct AstFClose : public AstNodeStmt {
+class AstFClose : public AstNodeStmt {
     // Parents: stmtlist
     // Children: file which must be a varref
+public:
     AstFClose(FileLine* fileline, AstNode* filep)
 	: AstNodeStmt (fileline) {
 	setNOp2p(filep);
@@ -2253,8 +2291,9 @@ struct AstFClose : public AstNodeStmt {
     void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
 };
 
-struct AstFOpen : public AstNodeStmt {
+class AstFOpen : public AstNodeStmt {
     // Although a system function in IEEE, here a statement which sets the file pointer (MCD)
+public:
     AstFOpen(FileLine* fileline, AstNode* filep, AstNode* filenamep, AstNode* modep)
 	: AstNodeStmt (fileline) {
 	setOp1p(filep);
@@ -2275,9 +2314,10 @@ struct AstFOpen : public AstNodeStmt {
     AstNode*	modep() const { return op3p(); }
 };
 
-struct AstFFlush : public AstNodeStmt {
+class AstFFlush : public AstNodeStmt {
     // Parents: stmtlist
     // Children: file which must be a varref
+public:
     AstFFlush(FileLine* fileline, AstNode* filep)
 	: AstNodeStmt (fileline) {
 	setNOp2p(filep);
@@ -2295,7 +2335,7 @@ struct AstFFlush : public AstNodeStmt {
     void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
 };
 
-struct AstFScanF : public AstNodeMath {
+class AstFScanF : public AstNodeMath {
     // Parents: expr
     // Children: file which must be a varref
     // Children: varrefs to load
@@ -2328,7 +2368,7 @@ public:
     void 	filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
 };
 
-struct AstSScanF : public AstNodeMath {
+class AstSScanF : public AstNodeMath {
     // Parents: expr
     // Children: file which must be a varref
     // Children: varrefs to load
@@ -2361,7 +2401,7 @@ public:
     void 	fromp(AstNode* nodep) { setOp2p(nodep); }
 };
 
-struct AstReadMem : public AstNodeStmt {
+class AstReadMem : public AstNodeStmt {
 private:
     bool	m_isHex;	// readmemh, not readmemb
 public:
@@ -2386,8 +2426,9 @@ public:
     AstNode*	msbp() const { return op4p()->castNode(); }
 };
 
-struct AstSystemT : public AstNodeStmt {
+class AstSystemT : public AstNodeStmt {
     // $system used as task
+public:
     AstSystemT(FileLine* fileline, AstNode* lhsp)
 	: AstNodeStmt (fileline) {
 	setOp1p(lhsp);
@@ -2404,8 +2445,9 @@ struct AstSystemT : public AstNodeStmt {
     AstNode*	lhsp() const { return op1p(); }
 };
 
-struct AstSystemF : public AstNodeMath {
+class AstSystemF : public AstNodeMath {
     // $system used as function
+public:
     AstSystemF(FileLine* fileline, AstNode* lhsp)
 	: AstNodeMath (fileline) {
 	setOp1p(lhsp);
@@ -2425,7 +2467,7 @@ struct AstSystemF : public AstNodeMath {
     AstNode*	lhsp() const { return op1p(); }
 };
 
-struct AstValuePlusArgs : public AstNodeMath {
+class AstValuePlusArgs : public AstNodeMath {
     // Parents: expr
     // Child: variable to set.  If NULL then this is a $test$plusargs instead of $value$plusargs
 private:
@@ -2452,7 +2494,7 @@ public:
     void 	text(const string& text) { m_text=text; }
 };
 
-struct AstTestPlusArgs : public AstNodeMath {
+class AstTestPlusArgs : public AstNodeMath {
     // Parents: expr
     // Child: variable to set.  If NULL then this is a $test$plusargs instead of $value$plusargs
 private:
@@ -2475,7 +2517,8 @@ public:
     void 	text(const string& text) { m_text=text; }
 };
 
-struct AstGenFor : public AstNodeFor {
+class AstGenFor : public AstNodeFor {
+public:
     AstGenFor(FileLine* fileline, AstNode* initsp, AstNode* condp,
 	   AstNode* incsp, AstNode* bodysp)
 	: AstNodeFor(fileline, initsp, condp, incsp, bodysp) {
@@ -2483,7 +2526,8 @@ struct AstGenFor : public AstNodeFor {
     ASTNODE_NODE_FUNCS(GenFor, GENFOR)
 };
 
-struct AstRepeat : public AstNodeStmt {
+class AstRepeat : public AstNodeStmt {
+public:
     AstRepeat(FileLine* fileline, AstNode* countp, AstNode* bodysp)
 	: AstNodeStmt(fileline) {
 	setOp2p(countp); addNOp3p(bodysp);
@@ -2497,7 +2541,8 @@ struct AstRepeat : public AstNodeStmt {
     virtual bool same(AstNode* samep) const { return true; }
 };
 
-struct AstWhile : public AstNodeStmt {
+class AstWhile : public AstNodeStmt {
+public:
     AstWhile(FileLine* fileline, AstNode* condp, AstNode* bodysp, AstNode* incsp=NULL)
 	: AstNodeStmt(fileline) {
 	setOp2p(condp); addNOp3p(bodysp); addNOp4p(incsp);
@@ -2518,7 +2563,8 @@ struct AstWhile : public AstNodeStmt {
     virtual void addNextStmt(AstNode* newp, AstNode* belowp);  // Stop statement searchback here
 };
 
-struct AstBreak : public AstNodeStmt {
+class AstBreak : public AstNodeStmt {
+public:
     AstBreak(FileLine* fileline)
 	: AstNodeStmt (fileline) {}
     ASTNODE_NODE_FUNCS(Break, BREAK)
@@ -2527,7 +2573,8 @@ struct AstBreak : public AstNodeStmt {
     virtual bool isBrancher() const { return true; }	// SPECIAL: We don't process code after breaks
 };
 
-struct AstContinue : public AstNodeStmt {
+class AstContinue : public AstNodeStmt {
+public:
     AstContinue(FileLine* fileline)
 	: AstNodeStmt (fileline) {}
     ASTNODE_NODE_FUNCS(Continue, CONTINUE)
@@ -2536,7 +2583,7 @@ struct AstContinue : public AstNodeStmt {
     virtual bool isBrancher() const { return true; }	// SPECIAL: We don't process code after breaks
 };
 
-struct AstDisable : public AstNodeStmt {
+class AstDisable : public AstNodeStmt {
 private:
     string	m_name;		// Name of block
 public:
@@ -2548,7 +2595,8 @@ public:
     virtual bool isBrancher() const { return true; }	// SPECIAL: We don't process code after breaks
 };
 
-struct AstReturn : public AstNodeStmt {
+class AstReturn : public AstNodeStmt {
+public:
     AstReturn(FileLine* fileline, AstNode* lhsp=NULL)
 	: AstNodeStmt (fileline) {
 	setNOp1p(lhsp);
@@ -2560,14 +2608,15 @@ struct AstReturn : public AstNodeStmt {
     virtual bool isBrancher() const { return true; }	// SPECIAL: We don't process code after breaks
 };
 
-struct AstGenIf : public AstNodeIf {
+class AstGenIf : public AstNodeIf {
+public:
     AstGenIf(FileLine* fileline, AstNode* condp, AstNode* ifsp, AstNode* elsesp)
 	: AstNodeIf(fileline, condp, ifsp, elsesp) {
     }
     ASTNODE_NODE_FUNCS(GenIf, GENIF)
 };
 
-struct AstIf : public AstNodeIf {
+class AstIf : public AstNodeIf {
 private:
     bool	m_uniquePragma;		// unique case
     bool	m_unique0Pragma;	// unique0 case
@@ -2586,7 +2635,7 @@ public:
     void	priorityPragma(bool flag) { m_priorityPragma=flag; }
 };
 
-struct AstJumpLabel : public AstNodeStmt {
+class AstJumpLabel : public AstNodeStmt {
     // Jump point declaration
     // Separate from AstJumpGo; as a declaration can't be deleted
     // Parents:  {statement list}
@@ -2610,7 +2659,7 @@ public:
     void labelNum(int flag) { m_labelNum=flag; }
 };
 
-struct AstJumpGo : public AstNodeStmt {
+class AstJumpGo : public AstNodeStmt {
     // Jump point; branch up to the JumpLabel
     // Parents:  {statement list}
 private:
@@ -2633,10 +2682,11 @@ public:
     AstJumpLabel* labelp() const { return m_labelp; }
 };
 
-struct AstUntilStable : public AstNodeStmt {
+class AstUntilStable : public AstNodeStmt {
     // Quasi-while loop until given signals are stable
     // Parents: CFUNC (generally)
     // Children: VARREF, statements
+public:
     AstUntilStable(FileLine* fileline, AstVarRef* stablesp, AstNode* bodysp)
 	: AstNodeStmt(fileline) {
 	addNOp2p(stablesp); addNOp3p(bodysp);
@@ -2653,11 +2703,12 @@ struct AstUntilStable : public AstNodeStmt {
     virtual bool same(AstNode* samep) const { return true; }
 };
 
-struct AstChangeXor : public AstNodeBiComAsv {
+class AstChangeXor : public AstNodeBiComAsv {
     // A comparison to determine change detection, common & must be fast.
     // Returns 32-bit or 64-bit value where 0 indicates no change.
     // Parents: OR or LOGOR
     // Children: VARREF
+public:
     AstChangeXor(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
 	: AstNodeBiComAsv(fl, lhsp, rhsp) {
 	dtypeSetUInt32(); // Always used on, and returns word entities
@@ -2673,7 +2724,7 @@ struct AstChangeXor : public AstNodeBiComAsv {
     virtual int instrCount()	const { return widthInstrs(); }
 };
 
-struct AstChangeDet : public AstNodeStmt {
+class AstChangeDet : public AstNodeStmt {
     // A comparison to determine change detection, common & must be fast.
 private:
     bool	m_clockReq;	// Type of detection
@@ -2694,7 +2745,7 @@ public:
     virtual bool same(AstNode* samep) const { return true; }
 };
 
-struct AstBegin : public AstNode {
+class AstBegin : public AstNode {
     // A Begin/end named block, only exists shortly after parsing until linking
     // Parents: statement
     // Children: statements
@@ -2726,7 +2777,8 @@ public:
     bool generate() const { return m_generate; }
 };
 
-struct AstInitial : public AstNode {
+class AstInitial : public AstNode {
+public:
     AstInitial(FileLine* fl, AstNode* bodysp)
 	: AstNode(fl) {
 	addNOp1p(bodysp);
@@ -2737,7 +2789,8 @@ struct AstInitial : public AstNode {
     bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); }
 };
 
-struct AstFinal : public AstNode {
+class AstFinal : public AstNode {
+public:
     AstFinal(FileLine* fl, AstNode* bodysp)
 	: AstNode(fl) {
 	addNOp1p(bodysp);
@@ -2746,7 +2799,8 @@ struct AstFinal : public AstNode {
     AstNode*	bodysp() 	const { return op1p()->castNode(); }	// op1 = Expressions to evaluate
 };
 
-struct AstInside : public AstNodeMath {
+class AstInside : public AstNodeMath {
+public:
     AstInside(FileLine* fl, AstNode* exprp, AstNode* itemsp)
 	: AstNodeMath(fl) {
 	addOp1p(exprp); addOp2p(itemsp);
@@ -2760,7 +2814,8 @@ struct AstInside : public AstNodeMath {
     virtual bool cleanOut() { return false; }  // NA
 };
 
-struct AstInsideRange : public AstNodeMath {
+class AstInsideRange : public AstNodeMath {
+public:
     AstInsideRange(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
 	: AstNodeMath(fl) {
 	addOp1p(lhsp); addOp2p(rhsp);
@@ -2773,12 +2828,13 @@ struct AstInsideRange : public AstNodeMath {
     virtual bool cleanOut() { return false; }  // NA
 };
 
-struct AstInitArray : public AstNode {
+class AstInitArray : public AstNode {
     // Set a var to a large list of values
     // The values must be in sorted order, and not exceed the size of the var's array.
     // The first value on the initsp() list is for the lo() index of the array.
     // Parents: ASTVAR::init()
     // Children: CONSTs...
+public:
     AstInitArray(FileLine* fl, AstNodeArrayDType* newDTypep, AstNode* initsp)
 	: AstNode(fl) {
 	dtypep(newDTypep);
@@ -2792,7 +2848,7 @@ struct AstInitArray : public AstNode {
     virtual bool same(AstNode* samep) const { return true; }
 };
 
-struct AstPragma : public AstNode {
+class AstPragma : public AstNode {
 private:
     AstPragmaType	m_pragType;	// Type of pragma
 public:
@@ -2810,7 +2866,8 @@ public:
 	return pragType()==samep->castPragma()->pragType(); }
 };
 
-struct AstStop : public AstNodeStmt {
+class AstStop : public AstNodeStmt {
+public:
     AstStop(FileLine* fl)
 	: AstNodeStmt(fl) {}
     ASTNODE_NODE_FUNCS(Stop, STOP)
@@ -2825,7 +2882,8 @@ struct AstStop : public AstNodeStmt {
 	return fileline() == samep->fileline(); }
 };
 
-struct AstFinish : public AstNodeStmt {
+class AstFinish : public AstNodeStmt {
+public:
     AstFinish(FileLine* fl)
 	: AstNodeStmt(fl) {}
     ASTNODE_NODE_FUNCS(Finish, FINISH)
@@ -2840,7 +2898,7 @@ struct AstFinish : public AstNodeStmt {
 	return fileline() == samep->fileline(); }
 };
 
-struct AstTraceDecl : public AstNodeStmt {
+class AstTraceDecl : public AstNodeStmt {
     // Trace point declaration
     // Separate from AstTraceInc; as a declaration can't be deleted
     // Parents:  {statement list}
@@ -2876,7 +2934,7 @@ public:
     const VNumRange& arrayRange() const { return m_arrayRange; }
 };
 
-struct AstTraceInc : public AstNodeStmt {
+class AstTraceInc : public AstNodeStmt {
     // Trace point; incremental change detect and dump
     // Parents:  {statement list}
     // Children: incremental value
@@ -2910,7 +2968,7 @@ public:
     AstNode*	valuep() 	const { return op2p()->castNode(); }
 };
 
-struct AstActive : public AstNode {
+class AstActive : public AstNode {
     // Block of code with sensitivity activation
     // Parents:  MODULE | CFUNC
     // Children: SENTREE, statements
@@ -2949,7 +3007,7 @@ public:
     bool hasClocked() const { return m_sensesp->hasClocked(); }
 };
 
-struct AstAttrOf : public AstNode {
+class AstAttrOf : public AstNode {
 private:
     // Return a value of a attribute, for example a LSB or array LSB of a signal
     AstAttrType	m_attrType;	// What sort of extraction
@@ -2966,7 +3024,7 @@ public:
     virtual void dump(ostream& str=cout);
 };
 
-struct AstScopeName : public AstNodeMath {
+class AstScopeName : public AstNodeMath {
     // For display %m and DPI context imports
     // Parents:  DISPLAY
     // Children: TEXT
@@ -2983,13 +3041,17 @@ public:
     virtual bool cleanOut() { return true; }
     AstText*	scopeAttrp() const { return op1p()->castText(); }
     void 	scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
+    AstText*	scopeEntrp() const { return op2p()->castText(); }
+    void 	scopeEntrp(AstNode* nodep) { addOp2p(nodep); }
     string scopeSymName() const;  // Name for __Vscope variable including children
+    string scopeDpiName() const;  // Name for DPI import scope
     string scopePrettyName() const;  // Name for __Vscope printing
     bool dpiExport() const { return m_dpiExport; }
     void dpiExport(bool flag) { m_dpiExport=flag; }
 };
 
-struct AstUdpTable : public AstNode {
+class AstUdpTable : public AstNode {
+public:
     AstUdpTable(FileLine* fl, AstNode* bodysp)
 	: AstNode(fl) {
 	addNOp1p(bodysp);
@@ -2998,7 +3060,7 @@ struct AstUdpTable : public AstNode {
     AstUdpTableLine*	bodysp() 	const { return op1p()->castUdpTableLine(); }	// op1 = List of UdpTableLines
 };
 
-struct AstUdpTableLine : public AstNode {
+class AstUdpTableLine : public AstNode {
     string	m_text;
 public:
     AstUdpTableLine(FileLine* fl, const string& text)
@@ -3011,7 +3073,7 @@ public:
 //======================================================================
 // non-ary ops
 
-struct AstRand : public AstNodeTermop {
+class AstRand : public AstNodeTermop {
     // Return a random number, based upon width()
 private:
     bool	m_reset;	// Random reset, versus always random
@@ -3033,7 +3095,8 @@ public:
     virtual bool same(AstNode* samep) const { return true; }
 };
 
-struct AstTime : public AstNodeTermop {
+class AstTime : public AstNodeTermop {
+public:
     AstTime(FileLine* fl)	: AstNodeTermop(fl) {
 	dtypeSetUInt64(); }
     ASTNODE_NODE_FUNCS(Time, TIME)
@@ -3047,7 +3110,8 @@ struct AstTime : public AstNodeTermop {
     virtual bool same(AstNode* samep) const { return true; }
 };
 
-struct AstTimeD : public AstNodeTermop {
+class AstTimeD : public AstNodeTermop {
+public:
     AstTimeD(FileLine* fl)	: AstNodeTermop(fl) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(TimeD, TIMED)
@@ -3061,9 +3125,10 @@ struct AstTimeD : public AstNodeTermop {
     virtual bool same(AstNode* samep) const { return true; }
 };
 
-struct AstUCFunc : public AstNodeMath {
+class AstUCFunc : public AstNodeMath {
     // User's $c function
     // Perhaps this should be an AstNodeListop; but there's only one list math right now
+public:
     AstUCFunc(FileLine* fl, AstNode* exprsp)
 	: AstNodeMath(fl) {
 	addNOp1p(exprsp);
@@ -3086,7 +3151,8 @@ struct AstUCFunc : public AstNodeMath {
 //======================================================================
 // Unary ops
 
-struct AstNegate : public AstNodeUniop {
+class AstNegate : public AstNodeUniop {
+public:
     AstNegate(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(Negate, NEGATE)
@@ -3096,7 +3162,8 @@ struct AstNegate : public AstNodeUniop {
     virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;}
     virtual bool sizeMattersLhs() {return true;}
 };
-struct AstNegateD : public AstNodeUniop {
+class AstNegateD : public AstNodeUniop {
+public:
     AstNegateD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(NegateD, NEGATED)
@@ -3109,7 +3176,8 @@ struct AstNegateD : public AstNodeUniop {
     virtual int instrCount()	const { return instrCountDouble(); }
     virtual bool doubleFlavor() const { return true; }
 };
-struct AstRedAnd : public AstNodeUniop {
+class AstRedAnd : public AstNodeUniop {
+public:
     AstRedAnd(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(RedAnd, REDAND)
@@ -3119,7 +3187,8 @@ struct AstRedAnd : public AstNodeUniop {
     virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
     virtual bool sizeMattersLhs() {return false;}
 };
-struct AstRedOr : public AstNodeUniop {
+class AstRedOr : public AstNodeUniop {
+public:
     AstRedOr(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(RedOr, REDOR)
@@ -3129,7 +3198,8 @@ struct AstRedOr : public AstNodeUniop {
     virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
     virtual bool sizeMattersLhs() {return false;}
 };
-struct AstRedXor : public AstNodeUniop {
+class AstRedXor : public AstNodeUniop {
+public:
     AstRedXor(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(RedXor, REDXOR)
@@ -3142,8 +3212,9 @@ struct AstRedXor : public AstNodeUniop {
     virtual bool sizeMattersLhs() {return false;}
     virtual int instrCount()	const { return 1+V3Number::log2b(width()); }
 };
-struct AstRedXnor : public AstNodeUniop {
+class AstRedXnor : public AstNodeUniop {
     // AstRedXnors are replaced with AstRedXors in V3Const.
+public:
     AstRedXnor(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(RedXnor, REDXNOR)
@@ -3155,7 +3226,8 @@ struct AstRedXnor : public AstNodeUniop {
     virtual int instrCount()	const { return 1+V3Number::log2b(width()); }
 };
 
-struct AstLogNot : public AstNodeUniop {
+class AstLogNot : public AstNodeUniop {
+public:
     AstLogNot(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(LogNot, LOGNOT)
@@ -3166,7 +3238,8 @@ struct AstLogNot : public AstNodeUniop {
     virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
     virtual bool sizeMattersLhs() {return false;}
 };
-struct AstNot : public AstNodeUniop {
+class AstNot : public AstNodeUniop {
+public:
     AstNot(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(Not, NOT)
@@ -3177,8 +3250,9 @@ struct AstNot : public AstNodeUniop {
     virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;}
     virtual bool sizeMattersLhs() {return true;}
 };
-struct AstExtend : public AstNodeUniop {
+class AstExtend : public AstNodeUniop {
     // Expand a value into a wider entity by 0 extension.  Width is implied from nodep->width()
+public:
     AstExtend(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
     AstExtend(FileLine* fl, AstNode* lhsp, int width) : AstNodeUniop(fl, lhsp) {
 	dtypeSetLogicSized(width,width,AstNumeric::UNSIGNED); }
@@ -3190,8 +3264,9 @@ struct AstExtend : public AstNodeUniop {
     virtual bool sizeMattersLhs() {return false;}  // Because the EXTEND operator self-casts
     virtual int instrCount()	const { return 0; }
 };
-struct AstExtendS : public AstNodeUniop {
+class AstExtendS : public AstNodeUniop {
     // Expand a value into a wider entity by sign extension.  Width is implied from nodep->width()
+public:
     AstExtendS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
     AstExtendS(FileLine* fl, AstNode* lhsp, int width) : AstNodeUniop(fl, lhsp) {
 	// Important that widthMin be correct, as opExtend requires it after V3Expand
@@ -3206,8 +3281,9 @@ struct AstExtendS : public AstNodeUniop {
     virtual int instrCount()	const { return 0; }
     virtual bool signedFlavor() const { return true; }
 };
-struct AstSigned : public AstNodeUniop {
+class AstSigned : public AstNodeUniop {
     // $signed(lhs)
+public:
     AstSigned(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	if (v3Global.assertDTypesResolved()) { v3fatalSrc("not coded to create after dtypes resolved"); }
     }
@@ -3219,8 +3295,9 @@ struct AstSigned : public AstNodeUniop {
     virtual bool sizeMattersLhs() {return true;}  // Eliminated before matters
     virtual int instrCount()	const { return 0; }
 };
-struct AstUnsigned : public AstNodeUniop {
+class AstUnsigned : public AstNodeUniop {
     // $unsigned(lhs)
+public:
     AstUnsigned(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	if (v3Global.assertDTypesResolved()) { v3fatalSrc("not coded to create after dtypes resolved"); }
     }
@@ -3232,8 +3309,9 @@ struct AstUnsigned : public AstNodeUniop {
     virtual bool sizeMattersLhs() {return true;}  // Eliminated before matters
     virtual int instrCount()	const { return 0; }
 };
-struct AstRToIS : public AstNodeUniop {
+class AstRToIS : public AstNodeUniop {
     // $rtoi(lhs)
+public:
     AstRToIS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetSigned32(); }
     ASTNODE_NODE_FUNCS(RToIS, RTOIS)
@@ -3244,7 +3322,8 @@ struct AstRToIS : public AstNodeUniop {
     virtual bool sizeMattersLhs() {return false;}  // Eliminated before matters
     virtual int instrCount()	const { return instrCountDouble(); }
 };
-struct AstRToIRoundS : public AstNodeUniop {
+class AstRToIRoundS : public AstNodeUniop {
+public:
     AstRToIRoundS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetSigned32(); }
     ASTNODE_NODE_FUNCS(RToIRoundS, RTOIROUNDS)
@@ -3255,7 +3334,8 @@ struct AstRToIRoundS : public AstNodeUniop {
     virtual bool sizeMattersLhs() {return false;}  // Eliminated before matters
     virtual int instrCount()	const { return instrCountDouble(); }
 };
-struct AstIToRD : public AstNodeUniop {
+class AstIToRD : public AstNodeUniop {
+public:
     AstIToRD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(IToRD, ITORD)
@@ -3266,7 +3346,8 @@ struct AstIToRD : public AstNodeUniop {
     virtual bool sizeMattersLhs() {return false;}  // Eliminated before matters
     virtual int instrCount()	const { return instrCountDouble(); }
 };
-struct AstRealToBits : public AstNodeUniop {
+class AstRealToBits : public AstNodeUniop {
+public:
     AstRealToBits(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetUInt64(); }
     ASTNODE_NODE_FUNCS(RealToBits, REALTOBITS)
@@ -3277,7 +3358,8 @@ struct AstRealToBits : public AstNodeUniop {
     virtual bool sizeMattersLhs() {return false;}  // Eliminated before matters
     virtual int instrCount()	const { return instrCountDouble(); }
 };
-struct AstBitsToRealD : public AstNodeUniop {
+class AstBitsToRealD : public AstNodeUniop {
+public:
     AstBitsToRealD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(BitsToRealD, BITSTOREALD)
@@ -3289,7 +3371,8 @@ struct AstBitsToRealD : public AstNodeUniop {
     virtual int instrCount()	const { return instrCountDouble(); }
 };
 
-struct AstCLog2 : public AstNodeUniop {
+class AstCLog2 : public AstNodeUniop {
+public:
     AstCLog2(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
     ASTNODE_NODE_FUNCS(CLog2, CLOG2)
     virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opCLog2(lhs); }
@@ -3299,8 +3382,9 @@ struct AstCLog2 : public AstNodeUniop {
     virtual bool sizeMattersLhs() {return false;}
     virtual int instrCount()	const { return widthInstrs()*16; }
 };
-struct AstCountOnes : public AstNodeUniop {
+class AstCountOnes : public AstNodeUniop {
     // Number of bits set in vector
+public:
     AstCountOnes(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
     ASTNODE_NODE_FUNCS(CountOnes, COUNTONES)
     virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opCountOnes(lhs); }
@@ -3310,8 +3394,9 @@ struct AstCountOnes : public AstNodeUniop {
     virtual bool sizeMattersLhs() {return false;}
     virtual int instrCount()	const { return widthInstrs()*16; }
 };
-struct AstIsUnknown : public AstNodeUniop {
+class AstIsUnknown : public AstNodeUniop {
     // True if any unknown bits
+public:
     AstIsUnknown(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(IsUnknown, ISUNKNOWN)
@@ -3321,8 +3406,9 @@ struct AstIsUnknown : public AstNodeUniop {
     virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;}
     virtual bool sizeMattersLhs() {return false;}
 };
-struct AstOneHot : public AstNodeUniop {
+class AstOneHot : public AstNodeUniop {
     // True if only single bit set in vector
+public:
     AstOneHot(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(OneHot, ONEHOT)
@@ -3333,8 +3419,9 @@ struct AstOneHot : public AstNodeUniop {
     virtual bool sizeMattersLhs() {return false;}
     virtual int instrCount()	const { return widthInstrs()*4; }
 };
-struct AstOneHot0 : public AstNodeUniop {
+class AstOneHot0 : public AstNodeUniop {
     // True if only single bit, or no bits set in vector
+public:
     AstOneHot0(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(OneHot0, ONEHOT0)
@@ -3346,8 +3433,9 @@ struct AstOneHot0 : public AstNodeUniop {
     virtual int instrCount()	const { return widthInstrs()*3; }
 };
 
-struct AstCast : public AstNode {
+class AstCast : public AstNode {
     // Cast to appropriate data type - note lhsp is value, to match AstTypedef, AstCCast, etc
+public:
     AstCast(FileLine* fl, AstNode* lhsp, AstNodeDType* dtp) : AstNode(fl) {
 	setOp1p(lhsp); setOp2p(dtp);
 	dtypeFrom(dtp);
@@ -3363,8 +3451,9 @@ struct AstCast : public AstNode {
     AstNodeDType* childDTypep() const { return op2p()->castNodeDType(); }
 };
 
-struct AstCastSize : public AstNode {
+class AstCastSize : public AstNode {
     // Cast to specific size; signed/twostate inherited from lower element per IEEE
+public:
     AstCastSize(FileLine* fl, AstNode* lhsp, AstConst* rhsp) : AstNode(fl) {
 	setOp1p(lhsp); setOp2p(rhsp);
     }
@@ -3377,7 +3466,7 @@ struct AstCastSize : public AstNode {
     AstNode* rhsp() const { return op2p(); }
 };
 
-struct AstCCast : public AstNodeUniop {
+class AstCCast : public AstNodeUniop {
     // Cast to C-based data type
 private:
     int		m_size;
@@ -3406,8 +3495,9 @@ public:
     int size()	const { return m_size; }
 };
 
-struct AstCvtPackString : public AstNodeUniop {
+class AstCvtPackString : public AstNodeUniop {
     // Convert to Verilator Packed Pack (aka Pack)
+public:
     AstCvtPackString(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetUInt64(); }  // Really, width should be dtypep -> STRING
     ASTNODE_NODE_FUNCS(CvtPackString, CVTPACKSTRING)
@@ -3420,7 +3510,8 @@ struct AstCvtPackString : public AstNodeUniop {
     virtual bool same(AstNode* samep) const { return true; }
 };
 
-struct AstFEof : public AstNodeUniop {
+class AstFEof : public AstNodeUniop {
+public:
     AstFEof(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
     ASTNODE_NODE_FUNCS(FEof, FEOF)
     virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; }
@@ -3433,7 +3524,8 @@ struct AstFEof : public AstNodeUniop {
     AstNode*	filep() const { return lhsp(); }
 };
 
-struct AstFGetC : public AstNodeUniop {
+class AstFGetC : public AstNodeUniop {
+public:
     AstFGetC(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
     ASTNODE_NODE_FUNCS(FGetC, FGETC)
     virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; }
@@ -3447,7 +3539,8 @@ struct AstFGetC : public AstNodeUniop {
     AstNode*	filep() const { return lhsp(); }
 };
 
-struct AstCeilD : public AstNodeUniop {
+class AstCeilD : public AstNodeUniop {
+public:
     AstCeilD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(CeilD, CEILD)
@@ -3461,7 +3554,8 @@ struct AstCeilD : public AstNodeUniop {
     virtual bool doubleFlavor() const { return true; }
 };
 
-struct AstExpD : public AstNodeUniop {
+class AstExpD : public AstNodeUniop {
+public:
     AstExpD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(ExpD, EXPD)
@@ -3475,7 +3569,8 @@ struct AstExpD : public AstNodeUniop {
     virtual bool doubleFlavor() const { return true; }
 };
 
-struct AstFloorD : public AstNodeUniop {
+class AstFloorD : public AstNodeUniop {
+public:
     AstFloorD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(FloorD, FLOORD)
@@ -3489,7 +3584,8 @@ struct AstFloorD : public AstNodeUniop {
     virtual bool doubleFlavor() const { return true; }
 };
 
-struct AstLogD : public AstNodeUniop {
+class AstLogD : public AstNodeUniop {
+public:
     AstLogD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(LogD, LOGD)
@@ -3503,7 +3599,8 @@ struct AstLogD : public AstNodeUniop {
     virtual bool doubleFlavor() const { return true; }
 };
 
-struct AstLog10D : public AstNodeUniop {
+class AstLog10D : public AstNodeUniop {
+public:
     AstLog10D(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(Log10D, LOG10D)
@@ -3517,7 +3614,8 @@ struct AstLog10D : public AstNodeUniop {
     virtual bool doubleFlavor() const { return true; }
 };
 
-struct AstSqrtD : public AstNodeUniop {
+class AstSqrtD : public AstNodeUniop {
+public:
     AstSqrtD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(SqrtD, SQRTD)
@@ -3534,7 +3632,8 @@ struct AstSqrtD : public AstNodeUniop {
 //======================================================================
 // Binary ops
 
-struct AstLogOr : public AstNodeBiop {
+class AstLogOr : public AstNodeBiop {
+public:
     AstLogOr(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(LogOr, LOGOR)
@@ -3547,7 +3646,8 @@ struct AstLogOr : public AstNodeBiop {
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
     virtual int instrCount()	const { return widthInstrs()+instrCountBranch(); }
 };
-struct AstLogAnd : public AstNodeBiop {
+class AstLogAnd : public AstNodeBiop {
+public:
     AstLogAnd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(LogAnd, LOGAND)
@@ -3560,7 +3660,8 @@ struct AstLogAnd : public AstNodeBiop {
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
     virtual int instrCount()	const { return widthInstrs()+instrCountBranch(); }
 };
-struct AstLogIf : public AstNodeBiop {
+class AstLogIf : public AstNodeBiop {
+public:
     AstLogIf(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(LogIf, LOGIF)
@@ -3573,7 +3674,8 @@ struct AstLogIf : public AstNodeBiop {
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
     virtual int instrCount()	const { return widthInstrs()+instrCountBranch(); }
 };
-struct AstLogIff : public AstNodeBiCom {
+class AstLogIff : public AstNodeBiCom {
+public:
     AstLogIff(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(LogIff, LOGIFF)
@@ -3586,7 +3688,8 @@ struct AstLogIff : public AstNodeBiCom {
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
     virtual int instrCount()	const { return widthInstrs()+instrCountBranch(); }
 };
-struct AstOr : public AstNodeBiComAsv {
+class AstOr : public AstNodeBiComAsv {
+public:
     AstOr(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(Or, OR)
@@ -3598,7 +3701,8 @@ struct AstOr : public AstNodeBiComAsv {
     virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstAnd : public AstNodeBiComAsv {
+class AstAnd : public AstNodeBiComAsv {
+public:
     AstAnd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(And, AND)
@@ -3610,7 +3714,8 @@ struct AstAnd : public AstNodeBiComAsv {
     virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstXor : public AstNodeBiComAsv {
+class AstXor : public AstNodeBiComAsv {
+public:
     AstXor(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(Xor, XOR)
@@ -3622,7 +3727,8 @@ struct AstXor : public AstNodeBiComAsv {
     virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstXnor : public AstNodeBiComAsv {
+class AstXnor : public AstNodeBiComAsv {
+public:
     AstXnor(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(Xnor, XNOR)
@@ -3634,7 +3740,8 @@ struct AstXnor : public AstNodeBiComAsv {
     virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
     virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
 };
-struct AstEq : public AstNodeBiCom {
+class AstEq : public AstNodeBiCom {
+public:
     AstEq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(Eq, EQ)
@@ -3647,7 +3754,8 @@ struct AstEq : public AstNodeBiCom {
     virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstEqD : public AstNodeBiCom {
+class AstEqD : public AstNodeBiCom {
+public:
     AstEqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(EqD, EQD)
@@ -3661,7 +3769,8 @@ struct AstEqD : public AstNodeBiCom {
     virtual int instrCount()	const { return instrCountDouble(); }
     virtual bool doubleFlavor() const { return true; }
 };
-struct AstNeq : public AstNodeBiCom {
+class AstNeq : public AstNodeBiCom {
+public:
     AstNeq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(Neq, NEQ)
@@ -3673,7 +3782,8 @@ struct AstNeq : public AstNodeBiCom {
     virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstNeqD : public AstNodeBiCom {
+class AstNeqD : public AstNodeBiCom {
+public:
     AstNeqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(NeqD, NEQD)
@@ -3687,7 +3797,8 @@ struct AstNeqD : public AstNodeBiCom {
     virtual int instrCount()	const { return instrCountDouble(); }
     virtual bool doubleFlavor() const { return true; }
 };
-struct AstLt : public AstNodeBiop {
+class AstLt : public AstNodeBiop {
+public:
     AstLt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(Lt, LT)
@@ -3699,7 +3810,8 @@ struct AstLt : public AstNodeBiop {
     virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstLtD : public AstNodeBiop {
+class AstLtD : public AstNodeBiop {
+public:
     AstLtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(LtD, LTD)
@@ -3713,7 +3825,8 @@ struct AstLtD : public AstNodeBiop {
     virtual int instrCount()	const { return instrCountDouble(); }
     virtual bool doubleFlavor() const { return true; }
 };
-struct AstLtS : public AstNodeBiop {
+class AstLtS : public AstNodeBiop {
+public:
     AstLtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(LtS, LTS)
@@ -3726,7 +3839,8 @@ struct AstLtS : public AstNodeBiop {
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
     virtual bool signedFlavor() const { return true; }
 };
-struct AstGt : public AstNodeBiop {
+class AstGt : public AstNodeBiop {
+public:
     AstGt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(Gt, GT)
@@ -3738,7 +3852,8 @@ struct AstGt : public AstNodeBiop {
     virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstGtD : public AstNodeBiop {
+class AstGtD : public AstNodeBiop {
+public:
     AstGtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(GtD, GTD)
@@ -3752,7 +3867,8 @@ struct AstGtD : public AstNodeBiop {
     virtual int instrCount()	const { return instrCountDouble(); }
     virtual bool doubleFlavor() const { return true; }
 };
-struct AstGtS : public AstNodeBiop {
+class AstGtS : public AstNodeBiop {
+public:
     AstGtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(GtS, GTS)
@@ -3765,7 +3881,8 @@ struct AstGtS : public AstNodeBiop {
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
     virtual bool signedFlavor() const { return true; }
 };
-struct AstGte : public AstNodeBiop {
+class AstGte : public AstNodeBiop {
+public:
     AstGte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(Gte, GTE)
@@ -3778,7 +3895,8 @@ struct AstGte : public AstNodeBiop {
     virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstGteD : public AstNodeBiop {
+class AstGteD : public AstNodeBiop {
+public:
     AstGteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(GteD, GTED)
@@ -3792,7 +3910,8 @@ struct AstGteD : public AstNodeBiop {
     virtual int instrCount()	const { return instrCountDouble(); }
     virtual bool doubleFlavor() const { return true; }
 };
-struct AstGteS : public AstNodeBiop {
+class AstGteS : public AstNodeBiop {
+public:
     AstGteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(GteS, GTES)
@@ -3805,7 +3924,8 @@ struct AstGteS : public AstNodeBiop {
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
     virtual bool signedFlavor() const { return true; }
 };
-struct AstLte : public AstNodeBiop {
+class AstLte : public AstNodeBiop {
+public:
     AstLte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(Lte, LTE)
@@ -3818,7 +3938,8 @@ struct AstLte : public AstNodeBiop {
     virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstLteD : public AstNodeBiop {
+class AstLteD : public AstNodeBiop {
+public:
     AstLteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(LteD, LTED)
@@ -3832,7 +3953,8 @@ struct AstLteD : public AstNodeBiop {
     virtual int instrCount()	const { return instrCountDouble(); }
     virtual bool doubleFlavor() const { return true; }
 };
-struct AstLteS : public AstNodeBiop {
+class AstLteS : public AstNodeBiop {
+public:
     AstLteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(LteS, LTES)
@@ -3845,7 +3967,8 @@ struct AstLteS : public AstNodeBiop {
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
     virtual bool signedFlavor() const { return true; }
 };
-struct AstShiftL : public AstNodeBiop {
+class AstShiftL : public AstNodeBiop {
+public:
     AstShiftL(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth=0)
 	: AstNodeBiop(fl, lhsp, rhsp) {
 	if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::UNSIGNED); }
@@ -3859,7 +3982,8 @@ struct AstShiftL : public AstNodeBiop {
     virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return true;}
     virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstShiftR : public AstNodeBiop {
+class AstShiftR : public AstNodeBiop {
+public:
     AstShiftR(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth=0)
 	: AstNodeBiop(fl, lhsp, rhsp) {
 	if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::UNSIGNED); }
@@ -3873,9 +3997,10 @@ struct AstShiftR : public AstNodeBiop {
     virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}  // LHS size might be > output size, so don't want to force size
 };
-struct AstShiftRS : public AstNodeBiop {
+class AstShiftRS : public AstNodeBiop {
     // Shift right with sign extension, >>> operator
     // Output data type's width determines which bit is used for sign extension
+public:
     AstShiftRS(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth=0)
 	: AstNodeBiop(fl, lhsp, rhsp) {
 	// Important that widthMin be correct, as opExtend requires it after V3Expand
@@ -3892,7 +4017,8 @@ struct AstShiftRS : public AstNodeBiop {
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
     virtual bool signedFlavor() const { return true; }
 };
-struct AstAdd : public AstNodeBiComAsv {
+class AstAdd : public AstNodeBiComAsv {
+public:
     AstAdd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(Add, ADD)
@@ -3904,7 +4030,8 @@ struct AstAdd : public AstNodeBiComAsv {
     virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
     virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
 };
-struct AstAddD : public AstNodeBiComAsv {
+class AstAddD : public AstNodeBiComAsv {
+public:
     AstAddD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(AddD, ADDD)
@@ -3918,7 +4045,8 @@ struct AstAddD : public AstNodeBiComAsv {
     virtual int instrCount()	const { return instrCountDouble(); }
     virtual bool doubleFlavor() const { return true; }
 };
-struct AstSub : public AstNodeBiop {
+class AstSub : public AstNodeBiop {
+public:
     AstSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(Sub, SUB)
@@ -3930,7 +4058,8 @@ struct AstSub : public AstNodeBiop {
     virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
     virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
 };
-struct AstSubD : public AstNodeBiop {
+class AstSubD : public AstNodeBiop {
+public:
     AstSubD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(SubD, SUBD)
@@ -3944,7 +4073,8 @@ struct AstSubD : public AstNodeBiop {
     virtual int instrCount()	const { return instrCountDouble(); }
     virtual bool doubleFlavor() const { return true; }
 };
-struct AstMul : public AstNodeBiComAsv {
+class AstMul : public AstNodeBiComAsv {
+public:
     AstMul(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(Mul, MUL)
@@ -3957,7 +4087,8 @@ struct AstMul : public AstNodeBiComAsv {
     virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
     virtual int instrCount()	const { return widthInstrs()*instrCountMul(); }
 };
-struct AstMulD : public AstNodeBiComAsv {
+class AstMulD : public AstNodeBiComAsv {
+public:
     AstMulD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(MulD, MULD)
@@ -3971,7 +4102,8 @@ struct AstMulD : public AstNodeBiComAsv {
     virtual int instrCount()	const { return instrCountDouble(); }
     virtual bool doubleFlavor() const { return true; }
 };
-struct AstMulS : public AstNodeBiComAsv {
+class AstMulS : public AstNodeBiComAsv {
+public:
     AstMulS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(MulS, MULS)
@@ -3985,7 +4117,8 @@ struct AstMulS : public AstNodeBiComAsv {
     virtual int instrCount()	const { return widthInstrs()*instrCountMul(); }
     virtual bool signedFlavor() const { return true; }
 };
-struct AstDiv : public AstNodeBiop {
+class AstDiv : public AstNodeBiop {
+public:
     AstDiv(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(Div, DIV)
@@ -3997,7 +4130,8 @@ struct AstDiv : public AstNodeBiop {
     virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
     virtual int instrCount()	const { return widthInstrs()*instrCountDiv(); }
 };
-struct AstDivD : public AstNodeBiop {
+class AstDivD : public AstNodeBiop {
+public:
     AstDivD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(DivD, DIVD)
@@ -4011,7 +4145,8 @@ struct AstDivD : public AstNodeBiop {
     virtual int instrCount()	const { return instrCountDoubleDiv(); }
     virtual bool doubleFlavor() const { return true; }
 };
-struct AstDivS : public AstNodeBiop {
+class AstDivS : public AstNodeBiop {
+public:
     AstDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(DivS, DIVS)
@@ -4024,7 +4159,8 @@ struct AstDivS : public AstNodeBiop {
     virtual int instrCount()	const { return widthInstrs()*instrCountDiv(); }
     virtual bool signedFlavor() const { return true; }
 };
-struct AstModDiv : public AstNodeBiop {
+class AstModDiv : public AstNodeBiop {
+public:
     AstModDiv(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(ModDiv, MODDIV)
@@ -4036,7 +4172,8 @@ struct AstModDiv : public AstNodeBiop {
     virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
     virtual int instrCount()	const { return widthInstrs()*instrCountDiv(); }
 };
-struct AstModDivS : public AstNodeBiop {
+class AstModDivS : public AstNodeBiop {
+public:
     AstModDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(ModDivS, MODDIVS)
@@ -4049,7 +4186,8 @@ struct AstModDivS : public AstNodeBiop {
     virtual int instrCount()	const { return widthInstrs()*instrCountDiv(); }
     virtual bool signedFlavor() const { return true; }
 };
-struct AstPow : public AstNodeBiop {
+class AstPow : public AstNodeBiop {
+public:
     AstPow(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(Pow, POW)
@@ -4061,7 +4199,8 @@ struct AstPow : public AstNodeBiop {
     virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;}
     virtual int instrCount()	const { return widthInstrs()*instrCountMul()*10; }
 };
-struct AstPowD : public AstNodeBiop {
+class AstPowD : public AstNodeBiop {
+public:
     AstPowD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetDouble(); }
     ASTNODE_NODE_FUNCS(PowD, POWD)
@@ -4074,7 +4213,8 @@ struct AstPowD : public AstNodeBiop {
     virtual int instrCount()	const { return instrCountDoubleDiv()*5; }
     virtual bool doubleFlavor() const { return true; }
 };
-struct AstPowSU : public AstNodeBiop {
+class AstPowSU : public AstNodeBiop {
+public:
     AstPowSU(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(PowSU, POWSU)
@@ -4087,7 +4227,8 @@ struct AstPowSU : public AstNodeBiop {
     virtual int instrCount()	const { return widthInstrs()*instrCountMul()*10; }
     virtual bool signedFlavor() const { return true; }
 };
-struct AstPowSS : public AstNodeBiop {
+class AstPowSS : public AstNodeBiop {
+public:
     AstPowSS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(PowSS, POWSS)
@@ -4100,7 +4241,8 @@ struct AstPowSS : public AstNodeBiop {
     virtual int instrCount()	const { return widthInstrs()*instrCountMul()*10; }
     virtual bool signedFlavor() const { return true; }
 };
-struct AstPowUS : public AstNodeBiop {
+class AstPowUS : public AstNodeBiop {
+public:
     AstPowUS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(PowUS, POWUS)
@@ -4113,7 +4255,8 @@ struct AstPowUS : public AstNodeBiop {
     virtual int instrCount()	const { return widthInstrs()*instrCountMul()*10; }
     virtual bool signedFlavor() const { return true; }
 };
-struct AstEqCase : public AstNodeBiCom {
+class AstEqCase : public AstNodeBiCom {
+public:
     AstEqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(EqCase, EQCASE)
@@ -4125,7 +4268,8 @@ struct AstEqCase : public AstNodeBiCom {
     virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstNeqCase : public AstNodeBiCom {
+class AstNeqCase : public AstNodeBiCom {
+public:
     AstNeqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(NeqCase, NEQCASE)
@@ -4137,8 +4281,9 @@ struct AstNeqCase : public AstNodeBiCom {
     virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstEqWild : public AstNodeBiop {
+class AstEqWild : public AstNodeBiop {
     // Note wildcard operator rhs differs from lhs
+public:
     AstEqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(EqWild, EQWILD)
@@ -4150,7 +4295,8 @@ struct AstEqWild : public AstNodeBiop {
     virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstNeqWild : public AstNodeBiop {
+class AstNeqWild : public AstNodeBiop {
+public:
     AstNeqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeSetLogicBool(); }
     ASTNODE_NODE_FUNCS(NeqWild, NEQWILD)
@@ -4162,8 +4308,9 @@ struct AstNeqWild : public AstNodeBiop {
     virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstConcat : public AstNodeBiop {
+class AstConcat : public AstNodeBiop {
     // If you're looking for {#{}}, see AstReplicate
+public:
     AstConcat(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	if (lhsp->dtypep() && rhsp->dtypep()) {
 	    dtypeSetLogicSized(lhsp->dtypep()->width()+rhsp->dtypep()->width(),
@@ -4180,7 +4327,7 @@ struct AstConcat : public AstNodeBiop {
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
     virtual int instrCount()	const { return widthInstrs()*2; }
 };
-struct AstReplicate : public AstNodeBiop {
+class AstReplicate : public AstNodeBiop {
     // Also used as a "Uniop" flavor of Concat, e.g. "{a}"
     // Verilog {rhs{lhs}} - Note rhsp() is the replicate value, not the lhsp()
 private:
@@ -4205,8 +4352,9 @@ public:
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
     virtual int instrCount()	const { return widthInstrs()*2; }
 };
-struct AstStreamL : public AstNodeStream {
+class AstStreamL : public AstNodeStream {
     // Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp()
+public:
     AstStreamL(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeStream(fl, lhsp, rhsp) {}
     ASTNODE_NODE_FUNCS(StreamL, STREAML)
     virtual string emitVerilog() { return "%f{ << %r %k{%l} }"; }
@@ -4217,8 +4365,9 @@ struct AstStreamL : public AstNodeStream {
     virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;}
     virtual int instrCount()	const { return widthInstrs()*2; }
 };
-struct AstStreamR : public AstNodeStream {
+class AstStreamR : public AstNodeStream {
     // Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp()
+public:
     AstStreamR(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeStream(fl, lhsp, rhsp) {}
     ASTNODE_NODE_FUNCS(StreamR, STREAMR)
     virtual string emitVerilog() { return "%f{ >> %r %k{%l} }"; }
@@ -4229,9 +4378,10 @@ struct AstStreamR : public AstNodeStream {
     virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;}
     virtual int instrCount()	const { return widthInstrs()*2; }
 };
-struct AstBufIf1 : public AstNodeBiop {
+class AstBufIf1 : public AstNodeBiop {
     // lhs is enable, rhs is data to drive
     // Note unlike the Verilog bufif1() UDP, this allows any width; each lhsp bit enables respective rhsp bit
+public:
     AstBufIf1(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
 	dtypeFrom(lhsp); }
     ASTNODE_NODE_FUNCS(BufIf1, BUFIF1)
@@ -4243,7 +4393,8 @@ struct AstBufIf1 : public AstNodeBiop {
     virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
     virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
 };
-struct AstFGetS : public AstNodeBiop {
+class AstFGetS : public AstNodeBiop {
+public:
     AstFGetS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {}
     ASTNODE_NODE_FUNCS(FGetS, FGETS)
     virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
@@ -4257,10 +4408,11 @@ struct AstFGetS : public AstNodeBiop {
     AstNode*	filep() const { return rhsp(); }
 };
 
-struct AstPattern : public AstNodeMath {
+class AstPattern : public AstNodeMath {
     // Verilog '{a,b,c,d...}
     // Parents: AstNodeAssign, AstPattern, ...
     // Children: expression, AstPattern, AstPatReplicate
+public:
     AstPattern(FileLine* fl, AstNode* itemsp) : AstNodeMath(fl) {
 	addNOp2p(itemsp);
     }
@@ -4277,7 +4429,7 @@ struct AstPattern : public AstNodeMath {
     AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
     AstNode* itemsp() const { return op2p(); } // op2 = AstPatReplicate, AstPatMember, etc
 };
-struct AstPatMember : public AstNodeMath {
+class AstPatMember : public AstNodeMath {
     // Verilog '{a} or '{a{b}}
     // Parents: AstPattern
     // Children: expression, AstPattern, replication count
@@ -4303,10 +4455,11 @@ public:
 //======================================================================
 // SysVerilog assertions
 
-struct AstVAssert : public AstNodeStmt {
+class AstVAssert : public AstNodeStmt {
     // Verilog Assertion
     // Parents:  {statement list}
     // Children: expression, if pass statements, if fail statements
+public:
     AstVAssert(FileLine* fl, AstNode* propp, AstNode* passsp, AstNode* failsp)
 	: AstNodeStmt(fl) {
 	addOp1p(propp);
@@ -4324,10 +4477,11 @@ struct AstVAssert : public AstNodeStmt {
 //======================================================================
 // Assertions
 
-struct AstClocking : public AstNode {
+class AstClocking : public AstNode {
     // Set default clock region
     // Parents:  MODULE
     // Children: Assertions
+public:
     AstClocking(FileLine* fl, AstNodeSenItem* sensesp, AstNode* bodysp)
 	: AstNode(fl) {
 	addOp1p(sensesp);
@@ -4341,10 +4495,11 @@ struct AstClocking : public AstNode {
 //======================================================================
 // PSL
 
-struct AstPslDefClock : public AstNode {
+class AstPslDefClock : public AstNode {
     // Set default PSL clock
     // Parents:  MODULE
     // Children: SENITEM
+public:
     AstPslDefClock(FileLine* fl, AstNodeSenItem* sensesp)
 	: AstNode(fl) {
 	addNOp1p(sensesp);
@@ -4353,10 +4508,11 @@ struct AstPslDefClock : public AstNode {
     AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); }	// op1 = Sensitivity list
 };
 
-struct AstPslClocked : public AstNode {
+class AstPslClocked : public AstNode {
     // A clocked property
     // Parents:  ASSERT|COVER (property)
     // Children: SENITEM, Properties
+public:
     AstPslClocked(FileLine* fl, AstNodeSenItem* sensesp, AstNode* disablep, AstNode* propp)
 	: AstNode(fl) {
 	addNOp1p(sensesp);
@@ -4370,7 +4526,7 @@ struct AstPslClocked : public AstNode {
     AstNode*	propp()		const { return op3p(); }	// op3 = property
 };
 
-struct AstPslAssert : public AstNodeStmt {
+class AstPslAssert : public AstNodeStmt {
     // Psl Assertion
     // Parents:  {statement list}
     // Children: expression, report string
@@ -4391,7 +4547,7 @@ public:
     void sentreep(AstSenTree* sentreep)  { addOp2p(sentreep); }	// op2 = clock domain
 };
 
-struct AstPslCover : public AstNodeStmt {
+class AstPslCover : public AstNodeStmt {
     // Psl Cover
     // Parents:  {statement list}
     // Children: expression, report string
@@ -4420,11 +4576,12 @@ public:
 //======================================================================
 // PSL Expressions
 
-struct AstPslBool : public AstNode {
+class AstPslBool : public AstNode {
     // Separates PSL Sere/sequences from the normal expression boolean layer below.
     // Note this excludes next() and similar functions; they are time domain, so not under AstPslBool.
     // Parents: Sequences, etc.
     // Children: math
+public:
     AstPslBool(FileLine* fileline, AstNode* exprp)
 	: AstNode(fileline) {
 	addOp1p(exprp);
@@ -4442,7 +4599,7 @@ struct AstPslBool : public AstNode {
 //======================================================================
 // Text based nodes
 
-struct AstText : public AstNodeText {
+class AstText : public AstNodeText {
 private:
     bool	m_tracking;	// When emit, it's ok to parse the string to do indentation
 public:
@@ -4453,7 +4610,8 @@ public:
     bool tracking() const { return m_tracking; }
 };
 
-struct AstScCtor : public AstNodeText {
+class AstScCtor : public AstNodeText {
+public:
     AstScCtor(FileLine* fl, const string& textp)
 	: AstNodeText(fl, textp) {}
     ASTNODE_NODE_FUNCS(ScCtor, SCCTOR)
@@ -4461,7 +4619,8 @@ struct AstScCtor : public AstNodeText {
     virtual bool isOutputter() const { return true; }
 };
 
-struct AstScDtor : public AstNodeText {
+class AstScDtor : public AstNodeText {
+public:
     AstScDtor(FileLine* fl, const string& textp)
 	: AstNodeText(fl, textp) {}
     ASTNODE_NODE_FUNCS(ScDtor, SCDTOR)
@@ -4469,7 +4628,8 @@ struct AstScDtor : public AstNodeText {
     virtual bool isOutputter() const { return true; }
 };
 
-struct AstScHdr : public AstNodeText {
+class AstScHdr : public AstNodeText {
+public:
     AstScHdr(FileLine* fl, const string& textp)
 	: AstNodeText(fl, textp) {}
     ASTNODE_NODE_FUNCS(ScHdr, SCHDR)
@@ -4477,7 +4637,8 @@ struct AstScHdr : public AstNodeText {
     virtual bool isOutputter() const { return true; }
 };
 
-struct AstScImp : public AstNodeText {
+class AstScImp : public AstNodeText {
+public:
     AstScImp(FileLine* fl, const string& textp)
 	: AstNodeText(fl, textp) {}
     ASTNODE_NODE_FUNCS(ScImp, SCIMP)
@@ -4485,7 +4646,8 @@ struct AstScImp : public AstNodeText {
     virtual bool isOutputter() const { return true; }
 };
 
-struct AstScImpHdr : public AstNodeText {
+class AstScImpHdr : public AstNodeText {
+public:
     AstScImpHdr(FileLine* fl, const string& textp)
 	: AstNodeText(fl, textp) {}
     ASTNODE_NODE_FUNCS(ScImpHdr, SCIMPHDR)
@@ -4493,7 +4655,8 @@ struct AstScImpHdr : public AstNodeText {
     virtual bool isOutputter() const { return true; }
 };
 
-struct AstScInt : public AstNodeText {
+class AstScInt : public AstNodeText {
+public:
     AstScInt(FileLine* fl, const string& textp)
 	: AstNodeText(fl, textp) {}
     ASTNODE_NODE_FUNCS(ScInt, SCINT)
@@ -4501,8 +4664,9 @@ struct AstScInt : public AstNodeText {
     virtual bool isOutputter() const { return true; }
 };
 
-struct AstUCStmt : public AstNodeStmt {
+class AstUCStmt : public AstNodeStmt {
     // User $c statement
+public:
     AstUCStmt(FileLine* fl, AstNode* exprsp)
 	: AstNodeStmt(fl) {
 	addNOp1p(exprsp);
@@ -4520,7 +4684,7 @@ struct AstUCStmt : public AstNodeStmt {
 //======================================================================
 // Emit C nodes
 
-struct AstCFile : public AstNode {
+class AstCFile : public AstNode {
     // C++ output file
     // Parents:  NETLIST
     // Children: nothing yet
@@ -4550,7 +4714,7 @@ public:
     void	support(bool flag) { m_support = flag; }
 };
 
-struct AstCFunc : public AstNode {
+class AstCFunc : public AstNode {
     // C++ function
     // Parents:  MODULE/SCOPE
     // Children: VAR/statements
@@ -4658,7 +4822,7 @@ public:
     bool	emptyBody() const { return argsp()==NULL && initsp()==NULL && stmtsp()==NULL && finalsp()==NULL; }
 };
 
-struct AstCCall : public AstNodeStmt {
+class AstCCall : public AstNodeStmt {
     // C++ function call
     // Parents:  Anything above a statement
     // Children: Args to the function
@@ -4706,10 +4870,11 @@ public:
     void addArgsp(AstNode* nodep) { addOp1p(nodep); }
 };
 
-struct AstCReturn : public AstNodeStmt {
+class AstCReturn : public AstNodeStmt {
     // C++ return from a function
     // Parents:  CFUNC/statement
     // Children: Math
+public:
     AstCReturn(FileLine* fl, AstNode* lhsp)
 	: AstNodeStmt(fl) {
 	setOp1p(lhsp);
@@ -4722,7 +4887,7 @@ struct AstCReturn : public AstNodeStmt {
     AstNode*	lhsp() const { return op1p(); }
 };
 
-struct AstCMath : public AstNodeMath {
+class AstCMath : public AstNodeMath {
 private:
     bool	m_cleanOut;
 public:
@@ -4750,8 +4915,9 @@ public:
 };
 
 
-struct AstCStmt : public AstNodeStmt {
+class AstCStmt : public AstNodeStmt {
     // Emit C statement
+public:
     AstCStmt(FileLine* fl, AstNode* exprsp)
 	: AstNodeStmt(fl) {
 	addNOp1p(exprsp);
@@ -4772,7 +4938,7 @@ struct AstCStmt : public AstNodeStmt {
 //######################################################################
 // Right below top
 
-struct AstTypeTable : public AstNode {
+class AstTypeTable : public AstNode {
     // Container for hash of standard data types
     // Children:  NODEDTYPEs
     typedef map<pair<int,int>,AstBasicDType*> LogicMap;
@@ -4804,7 +4970,7 @@ public:
 //######################################################################
 // Top
 
-struct AstNetlist : public AstNode {
+class AstNetlist : public AstNode {
     // All modules are under this single top node.
     // Parents:   none
     // Children:  MODULEs & CFILEs
diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp
index 8cfc030..829a911 100644
--- a/src/V3EmitC.cpp
+++ b/src/V3EmitC.cpp
@@ -226,7 +226,9 @@ public:
     virtual void visit(AstScopeName* nodep, AstNUser*) {
 	// For use under AstCCalls for dpiImports.  ScopeNames under displays are handled in AstDisplay
 	if (!nodep->dpiExport()) {
-	    putbs("(&(vlSymsp->__Vscope_"+nodep->scopeSymName()+"))");
+	    // this is where the DPI import context scope is set
+	    string scope = nodep->scopeDpiName();
+	    putbs("(&(vlSymsp->__Vscope_"+scope+"))");
 	}
     }
     virtual void visit(AstSFormat* nodep, AstNUser*) {
@@ -783,6 +785,7 @@ class EmitCImp : EmitCStmts {
 
     //---------------------------------------
     // VISITORS
+    using EmitCStmts::visit;  // Suppress hidden overloaded virtual function warnng
     virtual void visit(AstCFunc* nodep, AstNUser*) {
 	// TRACE_* and DPI handled elsewhere
 	if (nodep->funcType().isTrace()) return;
@@ -2303,6 +2306,7 @@ class EmitCTrace : EmitCStmts {
     }
 
     // VISITORS
+    using EmitCStmts::visit;  // Suppress hidden overloaded virtual function warnng
     virtual void visit(AstNetlist* nodep, AstNUser*) {
 	// Top module only
 	nodep->topModulep()->accept(*this);
diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp
index ae7b65a..b7c7c99 100644
--- a/src/V3EmitV.cpp
+++ b/src/V3EmitV.cpp
@@ -685,7 +685,6 @@ public:
 class EmitVPrefixedVisitor : public EmitVBaseVisitor {
     // MEMBERS
     EmitVPrefixedFormatter m_formatter; // Special verilog formatter (Way down the inheritance is another unused V3OutFormatter)
-    bool	m_user3mark;	// nodep->user3() if set means mark with %%
     // METHODS
     virtual void putsNoTracking(const string& str) { m_formatter.putsNoTracking(str); }
     virtual void puts(const string& str) { m_formatter.puts(str); }
@@ -706,7 +705,7 @@ class EmitVPrefixedVisitor : public EmitVBaseVisitor {
 public:
     EmitVPrefixedVisitor(AstNode* nodep, ostream& os, const string& prefix, int flWidth,
 			 AstSenTree* domainp, bool user3mark)
-	: EmitVBaseVisitor(domainp), m_formatter(os, prefix, flWidth), m_user3mark(user3mark) {
+	: EmitVBaseVisitor(domainp), m_formatter(os, prefix, flWidth) {
 	if (user3mark) { AstUser3InUse::check(); }
 	nodep->accept(*this);
     }
diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp
index f2a7fbf..25c8297 100644
--- a/src/V3Expand.cpp
+++ b/src/V3Expand.cpp
@@ -583,11 +583,15 @@ private:
 								     newSelBitBit(lhsp->lsbp()),
 								     VL_WORDSIZE)),
 					  oldvalp);
+
+		// Restrict the shift amount to 0-31, see bug804.
+		AstNode* shiftp = new AstAnd(nodep->fileline(), lhsp->lsbp()->cloneTree(true),
+					     new AstConst(nodep->fileline(), VL_WORDSIZE-1));
 		AstNode* newp = new AstOr (lhsp->fileline(),
 					   oldvalp,
 					   new AstShiftL (lhsp->fileline(),
 							  rhsp,
-							  lhsp->lsbp()->cloneTree(true),
+							  shiftp,
 							  VL_WORDSIZE));
 		newp = new AstAssign (nodep->fileline(),
 				      new AstWordSel (nodep->fileline(),
diff --git a/src/V3File.cpp b/src/V3File.cpp
index 8cba41f..aad16a6 100644
--- a/src/V3File.cpp
+++ b/src/V3File.cpp
@@ -567,7 +567,7 @@ const char* V3OutFormatter::indentStr(int num) {
     static char str[MAXSPACE+20];
     char* cp = str;
     if (num>MAXSPACE) num=MAXSPACE;
-    if (!m_lang==LA_VERILOG) {  // verilogPrefixedTree doesn't want tabs
+    if (m_lang!=LA_VERILOG) {  // verilogPrefixedTree doesn't want tabs
 	while (num>=8) {
 	    *cp++ = '\t';
 	    num -= 8;
diff --git a/src/V3GraphDfa.h b/src/V3GraphDfa.h
index c53c1e9..7cd0afd 100644
--- a/src/V3GraphDfa.h
+++ b/src/V3GraphDfa.h
@@ -96,6 +96,7 @@ public:
     DfaVertex(DfaGraph* graphp, bool start=false, bool accepting=false)
 	: V3GraphVertex(graphp)
 	, m_start(start), m_accepting(accepting) {}
+    using V3GraphVertex::clone;  // We are overriding, not overloading clone(V3Graph*)
     virtual DfaVertex* clone(DfaGraph* graphp) {
 	return new DfaVertex(graphp, start(), accepting()); }
     virtual ~DfaVertex() {}
diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp
index bcc26ba..9754435 100644
--- a/src/V3Inline.cpp
+++ b/src/V3Inline.cpp
@@ -387,6 +387,10 @@ private:
 	if (afterp) afterp->unlinkFrBackWithNext();
 	nodep->scopeAttrp(new AstText(nodep->fileline(), (string)"__DOT__"+m_cellp->name()));
 	if (afterp) nodep->scopeAttrp(afterp);
+	afterp = nodep->scopeEntrp();
+	if (afterp) afterp->unlinkFrBackWithNext();
+	nodep->scopeEntrp(new AstText(nodep->fileline(), (string)"__DOT__"+m_cellp->name()));
+	if (afterp) nodep->scopeEntrp(afterp);
 	nodep->iterateChildren(*this);
     }
     virtual void visit(AstCoverDecl* nodep, AstNUser*) {
diff --git a/src/V3Number.h b/src/V3Number.h
index 706c31f..c6bfd53 100644
--- a/src/V3Number.h
+++ b/src/V3Number.h
@@ -97,7 +97,7 @@ private:
     bool bitIsXZ(int bit) const {
 	if (bit<0) return false;
 	if (bit>=m_width) return bitIsXZ(m_width-1);
-	return ( (m_valueX[bit/32] & (1UL<<(bit&31))) && 1);
+	return ( (m_valueX[bit/32] & (1UL<<(bit&31))));
     }
     bool bitIsZ (int bit) const {
 	if (bit<0) return false;
diff --git a/src/V3Param.cpp b/src/V3Param.cpp
index 2862b54..3d1b13e 100644
--- a/src/V3Param.cpp
+++ b/src/V3Param.cpp
@@ -210,7 +210,8 @@ private:
     virtual void visit(AstNodeModule* nodep, AstNUser*) {
 	if (nodep->dead()) {
 	    UINFO(4," MOD-dead.  "<<nodep<<endl);  // Marked by LinkDot
-	} else if (nodep->level() <= 2) {  // Haven't added top yet, so level 2 is the top
+	} else if (nodep->level() <= 2  // Haven't added top yet, so level 2 is the top
+		   || nodep->castPackage()) {	// Likewise haven't done wrapTopPackages yet
 	    // Add request to END of modules left to process
 	    m_todoModps.insert(make_pair(nodep->level(),nodep));
 	    visitModules();
diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp
index 68cbcbb..0b46054 100644
--- a/src/V3Premit.cpp
+++ b/src/V3Premit.cpp
@@ -40,6 +40,60 @@
 #include "V3Premit.h"
 #include "V3Ast.h"
 
+
+//######################################################################
+// Structure for global state
+
+class PremitAssignVisitor : public AstNVisitor {
+private:
+    // NODE STATE
+    //  AstVar::user4()		// bool; occurs on LHS of current assignment
+    AstUser4InUse	m_inuser4;
+
+    // STATE
+    bool	m_noopt;	// Disable optimization of variables in this block
+
+    // METHODS
+    static int debug() {
+	static int level = -1;
+	if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
+	return level;
+    }
+
+    // VISITORS
+    virtual void visit(AstNodeAssign* nodep, AstNUser*) {
+        //AstNode::user4ClearTree();  // Implied by AstUser4InUse
+	// LHS first as fewer varrefs
+	nodep->lhsp()->iterateAndNext(*this);
+	// Now find vars marked as lhs
+	nodep->rhsp()->iterateAndNext(*this);
+    }
+    virtual void visit(AstVarRef* nodep, AstNUser*) {
+	// it's LHS var is used so need a deep temporary
+	if (nodep->lvalue()) {
+	    nodep->varp()->user4(true);
+	} else {
+	    if (nodep->varp()->user4()) {
+		if (!m_noopt) UINFO(4, "Block has LHS+RHS var: "<<nodep<<endl);
+		m_noopt = true;
+	    }
+	}
+    }
+    virtual void visit(AstNode* nodep, AstNUser*) {
+	nodep->iterateChildren(*this);
+    }
+
+public:
+    // CONSTRUCTORS
+    PremitAssignVisitor(AstNodeAssign* nodep) {
+	UINFO(4,"  PremitAssignVisitor on "<<nodep<<endl);
+	m_noopt = false;
+	nodep->accept(*this);
+    }
+    virtual ~PremitAssignVisitor() {}
+    bool noOpt() const { return m_noopt; }
+};
+
 //######################################################################
 // Premit state, as a visitor of each AstNode
 
@@ -49,6 +103,7 @@ private:
     //  AstNodeMath::user()	-> bool.  True if iterated already
     //  AstShiftL::user2()	-> bool.  True if converted to conditional
     //  AstShiftR::user2()	-> bool.  True if converted to conditional
+    //  *::user4()		-> See PremitAssignVisitor
     AstUser1InUse	m_inuser1;
     AstUser2InUse	m_inuser2;
 
@@ -115,11 +170,13 @@ private:
 	    m_inWhilep->addPrecondsp(newp);
 	} else if (m_inTracep) {
 	    m_inTracep->addPrecondsp(newp);
-	} else {
+	} else if (m_stmtp) {
 	    AstNRelinker linker;
 	    m_stmtp->unlinkFrBack(&linker);
 	    newp->addNext(m_stmtp);
 	    linker.relink(newp);
+	} else {
+	    newp->v3fatalSrc("No statement insertion point.");
 	}
     }
 
@@ -174,6 +231,14 @@ private:
     }
     virtual void visit(AstNodeAssign* nodep, AstNUser*) {
 	startStatement(nodep);
+	{
+	    bool noopt = PremitAssignVisitor(nodep).noOpt();
+	    if (noopt && !nodep->user1()) {
+		// Need to do this even if not wide, as e.g. a select may be on a wide operator
+		UINFO(4,"Deep temp for LHS/RHS\n");
+		createDeepTemp(nodep->rhsp());
+	    }
+	}
 	nodep->rhsp()->iterateAndNext(*this);
 	m_assignLhs = true;
 	nodep->lhsp()->iterateAndNext(*this);
diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp
index 00ab01e..ce2dffa 100644
--- a/src/V3Scope.cpp
+++ b/src/V3Scope.cpp
@@ -270,6 +270,10 @@ private:
 	if (afterp) afterp->unlinkFrBackWithNext();
 	nodep->scopeAttrp(new AstText(nodep->fileline(), prefix));
 	if (afterp) nodep->scopeAttrp(afterp);
+	afterp = nodep->scopeEntrp();
+	if (afterp) afterp->unlinkFrBackWithNext();
+	nodep->scopeEntrp(new AstText(nodep->fileline(), prefix));
+	if (afterp) nodep->scopeEntrp(afterp);
 	nodep->iterateChildren(*this);
     }
     virtual void visit(AstScope* nodep, AstNUser*) {
diff --git a/src/V3Split.cpp b/src/V3Split.cpp
index a70dfd6..2df3783 100644
--- a/src/V3Split.cpp
+++ b/src/V3Split.cpp
@@ -233,7 +233,6 @@ private:
     SplitPliVertex*	m_pliVertexp;	// Element specifying PLI ordering
     V3Graph		m_graph;	// Scoreboard of var usages/dependencies
     bool		m_inDly;	// Inside ASSIGNDLY
-    uint32_t		m_stepNum;	// Step number we need to ignore a edge in
     V3Double0		m_statSplits;	// Statistic tracking
 
     // METHODS
diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp
index e418390..aa84f92 100644
--- a/src/V3TraceDecl.cpp
+++ b/src/V3TraceDecl.cpp
@@ -43,7 +43,6 @@ private:
     // NODE STATE
 
     // STATE
-    AstNodeModule*	m_modp;		// Current module
     AstScope*		m_scopetopp;	// Current top scope
     AstCFunc*		m_initFuncp;	// Trace function being built
     AstCFunc*		m_initSubFuncp;	// Trace function being built (under m_init)
diff --git a/src/V3Width.cpp b/src/V3Width.cpp
index ff95810..62bdb3e 100644
--- a/src/V3Width.cpp
+++ b/src/V3Width.cpp
@@ -690,15 +690,21 @@ private:
 	// Pow is special, output sign only depends on LHS sign, but function result depends on both signs
 	// RHS is self-determined (IEEE)
 	// Real if either side is real (as with AstAdd)
-	iterate_shift_prelim(nodep, vup);  // Iterate rhsp() as self-determined
-
 	if (vup->c()->prelim()) {
+	    nodep->lhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p());
+	    nodep->rhsp()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p());
 	    if (nodep->lhsp()->isDouble() || nodep->rhsp()->isDouble()) {
 		spliceCvtD(nodep->lhsp());
 		spliceCvtD(nodep->rhsp());
 		replaceWithDVersion(nodep); nodep=NULL;
+		return;
 	    }
+
+	    checkCvtUS(nodep->lhsp());
+	    iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH);
+	    nodep->dtypeFrom(nodep->lhsp());
 	}
+
 	if (vup->c()->final()) {
 	    AstNodeDType* expDTypep = vup->c()->dtypeOverridep(nodep->dtypep());
 	    nodep->dtypeFrom(expDTypep);
@@ -902,7 +908,7 @@ private:
 	} else if (!basicp->isSigned() && newp->isSigned()) {
 	    newp = new AstUnsigned(nodep->fileline(), newp);
 	} else {
-	    newp = newp; // Can just remove cast
+	    //newp = newp; // Can just remove cast
 	}
 	nodep->replaceWith(newp);
 	pushDeletep(nodep); nodep=NULL;
@@ -2297,7 +2303,7 @@ private:
 	if (newp) {}  // Ununused
     }
     void iterate_shift_prelim(AstNodeBiop* nodep, AstNUser* vup)  {
-	// Shifts, Pow
+	// Shifts
 	// See IEEE-2012 11.4.10 and Table 11-21.
 	//   RHS is self-determined. RHS is always treated as unsigned, has no effect on result.
 	if (vup->c()->prelim()) {
@@ -2885,6 +2891,7 @@ private:
 	switch (nodep->type()) {
 	case AstType::atADD:  				newp = new AstAddD	(fl,lhsp,rhsp); break;
 	case AstType::atSUB:  				newp = new AstSubD	(fl,lhsp,rhsp); break;
+	case AstType::atPOW:				newp = new AstPowD	(fl,lhsp,rhsp); break;
 	case AstType::atEQ:	case AstType::atEQCASE:	newp = new AstEqD	(fl,lhsp,rhsp); break;
 	case AstType::atNEQ:	case AstType::atNEQCASE: newp = new AstNeqD	(fl,lhsp,rhsp); break;
 	case AstType::atGT:	case AstType::atGTS:	newp = new AstGtD	(fl,lhsp,rhsp); break;
diff --git a/src/config_build.h b/src/config_build.h
index c860ddd..f92709e 100644
--- a/src/config_build.h
+++ b/src/config_build.h
@@ -27,7 +27,7 @@
 //**** Version and host name
 
 // Autoconf substitutes this with the strings from AC_INIT.
-#define PACKAGE_STRING "Verilator 3.862 2014-06-10"
+#define PACKAGE_STRING "Verilator 3.864 2014-09-21"
 
 #define DTVERSION	PACKAGE_STRING
 
diff --git a/src/config_rev.h b/src/config_rev.h
index 8533bdf..b2eb163 100644
--- a/src/config_rev.h
+++ b/src/config_rev.h
@@ -1 +1 @@
-static const char* DTVERSION_rev = "verilator_3_860-25-gfedcb6d";
+static const char* DTVERSION_rev = "verilator_3_862-18-ge8edbad";
diff --git a/src/verilog.y b/src/verilog.y
index 2b6389a..5e4d869 100644
--- a/src/verilog.y
+++ b/src/verilog.y
@@ -62,8 +62,8 @@ public:
     int		m_pinNum;	// Pin number currently parsing
     string	m_instModule;	// Name of module referenced for instantiations
     AstPin*	m_instParamp;	// Parameters for instantiations
-    AstNodeModule* m_modp;	// Module
-    int		m_modTypeImpNum; // Implicit type number, incremented each module
+
+    static int	s_modTypeImpNum; // Implicit type number, incremented each module
 
     // CONSTRUCTORS
     V3ParseGrammar() {
@@ -76,8 +76,6 @@ public:
 	m_pinNum = -1;
 	m_instModule = "";
 	m_instParamp = NULL;
-	m_modp = NULL;
-	m_modTypeImpNum = 0;
 	m_varAttrp = NULL;
 	m_caseAttrp = NULL;
     }
@@ -121,7 +119,6 @@ public:
 	AstPackage* pkgp = SYMP->symRootp()->findIdFlat(AstPackage::dollarUnitName())->nodep()->castPackage();
 	if (!pkgp) {
 	    pkgp = PARSEP->rootp()->dollarUnitPkgAddp();
-	    GRAMMARP->m_modp = pkgp; GRAMMARP->m_modTypeImpNum = 0;
 	    SYMP->reinsert(pkgp, SYMP->symRootp());  // Don't push/pop scope as they're global
 	}
 	return pkgp;
@@ -167,6 +164,8 @@ public:
 const AstBasicDTypeKwd LOGIC = AstBasicDTypeKwd::LOGIC;	// Shorthand "LOGIC"
 const AstBasicDTypeKwd LOGIC_IMPLICIT = AstBasicDTypeKwd::LOGIC_IMPLICIT;
 
+int V3ParseGrammar::s_modTypeImpNum = 0;
+
 //======================================================================
 // Macro functions
 
@@ -697,7 +696,6 @@ packageFront<modulep>:
 			{ $$ = new AstPackage($1,*$2);
 			  $$->inLibrary(true);  // packages are always libraries; don't want to make them a "top"
 			  $$->modTrace(v3Global.opt.trace());
-			  GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
 			  PARSEP->rootp()->addModulep($$);
 			  SYMP->pushNew($$); }
 	;
@@ -793,7 +791,6 @@ modFront<modulep>:
 		yMODULE lifetimeE idAny
 			{ $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine());
 			  $$->modTrace(v3Global.opt.trace());
-			  GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
 			  PARSEP->rootp()->addModulep($$);
 			  SYMP->pushNew($$); }
 	;
@@ -810,7 +807,6 @@ udpFront<modulep>:
 			  $$->modTrace(false);
 			  $$->addStmtp(new AstPragma($1,AstPragmaType::INLINE_MODULE));
 			  PARSEP->fileline()->tracingOn(false);
-			  GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
 			  PARSEP->rootp()->addModulep($$);
 			  SYMP->pushNew($$); }
 	;
@@ -845,8 +841,7 @@ paramPortDeclOrArgList<nodep>:	// IEEE: list_of_param_assignments + { parameter_
 
 paramPortDeclOrArg<nodep>:	// IEEE: param_assignment + parameter_port_declaration
 	//			// We combine the two as we can't tell which follows a comma
-		param_assignment				{ $$ = $1; }
-	|	parameter_port_declarationFront param_assignment	{ $$ = $2; }
+		parameter_port_declarationFrontE param_assignment	{ $$ = $2; }
 	;
 
 portsStarE<nodep>:		// IEEE: .* + list_of_ports + list_of_port_declarations + empty
@@ -1029,7 +1024,6 @@ pgmFront<modulep>:
 		yPROGRAM lifetimeE idAny/*new_program*/
 			{ $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine());
 			  $$->modTrace(v3Global.opt.trace());
-			  GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
 			  PARSEP->rootp()->addModulep($$);
 			  SYMP->pushNew($$); }
 	;
@@ -1154,10 +1148,13 @@ parameter_declarationFront:	// IEEE: parameter_declaration w/o assignment
 	//UNSUP	varGParamReset yTYPE			{ /*VARRESET-in-varGParam*/ VARDTYPE($2); }
 	;
 
-parameter_port_declarationFront: // IEEE: parameter_port_declaration w/o assignment
+parameter_port_declarationFrontE: // IEEE: parameter_port_declaration w/o assignment
 	//			// IEEE: parameter_declaration (minus assignment)
-		parameter_declarationFront		{ }
-	//
+		varGParamReset implicit_typeE 		{ /*VARRESET-in-varGParam*/ VARDTYPE($2); }
+	|	varGParamReset data_type		{ /*VARRESET-in-varGParam*/ VARDTYPE($2); }
+	|	implicit_typeE 				{ /*VARRESET-in-varGParam*/ VARDTYPE($1); }
+	|	data_type				{ /*VARRESET-in-varGParam*/ VARDTYPE($1); }
+	//UNSUP	varGParamReset yTYPE			{ /*VARRESET-in-varGParam*/ VARDTYPE($2); }
 	//UNSUP	data_type				{ VARDTYPE($1); }
 	//UNSUP	yTYPE 					{ VARDTYPE($1); }
 	;
@@ -1344,10 +1341,10 @@ data_typeBasic<dtypep>:		// IEEE: part of data_type
 
 data_typeNoRef<dtypep>:		// ==IEEE: data_type, excluding class_type etc references
 		data_typeBasic				{ $$ = $1; }
-	|	struct_unionDecl packed_dimensionListE	{ $$ = GRAMMARP->createArray(new AstDefImplicitDType($1->fileline(),"__typeimpsu"+cvtToStr(GRAMMARP->m_modTypeImpNum++),
-													     GRAMMARP->m_modp,VFlagChildDType(),$1),$2,true); }
-	|	enumDecl				{ $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->m_modTypeImpNum++),
-										       GRAMMARP->m_modp,VFlagChildDType(),$1); }
+	|	struct_unionDecl packed_dimensionListE	{ $$ = GRAMMARP->createArray(new AstDefImplicitDType($1->fileline(),"__typeimpsu"+cvtToStr(GRAMMARP->s_modTypeImpNum++),
+													     SYMP,VFlagChildDType(),$1),$2,true); }
+	|	enumDecl				{ $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->s_modTypeImpNum++),
+										       SYMP,VFlagChildDType(),$1); }
 	|	ySTRING					{ $$ = new AstBasicDType($1,AstBasicDTypeKwd::STRING); }
 	|	yCHANDLE				{ $$ = new AstBasicDType($1,AstBasicDTypeKwd::CHANDLE); }
 	//UNSUP	yEVENT					{ UNSUP }
diff --git a/test_regress/driver.pl b/test_regress/driver.pl
index 77962e6..abee28c 100755
--- a/test_regress/driver.pl
+++ b/test_regress/driver.pl
@@ -673,7 +673,7 @@ sub compile {
 
     if ($param{make_pli}) {
 	$self->oprint("Compile vpi\n");
-	my @cmd = ('g++', @{$param{pli_flags}}, "-DIS_VPI", "$self->{t_dir}/$self->{name}.cpp");
+	my @cmd = ('c++', @{$param{pli_flags}}, "-DIS_VPI", "$self->{t_dir}/$self->{name}.cpp");
 
 	$self->_run(logfile=>"$self->{obj_dir}/pli_compile.log",
 		    fails=>$param{fails},
diff --git a/test_regress/t/t_EXAMPLE.v b/test_regress/t/t_EXAMPLE.v
index 7844313..2075946 100644
--- a/test_regress/t/t_EXAMPLE.v
+++ b/test_regress/t/t_EXAMPLE.v
@@ -54,10 +54,10 @@ module t (/*AUTOARG*/
       if (cyc==0) begin
 	 // Setup
 	 crc <= 64'h5aef0c8d_d70a4497;
-	 sum <= 64'h0;
+	 sum <= '0;
       end
       else if (cyc<10) begin
-	 sum <= 64'h0;
+	 sum <= '0;
       end
       else if (cyc<90) begin
       end
diff --git a/test_regress/t/t_assert_basic.v b/test_regress/t/t_assert_basic.v
index 02322c7..e51eed5 100644
--- a/test_regress/t/t_assert_basic.v
+++ b/test_regress/t/t_assert_basic.v
@@ -33,7 +33,7 @@ module t (/*AUTOARG*/
 	    assert (0) else $info;
 	    assert (0) else $info("Info message");
 	    assert (0) else $info("Info message, cyc=%d", cyc);
-	    InWarningBlock: assert (0) else $warning("Warning....");
+	    InWarningBlock: assert (0) else $warning("Warning.... 1.0=%f 2.0=%f", 1.0, 2.0);
 	    InErrorBlock: assert (0) else $error("Error....");
 	    assert (0) else $fatal(1,"Fatal....");
 `endif
diff --git a/test_regress/t/t_case_huge.pl b/test_regress/t/t_case_huge.pl
index 4d285b7..e29a6c0 100755
--- a/test_regress/t/t_case_huge.pl
+++ b/test_regress/t/t_case_huge.pl
@@ -8,17 +8,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
 # Version 2.0.
 
 compile (
-	 verilator_flags2 => ["--stats --profile-cfuncs"],
-	 );
+    verilator_flags2 => ["--stats"],
+    );
 
 if ($Self->{vlt}) {
     file_grep ($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10);
-    file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 10);
+    file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 9);
 }
 
 execute (
-	 check_finished=>1,
-     );
+    check_finished=>1,
+    );
 
 ok(1);
 1;
diff --git a/test_regress/t/t_case_huge_prof.pl b/test_regress/t/t_case_huge_prof.pl
new file mode 100755
index 0000000..d753930
--- /dev/null
+++ b/test_regress/t/t_case_huge_prof.pl
@@ -0,0 +1,44 @@
+#!/usr/bin/perl
+if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
+# 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
+# Lesser General Public License Version 3 or the Perl Artistic License
+# Version 2.0.
+
+$Self->{vlt} or $Self->skip("Verilator only test");
+
+top_filename("t/t_case_huge.v");
+
+compile (
+    verilator_flags2 => ["--stats --profile-cfuncs -CFLAGS '-pg' -LDFLAGS '-pg'"],
+    );
+
+if ($Self->{vlt}) {
+    file_grep ($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10);
+    file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 10);
+}
+
+unlink $_ foreach (glob "$Self->{obj_dir}/gmon.out.*");
+$ENV{GMON_OUT_PREFIX} = "$Self->{obj_dir}/gmon.out";
+
+execute (
+    check_finished=>1,
+    );
+
+my $gmon_path;
+$gmon_path = $_ foreach (glob "$Self->{obj_dir}/gmon.out.*");
+$gmon_path or $Self->error("Profiler did not create a gmon.out");
+(my $gmon_base = $gmon_path) =~ s!.*[/\\]!!;
+
+$Self->_run(cmd=>["cd $Self->{obj_dir} && gprof $Self->{VM_PREFIX} $gmon_base > gprof.out"],
+	    check_finished=>0);
+
+$Self->_run(cmd=>["cd $Self->{obj_dir} && $ENV{VERILATOR_ROOT}/bin/verilator_profcfunc gprof.out > cfuncs.out"],
+	    check_finished=>0);
+
+file_grep ("$Self->{obj_dir}/cfuncs.out", qr/Overall summary by/);
+
+ok(1);
+1;
diff --git a/test_regress/t/t_dpi_context.v b/test_regress/t/t_dpi_context.v
index f2cff60..d428a94 100644
--- a/test_regress/t/t_dpi_context.v
+++ b/test_regress/t/t_dpi_context.v
@@ -27,6 +27,7 @@ module sub (input integer inst);
    import "DPI-C" context function int dpic_line();
    import "DPI-C" context function int dpic_save(int value);
    import "DPI-C" context function int dpic_restore();
+   import "DPI-C" context function int unsigned dpic_getcontext();
 
    int result;
 
@@ -49,4 +50,17 @@ module sub (input integer inst);
       if (dpic_restore() != 23+inst) $stop;
    endtask
 
+   int unsigned cntxt1;
+   int unsigned cntxt2;
+
+   initial begin
+     cntxt1 = dpic_getcontext();
+     begin : caller_context
+       // call from a different scope - should still get the context of the function declaration
+       cntxt2 = dpic_getcontext();
+     end
+     // svContext should be the context of the function declaration, not the context of the function call
+     if (cntxt1 != cntxt2) $stop;
+   end
+
 endmodule
diff --git a/test_regress/t/t_dpi_context_c.cpp b/test_regress/t/t_dpi_context_c.cpp
index 12494fc..29a974e 100644
--- a/test_regress/t/t_dpi_context_c.cpp
+++ b/test_regress/t/t_dpi_context_c.cpp
@@ -42,6 +42,7 @@ extern "C" {
     extern int dpic_line();
     extern int dpic_save(int value);
     extern int dpic_restore();
+    extern unsigned dpic_getcontext();
 }
 #endif
 
@@ -126,3 +127,9 @@ int dpic_restore() {
 	return 0;
     }
 }
+
+unsigned dpic_getcontext() {
+    svScope scope = svGetScope();
+    printf("%%Info: svGetScope returned scope (%p) with name %s\n", scope, svGetNameFromScope(scope));
+    return (unsigned) (uintptr_t) scope;
+}
diff --git a/test_regress/t/t_flag_ldflags.pl b/test_regress/t/t_flag_ldflags.pl
index 4d7b59a..5a1d6bb 100755
--- a/test_regress/t/t_flag_ldflags.pl
+++ b/test_regress/t/t_flag_ldflags.pl
@@ -10,13 +10,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
 $Self->{vlt} or $Self->skip("Verilator only test");
 
 $Self->_run (cmd=>["cd $Self->{obj_dir}"
-		   ." && g++ -c ../../t/t_flag_ldflags_a.cpp"
+		   ." && c++ -c ../../t/t_flag_ldflags_a.cpp"
 		   ." && ar r t_flag_ldflags_a.a t_flag_ldflags_a.o"
 		   ." && ranlib t_flag_ldflags_a.a "],
 	     check_finished=>0);
 $Self->_run (cmd=>["cd $Self->{obj_dir}"
-		   ." && g++ -fPIC -c ../../t/t_flag_ldflags_so.cpp"
-		   ." && g++ -shared -o t_flag_ldflags_so.so -lc t_flag_ldflags_so.o"],
+		   ." && c++ -fPIC -c ../../t/t_flag_ldflags_so.cpp"
+		   ." && c++ -shared -o t_flag_ldflags_so.so -lc t_flag_ldflags_so.o"],
 	     check_finished=>0);
 
 compile (
diff --git a/test_regress/t/t_math_real.v b/test_regress/t/t_math_real.v
index 9fc2c77..dcb19a0 100644
--- a/test_regress/t/t_math_real.v
+++ b/test_regress/t/t_math_real.v
@@ -5,6 +5,8 @@
 // Lesser General Public License Version 3 or the Perl Artistic License
 // Version 2.0.
 
+`define is_near_real(a,b)  ($abs((a)-(b)) < (((a)/(b))*0.0001))
+
 module t (/*AUTOARG*/
    // Inputs
    clk
diff --git a/test_regress/t/t_math_trig.v b/test_regress/t/t_math_trig.v
index 3b2c549..6d60403 100644
--- a/test_regress/t/t_math_trig.v
+++ b/test_regress/t/t_math_trig.v
@@ -25,6 +25,7 @@ module t (/*AUTOARG*/
 
    initial begin
       // Check constant propagation
+      // Note $abs is not defined in SystemVerilog (as of 2012)
       check(`__LINE__, $ceil(-1.2),	-1);
       check(`__LINE__, $ceil(1.2),	2);
       check(`__LINE__, $exp(1.2),	3.3201169227365472380597566370852291584014892578125);
@@ -43,6 +44,7 @@ module t (/*AUTOARG*/
       //check(`__LINE__, $pow(-2.3,1.2),0);	// Bad value
       check(`__LINE__, $sqrt(1.2),	1.095445115010332148841598609578795731067657470703125);
       //check(`__LINE__, $sqrt(-1.2),	0);	// Bad value
+      check(`__LINE__, ((1.5)**(1.25)), 1.660023);
 `ifndef VERILATOR
       check(`__LINE__, $acos (0.2),	1.369438406);	// Arg1 is -1..1
       check(`__LINE__, $acosh(1.2),	0.622362503);
diff --git a/test_regress/t/t_param.v b/test_regress/t/t_param.v
index 9e7402c..8418cf4 100644
--- a/test_regress/t/t_param.v
+++ b/test_regress/t/t_param.v
@@ -46,8 +46,8 @@ module m1;
    initial if (PACKED_PARAM != 8'h36) $stop;
 endmodule
 
-module m2;
-   parameter PAR2 = 10;
+// bug 810
+module m2 #(/*parameter*/ integer PAR2 = 10);
    initial begin
       $display("%x",PAR2);
       if (PAR2 !== 2) $stop;
diff --git a/test_regress/t/t_case_huge.pl b/test_regress/t/t_struct_anon.pl
similarity index 59%
copy from test_regress/t/t_case_huge.pl
copy to test_regress/t/t_struct_anon.pl
index 4d285b7..1774aab 100755
--- a/test_regress/t/t_case_huge.pl
+++ b/test_regress/t/t_struct_anon.pl
@@ -8,17 +8,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
 # Version 2.0.
 
 compile (
-	 verilator_flags2 => ["--stats --profile-cfuncs"],
-	 );
-
-if ($Self->{vlt}) {
-    file_grep ($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10);
-    file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 10);
-}
-
-execute (
-	 check_finished=>1,
-     );
+    v_flags2 => ["--lint-only"],
+    verilator_make_gcc => 0,
+    make_top_shell => 0,
+    make_main => 0,
+    );
 
 ok(1);
 1;
diff --git a/test_regress/t/t_struct_anon.v b/test_regress/t/t_struct_anon.v
new file mode 100644
index 0000000..2b97364
--- /dev/null
+++ b/test_regress/t/t_struct_anon.v
@@ -0,0 +1,26 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2013 by Wilson Snyder.
+
+// Anonymous
+struct packed {
+    logic [31:0] val1;
+    logic [31:0] val2;
+} struct1;
+
+struct packed {
+    logic [31:0] val3;
+    logic [31:0] val4;
+} struct2;
+
+module t (
+    output [63:0] 	s1,
+    output [63:0] 	s2
+);
+   initial struct1 = 64'h123456789_abcdef0;
+   always_comb s1 = struct1;
+   initial struct2 = 64'h123456789_abcdef0;
+   always_comb s2 = struct2;
+endmodule
+
diff --git a/test_regress/t/t_case_huge.pl b/test_regress/t/t_struct_unaligned.pl
similarity index 61%
copy from test_regress/t/t_case_huge.pl
copy to test_regress/t/t_struct_unaligned.pl
index 4d285b7..3608a5a 100755
--- a/test_regress/t/t_case_huge.pl
+++ b/test_regress/t/t_struct_unaligned.pl
@@ -7,18 +7,15 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
 # Lesser General Public License Version 3 or the Perl Artistic License
 # Version 2.0.
 
-compile (
-	 verilator_flags2 => ["--stats --profile-cfuncs"],
-	 );
+# Note: need to run at a higher optimization level to reproduce the issue
+$Self->{benchmark} = 1;
 
-if ($Self->{vlt}) {
-    file_grep ($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10);
-    file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 10);
-}
+compile (
+    );
 
 execute (
-	 check_finished=>1,
-     );
+    check_finished=>1,
+    );
 
 ok(1);
 1;
diff --git a/test_regress/t/t_struct_unaligned.v b/test_regress/t/t_struct_unaligned.v
new file mode 100644
index 0000000..9faf1ff
--- /dev/null
+++ b/test_regress/t/t_struct_unaligned.v
@@ -0,0 +1,35 @@
+// DESCRIPTION: Verilator:
+//  Test an error where a shift amount was out of bounds and the compiler treats the
+//  value as undefined (Issue #803)
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2014 by Jeff Bush.
+
+module t (/*AUTOARG*/
+    // Inputs
+    clk
+    );
+    input clk;
+
+    struct packed {
+	logic flag;
+	logic [130:0] data;
+    } foo[1];
+
+    integer cyc=0;
+
+    // Test loop
+    always @ (posedge clk) begin
+	cyc <= cyc + 1;
+	foo[0].data <= 0;
+	foo[0].flag <= !foo[0].flag;
+	if (cyc==10) begin
+	   if (foo[0].data != 0) begin
+	   	$display("bad data value %x", foo[0].data);
+		$stop;
+	   end
+	   $write("*-* All Finished *-*\n");
+	   $finish;
+	end
+    end
+endmodule
diff --git a/test_regress/t/t_case_huge.pl b/test_regress/t/t_trace_param.pl
similarity index 50%
copy from test_regress/t/t_case_huge.pl
copy to test_regress/t/t_trace_param.pl
index 4d285b7..abf8ed7 100755
--- a/test_regress/t/t_case_huge.pl
+++ b/test_regress/t/t_trace_param.pl
@@ -2,23 +2,20 @@
 if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
 # DESCRIPTION: Verilator: Verilog Test driver/expect definition
 #
-# Copyright 2003 by Wilson Snyder. This program is free software; you can
+# Copyright 2003-2013 by Wilson Snyder. This program is free software; you can
 # redistribute it and/or modify it under the terms of either the GNU
 # Lesser General Public License Version 3 or the Perl Artistic License
 # Version 2.0.
 
-compile (
-	 verilator_flags2 => ["--stats --profile-cfuncs"],
-	 );
+$Self->{vlt} or $Self->skip("Verilator only test");
 
-if ($Self->{vlt}) {
-    file_grep ($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10);
-    file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 10);
-}
+compile (
+    v_flags2 => ["--trace"],
+    );
 
 execute (
-	 check_finished=>1,
-     );
+    check_finished=>1,
+    );
 
 ok(1);
 1;
diff --git a/test_regress/t/t_trace_param.v b/test_regress/t/t_trace_param.v
new file mode 100644
index 0000000..8f81eec
--- /dev/null
+++ b/test_regress/t/t_trace_param.v
@@ -0,0 +1,36 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2014 by Jonathon Donaldson.
+
+package my_funcs;
+   function automatic int simple_func (input int value);
+      begin
+	 simple_func = value;
+      end
+   endfunction
+endpackage
+
+package my_module_types;
+   import my_funcs::*;
+
+   localparam MY_PARAM = 3;
+   localparam MY_PARAM2 /*verilator public*/ = simple_func(12);
+endpackage
+
+module t
+  import my_module_types::*;
+   (
+    input 			i_clk,
+    input [MY_PARAM-1:0] 	i_d,
+    output logic [MY_PARAM-1:0] o_q
+    );
+
+   always_ff @(posedge i_clk)
+     o_q <= i_d;
+
+   initial begin
+      $write("*-* All Finished *-*\n");
+      $finish;
+   end
+endmodule
diff --git a/test_regress/t/t_case_huge.pl b/test_regress/t/t_var_assign_landr.pl
similarity index 61%
copy from test_regress/t/t_case_huge.pl
copy to test_regress/t/t_var_assign_landr.pl
index 4d285b7..f912897 100755
--- a/test_regress/t/t_case_huge.pl
+++ b/test_regress/t/t_var_assign_landr.pl
@@ -8,17 +8,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
 # Version 2.0.
 
 compile (
-	 verilator_flags2 => ["--stats --profile-cfuncs"],
-	 );
-
-if ($Self->{vlt}) {
-    file_grep ($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10);
-    file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 10);
-}
+    );
 
 execute (
-	 check_finished=>1,
-     );
+    check_finished=>1,
+    );
 
 ok(1);
 1;
diff --git a/test_regress/t/t_EXAMPLE.v b/test_regress/t/t_var_assign_landr.v
similarity index 64%
copy from test_regress/t/t_EXAMPLE.v
copy to test_regress/t/t_var_assign_landr.v
index 7844313..e03dedb 100644
--- a/test_regress/t/t_EXAMPLE.v
+++ b/test_regress/t/t_var_assign_landr.v
@@ -23,41 +23,39 @@ module t (/*AUTOARG*/
 
    integer 	cyc=0;
    reg [63:0] 	crc;
-   reg [63:0] 	sum;
+   reg [255:0] 	sum;
 
    // Take CRC data and apply to testblock inputs
-   wire [31:0]  in = crc[31:0];
+   wire [127:0]  in = {~crc[63:0], crc[63:0]};
 
    /*AUTOWIRE*/
    // Beginning of automatic wires (for undeclared instantiated-module outputs)
-   wire [31:0] 		out;			// From test of Test.v
+   wire [127:0]		o1;			// From test of Test.v
+   wire [127:0]		o2;			// From test of Test.v
    // End of automatics
 
    Test test (/*AUTOINST*/
 	      // Outputs
-	      .out			(out[31:0]),
+	      .o1			(o1[127:0]),
+	      .o2			(o2[127:0]),
 	      // Inputs
-	      .clk			(clk),
-	      .in			(in[31:0]));
-
-   // Aggregate outputs into a single result vector
-   wire [63:0] result = {32'h0, out};
+	      .in			(in[127:0]));
 
    // Test loop
    always @ (posedge clk) begin
 `ifdef TEST_VERBOSE
-      $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result);
+      $write("[%0t] cyc==%0d crc=%x result=%x %x\n",$time, cyc, crc, o1, o2);
 `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]};
+      sum <= {o1,o2} ^ {sum[254:0],sum[255]^sum[2]^sum[0]};
       if (cyc==0) begin
 	 // Setup
 	 crc <= 64'h5aef0c8d_d70a4497;
-	 sum <= 64'h0;
+	 sum <= '0;
       end
       else if (cyc<10) begin
-	 sum <= 64'h0;
+	 sum <= '0;
       end
       else if (cyc<90) begin
       end
@@ -65,7 +63,7 @@ module t (/*AUTOARG*/
 	 $write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
 	 if (crc !== 64'hc77bb9b3784ea091) $stop;
 	 // What checksum will we end up with (above print should match)
-`define EXPECTED_SUM 64'h4afe43fb79d7b71e
+`define EXPECTED_SUM 256'h008a080aaa000000140550404115dc7b008a080aaae7c8cd897bc1ca49c9350a
 	 if (sum !== `EXPECTED_SUM) $stop;
 	 $write("*-* All Finished *-*\n");
 	 $finish;
@@ -76,21 +74,29 @@ endmodule
 
 module Test (/*AUTOARG*/
    // Outputs
-   out,
+   o1, o2,
    // Inputs
-   clk, in
+   in
    );
 
-   // Replace this module with the device under test.
-   //
-   // Change the code in the t module to apply values to the inputs and
-   // merge the output values into the result vector.
+   input [127:0] in;
+   output logic [127:0] o1;
+   output logic [127:0] o2;
+   
+   always_comb begin: b_test
+      logic [127:0] tmpp;
+      logic [127:0] tmp;
+      tmp  = '0;
+      tmpp = '0;
 
-   input clk;
-   input [31:0] in;
-   output reg [31:0] out;
+      tmp[63:0]  = in[63:0];
+      tmpp[63:0] = in[63:0];
 
-   always @(posedge clk) begin
-      out <= in;
+      tmpp[63:0] = {tmp[0+:32], tmp[32+:32]};
+      tmp[63:0]  = {tmp[0+:32], tmp[32+:32]};
+
+      o1 = tmp;
+      o2 = tmpp;
    end
+
 endmodule
diff --git a/test_regress/t/t_vpi_get.cpp b/test_regress/t/t_vpi_get.cpp
index e1e78dc..c6bc3ac 100644
--- a/test_regress/t/t_vpi_get.cpp
+++ b/test_regress/t/t_vpi_get.cpp
@@ -152,7 +152,7 @@ struct params {
       unsigned int  size;
       unsigned int  direction;
       unsigned int  scalar;
-      unsigned int  type;
+      int  type;
     } attributes, children;
 } values[] = {
     {"onebit", {1, vpiNoDirection, 1, vpiReg}, {0, 0, 0, 0}},
diff --git a/test_regress/t/t_vpi_memory.cpp b/test_regress/t/t_vpi_memory.cpp
index 785ef94..57c7bd4 100644
--- a/test_regress/t/t_vpi_memory.cpp
+++ b/test_regress/t/t_vpi_memory.cpp
@@ -133,7 +133,7 @@ int _mon_check_memory() {
     // iterate and store
     iter_h = vpi_iterate(vpiMemoryWord, mem_h);
     cnt = 0;
-    while (lcl_h = vpi_scan(iter_h)) {
+    while ((lcl_h = vpi_scan(iter_h))) {
 	value.value.integer = ++cnt;
         vpi_put_value(lcl_h, &value, NULL, vpiNoDelay);
         // check size and range
@@ -143,7 +143,7 @@ int _mon_check_memory() {
     // iterate and accumulate
     iter_h = vpi_iterate(vpiMemoryWord, mem_h);
     cnt = 0;
-    while (lcl_h = vpi_scan(iter_h)) {
+    while ((lcl_h = vpi_scan(iter_h))) {
       ++cnt;
       vpi_get_value(lcl_h, &value);
       CHECK_RESULT(value.value.integer, cnt);
diff --git a/verilator.1 b/verilator.1
index 73b9a2b..26f5a1d 100644
--- a/verilator.1
+++ b/verilator.1
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "VERILATOR 1"
-.TH VERILATOR 1 "2014-06-10" "perl v5.14.2" "User Contributed Perl Documentation"
+.TH VERILATOR 1 "2014-08-31" "perl v5.14.2" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -665,8 +665,10 @@ Ignored for compatibility with other simulators.
 Disables optimization of the model.
 .IP "\-O3" 4
 .IX Item "-O3"
-Enables slow optimizations.  This may reduce simulation runtimes at the
-cost of compile time.  This currently sets \-\-inline\-mult \-1.
+Enables slow optimizations for the code Verilator itself generates (as
+opposed to \*(L"\-CFLAGS \-O3\*(R" which effects the C compiler's optimization.  \-O3
+may reduce simulation runtimes at the cost of compile time.  This currently
+sets \-\-inline\-mult \-1.
 .IP "\-O\fIoptimization-letter\fR" 4
 .IX Item "-Ooptimization-letter"
 Rarely needed.  Enables or disables a specific optimizations, with the
@@ -2740,8 +2742,8 @@ simulators.
 Warns that an `include filename specifies an absolute path.  This means the
 code will not work on any other system with a different file system layout.
 Instead of using absolute paths, relative paths (preferably without any
-directory specified whatever) should be used, and +include used on the
-command line to specify the top include source directory.
+directory specified whatever) should be used, and +incdir used on the
+command line to specify the top include source directories.
 .Sp
 Disabled by default as this is a code style warning; it will simulate
 correctly.
diff --git a/verilator.html b/verilator.html
index a1a4cca..f6f7670 100644
--- a/verilator.html
+++ b/verilator.html
@@ -720,8 +720,10 @@ files are identical, and all output files exist with newer dates.</p>
 <dt><strong><a name="o3" class="item">-O3</a></strong></dt>
 
 <dd>
-<p>Enables slow optimizations.  This may reduce simulation runtimes at the
-cost of compile time.  This currently sets --inline-mult -1.</p>
+<p>Enables slow optimizations for the code Verilator itself generates (as
+opposed to "-CFLAGS -O3" which effects the C compiler's optimization.  -O3
+may reduce simulation runtimes at the cost of compile time.  This currently
+sets --inline-mult -1.</p>
 </dd>
 <dt><strong><a name="ooptimization_letter" class="item">-O<em>optimization-letter</em></a></strong></dt>
 
@@ -2905,8 +2907,8 @@ simulators.</p>
 <p>Warns that an `include filename specifies an absolute path.  This means the
 code will not work on any other system with a different file system layout.
 Instead of using absolute paths, relative paths (preferably without any
-directory specified whatever) should be used, and +include used on the
-command line to specify the top include source directory.</p>
+directory specified whatever) should be used, and +incdir used on the
+command line to specify the top include source directories.</p>
 <p>Disabled by default as this is a code style warning; it will simulate
 correctly.</p>
 </dd>
diff --git a/verilator.pdf b/verilator.pdf
index 81fb69c..3f883ea 100644
Binary files a/verilator.pdf and b/verilator.pdf differ
diff --git a/verilator.txt b/verilator.txt
index b0a7787..67e9e6f 100644
--- a/verilator.txt
+++ b/verilator.txt
@@ -536,8 +536,10 @@ ARGUMENTS
 
     -O0 Disables optimization of the model.
 
-    -O3 Enables slow optimizations. This may reduce simulation runtimes at
-        the cost of compile time. This currently sets --inline-mult -1.
+    -O3 Enables slow optimizations for the code Verilator itself generates
+        (as opposed to "-CFLAGS -O3" which effects the C compiler's
+        optimization. -O3 may reduce simulation runtimes at the cost of
+        compile time. This currently sets --inline-mult -1.
 
     -O*optimization-letter*
         Rarely needed. Enables or disables a specific optimizations, with
@@ -2547,8 +2549,8 @@ ERRORS AND WARNINGS
         means the code will not work on any other system with a different
         file system layout. Instead of using absolute paths, relative paths
         (preferably without any directory specified whatever) should be
-        used, and +include used on the command line to specify the top
-        include source directory.
+        used, and +incdir used on the command line to specify the top
+        include source directories.
 
         Disabled by default as this is a code style warning; it will
         simulate correctly.
diff --git a/veripool-logo.png b/veripool-logo.png
deleted file mode 100644
index 6ca0a53..0000000
Binary files a/veripool-logo.png and /dev/null differ

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-electronics/verilator.git



More information about the Pkg-electronics-commits mailing list