| /**CFile**************************************************************** |
| |
| FileName [int2Bmc.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Interpolation engine.] |
| |
| Synopsis [BMC used inside IMC.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - Dec 1, 2013.] |
| |
| Revision [$Id: int2Bmc.c,v 1.00 2013/12/01 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "int2Int.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Trasnforms AIG to transition into the init state.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Int2_ManDupInit( Gia_Man_t * p, int fVerbose ) |
| { |
| Gia_Man_t * pNew, * pTemp; |
| Gia_Obj_t * pObj, * pObjRi, * pObjRo; |
| int i, iCtrl; |
| assert( Gia_ManRegNum(p) > 0 ); |
| pNew = Gia_ManStart( 10000 ); |
| pNew->pName = Abc_UtilStrsav( p->pName ); |
| pNew->pSpec = Abc_UtilStrsav( p->pSpec ); |
| Gia_ManConst0(p)->Value = 0; |
| Gia_ManForEachCi( p, pObj, i ) |
| { |
| if ( i == Gia_ManPiNum(p) ) |
| iCtrl = Gia_ManAppendCi( pNew ); |
| pObj->Value = Gia_ManAppendCi( pNew ); |
| } |
| Gia_ManHashAlloc( pNew ); |
| Gia_ManForEachAnd( p, pObj, i ) |
| pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); |
| Gia_ManForEachPo( p, pObj, i ) |
| pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); |
| Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) |
| Gia_ManAppendCo( pNew, Gia_ManHashMux( pNew, iCtrl, pObjRo->Value, Gia_ObjFanin0Copy(pObjRi) ) ); |
| Gia_ManHashStop( pNew ); |
| Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); |
| // remove dangling |
| pNew = Gia_ManCleanup( pTemp = pNew ); |
| if ( fVerbose ) |
| printf( "Before cleanup = %d nodes. After cleanup = %d nodes.\n", |
| Gia_ManAndNum(pTemp), Gia_ManAndNum(pNew) ); |
| Gia_ManStop( pTemp ); |
| return pNew; |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns 1 if AIG has transition into init state.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Int2_ManCheckInit( Gia_Man_t * p ) |
| { |
| sat_solver * pSat; |
| Cnf_Dat_t * pCnf; |
| Gia_Man_t * pNew; |
| Gia_Obj_t * pObj; |
| Vec_Int_t * vLits; |
| int i, Lit, RetValue = 0; |
| assert( Gia_ManRegNum(p) > 0 ); |
| pNew = Jf_ManDeriveCnf( p, 0 ); |
| pCnf = (Cnf_Dat_t *)pNew->pData; pNew->pData = NULL; |
| pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); |
| if ( pSat != NULL ) |
| { |
| vLits = Vec_IntAlloc( Gia_ManRegNum(p) ); |
| Gia_ManForEachRi( pNew, pObj, i ) |
| { |
| Lit = pCnf->pVarNums[ Gia_ObjId(pNew, Gia_ObjFanin0(pObj)) ]; |
| Lit = Abc_Var2Lit( Lit, Gia_ObjFaninC0(pObj) ); |
| Vec_IntPush( vLits, Abc_LitNot(Lit) ); |
| } |
| if ( sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), 0, 0, 0, 0 ) == l_True ) |
| RetValue = 1; |
| Vec_IntFree( vLits ); |
| sat_solver_delete( pSat ); |
| } |
| Cnf_DataFree( pCnf ); |
| Gia_ManStop( pNew ); |
| return RetValue; |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Creates the BMC instance in the SAT solver.] |
| |
| Description [The PIs are mapped in the natural order. The flop inputs |
| are the last Gia_ManRegNum(p) variables of resulting SAT solver.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Int2_ManFrameInit( Gia_Man_t * p, int nFrames, int fVerbose ) |
| { |
| Gia_Man_t * pFrames, * pTemp; |
| Gia_Obj_t * pObj; |
| int i, f; |
| pFrames = Gia_ManStart( 10000 ); |
| pFrames->pName = Abc_UtilStrsav( p->pName ); |
| pFrames->pSpec = Abc_UtilStrsav( p->pSpec ); |
| Gia_ManConst0(p)->Value = 0; |
| // perform structural hashing |
| Gia_ManHashAlloc( pFrames ); |
| for ( f = 0; f < nFrames; f++ ) |
| { |
| Gia_ManForEachPi( p, pObj, i ) |
| pObj->Value = Gia_ManAppendCi( pFrames ); |
| Gia_ManForEachRo( p, pObj, i ) |
| pObj->Value = f ? Gia_ObjRoToRi(p, pObj)->Value : 0; |
| Gia_ManForEachAnd( p, pObj, i ) |
| pObj->Value = Gia_ManHashAnd( pFrames, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); |
| Gia_ManForEachRi( p, pObj, i ) |
| pObj->Value = Gia_ObjFanin0Copy(pObj); |
| } |
| Gia_ManHashStop( pFrames ); |
| // create flop inputs |
| Gia_ManForEachRi( p, pObj, i ) |
| pObj->Value = Gia_ManAppendCo( pFrames, Gia_ObjFanin0Copy(pObj) ); |
| // remove dangling |
| pFrames = Gia_ManCleanup( pTemp = pFrames ); |
| if ( fVerbose ) |
| printf( "Before cleanup = %d nodes. After cleanup = %d nodes.\n", |
| Gia_ManAndNum(pTemp), Gia_ManAndNum(pFrames) ); |
| Gia_ManStop( pTemp ); |
| return pFrames; |
| } |
| sat_solver * Int2_ManSetupBmcSolver( Gia_Man_t * p, int nFrames ) |
| { |
| Gia_Man_t * pFrames, * pTemp; |
| Cnf_Dat_t * pCnf; |
| sat_solver * pSat; |
| // unfold for the given number of timeframes |
| pFrames = Int2_ManFrameInit( p, nFrames, 1 ); |
| assert( Gia_ManRegNum(pFrames) == 0 ); |
| // derive CNF for the timeframes |
| pFrames = Jf_ManDeriveCnf( pTemp = pFrames, 0 ); Gia_ManStop( pTemp ); |
| pCnf = (Cnf_Dat_t *)pFrames->pData; pFrames->pData = NULL; |
| // create SAT solver |
| pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); |
| if ( pSat != NULL ) |
| { |
| Gia_Obj_t * pObj; |
| int i, nVars = sat_solver_nvars( pSat ); |
| sat_solver_setnvars( pSat, nVars + Gia_ManPoNum(pFrames) ); |
| // add clauses for the POs |
| Gia_ManForEachCo( pFrames, pObj, i ) |
| sat_solver_add_buffer( pSat, nVars + i, pCnf->pVarNums[Gia_ObjId(pFrames, Gia_ObjFanin0(pObj))], Gia_ObjFaninC0(pObj) ); |
| } |
| Cnf_DataFree( pCnf ); |
| Gia_ManStop( pFrames ); |
| return pSat; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Int2_ManCheckFrames( Int2_Man_t * p, int iFrame, int iObj ) |
| { |
| Vec_Int_t * vMapFrame = (Vec_Int_t *)Vec_PtrEntry(p->vMapFrames, iFrame); |
| return Vec_IntEntry(vMapFrame, iObj); |
| } |
| static inline void Int2_ManWriteFrames( Int2_Man_t * p, int iFrame, int iObj, int iRes ) |
| { |
| Vec_Int_t * vMapFrame = (Vec_Int_t *)Vec_PtrEntry(p->vMapFrames, iFrame); |
| assert( Vec_IntEntry(vMapFrame, iObj) == -1 ); |
| Vec_IntWriteEntry( vMapFrame, iObj, iRes ); |
| } |
| void Int2_ManCreateFrames( Int2_Man_t * p, int iFrame, Vec_Int_t * vPrefCos ) |
| { |
| Gia_Obj_t * pObj; |
| int i, Entry, iLit; |
| // create storage room for unfolded IDs |
| for ( i = Vec_PtrSize(p->vMapFrames); i <= iFrame; i++ ) |
| Vec_PtrPush( p->vMapFrames, Vec_IntStartFull( Gia_ManObjNum(p->pGia) ) ); |
| assert( Vec_PtrSize(p->vMapFrames) == iFrame + 1 ); |
| // create constant 0 node |
| if ( f == 0 ) |
| { |
| iLit = 1; |
| Int2_ManWriteFrames( p, iFrame, iObj, 0 ); |
| sat_solver_addclause( p->pGiaPref, &iLit, &iLit + 1 ); |
| } |
| // start the stack |
| Vec_IntClear( p->vStack ); |
| Vec_IntForEachEntry( vPrefCos, Entry, i ) |
| { |
| pObj = Gia_ManCo( p->pGia, Entry ); |
| Vec_IntPush( p->vStack, iFrame ); |
| Vec_IntPush( p->vStack, Gia_ObjId(p->pGia, pObj) ); |
| } |
| // construct unfolded AIG |
| while ( Vec_IntSize(p->vStack) > 0 ) |
| { |
| int iObj = Vec_IntPop(p->vStack); |
| int iFrame = Vec_IntPop(p->vStack); |
| if ( Int2_ManCheckFrames(p, iFrame, iObj) >= 0 ) |
| continue; |
| pObj = Gia_ManObj( p->pGia, iObj ); |
| if ( Gia_ObjIsPi(p->pGia, pObj) ) |
| Int2_ManWriteFrames( p, iFrame, iObj, Gia_ManAppendCi(p->pFrames) ); |
| else if ( iFrame == 0 && Gia_ObjIsRo(p->pGia, iObj) ) |
| Int2_ManWriteFrames( p, iFrame, iObj, 0 ); |
| else if ( Gia_ObjIsRo(p->pGia, iObj) ) |
| { |
| int iObjF = Gia_ObjId( p->pGia, Gia_ObjRoToRi(p->pGia, pObj) ); |
| int iLit = Int2_ManCheckFrames( p, iFrame-1, iObjF ); |
| if ( iLit >= 0 ) |
| Int2_ManWriteFrames( p, iFrame, iObj, iLit ); |
| else |
| { |
| Vec_IntPush( p->vStack, iFrame ); |
| Vec_IntPush( p->vStack, iObj ); |
| Vec_IntPush( p->vStack, iFrame-1 ); |
| Vec_IntPush( p->vStack, iObjF ); |
| } |
| } |
| else if ( Gia_ObjIsCo(pObj) ) |
| { |
| int iObjF = Gia_ObjFaninId0(p->pGia, iObj) ); |
| int iLit = Int2_ManCheckFrames( p, iFrame, iObjF ); |
| if ( iLit >= 0 ) |
| Int2_ManWriteFrames( p, iFrame, iObj, Abc_LitNotCond(iLit, Gia_ObjFaninC0(pObj)) ); |
| else |
| { |
| Vec_IntPush( p->vStack, iFrame ); |
| Vec_IntPush( p->vStack, iObj ); |
| Vec_IntPush( p->vStack, iFrame ); |
| Vec_IntPush( p->vStack, iObjF ); |
| } |
| } |
| else if ( Gia_ObjIsAnd(pObj) ) |
| { |
| int iObjF0 = Gia_ObjFaninId0(p->pGia, iObj) ); |
| int iLit0 = Int2_ManCheckFrames( p, iFrame, iObjF0 ); |
| int iObjF1 = Gia_ObjFaninId1(p->pGia, iObj) ); |
| int iLit1 = Int2_ManCheckFrames( p, iFrame, iObjF1 ); |
| if ( iLit0 >= 0 && iLit1 >= 0 ) |
| { |
| Entry = Gia_ManObjNum(pFrames); |
| iLit = Gia_ManHashAnd(pFrames, iLit0, iLit1); |
| Int2_ManWriteFrames( p, iFrame, iObj, iLit ); |
| if ( Entry < Gia_ManObjNum(pFrames) ) |
| { |
| assert( !Abc_LitIsCompl(iLit) ); |
| sat_solver_add_and( p->pGiaPref, Abc_Lit2Var(iLit), Abc_Lit2Var(iLit0), Abc_Lit2Var(iLit1), Abc_LitIsCompl(iLit0), Abc_LitIsCompl(iLit1), 0 ); |
| } |
| } |
| else |
| { |
| Vec_IntPush( p->vStack, iFrame ); |
| Vec_IntPush( p->vStack, iObj ); |
| if ( iLit0 < 0 ) |
| { |
| Vec_IntPush( p->vStack, iFrame ); |
| Vec_IntPush( p->vStack, iObjF0 ); |
| } |
| if ( iLit1 < 0 ) |
| { |
| Vec_IntPush( p->vStack, iFrame ); |
| Vec_IntPush( p->vStack, iObjF1 ); |
| } |
| } |
| } |
| else assert( 0 ); |
| } |
| } |
| int Int2_ManCheckBmc( Int2_Man_t * p, Vec_Int_t * vCube ) |
| { |
| int status; |
| if ( vCube == NULL ) |
| { |
| Gia_Obj_t * pObj; |
| int i, iLit; |
| Gia_ManForEachPo( p->pGia, pObj, i ) |
| { |
| iLit = Int2_ManCheckFrames( p, 0, Gia_ObjId(p->pGia, pObj) ); |
| if ( iLit == 0 ) |
| continue; |
| if ( iLit == 1 ) |
| return 0; |
| status = sat_solver_solve( p->pSatPref, &iLit, &iLit + 1, 0, 0, 0, 0 ); |
| if ( status == l_False ) |
| continue; |
| if ( status == l_True ) |
| return 0; |
| return -1; |
| } |
| return 1; |
| } |
| status = sat_solver_solve( p->pSatPref, Vec_IntArray(vCube), Vec_IntArray(vCube) + Vec_IntSize(vCube), 0, 0, 0, 0 ); |
| if ( status == l_False ) |
| return 1; |
| if ( status == l_True ) |
| return 0; |
| return -1; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |