[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