From 5c7a6e278f3bc1dc115683d1cff1e7e34889f5de Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 12 Jan 2013 16:19:25 -0500 Subject: [PATCH] Internals: Split into packed and unpacked array types --- src/V3Ast.h | 48 ++++++++++++++++++++++++++- src/V3AstNodes.cpp | 12 +++---- src/V3AstNodes.h | 80 ++++++++++++++++++++------------------------- src/V3Changed.cpp | 2 +- src/V3Coverage.cpp | 2 +- src/V3EmitC.cpp | 36 ++++++++++---------- src/V3EmitCSyms.cpp | 2 +- src/V3EmitV.cpp | 2 +- src/V3Slice.cpp | 2 +- src/V3Stats.cpp | 4 +-- src/V3Table.cpp | 12 +++---- src/V3TraceDecl.cpp | 4 +-- src/V3Unknown.cpp | 2 +- src/V3Width.cpp | 10 +++--- src/V3WidthSel.cpp | 6 ++-- src/verilog.y | 6 +++- 16 files changed, 134 insertions(+), 96 deletions(-) diff --git a/src/V3Ast.h b/src/V3Ast.h index cd70254fb..3f73c762a 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1498,7 +1498,7 @@ public: // // Changing the width may confuse the data type resolution, so must clear TypeTable cache after use. void widthForce(int width, int sized) { m_width=width; m_widthMin=sized; } - // For backward compatibility AstArrayDType and others inherit width and signing from the subDType/base type + // For backward compatibility inherit width and signing from the subDType/base type void widthFromSub(AstNodeDType* nodep) { m_width=nodep->m_width; m_widthMin=nodep->m_widthMin; m_numeric=nodep->m_numeric; } // int width() const { return m_width; } @@ -1553,6 +1553,47 @@ public: } }; +struct AstNodeArrayDType : public AstNodeDType { + // Array data type, ie "some_dtype var_name [2:0]" + // Children: DTYPE (moved to refDTypep() in V3Width) + // Children: RANGE (array bounds) +private: + AstNodeDType* m_refDTypep; // Elements of this type (after widthing) + AstNode* rangenp() const { return op2p(); } // op2 = Array(s) of variable +public: + AstNodeArrayDType(FileLine* fl) : AstNodeDType(fl) {} + ASTNODE_BASE_FUNCS(NodeArrayDType) + virtual bool broken() const { return !((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists()) + || (!m_refDTypep && childDTypep())); } + virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) { + m_refDTypep = m_refDTypep->clonep()->castNodeDType(); + }} + virtual bool same(AstNode* samep) const { + AstNodeArrayDType* sp = samep->castNodeArrayDType(); + return (msb()==sp->msb() + && subDTypep()==sp->subDTypep() + && rangenp()->sameTree(sp->rangenp())); } // HashedDT doesn't recurse, so need to check children + virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(msb()),V3Hash(lsb())); } + AstNodeDType* getChildDTypep() const { return childDTypep(); } + AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable + void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } + AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } + void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } + virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; } + virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } + AstRange* rangep() const { return op2p()->castRange(); } // op2 = Array(s) of variable + void rangep(AstRange* nodep); + // METHODS + virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type + virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } + virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } + virtual int widthTotalBytes() const { return elementsConst() * subDTypep()->widthTotalBytes(); } + int msb() const; + int lsb() const; + int elementsConst() const; + int msbMaxSelect() const { return (lsb()<0 ? msb()-lsb() : msb()); } // Maximum value a [] select may index +}; + struct AstNodeSel : public AstNodeBiop { // Single bit range extraction, perhaps with non-constant selection or array selection AstNodeSel(FileLine* fl, AstNode* fromp, AstNode* bitp) @@ -1745,4 +1786,9 @@ inline bool AstNode::isAllOnesV() { return (this->castConst() && this->castConst inline void AstNodeVarRef::init() { if (m_varp) dtypep(m_varp->dtypep()); } +inline void AstNodeArrayDType::rangep(AstRange* nodep) { setOp2p(nodep); } +inline int AstNodeArrayDType::msb() const { return rangep()->msbConst(); } +inline int AstNodeArrayDType::lsb() const { return rangep()->lsbConst(); } +inline int AstNodeArrayDType::elementsConst() const { return rangep()->elementsConst(); } + #endif // Guard diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 8a008cb7e..cc2d06e52 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -310,7 +310,7 @@ AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) { int dim = 0; for (AstNodeDType* dtypep=this; dtypep; ) { dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node - if (AstArrayDType* adtypep = dtypep->castArrayDType()) { + if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) { if ((dim++)==dimension) { return dtypep; } @@ -344,7 +344,7 @@ uint32_t AstNodeDType::arrayElements() { uint32_t entries=1; for (AstNodeDType* dtypep=this; dtypep; ) { dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node - if (AstArrayDType* adtypep = dtypep->castArrayDType()) { + if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) { entries *= adtypep->elementsConst(); dtypep = adtypep->subDTypep(); } @@ -362,8 +362,8 @@ pair AstNodeDType::dimensions() { uint32_t unpacked = 0; for (AstNodeDType* dtypep=this; dtypep; ) { dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node - if (AstArrayDType* adtypep = dtypep->castArrayDType()) { - if (adtypep->isPacked()) packed += 1; + if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) { + if (adtypep->castPackArrayDType()) packed += 1; else unpacked += 1; dtypep = adtypep->subDTypep(); } @@ -667,10 +667,6 @@ void AstNode::dump(ostream& str) { if (name()!="") str<<" "<AstNodeDType::dump(str); - if (isPacked()) str<<" [PACKED]"; -} void AstArraySel::dump(ostream& str) { this->AstNode::dump(str); str<<" [start:"<brokeExists()) - || (!m_refDTypep && childDTypep())); } - virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) { - m_refDTypep = m_refDTypep->clonep()->castNodeDType(); - }} - virtual bool same(AstNode* samep) const { - AstArrayDType* sp = samep->castArrayDType(); - return (m_packed==sp->m_packed - && msb()==sp->msb() - && subDTypep()==sp->subDTypep() - && rangep()->sameTree(sp->rangep())); } // HashedDT doesn't recurse, so need to check children - virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(msb()),V3Hash(lsb())); } - AstNodeDType* getChildDTypep() const { return childDTypep(); } - AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable - void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } - AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } - void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } - virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; } - virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } - AstRange* rangep() const { return op2p()->castRange(); } // op2 = Array(s) of variable - void rangep(AstRange* nodep) { setOp2p(nodep); } - // METHODS - virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type - virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } - virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } - virtual int widthTotalBytes() const { return elementsConst() * subDTypep()->widthTotalBytes(); } - int msb() const { return rangep()->msbConst(); } - int lsb() const { return rangep()->lsbConst(); } - int elementsConst() const { return rangep()->elementsConst(); } - int msbMaxSelect() const { return (lsb()<0 ? msb()-lsb() : msb()); } // Maximum value a [] select may index - bool isPacked() const { return m_packed; } + ASTNODE_NODE_FUNCS(PackArrayDType, PACKARRAYDTYPE) +}; + +struct AstUnpackArrayDType : public AstNodeArrayDType { + // Array data type, ie "some_dtype var_name [2:0]" + // Children: DTYPE (moved to refDTypep() in V3Width) + // Children: RANGE (array bounds) +public: + AstUnpackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep) + : AstNodeArrayDType(fl) { + childDTypep(dtp); // Only for parser + refDTypep(NULL); + setOp2p(rangep); + dtypep(NULL); // V3Width will resolve + // For backward compatibility AstNodeArrayDType and others inherit width and signing from the subDType/base type + widthFromSub(subDTypep()); + } + AstUnpackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep) + : AstNodeArrayDType(fl) { + refDTypep(dtp); + setOp2p(rangep); + dtypep(this); + // For backward compatibility AstNodeArrayDType and others inherit width and signing from the subDType/base type + widthFromSub(subDTypep()); + } + ASTNODE_NODE_FUNCS(UnpackArrayDType, UNPACKARRAYDTYPE) }; struct AstBasicDType : public AstNodeDType { @@ -626,9 +618,9 @@ private: unsigned m_start; unsigned m_length; void init(AstNode* fromp) { - if (fromp && fromp->dtypep()->castArrayDType()) { + if (fromp && fromp->dtypep()->castNodeArrayDType()) { // Strip off array to find what array references - dtypeFrom(fromp->dtypep()->castArrayDType()->subDTypep()); + dtypeFrom(fromp->dtypep()->castNodeArrayDType()->subDTypep()); } } public: @@ -2604,7 +2596,7 @@ public: AstBasicDType* bdtypep = varp->basicp(); m_left = bdtypep ? bdtypep->left() : 0; m_right = bdtypep ? bdtypep->right() : 0; - if (AstArrayDType* adtypep = varp->dtypeSkipRefp()->castArrayDType()) { + if (AstNodeArrayDType* adtypep = varp->dtypeSkipRefp()->castNodeArrayDType()) { m_arrayLsb = adtypep->lsb(); m_arrayMsb = adtypep->msb(); } else { diff --git a/src/V3Changed.cpp b/src/V3Changed.cpp index 7cbe1f3db..287a684d8 100644 --- a/src/V3Changed.cpp +++ b/src/V3Changed.cpp @@ -86,7 +86,7 @@ private: #endif AstVar* varp = vscp->varp(); vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<dtypeSkipRefp()->castArrayDType(); + AstNodeArrayDType* arrayp = varp->dtypeSkipRefp()->castNodeArrayDType(); bool isArray = arrayp; int msb = isArray ? arrayp->msb() : 0; int lsb = isArray ? arrayp->lsb() : 0; diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index c93b7eb53..46aaaea37 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -209,7 +209,7 @@ private: varp, chgVarp); } } - else if (AstArrayDType* adtypep = dtypep->castArrayDType()) { + else if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) { for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb()+1; ++index_docs) { int index_code = index_docs - adtypep->lsb(); ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]", diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 602a7d153..3897e4e3e 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -321,7 +321,7 @@ public: { AstVarRef* varrefp = nodep->memp()->castVarRef(); if (!varrefp) { nodep->v3error("Readmem loading non-variable"); } - else if (AstArrayDType* adtypep = varrefp->varp()->dtypeSkipRefp()->castArrayDType()) { + else if (AstNodeArrayDType* adtypep = varrefp->varp()->dtypeSkipRefp()->castNodeArrayDType()) { puts(cvtToStr(varrefp->varp()->dtypep()->arrayElements())); array_lsb = adtypep->lsb(); } @@ -889,8 +889,8 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) { } puts(nodep->name()); if (isArray) { - for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; - arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) { + for (AstNodeArrayDType* arrayp=nodep->dtypeSkipRefp()->castNodeArrayDType(); arrayp; + arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) { puts("["+cvtToStr(arrayp->elementsConst())+"]"); } } @@ -910,8 +910,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->subDTypep()->skipRefp()->castArrayDType()) { + for (AstNodeArrayDType* arrayp=nodep->dtypeSkipRefp()->castNodeArrayDType(); arrayp; + arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) { puts("["+cvtToStr(arrayp->elementsConst())+"]"); } puts(","+cvtToStr(basicp->msb())+","+cvtToStr(basicp->lsb())); @@ -932,8 +932,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->subDTypep()->skipRefp()->castArrayDType()) { + for (AstNodeArrayDType* arrayp=nodep->dtypeSkipRefp()->castNodeArrayDType(); arrayp; + arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) { puts("["+cvtToStr(arrayp->elementsConst())+"]"); } puts(";\n"); @@ -958,8 +958,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->subDTypep()->skipRefp()->castArrayDType()) { + for (AstNodeArrayDType* arrayp=nodep->dtypeSkipRefp()->castNodeArrayDType(); arrayp; + arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) { puts("["+cvtToStr(arrayp->elementsConst())+"]"); } puts(","+cvtToStr(basicp->msb())+","+cvtToStr(basicp->lsb())); @@ -1328,7 +1328,7 @@ void EmitCImp::emitVarResets(AstNodeModule* modp) { } else if (AstInitArray* initarp = varp->valuep()->castInitArray()) { AstConst* constsp = initarp->initsp()->castConst(); - if (AstArrayDType* arrayp = varp->dtypeSkipRefp()->castArrayDType()) { + if (AstNodeArrayDType* arrayp = varp->dtypeSkipRefp()->castNodeArrayDType()) { for (int i=0; ielementsConst(); i++) { if (!constsp) initarp->v3fatalSrc("Not enough values in array initalizement"); emitSetVarConstant(varp->name()+"["+cvtToStr(i)+"]", constsp); @@ -1341,8 +1341,8 @@ void EmitCImp::emitVarResets(AstNodeModule* modp) { else { int vects = 0; // This isn't very robust and may need cleanup for other data types - for (AstArrayDType* arrayp=varp->dtypeSkipRefp()->castArrayDType(); arrayp; - arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) { + for (AstNodeArrayDType* arrayp=varp->dtypeSkipRefp()->castNodeArrayDType(); arrayp; + arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) { int vecnum = vects++; if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier."); string ivar = string("__Vi")+cvtToStr(vecnum); @@ -1508,8 +1508,8 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) { else { int vects = 0; // This isn't very robust and may need cleanup for other data types - for (AstArrayDType* arrayp=varp->dtypeSkipRefp()->castArrayDType(); arrayp; - arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) { + for (AstNodeArrayDType* arrayp=varp->dtypeSkipRefp()->castNodeArrayDType(); arrayp; + arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) { int vecnum = vects++; if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier."); string ivar = string("__Vi")+cvtToStr(vecnum); @@ -1599,8 +1599,8 @@ void EmitCImp::emitSensitives() { if (varp->isInput() && (varp->isScSensitive() || varp->isUsedClock())) { int vects = 0; // This isn't very robust and may need cleanup for other data types - for (AstArrayDType* arrayp=varp->dtypeSkipRefp()->castArrayDType(); arrayp; - arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) { + for (AstNodeArrayDType* arrayp=varp->dtypeSkipRefp()->castNodeArrayDType(); arrayp; + arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) { int vecnum = vects++; if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier."); string ivar = string("__Vi")+cvtToStr(vecnum); @@ -1697,7 +1697,7 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref int sigbytes = varp->dtypeSkipRefp()->widthAlignBytes(); int sortbytes = sortmax-1; if (varp->isUsedClock() && varp->widthMin()==1) sortbytes = 0; - else if (varp->dtypeSkipRefp()->castArrayDType()) sortbytes=8; + else if (varp->dtypeSkipRefp()->castNodeArrayDType()) sortbytes=8; else if (varp->basicp() && varp->basicp()->isOpaque()) sortbytes=7; else if (varp->isScBv()) sortbytes=6; else if (sigbytes==8) sortbytes=5; @@ -2234,7 +2234,7 @@ class EmitCTrace : EmitCStmts { if (emitTraceIsScBv(nodep)) puts("VL_SC_BV_DATAP("); varrefp->iterate(*this); // Put var name out // Tracing only supports 1D arrays - if (varp->dtypeSkipRefp()->castArrayDType()) { + if (varp->dtypeSkipRefp()->castNodeArrayDType()) { if (arrayindex==-2) puts("[i]"); else if (arrayindex==-1) puts("[0]"); else puts("["+cvtToStr(arrayindex)+"]"); diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 203d3b944..9225d2a92 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -465,7 +465,7 @@ void EmitCSyms::emitSymImp() { } for (AstNodeDType* dtypep=varp->dtypep(); dtypep; ) { dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node - if (AstArrayDType* adtypep = dtypep->castArrayDType()) { + if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) { bounds += " ,"; bounds += cvtToStr(adtypep->msb()); bounds += ","; bounds += cvtToStr(adtypep->lsb()); dim++; diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index 111c25b22..b7b5a142c 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -497,7 +497,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor { putfs(nodep,"const "); nodep->subDTypep()->iterateAndNext(*this); } - virtual void visit(AstArrayDType* nodep, AstNUser*) { + virtual void visit(AstNodeArrayDType* nodep, AstNUser*) { nodep->subDTypep()->iterateAndNext(*this); nodep->rangep()->iterateAndNext(*this); } diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index 6c6879e4c..0351ce75b 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -253,7 +253,7 @@ class SliceVisitor : public AstNVisitor { AstNode* topp = nodep; for (unsigned i = start; i < start + count; ++i) { AstNodeDType* dtypep = varp->dtypep()->dtypeDimensionp(i-1); - AstArrayDType* adtypep = dtypep->castArrayDType(); + AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType(); if (!adtypep) nodep->v3fatalSrc("insertImplicit tried to expand an array without an ArrayDType"); vlsint32_t msb = adtypep->msb(); vlsint32_t lsb = adtypep->lsb(); diff --git a/src/V3Stats.cpp b/src/V3Stats.cpp index e3b4ea4eb..22859e8f1 100644 --- a/src/V3Stats.cpp +++ b/src/V3Stats.cpp @@ -93,7 +93,7 @@ private: nodep->iterateChildren(*this); if (m_counting && nodep->dtypep()) { if (nodep->isUsedClock()) ++m_statVarClock; - if (nodep->dtypeSkipRefp()->castArrayDType()) ++m_statVarArray; + if (nodep->dtypeSkipRefp()->castPackArrayDType()) ++m_statVarArray; else m_statVarBytes += nodep->dtypeSkipRefp()->widthTotalBytes(); if (int(m_statVarWidths.size()) <= nodep->width()) { m_statVarWidths.resize(nodep->width()+5); @@ -197,7 +197,7 @@ public: V3Stats::addStat(m_stage, "Instruction count, TOTAL", m_statInstr); V3Stats::addStat(m_stage, "Instruction count, fast", m_statInstrFast); // Vars - V3Stats::addStat(m_stage, "Vars, arrayed", m_statVarArray); + V3Stats::addStat(m_stage, "Vars, packed arrayed", m_statVarArray); V3Stats::addStat(m_stage, "Vars, clock attribute", m_statVarClock); V3Stats::addStat(m_stage, "Var space, non-arrays, bytes", m_statVarBytes); if (m_statVarScpBytes) { diff --git a/src/V3Table.cpp b/src/V3Table.cpp index 6a84e92b1..a8c8c3f0b 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -189,10 +189,10 @@ private: // Change it variable FileLine* fl = nodep->fileline(); AstNodeDType* dtypep - = new AstArrayDType (fl, - nodep->findBitDType(m_outVarps.size(), - m_outVarps.size(), AstNumeric::UNSIGNED), - new AstRange (fl, VL_MASK_I(m_inWidth), 0), false); + = new AstUnpackArrayDType (fl, + nodep->findBitDType(m_outVarps.size(), + m_outVarps.size(), AstNumeric::UNSIGNED), + new AstRange (fl, VL_MASK_I(m_inWidth), 0)); v3Global.rootp()->typeTablep()->addTypesp(dtypep); AstVar* chgVarp = new AstVar (fl, AstVarType::MODULETEMP, @@ -237,8 +237,8 @@ private: AstVar* outvarp = outvscp->varp(); FileLine* fl = nodep->fileline(); AstNodeDType* dtypep - = new AstArrayDType (fl, outvarp->dtypep(), - new AstRange (fl, VL_MASK_I(m_inWidth), 0), false); + = new AstUnpackArrayDType (fl, outvarp->dtypep(), + new AstRange (fl, VL_MASK_I(m_inWidth), 0)); v3Global.rootp()->typeTablep()->addTypesp(dtypep); AstVar* tablevarp = new AstVar (fl, AstVarType::MODULETEMP, diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index 7d871d993..13e9a6e48 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -77,8 +77,8 @@ private: if ((int)nodep->width() > v3Global.opt.traceMaxWidth()) return "Wide bus > --trace-max-width bits"; if ((int)nodep->dtypep()->arrayElements() > v3Global.opt.traceMaxArray()) return "Wide memory > --trace-max-array ents"; if (!(nodep->dtypeSkipRefp()->castBasicDType() - || (nodep->dtypeSkipRefp()->castArrayDType() - && (nodep->dtypeSkipRefp()->castArrayDType()->subDTypep() + || (nodep->dtypeSkipRefp()->castNodeArrayDType() + && (nodep->dtypeSkipRefp()->castNodeArrayDType()->subDTypep() ->skipRefp()->castBasicDType())))) { return "Unsupported: Multi-dimensional array"; } diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 68506e713..85b95d42e 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -379,7 +379,7 @@ private: int maxmsb = 0; bool lvalue = false; if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { - AstArrayDType* adtypep = varrefp->varp()->dtypep()->dtypeDimensionp(dimension)->castArrayDType(); + AstNodeArrayDType* adtypep = varrefp->varp()->dtypep()->dtypeDimensionp(dimension)->castNodeArrayDType(); if (!adtypep) nodep->v3fatalSrc("ArraySel to type without array at same depth"); lvalue = varrefp->lvalue(); maxmsb = adtypep->elementsConst()-1; diff --git a/src/V3Width.cpp b/src/V3Width.cpp index e7a43862b..64c3a40ab 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -374,7 +374,7 @@ private: // So, see if we're sitting under a variable's arrayp. AstNode* huntbackp = nodep; while (huntbackp->backp()->castRange()) huntbackp=huntbackp->backp(); - if (huntbackp->backp()->castArrayDType()) { + if (huntbackp->backp()->castNodeArrayDType()) { } else { // Little endian bits are legal, just remember to swap // Warning is in V3Width to avoid false warnings when in "off" generate if's @@ -512,7 +512,7 @@ private: int frommsb; int fromlsb; AstNodeDType* ddtypep = varrp->varp()->dtypep()->dtypeDimensionp(dimension); - if (AstArrayDType* adtypep = ddtypep->castArrayDType()) { + if (AstNodeArrayDType* adtypep = ddtypep->castNodeArrayDType()) { frommsb = adtypep->msb(); fromlsb = adtypep->lsb(); if (fromlsb>frommsb) {int t=frommsb; frommsb=fromlsb; fromlsb=t; } @@ -676,7 +676,7 @@ private: } // DTYPES - virtual void visit(AstArrayDType* nodep, AstNUser*) { + virtual void visit(AstNodeArrayDType* nodep, AstNUser*) { if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed if (nodep->childDTypep()) nodep->refDTypep(moveChildDTypeEdit(nodep)); // Iterate into subDTypep() to resolve that type and update pointer. @@ -793,7 +793,7 @@ private: nodep->dtypep(iterateEditDTypep(nodep, nodep->dtypep())); if (!nodep->dtypep()) nodep->v3fatalSrc("No dtype determined for var"); if (nodep->isIO() && !(nodep->dtypeSkipRefp()->castBasicDType() - || nodep->dtypeSkipRefp()->castArrayDType() + || nodep->dtypeSkipRefp()->castNodeArrayDType() || nodep->dtypeSkipRefp()->castNodeClassDType())) { nodep->v3error("Unsupported: Inputs and outputs must be simple data types"); } @@ -1366,7 +1366,7 @@ private: virtual void visit(AstReadMem* nodep, AstNUser*) { nodep->filenamep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->memp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); - if (!nodep->memp()->dtypep()->skipRefp()->castArrayDType()) { + if (!nodep->memp()->dtypep()->skipRefp()->castNodeArrayDType()) { nodep->memp()->v3error("Unsupported: $readmem into non-array"); } nodep->lsbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index 601f49853..4cce95564 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -78,7 +78,7 @@ private: AstNodeDType* ddtypep = bfdtypep; ddtypep = ddtypep->dtypeDimensionp(dimension); if (debug()>=9 &&ddtypep) ddtypep->dumpTree(cout,"-ddtypep: "); - if (AstArrayDType* adtypep = ddtypep->castArrayDType()) { + if (AstNodeArrayDType* adtypep = ddtypep->castNodeArrayDType()) { return adtypep; } else if (AstNodeClassDType* adtypep = ddtypep->castNodeClassDType()) { @@ -195,7 +195,7 @@ private: AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); // bit we're extracting if (debug()>=9) ddtypep->dumpTree(cout,"-ddtypep: "); if (debug()>=9) nodep->dumpTree(cout,"-vsbmd: "); - if (AstArrayDType* adtypep = ddtypep->castArrayDType()) { + if (AstNodeArrayDType* adtypep = ddtypep->castNodeArrayDType()) { // SELBIT(array, index) -> ARRAYSEL(array, index) AstNode* subp = rhsp; if (adtypep->lsb()!=0 || adtypep->msb()<0) { @@ -258,7 +258,7 @@ private: vlsint32_t msb = msbp->castConst()->toSInt(); vlsint32_t lsb = lsbp->castConst()->toSInt(); AstNodeDType* ddtypep = dtypeForExtractp(nodep, basefromp, dimension, msb!=lsb); - if (AstArrayDType* adtypep = ddtypep->castArrayDType()) { + if (AstNodeArrayDType* adtypep = ddtypep->castNodeArrayDType()) { if (adtypep) {} // Slice extraction AstArraySel* newp = new AstArraySel (nodep->fileline(), fromp, lsbp); diff --git a/src/verilog.y b/src/verilog.y index e2d6090d5..b75aaa884 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -3433,7 +3433,11 @@ AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep, AstRange* rangep, while (rangep) { AstRange* prevp = rangep->backp()->castRange(); if (prevp) rangep->unlinkFrBack(); - arrayp = new AstArrayDType(rangep->fileline(), VFlagChildDType(), arrayp, rangep, isPacked); + if (isPacked) { + arrayp = new AstPackArrayDType(rangep->fileline(), VFlagChildDType(), arrayp, rangep); + } else { + arrayp = new AstUnpackArrayDType(rangep->fileline(), VFlagChildDType(), arrayp, rangep); + } rangep = prevp; } }