mirror of
https://github.com/verilator/verilator.git
synced 2025-05-03 22:16:53 +00:00
Internals: Prep work for simulation of array parameters, bug1315. No functional change intended.
This commit is contained in:
parent
c5f859c9a3
commit
704f40b1a2
@ -1207,11 +1207,11 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
AstNode() {init(); }
|
AstNode() { init(); }
|
||||||
explicit AstNode(FileLine* fileline) {init(); m_fileline = fileline; }
|
explicit AstNode(FileLine* fileline) {init(); m_fileline = fileline; }
|
||||||
virtual AstNode* clone() = 0; // Generally, cloneTree is what you want instead
|
virtual AstNode* clone() = 0; // Generally, cloneTree is what you want instead
|
||||||
virtual void cloneRelink() {}
|
virtual void cloneRelink() {}
|
||||||
void cloneRelinkTree();
|
void cloneRelinkTree();
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
void setOp1p(AstNode* newp); // Set non-list-type op1 to non-list element
|
void setOp1p(AstNode* newp); // Set non-list-type op1 to non-list element
|
||||||
@ -1467,9 +1467,10 @@ public:
|
|||||||
virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // When calling, "this" is second argument
|
virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // When calling, "this" is second argument
|
||||||
|
|
||||||
// METHODS - Iterate on a tree
|
// METHODS - Iterate on a tree
|
||||||
static AstNode* cloneTreeNull(AstNode* nodep, bool cloneNextLink) { // Clone or return NULL if NULL
|
// Clone or return NULL if NULL
|
||||||
|
static AstNode* cloneTreeNull(AstNode* nodep, bool cloneNextLink) {
|
||||||
return nodep ? nodep->cloneTree(cloneNextLink) : NULL; }
|
return nodep ? nodep->cloneTree(cloneNextLink) : NULL; }
|
||||||
AstNode* cloneTree(bool cloneNextLink);
|
AstNode* cloneTree(bool cloneNextLink); // Not const, as sets clonep() on original nodep
|
||||||
bool gateTree() { return gateTreeIter(); } // Is tree isGateOptimizable?
|
bool gateTree() { return gateTreeIter(); } // Is tree isGateOptimizable?
|
||||||
bool sameTree(const AstNode* node2p) const; // Does tree of this == node2p?
|
bool sameTree(const AstNode* node2p) const; // Does tree of this == node2p?
|
||||||
bool sameGateTree(const AstNode* node2p) const; // Does tree of this == node2p?, not allowing non-isGateOptimizable
|
bool sameGateTree(const AstNode* node2p) const; // Does tree of this == node2p?, not allowing non-isGateOptimizable
|
||||||
|
@ -233,9 +233,9 @@ private:
|
|||||||
return constp;
|
return constp;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
AstConst* newValue(AstNode* nodep) {
|
AstConst* newConst(AstNode* nodep) {
|
||||||
// Set a constant value for this node
|
// Set a constant value for this node
|
||||||
if (!nodep->user3p()) {
|
if (!VN_IS(nodep->user3p(), Const)) {
|
||||||
AstConst* constp = allocConst(nodep);
|
AstConst* constp = allocConst(nodep);
|
||||||
setValue(nodep, constp);
|
setValue(nodep, constp);
|
||||||
return constp;
|
return constp;
|
||||||
@ -243,9 +243,9 @@ private:
|
|||||||
return fetchConst(nodep);
|
return fetchConst(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AstConst* newOutValue(AstNode* nodep) {
|
AstConst* newOutConst(AstNode* nodep) {
|
||||||
// Set a constant value for this node
|
// Set a constant value for this node
|
||||||
if (!nodep->user2p()) {
|
if (!VN_IS(nodep->user2p(), Const)) {
|
||||||
AstConst* constp = allocConst(nodep);
|
AstConst* constp = allocConst(nodep);
|
||||||
setOutValue(nodep, constp);
|
setOutValue(nodep, constp);
|
||||||
return constp;
|
return constp;
|
||||||
@ -253,14 +253,20 @@ private:
|
|||||||
return fetchOutConst(nodep);
|
return fetchOutConst(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void newOutValue(AstNode* nodep, const AstConst* constr) {
|
void newOutConst(AstNode* nodep, const AstConst* constr) {
|
||||||
newOutValue(nodep)->num().opAssign(constr->num());
|
newOutConst(nodep)->num().opAssign(constr->num());
|
||||||
|
}
|
||||||
|
AstNode* fetchValueNull(AstNode* nodep) {
|
||||||
|
return (AstNode*)(nodep->user3p());
|
||||||
|
}
|
||||||
|
AstNode* fetchOutValueNull(AstNode* nodep) {
|
||||||
|
return (AstNode*)(nodep->user2p());
|
||||||
}
|
}
|
||||||
AstConst* fetchConstNull(AstNode* nodep) {
|
AstConst* fetchConstNull(AstNode* nodep) {
|
||||||
return ((AstConst*)nodep->user3p());
|
return VN_CAST(fetchValueNull(nodep), Const);
|
||||||
}
|
}
|
||||||
AstConst* fetchOutConstNull(AstNode* nodep) {
|
AstConst* fetchOutConstNull(AstNode* nodep) {
|
||||||
return ((AstConst*)nodep->user2p());
|
return VN_CAST(fetchOutValueNull(nodep), Const);
|
||||||
}
|
}
|
||||||
AstConst* fetchConst(AstNode* nodep) {
|
AstConst* fetchConst(AstNode* nodep) {
|
||||||
AstConst* constp = fetchConstNull(nodep);
|
AstConst* constp = fetchConstNull(nodep);
|
||||||
@ -275,30 +281,29 @@ private:
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
void newValue(AstNode* nodep, const AstConst* constp) {
|
void newValue(AstNode* nodep, const AstConst* constp) {
|
||||||
newValue(nodep)->num().opAssign(constp->num());
|
newConst(nodep, constp);
|
||||||
|
}
|
||||||
|
void newConst(AstNode* nodep, const AstConst* constp) {
|
||||||
|
newConst(nodep)->num().opAssign(constp->num());
|
||||||
}
|
}
|
||||||
V3Number* fetchNumberNull(AstNode* nodep) {
|
V3Number* fetchNumberNull(AstNode* nodep) {
|
||||||
AstConst* constp = fetchConstNull(nodep);
|
AstConst* constp = fetchConstNull(nodep);
|
||||||
if (constp) {
|
if (constp) return &constp->num();
|
||||||
return &constp->num();
|
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
V3Number* fetchOutNumberNull(AstNode* nodep) {
|
V3Number* fetchOutNumberNull(AstNode* nodep) {
|
||||||
AstConst* constp = fetchOutConstNull(nodep);
|
AstConst* constp = fetchOutConstNull(nodep);
|
||||||
if (constp) {
|
if (constp) return &constp->num();
|
||||||
return &constp->num();
|
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void setValue(AstNode* nodep, const AstConst* constp) {
|
void setValue(AstNode* nodep, const AstNode* valuep) {
|
||||||
UINFO(9, " set num "<<constp->name()<<" on "<<nodep<<endl);
|
UINFO(9, " set val "<<valuep->name()<<" on "<<nodep<<endl);
|
||||||
nodep->user3p((void*)constp);
|
nodep->user3p((void*)valuep);
|
||||||
}
|
}
|
||||||
void setOutValue(AstNode* nodep, const AstConst* constp) {
|
void setOutValue(AstNode* nodep, const AstNode* valuep) {
|
||||||
UINFO(9, " set onum "<<constp->name()<<" on "<<nodep<<endl);
|
UINFO(9, " set oval "<<valuep->name()<<" on "<<nodep<<endl);
|
||||||
nodep->user2p((void*)constp);
|
nodep->user2p((void*)valuep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkNodeInfo(AstNode* nodep) {
|
void checkNodeInfo(AstNode* nodep) {
|
||||||
@ -339,13 +344,13 @@ private:
|
|||||||
// True to jump over this node - all visitors must call this up front
|
// True to jump over this node - all visitors must call this up front
|
||||||
return (m_jumpp && m_jumpp->labelp() != nodep);
|
return (m_jumpp && m_jumpp->labelp() != nodep);
|
||||||
}
|
}
|
||||||
void assignOutValue(AstNodeAssign* nodep, AstNode* vscp, const AstConst* valuep) {
|
void assignOutConst(AstNodeAssign* nodep, AstNode* vscp, const AstConst* valuep) {
|
||||||
if (VN_IS(nodep, AssignDly)) {
|
if (VN_IS(nodep, AssignDly)) {
|
||||||
// Don't do setValue, as value isn't yet visible to following statements
|
// Don't do setValue, as value isn't yet visible to following statements
|
||||||
newOutValue(vscp, valuep);
|
newOutConst(vscp, valuep);
|
||||||
} else {
|
} else {
|
||||||
newValue(vscp, valuep);
|
newConst(vscp, valuep);
|
||||||
newOutValue(vscp, valuep);
|
newOutConst(vscp, valuep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +402,7 @@ private:
|
|||||||
AstConst* constp = isConst ? fetchConstNull(nodep->varp()->valuep()) : NULL;
|
AstConst* constp = isConst ? fetchConstNull(nodep->varp()->valuep()) : NULL;
|
||||||
if (isConst && constp) { // Propagate PARAM constants for constant function analysis
|
if (isConst && constp) { // Propagate PARAM constants for constant function analysis
|
||||||
if (!m_checkOnly && optimizable()) {
|
if (!m_checkOnly && optimizable()) {
|
||||||
newValue(vscp, constp);
|
newConst(vscp, constp);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_checkOnly) varRefCb(nodep);
|
if (m_checkOnly) varRefCb(nodep);
|
||||||
@ -456,7 +461,7 @@ private:
|
|||||||
virtual void visit(AstConst* nodep) {
|
virtual void visit(AstConst* nodep) {
|
||||||
checkNodeInfo(nodep);
|
checkNodeInfo(nodep);
|
||||||
if (!m_checkOnly && optimizable()) {
|
if (!m_checkOnly && optimizable()) {
|
||||||
newValue(nodep, nodep);
|
newConst(nodep, nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void visit(AstEnumItemRef* nodep) {
|
virtual void visit(AstEnumItemRef* nodep) {
|
||||||
@ -467,7 +472,7 @@ private:
|
|||||||
if (valuep) {
|
if (valuep) {
|
||||||
iterateAndNextNull(valuep);
|
iterateAndNextNull(valuep);
|
||||||
if (optimizable()) {
|
if (optimizable()) {
|
||||||
newValue(nodep, fetchConst(valuep));
|
newConst(nodep, fetchConst(valuep));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clearOptimizable(nodep, "No value found for enum item");
|
clearOptimizable(nodep, "No value found for enum item");
|
||||||
@ -479,7 +484,7 @@ private:
|
|||||||
checkNodeInfo(nodep);
|
checkNodeInfo(nodep);
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
if (!m_checkOnly && optimizable()) {
|
if (!m_checkOnly && optimizable()) {
|
||||||
nodep->numberOperate(newValue(nodep)->num(),
|
nodep->numberOperate(newConst(nodep)->num(),
|
||||||
fetchConst(nodep->lhsp())->num());
|
fetchConst(nodep->lhsp())->num());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -488,7 +493,7 @@ private:
|
|||||||
checkNodeInfo(nodep);
|
checkNodeInfo(nodep);
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
if (!m_checkOnly && optimizable()) {
|
if (!m_checkOnly && optimizable()) {
|
||||||
nodep->numberOperate(newValue(nodep)->num(),
|
nodep->numberOperate(newConst(nodep)->num(),
|
||||||
fetchConst(nodep->lhsp())->num(),
|
fetchConst(nodep->lhsp())->num(),
|
||||||
fetchConst(nodep->rhsp())->num());
|
fetchConst(nodep->rhsp())->num());
|
||||||
}
|
}
|
||||||
@ -498,7 +503,7 @@ private:
|
|||||||
checkNodeInfo(nodep);
|
checkNodeInfo(nodep);
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
if (!m_checkOnly && optimizable()) {
|
if (!m_checkOnly && optimizable()) {
|
||||||
nodep->numberOperate(newValue(nodep)->num(),
|
nodep->numberOperate(newConst(nodep)->num(),
|
||||||
fetchConst(nodep->lhsp())->num(),
|
fetchConst(nodep->lhsp())->num(),
|
||||||
fetchConst(nodep->rhsp())->num(),
|
fetchConst(nodep->rhsp())->num(),
|
||||||
fetchConst(nodep->thsp())->num());
|
fetchConst(nodep->thsp())->num());
|
||||||
@ -515,9 +520,9 @@ private:
|
|||||||
if (optimizable()) {
|
if (optimizable()) {
|
||||||
if (fetchConst(nodep->lhsp())->num().isNeqZero()) {
|
if (fetchConst(nodep->lhsp())->num().isNeqZero()) {
|
||||||
iterate(nodep->rhsp());
|
iterate(nodep->rhsp());
|
||||||
newValue(nodep, fetchConst(nodep->rhsp()));
|
newConst(nodep, fetchConst(nodep->rhsp()));
|
||||||
} else {
|
} else {
|
||||||
newValue(nodep, fetchConst(nodep->lhsp())); // a zero
|
newConst(nodep, fetchConst(nodep->lhsp())); // a zero
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -532,10 +537,10 @@ private:
|
|||||||
iterate(nodep->lhsp());
|
iterate(nodep->lhsp());
|
||||||
if (optimizable()) {
|
if (optimizable()) {
|
||||||
if (fetchConst(nodep->lhsp())->num().isNeqZero()) {
|
if (fetchConst(nodep->lhsp())->num().isNeqZero()) {
|
||||||
newValue(nodep, fetchConst(nodep->lhsp())); // a one
|
newConst(nodep, fetchConst(nodep->lhsp())); // a one
|
||||||
} else {
|
} else {
|
||||||
iterate(nodep->rhsp());
|
iterate(nodep->rhsp());
|
||||||
newValue(nodep, fetchConst(nodep->rhsp()));
|
newConst(nodep, fetchConst(nodep->rhsp()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -551,10 +556,10 @@ private:
|
|||||||
if (optimizable()) {
|
if (optimizable()) {
|
||||||
if (fetchConst(nodep->lhsp())->num().isEqZero()) {
|
if (fetchConst(nodep->lhsp())->num().isEqZero()) {
|
||||||
AstConst cnst(nodep->fileline(), AstConst::WidthedValue(), 1, 1); // a one
|
AstConst cnst(nodep->fileline(), AstConst::WidthedValue(), 1, 1); // a one
|
||||||
newValue(nodep, &cnst); // a one
|
newConst(nodep, &cnst); // a one
|
||||||
} else {
|
} else {
|
||||||
iterate(nodep->rhsp());
|
iterate(nodep->rhsp());
|
||||||
newValue(nodep, fetchConst(nodep->rhsp()));
|
newConst(nodep, fetchConst(nodep->rhsp()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -572,10 +577,10 @@ private:
|
|||||||
if (optimizable()) {
|
if (optimizable()) {
|
||||||
if (fetchConst(nodep->condp())->num().isNeqZero()) {
|
if (fetchConst(nodep->condp())->num().isNeqZero()) {
|
||||||
iterate(nodep->expr1p());
|
iterate(nodep->expr1p());
|
||||||
newValue(nodep, fetchConst(nodep->expr1p()));
|
newConst(nodep, fetchConst(nodep->expr1p()));
|
||||||
} else {
|
} else {
|
||||||
iterate(nodep->expr2p());
|
iterate(nodep->expr2p());
|
||||||
newValue(nodep, fetchConst(nodep->expr2p()));
|
newConst(nodep, fetchConst(nodep->expr2p()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -607,7 +612,7 @@ private:
|
|||||||
outconst->num().opSelInto(fetchConst(nodep->rhsp())->num(),
|
outconst->num().opSelInto(fetchConst(nodep->rhsp())->num(),
|
||||||
lsb,
|
lsb,
|
||||||
selp->widthConst());
|
selp->widthConst());
|
||||||
assignOutValue(nodep, vscp, outconst);
|
assignOutConst(nodep, vscp, outconst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void handleAssignSelRecurse(AstNodeAssign* nodep, AstSel* selp,
|
void handleAssignSelRecurse(AstNodeAssign* nodep, AstSel* selp,
|
||||||
@ -659,7 +664,7 @@ private:
|
|||||||
iterateAndNextNull(nodep->rhsp());
|
iterateAndNextNull(nodep->rhsp());
|
||||||
if (optimizable()) {
|
if (optimizable()) {
|
||||||
AstNode* vscp = varOrScope(VN_CAST(nodep->lhsp(), VarRef));
|
AstNode* vscp = varOrScope(VN_CAST(nodep->lhsp(), VarRef));
|
||||||
assignOutValue(nodep, vscp, fetchConst(nodep->rhsp()));
|
assignOutConst(nodep, vscp, fetchConst(nodep->rhsp()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_inDlyAssign = false;
|
m_inDlyAssign = false;
|
||||||
@ -836,7 +841,7 @@ private:
|
|||||||
if (pinp) { // Else too few arguments in function call - ignore it
|
if (pinp) { // Else too few arguments in function call - ignore it
|
||||||
// Apply value to the function
|
// Apply value to the function
|
||||||
if (!m_checkOnly && optimizable()) {
|
if (!m_checkOnly && optimizable()) {
|
||||||
newValue(portp, fetchConst(pinp));
|
newConst(portp, fetchConst(pinp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -848,7 +853,7 @@ private:
|
|||||||
if (!m_checkOnly && optimizable()) {
|
if (!m_checkOnly && optimizable()) {
|
||||||
// Grab return value from output variable (if it's a function)
|
// Grab return value from output variable (if it's a function)
|
||||||
UASSERT_OBJ(funcp->fvarp(), nodep, "Function reference points at non-function");
|
UASSERT_OBJ(funcp->fvarp(), nodep, "Function reference points at non-function");
|
||||||
newValue(nodep, fetchConst(funcp->fvarp()));
|
newConst(nodep, fetchConst(funcp->fvarp()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user