From 2b12fe5773960126ced1135f779917f9a7ada5cb Mon Sep 17 00:00:00 2001 From: Mariusz Glebocki Date: Mon, 8 Aug 2022 14:17:02 +0200 Subject: [PATCH] Internals: Construct V3Number with correct type instead of changing it manually. (#3529) --- src/V3AstNodes.h | 7 ++++--- src/V3Const.cpp | 2 +- src/V3Number.cpp | 12 ++++++++++++ src/V3Number.h | 8 ++++++-- src/V3Param.cpp | 16 +++++++++------- src/V3Simulate.h | 4 +--- 6 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 81753a419..9657052fb 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -77,10 +77,11 @@ public: , m_num(this, width, value) { initWithNumber(); } - class DtypedValue {}; // for creator type-overload selection - AstConst(FileLine* fl, DtypedValue, AstNodeDType* nodedtypep, uint32_t value) + class DTyped {}; // for creator type-overload selection + // Zero/empty constant with a type matching nodetypep + AstConst(FileLine* fl, DTyped, const AstNodeDType* nodedtypep) : ASTGEN_SUPER_Const(fl) - , m_num(this, nodedtypep->width(), value, nodedtypep->widthSized()) { + , m_num(this, nodedtypep) { initWithNumber(); } class StringToParse {}; // for creator type-overload selection diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 31e9e6360..fc4555304 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -1089,7 +1089,7 @@ private: if (orLIsRedundant && orRIsRedundant) { nodep->replaceWith( - new AstConst(nodep->fileline(), AstConst::DtypedValue(), nodep->dtypep(), 0)); + new AstConst(nodep->fileline(), AstConst::DTyped{}, nodep->dtypep())); VL_DO_DANGLING(nodep->deleteTree(), nodep); return true; } else if (orLIsRedundant) { diff --git a/src/V3Number.cpp b/src/V3Number.cpp index 9ff6bf5b1..214465f70 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -110,6 +110,18 @@ V3Number::V3Number(VerilogStringLiteral, AstNode* nodep, const string& str) { opCleanThis(true); } +V3Number::V3Number(AstNode* nodep, const AstNodeDType* nodedtypep) { + if (nodedtypep->isString()) { + init(nodep, 0); + setString(""); + } else if (nodedtypep->isDouble()) { + init(nodep, 64); + setDouble(0.0); + } else { + init(nodep, nodedtypep->width(), nodedtypep->widthSized()); + } +} + void V3Number::V3NumberCreate(AstNode* nodep, const char* sourcep, FileLine* fl) { init(nodep, 0); m_fileline = fl; diff --git a/src/V3Number.h b/src/V3Number.h index 56dd34512..fe2f11c5d 100644 --- a/src/V3Number.h +++ b/src/V3Number.h @@ -39,6 +39,7 @@ inline bool v3EpsilonEqual(double a, double b) { //============================================================================ class AstNode; +class AstNodeDType; class FileLine; // Holds a few entries of ValueAndX to avoid dynamic allocation in std::vector for less width of @@ -252,6 +253,11 @@ public: opCleanThis(); m_fileline = nump->fileline(); } + V3Number(AstNode* nodep, double value) { + init(nodep, 64); + setDouble(value); + } + V3Number(AstNode* nodep, const AstNodeDType* nodedtypep); private: void V3NumberCreate(AstNode* nodep, const char* sourcep, FileLine* fl); @@ -311,9 +317,7 @@ public: // (use AstConst::isSigned()) bool isDouble() const { return m_double; } // Only if have 64 bit value loaded, and want to indicate it's real - void isDouble(bool flag) { m_double = flag; } bool isString() const { return m_isString; } - void isString(bool flag) { m_isString = flag; } bool isNegative() const { return bitIs1(width() - 1); } bool isNull() const { return m_isNull; } bool isFourState() const; diff --git a/src/V3Param.cpp b/src/V3Param.cpp index 8a2b5a415..62aa66541 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -186,19 +186,21 @@ public: return pinValuep->num().toString() == hierOptParamp->num().toString(); } - // Bitwidth of hierOptParamp is accurate because V3Width already caluclated in the previous - // run. Bitwidth of pinValuep is before width analysis, so pinValuep is casted to - // hierOptParamp width. - V3Number varNum(pinValuep, hierOptParamp->num().width()); if (hierOptParamp->isDouble()) { - varNum.isDouble(true); + double var; if (pinValuep->isDouble()) { - varNum.opAssign(pinValuep->num()); + var = pinValuep->num().toDouble(); } else { // Cast from integer to real + V3Number varNum{pinValuep, 0.0}; varNum.opIToRD(pinValuep->num()); + var = varNum.toDouble(); } - return v3EpsilonEqual(varNum.toDouble(), hierOptParamp->num().toDouble()); + return v3EpsilonEqual(var, hierOptParamp->num().toDouble()); } else { // Now integer type is assumed + // Bitwidth of hierOptParamp is accurate because V3Width already caluclated in the + // previous run. Bitwidth of pinValuep is before width analysis, so pinValuep is casted + // to hierOptParamp width. + V3Number varNum{pinValuep, hierOptParamp->num().width()}; if (pinValuep->isDouble()) { // Need to cast to int // Parameter is actually an integral type, but passed value is floating point. // Conversion from real to integer uses rounding in V3Width.cpp diff --git a/src/V3Simulate.h b/src/V3Simulate.h index e2418e60d..42fadf297 100644 --- a/src/V3Simulate.h +++ b/src/V3Simulate.h @@ -239,13 +239,11 @@ private: } if (allocNewConst) { // Need to allocate new constant - constp = new AstConst{nodep->fileline(), AstConst::DtypedValue{}, nodep->dtypep(), 0}; + constp = new AstConst{nodep->fileline(), AstConst::DTyped{}, nodep->dtypep()}; // Mark as in use, add to free list for later reuse constp->user2(1); freeList.push_back(constp); } - constp->num().isDouble(nodep->isDouble()); - constp->num().isString(nodep->isString()); return constp; }