/**CFile**************************************************************** FileName [giaSopb.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Scalable AIG package.] Synopsis [SOP balancing for a window.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: giaSopb.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "gia.h" #include "base/main/main.h" #include "base/cmd/cmd.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManHighlight_rec( Gia_Man_t * p, int iObj ) { Gia_Obj_t * pObj; if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) return; Gia_ObjSetTravIdCurrentId(p, iObj); pObj = Gia_ManObj( p, iObj ); if ( Gia_ObjIsAnd(pObj) ) Gia_ManHighlight_rec( p, Gia_ObjFaninId0(pObj, iObj) ); if ( Gia_ObjIsAnd(pObj) ) Gia_ManHighlight_rec( p, Gia_ObjFaninId1(pObj, iObj) ); } void Gia_ManPrepareWin( Gia_Man_t * p, Vec_Int_t * vOuts, Vec_Int_t ** pvPis, Vec_Int_t ** pvPos, Vec_Int_t ** pvAnds, int fPoOnly ) { Gia_Obj_t * pObj; int i; // mark the section Gia_ManIncrementTravId( p ); Gia_ManForEachCoVec( vOuts, p, pObj, i ) Gia_ManHighlight_rec( p, Gia_ObjFaninId0p(p, pObj) ); // mark fanins of the outside area Gia_ManCleanMark0( p ); if ( fPoOnly ) { Gia_ManForEachCoVec( vOuts, p, pObj, i ) Gia_ObjFanin0(pObj)->fMark0 = 1; } else { Gia_ManForEachObj1( p, pObj, i ) { if ( Gia_ObjIsCi(pObj) ) continue; if ( Gia_ObjIsAnd(pObj) && !Gia_ObjIsTravIdCurrentId(p, i) ) continue; Gia_ObjFanin0(pObj)->fMark0 = 1; if ( Gia_ObjIsAnd(pObj) ) Gia_ObjFanin1(pObj)->fMark0 = 1; } } // collect pointed nodes *pvPis = Vec_IntAlloc( 1000 ); *pvPos = Vec_IntAlloc( 1000 ); *pvAnds = Vec_IntAlloc( 1000 ); Gia_ManForEachObj1( p, pObj, i ) { if ( !Gia_ObjIsTravIdCurrentId(p, i) ) continue; if ( Gia_ObjIsCi(pObj) ) Vec_IntPush( *pvPis, i ); else if ( pObj->fMark0 ) Vec_IntPush( *pvPos, i ); if ( Gia_ObjIsAnd(pObj) ) Vec_IntPush( *pvAnds, i ); } Gia_ManCleanMark0( p ); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManExtractWin( Gia_Man_t * p, Vec_Int_t * vOuts, int fPoOnly ) { Vec_Int_t * vPis, * vPos, * vAnds; Gia_Man_t * pNew; Gia_Obj_t * pObj; int i; Gia_ManPrepareWin( p, vOuts, &vPis, &vPos, &vAnds, fPoOnly ); // create AIG pNew = Gia_ManStart( Vec_IntSize(vPis) + Vec_IntSize(vPos) + Vec_IntSize(vAnds) + 1 ); pNew->pName = Abc_UtilStrsav( p->pName ); Gia_ManConst0(p)->Value = 0; Gia_ManForEachObjVec( vPis, p, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); Gia_ManForEachObjVec( vAnds, p, pObj, i ) pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachObjVec( vPos, p, pObj, i ) Gia_ManAppendCo( pNew, pObj->Value ); Vec_IntFree( vPis ); Vec_IntFree( vPos ); Vec_IntFree( vAnds ); return pNew; } Gia_Man_t * Gia_ManInsertWin( Gia_Man_t * p, Vec_Int_t * vOuts, Gia_Man_t * pWin ) { Vec_Int_t * vPos, * vPis, * vAnds; Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i; Gia_ManPrepareWin( p, vOuts, &vPis, &vPos, &vAnds, 0 ); // create AIG pNew = Gia_ManStart( Gia_ManObjNum(p) - Vec_IntSize(vAnds) + Gia_ManAndNum(pWin) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); // inputs Gia_ManConst0(p)->Value = 0; Gia_ManForEachCi( p, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); Gia_ManConst0(pWin)->Value = 0; Gia_ManForEachCi( pWin, pObj, i ) pObj->Value = Gia_ManObj(p, Vec_IntEntry(vPis, i))->Value; // internal nodes Gia_ManHashAlloc( pNew ); Gia_ManForEachAnd( pWin, pObj, i ) pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( pWin, pObj, i ) Gia_ManObj( p, Vec_IntEntry(vPos, i) )->Value = Gia_ObjFanin0Copy(pObj); Gia_ManForEachAnd( p, pObj, i ) if ( !Gia_ObjIsTravIdCurrentId(p, i) ) pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( p, pObj, i ) Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManHashStop( pNew ); // cleanup Vec_IntFree( vPis ); Vec_IntFree( vPos ); Vec_IntFree( vAnds ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); return pNew; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Gia_ManFindLatest( Gia_Man_t * p, int LevelMax, int nTimeWindow ) { Gia_Obj_t * pObj; Vec_Int_t * vOuts; vOuts = Vec_IntAlloc( 1000 ); if ( Gia_ManHasMapping(p) ) { int i, k, iFan, nLevels = 0; int * pLevels = ABC_CALLOC( int, Gia_ManObjNum(p) ); Gia_ManForEachLut( p, i ) { Gia_LutForEachFanin( p, i, iFan, k ) pLevels[i] = Abc_MaxInt( pLevels[i], pLevels[iFan] ); pLevels[i]++; nLevels = Abc_MaxInt( nLevels, pLevels[i] ); } if ( nTimeWindow ) LevelMax = (int)((1.0 - 0.01 * nTimeWindow) * nLevels); if ( nLevels < LevelMax ) printf( "The maximum mapped level (%d) is less than the target level (%d).\n", nLevels, LevelMax ); Gia_ManForEachCo( p, pObj, i ) if ( pLevels[Gia_ObjFaninId0p(p, pObj)] >= LevelMax ) Vec_IntPush( vOuts, i ); ABC_FREE( pLevels ); } else { int i, nLevels = Gia_ManLevelNum( p ); if ( nTimeWindow ) LevelMax = (int)((1.0 - 0.01 * nTimeWindow) * nLevels); if ( nLevels < LevelMax ) printf( "The maximum AIG level (%d) is less than the target level (%d).\n", nLevels, LevelMax ); Gia_ManForEachCo( p, pObj, i ) if ( Gia_ObjLevel(p, pObj) >= LevelMax ) Vec_IntPush( vOuts, i ); } return vOuts; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManExtractWindow( Gia_Man_t * p, int LevelMax, int nTimeWindow, int fVerbose ) { Vec_Int_t * vOuts; Gia_Man_t * pWin; assert( !LevelMax != !nTimeWindow ); vOuts = Gia_ManFindLatest( p, LevelMax, nTimeWindow ); if ( fVerbose ) printf( "Collected %d outputs to extract.\n", Vec_IntSize(vOuts) ); if ( Vec_IntSize(vOuts) == 0 ) { Vec_IntFree( vOuts ); return Gia_ManDup( p ); } pWin = Gia_ManExtractWin( p, vOuts, 1 ); Vec_IntFree( vOuts ); return pWin; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManPerformSopBalanceWin( Gia_Man_t * p, int LevelMax, int nTimeWindow, int nCutNum, int nRelaxRatio, int fVerbose ) { Vec_Int_t * vOuts; Gia_Man_t * pNew, * pWin, * pWinNew; assert( !LevelMax != !nTimeWindow ); vOuts = Gia_ManFindLatest( p, LevelMax, nTimeWindow ); if ( fVerbose ) printf( "Collected %d outputs to extract.\n", Vec_IntSize(vOuts) ); if ( Vec_IntSize(vOuts) == 0 ) { Vec_IntFree( vOuts ); return Gia_ManDup( p ); } pWin = Gia_ManExtractWin( p, vOuts, 0 ); pWinNew = Gia_ManPerformSopBalance( pWin, nCutNum, nRelaxRatio, fVerbose ); Gia_ManStop( pWin ); pNew = Gia_ManInsertWin( p, vOuts, pWinNew ); Gia_ManStop( pWinNew ); Vec_IntFree( vOuts ); return pNew; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManPerformDsdBalanceWin( Gia_Man_t * p, int LevelMax, int nTimeWindow, int nLutSize, int nCutNum, int nRelaxRatio, int fVerbose ) { Vec_Int_t * vOuts; Gia_Man_t * pNew, * pWin, * pWinNew; assert( !LevelMax != !nTimeWindow ); vOuts = Gia_ManFindLatest( p, LevelMax, nTimeWindow ); if ( fVerbose ) printf( "Collected %d outputs to extract.\n", Vec_IntSize(vOuts) ); if ( Vec_IntSize(vOuts) == 0 ) { Vec_IntFree( vOuts ); return Gia_ManDup( p ); } pWin = Gia_ManExtractWin( p, vOuts, 0 ); pWinNew = Gia_ManPerformDsdBalance( pWin, nLutSize, nCutNum, nRelaxRatio, fVerbose ); Gia_ManStop( pWin ); pNew = Gia_ManInsertWin( p, vOuts, pWinNew ); Gia_ManStop( pWinNew ); Vec_IntFree( vOuts ); return pNew; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManPerformMap( int nAnds, int nLutSize, int nCutNum, int fVerbose ) { char Command[200]; sprintf( Command, "&unmap; &lf -K %d -C %d -k; &save", nLutSize, nCutNum ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ); if ( fVerbose ) { printf( "MAPPING:\n" ); printf( "Mapping with &lf -k:\n" ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&ps" ); } sprintf( Command, "&unmap; &lf -K %d -C %d; &save", nLutSize, nCutNum ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ); if ( fVerbose ) { printf( "Mapping with &lf:\n" ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&ps" ); } if ( (nLutSize == 4 && nAnds < 100000) || (nLutSize == 6 && nAnds < 2000) ) { sprintf( Command, "&unmap; &if -sz -S %d%d -K %d -C %d", nLutSize, nLutSize, 2*nLutSize-1, 2*nCutNum ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ); Vec_IntFreeP( &Abc_FrameReadGia(Abc_FrameGetGlobalFrame())->vPacking ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&save" ); if ( fVerbose ) { printf( "Mapping with &if -sz -S %d%d -K %d -C %d:\n", nLutSize, nLutSize, 2*nLutSize-1, 2*nCutNum ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&ps" ); } } Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&load" ); if ( fVerbose ) { printf( "Mapping final:\n" ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&ps" ); } } void Gia_ManPerformRound( int fIsMapped, int nAnds, int nLevels, int nLutSize, int nCutNum, int nRelaxRatio, int fVerbose ) { char Command[200]; // perform AIG-based synthesis if ( nAnds < 50000 ) { Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "" ); sprintf( Command, "&dsdb; &dch -f; &if -K %d -C %d; &save", nLutSize, nCutNum ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ); if ( fVerbose ) { printf( "Mapping with &dch -f; &if -K %d -C %d:\n", nLutSize, nCutNum ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&ps" ); } Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&st" ); } // perform AIG-based synthesis if ( nAnds < 20000 ) { Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "" ); sprintf( Command, "&dsdb; &dch -f; &if -K %d -C %d; &save", nLutSize, nCutNum ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ); if ( fVerbose ) { printf( "Mapping with &dch -f; &if -K %d -C %d:\n", nLutSize, nCutNum ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&ps" ); } Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&st" ); } // perform first round of mapping Gia_ManPerformMap( nAnds, nLutSize, nCutNum, fVerbose ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&st" ); // perform synthesis Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&dsdb" ); // perform second round of mapping Gia_ManPerformMap( nAnds, nLutSize, nCutNum, fVerbose ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&st" ); // perform synthesis Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&syn2 -m -R 10; &dsdb" ); // prepare for final mapping sprintf( Command, "&blut -a -K %d", nLutSize ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ); // perform third round of mapping Gia_ManPerformMap( nAnds, nLutSize, nCutNum, fVerbose ); } void Gia_ManPerformFlow( int fIsMapped, int nAnds, int nLevels, int nLutSize, int nCutNum, int nRelaxRatio, int fVerbose ) { // remove comb equivs if ( fIsMapped ) Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&st" ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&fraig -c" ); // perform first round Gia_ManPerformRound( fIsMapped, nAnds, nLevels, nLutSize, nCutNum, nRelaxRatio, fVerbose ); // perform synthesis Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "&st; &sopb" ); // perform first round Gia_ManPerformRound( fIsMapped, nAnds, nLevels, nLutSize, nCutNum, nRelaxRatio, fVerbose ); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END