diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 29e19bc36..0646d10ba 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -2758,15 +2758,20 @@ struct AstInsideRange : public AstNodeMath { struct AstInitArray : public AstNode { // Set a var to a large list of values // The values must be in sorted order, and not exceed the size of the var's array. + // The first value on the initsp() list is for the lo() index of the array. // Parents: ASTVAR::init() // Children: CONSTs... - AstInitArray(FileLine* fl, AstNode* initsp) + AstInitArray(FileLine* fl, AstNodeArrayDType* newDTypep, AstNode* initsp) : AstNode(fl) { + dtypep(newDTypep); addNOp1p(initsp); } ASTNODE_NODE_FUNCS(InitArray, INITARRAY) AstNode* initsp() const { return op1p()->castNode(); } // op1 = Initial value expressions void addInitsp(AstNode* newp) { addOp1p(newp); } + virtual bool hasDType() const { return true; } + virtual V3Hash sameHash() const { return V3Hash(); } + virtual bool same(AstNode* samep) const { return true; } }; struct AstPragma : public AstNode { diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index b9f4a8706..b2c012af9 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -446,6 +446,14 @@ class EmitVBaseVisitor : public EmitCBaseVisitor { } puts(")"); } + virtual void visit(AstInitArray* nodep, AstNUser*) { + putfs(nodep,"`{"); + for (AstNode* subp = nodep->initsp(); subp; subp=subp->nextp()) { + subp->accept(*this); + if (subp->nextp()) putbs(","); + } + puts("}"); + } virtual void visit(AstNodeCond* nodep, AstNUser*) { putbs("("); nodep->condp()->iterateAndNext(*this); putfs(nodep," ? "); diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index b02ae3ba8..1d835666c 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -70,7 +70,7 @@ class SliceCloneVisitor : public AstNVisitor { // VISITORS virtual void visit(AstArraySel* nodep, AstNUser*) { if (!nodep->backp()->castArraySel()) { - // This is the top of an ArraySel, setup + // This is the top of an ArraySel, setup for iteration m_refp = nodep->user1p()->castNode()->castVarRef(); m_vecIdx += 1; if (m_vecIdx == (int)m_selBits.size()) { @@ -78,6 +78,7 @@ class SliceCloneVisitor : public AstNVisitor { AstVar* varp = m_refp->varp(); pair arrDim = varp->dtypep()->dimensions(false); uint32_t dimensions = arrDim.second; + // for 3-dimensions we want m_selBits[m_vecIdx]=[0,0,0] for (uint32_t i = 0; i < dimensions; ++i) { m_selBits[m_vecIdx].push_back(0); } @@ -165,19 +166,15 @@ class SliceCloneVisitor : public AstNVisitor { nodep->addNextHere(lhsp); nodep->unlinkFrBack()->deleteTree(); nodep = NULL; } - virtual void visit(AstRedOr* nodep, AstNUser*) { cloneUniop(nodep); } - virtual void visit(AstRedAnd* nodep, AstNUser*) { cloneUniop(nodep); } - virtual void visit(AstRedXor* nodep, AstNUser*) { cloneUniop(nodep); } - virtual void visit(AstRedXnor* nodep, AstNUser*) { cloneUniop(nodep); } @@ -188,8 +185,8 @@ class SliceCloneVisitor : public AstNVisitor { } public: // CONSTUCTORS - SliceCloneVisitor(AstNode* assignp) { - assignp->accept(*this); + SliceCloneVisitor(AstNode* nodep) { + nodep->accept(*this); } virtual ~SliceCloneVisitor() {} }; @@ -223,8 +220,8 @@ class SliceVisitor : public AstNVisitor { return level; } - // Find out how many explicit dimensions are in a given ArraySel. unsigned explicitDimensions(AstArraySel* nodep) { + // Find out how many explicit dimensions are in a given ArraySel. unsigned dim = 0; AstNode* fromp = nodep; AstArraySel* selp; @@ -243,10 +240,23 @@ class SliceVisitor : public AstNVisitor { return dim; } + int countClones(AstArraySel* nodep) { + // Count how many clones we need to make from this ArraySel + int clones = 1; + AstNode* fromp = nodep; + AstArraySel* selp; + do { + selp = fromp->castArraySel(); + fromp = (selp) ? selp->fromp() : NULL; + if (fromp && selp) clones *= selp->length(); + } while (fromp && selp); + return clones; + } + AstArraySel* insertImplicit(AstNode* nodep, unsigned start, unsigned count) { // Insert any implicit slices as explicit slices (ArraySel nodes). // Return a new pointer to replace nodep() in the ArraySel. - UINFO(9," insertImplicit "<user1p()->castNode()->castVarRef(); if (!refp) nodep->v3fatalSrc("No VarRef in user1 of node "<varp(); @@ -269,28 +279,15 @@ class SliceVisitor : public AstNVisitor { newp->user1p(refp); newp->start(lsb); newp->length(msb - lsb + 1); - topp = newp->castNode(); + topp = newp; } return topp->castArraySel(); } - int countClones(AstArraySel* nodep) { - // Count how many clones we need to make from this ArraySel - int clones = 1; - AstNode* fromp = nodep; - AstArraySel* selp; - do { - selp = fromp->castArraySel(); - fromp = (selp) ? selp->fromp() : NULL; - if (fromp && selp) clones *= selp->length(); - } while (fromp && selp); - return clones; - } - // VISITORS virtual void visit(AstVarRef* nodep, AstNUser*) { // The LHS/RHS of an Assign may be to a Var that is an array. In this - // case we need to create a slice accross the entire Var + // case we need to create a slice across the entire Var if (m_assignp && !nodep->backp()->castArraySel()) { pair arrDim = nodep->varp()->dtypep()->dimensions(false); uint32_t dimensions = arrDim.second; // unpacked only @@ -382,8 +379,8 @@ class SliceVisitor : public AstNVisitor { refp = findVarRefRecurse(nodep->op3p()); if (refp) return refp; } - if (nodep->op3p()) { - refp = findVarRefRecurse(nodep->op3p()); + if (nodep->op4p()) { + refp = findVarRefRecurse(nodep->op4p()); if (refp) return refp; } if (nodep->nextp()) { @@ -424,7 +421,7 @@ class SliceVisitor : public AstNVisitor { dim = explicitDimensions(selp); } if (dim == 0 && !nodep->lhsp()->castVarRef()) { - // No ArraySel or VarRef, not something we can expand + // No ArraySel nor VarRef, not something we can expand nodep->iterateChildren(*this); } else { AstVarRef* refp = findVarRefRecurse(nodep->lhsp()); @@ -445,25 +442,21 @@ class SliceVisitor : public AstNVisitor { } } } - virtual void visit(AstRedOr* nodep, AstNUser*) { if (!nodep->user1()) { expandUniOp(nodep); } } - virtual void visit(AstRedAnd* nodep, AstNUser*) { if (!nodep->user1()) { expandUniOp(nodep); } } - virtual void visit(AstRedXor* nodep, AstNUser*) { if (!nodep->user1()) { expandUniOp(nodep); } } - virtual void visit(AstRedXnor* nodep, AstNUser*) { if (!nodep->user1()) { expandUniOp(nodep); diff --git a/src/V3Table.cpp b/src/V3Table.cpp index e6e705457..19e38b2fe 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -188,7 +188,7 @@ private: // Change it variable FileLine* fl = nodep->fileline(); - AstNodeDType* dtypep + AstNodeArrayDType* dtypep = new AstUnpackArrayDType (fl, nodep->findBitDType(m_outVarps.size(), m_outVarps.size(), AstNumeric::UNSIGNED), @@ -199,7 +199,7 @@ private: "__Vtablechg" + cvtToStr(m_modTables), dtypep); chgVarp->isConst(true); - chgVarp->valuep(new AstInitArray (nodep->fileline(), NULL)); + chgVarp->valuep(new AstInitArray (nodep->fileline(), dtypep, NULL)); m_modp->addStmtp(chgVarp); AstVarScope* chgVscp = new AstVarScope (chgVarp->fileline(), m_scopep, chgVarp); m_scopep->addVarp(chgVscp); @@ -236,7 +236,7 @@ private: AstVarScope* outvscp = *it; AstVar* outvarp = outvscp->varp(); FileLine* fl = nodep->fileline(); - AstNodeDType* dtypep + AstNodeArrayDType* dtypep = new AstUnpackArrayDType (fl, outvarp->dtypep(), new AstRange (fl, VL_MASK_I(m_inWidth), 0)); v3Global.rootp()->typeTablep()->addTypesp(dtypep); @@ -246,7 +246,7 @@ private: dtypep); tablevarp->isConst(true); tablevarp->isStatic(true); - tablevarp->valuep(new AstInitArray (nodep->fileline(), NULL)); + tablevarp->valuep(new AstInitArray (nodep->fileline(), dtypep, NULL)); m_modp->addStmtp(tablevarp); AstVarScope* tablevscp = new AstVarScope(tablevarp->fileline(), m_scopep, tablevarp); m_scopep->addVarp(tablevscp); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 79477ff41..0a4fa7d33 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2600,10 +2600,10 @@ private: pair dim = nodep->skipRefp()->dimensions(true); uint32_t maxdim = dim.first+dim.second; // - AstInitArray* initp = new AstInitArray (nodep->fileline(), NULL); - AstNodeDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(), - nodep->findSigned32DType(), - new AstRange(nodep->fileline(), maxdim, 0)); + AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(), + nodep->findSigned32DType(), + new AstRange(nodep->fileline(), maxdim, 0)); + AstInitArray* initp = new AstInitArray (nodep->fileline(), vardtypep, NULL); v3Global.rootp()->typeTablep()->addTypesp(vardtypep); AstVar* varp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP, "__Vdimtable" + cvtToStr(m_dtTables++),