From b104ab9491fdd5609ee8343312a9b57caa9d91dc Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 20 Feb 2012 20:48:13 -0500 Subject: [PATCH] Internals: AstRefDType points to type _below_ AstTyperef. No functional change --- bin/verilator_difftree | 2 +- src/V3Ast.h | 7 ++++++- src/V3AstNodes.h | 32 ++++++++++++++++---------------- src/V3EmitC.cpp | 4 ++-- src/V3Link.cpp | 2 +- src/V3Width.cpp | 24 ++++++++++++++---------- src/Verilator.cpp | 2 +- 7 files changed, 41 insertions(+), 32 deletions(-) diff --git a/bin/verilator_difftree b/bin/verilator_difftree index f280782f0..f3d8986ce 100755 --- a/bin/verilator_difftree +++ b/bin/verilator_difftree @@ -193,5 +193,5 @@ C ###################################################################### ### Local Variables: -### compile-command: "$V4/bin/verilator_difftree $V4/test_c/obj_dir/V*_03_*.tree $V4N/test_c/obj_dir/V*_03_*.tree" +### compile-command: "$V4/bin/verilator_difftree {$V4D,$V4}/test_regress/obj_dir/t_EXAMPLE/V*_03_*.tree" ### End: diff --git a/src/V3Ast.h b/src/V3Ast.h index 0c2fba3ea..1fa35e9a0 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1269,16 +1269,18 @@ private: string m_name; // Name of variable string m_hiername; // Scope converted into name-> for emitting bool m_hierThis; // Hiername points to "this" function + void init(); public: AstNodeVarRef(FileLine* fl, const string& name, bool lvalue) : AstNodeMath(fl), m_lvalue(lvalue), m_varp(NULL), m_varScopep(NULL), m_packagep(NULL), m_name(name), m_hierThis(false) { + init(); } AstNodeVarRef(FileLine* fl, const string& name, AstVar* varp, bool lvalue) : AstNodeMath(fl), m_lvalue(lvalue), m_varp(varp), m_varScopep(NULL), m_packagep(NULL), m_name(name), m_hierThis(false) { // May have varp==NULL - if (m_varp) widthSignedFrom((AstNode*)m_varp); + init(); } ASTNODE_BASE_FUNCS(NodeVarRef) virtual bool broken() const; @@ -1331,6 +1333,7 @@ struct AstNodeDType : public AstNode { 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,... + virtual bool maybePointedTo() const { return true; } }; struct AstNodeSel : public AstNodeBiop { @@ -1512,4 +1515,6 @@ inline bool AstNode::isOne() { return (this->castConst() && this->castConst inline bool AstNode::isAllOnes() { return (this->castConst() && this->castConst()->isEqAllOnes()); } inline bool AstNode::isAllOnesV() { return (this->castConst() && this->castConst()->isEqAllOnesV()); } +inline void AstNodeVarRef::init() { if (m_varp) widthSignedFrom((AstNode*)m_varp); } + #endif // Guard diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 7f73ff473..2577a8d11 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -68,11 +68,11 @@ public: class LogicFalse {}; AstConst(FileLine* fl, LogicFalse) // Shorthand const 0, know the dtype should be a logic of size 1 :AstNodeMath(fl) - ,m_num(V3Number(fl,1,0)) { width(1,0); } + ,m_num(V3Number(fl,1,0)) { dtypeChgLogicBool(); } class LogicTrue {}; AstConst(FileLine* fl, LogicTrue) // Shorthand const 1, know the dtype should be a logic of size 1 :AstNodeMath(fl) - ,m_num(V3Number(fl,1,1)) { width(1,0); } + ,m_num(V3Number(fl,1,1)) { dtypeChgLogicBool(); } ASTNODE_NODE_FUNCS(Const, CONST) virtual string name() const { return num().ascii(); } // * = Value @@ -347,43 +347,43 @@ struct AstConstDType : public AstNodeDType { struct AstRefDType : public AstNodeDType { private: - AstTypedef* m_defp; - string m_name; + AstNodeDType* m_defp; // data type pointed to, BELOW the AstTypedef + string m_name; // Name of an AstTypedef AstPackage* m_packagep; // Package hierarchy public: AstRefDType(FileLine* fl, const string& name) : AstNodeDType(fl), m_defp(NULL), m_name(name), m_packagep(NULL) {} - AstRefDType(FileLine* fl, AstTypedef* defp) - : AstNodeDType(fl), m_defp(defp), m_name(defp->name()), m_packagep(NULL) { + AstRefDType(FileLine* fl, AstNodeDType* defp) + : AstNodeDType(fl), m_defp(defp), m_packagep(NULL) { widthSignedFrom(defp); } ASTNODE_NODE_FUNCS(RefDType, REFDTYPE) // METHODS virtual bool broken() const { return m_defp && !m_defp->brokeExists(); } virtual void cloneRelink() { if (m_defp && m_defp->clonep()) { - m_defp = m_defp->clonep()->castTypedef(); + m_defp = m_defp->clonep()->castNodeDType(); }} 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() const { return defp() ? dtypep()->basicp() : NULL; } + virtual AstBasicDType* basicp() const { return defp() ? defp()->basicp() : NULL; } virtual AstNodeDType* skipRefp() const { // Skip past both the Ref and the Typedef - if (defp()) return defp()->dtypep()->skipRefp(); + if (defp()) return defp()->skipRefp(); else { v3fatalSrc("Typedef not linked"); return NULL; } } - virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); } - virtual int widthTotalBytes() const { return dtypep()->widthTotalBytes(); } + virtual int widthAlignBytes() const { return dtypeSkipRefp()->widthAlignBytes(); } + virtual int widthTotalBytes() const { return dtypeSkipRefp()->widthTotalBytes(); } void name(const string& flag) { m_name = flag; } AstNodeDType* dtypep() const { - if (defp()) return defp()->dtypep(); + if (defp()) return defp(); else { v3fatalSrc("Typedef not linked"); return NULL; } } AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable - AstTypedef* defp() const { return m_defp; } - void defp(AstTypedef* nodep) { m_defp=nodep; } + AstNodeDType* defp() const { return m_defp; } + void defp(AstNodeDType* nodep) { m_defp=nodep; } AstPackage* packagep() const { return m_packagep; } void packagep(AstPackage* nodep) { m_packagep=nodep; } }; @@ -496,7 +496,7 @@ struct AstWordSel : public AstNodeSel { // Select a single word from a multi-word wide value AstWordSel(FileLine* fl, AstNode* fromp, AstNode* bitp) :AstNodeSel(fl, fromp, bitp) { - width(VL_WORDSIZE,VL_WORDSIZE); // Always used on, and returns word entities + dtypeChgUInt32(); // Always used on IData arrays so returns word entities } ASTNODE_NODE_FUNCS(WordSel, WORDSEL) virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit) { V3ERROR_NA; } @@ -2363,8 +2363,8 @@ public: ASTNODE_NODE_FUNCS(TraceDecl, TRACEDECL) virtual string name() const { return m_showname; } virtual bool maybePointedTo() const { return true; } - string showname() const { return m_showname; } // * = Var name virtual bool same(AstNode* samep) const { return false; } + string showname() const { return m_showname; } // * = Var name // Details on what we're tracing uint32_t code() const { return m_code; } void code(uint32_t code) { m_code=code; } diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 66c2a7cf9..de8e49791 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -677,10 +677,10 @@ class EmitCImp : EmitCStmts { puts(" | ("); } changep->lhsp()->iterateAndNext(*this); - if (changep->isWide()) puts("["+cvtToStr(word)+"]"); + if (changep->lhsp()->isWide()) puts("["+cvtToStr(word)+"]"); puts(" ^ "); changep->rhsp()->iterateAndNext(*this); - if (changep->isWide()) puts("["+cvtToStr(word)+"]"); + if (changep->lhsp()->isWide()) puts("["+cvtToStr(word)+"]"); puts(")"); } } diff --git a/src/V3Link.cpp b/src/V3Link.cpp index 3928eae73..0cb50f1e1 100644 --- a/src/V3Link.cpp +++ b/src/V3Link.cpp @@ -550,7 +550,7 @@ private: defp = m_curVarsp->findIdUpward(nodep->name())->castTypedef(); } if (!defp) { nodep->v3error("Can't find typedef: "<prettyName()); } - nodep->defp(defp); + nodep->defp(defp->dtypep()); nodep->packagep(packageFor(defp)); } nodep->iterateChildren(*this); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 85bcf261b..8ccfd3efc 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -136,7 +136,7 @@ private: virtual void visit(AstLogOr* nodep, AstNUser* vup) { visit_log_O1_LR1rus(nodep,vup); } virtual void visit(AstLogIf* nodep, AstNUser* vup) { visit_log_O1_LR1rus(nodep,vup); } // Conversion from real not in IEEE, but a fallout virtual void visit(AstLogIff* nodep, AstNUser* vup) { visit_log_O1_LR1rus(nodep,vup); } // Conversion from real not in IEEE, but a fallout - + // Widths: 1 bit out, Any width lhs virtual void visit(AstRedAnd* nodep, AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,false); } virtual void visit(AstRedOr* nodep, AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,false); } @@ -145,7 +145,7 @@ private: virtual void visit(AstIsUnknown* nodep,AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,true); } // Allow real virtual void visit(AstOneHot* nodep,AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,false); } virtual void visit(AstOneHot0* nodep,AstNUser* vup) { visit_red_O1_Lrus(nodep,vup,false); } - + // These have different node types, as they operate differently // Must add to case statement below, // Widths: 1 bit out, lhs width == rhs width. real if lhs|rhs real @@ -199,7 +199,7 @@ private: virtual void visit(AstNegate* nodep, AstNUser* vup) { visit_math_Orus_Dreplace(nodep,vup,true); } // Unary never real virtual void visit(AstNot* nodep, AstNUser* vup) { visit_math_Orus_Dreplace(nodep,vup,false); } - + // Real: inputs and output real virtual void visit(AstAddD* nodep, AstNUser* vup) { visit_math_Or_LRr(nodep,vup); } virtual void visit(AstSubD* nodep, AstNUser* vup) { visit_math_Or_LRr(nodep,vup); } @@ -215,18 +215,18 @@ private: virtual void visit(AstLogD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); } virtual void visit(AstLog10D* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); } virtual void visit(AstSqrtD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); } - - // Widths: out signed/unsigned width = lhs width, input un|signed + + // Widths: out signed/unsigned width = lhs width, input un|signed virtual void visit(AstSigned* nodep, AstNUser* vup) { visit_Ous_Lus_Wforce(nodep,vup,AstNumeric::SIGNED); } virtual void visit(AstUnsigned* nodep, AstNUser* vup) { visit_Ous_Lus_Wforce(nodep,vup,AstNumeric::UNSIGNED); } - + // Widths: Output width from lhs, rhs<33 bits // Signed: If lhs signed virtual void visit(AstShiftL* nodep, AstNUser* vup) { visit_shift_Ous_Lus_Rus32(nodep,vup); } virtual void visit(AstShiftR* nodep, AstNUser* vup) { visit_shift_Ous_Lus_Rus32(nodep,vup); } // ShiftRS converts to ShiftR, but not vice-versa virtual void visit(AstShiftRS* nodep, AstNUser* vup) { visit_shift_Ous_Lus_Rus32(nodep,vup); } - + //======== // Widths: Output real, input integer signed virtual void visit(AstBitsToRealD* nodep, AstNUser* vup) { visit_Or_Lu64(nodep,vup); } @@ -235,7 +235,7 @@ private: // Widths: Output integer signed, input real virtual void visit(AstRToIS* nodep, AstNUser* vup) { visit_Os32_Lr(nodep,vup); } virtual void visit(AstRToIRoundS* nodep, AstNUser* vup) { visit_Os32_Lr(nodep,vup); } - + // Widths: Output integer unsigned, input real virtual void visit(AstRealToBits* nodep, AstNUser* vup) { visit_Ou64_Lr(nodep,vup); } @@ -295,7 +295,7 @@ private: checkCvtUS(nodep->rhsp()); nodep->width(nodep->lhsp()->width() + nodep->rhsp()->width(), nodep->lhsp()->widthMin() + nodep->rhsp()->widthMin()); - nodep->numeric(AstNumeric::UNSIGNED); + nodep->numeric(AstNumeric::UNSIGNED); // Cleanup zero width Verilog2001 {x,{0{foo}}} now, // otherwise having width(0) will cause later assertions to fire if (AstReplicate* repp=nodep->lhsp()->castReplicate()) { @@ -613,6 +613,7 @@ private: // But also cleanup array size nodep->arrayp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->widthFrom(nodep->dtypep()); + UINFO(4,"dtWidthed "<rangep()) { @@ -621,15 +622,18 @@ private: } // else width in node is correct; it was set based on keyword().width() // at construction time. Ditto signed, so "unsigned byte" etc works right. + UINFO(4,"dtWidthed "<iterateChildren(*this, vup); nodep->widthFrom(nodep->dtypep()); + UINFO(4,"dtWidthed "<iterateChildren(*this, vup); if (nodep->defp()) nodep->defp()->iterate(*this,vup); nodep->widthSignedFrom(nodep->dtypeSkipRefp()); + UINFO(4,"dtWidthed "<iterateChildren(*this, vup); @@ -1365,7 +1369,7 @@ private: // COMPARES // Widths: 1 bit out, lhs width == rhs width // Signed: if RHS&LHS signed, OPERATOR CHANGES to signed flavor - // Real: allowed on RHS, if RHS|LHS is real, both become real, and OPERATOR CHANGES + // Real: allowed on RHS, if RHS|LHS is real, both become real, and OPERATOR CHANGES if (vup->c()->prelim()) { nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 0b52a2347..8b86e0f20 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -492,7 +492,7 @@ void process () { // Bits between widthMin() and width() are irrelevant, but may be non zero. v3Global.assertWidthsMatch(false); - // Make all operations a multiple of 32 bits + // Make all math operations either 8, 16, 32 or 64 bits V3Clean::cleanAll(v3Global.rootp()); v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("clean.tree"));