From f936cc0680c98ffe51b3a1716c996072d5dbf76c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 18 Jan 2009 08:01:00 -0800 Subject: Version abc90118 --- src/aig/mfx/mfx.h | 1 + src/aig/mfx/mfxCore.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++--- src/aig/mfx/mfxInt.h | 3 +++ src/aig/mfx/mfxMan.c | 2 ++ src/aig/mfx/mfxResub.c | 36 ++++++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 3 deletions(-) (limited to 'src/aig/mfx') diff --git a/src/aig/mfx/mfx.h b/src/aig/mfx/mfx.h index 783de56c..aae9e625 100644 --- a/src/aig/mfx/mfx.h +++ b/src/aig/mfx/mfx.h @@ -53,6 +53,7 @@ struct Mfx_Par_t_ int fMoreEffort; // performs high-affort minimization int fSwapEdge; // performs edge swapping int fDelay; // performs optimization for delay + int fPower; // performs power-aware optimization int fVerbose; // enable basic stats int fVeryVerbose; // enable detailed stats }; diff --git a/src/aig/mfx/mfxCore.c b/src/aig/mfx/mfxCore.c index d9f73c9d..f67fb520 100644 --- a/src/aig/mfx/mfxCore.c +++ b/src/aig/mfx/mfxCore.c @@ -53,6 +53,7 @@ void Mfx_ParsDefault( Mfx_Par_t * pPars ) pPars->fArea = 0; pPars->fMoreEffort = 0; pPars->fSwapEdge = 0; + pPars->fPower = 0; pPars->fVerbose = 0; pPars->fVeryVerbose = 0; } @@ -105,7 +106,9 @@ clk = clock(); return 1; } // solve the SAT problem - if ( p->pPars->fSwapEdge ) + if ( p->pPars->fPower ) + Mfx_EdgePower( p, pNode ); + else if ( p->pPars->fSwapEdge ) Mfx_EdgeSwapEval( p, pNode ); else { @@ -132,7 +135,7 @@ int Mfx_Node( Mfx_Man_t * p, Nwk_Obj_t * pNode ) { Hop_Obj_t * pObj; int RetValue; - + float dProb; int nGain, clk; p->nNodesTried++; // prepare data structure for this node @@ -170,7 +173,8 @@ p->timeSat += clock() - clk; } // minimize the local function of the node using bi-decomposition assert( p->nFanins == Nwk_ObjFaninNum(pNode) ); - pObj = Nwk_NodeIfNodeResyn( p->pManDec, pNode->pMan->pManHop, pNode->pFunc, p->nFanins, p->vTruth, p->uCare ); + dProb = p->pPars->fPower? ((float *)p->vProbs->pArray)[pNode->Id] : -1.0; + pObj = Nwk_NodeIfNodeResyn( p->pManDec, pNode->pMan->pManHop, pNode->pFunc, p->nFanins, p->vTruth, p->uCare, dProb ); nGain = Hop_DagSize(pNode->pFunc) - Hop_DagSize(pObj); if ( nGain >= 0 ) { @@ -182,6 +186,45 @@ p->timeSat += clock() - clk; return 1; } +/**Function************************************************************* + + Synopsis [Marks nodes for power-optimization.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Nwk_ManPowerEstimate( Nwk_Man_t * pNtk, int fProbOne ) +{ + extern Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne ); + Vec_Int_t * vProbs; + Vec_Int_t * vSwitching; + float * pProbability; + float * pSwitching; + Aig_Man_t * pAig; + Aig_Obj_t * pObjAig; + Nwk_Obj_t * pObjAbc; + int i; + // start the resulting array + vProbs = Vec_IntStart( Nwk_ManObjNumMax(pNtk) ); + pProbability = (float *)vProbs->pArray; + // map network into an AIG + pAig = Nwk_ManStrash( pNtk ); + vSwitching = Saig_ManComputeSwitchProbs( pAig, 48, 16, fProbOne ); + pSwitching = (float *)vSwitching->pArray; + Nwk_ManForEachObj( pNtk, pObjAbc, i ) + { + if ( (pObjAig = Aig_Regular(pObjAbc->pCopy)) ) + pProbability[pObjAbc->Id] = pSwitching[pObjAig->Id]; + } + Vec_IntFree( vSwitching ); + Aig_ManStop( pAig ); + return vProbs; +} + /**Function************************************************************* Synopsis [] @@ -253,6 +296,17 @@ int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars, If_Lib_t * pLutLib ) p->pManDec = Bdc_ManAlloc( pDecPars ); } + // precomputer power-aware metrics + if ( pPars->fPower ) + { + extern Vec_Int_t * Nwk_ManPowerEstimate( Nwk_Man_t * pNtk, int fProbOne ); + if ( pPars->fResub ) + p->vProbs = Nwk_ManPowerEstimate( pNtk, 0 ); + else + p->vProbs = Nwk_ManPowerEstimate( pNtk, 1 ); + printf( "Total switching before = %7.2f.\n", Nwl_ManComputeTotalSwitching(pNtk) ); + } + // compute don't-cares for each node nNodes = 0; p->nTotalNodesBeg = nTotalNodesBeg; @@ -276,6 +330,7 @@ int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars, If_Lib_t * pLutLib ) { pProgress = Bar_ProgressStart( stdout, Nwk_ManNodeNum(pNtk) ); vLevels = Nwk_ManLevelize( pNtk ); + Vec_VecForEachLevelStart( vLevels, vNodes, k, 1 ) { if ( !p->pPars->fVeryVerbose ) @@ -303,6 +358,7 @@ int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars, If_Lib_t * pLutLib ) PRT( "Time", clock() - clk2 ); } } + Bar_ProgressStop( pProgress ); Vec_VecFree( vLevels ); } @@ -312,6 +368,9 @@ int Mfx_Perform( Nwk_Man_t * pNtk, Mfx_Par_t * pPars, If_Lib_t * pLutLib ) assert( Nwk_ManVerifyLevel( pNtk ) ); assert( Nwk_ManVerifyTiming( pNtk ) ); + if ( pPars->fPower ) + printf( "Total switching after = %7.2f.\n", Nwl_ManComputeTotalSwitching(pNtk) ); + // free the manager p->timeTotal = clock() - clk; Mfx_ManStop( p ); diff --git a/src/aig/mfx/mfxInt.h b/src/aig/mfx/mfxInt.h index 0693200d..9095c8ce 100644 --- a/src/aig/mfx/mfxInt.h +++ b/src/aig/mfx/mfxInt.h @@ -81,6 +81,8 @@ struct Mfx_Man_t_ Vec_Ptr_t * vFanins; // the new set of fanins int nTotConfLim; // total conflict limit int nTotConfLevel; // total conflicts on this level + // switching activity + Vec_Int_t * vProbs; // the result of solving int nFanins; // the number of fanins int nWords; // the number of words @@ -136,6 +138,7 @@ extern void Mfx_ManStop( Mfx_Man_t * p ); extern void Mfx_ManClean( Mfx_Man_t * p ); /*=== mfxResub.c ==========================================================*/ extern void Mfx_PrintResubStats( Mfx_Man_t * p ); +extern int Mfx_EdgePower( Mfx_Man_t * p, Nwk_Obj_t * pNode ); extern int Mfx_EdgeSwapEval( Mfx_Man_t * p, Nwk_Obj_t * pNode ); extern int Mfx_ResubNode( Mfx_Man_t * p, Nwk_Obj_t * pNode ); extern int Mfx_ResubNode2( Mfx_Man_t * p, Nwk_Obj_t * pNode ); diff --git a/src/aig/mfx/mfxMan.c b/src/aig/mfx/mfxMan.c index 63531770..b8361a20 100644 --- a/src/aig/mfx/mfxMan.c +++ b/src/aig/mfx/mfxMan.c @@ -168,6 +168,8 @@ void Mfx_ManStop( Mfx_Man_t * p ) Aig_ManStop( p->pCare ); if ( p->vSuppsInv ) Vec_VecFree( (Vec_Vec_t *)p->vSuppsInv ); + if ( p->vProbs ) + Vec_IntFree( p->vProbs ); Mfx_ManClean( p ); Int_ManFree( p->pMan ); Vec_IntFree( p->vMem ); diff --git a/src/aig/mfx/mfxResub.c b/src/aig/mfx/mfxResub.c index 006656ee..312ae226 100644 --- a/src/aig/mfx/mfxResub.c +++ b/src/aig/mfx/mfxResub.c @@ -206,6 +206,8 @@ p->timeInt += clock() - clk; iVar = -1; while ( 1 ) { + float * pProbab = (float *)(p->vProbs? p->vProbs->pArray : NULL); + assert( (pProbab != NULL) == p->pPars->fPower ); if ( fVeryVerbose ) { printf( "%3d: %2d ", p->nCexes, iVar ); @@ -222,6 +224,13 @@ p->timeInt += clock() - clk; assert( nWords <= p->nDivWords ); for ( iVar = 0; iVar < Vec_PtrSize(p->vDivs)-Nwk_ObjFaninNum(pNode); iVar++ ) { + if ( p->pPars->fPower ) + { + Nwk_Obj_t * pDiv = Vec_PtrEntry(p->vDivs, iVar); + // only accept the divisor if it is "cool" + if ( pProbab[Nwk_ObjId(pDiv)] >= 0.2 ) + continue; + } pData = Vec_PtrEntry( p->vDivCexes, iVar ); for ( w = 0; w < nWords; w++ ) if ( pData[w] != ~0 ) @@ -429,6 +438,33 @@ int Mfx_EdgeSwapEval( Mfx_Man_t * p, Nwk_Obj_t * pNode ) return 0; } +/**Function************************************************************* + + Synopsis [Evaluates the possibility of replacing given edge by another edge.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mfx_EdgePower( Mfx_Man_t * p, Nwk_Obj_t * pNode ) +{ + Nwk_Obj_t * pFanin; + float * pProbab = (float *)p->vProbs->pArray; + int i; + // try replacing area critical fanins + Nwk_ObjForEachFanin( pNode, pFanin, i ) + if ( pProbab[pFanin->Id] >= 0.4 ) + { + if ( Mfx_SolveSatResub( p, pNode, i, 0, 0 ) ) + return 1; + } + return 0; +} + + /**Function************************************************************* Synopsis [Performs resubstitution for the node.] -- cgit v1.2.3