Internals: Split into packed and unpacked array types

This commit is contained in:
Wilson Snyder 2013-01-12 16:19:25 -05:00
parent ae1ab8aaaa
commit 5c7a6e278f
16 changed files with 134 additions and 96 deletions

View File

@ -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

View File

@ -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<uint32_t,uint32_t> 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<<" "<<AstNode::quoteName(name());
}
void AstArrayDType::dump(ostream& str) {
this->AstNodeDType::dump(str);
if (isPacked()) str<<" [PACKED]";
}
void AstArraySel::dump(ostream& str) {
this->AstNode::dump(str);
str<<" [start:"<<start()<<"] [length:"<<length()<<"]";

View File

@ -223,62 +223,54 @@ public:
void name(const string& flag) { m_name = flag; }
};
struct AstArrayDType : public AstNodeDType {
struct AstPackArrayDType : public AstNodeArrayDType {
// 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)
bool m_packed;
public:
AstArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep, bool isPacked=false)
: AstNodeDType(fl), m_packed(isPacked) {
AstPackArrayDType(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());
}
AstArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep, bool isPacked=false)
: AstNodeDType(fl), m_packed(isPacked) {
AstPackArrayDType(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(ArrayDType, ARRAYDTYPE)
virtual void dump(ostream& str);
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 {
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 {

View File

@ -86,7 +86,7 @@ private:
#endif
AstVar* varp = vscp->varp();
vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<<vscp);
AstArrayDType* arrayp = varp->dtypeSkipRefp()->castArrayDType();
AstNodeArrayDType* arrayp = varp->dtypeSkipRefp()->castNodeArrayDType();
bool isArray = arrayp;
int msb = isArray ? arrayp->msb() : 0;
int lsb = isArray ? arrayp->lsb() : 0;

View File

@ -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)+"]",

View File

@ -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; i<arrayp->elementsConst(); 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)+"]");

View File

@ -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++;

View File

@ -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);
}

View File

@ -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();

View File

@ -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) {

View File

@ -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,

View File

@ -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";
}

View File

@ -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;

View File

@ -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());

View File

@ -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);

View File

@ -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;
}
}