virtual void visit(AstActive* nodep, AstNUser*) { // Careful if adding variables here, ACTIVES can be under other ACTIVES // Need to save and restore any member state in AstUntilStable block if (!m_topScopep || !nodep->stmtsp()) { // Not at the top or empty block... // Only empty blocks should be leftover on the non-top. Killem. if (nodep->stmtsp()) nodep->v3fatalSrc("Non-empty lower active"); nodep->unlinkFrBack()->deleteTree(); nodep=NULL; } else { UINFO(4," ACTIVE "<<nodep<<endl); AstNode* stmtsp = nodep->stmtsp()->unlinkFrBackWithNext(); if (nodep->hasClocked()) { // Remember the latest sensitivity so we can compare it next time if (nodep->hasInitial()) nodep->v3fatalSrc("Initial block should not have clock sensitivity"); if (m_lastSenp && nodep->sensesp()->sameTree(m_lastSenp)) { UINFO(4," sameSenseTree\n"); } else { clearLastSen(); m_lastSenp = nodep->sensesp(); // Make a new if statement m_lastIfp = makeActiveIf(m_lastSenp); addToEvalLoop(m_lastIfp); } // Move statements to if m_lastIfp->addIfsp(stmtsp); } else if (nodep->hasInitial()) { // Don't need to: clearLastSen();, as we're adding it to different cfunc // Move statements to function addToInitial(stmtsp); } else if (nodep->hasSettle()) { // Don't need to: clearLastSen();, as we're adding it to different cfunc // Move statements to function addToSettleLoop(stmtsp); } else { // Combo clearLastSen(); // Move statements to function addToEvalLoop(stmtsp); } nodep->unlinkFrBack()->deleteTree(); nodep = NULL; } }
virtual void visit(AstExecGraph* nodep) { for (m_mtaskBodyp = VN_CAST(nodep->op1p(), MTaskBody); m_mtaskBodyp; m_mtaskBodyp = VN_CAST(m_mtaskBodyp->nextp(), MTaskBody)) { clearLastSen(); iterate(m_mtaskBodyp); } clearLastSen(); // Move the ExecGraph into _eval. Its location marks the // spot where the graph will execute, relative to other // (serial) logic in the cycle. nodep->unlinkFrBack(); addToEvalLoop(nodep); }