Internals: Have V3Unknown/Const use only dtypes for selects.

This commit is contained in:
Wilson Snyder
2013-01-13 14:54:12 -05:00
parent 1d5ebfd0b1
commit 13bf2f19ac
2 changed files with 57 additions and 40 deletions
+42 -26
View File
@@ -370,37 +370,53 @@ private:
// Extraction checks
bool warnSelect(AstSel* nodep) {
AstNode* basefromp = AstArraySel::baseFromp(nodep);
if (m_doGenerate) {
// Never checked yet
V3Width::widthParamsEdit(nodep);
nodep->iterateChildren(*this); // May need "constifying"
}
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
AstVar* varp = varrefp->varp();
if (!varp->dtypep()) varp->v3fatalSrc("Data type lost");
AstBasicDType* bdtypep = varp->basicp(); if (!bdtypep) varp->v3fatalSrc("Select of non-selectable type");
if (m_warn
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& (!bdtypep->isRanged() || bdtypep->msb())) { // else it's non-resolvable parameterized
if (nodep->lsbp()->castConst()->num().isFourState()
|| nodep->widthp()->castConst()->num().isFourState()) {
nodep->v3error("Selection index is constantly unknown or tristated: "
"lsb="<<nodep->lsbp()->name()<<" width="<<nodep->widthp()->name());
// Replacing nodep will make a mess above, so we replace the offender
replaceZero(nodep->lsbp());
}
else if ((nodep->msbConst() > bdtypep->msbMaxSelect())
|| (nodep->lsbConst() > bdtypep->msbMaxSelect())) {
// See also warning in V3Width
nodep->v3warn(SELRANGE, "Selection index out of range: "
<<nodep->msbConst()<<":"<<nodep->lsbConst()
<<" outside "<<bdtypep->msbMaxSelect()<<":0"
<<(bdtypep->lsb()>=0 ? ""
:" (adjusted +"+cvtToStr(-bdtypep->lsb())+" to account for negative lsb)"));
// Don't replace with zero, we'll do it later
}
// Find range of dtype we are selecting from
// Similar code in V3Unknown::AstSel
int declMsbMaxSelect = -1;
int declLsb = -1;
bool doit = false;
AstNodeDType* dtypep = nodep->fromp()->dtypep()->skipRefp();
if (!dtypep) nodep->v3fatalSrc("Select of non-selectable type");
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
declMsbMaxSelect = adtypep->msbMaxSelect();
declLsb = adtypep->lsb();
doit = true;
} else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
declMsbMaxSelect = adtypep->msbMaxSelect();
declLsb = adtypep->lsb();
doit = (!adtypep->isRanged() || adtypep->msb()); // else it's non-resolvable parameterized
} else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) {
declMsbMaxSelect = adtypep->msbMaxSelect();
declLsb = adtypep->lsb();
doit = true;
} else {
nodep->v3error("Select from non-selectable "<<dtypep->prettyTypeName());
}
if (m_warn
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& doit) {
if (nodep->lsbp()->castConst()->num().isFourState()
|| nodep->widthp()->castConst()->num().isFourState()) {
nodep->v3error("Selection index is constantly unknown or tristated: "
"lsb="<<nodep->lsbp()->name()<<" width="<<nodep->widthp()->name());
// Replacing nodep will make a mess above, so we replace the offender
replaceZero(nodep->lsbp());
}
else if ((nodep->msbConst() > declMsbMaxSelect)
|| (nodep->lsbConst() > declMsbMaxSelect)) {
// See also warning in V3Width
nodep->v3warn(SELRANGE, "Selection index out of range: "
<<nodep->msbConst()<<":"<<nodep->lsbConst()
<<" outside "<<declMsbMaxSelect<<":0"
<<(declLsb>=0 ? ""
:" (adjusted +"+cvtToStr(-declLsb)+" to account for negative lsb)"));
// Don't replace with zero, we'll do it later
}
}
return false; // Not a transform, so NOP