diff --git a/Makefile.in b/Makefile.in index 756d15200..6125101ac 100644 --- a/Makefile.in +++ b/Makefile.in @@ -151,10 +151,13 @@ else export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)") endif +default: all all: all_nomsg msg_test all_nomsg: verilator_exe $(VL_INST_MAN_FILES) .PHONY:verilator_exe +.PHONY:verilator_bin +.PHONY:verilator_bin_dbg verilator_exe verilator_bin verilator_bin_dbg: @echo ------------------------------------------------------------ @echo "making verilator in src" ; \ diff --git a/src/V3Ast.h b/src/V3Ast.h index 56ffa86b3..0906186f9 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -198,6 +198,38 @@ public: //###################################################################### +class AstBasicDTypeKwd { +public: + enum en { + BYTE, SHORTINT, INT, LONGINT, INTEGER, TIME, BIT, + LOGIC, REG, SHORTREAL, REAL, REALTIME + }; + enum en m_e; + const char* ascii() const { + static const char* names[] = { + "byte", "shortint", "int", "longint", "integer", "time", "bit", + "logic", "reg", "shortreal", "real", "realtime" + }; + return names[m_e]; + }; + inline AstBasicDTypeKwd () {} + inline AstBasicDTypeKwd (en _e) : m_e(_e) {} + explicit inline AstBasicDTypeKwd (int _e) : m_e(static_cast(_e)) {} + operator en () const { return m_e; } + }; + inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd rhs) { return (lhs.m_e == rhs.m_e); } + inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd::en rhs) { return (lhs.m_e == rhs); } + inline bool operator== (AstBasicDTypeKwd::en lhs, AstBasicDTypeKwd rhs) { return (lhs == rhs.m_e); } + +//###################################################################### + +enum AstSignedState { + // This can't be in the fancy class as the lexer union will get upset + signedst_NOP=0, signedst_SIGNED=1, signedst_UNSIGNED=2 +}; + +//###################################################################### + class AstVarType { public: enum en { @@ -205,7 +237,7 @@ public: GPARAM, LPARAM, GENVAR, - INTEGER, + VAR, // Reg, integer, logic, etc INPUT, OUTPUT, INOUT, @@ -213,7 +245,6 @@ public: SUPPLY1, WIRE, IMPLICIT, - REG, TRIWIRE, PORT, // Temp type used in parser only BLOCKTEMP, @@ -229,8 +260,8 @@ public: const char* ascii() const { static const char* names[] = { "?","GPARAM","LPARAM","GENVAR", - "INTEGER","INPUT","OUTPUT","INOUT", - "SUPPLY0","SUPPLY1","WIRE","IMPLICIT","REG","TRIWIRE","PORT", + "VAR","INPUT","OUTPUT","INOUT", + "SUPPLY0","SUPPLY1","WIRE","IMPLICIT","TRIWIRE","PORT", "BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP"}; return names[m_e]; } }; @@ -1121,10 +1152,19 @@ public: return text()==samep->castNodeText()->text(); } }; +struct AstNodeDType : public AstNode { + // Data type + AstNodeDType(FileLine* fl) : AstNode(fl) {} + ASTNODE_BASE_FUNCS(NodeDType) + // Accessors + AstRange* rangep(); +}; + struct AstNodeSel : public AstNodeBiop { // Single bit range extraction, perhaps with non-constant selection or array selection AstNodeSel(FileLine* fl, AstNode* fromp, AstNode* bitp) :AstNodeBiop(fl, fromp, bitp) {} + ASTNODE_BASE_FUNCS(NodeSel) AstNode* fromp() const { return op1p()->castNode(); } // op1 = Extracting what (NULL=TBD during parsing) AstNode* bitp() const { return op2p()->castNode(); } // op2 = Msb selection expression int bitConst() const; diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 55506b642..6565def1a 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -35,6 +35,11 @@ //====================================================================== // Special methods +AstRange* AstNodeDType::rangep() { + if (castBasicDType()) return castBasicDType()->rangep(); + else return NULL; +} + // We need these here, because the classes they point to aren't defined when we declare the class bool AstNodeVarRef::broken() const { return ((m_varScopep && !m_varScopep->brokeExists()) || (m_varp && !m_varp->brokeExists())); } @@ -319,6 +324,10 @@ void AstAttrOf::dump(ostream& str) { this->AstNode::dump(str); str<<" ["<AstNode::dump(str); + str<<" ["<AstNode::dump(str); str<<" sz"<castRange(); } // op1 = Range of variable + void rangep(AstRange* nodep) { setNOp1p(nodep); } + void setSignedState(AstSignedState signst) { + if (signst!=signedst_NOP) isSigned(signst==signedst_SIGNED); + } + // METHODS + bool isInteger() const { return (keyword() == AstBasicDTypeKwd::INTEGER); } + int msb() const { if (!rangep()) return 0; 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 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()); } +}; + struct AstArraySel : public AstNodeSel { // Parents: math|stmt // Children: varref|arraysel, math @@ -265,21 +306,30 @@ private: m_trace=false; } public: - AstVar(FileLine* fl, AstVarType type, const string& name, AstRange* rangep, AstRange* arrayp=NULL) + AstVar(FileLine* fl, AstVarType type, const string& name, AstNodeDType* dtypep, AstRange* arrayp=NULL) :AstNode(fl) , m_name(name) { init(); - combineType(type); setNOp1p(rangep); addNOp2p(arrayp); + combineType(type); setOp1p(dtypep); addNOp2p(arrayp); width(msb()-lsb()+1,0); } + class LogicPacked {}; + AstVar(FileLine* fl, AstVarType type, const string& name, LogicPacked, int wantwidth) + :AstNode(fl) + , m_name(name) { + init(); + combineType(type); + setOp1p(new AstBasicDType(fl, AstBasicDTypeKwd::LOGIC, + ((wantwidth > 1) ? new AstRange(fl, wantwidth-1, 0) : NULL))); + width(wantwidth,0); + } AstVar(FileLine* fl, AstVarType type, const string& name, AstVar* examplep) :AstNode(fl) , m_name(name) { init(); combineType(type); - if (examplep->rangep()) { - // Creating is faster than cloning; know have constant args - setOp1p(new AstRange(fl, examplep->msb(), examplep->lsb())); + if (examplep->dtypep()) { + setOp1p(examplep->dtypep()->cloneTree(true)); } if (examplep->arraysp()) { setOp2p(examplep->arraysp()->cloneTree(true)); @@ -290,21 +340,23 @@ public: virtual void dump(ostream& str); virtual string name() const { return m_name; } // * = Var name virtual bool maybePointedTo() const { return true; } + virtual bool broken() const { return !dtypep(); } AstVarType varType() const { return m_varType; } // * = Type of variable void varType2Out() { m_tristate=0; m_input=0; m_output=1; } void varType2In() { m_tristate=0; m_input=1; m_output=0; } string cType() const; // Return C type for declaration: bool, uint32_t, uint64_t, etc. string scType() const; // Return SysC type: bool, uint32_t, uint64_t, sc_bv void combineType(AstVarType type); - AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range of variable + AstNodeDType* dtypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable AstRange* arraysp() const { return op2p()->castRange(); } // op2 = Array(s) of variable + void addArraysp(AstNode* nodep) { addNOp2p(nodep); } AstRange* arrayp(int dim) const; // op2 = Range for specific dimension # 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 rangep(AstRange* nodep) { setOp1p(nodep); } + void dtypep(AstRange* nodep) { setOp1p(nodep); } void attrClockEn(bool flag) { m_attrClockEn = flag; } void attrFileDescr(bool flag) { m_fileDescr = flag; } void attrScClocked(bool flag) { m_scClocked = flag; } @@ -333,11 +385,11 @@ public: bool isPrimaryIn() const { return isPrimaryIO() && isInput(); } bool isIO() const { return (m_input||m_output); } bool isSignal() const { return (varType()==AstVarType::WIRE || varType()==AstVarType::IMPLICIT - || varType()==AstVarType::REG || varType()==AstVarType::INTEGER); } + || varType()==AstVarType::VAR); } bool isTemp() const { return (varType()==AstVarType::BLOCKTEMP || varType()==AstVarType::MODULETEMP || varType()==AstVarType::STMTTEMP || varType()==AstVarType::XTEMP); } bool isToggleCoverable() const { return ((isIO() || isSignal()) - && varType()!=AstVarType::INTEGER + && (isIO() || !isInteger()) // Wrapper would otherwise duplicate wrapped module's coverage && !isSc() && !isPrimaryIO()); } bool isStatementTemp() const { return (varType()==AstVarType::STMTTEMP); } @@ -346,7 +398,7 @@ public: bool isParam() const { return (varType()==AstVarType::LPARAM || varType()==AstVarType::GPARAM); } bool isGParam() const { return (varType()==AstVarType::GPARAM); } bool isGenVar() const { return (varType()==AstVarType::GENVAR); } - bool isInteger() const { return (varType() == AstVarType::INTEGER); } + bool isInteger() const { return dtypep()->castBasicDType() && dtypep()->castBasicDType()->isInteger(); } bool isUsedClock() const { return m_usedClock; } bool isUsedParam() const { return m_usedParam; } bool isSc() const { return m_sc; } @@ -366,12 +418,12 @@ public: bool attrIsolateAssign() const { return m_attrIsolateAssign; } int widthAlignBytes() const; // Structure alignment 1,2,4 or 8 bytes (arrays affect this) int widthTotalBytes() const; // Width in bytes rounding up 1,2,4,8,12,... - int msb() const { if (!rangep()) return 0; 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 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()); } + int msb() const { if (!dtypep()) return 0; return dtypep()->castBasicDType()->msb(); } + int lsb() const { if (!dtypep()) return 0; return dtypep()->castBasicDType()->lsb(); } + int msbEndianed() const { if (!dtypep()) return 0; return dtypep()->castBasicDType()->msbEndianed(); } + int lsbEndianed() const { if (!dtypep()) return 0; return dtypep()->castBasicDType()->lsbEndianed(); } + int msbMaxSelect() const { if (!dtypep()) return 0; return dtypep()->castBasicDType()->msbMaxSelect(); } + bool littleEndian() const { return (dtypep() && dtypep()->castBasicDType()->littleEndian()); } int arrayDimensions() const; uint32_t arrayElements() const; // 1, or total multiplication of all dimensions virtual string verilogKwd() const; diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index 625069979..607f242b6 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -157,8 +157,7 @@ private: // Note var can be signed or unsigned based on original number. AstNode* countp = nodep->countp()->unlinkFrBackWithNext(); string name = string("__Vrepeat")+cvtToStr(m_repeatNum++); - AstVar* varp = new AstVar(nodep->fileline(), AstVarType::BLOCKTEMP, name, - new AstRange(nodep->fileline(), countp->width()-1, 0)); + AstVar* varp = new AstVar(nodep->fileline(), AstVarType::BLOCKTEMP, name, AstVar::LogicPacked(), countp->width()); m_modp->addStmtp(varp); AstNode* initsp = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true), countp); diff --git a/src/V3Clock.cpp b/src/V3Clock.cpp index 006a8a6de..9a50e5d90 100644 --- a/src/V3Clock.cpp +++ b/src/V3Clock.cpp @@ -85,8 +85,7 @@ private: AstVar* varp = vscp->varp(); if (varp->width()!=1) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<prettyName()); string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->shortName()); - AstVar* newvarp - = new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, NULL, NULL); // No range; 1 bit. + AstVar* newvarp = new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, AstVar::LogicPacked(), 1); newvarp->width(1,1); m_modp->addStmtp(newvarp); AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp); @@ -105,7 +104,7 @@ private: AstVarScope* getCreateLocalVar(FileLine* fl, const string& name, AstVar* examplep, int width) { AstVar* newvarp; if (width) { - newvarp = new AstVar (fl, AstVarType::BLOCKTEMP, name, new AstRange(fl, width-1, 0)); + newvarp = new AstVar (fl, AstVarType::BLOCKTEMP, name, AstVar::LogicPacked(), width); } else { newvarp = new AstVar (fl, AstVarType::BLOCKTEMP, name, examplep); // No range; 1 bit. } diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 4e19c327a..9fc1de8c6 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -309,10 +309,11 @@ private: AstNode* basefromp = AstArraySel::baseFromp(nodep->fromp()); if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { AstVar* varp = varrefp->varp(); + if (!varp->dtypep()) varp->v3fatalSrc("Data type lost"); if (m_warn && nodep->lsbp()->castConst() && nodep->widthp()->castConst() - && (!varp->rangep() || varp->msb())) { // else it's non-resolvable parameterized + && (!varp->dtypep()->rangep() || varp->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: " @@ -770,9 +771,9 @@ private: string name1 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc())); string name2 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc())); AstVar* temp1p = new AstVar(sel1p->fileline(), AstVarType::BLOCKTEMP, name1, - new AstRange(sel1p->fileline(), msb1-lsb1, 0)); + AstVar::LogicPacked(), msb1-lsb1+1); AstVar* temp2p = new AstVar(sel2p->fileline(), AstVarType::BLOCKTEMP, name2, - new AstRange(sel2p->fileline(), msb2-lsb2, 0)); + AstVar::LogicPacked(), msb2-lsb2+1); m_modp->addStmtp(temp1p); m_modp->addStmtp(temp2p); AstNodeAssign* asn1ap=nodep->cloneType diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index bd0983ff5..af98ead8b 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -176,7 +176,7 @@ private: dimension+1, selects_docs, selects_code); } } else { // No more arraying - just each bit in the width - if (nodep->rangep()) { + if (nodep->msb() != nodep->lsb()) { for (int bitindex_docs=nodep->lsb(); bitindex_docsmsb()+1; bitindex_docs++) { toggleVarBottom(nodep, chgVarp, dimension, selects_docs, selects_code, diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 50171800c..761ea3d53 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -128,19 +128,12 @@ private: // Created module's AstVar earlier under some other scope varp = iter->second; } else { - AstRange* rangep = NULL; if (width==0) { - rangep = new AstRange(oldvarscp->fileline(), - oldvarscp->varp()->msb(), - oldvarscp->varp()->lsb()); - } else if (width==1) { - rangep = NULL; + varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, oldvarscp->varp()); + varp->widthSignedFrom(oldvarscp); } else { - rangep = new AstRange(oldvarscp->fileline(), - width-1, 0); + varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, AstVar::LogicPacked(), width); } - varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, rangep); - if (width==0) varp->widthSignedFrom(oldvarscp); addmodp->addStmtp(varp); m_modVarMap.insert(make_pair(make_pair(addmodp, name), varp)); } diff --git a/src/V3Depth.cpp b/src/V3Depth.cpp index 0d64a19cf..f2173e74b 100644 --- a/src/V3Depth.cpp +++ b/src/V3Depth.cpp @@ -68,7 +68,7 @@ private: // Width, not widthMin, as we may be in middle of BITSEL expression which // though it's one bit wide, needs the mask in the upper bits. // (Someday we'll have a valid bitmask instead of widths....) - new AstRange(nodep->fileline(), nodep->width()-1, 0)); + AstVar::LogicPacked(), nodep->width()); if (!m_funcp) nodep->v3fatalSrc("Deep expression not under a function"); m_funcp->addInitsp(varp); // Replace node tree with reference to var diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index 7671d0152..4b683627a 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -421,11 +421,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor { puts(nodep->verilogKwd()); puts(" "); if (nodep->isSigned()) puts("signed "); - if (nodep->rangep()) { - puts("["+cvtToStr(nodep->msb()) - +":"+cvtToStr(nodep->lsb()) - +"] "); - } + nodep->dtypep()->iterateChildren(*this); puts(nodep->name()); for (AstRange* arrayp=nodep->arraysp(); arrayp; arrayp = arrayp->nextp()->castRange()) { puts(" ["+cvtToStr(arrayp->msbConst()) diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index 2ace0c05e..55cb78ea1 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -106,6 +106,16 @@ private: UINFO(5," Inline CELL "<pinsp(); pinp; pinp=pinp->nextp()->castPin()) { + V3Inst::pinReconnectSimple(pinp, nodep, m_modp); + } + + // Clone original module if (debug()>=9) { nodep->dumpTree(cout,"inlcell:"); } //if (debug()>=9) { nodep->modp()->dumpTree(cout,"oldmod:"); } AstModule* newmodp = nodep->modp()->cloneTree(false); @@ -119,8 +129,6 @@ private: // Create assignments to the pins for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) { UINFO(6," Pin change from "<modVarp()<modVarp(); AstVarRef* connectRefp = pinp->exprp()->castVarRef(); if (connectRefp diff --git a/src/V3Link.cpp b/src/V3Link.cpp index f0fb3da64..50d785543 100644 --- a/src/V3Link.cpp +++ b/src/V3Link.cpp @@ -157,7 +157,8 @@ private: if (!forrefp->varp()) { if (!noWarn) forrefp->v3warn(IMPLICIT,"Signal definition not found, creating implicitly: "<prettyName()); AstVar* newp = new AstVar (forrefp->fileline(), AstVarType::WIRE, - forrefp->name(), NULL, NULL); // width 1 + forrefp->name(), AstVar::LogicPacked(), 1); + newp->trace(m_modp->modTrace()); m_modp->addStmtp(newp); // Link it to signal list @@ -298,9 +299,12 @@ private: // just attact normal signal attributes to it. if (AstFunc* funcp = nodep->castFunc()) { if (!funcp->fvarp()->castVar()) { - AstRange* rangep = funcp->fvarp()->castRange(); - if (rangep) rangep->unlinkFrBack(); - AstVar* newvarp = new AstVar(nodep->fileline(), AstVarType::OUTPUT, nodep->name(), rangep); + AstNodeDType* dtypep = funcp->fvarp()->castNodeDType(); + // If unspecified, function returns one bit; however when we support NEW() it could + // also return the class reference. + if (dtypep) dtypep->unlinkFrBack(); + else dtypep = new AstBasicDType(nodep->fileline(), AstBasicDTypeKwd::LOGIC, NULL); + AstVar* newvarp = new AstVar(nodep->fileline(), AstVarType::OUTPUT, nodep->name(), dtypep); newvarp->isSigned(funcp->isSigned()); newvarp->funcReturn(true); newvarp->trace(false); // Not user visible diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index e8ef4778c..ba94cd8d6 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -124,7 +124,7 @@ private: // Make a new temp wire string newvarname = "__Vsenitemexpr"+cvtToStr(++m_senitemCvtNum); AstVar* newvarp = new AstVar (sensp->fileline(), AstVarType::MODULETEMP, newvarname, - NULL,NULL); + AstVar::LogicPacked(), 1); // We can't just add under the module, because we may be inside a generate, begin, etc. // We know a SenItem should be under a SenTree/Always etc, we we'll just hunt upwards AstNode* addwherep = nodep; // Add to this element's next diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index a2dc2ea94..01787fdd0 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -52,9 +52,11 @@ struct V3ParseBisonYYSType { int cint; double cdouble; V3UniqState uniqstate; + AstSignedState signstate; AstNode* nodep; + AstBasicDType* bdtypep; AstBegin* beginp; AstCase* casep; AstCaseItem* caseitemp; @@ -62,6 +64,7 @@ struct V3ParseBisonYYSType { AstFunc* funcp; AstModule* modulep; AstNodeSenItem* senitemp; + AstNodeDType* typep; AstNodeVarRef* varnodep; AstParseRef* parserefp; AstPin* pinp; diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index 4a456924c..49c3f7e0e 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -103,7 +103,7 @@ private: AstVar* getBlockTemp(AstNode* nodep) { string newvarname = ((string)"__Vtemp"+cvtToStr(m_modp->varNumGetInc())); AstVar* varp = new AstVar (nodep->fileline(), AstVarType::STMTTEMP, newvarname, - new AstRange(nodep->fileline(), nodep->widthMin()-1, 0)); + AstVar::LogicPacked(), nodep->widthMin()); m_funcp->addInitsp(varp); return varp; } diff --git a/src/V3Signed.cpp b/src/V3Signed.cpp index 12f65b448..3372da6a7 100644 --- a/src/V3Signed.cpp +++ b/src/V3Signed.cpp @@ -139,9 +139,13 @@ private: //======= // These have proper signedness set when they were created. virtual void visit(AstFunc* nodep, AstNUser*) { nodep->iterateChildren(*this); } - virtual void visit(AstVar* nodep, AstNUser*) { nodep->iterateChildren(*this); } + virtual void visit(AstNodeDType* nodep, AstNUser*) { nodep->iterateChildren(*this); } // Inherit from others + virtual void visit(AstVar* nodep, AstNUser*) { + nodep->iterateChildren(*this); + nodep->signedFrom(nodep->dtypep()); + } virtual void visit(AstNodeVarRef* nodep, AstNUser*) { nodep->varp()->iterate(*this); nodep->signedFrom(nodep->varp()); diff --git a/src/V3Table.cpp b/src/V3Table.cpp index 1423d69cf..9ff463e21 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -182,7 +182,7 @@ private: // Index into our table AstVar* indexVarp = new AstVar (nodep->fileline(), AstVarType::BLOCKTEMP, "__Vtableidx" + cvtToStr(m_modTables), - new AstRange (nodep->fileline(), m_inWidth-1, 0)); + AstVar::LogicPacked(), m_inWidth); m_modp->addStmtp(indexVarp); AstVarScope* indexVscp = new AstVarScope (indexVarp->fileline(), m_scopep, indexVarp); m_scopep->addVarp(indexVscp); @@ -190,8 +190,8 @@ private: // Change it variable AstVar* chgVarp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP, "__Vtablechg" + cvtToStr(m_modTables), - new AstRange (nodep->fileline(), m_outVarps.size()-1, 0), - new AstRange (nodep->fileline(), VL_MASK_I(m_inWidth), 0)); + AstVar::LogicPacked(), m_outVarps.size()); + chgVarp->addArraysp(new AstRange (nodep->fileline(), VL_MASK_I(m_inWidth), 0)); chgVarp->isConst(true); chgVarp->initp(new AstInitArray (nodep->fileline(), NULL)); m_modp->addStmtp(chgVarp); @@ -232,8 +232,8 @@ private: AstVar* tablevarp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP, "__Vtable" + cvtToStr(m_modTables) +"_"+outvarp->name(), - new AstRange (nodep->fileline(), outvarp->widthMin()-1, 0), - new AstRange (nodep->fileline(), VL_MASK_I(m_inWidth), 0)); + AstVar::LogicPacked(), outvarp->widthMin()); + tablevarp->addArraysp(new AstRange (nodep->fileline(), VL_MASK_I(m_inWidth), 0)); tablevarp->isConst(true); tablevarp->isStatic(true); tablevarp->initp(new AstInitArray (nodep->fileline(), NULL)); diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index 260f2aa7e..782f9a2a7 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -311,10 +311,9 @@ private: // Insert global variable if (!activityNumber) activityNumber++; // For simplicity, always create it - activityNumber = VL_WORDS_I(activityNumber)*VL_WORDSIZE; // For tighter code; round to next 32 bit point. + int activityBits = VL_WORDS_I(activityNumber)*VL_WORDSIZE; // For tighter code; round to next 32 bit point. AstVar* newvarp = new AstVar (m_chgFuncp->fileline(), AstVarType::MODULETEMP, - "__Vm_traceActivity", - new AstRange (m_chgFuncp->fileline(), activityNumber-1, 0)); + "__Vm_traceActivity", AstVar::LogicPacked(), activityBits); m_topModp->addStmtp(newvarp); AstVarScope* newvscp = new AstVarScope(newvarp->fileline(), m_highScopep, newvarp); m_highScopep->addVarp(newvscp); diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index ef34bd8c3..a27ca7a8b 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -207,7 +207,7 @@ private: AstVar* enp = new AstVar (outrefp->varp()->fileline(), AstVarType::MODULETEMP, outrefp->name() + "__en" + suffix + cvtToStr(m_unique++), - (width>1) ? new AstRange(outp->fileline(), width-1, 0) : (AstRange *) NULL); + AstVar::LogicPacked(), width); enp->varType2Out(); if (enp->width() != enrhsp->width()) { @@ -381,7 +381,7 @@ private: AstVar* newlhsp = new AstVar(lhsp->fileline(), AstVarType::MODULETEMP, lhsp->name()+"__lhs"+cvtToStr(m_unique++), - (w>1) ? new AstRange(nodep->fileline(), w-1, 0) : (AstRange *) NULL); + AstVar::LogicPacked(), w); nodep->addStmtp(newlhsp); // now append this driver to the driver logic. @@ -396,7 +396,7 @@ private: bitselp = new AstVar(lhsp->fileline(), AstVarType::MODULETEMP, lhsp->name()+"__sel"+cvtToStr(m_unique-1), - (ws>1) ? new AstRange(nodep->fileline(), ws-1, 0) : (AstRange*) NULL); + AstVar::LogicPacked(), ws); // nodep->addStmtp(bitselp); nodep->addStmtp(new AstAssignW(lhsp->fileline(), diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 46d6ac656..27421eb22 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -127,7 +127,7 @@ private: else { string name = ((string)"__Vlvbound"+cvtToStr(m_modp->varNumGetInc())); AstVar* varp = new AstVar(fl, AstVarType::MODULETEMP, name, - new AstRange(fl, prep->width()-1, 0)); + AstVar::LogicPacked(), prep->width()); m_modp->addStmtp(varp); AstNode* abovep = prep->backp(); // Grab above point before loose it w/ next replace @@ -288,7 +288,7 @@ private: +cvtToStr(m_modp->varNumGetInc())); AstVar* newvarp = new AstVar (nodep->fileline(), AstVarType::XTEMP, newvarname, - new AstRange(nodep->fileline(), nodep->width()-1, 0)); + AstVar::LogicPacked(), nodep->width()); m_statUnkVars++; AstNRelinker replaceHandle; nodep->unlinkFrBack(&replaceHandle); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 492964b7b..61dfd2177 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -299,7 +299,7 @@ private: int frommsb = nodep->fromp()->width() - 1; int fromlsb = 0; AstNodeVarRef* varrp = nodep->fromp()->castNodeVarRef(); - if (varrp && varrp->varp()->rangep()) { // Selecting a bit from a multibit register + if (varrp && varrp->varp()->dtypep()->rangep()) { // Selecting a bit from a multibit register frommsb = varrp->varp()->msbMaxSelect(); // Corrected for negative lsb fromlsb = varrp->varp()->lsb(); } @@ -480,9 +480,9 @@ private: // with non-constant range gets size 1, not size 0. int width=1; int mwidth=1; nodep->arraysp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); - if (nodep->rangep()) { - nodep->rangep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); - width = mwidth = nodep->rangep()->width(); + if (nodep->dtypep()->rangep()) { + nodep->dtypep()->rangep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); + width = mwidth = nodep->dtypep()->rangep()->width(); } else if (nodep->isInteger() || nodep->isGenVar()) { width = 32; @@ -497,7 +497,7 @@ private: // we want the init numbers to retain their width/minwidth until parameters are replaced. nodep->initp()->iterateAndNext(*this,WidthVP(width,0,FINAL).p()); if (nodep->isParam()) { - if (nodep->rangep()) { + if (nodep->dtypep()->rangep()) { // Parameters need to preserve widthMin from the value, not get a constant size mwidth = nodep->initp()->widthMin(); } else if (nodep->initp()->widthSized()) { @@ -510,12 +510,13 @@ private: } //if (debug()) nodep->dumpTree(cout," final: "); } - if (nodep->isParam() && !nodep->rangep()) { + if (nodep->isParam() && !nodep->dtypep()->rangep()) { // Parameter sizes can come from the thing they get assigned from // They then "stick" to that width. if (!width) width=32; // Or, if nothing, they're 32 bits. - nodep->rangep(new AstRange(nodep->fileline(),width-1,0)); - nodep->rangep()->width(width,width); + AstBasicDType* bdtypep = nodep->dtypep()->castBasicDType(); + bdtypep->rangep(new AstRange(nodep->fileline(),width-1,0)); + bdtypep->rangep()->width(width,width); } nodep->width(width,mwidth); // See above note about initp()->...FINAL diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index a1be62bce..7ffb5d233 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -86,7 +86,7 @@ private: } else if (dimension > dimensions) { // Too many indexes provided nodep->v3error("Illegal bit or array select; variable already selected, or bad dimension: "<prettyName()); } else if (dimension == dimensions) { // Right number, but... - if (!varp->rangep()) { + if (!varp->dtypep()->rangep()) { nodep->v3error("Illegal bit select; variable does not have a bit range, or bad dimension: "<prettyName()); } } @@ -133,12 +133,12 @@ private: // Don't report WIDTH warnings etc here, as may be inside a generate branch that will be deleted AstVar* varp = varFromBasefrom(basefromp); // SUB #'s Not needed when LSB==0 and MSB>=0 (ie [0:-13] must still get added!) - if (!varp->rangep()) { + if (!varp->dtypep()->rangep()) { // vector without range is ok, for example a INTEGER x; y = x[21:0]; return underp; } else { - if (!varp->rangep()->msbp()->castConst() - || !varp->rangep()->lsbp()->castConst()) + if (!varp->dtypep()->rangep()->msbp()->castConst() + || !varp->dtypep()->rangep()->lsbp()->castConst()) varp->v3fatalSrc("Non-constant variable range; errored earlier"); // in constifyParam(varp) if (varp->littleEndian()) { // reg [1:3] was swapped to [3:1] (lsbEndianedp==3) and needs a SUB(3,under) @@ -239,7 +239,7 @@ private: vlsint32_t msb = msbp->castConst()->toSInt(); vlsint32_t lsb = lsbp->castConst()->toSInt(); selCheckDimension(nodep, basefromp, dimension, msb!=lsb); - if (varp->rangep() && varp->rangep()->littleEndian()) { + if (varp->dtypep()->rangep() && varp->dtypep()->rangep()->littleEndian()) { // Below code assumes big bit endian; just works out if we swap int x = msb; msb = lsb; lsb = x; } @@ -277,7 +277,7 @@ private: selCheckDimension(nodep, basefromp, dimension, width!=1); AstSel* newp = NULL; if (nodep->castSelPlus()) { - if (varp->rangep() && varp->rangep()->littleEndian()) { + if (varp->dtypep()->rangep() && varp->dtypep()->rangep()->littleEndian()) { // SELPLUS(from,lsb,width) -> SEL(from, (vector_msb-width+1)-sel, width) newp = new AstSel (nodep->fileline(), fromp, @@ -291,7 +291,7 @@ private: widthp); } } else if (nodep->castSelMinus()) { - if (varp->rangep() && varp->rangep()->littleEndian()) { + if (varp->dtypep()->rangep() && varp->dtypep()->rangep()->littleEndian()) { // SELMINUS(from,msb,width) -> SEL(from, msb-[bit]) newp = new AstSel (nodep->fileline(), fromp, diff --git a/src/verilog.y b/src/verilog.y index 4d6a49800..4a556f6bf 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -49,10 +49,9 @@ public: bool m_impliedDecl; // Allow implied wire declarations AstVarType m_varDecl; // Type for next signal declaration (reg/wire/etc) AstVarType m_varIO; // Type for next signal declaration (input/output/etc) - bool m_varSigned; // Signed state for next signal declaration AstVar* m_varAttrp; // Current variable for attribute adding AstCase* m_caseAttrp; // Current case statement for attribute adding - AstRange* m_varRangep; // Pointer to range for next signal declaration + AstNodeDType* m_varDTypep; // Pointer to data type for next signal declaration int m_pinNum; // Pin number currently parsing string m_instModule; // Name of module referenced for instantiations AstPin* m_instParamp; // Parameters for instantiations @@ -63,8 +62,7 @@ public: m_impliedDecl = false; m_varDecl = AstVarType::UNKNOWN; m_varIO = AstVarType::UNKNOWN; - m_varSigned = false; - m_varRangep = NULL; + m_varDTypep = NULL; m_pinNum = -1; m_instModule; m_instParamp = NULL; @@ -93,9 +91,9 @@ public: new AstVarRef(fileline, varp->name(),true), initp)); } - void setRange(AstRange* rangep) { - if (m_varRangep) { m_varRangep->deleteTree(); m_varRangep=NULL; } // It was cloned, so this is safe. - m_varRangep = rangep; + void setDType(AstNodeDType* dtypep) { + if (m_varDTypep) { m_varDTypep->deleteTree(); m_varDTypep=NULL; } // It was cloned, so this is safe. + m_varDTypep = dtypep; } string deQuote(FileLine* fileline, string text); }; @@ -104,6 +102,8 @@ public: #define SYMP PARSEP->symp() #define GRAMMARP V3ParseGrammar::singletonp() +const AstBasicDTypeKwd LOGIC = AstBasicDTypeKwd::LOGIC; // Shorthand "LOGIC" + //====================================================================== // Macro functions @@ -111,12 +111,10 @@ public: #define VARRESET_LIST(decl) { GRAMMARP->m_pinNum=1; VARRESET(); VARDECL(decl); } // Start of pinlist #define VARRESET_NONLIST(decl) { GRAMMARP->m_pinNum=0; VARRESET(); VARDECL(decl); } // Not in a pinlist -#define VARRESET() { VARDECL(UNKNOWN); VARIO(UNKNOWN); VARSIGNED(false); VARRANGE(NULL); } +#define VARRESET() { VARDECL(UNKNOWN); VARIO(UNKNOWN); VARDTYPE(NULL); } #define VARDECL(type) { GRAMMARP->m_varDecl = AstVarType::type; } #define VARIO(type) { GRAMMARP->m_varIO = AstVarType::type; } -#define VARSIGNED(value) { GRAMMARP->m_varSigned = value; } -#define VARRANGE(rangep) { GRAMMARP->setRange(rangep); } -#define VARTYPE(typep) { VARRANGE(typep); } // Temp until other data types supported +#define VARDTYPE(dtypep) { GRAMMARP->setDType(dtypep); } #define VARDONEA(name,array,attrs) GRAMMARP->createVariable(CRELINE(),(name),(array),(attrs)) #define VARDONEP(portp,array,attrs) GRAMMARP->createVariable((portp)->fileline(),(portp)->name(),(array),(attrs)) @@ -589,10 +587,10 @@ port: // ==IEEE: port // // IEEE: interface_port_header port_identifier { unpacked_dimension } // // Expanded interface_port_header // // We use instantCb here because the non-port form looks just like a module instantiation - //UNSUP portDirNetE id/*interface*/ idAny/*port*/ regArRangeE sigAttrListE { VARTYPE($2); VARDONEA($3, $4); PARSEP->instantCb(CRELINE(), $2, $3, $4); PINNUMINC(); } - //UNSUP portDirNetE yINTERFACE idAny/*port*/ regArRangeE sigAttrListE { VARTYPE($2); VARDONEA($3, $4); PINNUMINC(); } - //UNSUP portDirNetE id/*interface*/ '.' idAny/*modport*/ idAny/*port*/ regArRangeE sigAttrListE { VARTYPE($2); VARDONEA($5, $6); PARSEP->instantCb(CRELINE(), $2, $5, $6); PINNUMINC(); } - //UNSUP portDirNetE yINTERFACE '.' idAny/*modport*/ idAny/*port*/ regArRangeE sigAttrListE { VARTYPE($2); VARDONEA($5, $6); PINNUMINC(); } + //UNSUP portDirNetE id/*interface*/ idAny/*port*/ regArRangeE sigAttrListE { VARDTYPE($2); VARDONEA($3, $4); PARSEP->instantCb(CRELINE(), $2, $3, $4); PINNUMINC(); } + //UNSUP portDirNetE yINTERFACE idAny/*port*/ regArRangeE sigAttrListE { VARDTYPE($2); VARDONEA($3, $4); PINNUMINC(); } + //UNSUP portDirNetE id/*interface*/ '.' idAny/*modport*/ idAny/*port*/ regArRangeE sigAttrListE { VARDTYPE($2); VARDONEA($5, $6); PARSEP->instantCb(CRELINE(), $2, $5, $6); PINNUMINC(); } + //UNSUP portDirNetE yINTERFACE '.' idAny/*modport*/ idAny/*port*/ regArRangeE sigAttrListE { VARDTYPE($2); VARDONEA($5, $6); PINNUMINC(); } // // // IEEE: ansi_port_declaration, with [port_direction] removed // // IEEE: [ net_port_header | interface_port_header ] port_identifier { unpacked_dimension } @@ -625,24 +623,24 @@ port: // ==IEEE: port //UNSUP portDirNetE signingE rangeList '.' portSig '(' portAssignExprE ')' sigAttrListE { UNSUP } //UNSUP portDirNetE /*implicit*/ '.' portSig '(' portAssignExprE ')' sigAttrListE { UNSUP } // - portDirNetE data_type portSig variable_dimensionListE sigAttrListE { $$=$3; VARTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); } - //UNSUP portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE { $$=$4; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); } - //UNSUP portDirNetE yVAR implicit_type portSig variable_dimensionListE sigAttrListE { $$=$4; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); } - | portDirNetE signingE rangeList portSig variable_dimensionListE sigAttrListE { $$=$4; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); } - | portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE { $$=$2; /*VARTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); } + portDirNetE data_type portSig variable_dimensionListE sigAttrListE { $$=$3; VARDTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); } + //UNSUP portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE { $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); } + //UNSUP portDirNetE yVAR implicit_type portSig variable_dimensionListE sigAttrListE { $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); } + | portDirNetE signingE rangeList portSig variable_dimensionListE sigAttrListE { $$=$4; VARDTYPE(new AstBasicDType($3->fileline(), LOGIC, $3, $2)); $$->addNextNull(VARDONEP($$,$5,$6)); } + | portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE { $$=$2; /*VARDTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); } // - | portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); $$->addNextNull(GRAMMARP->newVarInit($6,$$,$7)); } - //UNSUP portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(GRAMMARP->newVarInit($7,$$,$8)); } - //UNSUP portDirNetE yVAR implicit_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(GRAMMARP->newVarInit($7,$$,$8)); } - | portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; /*VARTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); $$->addNextNull(GRAMMARP->newVarInit($5,$$,$6)); } + | portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARDTYPE($2); $$->addNextNull(VARDONEP($$,$4,$5)); $$->addNextNull(GRAMMARP->newVarInit($6,$$,$7)); } + //UNSUP portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(GRAMMARP->newVarInit($7,$$,$8)); } + //UNSUP portDirNetE yVAR implicit_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); $$->addNextNull(GRAMMARP->newVarInit($7,$$,$8)); } + | portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr { $$=$3; /*VARDTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); $$->addNextNull(GRAMMARP->newVarInit($5,$$,$6)); } ; portDirNetE: // IEEE: part of port, optional net type and/or direction /* empty */ { } // // Per spec, if direction given default the nettype. - // // The higher level rule may override this VARTYPE with one later in the parse. - | port_direction { VARDECL(PORT); VARTYPE(NULL/*default_nettype*/); } - | port_direction net_type { VARDECL(PORT); VARTYPE(NULL/*default_nettype*/); } // net_type calls VARNET + // // The higher level rule may override this VARDTYPE with one later in the parse. + | port_direction { VARDECL(PORT); VARDTYPE(NULL/*default_nettype*/); } + | port_direction net_type { VARDECL(PORT); VARDTYPE(NULL/*default_nettype*/); } // net_type calls VARNET | net_type { } // net_type calls VARNET ; @@ -675,7 +673,9 @@ list_of_genvar_identifiers: // IEEE: list_of_genvar_identifiers (for decl ; genvar_identifierDecl: // IEEE: genvar_identifier (for declaration) - id/*new-genvar_identifier*/ sigAttrListE { VARRESET_NONLIST(GENVAR); $$ = VARDONEA(*$1, NULL, $2); } + id/*new-genvar_identifier*/ sigAttrListE + { VARRESET_NONLIST(GENVAR); VARDTYPE(new AstBasicDType($1,AstBasicDTypeKwd::INTEGER)); + $$ = VARDONEA(*$1, NULL, $2); } ; local_parameter_declaration: // IEEE: local_parameter_declaration @@ -692,23 +692,23 @@ parameter_declaration: // IEEE: parameter_declaration ; local_parameter_declarationFront: // IEEE: local_parameter_declaration w/o assignment - varLParamReset implicit_type { /*VARRESET-in-varLParam*/ VARTYPE($2); } - //UNSUP varLParamReset data_type { /*VARRESET-in-varLParam*/ VARTYPE($2); } - //UNSUP varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARTYPE($2); } + varLParamReset implicit_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); } + //UNSUP varLParamReset data_type { /*VARRESET-in-varLParam*/ VARDTYPE($2); } + //UNSUP varLParamReset yTYPE { /*VARRESET-in-varLParam*/ VARDTYPE($2); } ; parameter_declarationFront: // IEEE: parameter_declaration w/o assignment - varGParamReset implicit_type { /*VARRESET-in-varGParam*/ VARTYPE($2); } - //UNSUP varGParamReset data_type { /*VARRESET-in-varGParam*/ VARTYPE($2); } - //UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARTYPE($2); } + varGParamReset implicit_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); } + //UNSUP varGParamReset data_type { /*VARRESET-in-varGParam*/ VARDTYPE($2); } + //UNSUP varGParamReset yTYPE { /*VARRESET-in-varGParam*/ VARDTYPE($2); } ; parameter_port_declarationFront: // IEEE: parameter_port_declaration w/o assignment // // IEEE: parameter_declaration (minus assignment) parameter_declarationFront { } // - //UNSUP data_type { VARTYPE($1); } - //UNSUP yTYPE { VARTYPE($1); } + //UNSUP data_type { VARDTYPE($1); } + //UNSUP yTYPE { VARDTYPE($1); } ; net_declaration: // IEEE: net_declaration - excluding implict @@ -716,7 +716,7 @@ net_declaration: // IEEE: net_declaration - excluding implict ; net_declarationFront: // IEEE: beginning of net_declaration - net_declRESET net_type strengthSpecE signingE delayrange { } + net_declRESET net_type strengthSpecE signingE delayrange { VARDTYPE($5); $5->setSignedState($4); } ; net_declRESET: @@ -738,7 +738,7 @@ net_type: // ==IEEE: net_type ; varRESET: - /* empty */ { VARRESET(); } + /* empty */ { VARRESET_NONLIST(VAR); } ; varGParamReset: @@ -775,53 +775,57 @@ port_declaration: // ==IEEE: port_declaration // // IEEE: input_declaration // // IEEE: output_declaration // // IEEE: ref_declaration - port_directionReset port_declNetE data_type { VARTYPE($3); } list_of_variable_decl_assignments { $$ = $5; } - //UNSUP port_directionReset port_declNetE yVAR data_type { VARTYPE($4); } list_of_variable_decl_assignments { $$ = $6; } - //UNSUP port_directionReset port_declNetE yVAR implicit_type { VARTYPE($4); } list_of_variable_decl_assignments { $$ = $6; } - | port_directionReset port_declNetE signingE rangeList { VARTYPE($4); } list_of_variable_decl_assignments { $$ = $6; } - | port_directionReset port_declNetE signing { VARTYPE(NULL); } list_of_variable_decl_assignments { $$ = $5; } - | port_directionReset port_declNetE /*implicit*/ { VARTYPE(NULL);/*default_nettype*/} list_of_variable_decl_assignments { $$ = $4; } + port_directionReset port_declNetE data_type { VARDTYPE($3); } + list_of_variable_decl_assignments { $$ = $5; } + //UNSUP port_directionReset port_declNetE yVAR data_type { VARDTYPE($4); } list_of_variable_decl_assignments { $$ = $6; } + //UNSUP port_directionReset port_declNetE yVAR implicit_type { VARDTYPE($4); } list_of_variable_decl_assignments { $$ = $6; } + | port_directionReset port_declNetE signingE rangeList { VARDTYPE(new AstBasicDType($4->fileline(), LOGIC, $4, $3)); } + list_of_variable_decl_assignments { $$ = $6; } + | port_directionReset port_declNetE signing { VARDTYPE(new AstBasicDType($3, LOGIC, NULL, $3)); } + list_of_variable_decl_assignments { $$ = $5; } + | port_directionReset port_declNetE /*implicit*/ { VARDTYPE(NULL);/*default_nettype*/} + list_of_variable_decl_assignments { $$ = $4; } ; tf_port_declaration: // ==IEEE: tf_port_declaration // // Used inside function; followed by ';' // // SIMILAR to port_declaration // - port_directionReset data_type { VARTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; } - | port_directionReset implicit_type { VARTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; } - //UNSUP port_directionReset yVAR data_type { VARTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; } - //UNSUP port_directionReset yVAR implicit_type { VARTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; } + port_directionReset data_type { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; } + | port_directionReset implicit_type { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; } + //UNSUP port_directionReset yVAR data_type { VARDTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; } + //UNSUP port_directionReset yVAR implicit_type { VARDTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; } ; -integer_atom_type: // ==IEEE: integer_atom_type - //UNSUP yBYTE { UNSUP } - //UNSUP ySHORTINT { UNSUP } - //UNSUP yINT { UNSUP } - //UNSUP yLONGINT { UNSUP } - yINTEGER { VARDECL(INTEGER); $$ = new AstRange($1,31,0); $$->isSigned(true); } - //UNSUP yTIME { UNSUP } +integer_atom_type: // ==IEEE: integer_atom_type + //UNSUP yBYTE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BYTE); } + //UNSUP ySHORTINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::SHORTINT); } + //UNSUP yINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INT); } + //UNSUP yLONGINT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LONGINT); } + yINTEGER { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INTEGER); } + //UNSUP yTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::TIME); } ; -integer_vector_type: // ==IEEE: integer_atom_type - yBIT { VARDECL(REG); } - | yLOGIC { VARDECL(REG); } - | yREG { VARDECL(REG); } +integer_vector_type: // ==IEEE: integer_atom_type + yBIT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BIT); } + | yLOGIC { $$ = new AstBasicDType($1,AstBasicDTypeKwd::LOGIC); } + | yREG { $$ = new AstBasicDType($1,AstBasicDTypeKwd::REG); } ; -signingE: // IEEE: signing - plus empty - /*empty*/ { } - | signing { } +signingE: // IEEE: signing - plus empty + /*empty*/ { $$ = signedst_NOP; } + | signing { $$ = $1; } ; -signing: // ==IEEE: signing - ySIGNED { VARSIGNED(true); } - | yUNSIGNED { VARSIGNED(false); } +signing: // ==IEEE: signing + ySIGNED { $$ = $1; $$ = signedst_SIGNED; } + | yUNSIGNED { $$ = $1; $$ = signedst_UNSIGNED; } ; //************************************************ // Data Types -data_type: // ==IEEE: data_type +data_type: // ==IEEE: data_type // // This expansion also replicated elsewhere, IE data_type__AndID data_typeNoRef { $$ = $1; } // // IEEE: [ class_scope | package_scope ] type_identifier { packed_dimension } @@ -833,10 +837,14 @@ data_type: // ==IEEE: data_type //UNSUP ps_covergroup_identifier { $$ = $1; } ; -data_typeNoRef: // ==IEEE: data_type, excluding class_type etc references - integer_vector_type signingE rangeListE { $$ = $3; } - | integer_atom_type signingE { $$ = $1; } +data_typeBasic: // IEEE: part of data_type + integer_vector_type signingE rangeListE { $$ = $1; $$->setSignedState($2); $$->rangep($3); } + | integer_atom_type signingE { $$ = $1; $$->setSignedState($2); } //UNSUP non_integer_type { UNSUP } + ; + +data_typeNoRef: // ==IEEE: data_type, excluding class_type etc references + data_typeBasic { $$ = $1; } //UNSUP ySTRUCT packedSigningE '{' struct_union_memberList '}' packed_dimensionE { UNSUP } //UNSUP yUNION taggedE packedSigningE '{' struct_union_memberList '}' packed_dimensionE { UNSUP } //UNSUP enumDecl { UNSUP } @@ -939,22 +947,22 @@ data_declarationVar: // IEEE: part of data_declaration data_declarationVarFront: // IEEE: part of data_declaration // // implicit_type expanded into /*empty*/ or "signingE rangeList" - //UNSUP constE yVAR lifetimeE data_type { /*VARRESET-in-ddVar*/ VARDECL("var"); VARTYPE(SPACED($1,$4)); } - //UNSUP constE yVAR lifetimeE { /*VARRESET-in-ddVar*/ VARDECL("var"); VARTYPE($1); } - //UNSUP constE yVAR lifetimeE signingE rangeList { /*VARRESET-in-ddVar*/ VARDECL("var"); VARTYPE(SPACED($1,SPACED($4,$5))); } + //UNSUP constE yVAR lifetimeE data_type { /*VARRESET-in-ddVar*/ VARDECL("var"); VARDTYPE(SPACED($1,$4)); } + //UNSUP constE yVAR lifetimeE { /*VARRESET-in-ddVar*/ VARDECL("var"); VARDTYPE($1); } + //UNSUP constE yVAR lifetimeE signingE rangeList { /*VARRESET-in-ddVar*/ VARDECL("var"); VARDTYPE(SPACED($1,SPACED($4,$5))); } // // // Expanded: "constE lifetimeE data_type" - /**/ data_type { /*VARRESET-in-ddVar*/ VARTYPE($1); } - | /**/ lifetime data_type { /*VARRESET-in-ddVar*/ VARTYPE($2); } - //UNSUP yCONST__ETC lifetimeE data_type { /*VARRESET-in-ddVar*/ VARTYPE($3); } + /**/ data_type { /*VARRESET-in-ddVar*/ VARDTYPE($1); } + | /**/ lifetime data_type { /*VARRESET-in-ddVar*/ VARDTYPE($2); } + //UNSUP yCONST__ETC lifetimeE data_type { /*VARRESET-in-ddVar*/ VARDTYPE($3); } // // = class_new is in variable_decl_assignment ; -implicit_type: // IEEE: part of *data_type_or_implicit +implicit_type: // IEEE: part of *data_type_or_implicit // // Also expanded in data_declaration /* empty */ { $$ = NULL; } - | signingE rangeList { $$ = $2; } // signing sets VARSIGNED, so not passed up - | signing { $$ = NULL; } // signing sets VARSIGNED, so not passed up + | signingE rangeList { $$ = new AstBasicDType($2->fileline(), LOGIC, $2, $1); } + | signing { $$ = new AstBasicDType($1, LOGIC, NULL, $1); } ; //************************************************ @@ -1232,9 +1240,9 @@ rangeList: // IEEE: {packed_dimension} | rangeList anyrange { $$ = $1; $1->addNext($2); } ; -regrangeE: - /* empty */ { $$ = NULL; VARRANGE($$); } - | anyrange { $$ = $1; VARRANGE($$); } +regrangeE: + /* empty */ { $$ = new AstBasicDType(CRELINE(), LOGIC, NULL); } + | anyrange { $$ = new AstBasicDType(CRELINE(), LOGIC, $1); } ; // IEEE: select @@ -1244,7 +1252,7 @@ anyrange: '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); } ; -delayrange: +delayrange: regrangeE delayE { $$ = $1; } | ySCALARED regrangeE delayE { $$ = $2; } | yVECTORED regrangeE delayE { $$ = $2; } @@ -1791,12 +1799,12 @@ tfBodyE: // IEEE: part of function_body_declaration/task_body_declarati | stmtList { $$ = $1; } ; -funcTypeE: +funcTypeE: /* empty */ { $$ = NULL; } - | yINTEGER { $$ = new AstRange($1,31,0); $$->isSigned(true); } - | ySIGNED { $$ = new AstRange($1,0,0); $$->isSigned(true); } - | ySIGNED '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$3,$5); $$->isSigned(true); } - | '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); } + | yINTEGER { $$ = new AstBasicDType($1,AstBasicDTypeKwd::INTEGER); } + | ySIGNED { $$ = new AstBasicDType($1,LOGIC, NULL); $$->isSigned(true); } + | ySIGNED '[' constExpr ':' constExpr ']' { $$ = new AstBasicDType($1,LOGIC, new AstRange($1,$3,$5)); $$->isSigned(true); } + | '[' constExpr ':' constExpr ']' { $$ = new AstBasicDType($1,LOGIC, new AstRange($1,$2,$4)); } ; tf_item_declarationList: @@ -1833,18 +1841,18 @@ tf_port_item: // ==IEEE: tf_port_item ; tf_port_itemFront: // IEEE: part of tf_port_item, which has the data type - data_type { VARTYPE($1); } - | signingE rangeList { VARTYPE($2); } - | signing { VARTYPE(NULL); } - //UNSUP yVAR data_type { VARTYPE($2); } - //UNSUP yVAR implicit_type { VARTYPE($2); } + data_type { VARDTYPE($1); } + | signingE rangeList { VARDTYPE(new AstBasicDType($2->fileline(), LOGIC, $2, $1)); } + | signing { VARDTYPE(new AstBasicDType($1, LOGIC, NULL, $1)); } + //UNSUP yVAR data_type { VARDTYPE($2); } + //UNSUP yVAR implicit_type { VARDTYPE($2); } // - | tf_port_itemDir /*implicit*/ { VARTYPE(NULL); /*default_nettype-see spec*/ } - | tf_port_itemDir data_type { VARTYPE($2); } - | tf_port_itemDir signingE rangeList { VARTYPE($3); } - | tf_port_itemDir signing { VARTYPE(NULL); } - //UNSUP tf_port_itemDir yVAR data_type { VARTYPE($3); } - //UNSUP tf_port_itemDir yVAR implicit_type { VARTYPE($3); } + | tf_port_itemDir /*implicit*/ { VARDTYPE(NULL); /*default_nettype-see spec*/ } + | tf_port_itemDir data_type { VARDTYPE($2); } + | tf_port_itemDir signingE rangeList { VARDTYPE(new AstBasicDType($3->fileline(), LOGIC, $3, $2)); } + | tf_port_itemDir signing { VARDTYPE(new AstBasicDType($2, LOGIC, NULL, $2)); } + //UNSUP tf_port_itemDir yVAR data_type { VARDTYPE($3); } + //UNSUP tf_port_itemDir yVAR implicit_type { VARDTYPE($3); } ; tf_port_itemDir: // IEEE: part of tf_port_item, direction @@ -2555,7 +2563,7 @@ const char* V3ParseImp::tokenName(int token) { void V3ParseImp::parserClear() { // Clear up any dynamic memory V3Parser required - GRAMMARP->setRange(NULL); + VARDTYPE(NULL); } AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, string name, int value) { @@ -2570,43 +2578,33 @@ AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, string name, int v } AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange* arrayp, AstNode* attrsp) { - AstVarType type = GRAMMARP->m_varIO; - AstRange* rangep = GRAMMARP->m_varRangep; - AstRange* cleanup_rangep = NULL; - //UINFO(0,"CREVAR "<ascii()<<" decl="<m_varDecl.ascii()<<" io="<m_varIO.ascii()<m_varDecl; - if (type == AstVarType::PORT) { - // Just wanted port decl; we've already made it. - if (rangep) fileline->v3error("Unsupported: Ranges ignored in port-lists"); + AstNodeDType* dtypep = GRAMMARP->m_varDTypep; + UINFO(5," creVar "<m_varIO == AstVarType::UNKNOWN + && GRAMMARP->m_varDecl == AstVarType::PORT) { + // Just a port list with variable name (not v2k format); AstPort already created + if (dtypep) fileline->v3error("Unsupported: Ranges ignored in port-lists"); return NULL; } - if (type == AstVarType::UNKNOWN) fileline->v3fatalSrc("Unknown signal type declared"); - // Linting, because we allow parsing of a superset of the language - if (type == AstVarType::INTEGER || GRAMMARP->m_varDecl == AstVarType::INTEGER - || type == AstVarType::GENVAR) { - if (rangep) { - if (rangep->msbConst()==31 && rangep->lsbConst()==0) { - // For backward compatibility with functions some INTEGERS are internally made as [31:0] - rangep->deleteTree(); rangep=NULL; GRAMMARP->m_varRangep=NULL; - } else { - fileline->v3error("Integers may not be ranged: "<m_varIO; + if (!dtypep) { // Created implicitly + // We also make them for standalone ports, which is a bit silly, but we'll clean up later + dtypep = new AstBasicDType(fileline, LOGIC); + } else { // May make new variables with same type, so clone + dtypep = dtypep->cloneTree(false); } + //UINFO(0,"CREVAR "<ascii()<<" decl="<m_varDecl.ascii()<<" io="<m_varIO.ascii()<m_varDecl != AstVarType::UNKNOWN)) + type = GRAMMARP->m_varDecl; + if (type == AstVarType::UNKNOWN) fileline->v3fatalSrc("Unknown signal type declared"); if (type == AstVarType::GENVAR) { if (arrayp) fileline->v3error("Genvars may not be arrayed: "<cloneTree(false), + dtypep, arrayp); nodep->addAttrsp(attrsp); - nodep->isSigned(GRAMMARP->m_varSigned); - if (type == AstVarType::INTEGER || GRAMMARP->m_varDecl == AstVarType::INTEGER - || type == AstVarType::GENVAR) { - nodep->isSigned(true); - } if (GRAMMARP->m_varDecl != AstVarType::UNKNOWN) nodep->combineType(GRAMMARP->m_varDecl); if (GRAMMARP->m_varIO != AstVarType::UNKNOWN) nodep->combineType(GRAMMARP->m_varIO); @@ -2625,7 +2623,6 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange // Remember the last variable created, so we can attach attributes to it in later parsing GRAMMARP->m_varAttrp = nodep; - if (cleanup_rangep) { cleanup_rangep->deleteTree(); cleanup_rangep=NULL; } return nodep; }