Internals: Make V3Width dimensionValue more generic. No functional change.
This commit is contained in:
parent
7c588c2e30
commit
2e5f5010f7
|
|
@ -818,45 +818,55 @@ private:
|
||||||
m_attrp = nodep;
|
m_attrp = nodep;
|
||||||
nodep->fromp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p());
|
nodep->fromp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p());
|
||||||
// Don't iterate children, don't want to lose VarRef.
|
// Don't iterate children, don't want to lose VarRef.
|
||||||
if (nodep->attrType()==AstAttrType::VAR_BASE) {
|
switch (nodep->attrType()) {
|
||||||
|
case AstAttrType::VAR_BASE:
|
||||||
// Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf
|
// Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf
|
||||||
} else if (nodep->attrType()==AstAttrType::MEMBER_BASE) {
|
break;
|
||||||
|
case AstAttrType::MEMBER_BASE:
|
||||||
// Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf
|
// Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf
|
||||||
} else if (nodep->attrType()==AstAttrType::DIM_DIMENSIONS
|
break;
|
||||||
|| nodep->attrType()==AstAttrType::DIM_UNPK_DIMENSIONS) {
|
case AstAttrType::DIM_DIMENSIONS:
|
||||||
|
case AstAttrType::DIM_UNPK_DIMENSIONS: {
|
||||||
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
|
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
|
||||||
pair<uint32_t,uint32_t> dim = nodep->fromp()->dtypep()->dimensions(true);
|
pair<uint32_t,uint32_t> dim = nodep->fromp()->dtypep()->dimensions(true);
|
||||||
int val = (nodep->attrType()==AstAttrType::DIM_UNPK_DIMENSIONS
|
int val = (nodep->attrType()==AstAttrType::DIM_UNPK_DIMENSIONS
|
||||||
? dim.second : (dim.first+dim.second));
|
? dim.second : (dim.first+dim.second));
|
||||||
nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Signed32(), val)); nodep->deleteTree(); nodep=NULL;
|
nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Signed32(), val)); nodep->deleteTree(); nodep=NULL;
|
||||||
} else if (nodep->attrType()==AstAttrType::DIM_BITS
|
break;
|
||||||
|| nodep->attrType()==AstAttrType::DIM_HIGH
|
}
|
||||||
|| nodep->attrType()==AstAttrType::DIM_INCREMENT
|
case AstAttrType::DIM_BITS:
|
||||||
|| nodep->attrType()==AstAttrType::DIM_LEFT
|
case AstAttrType::DIM_HIGH:
|
||||||
|| nodep->attrType()==AstAttrType::DIM_LOW
|
case AstAttrType::DIM_INCREMENT:
|
||||||
|| nodep->attrType()==AstAttrType::DIM_RIGHT
|
case AstAttrType::DIM_LEFT:
|
||||||
|| nodep->attrType()==AstAttrType::DIM_SIZE) {
|
case AstAttrType::DIM_LOW:
|
||||||
|
case AstAttrType::DIM_RIGHT:
|
||||||
|
case AstAttrType::DIM_SIZE: {
|
||||||
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
|
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
|
||||||
pair<uint32_t,uint32_t> dim = nodep->fromp()->dtypep()->skipRefp()->dimensions(true);
|
pair<uint32_t,uint32_t> dim = nodep->fromp()->dtypep()->skipRefp()->dimensions(true);
|
||||||
uint32_t maxdim = dim.first+dim.second;
|
uint32_t maxdim = dim.first+dim.second;
|
||||||
if (!nodep->dimp() || nodep->dimp()->castConst() || maxdim<1) {
|
if (!nodep->dimp() || nodep->dimp()->castConst() || maxdim<1) {
|
||||||
int dim = !nodep->dimp() ? 1 : nodep->dimp()->castConst()->toSInt();
|
int dim = !nodep->dimp() ? 1 : nodep->dimp()->castConst()->toSInt();
|
||||||
int val = dimensionValue(nodep->fromp()->dtypep(), nodep->attrType(), dim);
|
AstConst* newp = dimensionValue(nodep->fromp()->dtypep(), nodep->attrType(), dim);
|
||||||
nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Signed32(), val)); nodep->deleteTree(); nodep=NULL;
|
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
|
||||||
}
|
}
|
||||||
else { // Need a runtime lookup table. Yuk.
|
else { // Need a runtime lookup table. Yuk.
|
||||||
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
|
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
|
||||||
AstVar* varp = dimensionVarp(nodep->fromp()->dtypep(), nodep->attrType());
|
AstVar* varp = dimensionVarp(nodep->fromp()->dtypep(), nodep->attrType(), maxdim);
|
||||||
AstNode* dimp = nodep->dimp()->unlinkFrBack();
|
AstNode* dimp = nodep->dimp()->unlinkFrBack();
|
||||||
AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false);
|
AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false);
|
||||||
varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp());
|
varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp());
|
||||||
AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, dimp);
|
AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, dimp);
|
||||||
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
|
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
|
||||||
}
|
}
|
||||||
} else { // Everything else resolved earlier
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
// Everything else resolved earlier
|
||||||
nodep->dtypeSetLogicSized(32,1,AstNumeric::UNSIGNED); // Approximation, unsized 32
|
nodep->dtypeSetLogicSized(32,1,AstNumeric::UNSIGNED); // Approximation, unsized 32
|
||||||
UINFO(1,"Missing ATTR type case node: "<<nodep<<endl);
|
UINFO(1,"Missing ATTR type case node: "<<nodep<<endl);
|
||||||
nodep->v3fatalSrc("Missing ATTR type case");
|
nodep->v3fatalSrc("Missing ATTR type case");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_attrp = oldAttr;
|
m_attrp = oldAttr;
|
||||||
}
|
}
|
||||||
|
|
@ -3090,7 +3100,7 @@ private:
|
||||||
return nodep;
|
return nodep;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dimensionValue(AstNodeDType* nodep, AstAttrType attrType, int dim) {
|
AstConst* dimensionValue(AstNodeDType* nodep, AstAttrType attrType, int dim) {
|
||||||
// Return the dimension value for the specified attribute and constant dimension
|
// Return the dimension value for the specified attribute and constant dimension
|
||||||
AstNodeDType* dtypep = nodep->skipRefp();
|
AstNodeDType* dtypep = nodep->skipRefp();
|
||||||
VNumRange declRange; // ranged() set false
|
VNumRange declRange; // ranged() set false
|
||||||
|
|
@ -3111,8 +3121,10 @@ private:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
AstConst* valp = NULL; // If NULL, construct from val
|
||||||
int val = 0;
|
int val = 0;
|
||||||
if (attrType==AstAttrType::DIM_BITS) {
|
switch (attrType) {
|
||||||
|
case AstAttrType::DIM_BITS: {
|
||||||
int bits = 1;
|
int bits = 1;
|
||||||
while (dtypep) {
|
while (dtypep) {
|
||||||
//UINFO(9, " bits at "<<bits<<" "<<dtypep<<endl);
|
//UINFO(9, " bits at "<<bits<<" "<<dtypep<<endl);
|
||||||
|
|
@ -3136,29 +3148,35 @@ private:
|
||||||
} else {
|
} else {
|
||||||
val = bits;
|
val = bits;
|
||||||
}
|
}
|
||||||
} else if (attrType==AstAttrType::DIM_HIGH) {
|
break; }
|
||||||
|
case AstAttrType::DIM_HIGH:
|
||||||
val = !declRange.ranged() ? 0 : declRange.hi();
|
val = !declRange.ranged() ? 0 : declRange.hi();
|
||||||
} else if (attrType==AstAttrType::DIM_LEFT) {
|
break;
|
||||||
|
case AstAttrType::DIM_LEFT:
|
||||||
val = !declRange.ranged() ? 0 : declRange.left();
|
val = !declRange.ranged() ? 0 : declRange.left();
|
||||||
} else if (attrType==AstAttrType::DIM_LOW) {
|
break;
|
||||||
|
case AstAttrType::DIM_LOW:
|
||||||
val = !declRange.ranged() ? 0 : declRange.lo();
|
val = !declRange.ranged() ? 0 : declRange.lo();
|
||||||
} else if (attrType==AstAttrType::DIM_RIGHT) {
|
break;
|
||||||
|
case AstAttrType::DIM_RIGHT:
|
||||||
val = !declRange.ranged() ? 0 : declRange.right();
|
val = !declRange.ranged() ? 0 : declRange.right();
|
||||||
} else if (attrType==AstAttrType::DIM_INCREMENT) {
|
break;
|
||||||
|
case AstAttrType::DIM_INCREMENT:
|
||||||
val = (declRange.ranged() && declRange.littleEndian()) ? -1 : 1;
|
val = (declRange.ranged() && declRange.littleEndian()) ? -1 : 1;
|
||||||
} else if (attrType==AstAttrType::DIM_SIZE) {
|
break;
|
||||||
|
case AstAttrType::DIM_SIZE:
|
||||||
val = !declRange.ranged() ? 0 : declRange.elements();
|
val = !declRange.ranged() ? 0 : declRange.elements();
|
||||||
} else {
|
break;
|
||||||
|
default:
|
||||||
nodep->v3fatalSrc("Missing DIM ATTR type case");
|
nodep->v3fatalSrc("Missing DIM ATTR type case");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
UINFO(9," $dimension "<<attrType.ascii()<<"("<<((void*)dtypep)<<","<<dim<<")="<<val<<endl);
|
if (!valp) valp = new AstConst(nodep->fileline(), AstConst::Signed32(), val);
|
||||||
return val;
|
UINFO(9," $dimension "<<attrType.ascii()<<"("<<((void*)dtypep)<<","<<dim<<")="<<valp<<endl);
|
||||||
|
return valp;
|
||||||
}
|
}
|
||||||
AstVar* dimensionVarp(AstNodeDType* nodep, AstAttrType attrType) {
|
AstVar* dimensionVarp(AstNodeDType* nodep, AstAttrType attrType, uint32_t maxdim) {
|
||||||
// Return a variable table which has specified dimension properties for this variable
|
// Return a variable table which has specified dimension properties for this variable
|
||||||
pair<uint32_t,uint32_t> dim = nodep->skipRefp()->dimensions(true);
|
|
||||||
uint32_t maxdim = dim.first+dim.second;
|
|
||||||
//
|
|
||||||
AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(),
|
AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(),
|
||||||
nodep->findSigned32DType(),
|
nodep->findSigned32DType(),
|
||||||
new AstRange(nodep->fileline(), maxdim, 0));
|
new AstRange(nodep->fileline(), maxdim, 0));
|
||||||
|
|
@ -3173,11 +3191,9 @@ private:
|
||||||
// Add to root, as don't know module we are in, and aids later structure sharing
|
// Add to root, as don't know module we are in, and aids later structure sharing
|
||||||
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp);
|
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp);
|
||||||
// Element 0 is a non-index and has speced values
|
// Element 0 is a non-index and has speced values
|
||||||
initp->addInitsp(new AstConst(nodep->fileline(), AstConst::Signed32(),
|
initp->addInitsp(dimensionValue(nodep, attrType, 0));
|
||||||
dimensionValue(nodep, attrType, 0)));
|
|
||||||
for (unsigned i=1; i<maxdim+1; ++i) {
|
for (unsigned i=1; i<maxdim+1; ++i) {
|
||||||
initp->addInitsp(new AstConst(nodep->fileline(), AstConst::Signed32(),
|
initp->addInitsp(dimensionValue(nodep, attrType, i));
|
||||||
dimensionValue(nodep, attrType, i)));
|
|
||||||
}
|
}
|
||||||
varp->iterate(*this); // May have already done $unit so must do this var
|
varp->iterate(*this); // May have already done $unit so must do this var
|
||||||
return varp;
|
return varp;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue