Fix shift of > 32-bit number (#4719).

This commit is contained in:
Wilson Snyder
2023-11-27 21:41:32 -05:00
parent a022b672a0
commit 7167d4bdc0
9 changed files with 43 additions and 40 deletions
+6 -3
View File
@@ -1221,13 +1221,16 @@ class ConstVisitor final : public VNVisitor {
}
bool operandHugeShiftL(const AstNodeBiop* nodep) {
return (VN_IS(nodep->rhsp(), Const) && !VN_AS(nodep->rhsp(), Const)->num().isFourState()
&& (VN_AS(nodep->rhsp(), Const)->toUInt() >= static_cast<uint32_t>(nodep->width()))
&& (!VN_AS(nodep->rhsp(), Const)->num().fitsInUInt() // > 2^32 shift
|| (VN_AS(nodep->rhsp(), Const)->toUInt()
>= static_cast<uint32_t>(nodep->width())))
&& nodep->lhsp()->isPure());
}
bool operandHugeShiftR(const AstNodeBiop* nodep) {
return (VN_IS(nodep->rhsp(), Const) && !VN_AS(nodep->rhsp(), Const)->num().isFourState()
&& (VN_AS(nodep->rhsp(), Const)->toUInt()
>= static_cast<uint32_t>(nodep->lhsp()->width()))
&& (!VN_AS(nodep->rhsp(), Const)->num().fitsInUInt() // > 2^32 shift
|| (VN_AS(nodep->rhsp(), Const)->toUInt()
>= static_cast<uint32_t>(nodep->lhsp()->width())))
&& nodep->lhsp()->isPure());
}
bool operandIsTwo(const AstNode* nodep) {
+1 -1
View File
@@ -54,7 +54,7 @@ void V3Global::readFiles() {
if (v3Global.opt.std()) {
parser.parseFile(new FileLine{V3Options::getStdPackagePath()},
V3Options::getStdPackagePath(), false,
"Cannot find verilated_std.sv containing built-in std:: definitions:");
"Cannot find verilated_std.sv containing built-in std:: definitions: ");
}
// Read top module
+11 -5
View File
@@ -896,14 +896,20 @@ string V3Number::toDecimalU() const VL_MT_STABLE {
//======================================================================
// ACCESSORS - as numbers
bool V3Number::fitsInUInt() const VL_MT_SAFE {
if (isFourState()) return false;
// We allow wide numbers that represent values <= 32 bits
for (int i = 1; i < words(); ++i) {
if (m_data.num()[i].m_value) return false;
}
return true;
}
uint32_t V3Number::toUInt() const VL_MT_SAFE {
UASSERT(!isFourState(), "toUInt with 4-state " << *this);
// We allow wide numbers that represent values <= 32 bits
for (int i = 1; i < words(); ++i) {
if (m_data.num()[i].m_value) {
v3error("Value too wide for 32-bits expected in this context " << *this);
break;
}
if (VL_UNCOVERABLE(!fitsInUInt())) {
v3error("Value too wide for 32-bits expected in this context " // LCOV_EXCL_LINE
<< *this);
}
return m_data.num()[0].m_value;
}
+1
View File
@@ -638,6 +638,7 @@ public:
bool isAnyXZ() const;
bool isAnyZ() const VL_MT_SAFE;
bool isMsbXZ() const { return bitIsXZ(m_data.width() - 1); }
bool fitsInUInt() const VL_MT_SAFE;
uint32_t toUInt() const VL_MT_SAFE;
int32_t toSInt() const VL_MT_SAFE;
uint64_t toUQuad() const VL_MT_SAFE;