Compare commits

...
17 Commits
58 changed files with 452 additions and 137 deletions
+14
View File
@@ -2,6 +2,20 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 3.908 2017-08-28
**** Support x in $readmem, bug1180. [Arthur Kahlich]
**** Support packed struct DPI imports, bug1190. [Rob Stoddard]
**** Fix GCC 6 warnings.
**** Fix compile error on unused VL_VALUEPLUSARGS_IW, bug1181. [Thomas J Whatson]
**** Fix undefined VL_POW_WWI. [Clifford Wolf]
**** Fix internal error on unconnected inouts, bug1187. [Rob Stoddard]
* Verilator 3.906 2017-06-22
+1 -1
View File
@@ -1510,7 +1510,7 @@ OPT, OPT_FAST, or OPT_SLOW lib/verilated.mk. Or, use the -CFLAGS and/or
the compiler or linker. Or, just for one run, pass them on the command
line to make:
make OPT_FAST="-O2" -f Vour.mk Vour__ALL.a
make OPT_FAST="-O2 -fno-stack-protector" -f Vour.mk Vour__ALL.a
OPT_FAST specifies optimizations for those programs that are part of the
fast path, mostly code that is executed every cycle. OPT_SLOW specifies
+12 -11
View File
@@ -6,7 +6,7 @@
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[3.906 2017-06-22])
AC_INIT([Verilator],[3.908 2017-08-28])
# When releasing, also update header of Changes file
AC_CONFIG_HEADER(src/config_build.h)
@@ -140,34 +140,35 @@ AC_DEFUN([_MY_CXX_CHECK_OPT],
])# _MY_CXX_CHECK_OPT
# Flags for compiling Verilator internals including parser
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-char-subscripts)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-undefined-bool-conversion)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Qunused-arguments)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-faligned-new)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-fno-delete-null-pointer-checks)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-undefined-bool-conversion)
AC_SUBST(CFG_CXXFLAGS_SRC)
# Flags for compiling Verilator parser
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-unused)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-parentheses-equality)
# Flags for compiling Verilator parser (in addition to above CFG_CXXFLAGS_SRC)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-char-subscripts)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-null-conversion)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-parentheses-equality)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-unused)
AC_SUBST(CFG_CXXFLAGS_PARSER)
# Flags for Verilated makefile
# For example, -Wno-div-by-zero isn't in 4.1.2
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-char-subscripts)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-parentheses-equality)
# Random code often does / 0. Unfortunately VL_DIV_I(0,0) will warn
# without this flag, even though there's a conditional to prevent the divide.
# We still don't add no-div-by-zero as it throws message to stdout, though doesn't die.
#_MY_CXX_CHECK_OPT(-Wno-div-by-zero)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-faligned-new)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-fbracket-depth=4096)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-parentheses-equality)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-sign-compare)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-uninitialized)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-but-set-variable)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-parameter)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-variable)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-fbracket-depth=4096)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments)
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
# Checks for library functions.
+44 -7
View File
@@ -283,6 +283,7 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, boo
}
WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp) {
// obits==lbits, rbits can be different
owp[0] = 1;
for (int i=1; i < VL_WORDS_I(obits); i++) owp[i] = 0;
// cppcheck-suppress variableScope
@@ -303,8 +304,24 @@ WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDa
}
return owp;
}
WDataOutP VL_POW_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp, QData rhs) {
WData rhsw[2]; VL_SET_WQ(rhsw, rhs);
return VL_POW_WWW(obits,lbits,rbits,owp,lwp,rhsw);
}
QData VL_POW_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp) {
// Skip check for rhs == 0, as short-circuit doesn't save time
if (VL_UNLIKELY(lhs==0)) return 0;
QData power = lhs;
QData out = VL_ULL(1);
for (int bit=0; bit<rbits; ++bit) {
if (bit>0) power = power*power;
if (VL_BITISSET_W(rwp,bit)) out *= power;
}
return out;
}
WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool lsign, bool rsign) {
// obits==lbits, rbits can be different
if (rsign && VL_SIGN_W(rbits, rwp)) {
int words = VL_WORDS_I(obits);
VL_ZERO_W(obits, owp);
@@ -323,6 +340,23 @@ WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, W
}
return VL_POW_WWW(obits, rbits, rbits, owp, lwp, rwp);
}
WDataOutP VL_POWSS_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp, QData rhs, bool lsign, bool rsign) {
WData rhsw[2]; VL_SET_WQ(rhsw, rhs);
return VL_POWSS_WWW(obits,lbits,rbits,owp,lwp,rhsw,lsign,rsign);
}
QData VL_POWSS_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp, bool lsign, bool rsign) {
// Skip check for rhs == 0, as short-circuit doesn't save time
if (rsign && VL_SIGN_W(rbits, rwp)) {
if (lhs==0) return 0; // "X"
else if (lhs==1) return 1;
else if (lsign && lhs==VL_MASK_I(obits)) { // -1
if (rwp[0] & 1) return VL_MASK_I(obits); // -1^odd=-1
else return 1; // -1^even=1
}
return 0;
}
return VL_POW_QQW(obits, rbits, rbits, lhs, rwp);
}
//===========================================================================
// Formatting
@@ -495,25 +529,28 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
case 'u': // Packed 2-state
output.reserve(output.size() + 4*VL_WORDS_I(lbits));
for (int i=0; i<VL_WORDS_I(lbits); ++i) {
output += (char)((lwp[i] >> 0) & 0xff);
output += (char)((lwp[i] ) & 0xff);
output += (char)((lwp[i] >> 8) & 0xff);
output += (char)((lwp[i] >> 16) & 0xff);
output += (char)((lwp[i] >> 24) & 0xff);
}
break;
case 'z': // Packed 4-state
output.reserve(output.size() + 8*VL_WORDS_I(lbits));
for (int i=0; i<VL_WORDS_I(lbits); ++i) {
output += (char)((lwp[i] >> 0) & 0xff);
output += (char)((lwp[i] ) & 0xff);
output += (char)((lwp[i] >> 8) & 0xff);
output += (char)((lwp[i] >> 16) & 0xff);
output += (char)((lwp[i] >> 24) & 0xff);
output += "\0\0\0\0"; // No tristate
}
break;
case 'v': // Strength; assume always strong
for (lsb=lbits-1; lsb>=0; --lsb) {
if ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) output += "St1 ";
else output += "St0 ";
}
break;
case 'x':
for (; lsb>=0; --lsb) {
lsb = (lsb / 4) * 4; // Next digit
@@ -651,7 +688,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
// Deal with all read-and-scan somethings
// Note LSBs are preserved if there's an overflow
const int obits = va_arg(ap, int);
WData qowp[2];
WData qowp[2] = {0, 0};
WDataOutP owp = qowp;
if (obits > VL_QUADSIZE) {
owp = va_arg(ap,WDataOutP);
@@ -1038,9 +1075,9 @@ void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
else if (c=='_') {}
else if (c=='@') { reading_addr = true; innum=false; needinc=false; }
// Check for hex or binary digits as file format requests
else if (isxdigit(c)) {
else if (isxdigit(c) || (!reading_addr && (c=='x' || c=='X'))) {
c = tolower(c);
int value = (c >= 'a' ? (c-'a'+10) : (c-'0'));
int value = (c >= 'a' ? (c=='x' ? VL_RAND_RESET_I(4) : (c-'a'+10)) : (c-'0'));
if (!innum) { // Prep for next number
if (needinc) { addr++; needinc=false; }
}
@@ -1092,7 +1129,7 @@ void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
}
lastc = c;
}
if (needinc) { addr++; needinc=false; }
if (needinc) { addr++; }
// Final checks
fclose(fp);
@@ -1247,7 +1284,7 @@ const char* Verilated::catName(const char* n1, const char* n2) {
static char* strp = NULL;
static size_t len = 0;
size_t newlen = strlen(n1)+strlen(n2)+2;
if (newlen > len) {
if (!strp || newlen > len) {
if (strp) delete [] strp;
strp = new char[newlen];
len = newlen;
+13 -22
View File
@@ -392,7 +392,6 @@ extern IData VL_SYSTEM_IQ(QData lhs);
inline IData VL_SYSTEM_II(IData lhs) { return VL_SYSTEM_IQ(lhs); }
extern IData VL_TESTPLUSARGS_I(const char* formatp);
extern IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp);
extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
//=========================================================================
@@ -405,6 +404,7 @@ extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
#define VL_BITISSETLIMIT_W(data,width,bit) (((bit)<(width)) && data[VL_BITWORD_I(bit)] & (VL_UL(1)<<VL_BITBIT_I(bit)))
/// Create two 32-bit words from quadword
/// WData is always at least 2 words; does not clean upper bits
#define VL_SET_WQ(owp,data) { owp[0]=(IData)(data); owp[1]=(IData)((data)>>VL_WORDSIZE); }
#define VL_SET_WI(owp,data) { owp[0]=(IData)(data); owp[1]=0; }
#define VL_SET_QW(lwp) ( ((QData)(lwp[0])) | ((QData)(lwp[1])<<((QData)(VL_WORDSIZE)) ))
@@ -524,7 +524,7 @@ static inline WDataOutP VL_ALLONES_W(int obits, WDataOutP owp) {
// EMIT_RULE: VL_ASSIGN: oclean=rclean; obits==lbits;
// For now, we always have a clean rhs.
// Note: If a ASSIGN isn't clean, use VL_ASSIGNCLEAN instead to do the same thing.
static inline WDataOutP VL_ASSIGN_W(int obits, WDataOutP owp,WDataInP lwp){
static inline WDataOutP VL_ASSIGN_W(int obits, WDataOutP owp, WDataInP lwp) {
int words = VL_WORDS_I(obits);
for (int i=0; i < words; ++i) owp[i] = lwp[i];
return(owp);
@@ -1191,7 +1191,10 @@ static inline WDataOutP VL_MODDIVS_WWW(int lbits, WDataOutP owp,WDataInP lwp,WDa
}
}
#define VL_POW_IIQ(obits,lbits,rbits,lhs,rhs) VL_POW_QQQ(obits,lbits,rbits,lhs,rhs)
#define VL_POW_IIW(obits,lbits,rbits,lhs,rwp) VL_POW_QQW(obits,lbits,rbits,lhs,rwp)
#define VL_POW_QQI(obits,lbits,rbits,lhs,rhs) VL_POW_QQQ(obits,lbits,rbits,lhs,rhs)
#define VL_POW_WWI(obits,lbits,rbits,owp,lwp,rhs) VL_POW_WWQ(obits,lbits,rbits,owp,lwp,rhs)
static inline IData VL_POW_III(int, int, int rbits, IData lhs, IData rhs) {
if (VL_UNLIKELY(rhs==0)) return 1;
@@ -1216,8 +1219,14 @@ static inline QData VL_POW_QQQ(int, int, int rbits, QData lhs, QData rhs) {
return out;
}
WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp);
WDataOutP VL_POW_WWQ(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, QData rhs);
QData VL_POW_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp);
#define VL_POWSS_IIQ(obits,lbits,rbits,lhs,rhs,lsign,rsign) VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
#define VL_POWSS_IIQ(obits,lbits,rbits,lhs,rhs,lsign,rsign) VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
#define VL_POWSS_IIW(obits,lbits,rbits,lhs,rwp,lsign,rsign) VL_POWSS_QQW(obits,lbits,rbits,lhs,rwp,lsign,rsign)
#define VL_POWSS_QQI(obits,lbits,rbits,lhs,rhs,lsign,rsign) VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
#define VL_POWSS_WWI(obits,lbits,rbits,owp,lwp,rhs,lsign,rsign) VL_POWSS_WWQ(obits,lbits,rbits,owp,lwp,rhs,lsign,rsign)
static inline IData VL_POWSS_III(int obits, int, int rbits, IData lhs, IData rhs, bool lsign, bool rsign) {
if (VL_UNLIKELY(rhs==0)) return 1;
@@ -1246,6 +1255,8 @@ static inline QData VL_POWSS_QQQ(int obits, int, int rbits, QData lhs, QData rhs
return VL_POW_QQQ(obits, rbits, rbits, lhs, rhs);
}
WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool lsign, bool rsign);
WDataOutP VL_POWSS_WWQ(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, QData rhs, bool lsign, bool rsign);
QData VL_POWSS_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp, bool lsign, bool rsign);
//===================================================================
// Concat/replication
@@ -1880,26 +1891,6 @@ static inline WDataOutP VL_COND_WIWW(int obits, int, int, int,
return(owp);
}
//======================================================================
// System Functions
inline IData VL_VALUEPLUSARGS_IQ(int rbits, const char* prefixp, char fmt, QData& ldr) {
WData wd[2]; IData v=VL_VALUEPLUSARGS_IW(rbits,prefixp,fmt,wd); if (v) ldr=VL_SET_QW(wd);
return v;
}
inline IData VL_VALUEPLUSARGS_II(int rbits, const char* prefixp, char fmt, CData& ldr) {
QData qd; IData v=VL_VALUEPLUSARGS_IQ(rbits,prefixp,fmt,qd); if (v) ldr=(CData)qd;
return v;
}
inline IData VL_VALUEPLUSARGS_II(int rbits, const char* prefixp, char fmt, SData& ldr) {
QData qd; IData v=VL_VALUEPLUSARGS_IQ(rbits,prefixp,fmt,qd); if (v) ldr=(SData)qd;
return v;
}
inline IData VL_VALUEPLUSARGS_II(int rbits, const char* prefixp, char fmt, IData& ldr) {
QData qd; IData v=VL_VALUEPLUSARGS_IQ(rbits,prefixp,fmt,qd); if (v) ldr=(IData)qd;
return v;
}
//======================================================================
// Constification
+1
View File
@@ -72,6 +72,7 @@ private:
T* m_countp; ///< Count value
public:
// METHODS
// cppcheck-suppress truncLongCastReturn
virtual vluint64_t count() const { return *m_countp; }
virtual void zero() const { *m_countp = 0; }
// CONSTRUCTORS
+10 -10
View File
@@ -58,31 +58,31 @@ const char* svDpiVersion() {
//======================================================================
// Bit-select utility functions.
svBit svGetBitselBit(const svBitVecVal* s, int i) {
_VL_SVDPI_UNIMP(); return 0;
svBit svGetBitselBit(const svBitVecVal* sp, int bit) {
return VL_BITISSET_W(sp,bit);
}
svLogic svGetBitselLogic(const svLogicVecVal* s, int i) {
svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) {
_VL_SVDPI_UNIMP(); return 0;
}
void svPutBitselBit(svBitVecVal* d, int i, svBit s) {
_VL_SVDPI_UNIMP();
void svPutBitselBit(svBitVecVal* dp, int bit, svBit s) {
VL_ASSIGNBIT_WI(32, bit, dp, s);
}
void svPutBitselLogic(svLogicVecVal* d, int i, svLogic s) {
void svPutBitselLogic(svLogicVecVal* dp, int bit, svLogic s) {
_VL_SVDPI_UNIMP();
}
void svGetPartselBit(svBitVecVal* d, const svBitVecVal* s, int i, int w) {
void svGetPartselBit(svBitVecVal* dp, const svBitVecVal* sp, int i, int w) {
_VL_SVDPI_UNIMP();
}
void svGetPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w) {
void svGetPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int i, int w) {
_VL_SVDPI_UNIMP();
}
void svPutPartselBit(svBitVecVal* d, const svBitVecVal s, int i, int w) {
void svPutPartselBit(svBitVecVal* dp, const svBitVecVal s, int i, int w) {
_VL_SVDPI_UNIMP();
}
void svPutPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w) {
void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int i, int w) {
_VL_SVDPI_UNIMP();
}
+1 -1
View File
@@ -68,7 +68,7 @@ extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp,
extern string VL_SFORMATF_NX(const char* formatp, ...);
extern IData VL_VALUEPLUSARGS_INW(int rbits, const string& ld, WDataOutP rdp);
inline IData VL_VALUEPLUSARGS_INI(int rbits, const string& ld, IData& rdr) {
WData rwp[1];
WData rwp[2]; // WData must always be at least 2
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
if (got) rdr = rwp[0];
return got;
+2
View File
@@ -570,6 +570,7 @@ void VerilatedVcd::declDouble (vluint32_t code, const char* name, int arraynum
//=============================================================================
void VerilatedVcd::fullDouble (vluint32_t code, const double newval) {
// cppcheck-suppress invalidPointerCast
(*((double*)&m_sigs_oldvalp[code])) = newval;
// Buffer can't overflow before sprintf; we sized during declaration
sprintf(m_writep, "r%.16g", newval);
@@ -578,6 +579,7 @@ void VerilatedVcd::fullDouble (vluint32_t code, const double newval) {
bufferCheck();
}
void VerilatedVcd::fullFloat (vluint32_t code, const float newval) {
// cppcheck-suppress invalidPointerCast
(*((float*)&m_sigs_oldvalp[code])) = newval;
// Buffer can't overflow before sprintf; we sized during declaration
sprintf(m_writep, "r%.16g", (double)newval);
+2
View File
@@ -382,11 +382,13 @@ public:
}
}
inline void chgDouble (vluint32_t code, const double newval) {
// cppcheck-suppress invalidPointerCast
if (VL_UNLIKELY((*((double*)&m_sigs_oldvalp[code])) != newval)) {
fullDouble (code, newval);
}
}
inline void chgFloat (vluint32_t code, const float newval) {
// cppcheck-suppress invalidPointerCast
if (VL_UNLIKELY((*((float*)&m_sigs_oldvalp[code])) != newval)) {
fullFloat (code, newval);
}
+3 -4
View File
@@ -946,11 +946,10 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
case VLVT_UINT32:
value_p->value.integer = *((IData*)(vop->varDatap()));
return;
case VLVT_WDATA:
case VLVT_UINT64:
// Not legal
value_p->value.integer = 0;
case VLVT_WDATA: // FALLTHRU
case VLVT_UINT64: // FALLTHRU
default:
value_p->value.integer = 0;
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return;
+14 -14
View File
@@ -99,8 +99,8 @@ 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() const { return 0; }
virtual vluint32_t type() { return 0; }
virtual vluint32_t size() const { return 0; }
virtual const VerilatedRange* rangep() const { return NULL; }
virtual vpiHandle dovpi_scan() { return 0; }
};
@@ -120,7 +120,7 @@ public:
}
virtual ~VerilatedVpioCb() {}
static inline VerilatedVpioCb* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioCb*>((VerilatedVpio*)h); }
virtual const vluint32_t type() { return vpiCallback; }
virtual 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); }
@@ -133,7 +133,7 @@ public:
explicit 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; }
virtual vluint32_t type() { return vpiUndefined; }
vlsint32_t num() const { return m_num; }
};
@@ -144,8 +144,8 @@ public:
explicit VerilatedVpioRange(const VerilatedRange* range) : m_range(range), m_iteration(0) {}
virtual ~VerilatedVpioRange() {}
static inline VerilatedVpioRange* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioRange*>((VerilatedVpio*)h); }
virtual const vluint32_t type() { return vpiRange; }
virtual const vluint32_t size() const { return m_range->elements(); }
virtual vluint32_t type() { return vpiRange; }
virtual 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; }
@@ -167,7 +167,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; }
virtual 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(); }
@@ -206,12 +206,12 @@ 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() {
vluint32_t index() { return m_index; }
virtual vluint32_t type() {
if (varp()->vldir() != vpiNoDirection) return vpiPort;
return (varp()->dims()>1) ? vpiMemory : vpiReg; /* but might be wire, logic */
}
virtual const vluint32_t size() const { return get_range().elements(); }
virtual vluint32_t size() const { return get_range().elements(); }
virtual const VerilatedRange* rangep() const { return &get_range(); }
virtual const char* name() { return m_varp->name(); }
virtual const char* fullname() {
@@ -239,8 +239,8 @@ public:
}
virtual ~VerilatedVpioMemoryWord() {}
static inline VerilatedVpioMemoryWord* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioMemoryWord*>((VerilatedVpio*)h); }
virtual const vluint32_t type() { return vpiMemoryWord; }
virtual const vluint32_t size() const { return varp()->range().elements(); }
virtual vluint32_t type() { return vpiMemoryWord; }
virtual vluint32_t size() const { return varp()->range().elements(); }
virtual const VerilatedRange* rangep() const { return &(varp()->range()); }
virtual const char* fullname() {
VL_STATIC_OR_THREAD string out;
@@ -259,7 +259,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 vluint32_t type() { return vpiIterator; }
virtual vpiHandle dovpi_scan() {
if (VL_LIKELY(m_scopep->varsp())) {
VerilatedVarNameMap* varsp = m_scopep->varsp();
@@ -286,7 +286,7 @@ public:
: 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; }
virtual 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;
+1 -1
View File
@@ -95,7 +95,7 @@
// This is not necessarily the same as #UL, depending on what the IData typedef is.
#define VL_UL(c) ((IData)(c##UL)) ///< Add appropriate suffix to 32-bit constant
#ifdef VL_CPPCHECK
#if defined(VL_CPPCHECK) || defined(__clang_analyzer__)
# define VL_DANGLING(v)
#else
# define VL_DANGLING(v) do { (v) = NULL; } while(0) ///< After e.g. delete, set variable to NULL to indicate must not use later
+1 -1
View File
@@ -323,7 +323,7 @@ private:
// Read sensitivitues
m_itemCombo = false;
m_itemSequent = false;
oldsensesp->iterateAndNext(*this);
if (oldsensesp) oldsensesp->iterateAndNext(*this);
bool combo = m_itemCombo;
bool sequent = m_itemSequent;
+1 -1
View File
@@ -119,7 +119,7 @@ private:
} else {
nodep->v3fatalSrc("Unknown node type");
}
if (stmtsp) bodysp = bodysp->addNext(stmtsp);
if (bodysp && stmtsp) bodysp = bodysp->addNext(stmtsp);
AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL);
bodysp = ifp;
if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
+3 -1
View File
@@ -902,7 +902,7 @@ bool AstNode::sameTreeIter(AstNode* node1p, AstNode* node2p, bool ignNext, bool
//======================================================================
// Static utilities
ostream& operator<<(ostream& os, V3Hash rhs) {
ostream& operator<<(ostream& os, const V3Hash& rhs) {
return os<<hex<<setw(2)<<setfill('0')<<rhs.depth()
<<"_"<<setw(6)<<setfill('0')<<rhs.hshval();
}
@@ -1057,6 +1057,8 @@ void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
editCountSetLast();
}
void AstNode::v3errorEndFatal(ostringstream& str) const { v3errorEnd(str); assert(0); }
void AstNode::v3errorEnd(ostringstream& str) const {
if (!dynamic_cast<const AstNode*>(this)) {
// No known cases cause this, but better than a core dump
+17 -13
View File
@@ -61,7 +61,7 @@ public:
inline bool operator== (AstType lhs, AstType rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstType lhs, AstType::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstType::en lhs, AstType rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstType rhs) { return os<<rhs.ascii(); }
inline ostream& operator<<(ostream& os, const AstType& rhs) { return os<<rhs.ascii(); }
//######################################################################
@@ -107,7 +107,7 @@ public:
inline bool operator== (AstNumeric lhs, AstNumeric rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstNumeric lhs, AstNumeric::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstNumeric::en lhs, AstNumeric rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstNumeric rhs) { return os<<rhs.ascii(); }
inline ostream& operator<<(ostream& os, const AstNumeric& rhs) { return os<<rhs.ascii(); }
//######################################################################
@@ -396,7 +396,7 @@ public:
return (m_e==LOGIC || m_e==BIT);
}
bool isDpiUnsupported() const {
return (m_e==LOGIC || m_e==TIME);
return (m_e==TIME);
}
bool isDpiUnsignable() const { // Can add "unsigned" to DPI
return (m_e==BYTE || m_e==SHORTINT || m_e==INT || m_e==LONGINT || m_e==INTEGER);
@@ -464,7 +464,7 @@ public:
inline bool operator== (AstVarType lhs, AstVarType rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstVarType lhs, AstVarType::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstVarType::en lhs, AstVarType rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstVarType rhs) { return os<<rhs.ascii(); }
inline ostream& operator<<(ostream& os, const AstVarType& rhs) { return os<<rhs.ascii(); }
//######################################################################
@@ -496,7 +496,7 @@ public:
inline bool operator== (AstBranchPred lhs, AstBranchPred rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstBranchPred lhs, AstBranchPred::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstBranchPred::en lhs, AstBranchPred rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstBranchPred rhs) { return os<<rhs.ascii(); }
inline ostream& operator<<(ostream& os, const AstBranchPred& rhs) { return os<<rhs.ascii(); }
//######################################################################
@@ -529,7 +529,7 @@ public:
inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstVarAttrClocker::en lhs, AstVarAttrClocker rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstVarAttrClocker rhs) { return os<<rhs.ascii(); }
inline ostream& operator<<(ostream& os, const AstVarAttrClocker& rhs) { return os<<rhs.ascii(); }
//######################################################################
@@ -628,7 +628,7 @@ public:
inline bool operator== (AstParseRefExp lhs, AstParseRefExp rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstParseRefExp lhs, AstParseRefExp::en rhs) { return (lhs.m_e == rhs); }
inline bool operator== (AstParseRefExp::en lhs, AstParseRefExp rhs) { return (lhs == rhs.m_e); }
inline ostream& operator<<(ostream& os, AstParseRefExp rhs) { return os<<rhs.ascii(); }
inline ostream& operator<<(ostream& os, const AstParseRefExp& rhs) { return os<<rhs.ascii(); }
//######################################################################
// VNumRange - Structure containing numberic range information
@@ -680,7 +680,7 @@ struct VNumRange {
{ return (!m_ranged || (m_lo==0 && m_hi>=1 && !m_littleEndian)); }
void dump(ostream& str) const { if (ranged()) str<<"["<<left()<<":"<<right()<<"]"; else str<<"[norg]"; }
};
inline ostream& operator<<(ostream& os, VNumRange rhs) { rhs.dump(os); return os; }
inline ostream& operator<<(ostream& os, const VNumRange& rhs) { rhs.dump(os); return os; }
//######################################################################
@@ -709,7 +709,7 @@ struct VBasicTypeKey {
if (!(m_nrange == rhs.m_nrange)) return false; // lhs > rhs
return false; }
VBasicTypeKey(int width, int widthMin, AstNumeric numeric, AstBasicDTypeKwd kwd,
VNumRange nrange)
const VNumRange& nrange)
: m_width(width), m_widthMin(widthMin), m_numeric(numeric),
m_keyword(kwd), m_nrange(nrange) {}
~VBasicTypeKey() {}
@@ -733,8 +733,9 @@ class VNUser {
} m_u;
public:
VNUser() {}
// non-explicit:
VNUser(int i) { m_u.up = 0; m_u.ui = i; }
VNUser(void* p) { m_u.up = p; }
explicit VNUser(void* p) { m_u.up = p; }
~VNUser() {}
// Casters
WidthVP* c() { return ((WidthVP*)m_u.up); }
@@ -891,7 +892,7 @@ public:
AstNode* oldp() const { return m_oldp; }
void dump(ostream& str=cout) const;
};
inline ostream& operator<<(ostream& os, AstNRelinker& rhs) { rhs.dump(os); return os;}
inline ostream& operator<<(ostream& os, const AstNRelinker& rhs) { rhs.dump(os); return os;}
//######################################################################
// V3Hash -- Node hashing for V3Combine
@@ -903,7 +904,8 @@ class V3Hash {
uint32_t m_both;
static const uint32_t M24 = ((1<<24)-1);
void setBoth(uint32_t depth, uint32_t hshval) {
if (depth==0) depth=1; if (depth>255) depth=255;
if (depth==0) depth=1;
if (depth>255) depth=255;
m_both = (depth<<24) | (hshval & M24);
}
public:
@@ -940,7 +942,7 @@ public:
V3Hash(V3Hash h1, V3Hash h2, V3Hash h3, V3Hash h4) {
setBoth(1,((h1.hshval()*31+h2.hshval())*31+h3.hshval())*31+h4.hshval()); }
};
ostream& operator<<(ostream& os, V3Hash rhs);
ostream& operator<<(ostream& os, const V3Hash& rhs);
//######################################################################
// AstNode -- Base type of all Ast types
@@ -1230,6 +1232,7 @@ public:
// METHODS - dump and error
void v3errorEnd(ostringstream& str) const;
void v3errorEndFatal(ostringstream& str) const VL_ATTR_NORETURN;
string warnMore() const;
virtual void dump(ostream& str=cout);
void dumpGdb(); // For GDB only
@@ -1509,6 +1512,7 @@ public:
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode*) const { return true; }
virtual string verilogKwd() const { return "="; }
virtual bool brokeLhsMustBeLvalue() const = 0;
};
class AstNodeFor : public AstNodeStmt {
+12 -5
View File
@@ -121,7 +121,7 @@ public:
m_littleEndian = false;
setOp2p(new AstConst(fl,msb)); setOp3p(new AstConst(fl,lsb));
}
AstRange(FileLine* fl, VNumRange range)
AstRange(FileLine* fl, const VNumRange& range)
:AstNode(fl) {
m_littleEndian = range.littleEndian();
setOp2p(new AstConst(fl,range.hi())); setOp3p(new AstConst(fl,range.lo()));
@@ -743,7 +743,7 @@ class AstParseTypeDType : public AstNodeDType {
// During parsing, this indicates the type of a parameter is a "parameter type"
// e.g. the data type is a container of any data type
public:
AstParseTypeDType(FileLine* fl)
explicit AstParseTypeDType(FileLine* fl)
: AstNodeDType(fl) {}
ASTNODE_NODE_FUNCS(ParseTypeDType)
AstNodeDType* dtypep() const { return NULL; }
@@ -1655,7 +1655,7 @@ private:
string m_name; // Cell name
public:
AstCellRef(FileLine* fl,
string name, AstNode* cellp, AstNode* exprp)
const string& name, AstNode* cellp, AstNode* exprp)
: AstNode(fl)
, m_name(name) {
addNOp1p(cellp); addNOp2p(exprp); }
@@ -1672,7 +1672,7 @@ private:
string m_name; // Array name
public:
AstCellArrayRef(FileLine* fl,
string name, AstNode* selectExprp)
const string& name, AstNode* selectExprp)
: AstNode(fl)
, m_name(name) {
addNOp1p(selectExprp); }
@@ -1688,7 +1688,7 @@ private:
string m_name; // Var name
public:
AstUnlinkedRef(FileLine* fl,
AstNode* refp, string name, AstNode* crp)
AstNode* refp, const string& name, AstNode* crp)
: AstNode(fl)
, m_name(name) {
addNOp1p(refp); addNOp2p(crp); }
@@ -2039,6 +2039,7 @@ public:
}
ASTNODE_NODE_FUNCS(Assign)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssign(this->fileline(), lhsp, rhsp); }
virtual bool brokeLhsMustBeLvalue() const { return true; }
};
class AstAssignAlias : public AstNodeAssign {
@@ -2049,6 +2050,7 @@ public:
: AstNodeAssign(fileline, lhsp, rhsp) {}
ASTNODE_NODE_FUNCS(AssignAlias)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { V3ERROR_NA; return NULL; }
virtual bool brokeLhsMustBeLvalue() const { return false; }
};
class AstAssignDly : public AstNodeAssign {
@@ -2059,6 +2061,7 @@ public:
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignDly(this->fileline(), lhsp, rhsp); }
virtual bool isGateOptimizable() const { return false; }
virtual string verilogKwd() const { return "<="; }
virtual bool brokeLhsMustBeLvalue() const { return true; }
};
class AstAssignW : public AstNodeAssign {
@@ -2068,6 +2071,7 @@ public:
: AstNodeAssign(fileline, lhsp, rhsp) { }
ASTNODE_NODE_FUNCS(AssignW)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignW(this->fileline(), lhsp, rhsp); }
virtual bool brokeLhsMustBeLvalue() const { return true; }
AstAlways* convertToAlways() {
AstNode* lhs1p = lhsp()->unlinkFrBack();
AstNode* rhs1p = rhsp()->unlinkFrBack();
@@ -2087,6 +2091,7 @@ public:
}
ASTNODE_NODE_FUNCS(AssignVarScope)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignVarScope(this->fileline(), lhsp, rhsp); }
virtual bool brokeLhsMustBeLvalue() const { return false; }
};
class AstPull : public AstNode {
@@ -2113,6 +2118,7 @@ public:
: AstNodeAssign(fileline, lhsp, rhsp) {}
ASTNODE_NODE_FUNCS(AssignPre)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignPre(this->fileline(), lhsp, rhsp); }
virtual bool brokeLhsMustBeLvalue() const { return true; }
};
class AstAssignPost : public AstNodeAssign {
@@ -2122,6 +2128,7 @@ public:
: AstNodeAssign(fileline, lhsp, rhsp) {}
ASTNODE_NODE_FUNCS(AssignPost)
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignPost(this->fileline(), lhsp, rhsp); }
virtual bool brokeLhsMustBeLvalue() const { return true; }
};
class AstComment : public AstNodeStmt {
+9
View File
@@ -236,6 +236,15 @@ private:
nodep->iterateChildrenConst(*this);
BrokenTable::setUnder(nodep,false);
}
virtual void visit(AstNodeAssign* nodep) {
processAndIterate(nodep);
if (v3Global.assertDTypesResolved()
&& nodep->brokeLhsMustBeLvalue()
&& nodep->lhsp()->castNodeVarRef()
&& !nodep->lhsp()->castNodeVarRef()->lvalue()) {
nodep->v3fatalSrc("Assignment LHS is not an lvalue");
}
}
virtual void visit(AstNode* nodep) {
processAndIterate(nodep);
}
+1
View File
@@ -94,6 +94,7 @@ public:
m_funcp = m_tlFuncp;
m_modp->addStmtp(m_tlFuncp);
}
~V3CCtorsVisitor() {}
};
//######################################################################
+1 -1
View File
@@ -423,7 +423,7 @@ private:
// Handle any assertions
replaceCaseParallel(nodep, false);
// Replace the CASE... with IF...
if (debug()>=9) grouprootp->dumpTree(cout," _new: ");
if (debug()>=9 && grouprootp) grouprootp->dumpTree(cout," _new: ");
if (grouprootp) nodep->replaceWith(grouprootp);
else nodep->unlinkFrBack();
nodep->deleteTree(); VL_DANGLING(nodep);
+2 -2
View File
@@ -591,14 +591,14 @@ private:
vertexp->dstDomainp(senoutp);
if (debug()>=9) {
UINFO(9,spaces(level)+" Tracedst "<<vertexp);
if (senoutp) V3EmitV::verilogForTree(senoutp, cout); cout<<endl;
if (senoutp) { V3EmitV::verilogForTree(senoutp, cout); cout<<endl; }
}
} else {
vertexp->srcDomainSet(true); // Note it's set - domainp may be null, so can't use that
vertexp->srcDomainp(senoutp);
if (debug()>=9) {
UINFO(9,spaces(level)+" Tracesrc "<<vertexp);
if (senoutp) V3EmitV::verilogForTree(senoutp, cout); cout<<endl;
if (senoutp) { V3EmitV::verilogForTree(senoutp, cout); cout<<endl; }
}
}
}
+2 -1
View File
@@ -611,7 +611,8 @@ class GaterVisitor : public GaterBaseVisitor {
// Edges from IFs represent a real IF branch in the equation tree
//UINFO(9," ifver "<<(void*)(edgep)<<" cc"<<edgep->dotColor()<<endl);
eqnp = cVxp->nodep()->condp()->cloneTree(true);
if (eqnp && cedgep->ifelseFalse()) {
if (!eqnp) cVxp->nodep()->v3fatalSrc("null condition");
if (cedgep->ifelseFalse()) {
eqnp = new AstNot(eqnp->fileline(),eqnp);
}
// We need to AND this term onto whatever was found below it
+1 -1
View File
@@ -104,7 +104,7 @@ class V3ConfigIgnores {
public:
inline static V3ConfigIgnores& singleton() { return s_singleton; }
void addIgnore(V3ErrorCode code, string wildname, int lineno, bool on) {
void addIgnore(V3ErrorCode code, const string& wildname, int lineno, bool on) {
// Insert
IgnLines* linesp = findWilds(wildname);
UINFO(9,"config addIgnore "<<wildname<<":"<<lineno<<", "<<code<<", "<<on<<endl);
+1
View File
@@ -1374,6 +1374,7 @@ private:
AstNode* fromp = repp->lhsp()->unlinkFrBack();
AstConst* lsbp = nodep->lsbp()->castConst();
AstNode* widthp = nodep->widthp()->unlinkFrBack();
if (!fromp->width()) nodep->v3fatalSrc("Not widthed");
AstSel* newp = new AstSel(nodep->fileline(),
fromp,
new AstConst(lsbp->fileline(), lsbp->toUInt() % fromp->width()),
+1 -1
View File
@@ -158,7 +158,7 @@ private:
if (oldactivep->sensesp() != m_activep->sensesp()) {
if (!varrefp->varp()->fileline()->warnIsOff(V3ErrorCode::MULTIDRIVEN)
&& !varrefp->varp()->user2()) {
varrefp->varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks: "<<varrefp->varp()->prettyName()<<endl
varrefp->varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks with different clocking: "<<varrefp->varp()->prettyName()<<endl
<<varrefp->warnMore()<<"... Location of first driving block"<<endl
<<oldactivep->warnMore()<<"... Location of other driving block");
varrefp->varp()->user2(true);
+3 -2
View File
@@ -138,8 +138,9 @@ private:
for (AstNode* stmtp = newfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (portp->isIO() && !portp->isFuncReturn()) {
argsp = argsp->addNextNull(new AstVarRef(portp->fileline(), portp,
portp->isOutput()));
AstNode* newp = new AstVarRef(portp->fileline(), portp, portp->isOutput());
if (argsp) argsp = argsp->addNextNull(newp);
else argsp = newp;
}
}
}
+2 -3
View File
@@ -69,7 +69,7 @@ public:
const string& vformat, AstNode* exprsp, bool isScan);
void displayEmit(AstNode* nodep, bool isScan);
void displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
string vfmt, char fmtLetter);
const string& vfmt, char fmtLetter);
void emitVarDecl(AstVar* nodep, const string& prefixIfImp);
typedef enum {EVL_IO, EVL_SIG, EVL_TEMP, EVL_PAR, EVL_ALL} EisWhich;
@@ -1237,7 +1237,6 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
if (dispp) {}
puts("VL_SFORMATF_NX(");
} else {
isStmt = true;
nodep->v3fatalSrc("Unknown displayEmit node type");
}
ofp()->putsQuoted(emitDispState.m_format);
@@ -1269,7 +1268,7 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
}
void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
string vfmt, char fmtLetter) {
const string& vfmt, char fmtLetter) {
// Print display argument, edits elistp
AstNode* argp = *elistp;
if (!argp) {
+1 -1
View File
@@ -106,7 +106,7 @@ public:
}
else {
for (AstCFile* nodep = v3Global.rootp()->filesp(); nodep; nodep=nodep->nextp()->castCFile()) {
if (nodep->source() && nodep->slow()==slow && nodep->support()==support) {
if (nodep->source() && nodep->slow()==(slow!=0) && nodep->support()==(support!=0)) {
putMakeClassEntry(of, nodep->name());
}
}
+9 -5
View File
@@ -29,6 +29,7 @@
#include <map>
#include <set>
#include <deque>
#include <cassert>
//######################################################################
@@ -253,18 +254,21 @@ class V3Error {
// Global versions, so that if the class doesn't define a operator, we get the functions anyways.
inline int debug() { return V3Error::debugDefault(); }
inline void v3errorEnd(ostringstream& sstr) { V3Error::v3errorEnd(sstr); }
inline void v3errorEndFatal(ostringstream& sstr) VL_ATTR_NORETURN;
inline void v3errorEndFatal(ostringstream& sstr) { V3Error::v3errorEnd(sstr); assert(0); }
// Theses allow errors using << operators: v3error("foo"<<"bar");
// Careful, you can't put () around msg, as you would in most macro definitions
// Note the commas are the comma operator, not separating arguments. These are needed to insure
// evaluation order as otherwise we couldn't insure v3errorPrep is called first.
#define v3warnCode(code,msg) v3errorEnd((V3Error::v3errorPrep(code), (V3Error::v3errorStr()<<msg), V3Error::v3errorStr()));
#define v3warn(code,msg) v3warnCode(V3ErrorCode::code,msg)
#define v3info(msg) v3warn(EC_INFO,msg)
#define v3fatal(msg) v3warn(EC_FATAL,msg)
#define v3error(msg) v3warn(EC_ERROR,msg)
#define v3warnCodeFatal(code,msg) v3errorEndFatal((V3Error::v3errorPrep(code), (V3Error::v3errorStr()<<msg), V3Error::v3errorStr()));
#define v3warn(code,msg) v3warnCode(V3ErrorCode::code, msg)
#define v3info(msg) v3warnCode(V3ErrorCode::EC_INFO, msg)
#define v3error(msg) v3warnCode(V3ErrorCode::EC_ERROR, msg)
#define v3fatal(msg) v3warnCodeFatal(V3ErrorCode::EC_FATAL, msg)
// Use this instead of fatal() to mention the source code line.
#define v3fatalSrc(msg) v3warn(EC_FATALSRC,__FILE__<<":"<<dec<<__LINE__<<": "<<msg)
#define v3fatalSrc(msg) v3warnCodeFatal(V3ErrorCode::EC_FATALSRC, __FILE__<<":"<<dec<<__LINE__<<": "<<msg)
#define UINFO(level,stmsg) {if(VL_UNLIKELY(debug()>=(level))) { cout<<"- "<<V3Error::lineStr(__FILE__,__LINE__)<<stmsg; }}
#define UINFONL(level,stmsg) {if(VL_UNLIKELY(debug()>=(level))) { cout<<stmsg; } }
+3
View File
@@ -161,6 +161,7 @@ public:
// OPERATORS
void v3errorEnd(ostringstream& str);
void v3errorEndFatal(ostringstream& str) VL_ATTR_NORETURN;
string warnMore() const;
inline bool operator==(FileLine rhs) const {
return (m_lineno==rhs.m_lineno && m_filenameno==rhs.m_filenameno && m_warnOn==rhs.m_warnOn);
@@ -168,4 +169,6 @@ public:
};
ostream& operator<<(ostream& os, FileLine* fileline);
inline void FileLine::v3errorEndFatal(ostringstream& str) { v3errorEnd(str); assert(0); }
#endif // Guard
+1 -1
View File
@@ -1409,7 +1409,7 @@ private:
}
public:
GateClkDecompGraphVisitor(V3Graph* graphp) {
explicit GateClkDecompGraphVisitor(V3Graph* graphp) {
m_graphp = graphp;
m_seen_clk_vectors = 0;
m_clk_vsp = NULL;
+1 -1
View File
@@ -124,7 +124,7 @@ public:
static DfaInput EPSILON() { return VNUser::fromInt(0); }
static DfaInput NA() { return VNUser::fromInt(1); } // as in not-applicable
// CONSTRUCTORS
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, DfaInput input)
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, const DfaInput& input)
: V3GraphEdge(graphp, fromp, top, 1)
, m_input(input), m_complement(false) {}
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, const DfaEdge* copyfrom)
+3 -3
View File
@@ -72,7 +72,7 @@ public:
class V3GraphTestVertex : public V3GraphVertex {
string m_name;
public:
V3GraphTestVertex(V3Graph* graphp, string name) : V3GraphVertex(graphp), m_name(name) {}
V3GraphTestVertex(V3Graph* graphp, const string& name) : V3GraphVertex(graphp), m_name(name) {}
virtual ~V3GraphTestVertex() {}
// Accessors
virtual string name() const { return m_name; }
@@ -80,7 +80,7 @@ public:
class V3GraphTestVarVertex : public V3GraphTestVertex {
public:
V3GraphTestVarVertex(V3Graph* graphp, string name) : V3GraphTestVertex(graphp, name) {}
V3GraphTestVarVertex(V3Graph* graphp, const string& name) : V3GraphTestVertex(graphp, name) {}
virtual ~V3GraphTestVarVertex() {}
// Accessors
virtual string dotColor() const { return "blue"; }
@@ -270,7 +270,7 @@ public:
class DfaTestVertex : public DfaVertex {
string m_name;
public:
DfaTestVertex(DfaGraph* graphp, string name) : DfaVertex(graphp), m_name(name) {}
DfaTestVertex(DfaGraph* graphp, const string& name) : DfaVertex(graphp), m_name(name) {}
virtual ~DfaTestVertex() {}
// Accessors
virtual string name() const { return m_name; }
+3 -1
View File
@@ -131,7 +131,9 @@ private:
AstNode* valuep = NULL;
if (nodep->valuep()) valuep = new AstAdd(nodep->fileline(), nodep->valuep()->cloneTree(true),
new AstConst(nodep->fileline(), AstConst::Unsized32(), offset_from_init));
addp = addp->addNextNull(new AstEnumItem(nodep->fileline(), name, NULL, valuep));
AstNode* newp = new AstEnumItem(nodep->fileline(), name, NULL, valuep);
if (addp) addp = addp->addNextNull(newp);
else addp = newp;
}
nodep->replaceWith(addp);
nodep->deleteTree();
+1 -1
View File
@@ -71,7 +71,7 @@ V3Number::V3Number (FileLine* fileline, const char* sourcep) {
if (*cp != '_') *wp++ = *cp;
}
*wp++ = '\0';
while (*cp && *cp == '_') cp++;
while (*cp == '_') cp++;
if (*cp && tolower(*cp)=='s') {
cp++; isSigned(true);
}
+1 -1
View File
@@ -327,6 +327,6 @@ public:
V3Number& opLtN (const V3Number& lhs, const V3Number& rhs);
V3Number& opLteN (const V3Number& lhs, const V3Number& rhs);
};
inline ostream& operator<<(ostream& os, V3Number rhs) { return os<<rhs.ascii(); }
inline ostream& operator<<(ostream& os, const V3Number& rhs) { return os<<rhs.ascii(); }
#endif // Guard
+1 -1
View File
@@ -32,7 +32,7 @@
#include <algorithm>
#include "V3Number.h"
void test(string lhss, string op, string rhss, string exps) {
void test(const string& lhss, const string& op, const string& rhss, const string& exps) {
char* l1 = strdup(lhss.c_str());
char* r1 = strdup(rhss.c_str());
char* e1 = strdup(exps.c_str());
+2 -1
View File
@@ -559,8 +559,9 @@ string V3Options::version() {
}
void V3Options::throwSigsegv() {
// cppcheck-suppress nullPointer
#if !(defined(VL_CPPCHECK) || defined(__clang_analyzer__))
char* zp=NULL; *zp=0; // Intentional core dump, ignore warnings here
#endif
}
//######################################################################
+1
View File
@@ -1188,6 +1188,7 @@ int V3PreProcImp::getStateToken() {
}
else if (tok==VP_EOF) {
error("`\" not terminated at EOF\n");
break;
}
else if (tok==VP_BACKQUOTE) {
m_strify += "\\\"";
+2 -2
View File
@@ -90,8 +90,8 @@ public:
virtual string removeDefines(const string& text)=0; // Remove defines in a text string
// UTILITIES
void error(string msg) { fileline()->v3error(msg); } ///< Report a error
void fatal(string msg) { fileline()->v3fatalSrc(msg); } ///< Report a fatal error
void error(const string& msg) { fileline()->v3error(msg); } ///< Report a error
void fatal(const string& msg) { fileline()->v3fatalSrc(msg); } ///< Report a fatal error
protected:
// CONSTUCTORS
+2 -1
View File
@@ -411,7 +411,8 @@ private:
UINFO(6, " Color="<<color<<" New order: "<<nextp<<endl);
if (nextp == nodep && !splitAlwaysp) nodep->unlinkFrBack(&replaceHandle);
else nextp->unlinkFrBack();
newListp = newListp->addNext(nextp);
if (newListp) newListp = newListp->addNext(nextp);
else newListp = nextp;
}
if (splitAlwaysp) {
++m_statSplits;
+4 -2
View File
@@ -357,7 +357,7 @@ private:
return newvscp;
}
AstNode* createInlinedFTask(AstNodeFTaskRef* refp, string namePrefix, AstVarScope* outvscp) {
AstNode* createInlinedFTask(AstNodeFTaskRef* refp, const string& namePrefix, AstVarScope* outvscp) {
// outvscp is the variable for functions only, if NULL, it's a task
if (!refp->taskp()) refp->v3fatalSrc("Unlinked?");
AstNode* newbodysp = refp->taskp()->stmtsp()->cloneTree(true); // Maybe NULL
@@ -463,7 +463,7 @@ private:
return beginp;
}
AstNode* createNonInlinedFTask(AstNodeFTaskRef* refp, string namePrefix, AstVarScope* outvscp) {
AstNode* createNonInlinedFTask(AstNodeFTaskRef* refp, const string& namePrefix, AstVarScope* outvscp) {
// outvscp is the variable for functions only, if NULL, it's a task
if (!refp->taskp()) refp->v3fatalSrc("Unlinked?");
AstCFunc* cfuncp = m_statep->ftaskCFuncp(refp->taskp());
@@ -938,6 +938,8 @@ private:
if (!portp->basicp() || portp->basicp()->keyword().isDpiUnsupported()) {
portp->v3error("Unsupported: DPI argument of type "<<portp->basicp()->prettyTypeName()<<endl
<<portp->warnMore()<<"... For best portability, use bit, byte, int, or longint");
// We don't warn on logic either, although the 4-stateness is lost.
// That's what other simulators do.
}
}
} else {
+2 -1
View File
@@ -1074,7 +1074,8 @@ class TristateVisitor : public TristateBaseVisitor {
UINFO(5,"Unconnected pin terminate "<<nodep<<endl);
AstVar* ucVarp = getCreateUnconnVarp(nodep, nodep->modVarp()->dtypep());
nodep->exprp(new AstVarRef(nodep->fileline(), ucVarp,
nodep->modVarp()->isOutput()));
// We converted, so use declaration output state
nodep->modVarp()->isDeclOutput()));
m_tgraph.setTristate(ucVarp);
// We don't need a driver on the wire; the lack of one will default to tristate
} else if (inDeclProcessing) { // Not an input that was a converted tristate
+1 -1
View File
@@ -154,7 +154,7 @@ private:
return newp;
}
AstNode* newSubLsbOf(AstNode* underp, VNumRange fromRange) {
AstNode* newSubLsbOf(AstNode* underp, const VNumRange& fromRange) {
// Account for a variable's LSB in bit selections
// Will likely become SUB(underp, lsb_of_signal)
// Don't report WIDTH warnings etc here, as may be inside a generate branch that will be deleted
+1 -1
View File
@@ -106,7 +106,7 @@ AstNetlist* V3Global::makeNetlist() {
void V3Global::checkTree() { rootp()->checkTree(); }
void V3Global::clear() {
if (m_rootp) m_rootp->deleteTree(); m_rootp=NULL;
if (m_rootp) { m_rootp->deleteTree(); m_rootp=NULL; }
}
void V3Global::readFiles() {
+3 -2
View File
@@ -44,8 +44,9 @@ private:
if (m_dataSize<point) m_dataSize=(point+64) & ~63ULL; // Keep power of two
m_dataSize *= 2;
//UINFO(9, "Realloc "<<allocSize()<<" for "<<point<<" "<<(void*)(m_datap)<<endl);
m_datap = (vluint64_t*)realloc(m_datap, allocSize());
if (!m_datap) {v3fatal("Out of memory increasing buckets"); }
vluint64_t* newp = (vluint64_t*)realloc(m_datap, allocSize());
if (!newp) { free(m_datap); v3fatal("Out of memory increasing buckets"); }
m_datap = newp;
for (vluint64_t i=oldsize; i<m_dataSize; i+=64) m_datap[i/64] = 0;
}
+29 -2
View File
@@ -52,14 +52,19 @@ sub process {
$fh or die "%Error: '$cmd' failed: $!\n";
my %uniq;
my %errs;
my $last_error = "";
while (defined(my $line = $fh->getline())) {
$line =~ s/^\s+//;
$line =~ s/Checking usage of global functions\.+//; # Sometimes tacked at end-of-line
# General gunk
next if $uniq{$line}++;
next if $line =~ m!^<\?xml version!;
next if $line =~ m!^<results>!;
next if $line =~ m!^<cppcheck!;
next if $line =~ m!^<results!;
next if $line =~ m!^</results>!;
next if $line =~ m!^<errors!;
next if $line =~ m!^</error>!;
next if $line =~ m!^</errors>!;
next if $line =~ m!^<error.*id="unmatchedSuppression"!; # --suppress=unmatchedSuppression doesn't work
next if $line =~ m!Cppcheck cannot find all the include files!; # An earlier id line is more specific
next if $line =~ m!^Checking !;
@@ -80,10 +85,32 @@ sub process {
print $line;
} else {
my $suppress;
# --xml-format=1
if ($line =~ /file="([^"]+)"\s+line="(\d+)"\s+id="([^"]+)"/) {
my $file = $1; my $linenum = $2; my $id = $3;
$suppress = 1 if _suppress($file,$linenum,$id);
}
# --xml-format=2
if ($line =~ /<error id.*/) {
$last_error = $line;
chomp $last_error;
$suppress = 1;
}
elsif ($line =~ /<location.* file="([^"]+)"\s+line="(\d+)"/) {
my $file = $1; my $linenum = $2; my $id;
if ($last_error =~ / id="([^"]+)"/) {
$id = $1;
} else {
$id = "?";
}
$suppress = 1 if _suppress($file,$linenum,$id);
$suppress = 1 if $file eq "*";
if (!$suppress) {
chomp $line;
print "$file:$linenum: ".$last_error."\n";
$suppress = 1;
}
}
if (!$suppress) {
my $eline = "%Error: cppcheck: $line";
print $eline;
@@ -122,7 +149,7 @@ sub _suppress {
my $supids = $1;
foreach my $supid (split /\s+/, $supids) {
if ($supid eq $id
|| $supid eq $SuppressMap{$id}) {
|| $supid eq ($SuppressMap{$id}||'')) {
return 1;
}
}
+1
View File
@@ -18,6 +18,7 @@ use Data::Dumper; $Data::Dumper::Sortkeys=1;
use strict;
use vars qw ($Debug %Vars $Driver $Fork);
use POSIX qw(strftime);
use lib ".";
$::Driver = 1;
$::Have_Forker = 0;
+15
View File
@@ -21,6 +21,9 @@ module t (/*AUTOARG*/
);
input clk;
typedef struct packed { bit [47:0] lo; bit [47:0] hi; } str_t;
typedef struct packed { int a; int b; } substr_t;
// Allowed import return types:
// void, byte, shortint, int, longint, real, shortreal, chandle, and string
// Scalar bit and logic
@@ -53,6 +56,8 @@ module t (/*AUTOARG*/
import "DPI-C" pure function void dpii_v_byte (input byte i, output byte o);
import "DPI-C" pure function void dpii_v_shortint (input shortint i, output shortint o);
import "DPI-C" pure function void dpii_v_longint (input longint i, output longint o);
import "DPI-C" pure function void dpii_v_struct (input str_t i, output str_t o);
import "DPI-C" pure function void dpii_v_substruct(input substr_t i, output int o);
import "DPI-C" pure function void dpii_v_chandle (input chandle i, output chandle o);
import "DPI-C" pure function void dpii_v_string (input string i, output string o);
import "DPI-C" pure function void dpii_v_real (input real i, output real o);
@@ -96,6 +101,9 @@ module t (/*AUTOARG*/
byte i_y, o_y;
shortint i_s, o_s;
longint i_l, o_l;
str_t i_t, o_t;
substr_t i_ss;
int o_ss;
int unsigned i_iu, o_iu;
shortint unsigned i_su, o_su;
longint unsigned i_lu, o_lu;
@@ -133,7 +141,12 @@ module t (/*AUTOARG*/
i_su= {1'b1,wide[16-2:0]};
i_l = {1'b1,wide[64-2:0]};
i_lu= {1'b1,wide[64-2:0]};
i_t = {1'b1,wide[95-1:0]};
i_d = 32.1;
i_ss.a = 32'h054321ab;
i_ss.b = 32'h05a43b21;
`ifndef NO_SHORTREAL
i_f = 30.2;
`endif
@@ -173,6 +186,8 @@ module t (/*AUTOARG*/
dpii_v_uint (i_iu,o_iu); if (o_iu !== ~i_iu) $stop;
dpii_v_ushort (i_su,o_su); if (o_su !== ~i_su) $stop;
dpii_v_ulong (i_lu,o_lu); if (o_lu !== ~i_lu) $stop;
dpii_v_struct (i_t,o_t); if (o_t !== ~i_t) $stop;
dpii_v_substruct(i_ss,o_ss); if (o_ss !== i_ss.a - i_ss.b) $stop;
dpii_v_chandle (i_c,o_c); if (o_c !== i_c) $stop;
dpii_v_string (i_n,o_n); if (o_n != i_n) $stop;
dpii_v_real (i_d,o_d); if (o_d != i_d+1.5) $stop;
+27 -2
View File
@@ -29,8 +29,12 @@
# error "Unknown simulator for DPI test"
#endif
typedef struct { int a; int b; } substruct_t;
#ifdef NEED_EXTERNS
extern "C" {
// If get ncsim: *F,NOFDPI: Function {foo} not found in default libdpi.
// Then probably forgot to list a function here.
extern unsigned char dpii_f_bit (unsigned char i);
extern svBitVecVal dpii_f_bit8 (const svBitVecVal* i);
@@ -58,18 +62,26 @@ extern "C" {
extern void dpii_v_ushort (unsigned short i, unsigned short *o);
extern void dpii_v_longint (long long i, long long *o);
extern void dpii_v_ulong (unsigned long long i, unsigned long long *o);
extern void dpii_v_struct (const svBitVecVal* i, svBitVecVal* o);
extern void dpii_v_substruct (const svBitVecVal* i, int* o);
extern void dpii_v_chandle (void* i, void* *o);
extern void dpii_v_string (const char* i, const char** o);
extern void dpii_v_real (double i, double* o);
extern void dpii_v_shortreal(float i, float* o);
extern void dpii_v_struct (const svBitVecVal* i, svBitVecVal* o);
extern void dpii_v_substruct (const svBitVecVal* i, int* o);
extern void dpii_v_bit64(const svBitVecVal* i, svBitVecVal* o);
extern void dpii_v_bit95(const svBitVecVal* i, svBitVecVal* o);
extern void dpii_v_bit96(const svBitVecVal* i, svBitVecVal* o);
extern int dpii_f_strlen (const char* i);
extern void dpii_f_void ();
extern int dpii_t_void ();
extern int dpii_t_void_context ();
extern int dpii_t_int (int i, int *o);
extern int dpii_f_strlen (const char* i);
extern int dpii_fa_bit(int i);
}
#endif
@@ -107,6 +119,19 @@ void dpii_v_string (const char* i, const char** o) { *o = i; }
void dpii_v_real (double i, double* o) { *o = i + 1.5; }
void dpii_v_shortreal(float i, float* o) { *o = i + 1.5; }
void dpii_v_struct (const svBitVecVal* i, svBitVecVal* o) {
o[0] = ~i[0];
o[1] = ~i[1];
o[2] = ~i[2];
o[3] = ~i[3];
o[4] = ~i[4];
}
void dpii_v_substruct (const svBitVecVal* i, int* o) {
// To be most like other tools, this should automagically take the substruct_t
// as an argument, and not require this cast...
substruct_t* issp = (substruct_t*) i;
o[0] = issp->b - issp->a;
}
void dpii_v_bit64(const svBitVecVal* i, svBitVecVal* o) {
o[0] = ~i[0];
o[1] = ~i[1];
+2 -2
View File
@@ -7,8 +7,8 @@
module t ();
// Can't handle logic (yet?)
import "DPI-C" dpii_fa_bit = function int oth_f_int1(input logic [2:0] i);
// Can't handle time (yet?)
import "DPI-C" dpii_fa_bit = function int oth_f_int1(input time i);
initial begin
$stop;
+2 -2
View File
@@ -16,11 +16,11 @@ compile (
make_top_shell => 0,
make_main => 0,
expect=>
'%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: Signal has multiple driving blocks: t.mem
'%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: Signal has multiple driving blocks with different clocking: t.mem
%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of first driving block
%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of other driving block
%Warning-MULTIDRIVEN: Use ".*" and lint_on around source to disable this message.
%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: Signal has multiple driving blocks: out2
%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: Signal has multiple driving blocks with different clocking: out2
%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of first driving block
%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of other driving block
%Error: Exiting due to.*',
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+46
View File
@@ -0,0 +1,46 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2017 by Wilson Snyder.
module t (/*AUTOARG*/
// Outputs
i65, j65, i33, j33, i30, j30, q65, r65, q33, r33, q30, r30, w65, x65, w33,
x33, w30, x30,
// Inputs
a, a40, a70
);
input [3:0] a;
input [39:0] a40;
input [69:0] a70;
// -- Verilator 621c515 creates code that uses the undeclared function VL_POW_WWI()
// verilator lint_off WIDTH
output [3:0] i65 = 65'd3 ** a; // WWI
output [3:0] j65 = a ** 65'd3; // IIW
output [3:0] i33 = 33'd3 ** a; // QQI
output [3:0] j33 = a ** 33'd3; // IIQ
output [3:0] i30 = 30'd3 ** a; // III
output [3:0] j30 = a ** 30'd3; // III
output [39:0] q65 = 65'd3 ** a40; // WWQ
output [39:0] r65 = a40 ** 65'd3; // WWQ
output [39:0] q33 = 33'd3 ** a40; // QQQ
output [39:0] r33 = a40 ** 33'd3; // QQQ
output [39:0] q30 = 30'd3 ** a40; // QQI
output [39:0] r30 = a40 ** 30'd3; // QQI
output [69:0] w65 = 65'd3 ** a70; // WWW
output [69:0] x65 = a70 ** 65'd3; // WWW
output [69:0] w33 = 33'd3 ** a70; // WWW
output [69:0] x33 = a70 ** 33'd3; // WWW
output [69:0] w30 = 30'd3 ** a70; // WWW
output [69:0] x30 = a70 ** 30'd3; // WWW
// verilator lint_on WIDTH
initial begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+2
View File
@@ -39,6 +39,8 @@ int main(int argc, char **argv, char **env) {
top->clk = ~top->clk;
top->eval();
tfp->dump((unsigned int)(main_time));
// Advance by 0.5 time units, to make sure our fractional
// time is working correctly
main_time += VL_TIME_MULTIPLIER/2;
}
tfp->close();
+15
View File
@@ -0,0 +1,15 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# Compile only test
compile (
);
ok(1);
1;
+78
View File
@@ -0,0 +1,78 @@
// DESCRIPTION: Verilator: Unsupported tristate constructur error
//
// This is a compile only regression test of tristate handling for bug514
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2017 by Rob Stoddard.
module t (/*AUTOARG*/
// Outputs
out,
// Inputs
data, up_down, clk, reset
);
//----------Output Ports--------------
output [7:0] out;
//------------Input Ports--------------
//input [7:0] data ;
input [7:0] data;
input up_down, clk, reset;
//------------Internal Variables--------
reg [7:0] out;
logic [7:0] q_out;
//-------------Code Starts Here-------
always @(posedge clk)
if (reset) begin // active high reset
out <= 8'b0 ;
end else if (up_down) begin
out <= out + 1;
end else begin
out <= q_out;
end
// verilator lint_off PINMISSING
sub_mod sub_mod
(
.clk(clk),
.data(data),
.reset(reset),
.q(q_out)
);
// verilator lint_on PINMISSING
endmodule
module sub_mod (/*AUTOARG*/
// Outputs
q, test_out,
// Inouts
test_inout,
// Inputs
data, clk, reset
);
//-----------Input Ports---------------
input [7:0] data /*verilator public*/;
input clk, reset;
inout test_inout; // Get rid of this, the problem goes away.
//-----------Output Ports---------------
output [7:0] q;
output test_out; // Not assigned, no problem.
logic [7:0] que;
// Uncomment this line, the error goes away.
//assign test_inout = que;
assign q = que;
always @ ( posedge clk)
if (~reset) begin
que <= 8'b0;
end else begin
que <= data;
end
endmodule