AstVarScope* getCreateLastClk(AstVarScope* vscp) { if (vscp->user1p()) return ((AstVarScope*)vscp->user1p()); AstVar* varp = vscp->varp(); if (!varp->width1()) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<<varp->prettyName()); string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->name()); AstVar* newvarp = new AstVar(vscp->fileline(), AstVarType::MODULETEMP, newvarname, VFlagLogicPacked(), 1); newvarp->noReset(true); // Reset by below assign m_modp->addStmtp(newvarp); AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp); vscp->user1p(newvscp); m_scopep->addVarp(newvscp); // Add init AstNode* fromp = new AstVarRef(newvarp->fileline(), vscp, false); if (v3Global.opt.xInitialEdge()) fromp = new AstNot(fromp->fileline(), fromp); AstNode* newinitp = new AstAssign(vscp->fileline(), new AstVarRef(newvarp->fileline(), newvscp, true), fromp); addToInitial(newinitp); // At bottom, assign them AstAssign* finalp = new AstAssign(vscp->fileline(), new AstVarRef(vscp->fileline(), newvscp, true), new AstVarRef(vscp->fileline(), vscp, false)); m_evalFuncp->addFinalsp(finalp); // UINFO(4,"New Last: "<<newvscp<<endl); return newvscp; }
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; } }