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. // 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; } 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; } 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; } 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 { struct AstNodeSel : public AstNodeBiop {
// Single bit range extraction, perhaps with non-constant selection or array selection // Single bit range extraction, perhaps with non-constant selection or array selection
AstNodeSel(FileLine* fl, AstNode* fromp, AstNode* bitp) 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 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 #endif // Guard

View File

@ -310,7 +310,7 @@ AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
int dim = 0; int dim = 0;
for (AstNodeDType* dtypep=this; dtypep; ) { for (AstNodeDType* dtypep=this; dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstArrayDType* adtypep = dtypep->castArrayDType()) { if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
if ((dim++)==dimension) { if ((dim++)==dimension) {
return dtypep; return dtypep;
} }
@ -344,7 +344,7 @@ uint32_t AstNodeDType::arrayElements() {
uint32_t entries=1; uint32_t entries=1;
for (AstNodeDType* dtypep=this; dtypep; ) { for (AstNodeDType* dtypep=this; dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstArrayDType* adtypep = dtypep->castArrayDType()) { if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
entries *= adtypep->elementsConst(); entries *= adtypep->elementsConst();
dtypep = adtypep->subDTypep(); dtypep = adtypep->subDTypep();
} }
@ -362,8 +362,8 @@ pair<uint32_t,uint32_t> AstNodeDType::dimensions() {
uint32_t unpacked = 0; uint32_t unpacked = 0;
for (AstNodeDType* dtypep=this; dtypep; ) { for (AstNodeDType* dtypep=this; dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstArrayDType* adtypep = dtypep->castArrayDType()) { if (AstNodeArrayDType* adtypep = dtypep->castNodeArrayDType()) {
if (adtypep->isPacked()) packed += 1; if (adtypep->castPackArrayDType()) packed += 1;
else unpacked += 1; else unpacked += 1;
dtypep = adtypep->subDTypep(); dtypep = adtypep->subDTypep();
} }
@ -667,10 +667,6 @@ void AstNode::dump(ostream& str) {
if (name()!="") str<<" "<<AstNode::quoteName(name()); if (name()!="") str<<" "<<AstNode::quoteName(name());
} }
void AstArrayDType::dump(ostream& str) {
this->AstNodeDType::dump(str);
if (isPacked()) str<<" [PACKED]";
}
void AstArraySel::dump(ostream& str) { void AstArraySel::dump(ostream& str) {
this->AstNode::dump(str); this->AstNode::dump(str);
str<<" [start:"<<start()<<"] [length:"<<length()<<"]"; str<<" [start:"<<start()<<"] [length:"<<length()<<"]";

View File

@ -223,62 +223,54 @@ public:
void name(const string& flag) { m_name = flag; } 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]" // Array data type, ie "some_dtype var_name [2:0]"
// Children: DTYPE (moved to refDTypep() in V3Width) // Children: DTYPE (moved to refDTypep() in V3Width)
// Children: RANGE (array bounds) // Children: RANGE (array bounds)
private:
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
bool m_packed;
public: public:
AstArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep, bool isPacked=false) AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep)
: AstNodeDType(fl), m_packed(isPacked) { : AstNodeArrayDType(fl) {
childDTypep(dtp); // Only for parser childDTypep(dtp); // Only for parser
refDTypep(NULL); refDTypep(NULL);
setOp2p(rangep); setOp2p(rangep);
dtypep(NULL); // V3Width will resolve dtypep(NULL); // V3Width will resolve
// For backward compatibility AstNodeArrayDType and others inherit width and signing from the subDType/base type
widthFromSub(subDTypep()); widthFromSub(subDTypep());
} }
AstArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep, bool isPacked=false) AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep)
: AstNodeDType(fl), m_packed(isPacked) { : AstNodeArrayDType(fl) {
refDTypep(dtp); refDTypep(dtp);
setOp2p(rangep); setOp2p(rangep);
dtypep(this); dtypep(this);
// For backward compatibility AstNodeArrayDType and others inherit width and signing from the subDType/base type
widthFromSub(subDTypep()); widthFromSub(subDTypep());
} }
ASTNODE_NODE_FUNCS(ArrayDType, ARRAYDTYPE) ASTNODE_NODE_FUNCS(PackArrayDType, PACKARRAYDTYPE)
virtual void dump(ostream& str); };
virtual bool broken() const { return !((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|| (!m_refDTypep && childDTypep())); } struct AstUnpackArrayDType : public AstNodeArrayDType {
virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) { // Array data type, ie "some_dtype var_name [2:0]"
m_refDTypep = m_refDTypep->clonep()->castNodeDType(); // Children: DTYPE (moved to refDTypep() in V3Width)
}} // Children: RANGE (array bounds)
virtual bool same(AstNode* samep) const { public:
AstArrayDType* sp = samep->castArrayDType(); AstUnpackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep)
return (m_packed==sp->m_packed : AstNodeArrayDType(fl) {
&& msb()==sp->msb() childDTypep(dtp); // Only for parser
&& subDTypep()==sp->subDTypep() refDTypep(NULL);
&& rangep()->sameTree(sp->rangep())); } // HashedDT doesn't recurse, so need to check children setOp2p(rangep);
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(msb()),V3Hash(lsb())); } dtypep(NULL); // V3Width will resolve
AstNodeDType* getChildDTypep() const { return childDTypep(); } // For backward compatibility AstNodeArrayDType and others inherit width and signing from the subDType/base type
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable widthFromSub(subDTypep());
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } }
AstNodeDType* subDTypep() const { return m_refDTypep ? m_refDTypep : childDTypep(); } AstUnpackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep)
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } : AstNodeArrayDType(fl) {
virtual AstNodeDType* virtRefDTypep() const { return m_refDTypep; } refDTypep(dtp);
virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } setOp2p(rangep);
AstRange* rangep() const { return op2p()->castRange(); } // op2 = Array(s) of variable dtypep(this);
void rangep(AstRange* nodep) { setOp2p(nodep); } // For backward compatibility AstNodeArrayDType and others inherit width and signing from the subDType/base type
// METHODS widthFromSub(subDTypep());
virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type }
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } ASTNODE_NODE_FUNCS(UnpackArrayDType, UNPACKARRAYDTYPE)
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; }
}; };
struct AstBasicDType : public AstNodeDType { struct AstBasicDType : public AstNodeDType {
@ -626,9 +618,9 @@ private:
unsigned m_start; unsigned m_start;
unsigned m_length; unsigned m_length;
void init(AstNode* fromp) { void init(AstNode* fromp) {
if (fromp && fromp->dtypep()->castArrayDType()) { if (fromp && fromp->dtypep()->castNodeArrayDType()) {
// Strip off array to find what array references // Strip off array to find what array references
dtypeFrom(fromp->dtypep()->castArrayDType()->subDTypep()); dtypeFrom(fromp->dtypep()->castNodeArrayDType()->subDTypep());
} }
} }
public: public:
@ -2604,7 +2596,7 @@ public:
AstBasicDType* bdtypep = varp->basicp(); AstBasicDType* bdtypep = varp->basicp();
m_left = bdtypep ? bdtypep->left() : 0; m_left = bdtypep ? bdtypep->left() : 0;
m_right = bdtypep ? bdtypep->right() : 0; m_right = bdtypep ? bdtypep->right() : 0;
if (AstArrayDType* adtypep = varp->dtypeSkipRefp()->castArrayDType()) { if (AstNodeArrayDType* adtypep = varp->dtypeSkipRefp()->castNodeArrayDType()) {
m_arrayLsb = adtypep->lsb(); m_arrayLsb = adtypep->lsb();
m_arrayMsb = adtypep->msb(); m_arrayMsb = adtypep->msb();
} else { } else {

View File

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

View File

@ -209,7 +209,7 @@ private:
varp, chgVarp); 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) { for (int index_docs=adtypep->lsb(); index_docs<=adtypep->msb()+1; ++index_docs) {
int index_code = index_docs - adtypep->lsb(); int index_code = index_docs - adtypep->lsb();
ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]", ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]",

View File

@ -321,7 +321,7 @@ public:
{ {
AstVarRef* varrefp = nodep->memp()->castVarRef(); AstVarRef* varrefp = nodep->memp()->castVarRef();
if (!varrefp) { nodep->v3error("Readmem loading non-variable"); } 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())); puts(cvtToStr(varrefp->varp()->dtypep()->arrayElements()));
array_lsb = adtypep->lsb(); array_lsb = adtypep->lsb();
} }
@ -889,8 +889,8 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
} }
puts(nodep->name()); puts(nodep->name());
if (isArray) { if (isArray) {
for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; for (AstNodeArrayDType* arrayp=nodep->dtypeSkipRefp()->castNodeArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) { arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) {
puts("["+cvtToStr(arrayp->elementsConst())+"]"); puts("["+cvtToStr(arrayp->elementsConst())+"]");
} }
} }
@ -910,8 +910,8 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
if (isArray) { if (isArray) {
if (nodep->isWide()) puts("W"); if (nodep->isWide()) puts("W");
puts("("+nodep->name()); puts("("+nodep->name());
for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; for (AstNodeArrayDType* arrayp=nodep->dtypeSkipRefp()->castNodeArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) { arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) {
puts("["+cvtToStr(arrayp->elementsConst())+"]"); puts("["+cvtToStr(arrayp->elementsConst())+"]");
} }
puts(","+cvtToStr(basicp->msb())+","+cvtToStr(basicp->lsb())); 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 // strings and other fundamental c types
puts(nodep->vlArgType(true,false)); puts(nodep->vlArgType(true,false));
// This isn't very robust and may need cleanup for other data types // This isn't very robust and may need cleanup for other data types
for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; for (AstNodeArrayDType* arrayp=nodep->dtypeSkipRefp()->castNodeArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) { arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) {
puts("["+cvtToStr(arrayp->elementsConst())+"]"); puts("["+cvtToStr(arrayp->elementsConst())+"]");
} }
puts(";\n"); puts(";\n");
@ -958,8 +958,8 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
if (prefixIfImp!="") { puts(prefixIfImp); puts("::"); } if (prefixIfImp!="") { puts(prefixIfImp); puts("::"); }
puts(nodep->name()); puts(nodep->name());
// This isn't very robust and may need cleanup for other data types // This isn't very robust and may need cleanup for other data types
for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; for (AstNodeArrayDType* arrayp=nodep->dtypeSkipRefp()->castNodeArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) { arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) {
puts("["+cvtToStr(arrayp->elementsConst())+"]"); puts("["+cvtToStr(arrayp->elementsConst())+"]");
} }
puts(","+cvtToStr(basicp->msb())+","+cvtToStr(basicp->lsb())); puts(","+cvtToStr(basicp->msb())+","+cvtToStr(basicp->lsb()));
@ -1328,7 +1328,7 @@ void EmitCImp::emitVarResets(AstNodeModule* modp) {
} }
else if (AstInitArray* initarp = varp->valuep()->castInitArray()) { else if (AstInitArray* initarp = varp->valuep()->castInitArray()) {
AstConst* constsp = initarp->initsp()->castConst(); 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++) { for (int i=0; i<arrayp->elementsConst(); i++) {
if (!constsp) initarp->v3fatalSrc("Not enough values in array initalizement"); if (!constsp) initarp->v3fatalSrc("Not enough values in array initalizement");
emitSetVarConstant(varp->name()+"["+cvtToStr(i)+"]", constsp); emitSetVarConstant(varp->name()+"["+cvtToStr(i)+"]", constsp);
@ -1341,8 +1341,8 @@ void EmitCImp::emitVarResets(AstNodeModule* modp) {
else { else {
int vects = 0; int vects = 0;
// This isn't very robust and may need cleanup for other data types // This isn't very robust and may need cleanup for other data types
for (AstArrayDType* arrayp=varp->dtypeSkipRefp()->castArrayDType(); arrayp; for (AstNodeArrayDType* arrayp=varp->dtypeSkipRefp()->castNodeArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) { arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) {
int vecnum = vects++; int vecnum = vects++;
if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier."); if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
string ivar = string("__Vi")+cvtToStr(vecnum); string ivar = string("__Vi")+cvtToStr(vecnum);
@ -1508,8 +1508,8 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
else { else {
int vects = 0; int vects = 0;
// This isn't very robust and may need cleanup for other data types // This isn't very robust and may need cleanup for other data types
for (AstArrayDType* arrayp=varp->dtypeSkipRefp()->castArrayDType(); arrayp; for (AstNodeArrayDType* arrayp=varp->dtypeSkipRefp()->castNodeArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) { arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) {
int vecnum = vects++; int vecnum = vects++;
if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier."); if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
string ivar = string("__Vi")+cvtToStr(vecnum); string ivar = string("__Vi")+cvtToStr(vecnum);
@ -1599,8 +1599,8 @@ void EmitCImp::emitSensitives() {
if (varp->isInput() && (varp->isScSensitive() || varp->isUsedClock())) { if (varp->isInput() && (varp->isScSensitive() || varp->isUsedClock())) {
int vects = 0; int vects = 0;
// This isn't very robust and may need cleanup for other data types // This isn't very robust and may need cleanup for other data types
for (AstArrayDType* arrayp=varp->dtypeSkipRefp()->castArrayDType(); arrayp; for (AstNodeArrayDType* arrayp=varp->dtypeSkipRefp()->castNodeArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) { arrayp = arrayp->subDTypep()->skipRefp()->castNodeArrayDType()) {
int vecnum = vects++; int vecnum = vects++;
if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier."); if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
string ivar = string("__Vi")+cvtToStr(vecnum); 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 sigbytes = varp->dtypeSkipRefp()->widthAlignBytes();
int sortbytes = sortmax-1; int sortbytes = sortmax-1;
if (varp->isUsedClock() && varp->widthMin()==1) sortbytes = 0; 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->basicp() && varp->basicp()->isOpaque()) sortbytes=7;
else if (varp->isScBv()) sortbytes=6; else if (varp->isScBv()) sortbytes=6;
else if (sigbytes==8) sortbytes=5; else if (sigbytes==8) sortbytes=5;
@ -2234,7 +2234,7 @@ class EmitCTrace : EmitCStmts {
if (emitTraceIsScBv(nodep)) puts("VL_SC_BV_DATAP("); if (emitTraceIsScBv(nodep)) puts("VL_SC_BV_DATAP(");
varrefp->iterate(*this); // Put var name out varrefp->iterate(*this); // Put var name out
// Tracing only supports 1D arrays // Tracing only supports 1D arrays
if (varp->dtypeSkipRefp()->castArrayDType()) { if (varp->dtypeSkipRefp()->castNodeArrayDType()) {
if (arrayindex==-2) puts("[i]"); if (arrayindex==-2) puts("[i]");
else if (arrayindex==-1) puts("[0]"); else if (arrayindex==-1) puts("[0]");
else puts("["+cvtToStr(arrayindex)+"]"); else puts("["+cvtToStr(arrayindex)+"]");

View File

@ -465,7 +465,7 @@ void EmitCSyms::emitSymImp() {
} }
for (AstNodeDType* dtypep=varp->dtypep(); dtypep; ) { for (AstNodeDType* dtypep=varp->dtypep(); dtypep; ) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node 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->msb());
bounds += ","; bounds += cvtToStr(adtypep->lsb()); bounds += ","; bounds += cvtToStr(adtypep->lsb());
dim++; dim++;

View File

@ -497,7 +497,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
putfs(nodep,"const "); putfs(nodep,"const ");
nodep->subDTypep()->iterateAndNext(*this); nodep->subDTypep()->iterateAndNext(*this);
} }
virtual void visit(AstArrayDType* nodep, AstNUser*) { virtual void visit(AstNodeArrayDType* nodep, AstNUser*) {
nodep->subDTypep()->iterateAndNext(*this); nodep->subDTypep()->iterateAndNext(*this);
nodep->rangep()->iterateAndNext(*this); nodep->rangep()->iterateAndNext(*this);
} }

View File

@ -253,7 +253,7 @@ class SliceVisitor : public AstNVisitor {
AstNode* topp = nodep; AstNode* topp = nodep;
for (unsigned i = start; i < start + count; ++i) { for (unsigned i = start; i < start + count; ++i) {
AstNodeDType* dtypep = varp->dtypep()->dtypeDimensionp(i-1); 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"); if (!adtypep) nodep->v3fatalSrc("insertImplicit tried to expand an array without an ArrayDType");
vlsint32_t msb = adtypep->msb(); vlsint32_t msb = adtypep->msb();
vlsint32_t lsb = adtypep->lsb(); vlsint32_t lsb = adtypep->lsb();

View File

@ -93,7 +93,7 @@ private:
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
if (m_counting && nodep->dtypep()) { if (m_counting && nodep->dtypep()) {
if (nodep->isUsedClock()) ++m_statVarClock; if (nodep->isUsedClock()) ++m_statVarClock;
if (nodep->dtypeSkipRefp()->castArrayDType()) ++m_statVarArray; if (nodep->dtypeSkipRefp()->castPackArrayDType()) ++m_statVarArray;
else m_statVarBytes += nodep->dtypeSkipRefp()->widthTotalBytes(); else m_statVarBytes += nodep->dtypeSkipRefp()->widthTotalBytes();
if (int(m_statVarWidths.size()) <= nodep->width()) { if (int(m_statVarWidths.size()) <= nodep->width()) {
m_statVarWidths.resize(nodep->width()+5); 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, TOTAL", m_statInstr);
V3Stats::addStat(m_stage, "Instruction count, fast", m_statInstrFast); V3Stats::addStat(m_stage, "Instruction count, fast", m_statInstrFast);
// Vars // 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, "Vars, clock attribute", m_statVarClock);
V3Stats::addStat(m_stage, "Var space, non-arrays, bytes", m_statVarBytes); V3Stats::addStat(m_stage, "Var space, non-arrays, bytes", m_statVarBytes);
if (m_statVarScpBytes) { if (m_statVarScpBytes) {

View File

@ -189,10 +189,10 @@ private:
// Change it variable // Change it variable
FileLine* fl = nodep->fileline(); FileLine* fl = nodep->fileline();
AstNodeDType* dtypep AstNodeDType* dtypep
= new AstArrayDType (fl, = new AstUnpackArrayDType (fl,
nodep->findBitDType(m_outVarps.size(), nodep->findBitDType(m_outVarps.size(),
m_outVarps.size(), AstNumeric::UNSIGNED), m_outVarps.size(), AstNumeric::UNSIGNED),
new AstRange (fl, VL_MASK_I(m_inWidth), 0), false); new AstRange (fl, VL_MASK_I(m_inWidth), 0));
v3Global.rootp()->typeTablep()->addTypesp(dtypep); v3Global.rootp()->typeTablep()->addTypesp(dtypep);
AstVar* chgVarp AstVar* chgVarp
= new AstVar (fl, AstVarType::MODULETEMP, = new AstVar (fl, AstVarType::MODULETEMP,
@ -237,8 +237,8 @@ private:
AstVar* outvarp = outvscp->varp(); AstVar* outvarp = outvscp->varp();
FileLine* fl = nodep->fileline(); FileLine* fl = nodep->fileline();
AstNodeDType* dtypep AstNodeDType* dtypep
= new AstArrayDType (fl, outvarp->dtypep(), = new AstUnpackArrayDType (fl, outvarp->dtypep(),
new AstRange (fl, VL_MASK_I(m_inWidth), 0), false); new AstRange (fl, VL_MASK_I(m_inWidth), 0));
v3Global.rootp()->typeTablep()->addTypesp(dtypep); v3Global.rootp()->typeTablep()->addTypesp(dtypep);
AstVar* tablevarp AstVar* tablevarp
= new AstVar (fl, AstVarType::MODULETEMP, = 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->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 ((int)nodep->dtypep()->arrayElements() > v3Global.opt.traceMaxArray()) return "Wide memory > --trace-max-array ents";
if (!(nodep->dtypeSkipRefp()->castBasicDType() if (!(nodep->dtypeSkipRefp()->castBasicDType()
|| (nodep->dtypeSkipRefp()->castArrayDType() || (nodep->dtypeSkipRefp()->castNodeArrayDType()
&& (nodep->dtypeSkipRefp()->castArrayDType()->subDTypep() && (nodep->dtypeSkipRefp()->castNodeArrayDType()->subDTypep()
->skipRefp()->castBasicDType())))) { ->skipRefp()->castBasicDType())))) {
return "Unsupported: Multi-dimensional array"; return "Unsupported: Multi-dimensional array";
} }

View File

@ -379,7 +379,7 @@ private:
int maxmsb = 0; int maxmsb = 0;
bool lvalue = false; bool lvalue = false;
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { 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"); if (!adtypep) nodep->v3fatalSrc("ArraySel to type without array at same depth");
lvalue = varrefp->lvalue(); lvalue = varrefp->lvalue();
maxmsb = adtypep->elementsConst()-1; maxmsb = adtypep->elementsConst()-1;

View File

@ -374,7 +374,7 @@ private:
// So, see if we're sitting under a variable's arrayp. // So, see if we're sitting under a variable's arrayp.
AstNode* huntbackp = nodep; AstNode* huntbackp = nodep;
while (huntbackp->backp()->castRange()) huntbackp=huntbackp->backp(); while (huntbackp->backp()->castRange()) huntbackp=huntbackp->backp();
if (huntbackp->backp()->castArrayDType()) { if (huntbackp->backp()->castNodeArrayDType()) {
} else { } else {
// Little endian bits are legal, just remember to swap // Little endian bits are legal, just remember to swap
// Warning is in V3Width to avoid false warnings when in "off" generate if's // Warning is in V3Width to avoid false warnings when in "off" generate if's
@ -512,7 +512,7 @@ private:
int frommsb; int frommsb;
int fromlsb; int fromlsb;
AstNodeDType* ddtypep = varrp->varp()->dtypep()->dtypeDimensionp(dimension); AstNodeDType* ddtypep = varrp->varp()->dtypep()->dtypeDimensionp(dimension);
if (AstArrayDType* adtypep = ddtypep->castArrayDType()) { if (AstNodeArrayDType* adtypep = ddtypep->castNodeArrayDType()) {
frommsb = adtypep->msb(); frommsb = adtypep->msb();
fromlsb = adtypep->lsb(); fromlsb = adtypep->lsb();
if (fromlsb>frommsb) {int t=frommsb; frommsb=fromlsb; fromlsb=t; } if (fromlsb>frommsb) {int t=frommsb; frommsb=fromlsb; fromlsb=t; }
@ -676,7 +676,7 @@ private:
} }
// DTYPES // 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->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed
if (nodep->childDTypep()) nodep->refDTypep(moveChildDTypeEdit(nodep)); if (nodep->childDTypep()) nodep->refDTypep(moveChildDTypeEdit(nodep));
// Iterate into subDTypep() to resolve that type and update pointer. // Iterate into subDTypep() to resolve that type and update pointer.
@ -793,7 +793,7 @@ private:
nodep->dtypep(iterateEditDTypep(nodep, nodep->dtypep())); nodep->dtypep(iterateEditDTypep(nodep, nodep->dtypep()));
if (!nodep->dtypep()) nodep->v3fatalSrc("No dtype determined for var"); if (!nodep->dtypep()) nodep->v3fatalSrc("No dtype determined for var");
if (nodep->isIO() && !(nodep->dtypeSkipRefp()->castBasicDType() if (nodep->isIO() && !(nodep->dtypeSkipRefp()->castBasicDType()
|| nodep->dtypeSkipRefp()->castArrayDType() || nodep->dtypeSkipRefp()->castNodeArrayDType()
|| nodep->dtypeSkipRefp()->castNodeClassDType())) { || nodep->dtypeSkipRefp()->castNodeClassDType())) {
nodep->v3error("Unsupported: Inputs and outputs must be simple data types"); nodep->v3error("Unsupported: Inputs and outputs must be simple data types");
} }
@ -1366,7 +1366,7 @@ private:
virtual void visit(AstReadMem* nodep, AstNUser*) { virtual void visit(AstReadMem* nodep, AstNUser*) {
nodep->filenamep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->filenamep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
nodep->memp()->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->memp()->v3error("Unsupported: $readmem into non-array");
} }
nodep->lsbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->lsbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());

View File

@ -78,7 +78,7 @@ private:
AstNodeDType* ddtypep = bfdtypep; AstNodeDType* ddtypep = bfdtypep;
ddtypep = ddtypep->dtypeDimensionp(dimension); ddtypep = ddtypep->dtypeDimensionp(dimension);
if (debug()>=9 &&ddtypep) ddtypep->dumpTree(cout,"-ddtypep: "); if (debug()>=9 &&ddtypep) ddtypep->dumpTree(cout,"-ddtypep: ");
if (AstArrayDType* adtypep = ddtypep->castArrayDType()) { if (AstNodeArrayDType* adtypep = ddtypep->castNodeArrayDType()) {
return adtypep; return adtypep;
} }
else if (AstNodeClassDType* adtypep = ddtypep->castNodeClassDType()) { else if (AstNodeClassDType* adtypep = ddtypep->castNodeClassDType()) {
@ -195,7 +195,7 @@ private:
AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); // bit we're extracting AstNode* rhsp = nodep->rhsp()->unlinkFrBack(); // bit we're extracting
if (debug()>=9) ddtypep->dumpTree(cout,"-ddtypep: "); if (debug()>=9) ddtypep->dumpTree(cout,"-ddtypep: ");
if (debug()>=9) nodep->dumpTree(cout,"-vsbmd: "); if (debug()>=9) nodep->dumpTree(cout,"-vsbmd: ");
if (AstArrayDType* adtypep = ddtypep->castArrayDType()) { if (AstNodeArrayDType* adtypep = ddtypep->castNodeArrayDType()) {
// SELBIT(array, index) -> ARRAYSEL(array, index) // SELBIT(array, index) -> ARRAYSEL(array, index)
AstNode* subp = rhsp; AstNode* subp = rhsp;
if (adtypep->lsb()!=0 || adtypep->msb()<0) { if (adtypep->lsb()!=0 || adtypep->msb()<0) {
@ -258,7 +258,7 @@ private:
vlsint32_t msb = msbp->castConst()->toSInt(); vlsint32_t msb = msbp->castConst()->toSInt();
vlsint32_t lsb = lsbp->castConst()->toSInt(); vlsint32_t lsb = lsbp->castConst()->toSInt();
AstNodeDType* ddtypep = dtypeForExtractp(nodep, basefromp, dimension, msb!=lsb); AstNodeDType* ddtypep = dtypeForExtractp(nodep, basefromp, dimension, msb!=lsb);
if (AstArrayDType* adtypep = ddtypep->castArrayDType()) { if (AstNodeArrayDType* adtypep = ddtypep->castNodeArrayDType()) {
if (adtypep) {} if (adtypep) {}
// Slice extraction // Slice extraction
AstArraySel* newp = new AstArraySel (nodep->fileline(), fromp, lsbp); AstArraySel* newp = new AstArraySel (nodep->fileline(), fromp, lsbp);

View File

@ -3433,7 +3433,11 @@ AstNodeDType* V3ParseGrammar::createArray(AstNodeDType* basep, AstRange* rangep,
while (rangep) { while (rangep) {
AstRange* prevp = rangep->backp()->castRange(); AstRange* prevp = rangep->backp()->castRange();
if (prevp) rangep->unlinkFrBack(); 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; rangep = prevp;
} }
} }