mirror of
https://github.com/verilator/verilator.git
synced 2026-09-01 10:27:04 +02:00
The AstIf nodes conditional on events being triggered used to be created in V3Clock. Now it is in V3Sched*, in order to avoid having to pass AstActive in CFunc or MTask bodies. No functional change intended, some improved optimization due to simplifying timing triggers that were previously missed, also fixes what seems like a bug in the original timing commit code.
This commit is contained in:
+3
-75
@@ -1,6 +1,6 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Clocking POS/NEGEDGE insertion
|
||||
// DESCRIPTION: Verilator: Post scheduling transformations
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
@@ -15,15 +15,7 @@
|
||||
//*************************************************************************
|
||||
// V3Clock's Transformations:
|
||||
//
|
||||
// Top Scope:
|
||||
// Check created ACTIVEs
|
||||
// Compress adjacent ACTIVEs with same sensitivity list
|
||||
// Form master _eval function
|
||||
// Add around the SENTREE a (IF POSEDGE(..))
|
||||
// Add a __Vlast_{clock} for the comparison
|
||||
// Set the __Vlast_{clock} at the end of the block
|
||||
// Replace UNTILSTABLEs with loops until specified signals become const.
|
||||
// Create global calling function for any per-scope functions. (For FINALs).
|
||||
// This pass is historic and does some arbitray post scheduling rewrites
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
@@ -71,32 +63,7 @@ class ClockVisitor final : public VNVisitor {
|
||||
|
||||
// STATE
|
||||
AstCFunc* const m_evalp = nullptr; // The '_eval' function
|
||||
AstSenTree* m_lastSenp = nullptr; // Last sensitivity match, so we can detect duplicates.
|
||||
AstIf* m_lastIfp = nullptr; // Last sensitivity if active to add more under
|
||||
|
||||
// METHODS
|
||||
|
||||
AstNodeExpr* createSenseEquation(AstSenItem* nodesp) {
|
||||
AstNodeExpr* senEqnp = nullptr;
|
||||
for (AstSenItem* senp = nodesp; senp; senp = VN_AS(senp->nextp(), SenItem)) {
|
||||
UASSERT_OBJ(senp->edgeType() == VEdgeType::ET_TRUE, senp, "Should have been lowered");
|
||||
if (senp->sensp()) {
|
||||
AstNodeExpr* const senOnep = senp->sensp()->cloneTree(false);
|
||||
senEqnp = senEqnp ? new AstOr{senp->fileline(), senEqnp, senOnep} : senOnep;
|
||||
}
|
||||
}
|
||||
return senEqnp;
|
||||
}
|
||||
AstIf* makeActiveIf(AstSenTree* sentreep) {
|
||||
AstNodeExpr* const senEqnp = createSenseEquation(sentreep->sensesp());
|
||||
UASSERT_OBJ(senEqnp, sentreep, "No sense equation, shouldn't be in sequent activation.");
|
||||
AstIf* const newifp = new AstIf{sentreep->fileline(), senEqnp};
|
||||
return newifp;
|
||||
}
|
||||
void clearLastSen() {
|
||||
m_lastSenp = nullptr;
|
||||
m_lastIfp = nullptr;
|
||||
}
|
||||
// VISITORS
|
||||
void visit(AstCoverToggle* nodep) override {
|
||||
// UINFOTREE(1, nodep, "", "ct");
|
||||
@@ -125,41 +92,7 @@ class ClockVisitor final : public VNVisitor {
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
void visit(AstSenTree* nodep) override {
|
||||
nodep->unlinkFrBack();
|
||||
pushDeletep(nodep); // Delete it later, AstActives still pointing to it
|
||||
}
|
||||
void visit(AstActive* nodep) override {
|
||||
UASSERT_OBJ(nodep->hasClocked(), nodep, "Should have been converted by V3Sched");
|
||||
UASSERT_OBJ(nodep->stmtsp(), nodep, "Should not have been created if empty");
|
||||
|
||||
AstNode* const stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
|
||||
|
||||
// Create 'if' statement, if needed
|
||||
if (!m_lastSenp || !nodep->sentreep()->sameTree(m_lastSenp)) {
|
||||
VNRelinker relinker;
|
||||
nodep->unlinkFrBack(&relinker);
|
||||
clearLastSen();
|
||||
m_lastSenp = nodep->sentreep();
|
||||
// Make a new if statement
|
||||
m_lastIfp = makeActiveIf(m_lastSenp);
|
||||
relinker.relink(m_lastIfp);
|
||||
} else {
|
||||
nodep->unlinkFrBack();
|
||||
}
|
||||
|
||||
// Move statements to if
|
||||
m_lastIfp->addThensp(stmtsp);
|
||||
|
||||
// Dispose of the AstActive
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
void visit(AstExecGraph* nodep) override {
|
||||
for (AstMTaskBody* mtaskBodyp = nodep->mTaskBodiesp(); mtaskBodyp;
|
||||
mtaskBodyp = VN_AS(mtaskBodyp->nextp(), MTaskBody)) {
|
||||
clearLastSen();
|
||||
iterate(mtaskBodyp);
|
||||
}
|
||||
clearLastSen();
|
||||
pushDeletep(nodep->unlinkFrBack()); // No longer needed
|
||||
}
|
||||
|
||||
//========== Move sampled assignments
|
||||
@@ -187,11 +120,6 @@ public:
|
||||
// CONSTRUCTORS
|
||||
explicit ClockVisitor(AstNetlist* netlistp)
|
||||
: m_evalp{netlistp->evalp()} {
|
||||
// Simplify all SenTrees
|
||||
for (AstSenTree* senTreep = netlistp->topScopep()->senTreesp(); senTreep;
|
||||
senTreep = VN_AS(senTreep->nextp(), SenTree)) {
|
||||
V3Const::constifyExpensiveEdit(senTreep);
|
||||
}
|
||||
iterate(netlistp);
|
||||
}
|
||||
~ClockVisitor() override = default;
|
||||
|
||||
Reference in New Issue
Block a user