Fix nested packed arrays and structs, bug600.

IMPORTANT: Packed arrays are now represented as a single linear vector in
Verilated models this may affect packed arrays that are public or accessed via the VPI.
This commit is contained in:
Wilson Snyder
2013-01-14 21:49:22 -05:00
parent 057ca497dd
commit 8127a79cb1
23 changed files with 268 additions and 114 deletions
+9 -9
View File
@@ -77,7 +77,7 @@ class SliceCloneVisitor : public AstNVisitor {
m_selBits.push_back(vector<unsigned>());
AstVar* varp = m_refp->varp();
pair<uint32_t,uint32_t> arrDim = varp->dtypep()->dimensions();
uint32_t dimensions = arrDim.first + arrDim.second;
uint32_t dimensions = arrDim.second;
for (uint32_t i = 0; i < dimensions; ++i) {
m_selBits[m_vecIdx].push_back(0);
}
@@ -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);
AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType();
AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType();
if (!adtypep) nodep->v3fatalSrc("insertImplicit tried to expand an array without an ArrayDType");
vlsint32_t msb = adtypep->msb();
vlsint32_t lsb = adtypep->lsb();
@@ -293,7 +293,7 @@ class SliceVisitor : public AstNVisitor {
// case we need to create a slice accross the entire Var
if (m_assignp && !nodep->backp()->castArraySel()) {
pair<uint32_t,uint32_t> arrDim = nodep->varp()->dtypep()->dimensions();
uint32_t dimensions = arrDim.first + arrDim.second;
uint32_t dimensions = arrDim.second; // unpacked only
if (dimensions > 0) {
AstVarRef* clonep = nodep->cloneTree(false);
clonep->user1p(nodep);
@@ -307,7 +307,7 @@ class SliceVisitor : public AstNVisitor {
virtual void visit(AstExtend* nodep, AstNUser*) {
m_extend = true;
if (m_assignp && m_assignp->user2() > 1 && !m_assignError) {
m_assignp->v3error("Unsupported: Assignment between packed arrays of different dimensions");
m_assignp->v3error("Unsupported: Assignment between unpacked arrays of different dimensions");
m_assignError = true;
}
nodep->iterateChildren(*this);
@@ -327,7 +327,7 @@ class SliceVisitor : public AstNVisitor {
unsigned dim = explicitDimensions(nodep);
AstVarRef* refp = nodep->user1p()->castNode()->castVarRef();
pair<uint32_t,uint32_t> arrDim = refp->varp()->dtypep()->dimensions();
uint32_t implicit = (arrDim.first + arrDim.second) - dim;
uint32_t implicit = (arrDim.second) - dim;
if (implicit > 0) {
AstArraySel* newp = insertImplicit(nodep->cloneTree(false), dim+1, implicit);
nodep->replaceWith(newp); nodep = newp;
@@ -338,7 +338,7 @@ class SliceVisitor : public AstNVisitor {
m_assignp->v3error("Slices of arrays in assignments must have the same unpacked dimensions");
} else if (!m_assignp->user2()) {
if (m_extend && clones > 1 && !m_assignError) {
m_assignp->v3error("Unsupported: Assignment between packed arrays of different dimensions");
m_assignp->v3error("Unsupported: Assignment between unpacked arrays of different dimensions");
m_assignError = true;
}
if (clones > 1 && !refp->lvalue() && refp->varp() == m_lhsVarRefp->varp()
@@ -354,7 +354,7 @@ class SliceVisitor : public AstNVisitor {
virtual void visit(AstSel* nodep, AstNUser*) {
m_extend = true;
if (m_assignp && m_assignp->user2() > 1 && !m_assignError) {
m_assignp->v3error("Unsupported: Assignment between packed arrays of different dimensions");
m_assignp->v3error("Unsupported: Assignment between unpacked arrays of different dimensions");
m_assignError = true;
}
nodep->iterateChildren(*this);
@@ -432,9 +432,9 @@ class SliceVisitor : public AstNVisitor {
if ((int)(dim - varDim.second) < 0) {
// Unpacked dimensions are referenced first, make sure we have them all
nodep->v3error("Unary operator used across unpacked dimensions");
} else if ((int)(dim - (varDim.first + varDim.second)) < 0) {
} else if ((int)(dim - (varDim.second)) < 0) {
// Implicit packed dimensions are allowed, make them explicit
uint32_t newDim = (varDim.first + varDim.second) - dim;
uint32_t newDim = (varDim.second) - dim;
AstNode* clonep = nodep->lhsp()->cloneTree(false);
clonep->user1p(refp);
AstNode* newp = insertImplicit(clonep, dim+1, newDim);