Internals: Remove AstVar methods in preference of going via dtype

This commit is contained in:
Wilson Snyder 2009-11-15 08:52:19 -05:00
parent fd38216eda
commit 8e6846d9da
7 changed files with 62 additions and 47 deletions

View File

@ -1197,8 +1197,8 @@ struct AstNodeDType : public AstNode {
AstNodeDType(FileLine* fl) : AstNode(fl) {}
ASTNODE_BASE_FUNCS(NodeDType)
// Accessors
virtual AstBasicDType* basicp() = 0; // (Slow) recurse down to find basic data type
virtual AstNodeDType* skipRefp() = 0; // recurses over typedefs to next non-typeref type
virtual AstBasicDType* basicp() const = 0; // (Slow) recurse down to find basic data type
virtual AstNodeDType* skipRefp() const = 0; // recurses over typedefs to next non-typeref type
virtual int widthAlignBytes() const = 0; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
virtual int widthTotalBytes() const = 0; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
};

View File

@ -153,8 +153,8 @@ struct AstArrayDType : public AstNodeDType {
AstRange* arrayp() const { return op2p()->castRange(); } // op2 = Array(s) of variable
void arrayp(AstRange* nodep) { setOp2p(nodep); }
// METHODS
virtual AstBasicDType* basicp() { return dtypep()->basicp(); } // (Slow) recurse down to find basic data type
virtual AstNodeDType* skipRefp() { return this; }
virtual AstBasicDType* basicp() const { return dtypep()->basicp(); } // (Slow) recurse down to find basic data type
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); }
virtual int widthTotalBytes() const { return elementsConst() * dtypep()->widthTotalBytes(); }
int msb() const { return arrayp()->msbConst(); }
@ -203,6 +203,9 @@ private:
public:
ASTNODE_NODE_FUNCS(BasicDType, BASICDTYPE)
virtual void dump(ostream& str);
virtual V3Hash sameHash() const { return V3Hash(keyword()); }
virtual bool same(AstNode* samep) const {
return samep->castBasicDType()->keyword() == keyword(); }
virtual string name() const {
if (rangep()) return string(m_keyword.ascii())+"[]";
else return m_keyword.ascii();
@ -213,8 +216,8 @@ public:
if (signst!=signedst_NOP) isSigned(signst==signedst_SIGNED);
}
// METHODS
virtual AstBasicDType* basicp() { return this; } // (Slow) recurse down to find basic data type
virtual AstNodeDType* skipRefp() { return this; }
virtual AstBasicDType* basicp() const { return (AstBasicDType*)this; } // (Slow) recurse down to find basic data type
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
bool isBitLogic() const { return keyword().isBitLogic(); }
@ -247,10 +250,13 @@ public:
virtual void cloneRelink() { if (m_defp && m_defp->clonep()) {
m_defp = m_defp->clonep()->castTypedef();
}}
virtual V3Hash sameHash() const { return V3Hash(skipRefp()); }
virtual bool same(AstNode* samep) const {
return skipRefp()->sameTree(samep->castRefDType()->skipRefp()); }
virtual void dump(ostream& str=cout);
virtual string name() const { return m_name; }
virtual AstBasicDType* basicp() { return defp() ? dtypep()->basicp() : NULL; }
virtual AstNodeDType* skipRefp() {
virtual AstBasicDType* basicp() const { return defp() ? dtypep()->basicp() : NULL; }
virtual AstNodeDType* skipRefp() const {
// Skip past both the Ref and the Typedef
if (defp()) return defp()->dtypep();
else { v3fatalSrc("Typedef not linked"); return NULL; }
@ -436,7 +442,9 @@ public:
, m_name(name) {
init();
combineType(type); setOp1p(dtypep);
width(msb()-lsb()+1,0);
if (dtypep && dtypep->basicp()) {
width(dtypep->basicp()->width(), 0);
} else width(1, 0);
}
AstVar(FileLine* fl, AstVarType type, const string& name, AstLogicPacked, int wantwidth)
:AstNode(fl)
@ -468,14 +476,15 @@ public:
string scType() const; // Return SysC type: bool, uint32_t, uint64_t, sc_bv
void combineType(AstVarType type);
AstNodeDType* dtypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable
AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType)
AstBasicDType* basicp() const { return dtypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType)
AstNodeDType* dtypeDimensionp(int depth) const;
AstNode* initp() const { return op3p()->castNode(); } // op3 = Initial value that never changes (static const)
void initp(AstNode* nodep) { setOp3p(nodep); }
void addAttrsp(AstNode* nodep) { addNOp4p(nodep); }
AstNode* attrsp() const { return op4p()->castNode(); } // op4 = Attributes during early parse
bool hasSimpleInit() const { return (op3p() && !op3p()->castInitArray()); }
void dtypep(AstRange* nodep) { setOp1p(nodep); }
void dtypep(AstNodeDType* nodep) { setOp1p(nodep); }
void attrClockEn(bool flag) { m_attrClockEn = flag; }
void attrFileDescr(bool flag) { m_fileDescr = flag; }
void attrScClocked(bool flag) { m_scClocked = flag; }
@ -493,7 +502,6 @@ public:
void funcReturn(bool flag) { m_funcReturn = flag; }
void trace(bool flag) { m_trace=flag; }
// METHODS
AstBasicDType* basicp() const { return dtypep()->basicp(); } // (Slow) recurse down to find basic data type
virtual void name(const string& name) { m_name = name; }
bool isInput() const { return m_input; }
bool isOutput() const { return m_output; }
@ -536,11 +544,6 @@ public:
bool attrFileDescr() const { return m_fileDescr; }
bool attrScClocked() const { return m_scClocked; }
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
int msb() const { AstBasicDType* bdtypep = basicp(); return bdtypep ? bdtypep->msb() : 0; }
int lsb() const { AstBasicDType* bdtypep = basicp(); return bdtypep ? bdtypep->lsb() : 0; }
int msbEndianed() const { AstBasicDType* bdtypep = basicp(); return bdtypep ? bdtypep->msbEndianed() : 0; }
int lsbEndianed() const { AstBasicDType* bdtypep = basicp(); return bdtypep ? bdtypep->lsbEndianed() : 0; }
int msbMaxSelect() const { AstBasicDType* bdtypep = basicp(); return bdtypep ? bdtypep->msbMaxSelect() : 0; }
uint32_t arrayElements() const; // 1, or total multiplication of all dimensions
virtual string verilogKwd() const;
void propagateAttrFrom(AstVar* fromp) {
@ -1780,7 +1783,9 @@ public:
widthSignedFrom(varp);
m_code = 0;
m_codeInc = varp->arrayElements() * varp->widthWords();
m_lsb = varp->lsbEndianed(); m_msb = varp->msbEndianed();
AstBasicDType* bdtypep = varp->basicp();
m_msb = bdtypep ? bdtypep->msbEndianed() : 0;
m_lsb = bdtypep ? bdtypep->lsbEndianed() : 0;
if (AstArrayDType* adtypep = varp->dtypeSkipRefp()->castArrayDType()) {
m_arrayLsb = adtypep->arrayp()->lsbConst();
m_arrayMsb = adtypep->arrayp()->msbConst();

View File

@ -310,10 +310,11 @@ private:
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
AstVar* varp = varrefp->varp();
if (!varp->dtypep()) varp->v3fatalSrc("Data type lost");
AstBasicDType* bdtypep = varp->basicp(); if (!bdtypep) varp->v3fatalSrc("Select of non-selectable type");
if (m_warn
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& (!varp->basicp()->rangep() || varp->msb())) { // else it's non-resolvable parameterized
&& (!bdtypep->rangep() || bdtypep->msb())) { // else it's non-resolvable parameterized
if (nodep->lsbp()->castConst()->num().isFourState()
|| nodep->widthp()->castConst()->num().isFourState()) {
nodep->v3error("Selection index is constantly unknown or tristated: "
@ -321,14 +322,14 @@ private:
// Replacing nodep will make a mess above, so we replace the offender
replaceZero(nodep->lsbp());
}
else if ((nodep->msbConst() > varp->msbMaxSelect())
|| (nodep->lsbConst() > varp->msbMaxSelect())) {
else if ((nodep->msbConst() > bdtypep->msbMaxSelect())
|| (nodep->lsbConst() > bdtypep->msbMaxSelect())) {
// See also warning in V3Width
nodep->v3error("Selection index out of range: "
<<nodep->msbConst()<<":"<<nodep->lsbConst()
<<" outside "<<varp->msbMaxSelect()<<":0"
<<(varp->lsb()>=0 ? ""
:" (adjusted +"+cvtToStr(-varp->lsb())+" to account for negative lsb)"));
<<" outside "<<bdtypep->msbMaxSelect()<<":0"
<<(bdtypep->lsb()>=0 ? ""
:" (adjusted +"+cvtToStr(-bdtypep->lsb())+" to account for negative lsb)"));
// Don't replace with zero, we'll do it later
}
}

View File

@ -755,6 +755,7 @@ public:
// Internal EmitCStmts
void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
AstBasicDType* basicp = nodep->basicp(); if (!basicp) nodep->v3fatalSrc("Unimplemented: Outputting this data type");
if (nodep->isIO()) {
if (nodep->isSc()) {
m_ctorVarsVec.push_back(nodep);
@ -786,12 +787,12 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
if (!nodep->isWide())
puts("("+nodep->name()
+","+cvtToStr(nodep->msb())
+","+cvtToStr(nodep->lsb()));
+","+cvtToStr(basicp->msb())
+","+cvtToStr(basicp->lsb()));
else puts("W("+nodep->name()
+","+cvtToStr(nodep->msb())
+","+cvtToStr(nodep->lsb())
+","+cvtToStr(nodep->widthWords()));
+","+cvtToStr(basicp->msb())
+","+cvtToStr(basicp->lsb())
+","+cvtToStr(basicp->widthWords()));
puts(");\n");
}
} else {
@ -818,8 +819,8 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) {
puts("["+cvtToStr(arrayp->elementsConst())+"]");
}
puts(","+cvtToStr(nodep->msb())+","+cvtToStr(nodep->lsb()));
if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords()));
puts(","+cvtToStr(basicp->msb())+","+cvtToStr(basicp->lsb()));
if (basicp->isWide()) puts(","+cvtToStr(basicp->widthWords()));
puts(");\n");
}
}

View File

@ -238,12 +238,21 @@ void V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule* mod
// Note this module calles cloneTree() via new AstVar
AstVar* pinVarp = pinp->modVarp();
AstVarRef* connectRefp = pinp->exprp()->castVarRef();
AstBasicDType* pinBasicp = pinVarp->dtypep()->basicp(); // Maybe NULL
AstBasicDType* connBasicp = NULL;
if (connectRefp) connBasicp = connectRefp->varp()->dtypep()->basicp();
//
if (connectRefp
&& connectRefp->width() == pinVarp->width()
&& connectRefp->varp()->lsb() == pinVarp->lsb()
&& !connectRefp->varp()->isSc() // Need the signal as a 'shell' to convert types
&& pinp->width() == pinVarp->width()
&& 1) {
&& connectRefp->varp()->dtypep()->sameTree(pinVarp->dtypep())
&& !connectRefp->varp()->isSc()) { // Need the signal as a 'shell' to convert types
// Done. Same data type
} else if (connBasicp
&& pinBasicp
&& connBasicp->width() == pinBasicp->width()
&& connBasicp->lsb() == pinBasicp->lsb()
&& !connectRefp->varp()->isSc() // Need the signal as a 'shell' to convert types
&& pinp->width() == pinVarp->width()
&& 1) {
// Done. One to one interconnect won't need a temporary variable.
} else if (pinp->exprp()->castConst()) {
// Done. Constant.

View File

@ -301,8 +301,8 @@ private:
int fromlsb = 0;
AstNodeVarRef* varrp = nodep->fromp()->castNodeVarRef();
if (varrp && varrp->varp()->basicp()->rangep()) { // Selecting a bit from a multibit register
frommsb = varrp->varp()->msbMaxSelect(); // Corrected for negative lsb
fromlsb = varrp->varp()->lsb();
frommsb = varrp->varp()->basicp()->msbMaxSelect(); // Corrected for negative lsb
fromlsb = varrp->varp()->basicp()->lsb();
}
int selwidth = V3Number::log2b(frommsb+1-1)+1; // Width to address a bit
nodep->fromp()->iterateAndNext(*this,WidthVP(selwidth,selwidth,FINAL).p());

View File

@ -149,11 +149,11 @@ private:
varp->v3fatalSrc("Non-constant variable range; errored earlier"); // in constifyParam(varp)
if (varp->basicp()->rangep()->littleEndian()) {
// reg [1:3] was swapped to [3:1] (lsbEndianedp==3) and needs a SUB(3,under)
AstNode* newp = newSubNeg(varp->msb(), underp);
AstNode* newp = newSubNeg(varp->basicp()->msb(), underp);
return newp;
} else {
// reg [3:1] needs a SUB(under,1)
AstNode* newp = newSubNeg(underp, varp->lsb());
AstNode* newp = newSubNeg(underp, varp->basicp()->lsb());
return newp;
}
}
@ -287,19 +287,18 @@ private:
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
AstNode* widthp = nodep->thsp()->unlinkFrBack();
int width = widthp->castConst()->toSInt();
AstVar* varp = varFromBasefrom(basefromp);
//AstVar* varp = varFromBasefrom(basefromp);
if (width > (1<<28)) nodep->v3error("Width of :+ or :- is huge; vector of over 1billion bits: "<<widthp->prettyName());
if (width<0) nodep->v3error("Width of :+ or :- is < 0: "<<widthp->prettyName());
AstNodeDType* ddtypep = dtypeForExtractp(nodep, basefromp, dimension, width!=1);
if (AstBasicDType* adtypep = ddtypep->castBasicDType()) {
if (adtypep) {} // Unused
AstSel* newp = NULL;
if (nodep->castSelPlus()) {
if (varp->basicp()->rangep() && varp->basicp()->rangep()->littleEndian()) {
if (adtypep->rangep() && adtypep->rangep()->littleEndian()) {
// SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width)
newp = new AstSel (nodep->fileline(),
fromp,
newSubNeg((varp->msb()-width+1), rhsp),
newSubNeg((adtypep->msb()-width+1), rhsp),
widthp);
} else {
// SELPLUS(from,lsb,width) -> SEL(from, lsb-vector_lsb, width)
@ -309,17 +308,17 @@ private:
widthp);
}
} else if (nodep->castSelMinus()) {
if (varp->basicp()->rangep() && varp->basicp()->rangep()->littleEndian()) {
if (adtypep->rangep() && adtypep->rangep()->littleEndian()) {
// SELMINUS(from,msb,width) -> SEL(from, msb-[bit])
newp = new AstSel (nodep->fileline(),
fromp,
newSubNeg(varp->msb(), rhsp),
newSubNeg(adtypep->msb(), rhsp),
widthp);
} else {
// SELMINUS(from,msb,width) -> SEL(from, msb-(width-1)-lsb#)
newp = new AstSel (nodep->fileline(),
fromp,
newSubNeg(rhsp, varp->lsb()+(width-1)),
newSubNeg(rhsp, adtypep->lsb()+(width-1)),
widthp);
}
} else {