Internals: In AstBasicDType avoid use of Range for constants. No functional change.
This commit is contained in:
parent
7caafb4014
commit
d699247269
|
|
@ -269,7 +269,7 @@ AstNodeDType* AstVar::dtypeDimensionp(int dimension) const {
|
||||||
}
|
}
|
||||||
else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
|
else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
|
||||||
// AstBasicDType - nothing below, return null
|
// AstBasicDType - nothing below, return null
|
||||||
if (adtypep->rangep()) {
|
if (adtypep->isRanged()) {
|
||||||
if ((dim++) == dimension) {
|
if ((dim++) == dimension) {
|
||||||
return adtypep;
|
return adtypep;
|
||||||
}
|
}
|
||||||
|
|
@ -524,6 +524,7 @@ void AstAttrOf::dump(ostream& str) {
|
||||||
void AstBasicDType::dump(ostream& str) {
|
void AstBasicDType::dump(ostream& str) {
|
||||||
this->AstNodeDType::dump(str);
|
this->AstNodeDType::dump(str);
|
||||||
str<<" ["<<keyword().ascii()<<"]";
|
str<<" ["<<keyword().ascii()<<"]";
|
||||||
|
if (!rangep() && msb()) str<<" range["<<msb()<<":"<<lsb()<<"]";
|
||||||
if (implicit()) str<<" [IMPLICIT]";
|
if (implicit()) str<<" [IMPLICIT]";
|
||||||
}
|
}
|
||||||
void AstCCast::dump(ostream& str) {
|
void AstCCast::dump(ostream& str) {
|
||||||
|
|
|
||||||
|
|
@ -244,35 +244,38 @@ struct AstBasicDType : public AstNodeDType {
|
||||||
private:
|
private:
|
||||||
AstBasicDTypeKwd m_keyword; // What keyword created it
|
AstBasicDTypeKwd m_keyword; // What keyword created it
|
||||||
bool m_implicit; // Implicitly declared
|
bool m_implicit; // Implicitly declared
|
||||||
|
int m_msb; // MSB when no range attached
|
||||||
public:
|
public:
|
||||||
AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, AstSignedState signst=signedst_NOP)
|
AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, AstSignedState signst=signedst_NOP)
|
||||||
: AstNodeDType(fl) {
|
: AstNodeDType(fl) {
|
||||||
init(kwd, signst, NULL);
|
init(kwd, signst, 0, NULL);
|
||||||
}
|
}
|
||||||
AstBasicDType(FileLine* fl, AstLogicPacked, int wantwidth)
|
AstBasicDType(FileLine* fl, AstLogicPacked, int wantwidth)
|
||||||
: AstNodeDType(fl) {
|
: AstNodeDType(fl) {
|
||||||
init(AstBasicDTypeKwd::LOGIC, signedst_NOP,
|
init(AstBasicDTypeKwd::LOGIC, signedst_NOP, wantwidth, NULL);
|
||||||
((wantwidth > 1) ? new AstRange(fl, wantwidth-1, 0) : NULL));
|
|
||||||
}
|
}
|
||||||
AstBasicDType(FileLine* fl, AstBitPacked, int wantwidth)
|
AstBasicDType(FileLine* fl, AstBitPacked, int wantwidth)
|
||||||
: AstNodeDType(fl) {
|
: AstNodeDType(fl) {
|
||||||
init(AstBasicDTypeKwd::BIT, signedst_NOP,
|
init(AstBasicDTypeKwd::BIT, signedst_NOP, wantwidth, NULL);
|
||||||
((wantwidth > 1) ? new AstRange(fl, wantwidth-1, 0) : NULL));
|
|
||||||
}
|
}
|
||||||
// See also addRange in verilog.y
|
// See also addRange in verilog.y
|
||||||
private:
|
private:
|
||||||
void init(AstBasicDTypeKwd kwd, AstSignedState signst, AstRange* rangep) {
|
void init(AstBasicDTypeKwd kwd, AstSignedState signst, int wantwidth, AstRange* rangep) {
|
||||||
m_keyword = kwd;
|
m_keyword = kwd;
|
||||||
|
m_msb = 0;
|
||||||
// Implicitness: // "parameter X" is implicit and sized from initial value, "parameter reg x" not
|
// Implicitness: // "parameter X" is implicit and sized from initial value, "parameter reg x" not
|
||||||
m_implicit = false;
|
m_implicit = false;
|
||||||
if (keyword()==AstBasicDTypeKwd::LOGIC_IMPLICIT) {
|
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;
|
m_keyword = AstBasicDTypeKwd::LOGIC;
|
||||||
}
|
}
|
||||||
if (signst == signedst_NOP && keyword().isSigned()) signst = signedst_SIGNED;
|
if (signst == signedst_NOP && keyword().isSigned()) signst = signedst_SIGNED;
|
||||||
if (keyword().isDouble()) dtypeChgDouble();
|
if (keyword().isDouble()) dtypeChgDouble();
|
||||||
else setSignedState(signst);
|
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
|
// V3Width will pull from this width
|
||||||
if (keyword().width() > 1 && !isOpaque()) rangep = new AstRange(fileline(), keyword().width()-1, 0);
|
if (keyword().width() > 1 && !isOpaque()) rangep = new AstRange(fileline(), keyword().width()-1, 0);
|
||||||
width(keyword().width(), keyword().width());
|
width(keyword().width(), keyword().width());
|
||||||
|
|
@ -305,14 +308,22 @@ public:
|
||||||
bool isOpaque() const { return keyword().isOpaque(); }
|
bool isOpaque() const { return keyword().isOpaque(); }
|
||||||
bool isSloppy() const { return keyword().isSloppy(); }
|
bool isSloppy() const { return keyword().isSloppy(); }
|
||||||
bool isZeroInit() const { return keyword().isZeroInit(); }
|
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 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 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
|
int msbMaxSelect() const { return (lsb()<0 ? msb()-lsb() : msb()); } // Maximum value a [] select may index
|
||||||
bool littleEndian() const { return (rangep() && rangep()->littleEndian()); }
|
bool littleEndian() const { return (rangep() && rangep()->littleEndian()); }
|
||||||
bool implicit() const { return m_implicit; }
|
bool implicit() const { return m_implicit; }
|
||||||
void implicit(bool flag) { m_implicit = flag; }
|
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 {
|
struct AstConstDType : public AstNodeDType {
|
||||||
|
|
|
||||||
|
|
@ -1627,6 +1627,12 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simplify
|
||||||
|
virtual void visit(AstBasicDType* nodep, AstNUser*) {
|
||||||
|
nodep->iterateChildren(*this);
|
||||||
|
nodep->cvtRangeConst();
|
||||||
|
}
|
||||||
|
|
||||||
//-----
|
//-----
|
||||||
// Jump elimination
|
// Jump elimination
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,7 @@ private:
|
||||||
const ToggleEnt& above,
|
const ToggleEnt& above,
|
||||||
AstVar* varp, AstVar* chgVarp) { // Constant
|
AstVar* varp, AstVar* chgVarp) { // Constant
|
||||||
if (AstBasicDType* bdtypep = dtypep->castBasicDType()) {
|
if (AstBasicDType* bdtypep = dtypep->castBasicDType()) {
|
||||||
if (bdtypep->rangep()) {
|
if (bdtypep->isRanged()) {
|
||||||
for (int index_docs=bdtypep->lsb(); index_docs<bdtypep->msb()+1; index_docs++) {
|
for (int index_docs=bdtypep->lsb(); index_docs<bdtypep->msb()+1; index_docs++) {
|
||||||
int index_code = index_docs - bdtypep->lsb();
|
int index_code = index_docs - bdtypep->lsb();
|
||||||
ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]",
|
ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]",
|
||||||
|
|
|
||||||
|
|
@ -453,9 +453,9 @@ void EmitCSyms::emitSymImp() {
|
||||||
string bounds;
|
string bounds;
|
||||||
if (AstBasicDType* basicp = varp->basicp()) {
|
if (AstBasicDType* basicp = varp->basicp()) {
|
||||||
// Range is always first, it's not in "C" order
|
// Range is always first, it's not in "C" order
|
||||||
if (basicp->rangep()) {
|
if (basicp->isRanged()) {
|
||||||
bounds += " ,"; bounds += cvtToStr(basicp->rangep()->msbConst());
|
bounds += " ,"; bounds += cvtToStr(basicp->msb());
|
||||||
bounds += ","; bounds += cvtToStr(basicp->rangep()->lsbConst());
|
bounds += ","; bounds += cvtToStr(basicp->lsb());
|
||||||
dim++;
|
dim++;
|
||||||
}
|
}
|
||||||
for (AstNodeDType* dtypep=varp->dtypep(); dtypep; ) {
|
for (AstNodeDType* dtypep=varp->dtypep(); dtypep; ) {
|
||||||
|
|
|
||||||
|
|
@ -486,6 +486,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
||||||
if (nodep->isSigned()) putfs(nodep,"signed ");
|
if (nodep->isSigned()) putfs(nodep,"signed ");
|
||||||
putfs(nodep,nodep->prettyName());
|
putfs(nodep,nodep->prettyName());
|
||||||
if (nodep->rangep()) { puts(" "); nodep->rangep()->iterateAndNext(*this); puts(" "); }
|
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*) {
|
virtual void visit(AstConstDType* nodep, AstNUser*) {
|
||||||
putfs(nodep,"const ");
|
putfs(nodep,"const ");
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,7 @@ private:
|
||||||
AstNRelinker replaceHandle;
|
AstNRelinker replaceHandle;
|
||||||
nodep->unlinkFrBack(&replaceHandle);
|
nodep->unlinkFrBack(&replaceHandle);
|
||||||
AstNode* constzerop;
|
AstNode* constzerop;
|
||||||
|
int m1value = nodep->widthMin()-1; // Constant of width-1; not changing dtype width
|
||||||
if (nodep->signedFlavor()) {
|
if (nodep->signedFlavor()) {
|
||||||
// Then over shifting gives the sign bit, not all zeros
|
// Then over shifting gives the sign bit, not all zeros
|
||||||
// Note *NOT* clean output -- just like normal shift!
|
// Note *NOT* clean output -- just like normal shift!
|
||||||
|
|
@ -212,7 +213,7 @@ private:
|
||||||
new AstShiftR(nodep->fileline(),
|
new AstShiftR(nodep->fileline(),
|
||||||
nodep->lhsp()->cloneTree(false),
|
nodep->lhsp()->cloneTree(false),
|
||||||
new AstConst(nodep->fileline(),
|
new AstConst(nodep->fileline(),
|
||||||
nodep->widthMin()-1),
|
m1value),
|
||||||
nodep->width()));
|
nodep->width()));
|
||||||
} else {
|
} else {
|
||||||
V3Number zeronum (nodep->fileline(), nodep->width(), 0);
|
V3Number zeronum (nodep->fileline(), nodep->width(), 0);
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,7 @@ private:
|
||||||
= new AstVar (fl, AstVarType::MODULETEMP,
|
= new AstVar (fl, AstVarType::MODULETEMP,
|
||||||
"__Vtable" + cvtToStr(m_modTables) +"_"+outvarp->name(),
|
"__Vtable" + cvtToStr(m_modTables) +"_"+outvarp->name(),
|
||||||
new AstArrayDType (fl,
|
new AstArrayDType (fl,
|
||||||
|
// FUTURE: If support more types, below can use outvarp->dtype()
|
||||||
new AstBasicDType(fl, AstLogicPacked(), outvarp->width()),
|
new AstBasicDType(fl, AstLogicPacked(), outvarp->width()),
|
||||||
new AstRange (fl, VL_MASK_I(m_inWidth), 0)));
|
new AstRange (fl, VL_MASK_I(m_inWidth), 0)));
|
||||||
tablevarp->isConst(true);
|
tablevarp->isConst(true);
|
||||||
|
|
|
||||||
|
|
@ -405,7 +405,7 @@ private:
|
||||||
int frommsb = nodep->fromp()->width() - 1;
|
int frommsb = nodep->fromp()->width() - 1;
|
||||||
int fromlsb = 0;
|
int fromlsb = 0;
|
||||||
AstNodeVarRef* varrp = nodep->fromp()->castNodeVarRef();
|
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
|
frommsb = varrp->varp()->basicp()->msbMaxSelect(); // Corrected for negative lsb
|
||||||
fromlsb = varrp->varp()->basicp()->lsb();
|
fromlsb = varrp->varp()->basicp()->lsb();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ private:
|
||||||
return adtypep;
|
return adtypep;
|
||||||
}
|
}
|
||||||
else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
|
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());
|
nodep->v3error("Illegal bit select; variable does not have a bit range, or bad dimension: "<<varp->prettyName());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -145,13 +145,13 @@ private:
|
||||||
AstVar* varp = varFromBasefrom(basefromp);
|
AstVar* varp = varFromBasefrom(basefromp);
|
||||||
// SUB #'s Not needed when LSB==0 and MSB>=0 (ie [0:-13] must still get added!)
|
// SUB #'s Not needed when LSB==0 and MSB>=0 (ie [0:-13] must still get added!)
|
||||||
if (!varp->basicp()->rangep()) {
|
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;
|
return underp;
|
||||||
} else {
|
} else {
|
||||||
if (!varp->basicp()->rangep()->msbp()->castConst()
|
if (!varp->basicp()->rangep()->msbp()->castConst()
|
||||||
|| !varp->basicp()->rangep()->lsbp()->castConst())
|
|| !varp->basicp()->rangep()->lsbp()->castConst())
|
||||||
varp->v3fatalSrc("Non-constant variable range; errored earlier"); // in constifyParam(varp)
|
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)
|
// reg [1:3] was swapped to [3:1] (lsbEndianedp==3) and needs a SUB(3,under)
|
||||||
AstNode* newp = newSubNeg(varp->basicp()->msb(), underp);
|
AstNode* newp = newSubNeg(varp->basicp()->msb(), underp);
|
||||||
return newp;
|
return newp;
|
||||||
|
|
@ -263,7 +263,7 @@ private:
|
||||||
}
|
}
|
||||||
} else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
|
} else if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
|
||||||
if (adtypep) {} // Unused
|
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
|
// Below code assumes big bit endian; just works out if we swap
|
||||||
int x = msb; msb = lsb; lsb = x;
|
int x = msb; msb = lsb; lsb = x;
|
||||||
}
|
}
|
||||||
|
|
@ -308,7 +308,7 @@ private:
|
||||||
if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
|
if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
|
||||||
AstSel* newp = NULL;
|
AstSel* newp = NULL;
|
||||||
if (nodep->castSelPlus()) {
|
if (nodep->castSelPlus()) {
|
||||||
if (adtypep->rangep() && adtypep->rangep()->littleEndian()) {
|
if (adtypep->littleEndian()) {
|
||||||
// SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width)
|
// SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width)
|
||||||
newp = new AstSel (nodep->fileline(),
|
newp = new AstSel (nodep->fileline(),
|
||||||
fromp,
|
fromp,
|
||||||
|
|
@ -322,7 +322,7 @@ private:
|
||||||
widthp);
|
widthp);
|
||||||
}
|
}
|
||||||
} else if (nodep->castSelMinus()) {
|
} else if (nodep->castSelMinus()) {
|
||||||
if (adtypep->rangep() && adtypep->rangep()->littleEndian()) {
|
if (adtypep->littleEndian()) {
|
||||||
// SELMINUS(from,msb,width) -> SEL(from, msb-[bit])
|
// SELMINUS(from,msb,width) -> SEL(from, msb-[bit])
|
||||||
newp = new AstSel (nodep->fileline(),
|
newp = new AstSel (nodep->fileline(),
|
||||||
fromp,
|
fromp,
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ public:
|
||||||
// then [1:1] becomes the basicdtype range; everything else is arraying
|
// 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
|
// the final [5:5][4:4] will be passed in another call to createArray
|
||||||
AstRange* rangearraysp = NULL;
|
AstRange* rangearraysp = NULL;
|
||||||
if (dtypep->rangep()) {
|
if (dtypep->isRanged()) {
|
||||||
rangearraysp = rangesp; // Already a range; everything is an array
|
rangearraysp = rangesp; // Already a range; everything is an array
|
||||||
} else {
|
} else {
|
||||||
AstRange* finalp = rangesp;
|
AstRange* finalp = rangesp;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue