From 8e6846d9da8e1799e72af8568672803a90b24643 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 15 Nov 2009 08:52:19 -0500 Subject: [PATCH] Internals: Remove AstVar methods in preference of going via dtype --- src/V3Ast.h | 4 ++-- src/V3AstNodes.h | 37 +++++++++++++++++++++---------------- src/V3Const.cpp | 13 +++++++------ src/V3EmitC.cpp | 15 ++++++++------- src/V3Inst.cpp | 19 ++++++++++++++----- src/V3Width.cpp | 4 ++-- src/V3WidthSel.cpp | 17 ++++++++--------- 7 files changed, 62 insertions(+), 47 deletions(-) diff --git a/src/V3Ast.h b/src/V3Ast.h index 3ced513c8..707561287 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -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,... }; diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 6ce0a0af8..1fc96264b 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -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(); diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 4fa9fe5c5..23d8f0f0b 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -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: " <msbConst()<<":"<lsbConst() - <<" outside "<msbMaxSelect()<<":0" - <<(varp->lsb()>=0 ? "" - :" (adjusted +"+cvtToStr(-varp->lsb())+" to account for negative lsb)")); + <<" outside "<msbMaxSelect()<<":0" + <<(bdtypep->lsb()>=0 ? "" + :" (adjusted +"+cvtToStr(-bdtypep->lsb())+" to account for negative lsb)")); // Don't replace with zero, we'll do it later } } diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 36a06eb99..92020be49 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -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"); } } diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index 9821f266f..a3c81c627 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -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. diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 84c725466..0edb3183c 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -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()); diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index cc9bc2c15..dd10b0950 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -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: "<prettyName()); if (width<0) nodep->v3error("Width of :+ or :- is < 0: "<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 {