[Pkg-electronics-commits] [verilator] 01/02: Imported Upstream version 3.851

أحمد المحمودي (Ahmed El-Mahmoudy) aelmahmoudy at sabily.org
Sat Aug 24 13:29:59 UTC 2013


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

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

commit 9fc1ff7165ca14e5d1bd5eb49b00ff7b8f04d8ba
Author: أحمد المحمودي (Ahmed El-Mahmoudy) <aelmahmoudy at sabily.org>
Date:   Sat Aug 24 14:20:58 2013 +0200

    Imported Upstream version 3.851
---
 Changes                                            |   15 ++
 README.pdf                                         |  Bin 112274 -> 112563 bytes
 configure                                          |   18 +-
 configure.ac                                       |    2 +-
 include/verilated.cpp                              |   18 +-
 include/verilated.h                                |    7 +-
 include/verilated_config.h                         |    2 +-
 include/verilated_heavy.h                          |    4 +
 include/verilated_syms.h                           |   18 +-
 include/verilated_vpi.h                            |  176 +++++++++----
 internals.pdf                                      |  Bin 195627 -> 195921 bytes
 src/V3Active.cpp                                   |    2 +-
 src/V3Clock.cpp                                    |   12 +-
 src/V3Gate.cpp                                     |    2 +-
 src/V3LinkLevel.cpp                                |    2 +
 src/V3Number.cpp                                   |    2 +-
 src/V3Options.cpp                                  |    4 +-
 src/V3Order.cpp                                    |   26 +-
 src/V3OrderGraph.h                                 |    5 +-
 src/V3PreProc.cpp                                  |    3 +-
 src/V3Simulate.h                                   |    4 +-
 src/V3Width.cpp                                    |    3 +
 src/config_build.h                                 |    2 +-
 src/config_rev.h                                   |    2 +-
 src/verilog.y                                      |   35 ++-
 test_regress/driver.pl                             |   27 +-
 test_regress/t/t_clk_condflop.pl                   |    5 +-
 test_regress/t/t_clk_powerdn.pl                    |    5 +-
 .../t/{t_clk_condflop.pl => t_dpi_string.pl}       |   10 +-
 test_regress/t/t_dpi_string.v                      |   26 ++
 test_regress/t/t_dpi_string_c.cpp                  |   44 ++++
 test_regress/t/{t_clk_condflop.pl => t_final.pl}   |   11 +-
 test_regress/t/t_final.v                           |   27 ++
 .../t/{t_clk_condflop.pl => t_gated_clk_1.pl}      |   11 +-
 test_regress/t/t_gated_clk_1.v                     |   55 ++++
 .../t/{t_clk_condflop.pl => t_interface_twod.pl}   |    9 +-
 test_regress/t/t_interface_twod.v                  |   47 ++++
 .../t/{t_clk_condflop.pl => t_mod_recurse.pl}      |   11 +-
 test_regress/t/t_mod_recurse.v                     |  110 ++++++++
 test_regress/t/t_trace_cat.cpp                     |    2 +-
 .../t/{t_clk_condflop.pl => t_vams_wreal.pl}       |    9 +-
 test_regress/t/t_vams_wreal.v                      |   28 ++
 test_regress/t/t_vpi_memory.cpp                    |  278 ++++++++++++++++++++
 test_regress/t/t_vpi_memory.pl                     |   25 ++
 test_regress/t/t_vpi_memory.v                      |   47 ++++
 test_regress/t/t_vpi_var.cpp                       |   10 +-
 verilator.pdf                                      |  Bin 387862 -> 388154 bytes
 47 files changed, 982 insertions(+), 179 deletions(-)

diff --git a/Changes b/Changes
index 72649f4..1a52d47 100644
--- a/Changes
+++ b/Changes
@@ -3,6 +3,21 @@ 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.851 2013-08-15
+
+***   Fix ordering of clock enables with delayed assigns, bug613. [Jeremy Bennett]
+
+***   Fix vpi_iterate on memory words, bug655. [Rich Porter]
+
+****  Fix final duplicate declarations when non-inlined, bug661. [Charlie Brej]
+
+****  Fix interface ports with comma lists, msg1058. [Ed Lander]
+
+****  Fix parameter real conversion from integer.
+
+****  Fix clang warnings, bug668.  [Yutetsu Takatsukasa]
+
+
 * Verilator 3.850 2013-06-02
 
 **    Support interfaces and modports, bug102.  [Byron Bradley, Jeremy Bennett]
diff --git a/README.pdf b/README.pdf
index 625e547..ecffbd7 100644
Binary files a/README.pdf and b/README.pdf differ
diff --git a/configure b/configure
index 092d7b1..a88a629 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.850 2013-06-02.
+# Generated by GNU Autoconf 2.68 for Verilator 3.851 2013-08-15.
 #
 #
 # 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.850 2013-06-02'
-PACKAGE_STRING='Verilator 3.850 2013-06-02'
+PACKAGE_VERSION='3.851 2013-08-15'
+PACKAGE_STRING='Verilator 3.851 2013-08-15'
 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.850 2013-06-02 to adapt to many kinds of systems.
+\`configure' configures Verilator 3.851 2013-08-15 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.850 2013-06-02:";;
+     short | recursive ) echo "Configuration of Verilator 3.851 2013-08-15:";;
    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.850 2013-06-02
+Verilator configure 3.851 2013-08-15
 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.850 2013-06-02, which was
+It was created by Verilator $as_me 3.851 2013-08-15, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -4565,7 +4565,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.850 2013-06-02, which was
+This file was extended by Verilator $as_me 3.851 2013-08-15, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -4627,7 +4627,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.850 2013-06-02
+Verilator config.status 3.851 2013-08-15
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 3e9a8a2..12cc986 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.850 2013-06-02])
+AC_INIT([Verilator],[3.851 2013-08-15])
 AC_CONFIG_HEADER(src/config_build.h)
 AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h)
 
diff --git a/include/verilated.cpp b/include/verilated.cpp
index 123a5e9..5a6c909 100644
--- a/include/verilated.cpp
+++ b/include/verilated.cpp
@@ -769,6 +769,14 @@ void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) {
     _VL_STRING_TO_VINT(obits, destp, (int)output.length(), output.c_str());
 }
 
+void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...) {
+    output = "";
+    va_list ap;
+    va_start(ap,formatp);
+    _vl_vsformat(output, formatp, ap);
+    va_end(ap);
+}
+
 string VL_SFORMATF_NX(const char* formatp, ...) {
     VL_STATIC_OR_THREAD string output;  // static only for speed
     output = "";
@@ -1114,7 +1122,7 @@ vluint32_t VerilatedVar::entSize() const {
     case VLVT_UINT16:	size=sizeof(SData); break;
     case VLVT_UINT32:	size=sizeof(IData); break;
     case VLVT_UINT64:	size=sizeof(QData); break;
-    case VLVT_WDATA:	size=VL_WORDS_I(range().bits())*sizeof(IData); break;
+    case VLVT_WDATA:	size=VL_WORDS_I(range().elements())*sizeof(IData); break;
     default:		size=0; break;
     }
     return size;
@@ -1186,11 +1194,11 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap,
 	int msb = va_arg(ap,int);
 	int lsb = va_arg(ap,int);
 	if (i==0) {
-	    var.m_range.m_lhs = msb;
-	    var.m_range.m_rhs = lsb;
+	    var.m_range.m_left = msb;
+	    var.m_range.m_right = lsb;
 	} else if (i==1) {
-	    var.m_array.m_lhs = msb;
-	    var.m_array.m_rhs = lsb;
+	    var.m_array.m_left = msb;
+	    var.m_array.m_right = lsb;
 	} else {
 	    // We could have a linked list of ranges, but really this whole thing needs
 	    // to be generalized to support structs and unions, etc.
diff --git a/include/verilated.h b/include/verilated.h
index c39200d..541457c 100644
--- a/include/verilated.h
+++ b/include/verilated.h
@@ -145,7 +145,7 @@ public:
 # define VL_CELL(instname,type)		///< Declare a cell, ala SP_CELL
 
 /// Declare a module, ala SC_MODULE
-# define VL_MODULE(modname)		struct modname : public VerilatedModule
+# define VL_MODULE(modname)		class modname : public VerilatedModule
 
 /// Constructor, ala SC_CTOR
 # define VL_CTOR(modname)		modname(const char* __VCname="")
@@ -216,9 +216,8 @@ public:  // But internals only - called from VerilatedModule's
 //===========================================================================
 /// Verilator global static information class
 
-struct Verilated {
+class Verilated {
     // MEMBERS
-private:
     // Slow path variables
     static VerilatedVoidCb  s_flushCb;		///< Flush callback function
 
@@ -871,7 +870,7 @@ static inline WDataOutP VL_OR_W(int words, WDataOutP owp,WDataInP lwp,WDataInP r
 }
 // EMIT_RULE: VL_CHANGEXOR:  oclean=1; obits=32; lbits==rbits;
 static inline IData VL_CHANGEXOR_W(int words, WDataInP lwp,WDataInP rwp){
-    IData od;
+    IData od = 0;
     for (int i=0; (i < words); i++) od |= (lwp[i] ^ rwp[i]);
     return(od);
 }
diff --git a/include/verilated_config.h b/include/verilated_config.h
index 7489cf3..0f95cdd 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.850 2013-06-02"
+#define VERILATOR_VERSION    "3.851 2013-08-15"
diff --git a/include/verilated_heavy.h b/include/verilated_heavy.h
index b32586c..ec86151 100644
--- a/include/verilated_heavy.h
+++ b/include/verilated_heavy.h
@@ -41,11 +41,15 @@ inline string VL_CVT_PACK_STR_NQ(QData lhs) {
     IData lw[2];  VL_SET_WQ(lw, lhs);
     return VL_CVT_PACK_STR_NW(2, lw);
 }
+inline string VL_CVT_PACK_STR_NQ(string lhs) {
+    return lhs;
+}
 inline string VL_CVT_PACK_STR_NI(IData lhs) {
     IData lw[1];  lw[0] = lhs;
     return VL_CVT_PACK_STR_NW(1, lw);
 }
 
+extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...);
 extern string VL_SFORMATF_NX(const char* formatp, ...);
 
 #endif // Guard
diff --git a/include/verilated_syms.h b/include/verilated_syms.h
index 761b691..81957b4 100644
--- a/include/verilated_syms.h
+++ b/include/verilated_syms.h
@@ -45,19 +45,20 @@ struct VerilatedCStrCmp {
 //===========================================================================
 /// Verilator range
 
+// See also V3Ast::VNumRange
 class VerilatedRange { 
-    int		m_lhs;
-    int		m_rhs;
+    int		m_left;
+    int		m_right;
 protected:
     friend class VerilatedVar;
     friend class VerilatedScope;
-    VerilatedRange() : m_lhs(0), m_rhs(0) {}
-    void sets(int lhs, int rhs) { m_lhs=lhs; m_rhs=rhs; }
+    VerilatedRange() : m_left(0), m_right(0) {}
+    void sets(int left, int right) { m_left=left; m_right=right; }
 public:
     ~VerilatedRange() {}
-    int lhs() const { return m_lhs; }
-    int rhs() const { return m_rhs; }
-    int bits() const { return (VL_LIKELY(m_lhs>=m_rhs)?(m_lhs-m_rhs+1):(m_rhs-m_lhs+1)); }
+    int left() const { return m_left; }
+    int right() const { return m_right; }
+    int elements() const { return (VL_LIKELY(m_left>=m_right)?(m_left-m_right+1):(m_right-m_left+1)); }
 };
 
 //===========================================================================
@@ -92,7 +93,8 @@ public:
 //======================================================================
 /// Types
 
-struct VerilatedVarNameMap : public map<const char*, VerilatedVar, VerilatedCStrCmp> {
+class VerilatedVarNameMap : public map<const char*, VerilatedVar, VerilatedCStrCmp> {
+public:
     VerilatedVarNameMap() {}
     ~VerilatedVarNameMap() {}
 };
diff --git a/include/verilated_vpi.h b/include/verilated_vpi.h
index 1cfe562..1c1a123 100644
--- a/include/verilated_vpi.h
+++ b/include/verilated_vpi.h
@@ -94,6 +94,9 @@ public:
     virtual const char* name() { return "<null>"; }
     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 vpiHandle dovpi_scan() { return 0; }
 };
 
@@ -112,6 +115,7 @@ public:
     }
     virtual ~VerilatedVpioCb() {}
     static inline VerilatedVpioCb* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioCb*>((VerilatedVpio*)h); }
+    virtual const vluint32_t type() { return vpiCallback; }
     vluint32_t reason() const { return m_cbData.reason; }
     VerilatedPliCb cb_rtnp() const { return m_cbData.cb_rtn; }
     t_cb_data* cb_datap() { return &(m_cbData); }
@@ -124,19 +128,20 @@ public:
     VerilatedVpioConst(vlsint32_t num) : m_num(num) {}
     virtual ~VerilatedVpioConst() {}
     static inline VerilatedVpioConst* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioConst*>((VerilatedVpio*)h); }
+    virtual const vluint32_t type() { return vpiUndefined; }
     vlsint32_t num() const { return m_num; }
 };
 
 class VerilatedVpioRange : public VerilatedVpio {
-    vlsint32_t	m_lhs;	// Ranges can be signed
-    vlsint32_t	m_rhs;
+    const VerilatedRange* m_range;
     bool	m_iteration;
 public:
-    VerilatedVpioRange(vlsint32_t lhs, vlsint32_t rhs) : m_lhs(lhs), m_rhs(rhs), m_iteration(0) {}
+    VerilatedVpioRange(const VerilatedRange* range) : m_range(range), m_iteration(0) {}
     virtual ~VerilatedVpioRange() {}
     static inline VerilatedVpioRange* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioRange*>((VerilatedVpio*)h); }
-    vlsint32_t lhs() const { return m_lhs; }
-    vlsint32_t rhs() const { return m_rhs; }
+    virtual const vluint32_t type() { return vpiRange; }
+    virtual const vluint32_t size() const { return m_range->elements(); }
+    virtual const VerilatedRange* rangep() const { return m_range; }
     int iteration() const { return m_iteration; }
     void iterationInc() { ++m_iteration; }
     virtual vpiHandle dovpi_scan() {
@@ -157,6 +162,7 @@ public:
 	: m_scopep(scopep) {}
     virtual ~VerilatedVpioScope() {}
     static inline VerilatedVpioScope* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioScope*>((VerilatedVpio*)h); }
+    virtual const vluint32_t type() { return vpiScope; }
     const VerilatedScope* scopep() const { return m_scopep; }
     virtual const char* name() { return m_scopep->name(); }
     virtual const char* fullname() { return m_scopep->name(); }
@@ -178,7 +184,7 @@ public:
     VerilatedVpioVar(const VerilatedVar* varp, const VerilatedScope* scopep)
 	: m_varp(varp), m_scopep(scopep), m_index(0) {
 	m_prevDatap = NULL;
-	m_mask.u32 = VL_MASK_I(varp->range().bits());
+	m_mask.u32 = VL_MASK_I(varp->range().elements());
 	m_entSize = varp->entSize();
 	m_varDatap = varp->datap();
     }
@@ -191,6 +197,11 @@ public:
     vluint32_t mask() const { return m_mask.u32; }
     vluint8_t mask_byte(int idx) { return m_mask.u8[idx & 3]; }
     vluint32_t entSize() const { return m_entSize; }
+    const vluint32_t index() { return m_index; }
+    virtual const vluint32_t type() { return (varp()->dims()>1) ? vpiMemory : vpiReg; /* but might be wire, logic */ }
+    virtual const vluint32_t size() { return range().elements(); }
+    const VerilatedRange& range() { return m_varp->dims()?m_varp->array():m_varp->range(); }
+    virtual const VerilatedRange* rangep() { return &range(); }
     virtual const char* name() { return m_varp->name(); }
     virtual const char* fullname() {
 	VL_STATIC_OR_THREAD string out;
@@ -207,16 +218,19 @@ public:
     }
 };
 
-class VerilatedVpioVarIndex : public VerilatedVpioVar {
+class VerilatedVpioMemoryWord : public VerilatedVpioVar {
 public:
-    VerilatedVpioVarIndex(const VerilatedVar* varp, const VerilatedScope* scopep,
+    VerilatedVpioMemoryWord(const VerilatedVar* varp, const VerilatedScope* scopep,
 			  vlsint32_t index, int offset)
 	: VerilatedVpioVar(varp, scopep) {
 	m_index = index;
 	m_varDatap = ((vluint8_t*)varp->datap()) + entSize()*offset;
     }
-    virtual ~VerilatedVpioVarIndex() {}
-    static inline VerilatedVpioVarIndex* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVarIndex*>((VerilatedVpio*)h); }
+    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 char* fullname() {
 	VL_STATIC_OR_THREAD string out;
 	char num[20]; sprintf(num,"%d",m_index);
@@ -234,6 +248,7 @@ public:
 	: m_scopep(scopep), m_started(false) {  }
     virtual ~VerilatedVpioVarIter() {}
     static inline VerilatedVpioVarIter* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVarIter*>((VerilatedVpio*)h); }
+    virtual const vluint32_t type() { return vpiIterator; }
     virtual vpiHandle dovpi_scan() {
 	if (VL_LIKELY(m_scopep->varsp())) {
 	    if (VL_UNLIKELY(!m_started)) { m_it = m_scopep->varsp()->begin(); m_started=true; }
@@ -248,6 +263,28 @@ public:
     }
 };
 
+class VerilatedVpioMemoryWordIter : public VerilatedVpio {
+    const vpiHandle		m_handle;
+    const VerilatedVar*		m_varp;
+    vlsint32_t                  m_iteration;
+    vlsint32_t                  m_direction;
+    bool                        m_done;
+public:
+    VerilatedVpioMemoryWordIter(const vpiHandle handle, const VerilatedVar* varp)
+	: m_handle(handle), m_varp(varp), m_iteration(varp->array().right()), m_direction(VL_LIKELY(varp->array().left()>varp->array().right())?1:-1), m_done(false) {  }
+    virtual ~VerilatedVpioMemoryWordIter() {}
+    static inline VerilatedVpioMemoryWordIter* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioMemoryWordIter*>((VerilatedVpio*)h); }
+    virtual const vluint32_t type() { return vpiIterator; }
+    void iterationInc() { if (!(m_done = m_iteration == m_varp->array().left())) m_iteration+=m_direction; }
+    virtual vpiHandle dovpi_scan() {
+	vpiHandle result;
+	if (m_done) return 0;
+	result = vpi_handle_by_index(m_handle, m_iteration);
+	iterationInc();
+	return result;
+    }
+};
+
 //======================================================================
 
 struct VerilatedVpiTimedCbsCmp {
@@ -260,13 +297,18 @@ struct VerilatedVpiTimedCbsCmp {
     }
 };
 
-struct VerilatedVpiError;
+class VerilatedVpiError;
 
 class VerilatedVpi {
     enum { CB_ENUM_MAX_VALUE = cbAtEndOfSimTime+1 };	// Maxium callback reason
     typedef set<VerilatedVpioCb*> VpioCbSet;
     typedef set<pair<QData,VerilatedVpioCb*>,VerilatedVpiTimedCbsCmp > VpioTimedCbs;
 
+    struct product_info {
+	PLI_BYTE8* product;
+	PLI_BYTE8* version;
+    };
+
     VpioCbSet		m_cbObjSets[CB_ENUM_MAX_VALUE];	// Callbacks for each supported reason
     VpioTimedCbs	m_timedCbs;	// Time based callbacks
     VerilatedVpiError*  m_errorInfop;	// Container for vpi error info
@@ -545,15 +587,15 @@ vpiHandle vpi_handle_by_index(vpiHandle object, PLI_INT32 indx) {
     _VL_VPI_ERROR_RESET(); // reset vpi error status
     if (VL_LIKELY(varop)) {
 	if (varop->varp()->dims()<2) return 0;
-	if (VL_LIKELY(varop->varp()->array().lhs() >= varop->varp()->array().rhs())) {
-	    if (VL_UNLIKELY(indx > varop->varp()->array().lhs() || indx < varop->varp()->array().rhs())) return 0;
-	    return (new VerilatedVpioVarIndex(varop->varp(), varop->scopep(), indx,
-					      indx - varop->varp()->array().rhs()))
+	if (VL_LIKELY(varop->varp()->array().left() >= varop->varp()->array().right())) {
+	    if (VL_UNLIKELY(indx > varop->varp()->array().left() || indx < varop->varp()->array().right())) return 0;
+	    return (new VerilatedVpioMemoryWord(varop->varp(), varop->scopep(), indx,
+					      indx - varop->varp()->array().right()))
 		->castVpiHandle();
 	} else {
-	    if (VL_UNLIKELY(indx < varop->varp()->array().lhs() || indx > varop->varp()->array().rhs())) return 0;
-	    return (new VerilatedVpioVarIndex(varop->varp(), varop->scopep(), indx,
-					      indx - varop->varp()->array().lhs()))
+	    if (VL_UNLIKELY(indx < varop->varp()->array().left() || indx > varop->varp()->array().right())) return 0;
+	    return (new VerilatedVpioMemoryWord(varop->varp(), varop->scopep(), indx,
+					      indx - varop->varp()->array().left()))
 		->castVpiHandle();
 	}
     } else {
@@ -568,21 +610,32 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) {
     VL_DEBUG_IF_PLI(VL_PRINTF("-vltVpi:  vpi_handle %d %p\n",type,object););
     _VL_VPI_ERROR_RESET(); // reset vpi error status
     switch (type) {
-    case vpiLeftRange:  // FALLTHRU
+    case vpiLeftRange: {
+	VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
+	if (VL_UNLIKELY(!vop)) return 0;
+	if (VL_UNLIKELY(!vop->rangep())) return 0;
+        return (new VerilatedVpioConst(vop->rangep()->left()))->castVpiHandle();
+    }
     case vpiRightRange: {
-	if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) {
-	    vluint32_t num = ((type==vpiLeftRange)
-			      ? vop->varp()->range().lhs()
-			      : vop->varp()->range().rhs());
-	    return (new VerilatedVpioConst(num))->castVpiHandle();
-	} else if (VerilatedVpioRange* vop = VerilatedVpioRange::castp(object)) {
-	    vluint32_t num = ((type==vpiLeftRange)
-			      ? vop->lhs()
-			      : vop->rhs());
-	    return (new VerilatedVpioConst(num))->castVpiHandle();
-	} else {
-	    return 0;
-	}
+	VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
+	if (VL_UNLIKELY(!vop)) return 0;
+	if (VL_UNLIKELY(!vop->rangep())) return 0;
+        return (new VerilatedVpioConst(vop->rangep()->right()))->castVpiHandle();
+    }
+    case vpiIndex: {
+	VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
+	if (VL_UNLIKELY(!vop)) return 0;
+        return (new VerilatedVpioConst(vop->index()))->castVpiHandle();
+    }
+    case vpiScope: {
+	VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
+	if (VL_UNLIKELY(!vop)) return 0;
+	return (new VerilatedVpioScope(vop->scopep()))->castVpiHandle();
+    }
+    case vpiParent: {
+	VerilatedVpioMemoryWord* vop = VerilatedVpioMemoryWord::castp(object);
+	if (VL_UNLIKELY(!vop)) return 0;
+	return (new VerilatedVpioVar(vop->varp(), vop->scopep()))->castVpiHandle();
     }
     default:
         _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported type %s, nothing will be returned",
@@ -603,10 +656,22 @@ vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle object) {
 	VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
 	if (VL_UNLIKELY(!vop)) return 0;
 	if (vop->varp()->dims() < 2) return 0;
+	if (vop->varp()->dims() > 2) {
+	    _VL_VPI_WARNING(__FILE__, __LINE__, "%s: %s, object %s has unsupported number of indices (%d)",
+			    VL_FUNC, VerilatedVpiError::strFromVpiMethod(type), vop->fullname() , vop->varp()->dims());
+	}
+	return (new VerilatedVpioMemoryWordIter(object, vop->varp()))->castVpiHandle();
+    }
+    case vpiRange: {
+	VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
+	if (VL_UNLIKELY(!vop)) return 0;
+	if (vop->varp()->dims() < 2) return 0;
 	// Unsupported is multidim list
-	return ((new VerilatedVpioRange(vop->varp()->array().lhs(),
-					vop->varp()->array().rhs()))
-		->castVpiHandle());
+        if (vop->varp()->dims() > 2) {
+	    _VL_VPI_WARNING(__FILE__, __LINE__, "%s: %s, object %s has unsupported number of indices (%d)",
+			    VL_FUNC, VerilatedVpiError::strFromVpiMethod(type), vop->fullname() , vop->varp()->dims());
+	}
+	return ((new VerilatedVpioRange(vop->rangep()))->castVpiHandle());
     }
     case vpiReg: {
 	VerilatedVpioScope* vop = VerilatedVpioScope::castp(object);
@@ -639,9 +704,9 @@ PLI_INT32 vpi_get(PLI_INT32 property, vpiHandle object) {
 	return VL_TIME_PRECISION;
     }
     case vpiType: {
-	VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
+	VerilatedVpio* vop = VerilatedVpioVar::castp(object);
 	if (VL_UNLIKELY(!vop)) return 0;
-	return ((vop->varp()->dims()>1) ? vpiMemory : vpiReg);
+	return vop->type();
     }
     case vpiDirection: {
 	// By forthought, the directions already are vpi enumerated
@@ -649,11 +714,16 @@ PLI_INT32 vpi_get(PLI_INT32 property, vpiHandle object) {
 	if (VL_UNLIKELY(!vop)) return 0;
 	return vop->varp()->vldir();
     }
+    case vpiScalar:  // FALLTHRU
     case vpiVector: {
 	VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
 	if (VL_UNLIKELY(!vop)) return 0;
-	if (vop->varp()->dims()==0) return 0;
-	else return 1;
+        return (property==vpiVector)^(vop->varp()->dims()==0);
+    }
+    case vpiSize: {
+	VerilatedVpioVar* vop = VerilatedVpioVar::castp(object);
+	if (VL_UNLIKELY(!vop)) return 0;
+	return vop->size();
     }
     default:
         _VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported type %s, nothing will be returned",
@@ -730,7 +800,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
 		out[0].bval = 0;
 		return;
 	    case VLVT_WDATA: {
-		int words = VL_WORDS_I(vop->varp()->range().bits());
+		int words = VL_WORDS_I(vop->varp()->range().elements());
 		if (VL_UNLIKELY(words >= VL_MULS_MAX_WORDS)) {
 		    vl_fatal(__FILE__,__LINE__,"", "vpi_get_value with more than VL_MULS_MAX_WORDS; increase and recompile");
 		}
@@ -763,7 +833,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
 	    case VLVT_UINT32:
 	    case VLVT_UINT64:
 	    case VLVT_WDATA: {
-		int bits = vop->varp()->range().bits();
+		int bits = vop->varp()->range().elements();
 		CData* datap = ((CData*)(vop->varDatap()));
 		int i;
 		if (bits > outStrSz) {
@@ -792,8 +862,8 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
 	    case VLVT_UINT32:
 	    case VLVT_UINT64:
 	    case VLVT_WDATA: {
-		int chars = (vop->varp()->range().bits()+2)/3;
-		int bytes = VL_BYTES_I(vop->varp()->range().bits());
+		int chars = (vop->varp()->range().elements()+2)/3;
+		int bytes = VL_BYTES_I(vop->varp()->range().elements());
 		CData* datap = ((CData*)(vop->varDatap()));
 		int i;
 		if (chars > outStrSz) {
@@ -815,7 +885,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
                     if (i==(chars-1)) {
 			// most signifcant char, mask off non existant bits when vector
                         // size is not a multiple of 3
-			unsigned int rem = vop->varp()->range().bits() % 3;
+			unsigned int rem = vop->varp()->range().elements() % 3;
                         if (rem) {
 			    // generate bit mask & zero non existant bits
                             val &= (1<<rem)-1;
@@ -854,7 +924,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
 	    case VLVT_UINT32:
 	    case VLVT_UINT64:
 	    case VLVT_WDATA: {
-		int chars = (vop->varp()->range().bits()+3)>>2;
+		int chars = (vop->varp()->range().elements()+3)>>2;
 		CData* datap = ((CData*)(vop->varDatap()));
 		int i;
 		if (chars > outStrSz) {
@@ -869,7 +939,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
                     if (i==(chars-1)) {
 			// most signifcant char, mask off non existant bits when vector
                         // size is not a multiple of 4
-			unsigned int rem = vop->varp()->range().bits() & 3;
+			unsigned int rem = vop->varp()->range().elements() & 3;
                         if (rem) {
 			    // generate bit mask & zero non existant bits
                             val &= (1<<rem)-1;
@@ -893,7 +963,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
 	    case VLVT_UINT32:
 	    case VLVT_UINT64:
 	    case VLVT_WDATA: {
-		int bytes = VL_BYTES_I(vop->varp()->range().bits());
+		int bytes = VL_BYTES_I(vop->varp()->range().elements());
 		CData* datap = ((CData*)(vop->varDatap()));
 		int i;
 		if (bytes > outStrSz) {
@@ -984,7 +1054,7 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
 		*((IData*)(vop->varDatap())) = value_p->value.vector[0].aval & vop->mask();
 		return object;
 	    case VLVT_WDATA: {
-		int words = VL_WORDS_I(vop->varp()->range().bits());
+		int words = VL_WORDS_I(vop->varp()->range().elements());
 		WDataOutP datap = ((IData*)(vop->varDatap()));
 		for (int i=0; i<words; i++) {
 		    datap[i] = value_p->value.vector[i].aval;
@@ -1013,7 +1083,7 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
 	    case VLVT_UINT32:
 	    case VLVT_UINT64:
 	    case VLVT_WDATA: {
-		int bits = vop->varp()->range().bits();
+		int bits = vop->varp()->range().elements();
 		int len	 = strlen(value_p->value.str);
 		CData* datap = ((CData*)(vop->varDatap()));
 		for (int i=0; i<bits; i++) {
@@ -1040,8 +1110,8 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
 	    case VLVT_UINT32:
 	    case VLVT_UINT64:
 	    case VLVT_WDATA: {
-		int chars = (vop->varp()->range().bits()+2)/3;
-		int bytes = VL_BYTES_I(vop->varp()->range().bits());
+		int chars = (vop->varp()->range().elements()+2)/3;
+		int bytes = VL_BYTES_I(vop->varp()->range().elements());
 		int len	 = strlen(value_p->value.str);
 		CData* datap = ((CData*)(vop->varDatap()));
                 div_t idx;
@@ -1126,7 +1196,7 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
 	    case VLVT_UINT32:
 	    case VLVT_UINT64:
 	    case VLVT_WDATA: {
-		int chars = (vop->varp()->range().bits()+3)>>2;
+		int chars = (vop->varp()->range().elements()+3)>>2;
 		CData* datap = ((CData*)(vop->varDatap()));
                 char* val = value_p->value.str;
                 // skip hex ident if one is detected at the start of the string
@@ -1173,7 +1243,7 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p,
 	    case VLVT_UINT32:
 	    case VLVT_UINT64:
 	    case VLVT_WDATA: {
-		int bytes = VL_BYTES_I(vop->varp()->range().bits());
+		int bytes = VL_BYTES_I(vop->varp()->range().elements());
 		int len	  = strlen(value_p->value.str);
 		CData* datap = ((CData*)(vop->varDatap()));
 		for (int i=0; i<bytes; i++) {
diff --git a/internals.pdf b/internals.pdf
index 00cda40..1a92c66 100644
Binary files a/internals.pdf and b/internals.pdf differ
diff --git a/src/V3Active.cpp b/src/V3Active.cpp
index dd5150d..f221cf4 100644
--- a/src/V3Active.cpp
+++ b/src/V3Active.cpp
@@ -291,7 +291,7 @@ private:
 	}
 	ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
 	if (!m_scopeFinalp) {
-	    m_scopeFinalp = new AstCFunc(nodep->fileline(), "_final", m_namer.scopep());
+	    m_scopeFinalp = new AstCFunc(nodep->fileline(), "_final_"+m_namer.scopep()->nameDotless(), m_namer.scopep());
 	    m_scopeFinalp->argTypes(EmitCBaseVisitor::symClassVar());
 	    m_scopeFinalp->addInitsp(new AstCStmt(nodep->fileline(), EmitCBaseVisitor::symTopAssign()+"\n"));
 	    m_scopeFinalp->dontCombine(true);
diff --git a/src/V3Clock.cpp b/src/V3Clock.cpp
index a4dd10b..f0f3925 100644
--- a/src/V3Clock.cpp
+++ b/src/V3Clock.cpp
@@ -346,14 +346,10 @@ private:
 	nodep->iterateChildren(*this);
 	// Link to global function
 	if (nodep->formCallTree()) {
-	    if (nodep->name() == "_final") {
-		UINFO(4, "    formCallTree "<<nodep<<endl);
-		AstCCall* callp = new AstCCall(nodep->fileline(), nodep);
-		callp->argTypes("vlSymsp");
-		m_finalFuncp->addStmtsp(callp);
-	    } else {
-		nodep->v3fatalSrc("Unknown CFunc name.  Make code more generic, with a map of func names");
-	    }
+	    UINFO(4, "    formCallTree "<<nodep<<endl);
+	    AstCCall* callp = new AstCCall(nodep->fileline(), nodep);
+	    callp->argTypes("vlSymsp");
+	    m_finalFuncp->addStmtsp(callp);
 	}
     }
     virtual void visit(AstSenTree* nodep, AstNUser*) {
diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp
index b6a94f4..e05dcbf 100644
--- a/src/V3Gate.cpp
+++ b/src/V3Gate.cpp
@@ -215,7 +215,7 @@ private:
     virtual void visit(AstNodeAssign* nodep, AstNUser*) {
 	m_substTreep = nodep->rhsp();
 	if (!nodep->lhsp()->castNodeVarRef())
-	    clearSimple("ASSIGN(non VARREF)");
+	    clearSimple("ASSIGN(non-VARREF)");
 	else nodep->iterateChildren(*this);
 	// We don't push logic other then assignments/NOTs into SenItems
 	// This avoids a mess in computing what exactly a POSEDGE is
diff --git a/src/V3LinkLevel.cpp b/src/V3LinkLevel.cpp
index 9829184..5f3e739 100644
--- a/src/V3LinkLevel.cpp
+++ b/src/V3LinkLevel.cpp
@@ -68,6 +68,7 @@ void V3LinkLevel::modSortByLevel() {
 	vec.push_back(nodep);
     }
     stable_sort(vec.begin(), vec.end(), CmpLevel()); // Sort the vector
+    UINFO(9,"modSortByLevel() sorted\n");  // Comment required for gcc4.6.3 / bug666
     for (ModVec::iterator it = vec.begin(); it != vec.end(); ++it) {
 	AstNodeModule* nodep = *it;
 	nodep->unlinkFrBack();
@@ -77,6 +78,7 @@ void V3LinkLevel::modSortByLevel() {
 	AstNodeModule* nodep = *it;
 	v3Global.rootp()->addModulep(nodep);
     }
+    UINFO(9,"modSortByLevel() done\n");  // Comment required for gcc4.6.3 / bug666
 }
 
 //######################################################################
diff --git a/src/V3Number.cpp b/src/V3Number.cpp
index 3026666..5a089a6 100644
--- a/src/V3Number.cpp
+++ b/src/V3Number.cpp
@@ -515,7 +515,7 @@ uint32_t V3Number::toUInt() const {
 
 double V3Number::toDouble() const {
     if (VL_UNLIKELY(!isDouble())) {
-	m_fileline->v3fatalSrc("Real conversion on non real number");
+	m_fileline->v3fatalSrc("Real conversion on non-real number");
     }
     if (VL_UNLIKELY(width()!=64)) {
 	m_fileline->v3fatalSrc("Real operation on wrong sized number");
diff --git a/src/V3Options.cpp b/src/V3Options.cpp
index e901b78..caecbb4 100644
--- a/src/V3Options.cpp
+++ b/src/V3Options.cpp
@@ -46,7 +46,8 @@
 //######################################################################
 // V3 Internal state
 
-struct V3OptionsImp {
+class V3OptionsImp {
+public:
     // TYPES
     typedef std::map<string,set<string> > DirMap;	// Directory listing
 
@@ -91,6 +92,7 @@ struct V3OptionsImp {
 	}
     }
     V3OptionsImp() {}
+    ~V3OptionsImp() {}
 };
 
 void V3Options::addIncDirUser(const string& incdir) {
diff --git a/src/V3Order.cpp b/src/V3Order.cpp
index 38da6da..313dcb6 100644
--- a/src/V3Order.cpp
+++ b/src/V3Order.cpp
@@ -697,6 +697,13 @@ private:
 			    OrderVarVertex* varVxp = newVarUserVertex(varscp, WV_STD);
 			    if (m_inPost) {
 				new OrderPostCutEdge(&m_graph, m_logicVxp, varVxp);
+				// Mark the vertex. Used to control marking
+				// internal clocks circular, which must only
+				// happen if they are generated by delayed
+				// assignment.
+				UINFO(5, "     Found delayed assignment (post) "
+				      << varVxp << endl);
+				varVxp->isDelayed(true);
 			    } else {
 				new OrderComboCutEdge(&m_graph, m_logicVxp, varVxp);
 			    }
@@ -1146,10 +1153,21 @@ void OrderVisitor::processCircular() {
     for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) {
 	if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(itp)) {
 	    if (vvertexp->isClock() && !vvertexp->isFromInput()) {
-		// If a clock is generated internally, we need to do another loop
-		// through the entire evaluation.  This fixes races; see t_clk_dpulse test.
-		UINFO(5,"Circular Clock "<<vvertexp<<endl);
-		nodeMarkCircular(vvertexp, NULL);
+		// If a clock is generated internally, we need to do another
+		// loop through the entire evaluation.  This fixes races; see
+		// t_clk_dpulse test.
+		//
+		// This all seems to hinge on how the clock is generated. If
+		// it is generated by delayed assignment, we need the loop. If
+		// it is combinatorial, we do not (and indeed it will break
+		// other tests such as t_gated_clk_1.
+		if (vvertexp->isDelayed()) {
+		    UINFO(5,"Circular Clock, delayed "<<vvertexp<<endl);
+		    nodeMarkCircular(vvertexp, NULL);
+		}
+		else {
+		    UINFO(5,"Circular Clock, not delayed "<<vvertexp<<endl);
+		}
 	    }
 	    // Also mark any cut edges
 	    for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
diff --git a/src/V3OrderGraph.h b/src/V3OrderGraph.h
index 4fcf6dc..bbd876e 100644
--- a/src/V3OrderGraph.h
+++ b/src/V3OrderGraph.h
@@ -224,6 +224,7 @@ class OrderVarVertex : public OrderEitherVertex {
     AstVarScope* m_varScp;
     OrderVarVertex*	m_pilNewVertexp;	// for processInsLoopNewVar
     bool	 m_isClock;	// Used as clock
+    bool	 m_isDelayed;	// Set in a delayed assignment
 protected:
     OrderVarVertex(V3Graph* graphp, const OrderVarVertex& old)
 	: OrderEitherVertex(graphp, old)
@@ -231,7 +232,7 @@ protected:
 public:
     OrderVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
 	: OrderEitherVertex(graphp, scopep, NULL), m_varScp(varScp)
-	, m_pilNewVertexp(NULL), m_isClock(false) {}
+	, m_pilNewVertexp(NULL), m_isClock(false), m_isDelayed(false) {}
     virtual ~OrderVarVertex() {}
     virtual OrderVarVertex* clone (V3Graph* graphp) const = 0;
     virtual OrderVEdgeType type() const = 0;
@@ -239,6 +240,8 @@ public:
     AstVarScope* varScp() const { return m_varScp; }
     void isClock(bool flag) { m_isClock=flag; }
     bool isClock() const { return m_isClock; }
+    void isDelayed(bool flag) { m_isDelayed=flag; }
+    bool isDelayed() const { return m_isDelayed; }
     OrderVarVertex* pilNewVertexp() const { return m_pilNewVertexp; }
     void pilNewVertexp (OrderVarVertex* vertexp) { m_pilNewVertexp = vertexp; }
 };
diff --git a/src/V3PreProc.cpp b/src/V3PreProc.cpp
index 01638ef..35b0b24 100644
--- a/src/V3PreProc.cpp
+++ b/src/V3PreProc.cpp
@@ -107,7 +107,8 @@ public:
 //*************************************************************************
 // Data for a preprocessor instantiation.
 
-struct V3PreProcImp : public V3PreProc {
+class V3PreProcImp : public V3PreProc {
+public:
     // TYPES
     typedef std::map<string,V3Define> DefinesMap;
     typedef V3InFilter::StrList StrList;
diff --git a/src/V3Simulate.h b/src/V3Simulate.h
index 4388820..f465323 100644
--- a/src/V3Simulate.h
+++ b/src/V3Simulate.h
@@ -431,11 +431,11 @@ private:
 	if (jumpingOver(nodep)) return;
 	if (!optimizable()) return;  // Accelerate
 	if (nodep->castAssignDly()) {
-	    if (m_anyAssignComb) clearOptimizable(nodep, "Mix of dly/non dly assigns");
+	    if (m_anyAssignComb) clearOptimizable(nodep, "Mix of dly/non-dly assigns");
 	    m_anyAssignDly = true;
 	    m_inDlyAssign = true;
 	} else {
-	    if (m_anyAssignDly) clearOptimizable(nodep, "Mix of dly/non dly assigns");
+	    if (m_anyAssignDly) clearOptimizable(nodep, "Mix of dly/non-dly assigns");
 	    m_anyAssignComb = true;
 	}
 	if (!nodep->lhsp()->castVarRef()) {
diff --git a/src/V3Width.cpp b/src/V3Width.cpp
index ca64a07..813c293 100644
--- a/src/V3Width.cpp
+++ b/src/V3Width.cpp
@@ -915,6 +915,9 @@ private:
 	    if (!nodep->valuep()->castInitArray()) { // No dtype at present, perhaps TODO
 		widthCheck(nodep,"Initial value",nodep->valuep(),nodep->width(),nodep->widthMin());
 	    }
+	    if (nodep->isDouble() && !nodep->valuep()->isDouble()) {
+		spliceCvtD(nodep->valuep());
+	    }
 	}
 	UINFO(4,"varWidthed "<<nodep<<endl);
 	//if (debug()) nodep->dumpTree(cout,"  InitOut: ");
diff --git a/src/config_build.h b/src/config_build.h
index fb22c26..8e8c91a 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.850 2013-06-02"
+#define PACKAGE_STRING "Verilator 3.851 2013-08-15"
 
 #define DTVERSION	PACKAGE_STRING
 
diff --git a/src/config_rev.h b/src/config_rev.h
index d4c04c3..eb37c7b 100644
--- a/src/config_rev.h
+++ b/src/config_rev.h
@@ -1 +1 @@
-static const char* DTVERSION_rev = "verilator_3_848-1-g7a65df7";
+static const char* DTVERSION_rev = "verilator_3_850-15-gc996d28";
diff --git a/src/verilog.y b/src/verilog.y
index ad0ab28..d99177f 100644
--- a/src/verilog.y
+++ b/src/verilog.y
@@ -847,24 +847,18 @@ port<nodep>:			// ==IEEE: port
 	//			// IEEE: interface_port_header port_identifier { unpacked_dimension }
 	//			// Expanded interface_port_header
 	//			// We use instantCb here because the non-port form looks just like a module instantiation
-		portDirNetE id/*interface*/                      idAny/*port*/ variable_dimensionListE sigAttrListE
-			{ $$ = new AstPort($<fl>2,PINNUMINC(),*$3);
-			  AstVar* varp=new AstVar($<fl>2,AstVarType(AstVarType::IFACEREF),*$3,VFlagChildDType(),
-						  new AstIfaceRefDType($<fl>2,"",*$2));
-			  if ($4) varp->v3error("Unsupported: Arrayed interfaces");
-			  varp->addAttrsp($5);
-			  $$->addNext(varp); }
-	|	portDirNetE yINTERFACE                           idAny/*port*/ rangeListE sigAttrListE
-			{ $<fl>2->v3error("Unsupported: virtual interfaces"); }
-	|	portDirNetE id/*interface*/ '.' idAny/*modport*/ idAny/*port*/ rangeListE sigAttrListE
-			{ $$ = new AstPort($3,PINNUMINC(),*$5);
-			  AstVar* varp=new AstVar($<fl>2,AstVarType(AstVarType::IFACEREF),*$5,VFlagChildDType(),
-						  new AstIfaceRefDType($<fl>2,"",*$2,*$4));
-			  if ($6) varp->v3error("Unsupported: Arrayed interfaces");
-			  varp->addAttrsp($7);
-			  $$->addNext(varp); }
-	|	portDirNetE yINTERFACE      '.' idAny/*modport*/ idAny/*port*/ rangeListE sigAttrListE
-			{ $<fl>2->v3error("Unsupported: virtual interfaces"); }
+		portDirNetE id/*interface*/                      portSig variable_dimensionListE sigAttrListE
+			{ $$ = $3; VARDECL(AstVarType::IFACEREF); VARIO(UNKNOWN);
+			  VARDTYPE(new AstIfaceRefDType($<fl>2,"",*$2));
+			  $$->addNextNull(VARDONEP($$,$4,$5)); }
+	|	portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig rangeListE sigAttrListE
+			{ $$ = $5; VARDECL(AstVarType::IFACEREF); VARIO(UNKNOWN);
+			  VARDTYPE(new AstIfaceRefDType($<fl>2,"",*$2,*$4));
+			  $$->addNextNull(VARDONEP($$,$6,$7)); }
+	|	portDirNetE yINTERFACE                           portSig rangeListE sigAttrListE
+			{ $<fl>2->v3error("Unsupported: virtual interfaces"); $$=NULL; }
+	|	portDirNetE yINTERFACE      '.' idAny/*modport*/ portSig rangeListE sigAttrListE
+			{ $<fl>2->v3error("Unsupported: virtual interfaces"); $$=NULL; }
 	//
 	//			// IEEE: ansi_port_declaration, with [port_direction] removed
 	//			//   IEEE: [ net_port_header | interface_port_header ] port_identifier { unpacked_dimension } [ '=' constant_expression ]
@@ -902,7 +896,7 @@ port<nodep>:			// ==IEEE: port
 	//UNSUP	portDirNetE /*implicit*/       '.' portSig '(' portAssignExprE ')' sigAttrListE
 	//UNSUP		{ UNSUP }
 	//
-	|	portDirNetE data_type          portSig variable_dimensionListE sigAttrListE
+	|	portDirNetE data_type           portSig variable_dimensionListE sigAttrListE
 			{ $$=$3; VARDTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); }
 	|	portDirNetE yVAR data_type      portSig variable_dimensionListE sigAttrListE
 			{ $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
@@ -3636,6 +3630,9 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange
 	return NULL;
     }
     AstVarType type = GRAMMARP->m_varIO;
+    if (dtypep->castIfaceRefDType()) {
+	if (arrayp) { fileline->v3error("Unsupported: Arrayed interfaces"); arrayp=NULL; }
+    }
     if (!dtypep) {  // Created implicitly
 	dtypep = new AstBasicDType(fileline, LOGIC_IMPLICIT);
     } else {  // May make new variables with same type, so clone
diff --git a/test_regress/driver.pl b/test_regress/driver.pl
index 3b9d364..ec2ad1b 100755
--- a/test_regress/driver.pl
+++ b/test_regress/driver.pl
@@ -317,6 +317,7 @@ sub new {
 	pl_filename => undef,	# Name of .pl file to get setup from
 	make_top_shell => 1,	# Make a default __top.v file
 	make_main => 1,		# Make __main.cpp
+	make_pli => 0,		# need to compile pli
 	sim_time => 1100,
 	benchmark => $opt_benchmark,
 	run_env => '',
@@ -331,7 +332,8 @@ sub new {
 	v_flags2 => [],  # Overridden in some sim files
 	v_other_filenames => [],	# After the filename so we can spec multiple files
 	all_run_flags => [],
-        # ATSIM
+	pli_flags => ["-I$ENV{VERILATOR_ROOT}/include/vltstd -fPIC -export-dynamic -shared -o $self->{obj_dir}/libvpi.so"],
+	# ATSIM
 	atsim => 0,
 	atsim_flags => [split(/\s+/,"-c +sv +define+ATSIM"),
 			"+sv_dir+$self->{obj_dir}/.athdl_compile"],
@@ -348,6 +350,7 @@ sub new {
 	iv => 0,
 	iv_flags => [split(/\s+/,"+define+iverilog -o $self->{obj_dir}/simiv")],
 	iv_flags2 => [],  # Overridden in some sim files
+	iv_pli => 0, # need to use pli
 	iv_run_flags => [],
 	# VCS
 	vcs => 0,
@@ -658,6 +661,16 @@ sub compile {
     else {
 	$self->error("No compile step for this simulator");
     }
+
+    if ($param{make_pli}) {
+	$self->oprint("Compile vpi\n");
+	my @cmd = ('g++', @{$param{pli_flags}}, "-DIS_VPI", "$self->{t_dir}/$self->{name}.cpp");
+
+	$self->_run(logfile=>"$self->{obj_dir}/pli_compile.log",
+		    fails=>$param{fails},
+		    cmd=>\@cmd);
+    }
+
     return 1;
 }
 
@@ -694,12 +707,16 @@ sub execute {
 		    );
     }
     elsif ($param{iv}) {
+	my @cmd = ($run_env."$self->{obj_dir}/simiv",
+		   @{$param{iv_run_flags}},
+		   @{$param{all_run_flags}},
+		          );
+	if ($param{iv_pli}) {
+	    unshift @cmd, "vvp -m $self->{obj_dir}/libvpi.so";
+	}
 	$self->_run(logfile=>"$self->{obj_dir}/iv_sim.log",
 		    fails=>$param{fails},
-		    cmd=>[$run_env."$self->{obj_dir}/simiv",
-			  @{$param{iv_run_flags}},
-			  @{$param{all_run_flags}},
-		          ],
+		    cmd=> \@cmd,
 		    %param,
 		    expect=>$param{iv_run_expect},	# non-verilator expect isn't the same
 		    );
diff --git a/test_regress/t/t_clk_condflop.pl b/test_regress/t/t_clk_condflop.pl
index f6d3de4..302562a 100755
--- a/test_regress/t/t_clk_condflop.pl
+++ b/test_regress/t/t_clk_condflop.pl
@@ -7,14 +7,11 @@ 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.
 
-my $fail = ($Self->{v3} && verilator_version() !~ /\(ord\)/);
-
 compile (
 	 );
 
 execute (
-	 check_finished => !$fail,
-	 fails => $fail,
+	 check_finished => 1
 	 );
 
 ok(1);
diff --git a/test_regress/t/t_clk_powerdn.pl b/test_regress/t/t_clk_powerdn.pl
index f6d3de4..302562a 100755
--- a/test_regress/t/t_clk_powerdn.pl
+++ b/test_regress/t/t_clk_powerdn.pl
@@ -7,14 +7,11 @@ 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.
 
-my $fail = ($Self->{v3} && verilator_version() !~ /\(ord\)/);
-
 compile (
 	 );
 
 execute (
-	 check_finished => !$fail,
-	 fails => $fail,
+	 check_finished => 1
 	 );
 
 ok(1);
diff --git a/test_regress/t/t_clk_condflop.pl b/test_regress/t/t_dpi_string.pl
similarity index 65%
copy from test_regress/t/t_clk_condflop.pl
copy to test_regress/t/t_dpi_string.pl
index f6d3de4..ae6cbdd 100755
--- a/test_regress/t/t_clk_condflop.pl
+++ b/test_regress/t/t_dpi_string.pl
@@ -2,20 +2,18 @@
 if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
 # DESCRIPTION: Verilator: Verilog Test driver/expect definition
 #
-# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
+# 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.
 
-my $fail = ($Self->{v3} && verilator_version() !~ /\(ord\)/);
-
 compile (
+    	 v_flags2 => ["t/t_dpi_string_c.cpp"],
 	 );
 
 execute (
-	 check_finished => !$fail,
-	 fails => $fail,
-	 );
+	 check_finished=>1,
+     );
 
 ok(1);
 1;
diff --git a/test_regress/t/t_dpi_string.v b/test_regress/t/t_dpi_string.v
new file mode 100644
index 0000000..26b7312
--- /dev/null
+++ b/test_regress/t/t_dpi_string.v
@@ -0,0 +1,26 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// Copyright 2009 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.
+
+module t ();
+
+   import "DPI-C" function int dpii_string(input string DSM_NAME);
+
+   generate
+      begin : DSM
+	 string SOME_STRING;
+      end
+   endgenerate
+
+   initial begin
+      $sformat(DSM.SOME_STRING, "%m");
+      if (dpii_string(DSM.SOME_STRING) != 5) $stop;
+
+      $write("*-* All Finished *-*\n");
+      $finish;
+   end
+
+endmodule
diff --git a/test_regress/t/t_dpi_string_c.cpp b/test_regress/t/t_dpi_string_c.cpp
new file mode 100644
index 0000000..cba6071
--- /dev/null
+++ b/test_regress/t/t_dpi_string_c.cpp
@@ -0,0 +1,44 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//*************************************************************************
+//
+// Copyright 2009-2009 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.
+//
+// Verilator is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+//*************************************************************************
+
+#include <cstdio>
+#include "svdpi.h"
+
+//======================================================================
+
+#if defined(VERILATOR)
+# include "Vt_dpi_string__Dpi.h"
+#elif defined(VCS)
+# include "../vc_hdrs.h"
+#elif defined(CADENCE)
+# define NEED_EXTERNS
+#else
+# error "Unknown simulator for DPI test"
+#endif
+
+#ifdef NEED_EXTERNS
+extern "C" {
+
+    extern int dpii_string (const char* s);
+
+}
+#endif
+
+//======================================================================
+
+int dpii_string(const char* s) {
+    printf("dpii_string: %s\n",s);
+    return strlen(s);
+}
diff --git a/test_regress/t/t_clk_condflop.pl b/test_regress/t/t_final.pl
similarity index 64%
copy from test_regress/t/t_clk_condflop.pl
copy to test_regress/t/t_final.pl
index f6d3de4..f912897 100755
--- a/test_regress/t/t_clk_condflop.pl
+++ b/test_regress/t/t_final.pl
@@ -2,20 +2,17 @@
 if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
 # DESCRIPTION: Verilator: Verilog Test driver/expect definition
 #
-# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
+# 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.
 
-my $fail = ($Self->{v3} && verilator_version() !~ /\(ord\)/);
-
 compile (
-	 );
+    );
 
 execute (
-	 check_finished => !$fail,
-	 fails => $fail,
-	 );
+    check_finished=>1,
+    );
 
 ok(1);
 1;
diff --git a/test_regress/t/t_final.v b/test_regress/t/t_final.v
new file mode 100644
index 0000000..f8da608
--- /dev/null
+++ b/test_regress/t/t_final.v
@@ -0,0 +1,27 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2013 by Charlie Brej.
+
+module submodule ();
+   // This bug only appears when not inlining
+   // verilator no_inline_module
+   initial begin
+      $write("d");
+   end
+   final begin
+      $write("d");
+   end
+endmodule
+
+module t ();
+   generate
+      for (genvar i = 0; i < 100; i = i + 1) begin : module_set
+	 submodule u_submodule ();
+      end
+   endgenerate
+   initial begin
+      $write("*-* All Finished *-*\n");
+      $finish;
+   end
+endmodule
diff --git a/test_regress/t/t_clk_condflop.pl b/test_regress/t/t_gated_clk_1.pl
similarity index 64%
copy from test_regress/t/t_clk_condflop.pl
copy to test_regress/t/t_gated_clk_1.pl
index f6d3de4..f912897 100755
--- a/test_regress/t/t_clk_condflop.pl
+++ b/test_regress/t/t_gated_clk_1.pl
@@ -2,20 +2,17 @@
 if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
 # DESCRIPTION: Verilator: Verilog Test driver/expect definition
 #
-# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
+# 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.
 
-my $fail = ($Self->{v3} && verilator_version() !~ /\(ord\)/);
-
 compile (
-	 );
+    );
 
 execute (
-	 check_finished => !$fail,
-	 fails => $fail,
-	 );
+    check_finished=>1,
+    );
 
 ok(1);
 1;
diff --git a/test_regress/t/t_gated_clk_1.v b/test_regress/t/t_gated_clk_1.v
new file mode 100644
index 0000000..a638cb6
--- /dev/null
+++ b/test_regress/t/t_gated_clk_1.v
@@ -0,0 +1,55 @@
+// DESCRIPTION: Verilator: Test of gated clock detection
+//
+// The code as shown generates a result by a delayed assignment from PC. The
+// creation of the result is from a clock gated from the clock that sets
+// PC. Howevever since they are essentially the same clock, the result should
+// be delayed by one cycle.
+//
+// Standard Verilator treats them as different clocks, so the result stays in
+// step with the PC. An event drive simulator always allows the clock to win.
+//
+// The problem is caused by the extra loop added by Verilator to the
+// evaluation of all internally generated clocks (effectively removed by
+// marking the clock enable).
+//
+// This test is added to facilitate experiments with solutions.
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2013 by Jeremy Bennett <jeremy.bennett at embecosm.com>.
+
+module t (/*AUTOARG*/
+   // Inputs
+   clk
+   );
+   input clk;
+
+   reg gated_clk_en = 1'b0 ;
+   reg [1:0] pc = 2'b0;
+   reg [1:0] res = 2'b0;
+
+   wire gated_clk = gated_clk_en & clk;
+
+   always @(posedge clk) begin
+      pc <= pc + 1;
+      gated_clk_en <= 1'b1;
+   end
+
+   always @(posedge gated_clk) begin
+      res <= pc;
+   end
+
+   always @(posedge clk) begin
+      if (pc == 2'b11) begin
+	 // Correct behaviour is that res should be lagging pc in the count
+	 // by one cycle
+	 if (res == 2'b10) begin
+	    $write("*-* All Finished *-*\n");
+	    $finish;
+	 end
+	 else begin
+	   $stop;
+	 end
+      end
+   end
+
+endmodule
diff --git a/test_regress/t/t_clk_condflop.pl b/test_regress/t/t_interface_twod.pl
similarity index 78%
copy from test_regress/t/t_clk_condflop.pl
copy to test_regress/t/t_interface_twod.pl
index f6d3de4..1118f2e 100755
--- a/test_regress/t/t_clk_condflop.pl
+++ b/test_regress/t/t_interface_twod.pl
@@ -7,15 +7,12 @@ 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.
 
-my $fail = ($Self->{v3} && verilator_version() !~ /\(ord\)/);
-
 compile (
-	 );
+    );
 
 execute (
-	 check_finished => !$fail,
-	 fails => $fail,
-	 );
+    check_finished=>1,
+    );
 
 ok(1);
 1;
diff --git a/test_regress/t/t_interface_twod.v b/test_regress/t/t_interface_twod.v
new file mode 100644
index 0000000..4fe47a6
--- /dev/null
+++ b/test_regress/t/t_interface_twod.v
@@ -0,0 +1,47 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2013 by Wilson Snyder.
+
+interface ifc;
+   integer value;
+   modport i (output value);
+   modport o (input value);
+endinterface
+
+module t (/*AUTOARG*/
+   // Inputs
+   clk
+   );
+   input clk;
+   integer cyc=1;
+
+   ifc itop1a(),
+       itop1b();
+
+   wrapper  c1 (.isuba(itop1a),
+		.isubb(itop1b),
+		.i_valuea(14),
+		.i_valueb(15));
+
+   always @ (posedge clk) begin
+      cyc <= cyc + 1;
+      if (cyc==20) begin
+	 if (itop1a.value != 14) $stop;
+	 if (itop1b.value != 15) $stop;
+	 $write("*-* All Finished *-*\n");
+	 $finish;
+      end
+   end
+endmodule
+
+module wrapper
+  (
+   ifc.i isuba, isubb,
+   input integer i_valuea, i_valueb
+   );
+   always @* begin
+      isuba.value = i_valuea;
+      isubb.value = i_valueb;
+   end
+endmodule
diff --git a/test_regress/t/t_clk_condflop.pl b/test_regress/t/t_mod_recurse.pl
similarity index 64%
copy from test_regress/t/t_clk_condflop.pl
copy to test_regress/t/t_mod_recurse.pl
index f6d3de4..e747591 100755
--- a/test_regress/t/t_clk_condflop.pl
+++ b/test_regress/t/t_mod_recurse.pl
@@ -2,20 +2,19 @@
 if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
 # DESCRIPTION: Verilator: Verilog Test driver/expect definition
 #
-# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
+# 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.
 
-my $fail = ($Self->{v3} && verilator_version() !~ /\(ord\)/);
+$Self->{vlt} and $Self->unsupported("Verilator unsupported, bug659");
 
 compile (
-	 );
+    );
 
 execute (
-	 check_finished => !$fail,
-	 fails => $fail,
-	 );
+    check_finished=>1,
+    );
 
 ok(1);
 1;
diff --git a/test_regress/t/t_mod_recurse.v b/test_regress/t/t_mod_recurse.v
new file mode 100644
index 0000000..9de45a4
--- /dev/null
+++ b/test_regress/t/t_mod_recurse.v
@@ -0,0 +1,110 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2013 by Sean Moore.
+
+module t (/*AUTOARG*/
+   // Inputs
+   clk
+   );
+   input clk;
+
+   integer 	cyc=0;
+   reg [63:0] 	crc;
+   reg [63:0] 	sum;
+
+   // Take CRC data and apply to testblock inputs
+   wire [7:0]  tripline = crc[7:0];
+
+   /*AUTOWIRE*/
+
+   wire         valid;
+   wire [3-1:0] value;
+   
+   PriorityChoice #(.OCODEWIDTH(3))
+   pe (.out(valid), .outN(value[2:0]), .tripline(tripline));
+
+   // Aggregate outputs into a single result vector
+   wire [63:0] result = {59'h0, valid, value};
+
+   // Test loop
+   always @ (posedge clk) begin
+`ifdef TEST_VERBOSE
+      $write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result);
+`endif
+      cyc <= cyc + 1;
+      crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
+      sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
+      if (cyc==0) begin
+	 // Setup
+	 crc <= 64'h5aef0c8d_d70a4497;
+	 sum <= 64'h0;
+      end
+      else if (cyc<10) begin
+	 sum <= 64'h0;
+      end
+      else if (cyc<90) begin
+      end
+      else if (cyc==99) begin
+	 $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'hc5fc632f816568fb
+	 if (sum !== `EXPECTED_SUM) $stop;
+	 $write("*-* All Finished *-*\n");
+	 $finish;
+      end
+   end
+
+endmodule
+
+module PriorityChoice (out, outN, tripline);
+   parameter OCODEWIDTH = 1;
+   localparam CODEWIDTH=OCODEWIDTH-1;
+   localparam SCODEWIDTH= (CODEWIDTH<1) ? 1 : CODEWIDTH;
+   
+   output reg             out;
+   output reg [OCODEWIDTH-1:0] outN;
+   input wire [(1<<OCODEWIDTH)-1:0] tripline;
+   wire 			    left;
+   wire [SCODEWIDTH-1:0] 	    leftN;
+   wire 			    right;
+   wire [SCODEWIDTH-1:0] 	    rightN;
+   
+   generate
+      if(OCODEWIDTH==1) begin
+	 assign left = tripline[1];
+	 assign right = tripline[0];
+	 
+	 always @(*) begin
+	    out  <= left || right ;
+	    if(right) begin outN <= {1'b0}; end
+	    else  begin outN <= {1'b1}; end
+	 end
+      end else begin
+	 PriorityChoice #(.OCODEWIDTH(OCODEWIDTH-1))
+	 leftMap
+	   (
+	    .out(left),
+	    .outN(leftN),
+	    .tripline(tripline[(2<<CODEWIDTH)-1:(1<<CODEWIDTH)])
+	    );
+	 PriorityChoice #(.OCODEWIDTH(OCODEWIDTH-1))
+	 rightMap
+	   (
+	    .out(right),
+	    .outN(rightN),
+	    .tripline(tripline[(1<<CODEWIDTH)-1:0])
+	    );
+	 always @(*) begin
+	    if(right) begin
+               out  <= right;
+               outN <= {1'b0, rightN[OCODEWIDTH-2:0]};
+	    end else begin
+               out  <= left;
+               outN <= {1'b1, leftN[OCODEWIDTH-2:0]};
+	    end
+	 end
+      end
+   endgenerate
+endmodule
diff --git a/test_regress/t/t_trace_cat.cpp b/test_regress/t/t_trace_cat.cpp
index 86b5149..0200377 100644
--- a/test_regress/t/t_trace_cat.cpp
+++ b/test_regress/t/t_trace_cat.cpp
@@ -63,7 +63,7 @@ int main(int argc, char **argv, char **env) {
 #elif defined(T_TRACE_CAT_RENEW)
 	    tfp->close();
 	    delete tfp;
-	    VerilatedVcdC* tfp = new VerilatedVcdC;
+	    tfp = new VerilatedVcdC;
 	    top->trace(tfp,99);
 	    tfp->open(trace_name());
 #else
diff --git a/test_regress/t/t_clk_condflop.pl b/test_regress/t/t_vams_wreal.pl
similarity index 65%
copy from test_regress/t/t_clk_condflop.pl
copy to test_regress/t/t_vams_wreal.pl
index f6d3de4..7058e62 100755
--- a/test_regress/t/t_clk_condflop.pl
+++ b/test_regress/t/t_vams_wreal.pl
@@ -2,20 +2,17 @@
 if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
 # DESCRIPTION: Verilator: Verilog Test driver/expect definition
 #
-# Copyright 2003-2009 by Wilson Snyder. This program is free software; you can
+# 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.
 
-my $fail = ($Self->{v3} && verilator_version() !~ /\(ord\)/);
-
 compile (
 	 );
 
 execute (
-	 check_finished => !$fail,
-	 fails => $fail,
-	 );
+	 check_finished=>1,
+     );
 
 ok(1);
 1;
diff --git a/test_regress/t/t_vams_wreal.v b/test_regress/t/t_vams_wreal.v
new file mode 100644
index 0000000..091c792
--- /dev/null
+++ b/test_regress/t/t_vams_wreal.v
@@ -0,0 +1,28 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2011 by Wilson Snyder.
+
+`begin_keywords "VAMS-2.3"
+
+module t (/*autoarg*/
+   // Outputs
+   aout,
+   // Inputs
+   in
+   );
+
+   input [15:0] in;
+   output 	aout; 
+   wreal aout;
+
+   parameter real lsb = 1;
+   // verilator lint_off WIDTH
+   assign  aout = $itor(in) * lsb;
+   
+   initial begin
+      $write("*-* All Finished *-*\n");
+      $finish;
+   end
+
+endmodule
diff --git a/test_regress/t/t_vpi_memory.cpp b/test_regress/t/t_vpi_memory.cpp
new file mode 100644
index 0000000..0a9ad78
--- /dev/null
+++ b/test_regress/t/t_vpi_memory.cpp
@@ -0,0 +1,278 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//*************************************************************************
+//
+// Copyright 2010-2011 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.
+//
+// Verilator is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+//*************************************************************************
+
+#ifdef IS_VPI
+
+#include "vpi_user.h"
+
+#else
+
+#include "Vt_vpi_memory.h"
+#include "verilated.h"
+#include "svdpi.h"
+
+#include "Vt_vpi_memory__Dpi.h"
+
+#include "verilated_vpi.h"
+#include "verilated_vpi.cpp"
+#include "verilated_vcd_c.h"
+
+#endif
+
+#include <cstdio>
+#include <cstring>
+#include <iostream>
+using namespace std;
+
+// __FILE__ is too long
+#define FILENM "t_vpi_memory.cpp"
+
+#define DEBUG if (0) printf
+
+unsigned int main_time = false;
+
+//======================================================================
+
+class VlVpiHandle {
+    /// For testing, etc, wrap vpiHandle in an auto-releasing class
+    vpiHandle m_handle;
+public:
+    VlVpiHandle() : m_handle(NULL) { }
+    VlVpiHandle(vpiHandle h) : m_handle(h) { }
+    ~VlVpiHandle() { if (m_handle) { vpi_free_object(m_handle); m_handle=NULL; } } // icarus has yet to catch up with 1800-2009
+    operator vpiHandle () const { return m_handle; }
+    inline VlVpiHandle& operator= (vpiHandle h) { m_handle = h; return *this; }
+};
+
+//======================================================================
+
+#define CHECK_RESULT_VH(got, exp) \
+    if ((got) != (exp)) { \
+	printf("%%Error: %s:%d: GOT = %p   EXP = %p\n", \
+	       FILENM,__LINE__, (got), (exp)); \
+	return __LINE__; \
+    }
+
+#define CHECK_RESULT_NZ(got) \
+    if (!(got)) { \
+	printf("%%Error: %s:%d: GOT = NULL  EXP = !NULL\n", FILENM,__LINE__); \
+	return __LINE__; \
+    }
+
+// Use cout to avoid issues with %d/%lx etc
+#define CHECK_RESULT(got, exp) \
+    if ((got != exp)) { \
+	cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__ \
+	   <<": GOT = "<<(got)<<"   EXP = "<<(exp)<<endl;	\
+	return __LINE__; \
+    }
+
+#define CHECK_RESULT_HEX(got, exp) \
+    if ((got != exp)) { \
+	cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__<<hex \
+	   <<": GOT = "<<(got)<<"   EXP = "<<(exp)<<endl;	\
+	return __LINE__; \
+    }
+
+#define CHECK_RESULT_CSTR(got, exp) \
+    if (strcmp((got),(exp))) { \
+	printf("%%Error: %s:%d: GOT = '%s'   EXP = '%s'\n", \
+	       FILENM,__LINE__, (got)?(got):"<null>", (exp)?(exp):"<null>"); \
+	return __LINE__; \
+    }
+
+#define CHECK_RESULT_CSTR_STRIP(got, exp) \
+    CHECK_RESULT_CSTR(got+strspn(got, " "), exp)
+
+// ideally we should be able to iterate on vpiRange against a list of this struct
+typedef struct range {
+    int size;
+    int left;
+    int right;
+} range_s, *range_p;
+
+int _mon_check_range(VlVpiHandle& handle, int size, int left, int right) {
+    VlVpiHandle iter_h, rng_h, left_h, right_h;
+    s_vpi_value value = {
+      vpiIntVal
+    };
+    // check size of object
+    int vpisize = vpi_get(vpiSize, handle);
+    CHECK_RESULT(vpisize, size);
+/*
+    // get range and check against expected
+    iter_h = vpi_iterate(vpiRange, handle);
+    CHECK_RESULT_NZ(iter_h);
+    rng_h = vpi_scan(iter_h);
+    CHECK_RESULT_NZ(rng_h);
+    int vpitype = vpi_get(vpiType, rng_h);
+    CHECK_RESULT(vpitype, vpiRange);
+*/
+    // check size of range
+    vpisize = vpi_get(vpiSize, handle);
+    CHECK_RESULT(vpisize, size);
+    // check left hand side of range
+    left_h = vpi_handle(vpiLeftRange, handle);
+    CHECK_RESULT_NZ(left_h);
+    vpi_get_value(left_h, &value);
+    CHECK_RESULT(value.value.integer, left);
+    // check right hand side of range
+    right_h = vpi_handle(vpiRightRange, handle);
+    CHECK_RESULT_NZ(right_h);
+    vpi_get_value(right_h, &value);
+    CHECK_RESULT(value.value.integer, right);
+    return 0; // Ok
+}
+
+int _mon_check_memory() {
+    int cnt;
+    VlVpiHandle mem_h, lcl_h;
+    vpiHandle iter_h; // icarus does not like auto free of iterator handles
+    s_vpi_value value = {
+      vpiIntVal
+    };
+    vpi_printf((PLI_BYTE8*)"Check memory vpi ...\n");
+    mem_h = vpi_handle_by_name((PLI_BYTE8*)"t.mem0", NULL);
+    CHECK_RESULT_NZ(mem_h);
+    // check type
+    int vpitype = vpi_get(vpiType, mem_h);
+    CHECK_RESULT(vpitype, vpiMemory);
+    _mon_check_range(mem_h, 16, 16, 1);
+    // iterate and store
+    iter_h = vpi_iterate(vpiMemoryWord, mem_h);
+    cnt = 0;
+    while (lcl_h = vpi_scan(iter_h)) {
+	value.value.integer = ++cnt;
+        vpi_put_value(lcl_h, &value, NULL, vpiNoDelay);
+        // check size and range
+        _mon_check_range(lcl_h, 32, 31, 0);
+    }
+    CHECK_RESULT(cnt, 16); // should be 16 addresses
+    // iterate and accumulate
+    iter_h = vpi_iterate(vpiMemoryWord, mem_h);
+    cnt = 0;
+    while (lcl_h = vpi_scan(iter_h)) {
+      ++cnt;
+      vpi_get_value(lcl_h, &value);
+      CHECK_RESULT(value.value.integer, cnt);
+    }
+    CHECK_RESULT(cnt, 16); // should be 16 addresses
+    // don't care for non verilator
+    // (crashes on Icarus)
+    s_vpi_vlog_info info;
+    vpi_get_vlog_info(&info);
+    if (strcmp(info.product, "Verilator") != 0) {
+	vpi_printf((PLI_BYTE8*)"Skipping property checks for simulator %s\n", info.product);
+        return 0; // Ok
+    }
+    // make sure trying to get properties that don't exist
+    // doesn't crash
+    int should_be_0 = vpi_get(vpiSize, iter_h);
+    CHECK_RESULT(should_be_0, 0);
+    should_be_0 = vpi_get(vpiIndex, iter_h);
+    CHECK_RESULT(should_be_0, 0);
+    vpiHandle should_be_NULL = vpi_handle(vpiLeftRange, iter_h);
+    CHECK_RESULT(should_be_NULL, 0);
+    should_be_NULL = vpi_handle(vpiRightRange, iter_h);
+    CHECK_RESULT(should_be_NULL, 0);
+    should_be_NULL = vpi_handle(vpiScope, iter_h);
+    CHECK_RESULT(should_be_NULL, 0);
+    return 0; // Ok
+}
+
+int mon_check() {
+    // Callback from initial block in monitor
+    if (int status = _mon_check_memory()) return status;
+    return 0; // Ok
+}
+
+//======================================================================
+
+#ifdef IS_VPI
+
+
+static s_vpi_systf_data vpi_systf_data[] = {
+  {vpiSysFunc, vpiSysFunc, (PLI_BYTE8*)"$mon_check", (PLI_INT32(*)(PLI_BYTE8*))mon_check, 0, 0, 0},
+  0
+};
+
+// cver entry
+void vpi_compat_bootstrap(void) {
+  p_vpi_systf_data systf_data_p;
+  systf_data_p = &(vpi_systf_data[0]);
+  while (systf_data_p->type != 0) vpi_register_systf(systf_data_p++);
+}
+
+// icarus entry
+void (*vlog_startup_routines[])() = {
+      vpi_compat_bootstrap,
+      0
+};
+
+#else
+double sc_time_stamp () {
+    return main_time;
+}
+int main(int argc, char **argv, char **env) {
+    double sim_time = 1100;
+    Verilated::commandArgs(argc, argv);
+    Verilated::debug(0);
+    Verilated::fatalOnVpiError(0); // we're going to be checking for these errors do don't crash out
+
+    VM_PREFIX* topp = new VM_PREFIX ("");  // Note null name - we're flattening it out
+
+#ifdef VERILATOR
+# ifdef TEST_VERBOSE
+    Verilated::scopesDump();
+# endif
+#endif
+
+    Verilated::traceEverOn(true);
+    VerilatedVcdC* tfp = new VerilatedVcdC;
+#if VM_TRACE
+    VL_PRINTF("Enabling waves...\n");
+    topp->trace (tfp, 99);
+    tfp->open ("obj_dir/t_vpi_var/simx.vcd");
+#endif
+
+    topp->eval();
+    topp->clk = 0;
+    main_time += 10;
+
+    while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {
+	main_time += 1;
+	topp->eval();
+	VerilatedVpi::callValueCbs();
+	topp->clk = !topp->clk;
+	//mon_do();
+#if VM_TRACE
+	if (tfp) tfp->dump (main_time);
+#endif
+    }
+    if (!Verilated::gotFinish()) {
+	vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
+    }
+    topp->final();
+
+#if VM_TRACE
+    if (tfp) tfp->close();
+#endif
+
+    delete topp; topp=NULL;
+    exit(0L);
+}
+
+#endif
+
diff --git a/test_regress/t/t_vpi_memory.pl b/test_regress/t/t_vpi_memory.pl
new file mode 100755
index 0000000..5a1982e
--- /dev/null
+++ b/test_regress/t/t_vpi_memory.pl
@@ -0,0 +1,25 @@
+#!/usr/bin/perl
+if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
+# DESCRIPTION: Verilator: Verilog Test driver/expect definition
+#
+# Copyright 2010 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 (
+    make_top_shell => 0,
+    make_main => 0,
+    make_pli => 1,
+    iv_flags2 => ["-g2005-sv -D USE_VPI_NOT_DPI -s t -o obj_dir/iv_t_vpi_memory/simiv"],
+    v_flags2 => ["+define+USE_VPI_NOT_DPI"],
+    verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb' --exe --no-l2name $Self->{t_dir}/t_vpi_memory.cpp"],
+    );
+
+execute (
+    iv_pli => 1,
+    check_finished=>1
+    );
+
+ok(1);
+1;
diff --git a/test_regress/t/t_vpi_memory.v b/test_regress/t/t_vpi_memory.v
new file mode 100644
index 0000000..1ae92a6
--- /dev/null
+++ b/test_regress/t/t_vpi_memory.v
@@ -0,0 +1,47 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// Copyright 2010 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.
+
+`ifdef USE_VPI_NOT_DPI
+//We call it via $c so we can verify DPI isn't required - see bug572
+`else
+import "DPI-C" context function integer mon_check();
+`endif
+
+module t (/*AUTOARG*/
+   // Inputs
+   clk
+   );
+
+`ifdef VERILATOR
+`systemc_header
+extern "C" int mon_check();
+`verilog
+`endif
+
+   input clk;
+
+   reg [31:0] mem0 [16:1] /*verilator public_flat_rw @(posedge clk) */;
+   integer 	  i, status;
+
+   // Test loop
+   initial begin
+`ifdef VERILATOR
+      status = $c32("mon_check()");
+`endif
+`ifdef iverilog
+     status = $mon_check();
+`endif
+`ifndef USE_VPI_NOT_DPI
+     status = mon_check();
+`endif
+      for (i = 16; i > 0; i--)
+	if (mem0[i] !== i) $write("%%Error: %d : GOT = %d  EXP = %d\n", i, mem0[i], i);
+      $write("*-* All Finished *-*\n");
+      $finish;
+   end
+
+endmodule : t
diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp
index bbb7fa9..893f918 100644
--- a/test_regress/t/t_vpi_var.cpp
+++ b/test_regress/t/t_vpi_var.cpp
@@ -93,7 +93,7 @@ public:
 
 int _mon_check_mcd() {
     PLI_INT32 status;
-    
+
     PLI_UINT32 mcd;
     PLI_BYTE8* filename = (PLI_BYTE8*)"obj_dir/t_vpi_var/mcd_open.tmp";
     mcd = vpi_mcd_open(filename);
@@ -247,13 +247,13 @@ int _mon_check_var() {
 	VlVpiHandle vh10 = vpi_handle(vpiLeftRange, vh4);
 	CHECK_RESULT_NZ(vh10);
 	vpi_get_value(vh10, &tmpValue);
-	CHECK_RESULT(tmpValue.value.integer,2);
+	CHECK_RESULT(tmpValue.value.integer,4);
     }
     {
 	VlVpiHandle vh10 = vpi_handle(vpiRightRange, vh4);
 	CHECK_RESULT_NZ(vh10);
 	vpi_get_value(vh10, &tmpValue);
-	CHECK_RESULT(tmpValue.value.integer,1);
+	CHECK_RESULT(tmpValue.value.integer,3);
     }
     {
 	VlVpiHandle vh10 = vpi_iterate(vpiMemoryWord, vh4);
@@ -263,11 +263,11 @@ int _mon_check_var() {
 	VlVpiHandle vh12 = vpi_handle(vpiLeftRange, vh11);
 	CHECK_RESULT_NZ(vh12);
 	vpi_get_value(vh12, &tmpValue);
-	CHECK_RESULT(tmpValue.value.integer,4);
+	CHECK_RESULT(tmpValue.value.integer,2);
 	VlVpiHandle vh13 = vpi_handle(vpiRightRange, vh11);
 	CHECK_RESULT_NZ(vh13);
 	vpi_get_value(vh13, &tmpValue);
-	CHECK_RESULT(tmpValue.value.integer,3);
+	CHECK_RESULT(tmpValue.value.integer,1);
     }
 
     return 0;
diff --git a/verilator.pdf b/verilator.pdf
index 49812e7..c37b921 100644
Binary files a/verilator.pdf and b/verilator.pdf 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