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()) {
|
||||
// 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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -1627,6 +1627,12 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
// Simplify
|
||||
virtual void visit(AstBasicDType* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->cvtRangeConst();
|
||||
}
|
||||
|
||||
//-----
|
||||
// Jump elimination
|
||||
|
||||
|
|
|
|||
|
|
@ -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)+"]",
|
||||
|
|
|
|||
|
|
@ -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; ) {
|
||||
|
|
|
|||
|
|
@ -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 ");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue