forked from github/verilator
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) {
|
||||
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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user