diff options
-rw-r--r-- | src/aig/gia/giaFalse.c | 187 | ||||
-rw-r--r-- | src/aig/gia/giaUtil.c | 24 | ||||
-rw-r--r-- | src/base/abci/abc.c | 84 |
3 files changed, 228 insertions, 67 deletions
diff --git a/src/aig/gia/giaFalse.c b/src/aig/gia/giaFalse.c index c4548ef4..c7a5a638 100644 --- a/src/aig/gia/giaFalse.c +++ b/src/aig/gia/giaFalse.c @@ -20,6 +20,7 @@ #include "gia.h" #include "misc/vec/vecQue.h" +#include "misc/vec/vecWec.h" #include "sat/bsat/satStore.h" ABC_NAMESPACE_IMPL_START @@ -35,7 +36,7 @@ ABC_NAMESPACE_IMPL_START /**Function************************************************************* - Synopsis [Compute slacks measured using the number of AIG levels.] + Synopsis [Reconstruct the AIG after detecting false paths.] Description [] @@ -44,17 +45,60 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -Vec_Int_t * Gia_ManComputeSlacks( Gia_Man_t * p ) +void Gia_ManFalseRebuildOne( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vHook, int fVerbose, int fVeryVerbose ) { + Gia_Obj_t * pObj, * pPrev = NULL; + int i, iObjValue, iPrevValue = -1; + if ( fVerbose ) + { + printf( "Eliminating path: " ); + Vec_IntPrint( vHook ); + } + Gia_ManForEachObjVec( vHook, p, pObj, i ) + { + if ( fVeryVerbose ) + Gia_ObjPrint( p, pObj ); + iObjValue = pObj->Value; + pObj->Value = i ? Gia_ManHashAnd(pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj)) : 0; + if ( pPrev ) + pPrev->Value = iPrevValue; + iPrevValue = iObjValue; + pPrev = pObj; + } +} +Gia_Man_t * Gia_ManFalseRebuild( Gia_Man_t * p, Vec_Wec_t * vHooks, int fVerbose, int fVeryVerbose ) +{ + Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; - int i, nLevels = Gia_ManLevelNum( p ); - Vec_Int_t * vLevelR = Gia_ManReverseLevel( p ); - Vec_Int_t * vSlacks = Vec_IntAlloc( Gia_ManObjNum(p) ); - Gia_ManForEachObj( p, pObj, i ) - Vec_IntPush( vSlacks, nLevels - Gia_ObjLevelId(p, i) - Vec_IntEntry(vLevelR, i) ); - assert( Vec_IntSize(vSlacks) == Gia_ManObjNum(p) ); - Vec_IntFree( vLevelR ); - return vSlacks; + int i, Counter = 0; + pNew = Gia_ManStart( 4 * Gia_ManObjNum(p) / 3 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManHashAlloc( pNew ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + { + if ( Vec_WecLevelSize(vHooks, i) > 0 ) + { + if ( fVerbose ) + printf( "Path %d : ", Counter++ ); + Gia_ManFalseRebuildOne( pNew, p, Vec_WecEntry(vHooks, i), fVerbose, fVeryVerbose ); + } + else + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + } + else if ( Gia_ObjIsCi(pObj) ) + pObj->Value = Gia_ManAppendCi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; } /**Function************************************************************* @@ -68,26 +112,25 @@ Vec_Int_t * Gia_ManComputeSlacks( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -void Gia_ManCollectPath_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSlacks, Vec_Int_t * vPath ) +void Gia_ManCollectPath_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPath ) { if ( Gia_ObjIsAnd(pObj) ) { - int Slack = Vec_IntEntry(vSlacks, Gia_ObjId(p, pObj)); - int Slack0 = Vec_IntEntry(vSlacks, Gia_ObjFaninId0p(p, pObj)); - int Slack1 = Vec_IntEntry(vSlacks, Gia_ObjFaninId1p(p, pObj)); - assert( Slack == Slack0 || Slack == Slack1 ); - if ( Slack == Slack0 ) - Gia_ManCollectPath_rec( p, Gia_ObjFanin0(pObj), vSlacks, vPath ); - else - Gia_ManCollectPath_rec( p, Gia_ObjFanin1(pObj), vSlacks, vPath ); + if ( Gia_ObjLevel(p, Gia_ObjFanin0(pObj)) > Gia_ObjLevel(p, Gia_ObjFanin1(pObj)) ) + Gia_ManCollectPath_rec( p, Gia_ObjFanin0(pObj), vPath ); + else if ( Gia_ObjLevel(p, Gia_ObjFanin0(pObj)) < Gia_ObjLevel(p, Gia_ObjFanin1(pObj)) ) + Gia_ManCollectPath_rec( p, Gia_ObjFanin1(pObj), vPath ); +// else if ( rand() & 1 ) +// Gia_ManCollectPath_rec( p, Gia_ObjFanin0(pObj), vPath ); + else + Gia_ManCollectPath_rec( p, Gia_ObjFanin1(pObj), vPath ); } Vec_IntPush( vPath, Gia_ObjId(p, pObj) ); } -Vec_Int_t * Gia_ManCollectPath( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSlacks ) +Vec_Int_t * Gia_ManCollectPath( Gia_Man_t * p, Gia_Obj_t * pObj ) { Vec_Int_t * vPath = Vec_IntAlloc( p->nLevels ); - assert( Gia_ObjIsCo(pObj) ); - Gia_ManCollectPath_rec( p, Gia_ObjFanin0(pObj), vSlacks, vPath ); + Gia_ManCollectPath_rec( p, Gia_ObjFanin0(pObj), vPath ); return vPath; } @@ -102,19 +145,22 @@ Vec_Int_t * Gia_ManCollectPath( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSl SeeAlso [] ***********************************************************************/ -void Gia_ManCheckFalseOne( Gia_Man_t * p, int iOut, int nTimeOut, Vec_Int_t * vSlacks ) +void Gia_ManCheckFalseOne( Gia_Man_t * p, int iOut, int nTimeOut, Vec_Wec_t * vHooks, int fVerbose, int fVeryVerbose ) { sat_solver * pSat; - Gia_Obj_t * pObj = Gia_ManCo( p, iOut ); + Gia_Obj_t * pObj; + Gia_Obj_t * pPivot = Gia_ManCo( p, iOut ); Vec_Int_t * vLits = Vec_IntAlloc( p->nLevels ); - Vec_Int_t * vPath = Gia_ManCollectPath( p, pObj, vSlacks ); - int i, Shift[2], status, nLits, * pLits; + Vec_Int_t * vPath = Gia_ManCollectPath( p, pPivot ); + int nLits = 0, * pLits = NULL; + int i, Shift[2], status; abctime clkStart = Abc_Clock(); // collect objects and assign SAT variables - int iFanin = Gia_ObjFaninId0p( p, pObj ); + int iFanin = Gia_ObjFaninId0p( p, pPivot ); Vec_Int_t * vObjs = Gia_ManCollectNodesCis( p, &iFanin, 1 ); Gia_ManForEachObjVec( vObjs, p, pObj, i ) pObj->Value = Vec_IntSize(vObjs) - 1 - i; + assert( Gia_ObjIsCo(pPivot) ); // create SAT solver pSat = sat_solver_new(); sat_solver_set_runtime_limit( pSat, nTimeOut ? nTimeOut * CLOCKS_PER_SEC + Abc_Clock(): 0 ); @@ -139,74 +185,85 @@ void Gia_ManCheckFalseOne( Gia_Man_t * p, int iOut, int nTimeOut, Vec_Int_t * vS Gia_ObjFanin0(pObj)->Value + Shift[1], Gia_ObjFanin1(pObj)->Value + Shift[1], Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj) ); } - printf( "PO %6d : ", iOut ); // call the SAT solver status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); - if ( status == l_Undef ) - printf( "Timeout reached after %d seconds. ", nTimeOut ); - else if ( status == l_True ) - printf( "There is no false path. " ); - else + if ( status == l_False ) { - assert( status == l_False ); - // call analize_final + int iBeg, iEnd; nLits = sat_solver_final( pSat, &pLits ); - printf( "False path contains %d nodes (out of %d): ", nLits, Vec_IntSize(vLits) ); - printf( "top = %d ", Vec_IntEntry(vPath, Abc_Lit2Var(pLits[0])) ); - for ( i = 0; i < nLits; i++ ) - printf( "%d ", Abc_Lit2Var(pLits[i]) ); - printf( " " ); + iBeg = Abc_Lit2Var(pLits[nLits-1]); + iEnd = Abc_Lit2Var(pLits[0]); + if ( iEnd - iBeg < 20 ) + { + // check if nodes on the path are already used + for ( i = iBeg; i <= iEnd; i++ ) + if ( Vec_WecLevelSize(vHooks, Vec_IntEntry(vPath, i)) > 0 ) + break; + if ( i > iEnd ) + { + Vec_Int_t * vHook = Vec_WecEntry(vHooks, Vec_IntEntry(vPath, iEnd)); + for ( i = iBeg; i <= iEnd; i++ ) + Vec_IntPush( vHook, Vec_IntEntry(vPath, i) ); + } + } + } + if ( fVerbose ) + { + printf( "PO %6d : Level = %3d ", iOut, Gia_ObjLevel(p, pPivot) ); + if ( status == l_Undef ) + printf( "Timeout reached after %d seconds. ", nTimeOut ); + else if ( status == l_True ) + printf( "There is no false path. " ); + else + { + printf( "False path contains %d nodes (out of %d): ", nLits, Vec_IntSize(vLits) ); + printf( "top = %d ", Vec_IntEntry(vPath, Abc_Lit2Var(pLits[0])) ); + if ( fVeryVerbose ) + for ( i = 0; i < nLits; i++ ) + printf( "%d ", Abc_Lit2Var(pLits[i]) ); + printf( " " ); + } + Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart ); } - Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart ); sat_solver_delete( pSat ); Vec_IntFree( vObjs ); Vec_IntFree( vPath ); Vec_IntFree( vLits ); } -void Gia_ManCheckFalse( Gia_Man_t * p, int nSlackMax, int nTimeOut ) +Gia_Man_t * Gia_ManCheckFalse( Gia_Man_t * p, int nSlackMax, int nTimeOut, int fVerbose, int fVeryVerbose ) { + Gia_Man_t * pNew; + Vec_Wec_t * vHooks; Vec_Que_t * vPrio; Vec_Flt_t * vWeights; - Vec_Int_t * vSlacks; Gia_Obj_t * pObj; int i; - vSlacks = Gia_ManComputeSlacks(p); -//Vec_IntPrint( vSlacks ); + srand( 111 ); + Gia_ManLevelNum( p ); // create PO weights vWeights = Vec_FltAlloc( Gia_ManCoNum(p) ); Gia_ManForEachCo( p, pObj, i ) - Vec_FltPush( vWeights, p->nLevels - Vec_IntEntry(vSlacks, Gia_ObjId(p, pObj)) ); + Vec_FltPush( vWeights, Gia_ObjLevel(p, pObj) ); // put POs into the queue vPrio = Vec_QueAlloc( Gia_ManCoNum(p) ); Vec_QueSetPriority( vPrio, Vec_FltArrayP(vWeights) ); Gia_ManForEachCo( p, pObj, i ) Vec_QuePush( vPrio, i ); // work on each PO in the queue + vHooks = Vec_WecStart( Gia_ManObjNum(p) ); while ( Vec_QueTopPriority(vPrio) >= p->nLevels - nSlackMax ) - Gia_ManCheckFalseOne( p, Vec_QuePop(vPrio), nTimeOut, vSlacks ); + Gia_ManCheckFalseOne( p, Vec_QuePop(vPrio), nTimeOut, vHooks, fVerbose, fVeryVerbose ); + if ( fVerbose ) + printf( "Collected %d non-overlapping false paths.\n", Vec_WecSizeUsed(vHooks) ); + // reconstruct the AIG + pNew = Gia_ManFalseRebuild( p, vHooks, fVerbose, fVeryVerbose ); // cleanup - Vec_IntFree( vSlacks ); + Vec_WecFree( vHooks ); Vec_FltFree( vWeights ); Vec_QueFree( vPrio ); + return pNew; } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManCheckFalseTest( Gia_Man_t * p, int nSlackMax ) -{ - Gia_ManCheckFalse( p, nSlackMax, 0 ); -} - - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index f3edca36..34bda9bb 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -621,6 +621,30 @@ Vec_Int_t * Gia_ManRequiredLevel( Gia_Man_t * p ) /**Function************************************************************* + Synopsis [Compute slacks measured using the number of AIG levels.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManComputeSlacks( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i, nLevels = Gia_ManLevelNum( p ); + Vec_Int_t * vLevelR = Gia_ManReverseLevel( p ); + Vec_Int_t * vSlacks = Vec_IntAlloc( Gia_ManObjNum(p) ); + Gia_ManForEachObj( p, pObj, i ) + Vec_IntPush( vSlacks, nLevels - Gia_ObjLevelId(p, i) - Vec_IntEntry(vLevelR, i) ); + assert( Vec_IntSize(vSlacks) == Gia_ManObjNum(p) ); + Vec_IntFree( vLevelR ); + return vSlacks; +} + +/**Function************************************************************* + Synopsis [Assigns levels.] Description [] diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 3da41636..0681f28e 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -355,6 +355,7 @@ static int Abc_CommandAbc9Balance ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9Syn2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Syn3 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Syn4 ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9False ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Miter ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Miter2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Append ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -920,6 +921,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&syn2", Abc_CommandAbc9Syn2, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&syn3", Abc_CommandAbc9Syn3, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&syn4", Abc_CommandAbc9Syn4, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&false", Abc_CommandAbc9False, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&miter", Abc_CommandAbc9Miter, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&miter2", Abc_CommandAbc9Miter2, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&append", Abc_CommandAbc9Append, 0 ); @@ -27790,6 +27792,84 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandAbc9False( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Gia_ManCheckFalse( Gia_Man_t * p, int nSlackMax, int nTimeOut, int fVerbose, int fVeryVerbose ); + Gia_Man_t * pTemp; + int nSlackMax = 0; + int nTimeOut = 0; + int c, fVerbose = 0; + int fVeryVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "STvwh" ) ) != EOF ) + { + switch ( c ) + { + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by a char string.\n" ); + goto usage; + } + nSlackMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nSlackMax < 0 ) + goto usage; + break; + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by a char string.\n" ); + goto usage; + } + nTimeOut = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nTimeOut < 0 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'w': + fVeryVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9False(): There is no AIG.\n" ); + return 1; + } + pTemp = Gia_ManCheckFalse( pAbc->pGia, nSlackMax, nTimeOut, fVerbose, fVeryVerbose ); + Abc_FrameUpdateGia( pAbc, pTemp ); + return 0; + +usage: + Abc_Print( -2, "usage: &false [-ST num] [-vwh]\n" ); + Abc_Print( -2, "\t detecting and elimintation false paths\n" ); + Abc_Print( -2, "\t-S num : maximum slack to idetify false paths [default = %d]\n", nSlackMax ); + Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", nTimeOut ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing additional information [default = %s]\n", fVeryVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandAbc9Miter( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pFile; @@ -34003,7 +34083,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // extern Gia_Man_t * Llb_ReachableStatesGia( Gia_Man_t * p ); // extern Gia_Man_t * Unm_ManTest( Gia_Man_t * pGia ); // extern void Agi_ManTest( Gia_Man_t * pGia ); - extern void Gia_ManCheckFalseTest( Gia_Man_t * p, int nSlackMax ); +// extern void Gia_ManCheckFalseTest( Gia_Man_t * p, int nSlackMax ); Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "Fsvh" ) ) != EOF ) @@ -34083,7 +34163,7 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Agi_ManTest( pAbc->pGia ); // Gia_ManResubTest( pAbc->pGia ); // Jf_ManTestCnf( pAbc->pGia ); - Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); +// Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); return 0; usage: Abc_Print( -2, "usage: &test [-F num] [-svh]\n" ); |