Add verilated asserts that VL_MULS_MAX_WORDS does not overflow (#4781). No functional change intended.

This commit is contained in:
Wilson Snyder 2023-12-30 15:31:58 -05:00
parent 9de6612cde
commit ca3b5fbe99
2 changed files with 24 additions and 15 deletions

View File

@ -444,6 +444,8 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
const int uw = VL_WORDS_I(umsbp1); // aka "m" in the algorithm
const int vw = VL_WORDS_I(vmsbp1); // aka "n" in the algorithm
VL_DEBUG_IFDEF(assert(uw <= VL_MULS_MAX_WORDS););
VL_DEBUG_IFDEF(assert(vw <= VL_MULS_MAX_WORDS););
if (vw == 1) { // Single divisor word breaks rest of algorithm
uint64_t k = 0;
@ -542,6 +544,8 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, const WDataInP lwp,
const WDataInP rwp) VL_MT_SAFE {
// obits==lbits, rbits can be different
const int owords = VL_WORDS_I(obits);
VL_DEBUG_IFDEF(assert(owords <= VL_MULS_MAX_WORDS););
owp[0] = 1;
for (int i = 1; i < VL_WORDS_I(obits); i++) owp[i] = 0;
// cppcheck-has-bug-suppress variableScope
@ -553,11 +557,11 @@ WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, const WDataInP lw
for (int bit = 0; bit < rbits; bit++) {
if (bit > 0) { // power = power*power
VL_ASSIGN_W(obits, lastpowstore, powstore);
VL_MUL_W(VL_WORDS_I(obits), powstore, lastpowstore, lastpowstore);
VL_MUL_W(owords, powstore, lastpowstore, lastpowstore);
}
if (VL_BITISSET_W(rwp, bit)) { // out *= power
VL_ASSIGN_W(obits, lastoutstore, owp);
VL_MUL_W(VL_WORDS_I(obits), owp, lastoutstore, powstore);
VL_MUL_W(owords, owp, lastoutstore, powstore);
}
}
return owp;
@ -653,8 +657,10 @@ double VL_ITOR_D_W(int lbits, const WDataInP lwp) VL_PURE {
}
double VL_ISTOR_D_W(int lbits, const WDataInP lwp) VL_MT_SAFE {
if (!VL_SIGN_W(lbits, lwp)) return VL_ITOR_D_W(lbits, lwp);
const int words = VL_WORDS_I(lbits);
VL_DEBUG_IFDEF(assert(words <= VL_MULS_MAX_WORDS););
uint32_t pos[VL_MULS_MAX_WORDS + 1]; // Fixed size, as MSVC++ doesn't allow [words] here
VL_NEGATE_W(VL_WORDS_I(lbits), pos, lwp);
VL_NEGATE_W(words, pos, lwp);
_vl_clean_inplace_w(lbits, pos);
return -VL_ITOR_D_W(lbits, pos);
}

View File

@ -1032,6 +1032,7 @@ static inline QData VL_MULS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
static inline WDataOutP VL_MULS_WWW(int lbits, WDataOutP owp, WDataInP const lwp,
WDataInP const rwp) VL_MT_SAFE {
const int words = VL_WORDS_I(lbits);
VL_DEBUG_IFDEF(assert(words <= VL_MULS_MAX_WORDS););
// cppcheck-suppress variableScope
WData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
// cppcheck-suppress variableScope
@ -1102,21 +1103,22 @@ static inline QData VL_MODDIVS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
static inline WDataOutP VL_DIVS_WWW(int lbits, WDataOutP owp, WDataInP const lwp,
WDataInP const rwp) VL_MT_SAFE {
const int words = VL_WORDS_I(lbits);
const EData lsign = VL_SIGN_E(lbits, lwp[words - 1]);
const EData rsign = VL_SIGN_E(lbits, rwp[words - 1]);
const int lwords = VL_WORDS_I(lbits);
const EData lsign = VL_SIGN_E(lbits, lwp[lwords - 1]);
const EData rsign = VL_SIGN_E(lbits, rwp[lwords - 1]);
VL_DEBUG_IFDEF(assert(lwords <= VL_MULS_MAX_WORDS););
// cppcheck-suppress variableScope
WData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
// cppcheck-suppress variableScope
WData rwstore[VL_MULS_MAX_WORDS];
WDataInP ltup = lwp;
WDataInP rtup = rwp;
if (lsign) ltup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), lwstore, lwp));
if (rsign) rtup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), rwstore, rwp));
if (lsign) ltup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, lwstore, lwp));
if (rsign) rtup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, rwstore, rwp));
if ((lsign && !rsign) || (!lsign && rsign)) {
WData qNoSign[VL_MULS_MAX_WORDS];
VL_DIV_WWW(lbits, qNoSign, ltup, rtup);
_vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), owp, qNoSign));
_vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, owp, qNoSign));
return owp;
} else {
return VL_DIV_WWW(lbits, owp, ltup, rtup);
@ -1124,21 +1126,22 @@ static inline WDataOutP VL_DIVS_WWW(int lbits, WDataOutP owp, WDataInP const lwp
}
static inline WDataOutP VL_MODDIVS_WWW(int lbits, WDataOutP owp, WDataInP const lwp,
WDataInP const rwp) VL_MT_SAFE {
const int words = VL_WORDS_I(lbits);
const EData lsign = VL_SIGN_E(lbits, lwp[words - 1]);
const EData rsign = VL_SIGN_E(lbits, rwp[words - 1]);
const int lwords = VL_WORDS_I(lbits);
const EData lsign = VL_SIGN_E(lbits, lwp[lwords - 1]);
const EData rsign = VL_SIGN_E(lbits, rwp[lwords - 1]);
VL_DEBUG_IFDEF(assert(lwords <= VL_MULS_MAX_WORDS););
// cppcheck-suppress variableScope
WData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
// cppcheck-suppress variableScope
WData rwstore[VL_MULS_MAX_WORDS];
WDataInP ltup = lwp;
WDataInP rtup = rwp;
if (lsign) ltup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), lwstore, lwp));
if (rsign) rtup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), rwstore, rwp));
if (lsign) ltup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, lwstore, lwp));
if (rsign) rtup = _vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, rwstore, rwp));
if (lsign) { // Only dividend sign matters for modulus
WData qNoSign[VL_MULS_MAX_WORDS];
VL_MODDIV_WWW(lbits, qNoSign, ltup, rtup);
_vl_clean_inplace_w(lbits, VL_NEGATE_W(VL_WORDS_I(lbits), owp, qNoSign));
_vl_clean_inplace_w(lbits, VL_NEGATE_W(lwords, owp, qNoSign));
return owp;
} else {
return VL_MODDIV_WWW(lbits, owp, ltup, rtup);