/**CFile**************************************************************** FileName [mapperSwitch.c] PackageName [MVSIS 1.3: Multi-valued logic synthesis system.] Synopsis [Generic technology mapping engine.] Author [MVSIS Group] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - September 8, 2003.] Revision [$Id: mapperSwitch.h,v 1.0 2003/09/08 00:00:00 alanmi Exp $] ***********************************************************************/ #include "mapperInt.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// static float Map_SwitchCutRefDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, int fReference ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**function************************************************************* synopsis [Computes the exact area associated with the cut.] description [] sideeffects [] seealso [] ***********************************************************************/ float Map_SwitchCutGetDerefed( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase ) { float aResult, aResult2; // assert( pNode->Switching > 0 ); aResult2 = Map_SwitchCutRefDeref( pNode, pCut, fPhase, 1 ); // reference aResult = Map_SwitchCutRefDeref( pNode, pCut, fPhase, 0 ); // dereference // assert( aResult == aResult2 ); return aResult; } /**function************************************************************* synopsis [References the cut.] description [] sideeffects [] seealso [] ***********************************************************************/ float Map_SwitchCutRef( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase ) { return Map_SwitchCutRefDeref( pNode, pCut, fPhase, 1 ); // reference } /**function************************************************************* synopsis [References the cut.] description [] sideeffects [] seealso [] ***********************************************************************/ float Map_SwitchCutDeref( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase ) { return Map_SwitchCutRefDeref( pNode, pCut, fPhase, 0 ); // dereference } /**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; } /**Function************************************************************* Synopsis [Computes the array of mapping.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ float Map_MappingGetSwitching( Map_Man_t * pMan ) { Map_Node_t * pNode; float Switch = 0.0; int i; for ( i = 0; i < pMan->vMapObjs->nSize; i++ ) { pNode = pMan->vMapObjs->pArray[i]; if ( pNode->nRefAct[2] == 0 ) 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 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; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END