diff --git a/src/V3Ast.h b/src/V3Ast.h index 59889f314..3454d279f 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -291,11 +291,13 @@ public: case INTEGER: return 32; case LOGIC: return 1; case LONGINT: return 64; - case DOUBLE: return 64; - case FLOAT: return 32; + case DOUBLE: return 64; // opaque + case FLOAT: return 32; // opaque case SHORTINT: return 16; case TIME: return 64; - case STRING: return 64; // Just the pointer, for today + case STRING: return 64; // opaque // Just the pointer, for today + case SCOPEPTR: return 0; // opaque + case CHARPTR: return 0; // opaque default: return 0; } } @@ -862,8 +864,6 @@ public: void numericFrom(AstNode* fromp) { numeric(fromp->numeric()); } void numeric(AstNumeric flag) { m_numeric = (int)flag; if (flag.isDouble()) width(64,64); } AstNumeric numeric() const { return AstNumeric(m_numeric); } - bool isDouble() const { return numeric().isDouble(); } - bool isSigned() const { return numeric().isSigned(); } void isSigned(bool flag) { numeric(flag ? AstNumeric::SIGNED : AstNumeric::UNSIGNED); } bool isUnsigned() const { return numeric().isUnsigned(); } void didWidth(bool flag) { m_didWidth=flag; } @@ -872,6 +872,8 @@ public: bool doingWidth() const { return m_doingWidth; } bool isQuad() const { return (width()>VL_WORDSIZE && width()<=VL_QUADSIZE); } bool isWide() const { return (width()>VL_QUADSIZE); } + bool isDouble() const; + bool isSigned() const; AstNUser* user1p() const { // Slows things down measurably, so disabled by default @@ -1512,6 +1514,9 @@ public: //###################################################################### // Inline ACCESSORS +inline bool AstNode::isDouble() const { return numeric().isDouble(); } +inline bool AstNode::isSigned() const { return numeric().isSigned(); } + inline bool AstNode::isZero() { return (this->castConst() && this->castConst()->num().isEqZero()); } inline bool AstNode::isNeqZero() { return (this->castConst() && this->castConst()->num().isNeqZero()); } inline bool AstNode::isOne() { return (this->castConst() && this->castConst()->num().isEqOne()); } diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index b28f9a4ab..01867533c 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -48,11 +48,14 @@ private: public: AstConst(FileLine* fl, const V3Number& num) :AstNodeMath(fl) - ,m_num(num) { - width(m_num.width(), m_num.sized()?0:m_num.widthMin()); - numeric(m_num.isDouble() ? AstNumeric::DOUBLE - : m_num.isSigned() ? AstNumeric::SIGNED - : AstNumeric::UNSIGNED); + ,m_num(num) { + if (m_num.isDouble()) { + dtypeChgDouble(); + } else { + width(m_num.width(), m_num.sized()?0:m_num.widthMin()); + numeric(m_num.isSigned() ? AstNumeric::SIGNED + : AstNumeric::UNSIGNED); + } } AstConst(FileLine* fl, uint32_t num) :AstNodeMath(fl) @@ -212,7 +215,7 @@ public: struct AstArrayDType : public AstNodeDType { // Array data type, ie "some_dtype var_name [2:0]" private: - bool m_packed; + bool m_packed; public: AstArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep, bool isPacked=false) : AstNodeDType(fl), m_packed(isPacked) { @@ -318,13 +321,7 @@ public: 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); - } - } + void cvtRangeConst() {} // Convert to smaller represenation - disabled }; struct AstConstDType : public AstNodeDType { @@ -382,7 +379,7 @@ public: if (defp()) return defp(); else { v3fatalSrc("Typedef not linked"); return NULL; } } - AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable + AstNodeDType* dtypeSkipRefp() const { return defp()->skipRefp(); } // op1 = Range of variable AstNodeDType* defp() const { return m_defp; } void defp(AstNodeDType* nodep) { m_defp=nodep; } AstPackage* packagep() const { return m_packagep; } @@ -556,7 +553,9 @@ struct AstSel : public AstNodeTriop { // Children: varref|arraysel, math, constant math AstSel(FileLine* fl, AstNode* fromp, AstNode* lsbp, AstNode* widthp) :AstNodeTriop(fl, fromp, lsbp, widthp) { - if (widthp->castConst()) width(widthp->castConst()->toUInt(), widthp->castConst()->toUInt()); + if (widthp->castConst()) { + width(widthp->castConst()->toUInt(), widthp->castConst()->toUInt()); + } } AstSel(FileLine* fl, AstNode* fromp, int lsb, int bitwidth) :AstNodeTriop(fl, fromp, diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index c83ca565d..7d75357d8 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -91,14 +91,18 @@ private: if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } + void checkAll(AstNode* nodep) { + } // VISITORS virtual void visit(AstCell* nodep, AstNUser*) { nodep->iterateChildren(*this); + checkAll(nodep); nodep->modp()->user1Inc(); } virtual void visit(AstNodeVarRef* nodep, AstNUser*) { nodep->iterateChildren(*this); + checkAll(nodep); if (nodep->varScopep()) { nodep->varScopep()->user1Inc(); nodep->varScopep()->varp()->user1Inc(); @@ -112,30 +116,35 @@ private: } virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) { nodep->iterateChildren(*this); + checkAll(nodep); if (nodep->packagep()) { nodep->packagep()->user1Inc(); } } virtual void visit(AstRefDType* nodep, AstNUser*) { nodep->iterateChildren(*this); + checkAll(nodep); if (nodep->packagep()) { nodep->packagep()->user1Inc(); } } virtual void visit(AstEnumItemRef* nodep, AstNUser*) { nodep->iterateChildren(*this); + checkAll(nodep); if (nodep->packagep()) { nodep->packagep()->user1Inc(); } } virtual void visit(AstVarScope* nodep, AstNUser*) { nodep->iterateChildren(*this); + checkAll(nodep); if (mightElim(nodep->varp())) { m_vscsp.push_back(nodep); } } virtual void visit(AstVar* nodep, AstNUser*) { nodep->iterateChildren(*this); + checkAll(nodep); if (mightElim(nodep)) { m_varEtcsp.push_back(nodep); } @@ -154,12 +163,14 @@ private: } else { // Track like any other statement nodep->lhsp()->iterateAndNext(*this); } + checkAll(nodep); } //----- virtual void visit(AstNode* nodep, AstNUser*) { if (nodep->isOutputter()) m_sideEffect=true; nodep->iterateChildren(*this); + checkAll(nodep); } // METHODS diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 301e8a74b..15e175a1a 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -887,7 +887,8 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) { } puts(nodep->name()); if (isArray) { - for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) { + for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; + arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) { puts("["+cvtToStr(arrayp->elementsConst())+"]"); } } @@ -907,7 +908,8 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) { if (isArray) { if (nodep->isWide()) puts("W"); puts("("+nodep->name()); - for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) { + for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; + arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) { puts("["+cvtToStr(arrayp->elementsConst())+"]"); } puts(","+cvtToStr(basicp->msb())+","+cvtToStr(basicp->lsb())); @@ -928,7 +930,8 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) { // strings and other fundamental c types puts(nodep->vlArgType(true,false)); // This isn't very robust and may need cleanup for other data types - for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) { + for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; + arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) { puts("["+cvtToStr(arrayp->elementsConst())+"]"); } puts(";\n"); @@ -953,7 +956,8 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) { if (prefixIfImp!="") { puts(prefixIfImp); puts("::"); } puts(nodep->name()); // This isn't very robust and may need cleanup for other data types - for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) { + for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; + arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) { puts("["+cvtToStr(arrayp->elementsConst())+"]"); } puts(","+cvtToStr(basicp->msb())+","+cvtToStr(basicp->lsb())); @@ -2086,7 +2090,8 @@ class EmitCTrace : EmitCStmts { } else { puts(",-1"); } - if (nodep->msbEndianed() || nodep->lsbEndianed()) { + if (!nodep->isDouble() // When float/double no longer have widths this can go + && (nodep->msbEndianed() || nodep->lsbEndianed())) { puts(","+cvtToStr(nodep->msbEndianed())+","+cvtToStr(nodep->lsbEndianed())); } puts(");"); @@ -2112,7 +2117,8 @@ class EmitCTrace : EmitCStmts { + ((arrayindex<0) ? 0 : (arrayindex*nodep->declp()->widthWords())))); puts(","); emitTraceValue(nodep, arrayindex); - if (nodep->declp()->msbEndianed() || nodep->declp()->lsbEndianed() || emitTraceIsScBv(nodep)) { + if (!nodep->isDouble() // When float/double no longer have widths this can go + && (nodep->declp()->msbEndianed() || nodep->declp()->lsbEndianed() || emitTraceIsScBv(nodep))) { puts(","+cvtToStr(nodep->declp()->widthMin())); } puts(");\n"); diff --git a/src/V3Table.cpp b/src/V3Table.cpp index 547b79df4..143c0f894 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -189,12 +189,14 @@ private: // Change it variable FileLine* fl = nodep->fileline(); + AstNodeDType* dtypep + = new AstArrayDType (fl, + new AstBasicDType(fl, AstBitPacked(), m_outVarps.size()), + new AstRange (fl, VL_MASK_I(m_inWidth), 0)); AstVar* chgVarp = new AstVar (fl, AstVarType::MODULETEMP, "__Vtablechg" + cvtToStr(m_modTables), - new AstArrayDType (fl, - new AstBasicDType(fl, AstBitPacked(), m_outVarps.size()), - new AstRange (fl, VL_MASK_I(m_inWidth), 0))); + dtypep); chgVarp->isConst(true); chgVarp->valuep(new AstInitArray (nodep->fileline(), NULL)); m_modp->addStmtp(chgVarp); @@ -233,13 +235,15 @@ private: AstVarScope* outvscp = *it; AstVar* outvarp = outvscp->varp(); FileLine* fl = nodep->fileline(); + AstNodeDType* dtypep + = 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)); AstVar* tablevarp = 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))); + dtypep); tablevarp->isConst(true); tablevarp->isStatic(true); tablevarp->valuep(new AstInitArray (nodep->fileline(), NULL)); diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index 19aad0900..715ebdc88 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -328,8 +328,7 @@ private: vvertexp->insertp()->addNextHere (new AstAssign (fl, new AstSel (fl, new AstVarRef(fl, m_activityVscp, true), - new AstConst(fl, acode), - new AstConst(fl, 1)), + acode, 1), new AstConst (fl, AstConst::LogicTrue()))); } } @@ -452,8 +451,7 @@ private: for (ActCodeSet::const_iterator csit = actset.begin(); csit!=actset.end(); ++csit) { uint32_t acode = *csit; AstNode* selp = new AstSel (fl, new AstVarRef(fl, m_activityVscp, false), - new AstConst(fl, acode), - new AstConst(fl, 1)); + acode, 1); if (condp) condp = new AstOr (fl, condp, selp); else condp = selp; } diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index e59d94fa2..b1fc6dae2 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -56,7 +56,6 @@ #include "V3Global.h" #include "V3Tristate.h" #include "V3Ast.h" -#include "V3Const.h" #include "V3Stats.h" #include "V3Inst.h" diff --git a/src/verilog.y b/src/verilog.y index 6f2ca556a..f39ae088f 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1154,7 +1154,8 @@ data_typeNoRef: // ==IEEE: data_type, excluding class_type etc referenc //UNSUP { UNSUP } //UNSUP yUNION taggedE packedSigningE '{' struct_union_memberList '}' packed_dimensionListE //UNSUP { UNSUP } - | enumDecl { $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->m_modTypeImpNum++),GRAMMARP->m_modp,$1); } + | enumDecl { $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->m_modTypeImpNum++), + GRAMMARP->m_modp,$1); } | ySTRING { $$ = new AstBasicDType($1,AstBasicDTypeKwd::STRING); } | yCHANDLE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::CHANDLE); } //UNSUP yEVENT { UNSUP }