virtual void visit(AstVarRef* nodep) { if (!m_stmtStackps.empty()) { AstVarScope* vscp = nodep->varScopep(); if (!vscp) nodep->v3fatalSrc("Not linked"); if (!nodep->varp()->isConst()) { // Constant lookups can be ignored // --- // NOTE: Formerly at this location we would avoid // splitting or reordering if the variable is public. // // However, it should be perfectly safe to split an // always block containing a public variable. // Neither operation should perturb PLI's view of // the variable. // // Former code: // // if (nodep->varp()->isSigPublic()) { // // Public signals shouldn't be changed, // // pli code might be messing with them // scoreboardPli(nodep); // } // --- // Create vertexes for variable if (!vscp->user1p()) { SplitVarStdVertex* vstdp = new SplitVarStdVertex(&m_graph, vscp); vscp->user1p(vstdp); } SplitVarStdVertex* vstdp = (SplitVarStdVertex*) vscp->user1p(); // SPEEDUP: We add duplicate edges, that should be fixed if (m_inDly && nodep->lvalue()) { UINFO(4," VARREFDLY: "<<nodep<<endl); // Delayed variable is different from non-delayed variable if (!vscp->user2p()) { SplitVarPostVertex* vpostp = new SplitVarPostVertex(&m_graph, vscp); vscp->user2p(vpostp); new SplitPostEdge(&m_graph, vstdp, vpostp); } SplitVarPostVertex* vpostp = (SplitVarPostVertex*)vscp->user2p(); // Add edges for (VStack::iterator it = m_stmtStackps.begin(); it != m_stmtStackps.end(); ++it) { new SplitLVEdge(&m_graph, vpostp, *it); } } else { // Nondelayed assignment if (nodep->lvalue()) { // Non-delay; need to maintain existing ordering with all consumers of the signal UINFO(4," VARREFLV: "<<nodep<<endl); for (VStack::iterator it = m_stmtStackps.begin(); it != m_stmtStackps.end(); ++it) { new SplitLVEdge(&m_graph, vstdp, *it); } } else { UINFO(4," VARREF: "<<nodep<<endl); makeRvalueEdges(vstdp); } } } } }
void scoreboardPli(AstNode* nodep) { // Order all PLI statements with other PLI statements // This ensures $display's and such remain in proper order // We don't prevent splitting out other non-pli statements, however. if (!m_pliVertexp) { m_pliVertexp = new SplitPliVertex(&m_graph, nodep); // m_graph.clear() will delete it } for (VStack::iterator it = m_stmtStackps.begin(); it != m_stmtStackps.end(); ++it) { // Both ways... new SplitScorebdEdge(&m_graph, *it, m_pliVertexp); new SplitScorebdEdge(&m_graph, m_pliVertexp, *it); } }
void scoreboardPushStmt(AstNode* nodep) { //UINFO(9," push "<<nodep<<endl); SplitLogicVertex* vertexp = new SplitLogicVertex(&m_graph, nodep); m_stmtStackps.push_back(vertexp); if (nodep->user3p()) nodep->v3fatalSrc("user3p should not be used; cleared in processBlock"); nodep->user3p(vertexp); }
//-------------------- // Default virtual void visit(AstNode* nodep) { // **** SPECIAL default type that sets PLI_ORDERING if (!m_stmtStackps.empty() && !nodep->isPure()) { UINFO(9," NotSplittable "<<nodep<<endl); scoreboardPli(nodep); } iterateChildren(nodep); }
void scoreboardClear() { //VV***** We reset user1p() and user2p on each block!!! m_inDly = false; m_graph.clear(); m_stmtStackps.clear(); m_pliVertexp = NULL; m_noReorderWhy = ""; AstNode::user1ClearTree(); AstNode::user2ClearTree(); AstNode::user3ClearTree(); AstNode::user4ClearTree(); }
virtual void visit(AstVarRef* nodep, AstNUser*) { if (!m_stmtStackps.empty()) { AstVarScope* vscp = nodep->varScopep(); if (!vscp) nodep->v3fatalSrc("Not linked"); if (!nodep->varp()->isConst()) { // Constant lookups can be ignored if (nodep->varp()->isSigPublic()) { // Public signals shouldn't be changed, pli code might be messing with them scoreboardPli(); } // Create vertexes for variable if (!vscp->user1p()) { SplitVarStdVertex* vstdp = new SplitVarStdVertex(&m_graph, vscp); vscp->user1p(vstdp); } SplitVarStdVertex* vstdp = (SplitVarStdVertex*) vscp->user1p(); // SPEEDUP: We add duplicate edges, that should be fixed if (m_inDly && nodep->lvalue()) { UINFO(4," VARREFDLY: "<<nodep<<endl); // Delayed variable is different from non-delayed variable if (!vscp->user2p()) { SplitVarPostVertex* vpostp = new SplitVarPostVertex(&m_graph, vscp); vscp->user2p(vpostp); new SplitPostEdge(&m_graph, vstdp, vpostp); } SplitVarPostVertex* vpostp = (SplitVarPostVertex*)vscp->user2p(); // Add edges for (VStack::iterator it = m_stmtStackps.begin(); it != m_stmtStackps.end(); ++it) { new SplitLVEdge(&m_graph, vpostp, *it); } } else { // Nondelayed assignment if (nodep->lvalue()) { // Non-delay; need to maintain existing ordering with all consumers of the signal UINFO(4," VARREFLV: "<<nodep<<endl); for (VStack::iterator it = m_stmtStackps.begin(); it != m_stmtStackps.end(); ++it) { new SplitLVEdge(&m_graph, vstdp, *it); } } else { UINFO(4," VARREF: "<<nodep<<endl); for (VStack::iterator it = m_stmtStackps.begin(); it != m_stmtStackps.end(); ++it) { new SplitRVEdge(&m_graph, *it, vstdp); } } } } } }
void scoreboardPopStmt() { //UINFO(9," pop"<<endl); if (m_stmtStackps.empty()) v3fatalSrc("Stack underflow"); m_stmtStackps.pop_back(); }