/**function************************************************************* synopsis [References or dereferences the cut.] description [This reference part is similar to Cudd_NodeReclaim(). The dereference part is similar to Cudd_RecursiveDeref().] sideeffects [] seealso [] ***********************************************************************/ float Map_CutRefDeref( Map_Cut_t * pCut, int fPhase, int fReference, int fUpdateProf ) { Map_Node_t * pNodeChild; Map_Cut_t * pCutChild; float aArea; int i, fPhaseChild; // int nRefs; // consider the elementary variable if ( pCut->nLeaves == 1 ) return 0; // start the area of this cut aArea = Map_CutGetRootArea( pCut, fPhase ); if ( fUpdateProf ) { if ( fReference ) Mio_GateIncProfile2( pCut->M[fPhase].pSuperBest->pRoot ); else Mio_GateDecProfile2( pCut->M[fPhase].pSuperBest->pRoot ); } // go through the children for ( i = 0; i < pCut->nLeaves; i++ ) { pNodeChild = pCut->ppLeaves[i]; fPhaseChild = Map_CutGetLeafPhase( pCut, fPhase, i ); // get the reference counter of the child /* // this code does not take inverters into account // the quality of area recovery seems to always be a little worse if ( fReference ) nRefs = Map_NodeIncRefPhaseAct( pNodeChild, fPhaseChild ); else nRefs = Map_NodeDecRefPhaseAct( pNodeChild, fPhaseChild ); assert( nRefs >= 0 ); // skip if the child was already reference before if ( nRefs > 0 ) continue; */ if ( fReference ) { if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present { // if this phase of the node is referenced, there is no recursive call pNodeChild->nRefAct[2]++; if ( pNodeChild->nRefAct[fPhaseChild]++ > 0 ) continue; } else // only one phase is present { // inverter should be added if the phase // (a) has no reference and (b) is implemented using other phase if ( pNodeChild->nRefAct[fPhaseChild]++ == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL ) aArea += pNodeChild->p->pSuperLib->AreaInv; // if the node is referenced, there is no recursive call if ( pNodeChild->nRefAct[2]++ > 0 ) continue; } } else { if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present { // if this phase of the node is referenced, there is no recursive call --pNodeChild->nRefAct[2]; if ( --pNodeChild->nRefAct[fPhaseChild] > 0 ) continue; } else // only one phase is present { // inverter should be added if the phase // (a) has no reference and (b) is implemented using other phase if ( --pNodeChild->nRefAct[fPhaseChild] == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL ) aArea += pNodeChild->p->pSuperLib->AreaInv; // if the node is referenced, there is no recursive call if ( --pNodeChild->nRefAct[2] > 0 ) continue; } assert( pNodeChild->nRefAct[fPhaseChild] >= 0 ); } // get the child cut pCutChild = pNodeChild->pCutBest[fPhaseChild]; // if the child does not have this phase mapped, take the opposite phase if ( pCutChild == NULL ) { fPhaseChild = !fPhaseChild; pCutChild = pNodeChild->pCutBest[fPhaseChild]; } // reference and compute area recursively aArea += Map_CutRefDeref( pCutChild, fPhaseChild, fReference, fUpdateProf ); } return aArea; }
/**function************************************************************* synopsis [References or dereferences the cut.] description [This reference part is similar to Cudd_NodeReclaim(). The dereference part is similar to Cudd_RecursiveDeref().] sideeffects [] seealso [] ***********************************************************************/ float Map_SwitchCutRefDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, int fReference ) { Map_Node_t * pNodeChild; Map_Cut_t * pCutChild; float aSwitchActivity; int i, fPhaseChild; // start switching activity for the node aSwitchActivity = pNode->Switching; // consider the elementary variable if ( pCut->nLeaves == 1 ) return aSwitchActivity; // go through the children assert( pCut->M[fPhase].pSuperBest ); for ( i = 0; i < pCut->nLeaves; i++ ) { pNodeChild = pCut->ppLeaves[i]; fPhaseChild = Map_CutGetLeafPhase( pCut, fPhase, i ); // get the reference counter of the child if ( fReference ) { if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present { // if this phase of the node is referenced, there is no recursive call pNodeChild->nRefAct[2]++; if ( pNodeChild->nRefAct[fPhaseChild]++ > 0 ) continue; } else // only one phase is present { // inverter should be added if the phase // (a) has no reference and (b) is implemented using other phase if ( pNodeChild->nRefAct[fPhaseChild]++ == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL ) aSwitchActivity += pNodeChild->Switching; // inverter switches the same as the node // if the node is referenced, there is no recursive call if ( pNodeChild->nRefAct[2]++ > 0 ) continue; } } else { if ( pNodeChild->pCutBest[0] && pNodeChild->pCutBest[1] ) // both phases are present { // if this phase of the node is referenced, there is no recursive call --pNodeChild->nRefAct[2]; if ( --pNodeChild->nRefAct[fPhaseChild] > 0 ) continue; } else // only one phase is present { // inverter should be added if the phase // (a) has no reference and (b) is implemented using other phase if ( --pNodeChild->nRefAct[fPhaseChild] == 0 && pNodeChild->pCutBest[fPhaseChild] == NULL ) aSwitchActivity += pNodeChild->Switching; // inverter switches the same as the node // if the node is referenced, there is no recursive call if ( --pNodeChild->nRefAct[2] > 0 ) continue; } assert( pNodeChild->nRefAct[fPhaseChild] >= 0 ); } // get the child cut pCutChild = pNodeChild->pCutBest[fPhaseChild]; // if the child does not have this phase mapped, take the opposite phase if ( pCutChild == NULL ) { fPhaseChild = !fPhaseChild; pCutChild = pNodeChild->pCutBest[fPhaseChild]; } // reference and compute area recursively aSwitchActivity += Map_SwitchCutRefDeref( pNodeChild, pCutChild, fPhaseChild, fReference ); } return aSwitchActivity; }