/**Function************************************************************* Synopsis [Verify one useful property.] Description [This procedure verifies one useful property. After the FRAIG construction with choice nodes is over, each primary node should have fanins that are primary nodes. The primary nodes is the one that does not have pNode->pRepr set to point to another node.] SideEffects [] SeeAlso [] ***********************************************************************/ int Map_ManCheckConsistency( Map_Man_t * p ) { Map_Node_t * pNode; Map_NodeVec_t * pVec; int i; pVec = Map_MappingDfs( p, 0 ); for ( i = 0; i < pVec->nSize; i++ ) { pNode = pVec->pArray[i]; if ( Map_NodeIsVar(pNode) ) { if ( pNode->pRepr ) printf( "Primary input %d is a secondary node.\n", pNode->Num ); } else if ( Map_NodeIsConst(pNode) ) { if ( pNode->pRepr ) printf( "Constant 1 %d is a secondary node.\n", pNode->Num ); } else { if ( pNode->pRepr ) printf( "Internal node %d is a secondary node.\n", pNode->Num ); if ( Map_Regular(pNode->p1)->pRepr ) printf( "Internal node %d has first fanin that is a secondary node.\n", pNode->Num ); if ( Map_Regular(pNode->p2)->pRepr ) printf( "Internal node %d has second fanin that is a secondary node.\n", pNode->Num ); } } Map_NodeVecFree( pVec ); return 1; }
/**Function************************************************************* Synopsis [Computes the array of mapping.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ float Map_MappingGetSwitching( Map_Man_t * pMan, Map_NodeVec_t * vMapping ) { Map_Node_t * pNode; float Switch; int i; Switch = 0.0; for ( i = 0; i < vMapping->nSize; i++ ) { pNode = vMapping->pArray[i]; // at least one phase has the best cut assigned assert( pNode->pCutBest[0] != NULL || pNode->pCutBest[1] != NULL ); // at least one phase is used in the mapping assert( pNode->nRefAct[0] > 0 || pNode->nRefAct[1] > 0 ); // compute the array due to the supergate if ( Map_NodeIsAnd(pNode) ) { // count switching of the negative phase if ( pNode->pCutBest[0] && (pNode->nRefAct[0] > 0 || pNode->pCutBest[1] == NULL) ) Switch += pNode->Switching; // count switching of the positive phase if ( pNode->pCutBest[1] && (pNode->nRefAct[1] > 0 || pNode->pCutBest[0] == NULL) ) Switch += pNode->Switching; } // count switching of the interver if we need to implement one phase with another phase if ( (pNode->pCutBest[0] == NULL && pNode->nRefAct[0] > 0) || (pNode->pCutBest[1] == NULL && pNode->nRefAct[1] > 0) ) Switch += pNode->Switching; // inverter switches the same as the node } // add buffers for each CO driven by a CI for ( i = 0; i < pMan->nOutputs; i++ ) if ( Map_NodeIsVar(pMan->pOutputs[i]) && !Map_IsComplement(pMan->pOutputs[i]) ) Switch += pMan->pOutputs[i]->Switching; return Switch; }
/**Function************************************************************* Synopsis [Recursively computes the DFS ordering of the nodes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Map_MappingDfsMarked2_rec( Map_Node_t * pNode, Map_NodeVec_t * vNodes, Map_NodeVec_t * vBoundary, int fFirst ) { assert( !Map_IsComplement(pNode) ); if ( pNode->fMark1 ) return; if ( pNode->fMark0 || Map_NodeIsVar(pNode) ) { pNode->fMark1 = 1; Map_NodeVecPush(vBoundary, pNode); return; } // visit the transitive fanin if ( Map_NodeIsAnd(pNode) ) { Map_MappingDfsMarked2_rec( Map_Regular(pNode->p1), vNodes, vBoundary, 0 ); Map_MappingDfsMarked2_rec( Map_Regular(pNode->p2), vNodes, vBoundary, 0 ); } // visit the equivalent nodes if ( !fFirst && pNode->pNextE ) Map_MappingDfsMarked2_rec( pNode->pNextE, vNodes, vBoundary, 0 ); // make sure the node is not visited through the equivalent nodes assert( pNode->fMark1 == 0 ); // mark the node as visited pNode->fMark1 = 1; // add the node to the list Map_NodeVecPush( vNodes, pNode ); }
/**Function************************************************************* Synopsis [Computes the array of mapping.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ float Map_MappingGetArea( Map_Man_t * pMan ) { Map_Node_t * pNode; float Area = 0.0; int i; if ( pMan->fUseProfile ) Mio_LibraryCleanProfile2( pMan->pSuperLib->pGenlib ); for ( i = 0; i < pMan->vMapObjs->nSize; i++ ) { pNode = pMan->vMapObjs->pArray[i]; if ( pNode->nRefAct[2] == 0 ) continue; if ( Map_NodeIsBuf(pNode) ) continue; // at least one phase has the best cut assigned assert( pNode->pCutBest[0] != NULL || pNode->pCutBest[1] != NULL ); // at least one phase is used in the mapping assert( pNode->nRefAct[0] > 0 || pNode->nRefAct[1] > 0 ); // compute the array due to the supergate if ( Map_NodeIsAnd(pNode) ) { // count area of the negative phase if ( pNode->pCutBest[0] && (pNode->nRefAct[0] > 0 || pNode->pCutBest[1] == NULL) ) { Area += pNode->pCutBest[0]->M[0].pSuperBest->Area; if ( pMan->fUseProfile ) Mio_GateIncProfile2( pNode->pCutBest[0]->M[0].pSuperBest->pRoot ); } // count area of the positive phase if ( pNode->pCutBest[1] && (pNode->nRefAct[1] > 0 || pNode->pCutBest[0] == NULL) ) { Area += pNode->pCutBest[1]->M[1].pSuperBest->Area; if ( pMan->fUseProfile ) Mio_GateIncProfile2( pNode->pCutBest[1]->M[1].pSuperBest->pRoot ); } } // count area of the interver if we need to implement one phase with another phase if ( (pNode->pCutBest[0] == NULL && pNode->nRefAct[0] > 0) || (pNode->pCutBest[1] == NULL && pNode->nRefAct[1] > 0) ) Area += pMan->pSuperLib->AreaInv; } // add buffers for each CO driven by a CI for ( i = 0; i < pMan->nOutputs; i++ ) if ( Map_NodeIsVar(pMan->pOutputs[i]) && !Map_IsComplement(pMan->pOutputs[i]) ) Area += pMan->pSuperLib->AreaBuf; return Area; }
/**Function************************************************************* Synopsis [Computes actual reference counters.] Description [Collects the nodes used in the mapping in array pMan->vMapping. Nodes are collected in reverse topological order to facilitate the computation of required times.] SideEffects [] SeeAlso [] ***********************************************************************/ void Map_MappingSetRefs_rec( Map_Man_t * pMan, Map_Node_t * pNode ) { Map_Cut_t * pCut; Map_Node_t * pNodeR; unsigned uPhase; int i, fPhase, fInvPin; // get the regular node and its phase pNodeR = Map_Regular(pNode); fPhase = !Map_IsComplement(pNode); pNodeR->nRefAct[2]++; // quit if the node was already visited in this phase if ( pNodeR->nRefAct[fPhase]++ ) return; // quit if this is a PI node if ( Map_NodeIsVar(pNodeR) ) return; // propagate through buffer if ( Map_NodeIsBuf(pNodeR) ) { Map_MappingSetRefs_rec( pMan, Map_NotCond(pNodeR->p1, Map_IsComplement(pNode)) ); return; } assert( Map_NodeIsAnd(pNode) ); // get the cut implementing this or opposite polarity pCut = pNodeR->pCutBest[fPhase]; if ( pCut == NULL ) { fPhase = !fPhase; pCut = pNodeR->pCutBest[fPhase]; } if ( pMan->fUseProfile ) Mio_GateIncProfile2( pCut->M[fPhase].pSuperBest->pRoot ); // visit the transitive fanin uPhase = pCut->M[fPhase].uPhaseBest; for ( i = 0; i < pCut->nLeaves; i++ ) { fInvPin = ((uPhase & (1 << i)) > 0); Map_MappingSetRefs_rec( pMan, Map_NotCond(pCut->ppLeaves[i], fInvPin) ); } }