mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Fix shift of > 32-bit number (#4719).
This commit is contained in:
+6
-3
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user