mirror of
https://github.com/verilator/verilator.git
synced 2026-10-03 16:44:11 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42d2cbad41 | ||
|
|
cb82c42e35 | ||
|
|
f13fb330ed | ||
|
|
d4bae48ca2 | ||
|
|
590ad964b1 | ||
|
|
d4595df8a4 | ||
|
|
7b642bcbb4 | ||
|
|
ca26596695 | ||
|
|
88cf5e5d98 | ||
|
|
13f790360d | ||
|
|
70daadf987 | ||
|
|
9d5004db1c | ||
|
|
ea82bfcced | ||
|
|
00a502942e | ||
|
|
2031bc7fc4 | ||
|
|
3adb22e971 | ||
|
|
331ea5116f |
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ public:
|
||||
m_funcp = m_tlFuncp;
|
||||
m_modp->addStmtp(m_tlFuncp);
|
||||
}
|
||||
~V3CCtorsVisitor() {}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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; } }
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.*',
|
||||
|
||||
Executable
+18
@@ -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;
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
Executable
+15
@@ -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;
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user