Internals: In AstBasicDType avoid use of Range for constants. No functional change.

This commit is contained in:
Wilson Snyder 2012-02-20 11:48:31 -05:00
parent 7caafb4014
commit d699247269
11 changed files with 45 additions and 24 deletions

View File

@ -269,7 +269,7 @@ AstNodeDType* AstVar::dtypeDimensionp(int dimension) const {
}
else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
// AstBasicDType - nothing below, return null
if (adtypep->rangep()) {
if (adtypep->isRanged()) {
if ((dim++) == dimension) {
return adtypep;
}
@ -524,6 +524,7 @@ void AstAttrOf::dump(ostream& str) {
void AstBasicDType::dump(ostream& str) {
this->AstNodeDType::dump(str);
str<<" ["<<keyword().ascii()<<"]";
if (!rangep() && msb()) str<<" range["<<msb()<<":"<<lsb()<<"]";
if (implicit()) str<<" [IMPLICIT]";
}
void AstCCast::dump(ostream& str) {

View File

@ -244,35 +244,38 @@ struct AstBasicDType : public AstNodeDType {
private:
AstBasicDTypeKwd m_keyword; // What keyword created it
bool m_implicit; // Implicitly declared
int m_msb; // MSB when no range attached
public:
AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, AstSignedState signst=signedst_NOP)
: AstNodeDType(fl) {
init(kwd, signst, NULL);
init(kwd, signst, 0, NULL);
}
AstBasicDType(FileLine* fl, AstLogicPacked, int wantwidth)
: AstNodeDType(fl) {
init(AstBasicDTypeKwd::LOGIC, signedst_NOP,
((wantwidth > 1) ? new AstRange(fl, wantwidth-1, 0) : NULL));
init(AstBasicDTypeKwd::LOGIC, signedst_NOP, wantwidth, NULL);
}
AstBasicDType(FileLine* fl, AstBitPacked, int wantwidth)
: AstNodeDType(fl) {
init(AstBasicDTypeKwd::BIT, signedst_NOP,
((wantwidth > 1) ? new AstRange(fl, wantwidth-1, 0) : NULL));
init(AstBasicDTypeKwd::BIT, signedst_NOP, wantwidth, NULL);
}
// See also addRange in verilog.y
private:
void init(AstBasicDTypeKwd kwd, AstSignedState signst, AstRange* rangep) {
void init(AstBasicDTypeKwd kwd, AstSignedState signst, int wantwidth, AstRange* rangep) {
m_keyword = kwd;
m_msb = 0;
// Implicitness: // "parameter X" is implicit and sized from initial value, "parameter reg x" not
m_implicit = false;
if (keyword()==AstBasicDTypeKwd::LOGIC_IMPLICIT) {
if (!rangep) m_implicit = true; // Also cleared if range added later
if (!rangep && !wantwidth) m_implicit = true; // Also cleared if range added later
m_keyword = AstBasicDTypeKwd::LOGIC;
}
if (signst == signedst_NOP && keyword().isSigned()) signst = signedst_SIGNED;
if (keyword().isDouble()) dtypeChgDouble();
else setSignedState(signst);
if (!rangep) { // Set based on keyword properties
if (!rangep && wantwidth) { // Constant width
m_msb = wantwidth - 1;
width(wantwidth, wantwidth);
} else if (!rangep) { // Set based on keyword properties
// V3Width will pull from this width
if (keyword().width() > 1 && !isOpaque()) rangep = new AstRange(fileline(), keyword().width()-1, 0);
width(keyword().width(), keyword().width());
@ -305,14 +308,22 @@ public:
bool isOpaque() const { return keyword().isOpaque(); }
bool isSloppy() const { return keyword().isSloppy(); }
bool isZeroInit() const { return keyword().isZeroInit(); }
int msb() const { if (!rangep()) return 0; return rangep()->msbConst(); }
bool isRanged() const { return rangep() || m_msb; }
int msb() const { if (!rangep()) return m_msb; return rangep()->msbConst(); }
int lsb() const { if (!rangep()) return 0; return rangep()->lsbConst(); }
int msbEndianed() const { if (!rangep()) return 0; return littleEndian()?rangep()->lsbConst():rangep()->msbConst(); }
int msbEndianed() const { if (!rangep()) return m_msb; return littleEndian()?rangep()->lsbConst():rangep()->msbConst(); }
int lsbEndianed() const { if (!rangep()) return 0; return littleEndian()?rangep()->msbConst():rangep()->lsbConst(); }
int msbMaxSelect() const { return (lsb()<0 ? msb()-lsb() : msb()); } // Maximum value a [] select may index
bool littleEndian() const { return (rangep() && rangep()->littleEndian()); }
bool implicit() const { return m_implicit; }
void implicit(bool flag) { m_implicit = flag; }
void cvtRangeConst() { // Convert to smaller represenation
if (rangep() && rangep()->castConst() && lsb()==0 && !littleEndian()) {
m_msb = msb();
rangep()->deleteTree();
rangep(NULL);
}
}
};
struct AstConstDType : public AstNodeDType {

View File

@ -1627,6 +1627,12 @@ private:
}
}
// Simplify
virtual void visit(AstBasicDType* nodep, AstNUser*) {
nodep->iterateChildren(*this);
nodep->cvtRangeConst();
}
//-----
// Jump elimination

View File

@ -193,7 +193,7 @@ private:
const ToggleEnt& above,
AstVar* varp, AstVar* chgVarp) { // Constant
if (AstBasicDType* bdtypep = dtypep->castBasicDType()) {
if (bdtypep->rangep()) {
if (bdtypep->isRanged()) {
for (int index_docs=bdtypep->lsb(); index_docs<bdtypep->msb()+1; index_docs++) {
int index_code = index_docs - bdtypep->lsb();
ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]",

View File

@ -453,9 +453,9 @@ void EmitCSyms::emitSymImp() {
string bounds;
if (AstBasicDType* basicp = varp->basicp()) {
// Range is always first, it's not in "C" order
if (basicp->rangep()) {
bounds += " ,"; bounds += cvtToStr(basicp->rangep()->msbConst());
bounds += ","; bounds += cvtToStr(basicp->rangep()->lsbConst());
if (basicp->isRanged()) {
bounds += " ,"; bounds += cvtToStr(basicp->msb());
bounds += ","; bounds += cvtToStr(basicp->lsb());
dim++;
}
for (AstNodeDType* dtypep=varp->dtypep(); dtypep; ) {

View File

@ -486,6 +486,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
if (nodep->isSigned()) putfs(nodep,"signed ");
putfs(nodep,nodep->prettyName());
if (nodep->rangep()) { puts(" "); nodep->rangep()->iterateAndNext(*this); puts(" "); }
else if (nodep->msb()) { puts(" ["); puts(cvtToStr(nodep->msb())); puts(":0] "); }
}
virtual void visit(AstConstDType* nodep, AstNUser*) {
putfs(nodep,"const ");

View File

@ -204,6 +204,7 @@ private:
AstNRelinker replaceHandle;
nodep->unlinkFrBack(&replaceHandle);
AstNode* constzerop;
int m1value = nodep->widthMin()-1; // Constant of width-1; not changing dtype width
if (nodep->signedFlavor()) {
// Then over shifting gives the sign bit, not all zeros
// Note *NOT* clean output -- just like normal shift!
@ -212,7 +213,7 @@ private:
new AstShiftR(nodep->fileline(),
nodep->lhsp()->cloneTree(false),
new AstConst(nodep->fileline(),
nodep->widthMin()-1),
m1value),
nodep->width()));
} else {
V3Number zeronum (nodep->fileline(), nodep->width(), 0);

View File

@ -237,6 +237,7 @@ private:
= new AstVar (fl, AstVarType::MODULETEMP,
"__Vtable" + cvtToStr(m_modTables) +"_"+outvarp->name(),
new AstArrayDType (fl,
// FUTURE: If support more types, below can use outvarp->dtype()
new AstBasicDType(fl, AstLogicPacked(), outvarp->width()),
new AstRange (fl, VL_MASK_I(m_inWidth), 0)));
tablevarp->isConst(true);

View File

@ -405,7 +405,7 @@ private:
int frommsb = nodep->fromp()->width() - 1;
int fromlsb = 0;
AstNodeVarRef* varrp = nodep->fromp()->castNodeVarRef();
if (varrp && varrp->varp()->basicp()->rangep()) { // Selecting a bit from a multibit register
if (varrp && varrp->varp()->basicp()->isRanged()) { // Selecting a bit from a multibit register
frommsb = varrp->varp()->basicp()->msbMaxSelect(); // Corrected for negative lsb
fromlsb = varrp->varp()->basicp()->lsb();
}

View File

@ -83,7 +83,7 @@ private:
return adtypep;
}
else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
if (!adtypep->rangep()) {
if (!adtypep->isRanged()) {
nodep->v3error("Illegal bit select; variable does not have a bit range, or bad dimension: "<<varp->prettyName());
return NULL;
}
@ -145,13 +145,13 @@ private:
AstVar* varp = varFromBasefrom(basefromp);
// SUB #'s Not needed when LSB==0 and MSB>=0 (ie [0:-13] must still get added!)
if (!varp->basicp()->rangep()) {
// vector without range is ok, for example a INTEGER x; y = x[21:0];
// vector without range, or 0 lsb is ok, for example a INTEGER x; y = x[21:0];
return underp;
} else {
if (!varp->basicp()->rangep()->msbp()->castConst()
|| !varp->basicp()->rangep()->lsbp()->castConst())
varp->v3fatalSrc("Non-constant variable range; errored earlier"); // in constifyParam(varp)
if (varp->basicp()->rangep()->littleEndian()) {
if (varp->basicp()->littleEndian()) {
// reg [1:3] was swapped to [3:1] (lsbEndianedp==3) and needs a SUB(3,under)
AstNode* newp = newSubNeg(varp->basicp()->msb(), underp);
return newp;
@ -263,7 +263,7 @@ private:
}
} else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
if (adtypep) {} // Unused
if (varp->basicp()->rangep() && varp->basicp()->rangep()->littleEndian()) {
if (varp->basicp()->littleEndian()) {
// Below code assumes big bit endian; just works out if we swap
int x = msb; msb = lsb; lsb = x;
}
@ -308,7 +308,7 @@ private:
if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
AstSel* newp = NULL;
if (nodep->castSelPlus()) {
if (adtypep->rangep() && adtypep->rangep()->littleEndian()) {
if (adtypep->littleEndian()) {
// SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width)
newp = new AstSel (nodep->fileline(),
fromp,
@ -322,7 +322,7 @@ private:
widthp);
}
} else if (nodep->castSelMinus()) {
if (adtypep->rangep() && adtypep->rangep()->littleEndian()) {
if (adtypep->littleEndian()) {
// SELMINUS(from,msb,width) -> SEL(from, msb-[bit])
newp = new AstSel (nodep->fileline(),
fromp,

View File

@ -122,7 +122,7 @@ public:
// then [1:1] becomes the basicdtype range; everything else is arraying
// the final [5:5][4:4] will be passed in another call to createArray
AstRange* rangearraysp = NULL;
if (dtypep->rangep()) {
if (dtypep->isRanged()) {
rangearraysp = rangesp; // Already a range; everything is an array
} else {
AstRange* finalp = rangesp;