mirror of
https://github.com/verilator/verilator.git
synced 2025-01-24 15:24:04 +00:00
Internals: Add dtype to InitArray; misc Slice cleanups. From bug355 branch.
This commit is contained in:
parent
17b8b660f0
commit
6e3e8318d0
@ -2758,15 +2758,20 @@ struct AstInsideRange : public AstNodeMath {
|
||||
struct AstInitArray : public AstNode {
|
||||
// Set a var to a large list of values
|
||||
// The values must be in sorted order, and not exceed the size of the var's array.
|
||||
// The first value on the initsp() list is for the lo() index of the array.
|
||||
// Parents: ASTVAR::init()
|
||||
// Children: CONSTs...
|
||||
AstInitArray(FileLine* fl, AstNode* initsp)
|
||||
AstInitArray(FileLine* fl, AstNodeArrayDType* newDTypep, AstNode* initsp)
|
||||
: AstNode(fl) {
|
||||
dtypep(newDTypep);
|
||||
addNOp1p(initsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(InitArray, INITARRAY)
|
||||
AstNode* initsp() const { return op1p()->castNode(); } // op1 = Initial value expressions
|
||||
void addInitsp(AstNode* newp) { addOp1p(newp); }
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return true; }
|
||||
};
|
||||
|
||||
struct AstPragma : public AstNode {
|
||||
|
@ -446,6 +446,14 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
||||
}
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstInitArray* nodep, AstNUser*) {
|
||||
putfs(nodep,"`{");
|
||||
for (AstNode* subp = nodep->initsp(); subp; subp=subp->nextp()) {
|
||||
subp->accept(*this);
|
||||
if (subp->nextp()) putbs(",");
|
||||
}
|
||||
puts("}");
|
||||
}
|
||||
virtual void visit(AstNodeCond* nodep, AstNUser*) {
|
||||
putbs("(");
|
||||
nodep->condp()->iterateAndNext(*this); putfs(nodep," ? ");
|
||||
|
@ -70,7 +70,7 @@ class SliceCloneVisitor : public AstNVisitor {
|
||||
// VISITORS
|
||||
virtual void visit(AstArraySel* nodep, AstNUser*) {
|
||||
if (!nodep->backp()->castArraySel()) {
|
||||
// This is the top of an ArraySel, setup
|
||||
// This is the top of an ArraySel, setup for iteration
|
||||
m_refp = nodep->user1p()->castNode()->castVarRef();
|
||||
m_vecIdx += 1;
|
||||
if (m_vecIdx == (int)m_selBits.size()) {
|
||||
@ -78,6 +78,7 @@ class SliceCloneVisitor : public AstNVisitor {
|
||||
AstVar* varp = m_refp->varp();
|
||||
pair<uint32_t,uint32_t> arrDim = varp->dtypep()->dimensions(false);
|
||||
uint32_t dimensions = arrDim.second;
|
||||
// for 3-dimensions we want m_selBits[m_vecIdx]=[0,0,0]
|
||||
for (uint32_t i = 0; i < dimensions; ++i) {
|
||||
m_selBits[m_vecIdx].push_back(0);
|
||||
}
|
||||
@ -165,19 +166,15 @@ class SliceCloneVisitor : public AstNVisitor {
|
||||
nodep->addNextHere(lhsp);
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep = NULL;
|
||||
}
|
||||
|
||||
virtual void visit(AstRedOr* nodep, AstNUser*) {
|
||||
cloneUniop(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstRedAnd* nodep, AstNUser*) {
|
||||
cloneUniop(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstRedXor* nodep, AstNUser*) {
|
||||
cloneUniop(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstRedXnor* nodep, AstNUser*) {
|
||||
cloneUniop(nodep);
|
||||
}
|
||||
@ -188,8 +185,8 @@ class SliceCloneVisitor : public AstNVisitor {
|
||||
}
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
SliceCloneVisitor(AstNode* assignp) {
|
||||
assignp->accept(*this);
|
||||
SliceCloneVisitor(AstNode* nodep) {
|
||||
nodep->accept(*this);
|
||||
}
|
||||
virtual ~SliceCloneVisitor() {}
|
||||
};
|
||||
@ -223,8 +220,8 @@ class SliceVisitor : public AstNVisitor {
|
||||
return level;
|
||||
}
|
||||
|
||||
// Find out how many explicit dimensions are in a given ArraySel.
|
||||
unsigned explicitDimensions(AstArraySel* nodep) {
|
||||
// Find out how many explicit dimensions are in a given ArraySel.
|
||||
unsigned dim = 0;
|
||||
AstNode* fromp = nodep;
|
||||
AstArraySel* selp;
|
||||
@ -243,10 +240,23 @@ class SliceVisitor : public AstNVisitor {
|
||||
return dim;
|
||||
}
|
||||
|
||||
int countClones(AstArraySel* nodep) {
|
||||
// Count how many clones we need to make from this ArraySel
|
||||
int clones = 1;
|
||||
AstNode* fromp = nodep;
|
||||
AstArraySel* selp;
|
||||
do {
|
||||
selp = fromp->castArraySel();
|
||||
fromp = (selp) ? selp->fromp() : NULL;
|
||||
if (fromp && selp) clones *= selp->length();
|
||||
} while (fromp && selp);
|
||||
return clones;
|
||||
}
|
||||
|
||||
AstArraySel* insertImplicit(AstNode* nodep, unsigned start, unsigned count) {
|
||||
// Insert any implicit slices as explicit slices (ArraySel nodes).
|
||||
// Return a new pointer to replace nodep() in the ArraySel.
|
||||
UINFO(9," insertImplicit "<<nodep<<endl);
|
||||
UINFO(9," insertImplicit (start="<<start<<",c="<<count<<") "<<nodep<<endl);
|
||||
AstVarRef* refp = nodep->user1p()->castNode()->castVarRef();
|
||||
if (!refp) nodep->v3fatalSrc("No VarRef in user1 of node "<<nodep);
|
||||
AstVar* varp = refp->varp();
|
||||
@ -269,28 +279,15 @@ class SliceVisitor : public AstNVisitor {
|
||||
newp->user1p(refp);
|
||||
newp->start(lsb);
|
||||
newp->length(msb - lsb + 1);
|
||||
topp = newp->castNode();
|
||||
topp = newp;
|
||||
}
|
||||
return topp->castArraySel();
|
||||
}
|
||||
|
||||
int countClones(AstArraySel* nodep) {
|
||||
// Count how many clones we need to make from this ArraySel
|
||||
int clones = 1;
|
||||
AstNode* fromp = nodep;
|
||||
AstArraySel* selp;
|
||||
do {
|
||||
selp = fromp->castArraySel();
|
||||
fromp = (selp) ? selp->fromp() : NULL;
|
||||
if (fromp && selp) clones *= selp->length();
|
||||
} while (fromp && selp);
|
||||
return clones;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
// The LHS/RHS of an Assign may be to a Var that is an array. In this
|
||||
// case we need to create a slice accross the entire Var
|
||||
// case we need to create a slice across the entire Var
|
||||
if (m_assignp && !nodep->backp()->castArraySel()) {
|
||||
pair<uint32_t,uint32_t> arrDim = nodep->varp()->dtypep()->dimensions(false);
|
||||
uint32_t dimensions = arrDim.second; // unpacked only
|
||||
@ -382,8 +379,8 @@ class SliceVisitor : public AstNVisitor {
|
||||
refp = findVarRefRecurse(nodep->op3p());
|
||||
if (refp) return refp;
|
||||
}
|
||||
if (nodep->op3p()) {
|
||||
refp = findVarRefRecurse(nodep->op3p());
|
||||
if (nodep->op4p()) {
|
||||
refp = findVarRefRecurse(nodep->op4p());
|
||||
if (refp) return refp;
|
||||
}
|
||||
if (nodep->nextp()) {
|
||||
@ -424,7 +421,7 @@ class SliceVisitor : public AstNVisitor {
|
||||
dim = explicitDimensions(selp);
|
||||
}
|
||||
if (dim == 0 && !nodep->lhsp()->castVarRef()) {
|
||||
// No ArraySel or VarRef, not something we can expand
|
||||
// No ArraySel nor VarRef, not something we can expand
|
||||
nodep->iterateChildren(*this);
|
||||
} else {
|
||||
AstVarRef* refp = findVarRefRecurse(nodep->lhsp());
|
||||
@ -445,25 +442,21 @@ class SliceVisitor : public AstNVisitor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstRedOr* nodep, AstNUser*) {
|
||||
if (!nodep->user1()) {
|
||||
expandUniOp(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstRedAnd* nodep, AstNUser*) {
|
||||
if (!nodep->user1()) {
|
||||
expandUniOp(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstRedXor* nodep, AstNUser*) {
|
||||
if (!nodep->user1()) {
|
||||
expandUniOp(nodep);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstRedXnor* nodep, AstNUser*) {
|
||||
if (!nodep->user1()) {
|
||||
expandUniOp(nodep);
|
||||
|
@ -188,7 +188,7 @@ private:
|
||||
|
||||
// Change it variable
|
||||
FileLine* fl = nodep->fileline();
|
||||
AstNodeDType* dtypep
|
||||
AstNodeArrayDType* dtypep
|
||||
= new AstUnpackArrayDType (fl,
|
||||
nodep->findBitDType(m_outVarps.size(),
|
||||
m_outVarps.size(), AstNumeric::UNSIGNED),
|
||||
@ -199,7 +199,7 @@ private:
|
||||
"__Vtablechg" + cvtToStr(m_modTables),
|
||||
dtypep);
|
||||
chgVarp->isConst(true);
|
||||
chgVarp->valuep(new AstInitArray (nodep->fileline(), NULL));
|
||||
chgVarp->valuep(new AstInitArray (nodep->fileline(), dtypep, NULL));
|
||||
m_modp->addStmtp(chgVarp);
|
||||
AstVarScope* chgVscp = new AstVarScope (chgVarp->fileline(), m_scopep, chgVarp);
|
||||
m_scopep->addVarp(chgVscp);
|
||||
@ -236,7 +236,7 @@ private:
|
||||
AstVarScope* outvscp = *it;
|
||||
AstVar* outvarp = outvscp->varp();
|
||||
FileLine* fl = nodep->fileline();
|
||||
AstNodeDType* dtypep
|
||||
AstNodeArrayDType* dtypep
|
||||
= new AstUnpackArrayDType (fl, outvarp->dtypep(),
|
||||
new AstRange (fl, VL_MASK_I(m_inWidth), 0));
|
||||
v3Global.rootp()->typeTablep()->addTypesp(dtypep);
|
||||
@ -246,7 +246,7 @@ private:
|
||||
dtypep);
|
||||
tablevarp->isConst(true);
|
||||
tablevarp->isStatic(true);
|
||||
tablevarp->valuep(new AstInitArray (nodep->fileline(), NULL));
|
||||
tablevarp->valuep(new AstInitArray (nodep->fileline(), dtypep, NULL));
|
||||
m_modp->addStmtp(tablevarp);
|
||||
AstVarScope* tablevscp = new AstVarScope(tablevarp->fileline(), m_scopep, tablevarp);
|
||||
m_scopep->addVarp(tablevscp);
|
||||
|
@ -2600,10 +2600,10 @@ private:
|
||||
pair<uint32_t,uint32_t> dim = nodep->skipRefp()->dimensions(true);
|
||||
uint32_t maxdim = dim.first+dim.second;
|
||||
//
|
||||
AstInitArray* initp = new AstInitArray (nodep->fileline(), NULL);
|
||||
AstNodeDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(),
|
||||
nodep->findSigned32DType(),
|
||||
new AstRange(nodep->fileline(), maxdim, 0));
|
||||
AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(),
|
||||
nodep->findSigned32DType(),
|
||||
new AstRange(nodep->fileline(), maxdim, 0));
|
||||
AstInitArray* initp = new AstInitArray (nodep->fileline(), vardtypep, NULL);
|
||||
v3Global.rootp()->typeTablep()->addTypesp(vardtypep);
|
||||
AstVar* varp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP,
|
||||
"__Vdimtable" + cvtToStr(m_dtTables++),
|
||||
|
Loading…
Reference in New Issue
Block a user