Internals: Construct V3Number with correct type instead of changing it manually. (#3529)
This commit is contained in:
parent
d20f22beb1
commit
2b12fe5773
|
|
@ -77,10 +77,11 @@ public:
|
||||||
, m_num(this, width, value) {
|
, m_num(this, width, value) {
|
||||||
initWithNumber();
|
initWithNumber();
|
||||||
}
|
}
|
||||||
class DtypedValue {}; // for creator type-overload selection
|
class DTyped {}; // for creator type-overload selection
|
||||||
AstConst(FileLine* fl, DtypedValue, AstNodeDType* nodedtypep, uint32_t value)
|
// Zero/empty constant with a type matching nodetypep
|
||||||
|
AstConst(FileLine* fl, DTyped, const AstNodeDType* nodedtypep)
|
||||||
: ASTGEN_SUPER_Const(fl)
|
: ASTGEN_SUPER_Const(fl)
|
||||||
, m_num(this, nodedtypep->width(), value, nodedtypep->widthSized()) {
|
, m_num(this, nodedtypep) {
|
||||||
initWithNumber();
|
initWithNumber();
|
||||||
}
|
}
|
||||||
class StringToParse {}; // for creator type-overload selection
|
class StringToParse {}; // for creator type-overload selection
|
||||||
|
|
|
||||||
|
|
@ -1089,7 +1089,7 @@ private:
|
||||||
|
|
||||||
if (orLIsRedundant && orRIsRedundant) {
|
if (orLIsRedundant && orRIsRedundant) {
|
||||||
nodep->replaceWith(
|
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);
|
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||||
return true;
|
return true;
|
||||||
} else if (orLIsRedundant) {
|
} else if (orLIsRedundant) {
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,18 @@ V3Number::V3Number(VerilogStringLiteral, AstNode* nodep, const string& str) {
|
||||||
opCleanThis(true);
|
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) {
|
void V3Number::V3NumberCreate(AstNode* nodep, const char* sourcep, FileLine* fl) {
|
||||||
init(nodep, 0);
|
init(nodep, 0);
|
||||||
m_fileline = fl;
|
m_fileline = fl;
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ inline bool v3EpsilonEqual(double a, double b) {
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
class AstNode;
|
class AstNode;
|
||||||
|
class AstNodeDType;
|
||||||
class FileLine;
|
class FileLine;
|
||||||
|
|
||||||
// Holds a few entries of ValueAndX to avoid dynamic allocation in std::vector for less width of
|
// Holds a few entries of ValueAndX to avoid dynamic allocation in std::vector for less width of
|
||||||
|
|
@ -252,6 +253,11 @@ public:
|
||||||
opCleanThis();
|
opCleanThis();
|
||||||
m_fileline = nump->fileline();
|
m_fileline = nump->fileline();
|
||||||
}
|
}
|
||||||
|
V3Number(AstNode* nodep, double value) {
|
||||||
|
init(nodep, 64);
|
||||||
|
setDouble(value);
|
||||||
|
}
|
||||||
|
V3Number(AstNode* nodep, const AstNodeDType* nodedtypep);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void V3NumberCreate(AstNode* nodep, const char* sourcep, FileLine* fl);
|
void V3NumberCreate(AstNode* nodep, const char* sourcep, FileLine* fl);
|
||||||
|
|
@ -311,9 +317,7 @@ public:
|
||||||
// (use AstConst::isSigned())
|
// (use AstConst::isSigned())
|
||||||
bool isDouble() const { return m_double; }
|
bool isDouble() const { return m_double; }
|
||||||
// Only if have 64 bit value loaded, and want to indicate it's real
|
// 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; }
|
bool isString() const { return m_isString; }
|
||||||
void isString(bool flag) { m_isString = flag; }
|
|
||||||
bool isNegative() const { return bitIs1(width() - 1); }
|
bool isNegative() const { return bitIs1(width() - 1); }
|
||||||
bool isNull() const { return m_isNull; }
|
bool isNull() const { return m_isNull; }
|
||||||
bool isFourState() const;
|
bool isFourState() const;
|
||||||
|
|
|
||||||
|
|
@ -186,19 +186,21 @@ public:
|
||||||
return pinValuep->num().toString() == hierOptParamp->num().toString();
|
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()) {
|
if (hierOptParamp->isDouble()) {
|
||||||
varNum.isDouble(true);
|
double var;
|
||||||
if (pinValuep->isDouble()) {
|
if (pinValuep->isDouble()) {
|
||||||
varNum.opAssign(pinValuep->num());
|
var = pinValuep->num().toDouble();
|
||||||
} else { // Cast from integer to real
|
} else { // Cast from integer to real
|
||||||
|
V3Number varNum{pinValuep, 0.0};
|
||||||
varNum.opIToRD(pinValuep->num());
|
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
|
} 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
|
if (pinValuep->isDouble()) { // Need to cast to int
|
||||||
// Parameter is actually an integral type, but passed value is floating point.
|
// Parameter is actually an integral type, but passed value is floating point.
|
||||||
// Conversion from real to integer uses rounding in V3Width.cpp
|
// Conversion from real to integer uses rounding in V3Width.cpp
|
||||||
|
|
|
||||||
|
|
@ -239,13 +239,11 @@ private:
|
||||||
}
|
}
|
||||||
if (allocNewConst) {
|
if (allocNewConst) {
|
||||||
// Need to allocate new constant
|
// 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
|
// Mark as in use, add to free list for later reuse
|
||||||
constp->user2(1);
|
constp->user2(1);
|
||||||
freeList.push_back(constp);
|
freeList.push_back(constp);
|
||||||
}
|
}
|
||||||
constp->num().isDouble(nodep->isDouble());
|
|
||||||
constp->num().isString(nodep->isString());
|
|
||||||
return constp;
|
return constp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue