Internals: Remove redunand SenItem nodes (#2457)
This commit is contained in:
parent
e609328ebb
commit
1632160fb1
|
|
@ -376,14 +376,6 @@ private:
|
|||
// if (debug() >= 9) nodep->dumpTree(cout, " Alw: ");
|
||||
visitAlways(nodep, nodep->sensesp(), VAlwaysKwd::ALWAYS);
|
||||
}
|
||||
virtual void visit(AstSenGate* nodep) VL_OVERRIDE {
|
||||
AstSenItem* subitemp = nodep->sensesp();
|
||||
UASSERT_OBJ(subitemp->edgeType() == VEdgeType::ET_ANYEDGE
|
||||
|| subitemp->edgeType() == VEdgeType::ET_POSEDGE
|
||||
|| subitemp->edgeType() == VEdgeType::ET_NEGEDGE,
|
||||
nodep, "Strange activity type under SenGate");
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep) VL_OVERRIDE {
|
||||
if (nodep->varrefp()) {
|
||||
if (AstBasicDType* basicp = nodep->varrefp()->dtypep()->basicp()) {
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ private:
|
|||
// NODE STATE/TYPES
|
||||
// STATE
|
||||
// Reset each module:
|
||||
AstNodeSenItem* m_seniDefaultp; // Default sensitivity (from AstDefClock)
|
||||
AstSenItem* m_seniDefaultp; // Default sensitivity (from AstDefClock)
|
||||
// Reset each assertion:
|
||||
AstNodeSenItem* m_senip; // Last sensitivity
|
||||
AstSenItem* m_senip; // Last sensitivity
|
||||
// Reset each always:
|
||||
AstNodeSenItem* m_seniAlwaysp; // Last sensitivity in always
|
||||
AstSenItem* m_seniAlwaysp; // Last sensitivity in always
|
||||
|
||||
// METHODS
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
|
@ -47,7 +47,7 @@ private:
|
|||
// Create sentree based on clocked or default clock
|
||||
// Return NULL for always
|
||||
AstSenTree* newp = NULL;
|
||||
AstNodeSenItem* senip = m_senip;
|
||||
AstSenItem* senip = m_senip;
|
||||
if (!senip) senip = m_seniDefaultp;
|
||||
if (!senip) senip = m_seniAlwaysp;
|
||||
if (!senip) {
|
||||
|
|
|
|||
13
src/V3Ast.h
13
src/V3Ast.h
|
|
@ -2246,19 +2246,6 @@ public:
|
|||
void addNotParallelp(AstNode* nodep) { setOp3p(nodep); }
|
||||
};
|
||||
|
||||
class AstNodeSenItem : public AstNode {
|
||||
// An AstSenItem or AstSenGate
|
||||
public:
|
||||
AstNodeSenItem(AstType t, FileLine* fl)
|
||||
: AstNode(t, fl) {}
|
||||
ASTNODE_BASE_FUNCS(NodeSenItem)
|
||||
virtual bool isClocked() const = 0;
|
||||
virtual bool isCombo() const = 0;
|
||||
virtual bool isInitial() const = 0;
|
||||
virtual bool isSettle() const = 0;
|
||||
virtual bool isNever() const = 0;
|
||||
};
|
||||
|
||||
class AstNodeVarRef : public AstNodeMath {
|
||||
// An AstVarRef or AstVarXRef
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -815,28 +815,28 @@ string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
|
|||
|
||||
bool AstSenTree::hasClocked() const {
|
||||
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp = VN_CAST(senp->nextp(), NodeSenItem)) {
|
||||
for (AstSenItem* senp = sensesp(); senp; senp = VN_CAST(senp->nextp(), SenItem)) {
|
||||
if (senp->isClocked()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool AstSenTree::hasSettle() const {
|
||||
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp = VN_CAST(senp->nextp(), NodeSenItem)) {
|
||||
for (AstSenItem* senp = sensesp(); senp; senp = VN_CAST(senp->nextp(), SenItem)) {
|
||||
if (senp->isSettle()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool AstSenTree::hasInitial() const {
|
||||
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp = VN_CAST(senp->nextp(), NodeSenItem)) {
|
||||
for (AstSenItem* senp = sensesp(); senp; senp = VN_CAST(senp->nextp(), SenItem)) {
|
||||
if (senp->isInitial()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool AstSenTree::hasCombo() const {
|
||||
UASSERT_OBJ(sensesp(), this, "SENTREE without any SENITEMs under it");
|
||||
for (AstNodeSenItem* senp = sensesp(); senp; senp = VN_CAST(senp->nextp(), NodeSenItem)) {
|
||||
for (AstSenItem* senp = sensesp(); senp; senp = VN_CAST(senp->nextp(), SenItem)) {
|
||||
if (senp->isCombo()) return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -3035,9 +3035,9 @@ public:
|
|||
|
||||
//######################################################################
|
||||
|
||||
class AstSenItem : public AstNodeSenItem {
|
||||
class AstSenItem : public AstNode {
|
||||
// Parents: SENTREE
|
||||
// Children: (optional) VARREF SENGATE
|
||||
// Children: (optional) VARREF
|
||||
private:
|
||||
VEdgeType m_edgeType; // Edge type
|
||||
public:
|
||||
|
|
@ -3087,41 +3087,15 @@ public:
|
|||
return VN_CAST(op1p(), NodeVarRef);
|
||||
} // op1 = Signal sensitized
|
||||
//
|
||||
virtual bool isClocked() const { return edgeType().clockedStmt(); }
|
||||
virtual bool isCombo() const { return edgeType() == VEdgeType::ET_COMBO; }
|
||||
virtual bool isInitial() const { return edgeType() == VEdgeType::ET_INITIAL; }
|
||||
virtual bool isIllegal() const { return edgeType() == VEdgeType::ET_ILLEGAL; }
|
||||
virtual bool isSettle() const { return edgeType() == VEdgeType::ET_SETTLE; }
|
||||
virtual bool isNever() const { return edgeType() == VEdgeType::ET_NEVER; }
|
||||
bool isClocked() const { return edgeType().clockedStmt(); }
|
||||
bool isCombo() const { return edgeType() == VEdgeType::ET_COMBO; }
|
||||
bool isInitial() const { return edgeType() == VEdgeType::ET_INITIAL; }
|
||||
bool isIllegal() const { return edgeType() == VEdgeType::ET_ILLEGAL; }
|
||||
bool isSettle() const { return edgeType() == VEdgeType::ET_SETTLE; }
|
||||
bool isNever() const { return edgeType() == VEdgeType::ET_NEVER; }
|
||||
bool hasVar() const { return !(isCombo() || isInitial() || isSettle() || isNever()); }
|
||||
};
|
||||
|
||||
class AstSenGate : public AstNodeSenItem {
|
||||
// Parents: SENTREE
|
||||
// Children: SENITEM expr
|
||||
// AND as applied to a sensitivity list and a gating expression
|
||||
// Performing this gating is optional; it may be removed by later optimizations
|
||||
public:
|
||||
AstSenGate(FileLine* fl, AstSenItem* sensesp, AstNode* rhsp)
|
||||
: ASTGEN_SUPER(fl) {
|
||||
dtypeSetLogicBool();
|
||||
addOp1p(sensesp);
|
||||
setOp2p(rhsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(SenGate)
|
||||
virtual string emitVerilog() { return "(%l) %f&& (%r)"; }
|
||||
AstSenItem* sensesp() const { return VN_CAST(op1p(), SenItem); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
void sensesp(AstSenItem* nodep) { addOp1p(nodep); }
|
||||
void rhsp(AstNode* nodep) { setOp2p(nodep); }
|
||||
//
|
||||
virtual bool isClocked() const { return true; }
|
||||
virtual bool isCombo() const { return false; }
|
||||
virtual bool isInitial() const { return false; }
|
||||
virtual bool isSettle() const { return false; }
|
||||
virtual bool isNever() const { return false; }
|
||||
};
|
||||
|
||||
class AstSenTree : public AstNode {
|
||||
// A list of senitems
|
||||
// Parents: MODULE | SBLOCK
|
||||
|
|
@ -3129,7 +3103,7 @@ class AstSenTree : public AstNode {
|
|||
private:
|
||||
bool m_multi; // Created from combo logic by ORing multiple clock domains
|
||||
public:
|
||||
AstSenTree(FileLine* fl, AstNodeSenItem* sensesp)
|
||||
AstSenTree(FileLine* fl, AstSenItem* sensesp)
|
||||
: ASTGEN_SUPER(fl)
|
||||
, m_multi(false) {
|
||||
addNOp1p(sensesp);
|
||||
|
|
@ -3140,8 +3114,8 @@ public:
|
|||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
bool isMulti() const { return m_multi; }
|
||||
// op1 = Sensitivity list
|
||||
AstNodeSenItem* sensesp() const { return VN_CAST(op1p(), NodeSenItem); }
|
||||
void addSensesp(AstNodeSenItem* nodep) { addOp1p(nodep); }
|
||||
AstSenItem* sensesp() const { return VN_CAST(op1p(), SenItem); }
|
||||
void addSensesp(AstSenItem* nodep) { addOp1p(nodep); }
|
||||
void multi(bool flag) { m_multi = true; }
|
||||
// METHODS
|
||||
bool hasClocked() const; // Includes a clocked statement
|
||||
|
|
@ -8078,14 +8052,14 @@ class AstClocking : public AstNode {
|
|||
// Parents: MODULE
|
||||
// Children: Assertions
|
||||
public:
|
||||
AstClocking(FileLine* fl, AstNodeSenItem* sensesp, AstNode* bodysp)
|
||||
AstClocking(FileLine* fl, AstSenItem* sensesp, AstNode* bodysp)
|
||||
: ASTGEN_SUPER(fl) {
|
||||
addOp1p(sensesp);
|
||||
addNOp2p(bodysp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Clocking)
|
||||
// op1 = Sensitivity list
|
||||
AstNodeSenItem* sensesp() const { return VN_CAST(op1p(), NodeSenItem); }
|
||||
AstSenItem* sensesp() const { return VN_CAST(op1p(), SenItem); }
|
||||
AstNode* bodysp() const { return op2p(); } // op2 = Body
|
||||
};
|
||||
|
||||
|
|
@ -8097,7 +8071,7 @@ class AstPropClocked : public AstNode {
|
|||
// Parents: ASSERT|COVER (property)
|
||||
// Children: SENITEM, Properties
|
||||
public:
|
||||
AstPropClocked(FileLine* fl, AstNodeSenItem* sensesp, AstNode* disablep, AstNode* propp)
|
||||
AstPropClocked(FileLine* fl, AstSenItem* sensesp, AstNode* disablep, AstNode* propp)
|
||||
: ASTGEN_SUPER(fl) {
|
||||
addNOp1p(sensesp);
|
||||
addNOp2p(disablep);
|
||||
|
|
@ -8105,8 +8079,8 @@ public:
|
|||
}
|
||||
ASTNODE_NODE_FUNCS(PropClocked)
|
||||
virtual bool hasDType() const { return true; } // Used under Cover, which expects a bool child
|
||||
AstNodeSenItem* sensesp() const {
|
||||
return VN_CAST(op1p(), NodeSenItem);
|
||||
AstSenItem* sensesp() const {
|
||||
return VN_CAST(op1p(), SenItem);
|
||||
} // op1 = Sensitivity list
|
||||
AstNode* disablep() const { return op2p(); } // op2 = disable
|
||||
AstNode* propp() const { return op3p(); } // op3 = property
|
||||
|
|
|
|||
|
|
@ -694,8 +694,6 @@ private:
|
|||
m_inDly = false;
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep) VL_OVERRIDE {
|
||||
// Note we look at only AstSenItems, not AstSenGate's
|
||||
// The gating term of a AstSenGate is normal logic
|
||||
m_inSenItem = true;
|
||||
iterateChildren(nodep);
|
||||
m_inSenItem = false;
|
||||
|
|
@ -705,11 +703,6 @@ private:
|
|||
// CDC doesn't care about public variables
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) VL_OVERRIDE { iterateNewStmt(nodep); }
|
||||
virtual void visit(AstSenGate* nodep) VL_OVERRIDE {
|
||||
// First handle the clock part will be handled in a minute by visit AstSenItem
|
||||
// The logic gating term is dealt with as logic
|
||||
iterateNewStmt(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep) VL_OVERRIDE { iterateNewStmt(nodep); }
|
||||
virtual void visit(AstAssignW* nodep) VL_OVERRIDE { iterateNewStmt(nodep); }
|
||||
|
||||
|
|
|
|||
|
|
@ -136,23 +136,11 @@ private:
|
|||
}
|
||||
return newp;
|
||||
}
|
||||
AstNode* createSenGateEquation(AstSenGate* nodep) {
|
||||
AstNode* newp = new AstAnd(nodep->fileline(), createSenseEquation(nodep->sensesp()),
|
||||
nodep->rhsp()->cloneTree(true));
|
||||
return newp;
|
||||
}
|
||||
AstNode* createSenseEquation(AstNodeSenItem* nodesp) {
|
||||
AstNode* createSenseEquation(AstSenItem* nodesp) {
|
||||
// Nodep may be a list of elements; we need to walk it
|
||||
AstNode* senEqnp = NULL;
|
||||
for (AstNodeSenItem* senp = nodesp; senp; senp = VN_CAST(senp->nextp(), NodeSenItem)) {
|
||||
AstNode* senOnep = NULL;
|
||||
if (AstSenItem* itemp = VN_CAST(senp, SenItem)) {
|
||||
senOnep = createSenItemEquation(itemp);
|
||||
} else if (AstSenGate* itemp = VN_CAST(senp, SenGate)) {
|
||||
senOnep = createSenGateEquation(itemp);
|
||||
} else {
|
||||
senp->v3fatalSrc("Strange node under sentree");
|
||||
}
|
||||
for (AstSenItem* senp = nodesp; senp; senp = VN_CAST(senp->nextp(), SenItem)) {
|
||||
AstNode*const senOnep = createSenItemEquation(senp);
|
||||
if (senEqnp) {
|
||||
// Add new OR to the sensitivity list equation
|
||||
senEqnp = new AstOr(senp->fileline(), senEqnp, senOnep);
|
||||
|
|
|
|||
120
src/V3Const.cpp
120
src/V3Const.cpp
|
|
@ -1679,7 +1679,7 @@ private:
|
|||
// Not constant propagated (for today) because AstNodeMath::isOpaque is set
|
||||
// Someday if lower is constant, convert to quoted "string".
|
||||
|
||||
bool onlySenItemInSenTree(AstNodeSenItem* nodep) {
|
||||
bool onlySenItemInSenTree(AstSenItem* nodep) {
|
||||
// Only one if it's not in a list
|
||||
return (!nodep->nextp() && nodep->backp()->nextp() != nodep);
|
||||
}
|
||||
|
|
@ -1723,56 +1723,29 @@ private:
|
|||
"Null sensitivity variable");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSenGate* nodep) VL_OVERRIDE {
|
||||
iterateChildren(nodep);
|
||||
if (AstConst* constp = VN_CAST(nodep->rhsp(), Const)) {
|
||||
if (constp->isZero()) {
|
||||
UINFO(4, "SENGATE(...,0)->NEVER" << endl);
|
||||
if (onlySenItemInSenTree(nodep)) {
|
||||
nodep->replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Never()));
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
} else {
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
} else {
|
||||
UINFO(4, "SENGATE(SENITEM,0)->ALWAYS SENITEM" << endl);
|
||||
AstNode* senitemp = nodep->sensesp()->unlinkFrBack();
|
||||
nodep->replaceWith(senitemp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SenItemCmp {
|
||||
inline bool operator()(AstNodeSenItem* lhsp, AstNodeSenItem* rhsp) const {
|
||||
inline bool operator()(const AstSenItem* lhsp, const AstSenItem* rhsp) const {
|
||||
if (lhsp->type() < rhsp->type()) return true;
|
||||
if (lhsp->type() > rhsp->type()) return false;
|
||||
const AstSenItem* litemp = VN_CAST_CONST(lhsp, SenItem);
|
||||
const AstSenItem* ritemp = VN_CAST_CONST(rhsp, SenItem);
|
||||
if (litemp && ritemp) {
|
||||
// Looks visually better if we keep sorted by name
|
||||
if (!litemp->varrefp() && ritemp->varrefp()) return true;
|
||||
if (litemp->varrefp() && !ritemp->varrefp()) return false;
|
||||
if (litemp->varrefp() && ritemp->varrefp()) {
|
||||
if (litemp->varrefp()->name() < ritemp->varrefp()->name()) return true;
|
||||
if (litemp->varrefp()->name() > ritemp->varrefp()->name()) return false;
|
||||
// But might be same name with different scopes
|
||||
if (litemp->varrefp()->varScopep() < ritemp->varrefp()->varScopep()) {
|
||||
return true;
|
||||
}
|
||||
if (litemp->varrefp()->varScopep() > ritemp->varrefp()->varScopep()) {
|
||||
return false;
|
||||
}
|
||||
// Or rarely, different data types
|
||||
if (litemp->varrefp()->dtypep() < ritemp->varrefp()->dtypep()) return true;
|
||||
if (litemp->varrefp()->dtypep() > ritemp->varrefp()->dtypep()) return false;
|
||||
}
|
||||
// Sort by edge, AFTER variable, as we want multiple edges for same var adjacent.
|
||||
// note the SenTree optimizer requires this order (more
|
||||
// general first, less general last)
|
||||
if (litemp->edgeType() < ritemp->edgeType()) return true;
|
||||
if (litemp->edgeType() > ritemp->edgeType()) return false;
|
||||
// Looks visually better if we keep sorted by name
|
||||
if (!lhsp->varrefp() && rhsp->varrefp()) return true;
|
||||
if (lhsp->varrefp() && !rhsp->varrefp()) return false;
|
||||
if (lhsp->varrefp() && rhsp->varrefp()) {
|
||||
if (lhsp->varrefp()->name() < rhsp->varrefp()->name()) return true;
|
||||
if (lhsp->varrefp()->name() > rhsp->varrefp()->name()) return false;
|
||||
// But might be same name with different scopes
|
||||
if (lhsp->varrefp()->varScopep() < rhsp->varrefp()->varScopep()) { return true; }
|
||||
if (lhsp->varrefp()->varScopep() > rhsp->varrefp()->varScopep()) { return false; }
|
||||
// Or rarely, different data types
|
||||
if (lhsp->varrefp()->dtypep() < rhsp->varrefp()->dtypep()) return true;
|
||||
if (lhsp->varrefp()->dtypep() > rhsp->varrefp()->dtypep()) return false;
|
||||
}
|
||||
// Sort by edge, AFTER variable, as we want multiple edges for same var adjacent.
|
||||
// note the SenTree optimizer requires this order (more
|
||||
// general first, less general last)
|
||||
if (lhsp->edgeType() < rhsp->edgeType()) return true;
|
||||
if (lhsp->edgeType() > rhsp->edgeType()) return false;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
@ -1793,30 +1766,10 @@ private:
|
|||
{
|
||||
AstUser4InUse m_inuse4;
|
||||
// Mark x in SENITEM(x)
|
||||
for (AstNodeSenItem* senp = VN_CAST(nodep->sensesp(), NodeSenItem); senp;
|
||||
senp = VN_CAST(senp->nextp(), NodeSenItem)) {
|
||||
if (AstSenItem* itemp = VN_CAST(senp, SenItem)) {
|
||||
if (itemp->varrefp() && itemp->varrefp()->varScopep()) {
|
||||
itemp->varrefp()->varScopep()->user4(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Find x in SENTREE(SENITEM(x))
|
||||
for (AstNodeSenItem *nextp, *senp = VN_CAST(nodep->sensesp(), NodeSenItem); senp;
|
||||
senp = nextp) {
|
||||
nextp = VN_CAST(senp->nextp(), NodeSenItem);
|
||||
if (AstSenGate* gatep = VN_CAST(senp, SenGate)) {
|
||||
if (AstSenItem* itemp = VN_CAST(gatep->sensesp(), SenItem)) {
|
||||
if (itemp->varrefp() && itemp->varrefp()->varScopep()) {
|
||||
if (itemp->varrefp()->varScopep()->user4()) {
|
||||
// Found, push this item up to the top
|
||||
itemp->unlinkFrBack();
|
||||
nodep->addSensesp(itemp);
|
||||
VL_DO_DANGLING(gatep->unlinkFrBack()->deleteTree(), gatep);
|
||||
VL_DANGLING(senp);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (AstSenItem* senp = VN_CAST(nodep->sensesp(), SenItem); senp;
|
||||
senp = VN_CAST(senp->nextp(), SenItem)) {
|
||||
if (senp->varrefp() && senp->varrefp()->varScopep()) {
|
||||
senp->varrefp()->varScopep()->user4(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1824,25 +1777,25 @@ private:
|
|||
// Sort the sensitivity names so "posedge a or b" and "posedge b or a" end up together.
|
||||
// Also, remove duplicate assignments, and fold POS&NEGs into ANYEDGEs
|
||||
// Make things a little faster; check first if we need a sort
|
||||
for (AstNodeSenItem *nextp, *senp = VN_CAST(nodep->sensesp(), NodeSenItem); senp;
|
||||
for (AstSenItem *nextp, *senp = VN_CAST(nodep->sensesp(), SenItem); senp;
|
||||
senp = nextp) {
|
||||
nextp = VN_CAST(senp->nextp(), NodeSenItem);
|
||||
nextp = VN_CAST(senp->nextp(), SenItem);
|
||||
// cppcheck-suppress unassignedVariable // cppcheck bug
|
||||
SenItemCmp cmp;
|
||||
if (nextp && !cmp(senp, nextp)) {
|
||||
// Something's out of order, sort it
|
||||
senp = NULL;
|
||||
std::vector<AstNodeSenItem*> vec;
|
||||
for (AstNodeSenItem* senp = VN_CAST(nodep->sensesp(), NodeSenItem); senp;
|
||||
senp = VN_CAST(senp->nextp(), NodeSenItem)) {
|
||||
std::vector<AstSenItem*> vec;
|
||||
for (AstSenItem* senp = VN_CAST(nodep->sensesp(), SenItem); senp;
|
||||
senp = VN_CAST(senp->nextp(), SenItem)) {
|
||||
vec.push_back(senp);
|
||||
}
|
||||
stable_sort(vec.begin(), vec.end(), SenItemCmp());
|
||||
for (std::vector<AstNodeSenItem*>::iterator it = vec.begin(); it != vec.end();
|
||||
for (std::vector<AstSenItem*>::iterator it = vec.begin(); it != vec.end();
|
||||
++it) {
|
||||
(*it)->unlinkFrBack();
|
||||
}
|
||||
for (std::vector<AstNodeSenItem*>::iterator it = vec.begin(); it != vec.end();
|
||||
for (std::vector<AstSenItem*>::iterator it = vec.begin(); it != vec.end();
|
||||
++it) {
|
||||
nodep->addSensesp(*it);
|
||||
}
|
||||
|
|
@ -1851,13 +1804,12 @@ private:
|
|||
}
|
||||
|
||||
// Pass2, remove dup edges
|
||||
for (AstNodeSenItem *nextp, *senp = VN_CAST(nodep->sensesp(), NodeSenItem); senp;
|
||||
for (AstSenItem *nextp, *senp = VN_CAST(nodep->sensesp(), SenItem); senp;
|
||||
senp = nextp) {
|
||||
nextp = VN_CAST(senp->nextp(), NodeSenItem);
|
||||
AstNodeSenItem* cmpp = nextp;
|
||||
AstSenItem* litemp = VN_CAST(senp, SenItem);
|
||||
AstSenItem* ritemp = VN_CAST(cmpp, SenItem);
|
||||
if (litemp && ritemp) {
|
||||
nextp = VN_CAST(senp->nextp(), SenItem);
|
||||
AstSenItem*const litemp = senp;
|
||||
AstSenItem*const ritemp = nextp;
|
||||
if (ritemp) {
|
||||
if ((litemp->varrefp() && ritemp->varrefp()
|
||||
&& litemp->varrefp()->sameGateTree(ritemp->varrefp()))
|
||||
|| (!litemp->varrefp() && !ritemp->varrefp())) {
|
||||
|
|
@ -1877,7 +1829,7 @@ private:
|
|||
litemp->edgeType(VEdgeType::ET_BOTHEDGE);
|
||||
// Remove redundant node
|
||||
VL_DO_DANGLING(ritemp->unlinkFrBack()->deleteTree(), ritemp);
|
||||
VL_DANGLING(cmpp);
|
||||
VL_DANGLING(ritemp);
|
||||
// Try to collapse again
|
||||
nextp = litemp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,8 +171,8 @@ private:
|
|||
UINFO(4, " Act: " << m_activep << endl);
|
||||
UINFO(4, " Act: " << oldactivep << endl);
|
||||
// Make a new sensitivity list, which is the combination of both blocks
|
||||
AstNodeSenItem* sena = m_activep->sensesp()->sensesp()->cloneTree(true);
|
||||
AstNodeSenItem* senb = oldactivep->sensesp()->sensesp()->cloneTree(true);
|
||||
AstSenItem* sena = m_activep->sensesp()->sensesp()->cloneTree(true);
|
||||
AstSenItem* senb = oldactivep->sensesp()->sensesp()->cloneTree(true);
|
||||
AstSenTree* treep = new AstSenTree(m_activep->fileline(), sena);
|
||||
if (senb) treep->addSensesp(senb);
|
||||
if (AstSenTree* storep = oldactivep->sensesStorep()) {
|
||||
|
|
|
|||
|
|
@ -160,9 +160,6 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
|||
}
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstSenGate* nodep) VL_OVERRIDE {
|
||||
emitVerilogFormat(nodep, nodep->emitVerilog(), nodep->sensesp(), nodep->rhsp());
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep) VL_OVERRIDE {
|
||||
putfs(nodep, "");
|
||||
puts(nodep->edgeType().verilogKwd());
|
||||
|
|
|
|||
|
|
@ -483,8 +483,6 @@ private:
|
|||
iterateNewStmt(nodep, "User C Function", "User C Function");
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep) VL_OVERRIDE {
|
||||
// Note we look at only AstSenItems, not AstSenGate's
|
||||
// The gating term of a AstSenGate is normal logic
|
||||
m_inSenItem = true;
|
||||
if (m_logicVertexp) { // Already under logic; presumably a SenGate
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -493,11 +491,6 @@ private:
|
|||
}
|
||||
m_inSenItem = false;
|
||||
}
|
||||
virtual void visit(AstSenGate* nodep) VL_OVERRIDE {
|
||||
// First handle the clock part will be handled in a minute by visit AstSenItem
|
||||
// The logic gating term is dealt with as logic
|
||||
iterateNewStmt(nodep, "Clock gater", "Clock gater");
|
||||
}
|
||||
virtual void visit(AstInitial* nodep) VL_OVERRIDE {
|
||||
bool lastslow = m_inSlow;
|
||||
m_inSlow = true;
|
||||
|
|
|
|||
|
|
@ -218,9 +218,6 @@ private:
|
|||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: Complex statement in sensitivity list");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSenGate* nodep) VL_OVERRIDE { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc("SenGates shouldn't be in tree yet");
|
||||
}
|
||||
|
||||
virtual void visit(AstNodePreSel* nodep) VL_OVERRIDE {
|
||||
if (!nodep->attrp()) {
|
||||
|
|
|
|||
|
|
@ -1282,8 +1282,7 @@ static bool domainsExclusive(const AstSenTree* fromp, const AstSenTree* top) {
|
|||
|
||||
const AstSenItem* fromSenListp = VN_CAST(fromp->sensesp(), SenItem);
|
||||
const AstSenItem* toSenListp = VN_CAST(top->sensesp(), SenItem);
|
||||
// If clk gating is ever reenabled, we may need to update this to handle
|
||||
// AstSenGate also.
|
||||
|
||||
UASSERT_OBJ(fromSenListp, fromp, "sensitivity list item is not an AstSenItem");
|
||||
UASSERT_OBJ(toSenListp, top, "sensitivity list item is not an AstSenItem");
|
||||
|
||||
|
|
@ -1531,7 +1530,7 @@ void OrderVisitor::processDomainsIterate(OrderEitherVertex* vertexp) {
|
|||
fromVertexp->domainp()->dumpTree(cout);
|
||||
} // LCOV_EXCL_STOP
|
||||
AstSenTree* newtreep = domainp->cloneTree(false);
|
||||
AstNodeSenItem* newtree2p = fromVertexp->domainp()->sensesp()->cloneTree(true);
|
||||
AstSenItem* newtree2p = fromVertexp->domainp()->sensesp()->cloneTree(true);
|
||||
UASSERT_OBJ(newtree2p, fromVertexp->domainp(),
|
||||
"No senitem found under clocked domain");
|
||||
newtreep->addSensesp(newtree2p);
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ struct V3ParseBisonYYSType {
|
|||
AstNodeFTask* ftaskp;
|
||||
AstNodeFTaskRef* ftaskrefp;
|
||||
AstNodeRange* rangep;
|
||||
AstNodeSenItem* senitemp;
|
||||
AstSenItem* senitemp;
|
||||
AstNodeVarRef* varnodep;
|
||||
AstPackage* packagep;
|
||||
AstPackageRef* packagerefp;
|
||||
|
|
|
|||
|
|
@ -2836,11 +2836,11 @@ event_control<sentreep>: // ==IEEE: event_control
|
|||
event_expression<senitemp>: // IEEE: event_expression - split over several
|
||||
//UNSUP // Below are all removed
|
||||
senitem { $$ = $1; }
|
||||
| event_expression yOR senitem { $$ = VN_CAST($1->addNextNull($3), NodeSenItem); }
|
||||
| event_expression ',' senitem { $$ = VN_CAST($1->addNextNull($3), NodeSenItem); } /* Verilog 2001 */
|
||||
| event_expression yOR senitem { $$ = VN_CAST($1->addNextNull($3), SenItem); }
|
||||
| event_expression ',' senitem { $$ = VN_CAST($1->addNextNull($3), SenItem); } /* Verilog 2001 */
|
||||
//UNSUP // Above are all removed, replace with:
|
||||
//UNSUP ev_expr { $$ = $1; }
|
||||
//UNSUP event_expression ',' ev_expr %prec yOR { $$ = VN_CAST($1->addNextNull($3), NodeSenItem); }
|
||||
//UNSUP event_expression ',' ev_expr %prec yOR { $$ = VN_CAST($1->addNextNull($3), SenItem); }
|
||||
;
|
||||
|
||||
senitem<senitemp>: // IEEE: part of event_expression, non-'OR' ',' terms
|
||||
|
|
|
|||
Loading…
Reference in New Issue