mirror of
https://github.com/verilator/verilator.git
synced 2025-05-04 22:46:57 +00:00
Internals: Have V3Unknown/Const use only dtypes for selects.
This commit is contained in:
parent
1d5ebfd0b1
commit
13bf2f19ac
@ -370,37 +370,53 @@ private:
|
|||||||
|
|
||||||
// Extraction checks
|
// Extraction checks
|
||||||
bool warnSelect(AstSel* nodep) {
|
bool warnSelect(AstSel* nodep) {
|
||||||
AstNode* basefromp = AstArraySel::baseFromp(nodep);
|
|
||||||
if (m_doGenerate) {
|
if (m_doGenerate) {
|
||||||
// Never checked yet
|
// Never checked yet
|
||||||
V3Width::widthParamsEdit(nodep);
|
V3Width::widthParamsEdit(nodep);
|
||||||
nodep->iterateChildren(*this); // May need "constifying"
|
nodep->iterateChildren(*this); // May need "constifying"
|
||||||
}
|
}
|
||||||
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
|
// Find range of dtype we are selecting from
|
||||||
AstVar* varp = varrefp->varp();
|
// Similar code in V3Unknown::AstSel
|
||||||
if (!varp->dtypep()) varp->v3fatalSrc("Data type lost");
|
int declMsbMaxSelect = -1;
|
||||||
AstBasicDType* bdtypep = varp->basicp(); if (!bdtypep) varp->v3fatalSrc("Select of non-selectable type");
|
int declLsb = -1;
|
||||||
if (m_warn
|
bool doit = false;
|
||||||
&& nodep->lsbp()->castConst()
|
AstNodeDType* dtypep = nodep->fromp()->dtypep()->skipRefp();
|
||||||
&& nodep->widthp()->castConst()
|
if (!dtypep) nodep->v3fatalSrc("Select of non-selectable type");
|
||||||
&& (!bdtypep->isRanged() || bdtypep->msb())) { // else it's non-resolvable parameterized
|
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
|
||||||
if (nodep->lsbp()->castConst()->num().isFourState()
|
declMsbMaxSelect = adtypep->msbMaxSelect();
|
||||||
|| nodep->widthp()->castConst()->num().isFourState()) {
|
declLsb = adtypep->lsb();
|
||||||
nodep->v3error("Selection index is constantly unknown or tristated: "
|
doit = true;
|
||||||
"lsb="<<nodep->lsbp()->name()<<" width="<<nodep->widthp()->name());
|
} else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
|
||||||
// Replacing nodep will make a mess above, so we replace the offender
|
declMsbMaxSelect = adtypep->msbMaxSelect();
|
||||||
replaceZero(nodep->lsbp());
|
declLsb = adtypep->lsb();
|
||||||
}
|
doit = (!adtypep->isRanged() || adtypep->msb()); // else it's non-resolvable parameterized
|
||||||
else if ((nodep->msbConst() > bdtypep->msbMaxSelect())
|
} else if (AstNodeClassDType* adtypep = dtypep->castNodeClassDType()) {
|
||||||
|| (nodep->lsbConst() > bdtypep->msbMaxSelect())) {
|
declMsbMaxSelect = adtypep->msbMaxSelect();
|
||||||
// See also warning in V3Width
|
declLsb = adtypep->lsb();
|
||||||
nodep->v3warn(SELRANGE, "Selection index out of range: "
|
doit = true;
|
||||||
<<nodep->msbConst()<<":"<<nodep->lsbConst()
|
} else {
|
||||||
<<" outside "<<bdtypep->msbMaxSelect()<<":0"
|
nodep->v3error("Select from non-selectable "<<dtypep->prettyTypeName());
|
||||||
<<(bdtypep->lsb()>=0 ? ""
|
}
|
||||||
:" (adjusted +"+cvtToStr(-bdtypep->lsb())+" to account for negative lsb)"));
|
if (m_warn
|
||||||
// Don't replace with zero, we'll do it later
|
&& 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
|
return false; // Not a transform, so NOP
|
||||||
|
@ -323,16 +323,14 @@ private:
|
|||||||
nodep->iterateChildren(*this);
|
nodep->iterateChildren(*this);
|
||||||
if (!nodep->user1SetOnce()) {
|
if (!nodep->user1SetOnce()) {
|
||||||
// Guard against reading/writing past end of bit vector array
|
// Guard against reading/writing past end of bit vector array
|
||||||
int maxmsb = 0;
|
|
||||||
bool lvalue = false;
|
|
||||||
AstNode* basefromp = AstArraySel::baseFromp(nodep);
|
AstNode* basefromp = AstArraySel::baseFromp(nodep);
|
||||||
|
bool lvalue = false;
|
||||||
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
|
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
|
||||||
lvalue = varrefp->lvalue();
|
lvalue = varrefp->lvalue();
|
||||||
maxmsb = (varrefp->varp()->width()-1);
|
|
||||||
} else {
|
|
||||||
// If it's a PARAMETER[bit], then basefromp may be a constant instead of a varrefp
|
|
||||||
maxmsb = basefromp->width()-1;
|
|
||||||
}
|
}
|
||||||
|
// Find range of dtype we are selecting from
|
||||||
|
// Similar code in V3Const::warnSelect
|
||||||
|
int maxmsb = nodep->fromp()->dtypep()->width()-1;
|
||||||
int maxlsb = maxmsb - nodep->width() + 1;
|
int maxlsb = maxmsb - nodep->width() + 1;
|
||||||
if (debug()>=9) nodep->dumpTree(cout,"sel_old: ");
|
if (debug()>=9) nodep->dumpTree(cout,"sel_old: ");
|
||||||
V3Number maxlsbnum (nodep->fileline(), nodep->lsbp()->width(), maxlsb);
|
V3Number maxlsbnum (nodep->fileline(), nodep->lsbp()->width(), maxlsb);
|
||||||
@ -375,22 +373,25 @@ private:
|
|||||||
if (debug()==9) nodep->dumpTree(cout,"-in: ");
|
if (debug()==9) nodep->dumpTree(cout,"-in: ");
|
||||||
// Guard against reading/writing past end of arrays
|
// Guard against reading/writing past end of arrays
|
||||||
AstNode* basefromp = AstArraySel::baseFromp(nodep->fromp());
|
AstNode* basefromp = AstArraySel::baseFromp(nodep->fromp());
|
||||||
int dimension = AstArraySel::dimension(nodep->fromp());
|
|
||||||
int maxmsb = 0;
|
|
||||||
bool lvalue = false;
|
bool lvalue = false;
|
||||||
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
|
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
|
||||||
AstNodeArrayDType* adtypep = varrefp->varp()->dtypep()->dtypeDimensionp(dimension)->castNodeArrayDType();
|
|
||||||
if (!adtypep) nodep->v3fatalSrc("ArraySel to type without array at same depth");
|
|
||||||
lvalue = varrefp->lvalue();
|
lvalue = varrefp->lvalue();
|
||||||
maxmsb = adtypep->elementsConst()-1;
|
} else if (basefromp->castConst()) {
|
||||||
} else if (AstConst* lhconstp = basefromp->castConst()) {
|
|
||||||
// If it's a PARAMETER[bit], then basefromp may be a constant instead of a varrefp
|
// If it's a PARAMETER[bit], then basefromp may be a constant instead of a varrefp
|
||||||
maxmsb = lhconstp->width();
|
|
||||||
} else {
|
} else {
|
||||||
nodep->v3fatalSrc("No VarRef or Const under ArraySel\n");
|
nodep->v3fatalSrc("No VarRef or Const under ArraySel\n");
|
||||||
}
|
}
|
||||||
|
// Find range of dtype we are selecting from
|
||||||
|
int declElements = -1;
|
||||||
|
AstNodeDType* dtypep = nodep->fromp()->dtypep()->skipRefp();
|
||||||
|
if (!dtypep) nodep->v3fatalSrc("Select of non-selectable type");
|
||||||
|
if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
|
||||||
|
declElements = adtypep->elementsConst();
|
||||||
|
} else {
|
||||||
|
nodep->v3error("Select from non-array "<<dtypep->prettyTypeName());
|
||||||
|
}
|
||||||
if (debug()>=9) nodep->dumpTree(cout,"arraysel_old: ");
|
if (debug()>=9) nodep->dumpTree(cout,"arraysel_old: ");
|
||||||
V3Number widthnum (nodep->fileline(), nodep->bitp()->width(), maxmsb);
|
V3Number widthnum (nodep->fileline(), nodep->bitp()->width(), declElements-1);
|
||||||
|
|
||||||
// See if the condition is constant true
|
// See if the condition is constant true
|
||||||
AstNode* condp = new AstLte (nodep->fileline(),
|
AstNode* condp = new AstLte (nodep->fileline(),
|
||||||
|
Loading…
Reference in New Issue
Block a user