Internals: Construct V3Number with correct type instead of changing it manually. (#3529)

This commit is contained in:
Mariusz Glebocki 2022-08-08 14:17:02 +02:00 committed by GitHub
parent d20f22beb1
commit 2b12fe5773
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 33 additions and 16 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;
}