mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
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:
+9
-9
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user