forked from github/verilator
Internals: Split into packed and unpacked array types
This commit is contained in:
parent
ae1ab8aaaa
commit
5c7a6e278f
48
src/V3Ast.h
48
src/V3Ast.h
@ -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
|
||||
|
@ -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()<<"]";
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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)+"]",
|
||||
|
@ -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)+"]");
|
||||
|
@ -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++;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user