diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2011-10-14 16:48:45 +0300 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2011-10-14 16:48:45 +0300 |
commit | c6982485e4ef948a2777f3a8c3d6ac38b33b5a88 (patch) | |
tree | f02eb78f2920028bb3c2f472ef8b1710291801e8 /src/aig | |
parent | ad5ee9ff4603340aab234549c400a18af7df9df1 (diff) | |
download | abc-c6982485e4ef948a2777f3a8c3d6ac38b33b5a88.tar.gz abc-c6982485e4ef948a2777f3a8c3d6ac38b33b5a88.tar.bz2 abc-c6982485e4ef948a2777f3a8c3d6ac38b33b5a88.zip |
New abstraction code.
Diffstat (limited to 'src/aig')
-rw-r--r-- | src/aig/saig/saigAbsGla.c | 564 |
1 files changed, 564 insertions, 0 deletions
diff --git a/src/aig/saig/saigAbsGla.c b/src/aig/saig/saigAbsGla.c new file mode 100644 index 00000000..3915c24b --- /dev/null +++ b/src/aig/saig/saigAbsGla.c @@ -0,0 +1,564 @@ +/**CFile**************************************************************** + + FileName [saigAbsGla.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Gate level abstraction.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigAbsGla.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" +#include "satSolver.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Aig_GlaMan_t_ Aig_GlaMan_t; +struct Aig_GlaMan_t_ +{ + // user data + Aig_Man_t * pAig; + int nConfLimit; + int nFramesMax; + int fVerbose; + // abstraction + Vec_Int_t * vAbstr; // collects objects used in the abstraction + Vec_Int_t * vUsed; // maps object ID into its status (0=unused; 1=used) + Vec_Int_t * vPis; // primary inputs + Vec_Int_t * vPPis; // pseudo primary inputs + Vec_Int_t * vFlops; // flops + Vec_Int_t * vNodes; // nodes + // unrolling + int iFrame; + int nFrames; + Vec_Int_t * vObj2Vec; // maps obj ID into its vec ID + Vec_Int_t * vVec2Var; // maps vec ID into its sat Var (nFrames per vec ID) + Vec_Int_t * vVar2Inf; // maps sat Var into its frame and obj ID + // SAT solver + sat_solver * pSat; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Performs abstraction of the AIG to preserve the included gates.] + + Description [The array contains 1 if the obj is included; 0 otherwise.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Aig_GlaDupAbsGates( Aig_Man_t * p, Vec_Int_t * vUsed, int * pnRealPis ) +{ + Aig_Man_t * pNew; + Aig_Obj_t * pObj, * pObjLi, * pObjLo; + int i, nFlops = 0, RetValue; + assert( Aig_ManPoNum(p) == 1 ); + // start the new manager + pNew = Aig_ManStart( 5000 ); + pNew->pName = Aig_UtilStrsav( p->pName ); + // create constant + Aig_ManCleanData( p ); + Aig_ManConst1(p)->pData = Aig_ManConst1(pNew); + // create PIs + Saig_ManForEachPi( p, pObj, i ) + if ( Vec_IntEntry(vUsed, Aig_ObjId(pObj)) ) + pObj->pData = Aig_ObjCreatePi(pNew); + if ( pnRealPis ) + *pnRealPis = Aig_ManPiNum(pNew); + // create additional PIs + Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) + if ( Vec_IntEntry(vUsed, Aig_ObjId(pObjLo)) && !Vec_IntEntry(vUsed, Aig_ObjId(pObjLi)) ) + pObjLo->pData = Aig_ObjCreatePi(pNew); + Aig_ManForEachNode( p, pObj, i ) + { + if ( Vec_IntEntry(vUsed, Aig_ObjId(pObj)) && + (!Vec_IntEntry(vUsed, Aig_ObjFaninId0(pObj)) || + !Vec_IntEntry(vUsed, Aig_ObjFaninId1(pObj))) ) + pObj->pData = Aig_ObjCreatePi(pNew); + } + // create ROs + Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) + if ( Vec_IntEntry(vUsed, Aig_ObjId(pObjLo)) && Vec_IntEntry(vUsed, Aig_ObjId(pObjLi)) ) + pObjLo->pData = Aig_ObjCreatePi(pNew), nFlops++; + // create internal nodes + Aig_ManForEachNode( p, pObj, i ) + { + if ( Vec_IntEntry(vUsed, Aig_ObjId(pObj)) && + Vec_IntEntry(vUsed, Aig_ObjFaninId0(pObj)) && + Vec_IntEntry(vUsed, Aig_ObjFaninId1(pObj)) ) + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + } + // create PO + Saig_ManForEachPo( p, pObj, i ) + pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); + // create RIs + Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) + if ( Vec_IntEntry(vUsed, Aig_ObjId(pObjLo)) && Vec_IntEntry(vUsed, Aig_ObjId(pObjLi)) ) + pObjLi->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObjLi) ); + Aig_ManSetRegNum( pNew, nFlops ); + // clean up + RetValue = Aig_ManCleanup( pNew ); + assert( RetValue == 0 ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Aig_GlaDeriveAbs( Aig_GlaMan_t * p ) +{ + Aig_Man_t * pNew; + Aig_Obj_t * pObj; + int i, nFlops = 0, RetValue; + assert( Aig_ManPoNum(p) == 1 ); + // start the new manager + pNew = Aig_ManStart( 5000 ); + pNew->pName = Aig_UtilStrsav( p->pAig->pName ); + // create constant + Aig_ManCleanData( p->pAig ); + Aig_ManConst1(p->pAig)->pData = Aig_ManConst1(pNew); + // create PIs + Aig_ManForEachObjVec( p->vPis, p->pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi(pNew); + // create additional PIs + Aig_ManForEachObjVec( p->vPPis, p->pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi(pNew); + // create ROs + Aig_ManForEachObjVec( p->vFlops, p->pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePi(pNew); + // create internal nodes + Aig_ManForEachObjVec( p->vNodes, p->pAig, pObj, i ) + pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); + // create PO + Saig_ManForEachPo( p->pAig, pObj, i ) + pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); + // create RIs + Aig_ManForEachObjVec( p->vFlops, p->pAig, pObj, i ) + Saig_ObjLoToLi(p->pAig, pObj)->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(Saig_ObjLoToLi(p->pAig, pObj)) ); + Aig_ManSetRegNum( pNew, Vec_IntSize(p->vFlops) ); + // clean up + RetValue = Aig_ManCleanup( pNew ); + assert( RetValue == 0 ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Adds constant to the solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_GlaAddConst( sat_solver * pSat, int iVar, int fCompl ) +{ + lit Lit = toLitCond( iVar, fCompl ); + if ( !sat_solver_addclause( pSat, &Lit, &Lit + 1 ) ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Adds buffer to the solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_GlaAddBuffer( sat_solver * pSat, int iVar0, int iVar1, int fCompl ) +{ + lit Lits[2]; + + Lits[0] = toLitCond( iVar0, 0 ); + Lits[1] = toLitCond( iVar1, !fCompl ); + if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) ) + return 0; + + Lits[0] = toLitCond( iVar0, 1 ); + Lits[1] = toLitCond( iVar1, fCompl ); + if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) ) + return 0; + + return 1; +} + +/**Function************************************************************* + + Synopsis [Adds buffer to the solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_GlaAddNode( sat_solver * pSat, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1 ) +{ + lit Lits[3]; + + Lits[0] = toLitCond( iVar, 1 ); + Lits[1] = toLitCond( iVar0, fCompl0 ); + if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) ) + return 0; + + Lits[0] = toLitCond( iVar, 1 ); + Lits[1] = toLitCond( iVar1, fCompl1 ); + if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) ) + return 0; + + Lits[0] = toLitCond( iVar, 0 ); + Lits[1] = toLitCond( iVar0, !fCompl0 ); + Lits[2] = toLitCond( iVar1, !fCompl1 ); + if ( !sat_solver_addclause( pSat, Lits, Lits + 3 ) ) + return 0; + + return 1; +} + + +/**Function************************************************************* + + Synopsis [Finds existing SAT variable or creates a new one.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_GlaFetchVar( Aig_GlaMan_t * p, Aig_Obj_t * pObj, int k ) +{ + int i, iVecId, iSatVar; + if ( !Vec_IntEntry(p->vUsed, Aig_ObjId(pObj)) ) + { + Vec_IntWriteEntry( p->vUsed, Aig_ObjId(pObj), 1 ); + Vec_IntPush( p->vAbstr, Aig_ObjId(pObj) ); + } + iVecId = Vec_IntEntry( p->vObj2Vec, Aig_ObjId(pObj) ); + if ( iVecId == 0 ) + { + iVecId = Vec_IntSize( p->vVec2Var ) / p->nFrames; + for ( i = 0; i < p->nFrames; i++ ) + Vec_IntPush( p->vVec2Var, 0 ); + } + iSatVar = Vec_IntEntry( p->vVec2Var, iVecId * p->nFrames + k ); + if ( iSatVar == 0 ) + { + iSatVar = Vec_IntSize( p->vVar2Inf ) / 2; + Vec_IntPush( p->vVar2Inf, Aig_ObjId(pObj) ); + Vec_IntPush( p->vVar2Inf, k ); + Vec_IntWriteEntry( p->vVec2Var, iVecId * p->nFrames + k, iSatVar ); + } + return iSatVar; +} + +/**Function************************************************************* + + Synopsis [Adds CNF for the given object in the given frame.] + + Description [Returns 0, if the solver becames UNSAT.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_GlaObjAddToSolver( Aig_GlaMan_t * p, Aig_Obj_t * pObj, int k ) +{ + assert( Vec_IntEntry(vUsed, Aig_ObjId(pObj)) ); + if ( Aig_ObjIsConst1(pObj) ) + return Aig_GlaAddConst( p->pSat, Aig_GlaFetchVar(p, pObj, k), 0 ); + if ( Saig_ObjIsPi(p->pAig, pObj) ) + return 1; + if ( Saig_ObjIsLo(p->pAig, pObj) ) + { + Aig_Obj_t * pObjLi = Saig_ObjLoToLi(p->pAig, pObj); + if ( k == 0 ) + return Aig_GlaAddConst( p->pSat, Aig_GlaFetchVar(p, pObj, k), 1 ); + if ( Vec_IntEntry(p->vUsed, Aig_ObjId(pObjLi)) ) + return 1; + return Aig_GlaAddBuffer( p->pSat, Aig_GlaFetchVar(p, pObj, k), Aig_GlaFetchVar(p, Aig_ObjFanin0(pObjLi), k-1), Aig_ObjFaninC0(pObjLi) ); + } + assert( Aig_ObjIsNode(pObj) ); + if ( Vec_IntEntry(p->vUsed, Aig_ObjFaninId0(pObj)) && Vec_IntEntry(p->vUsed, Aig_ObjFaninId1(pObj)) ) + return 0; + return Aig_GlaAddNode( p->pSat, Aig_GlaFetchVar(p, pObj, k), + Aig_GlaFetchVar(p, Aig_ObjFanin0(pObj), k), + Aig_GlaFetchVar(p, Aig_ObjFanin1(pObj), k), + Aig_ObjFaninC0(pObj), Aig_ObjFaninC1(pObj) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_GlaMan_t * Aig_GlaManStart( Aig_Man_t * pAig ) +{ + Aig_GlaMan_t * p; + int i; + + p = ABC_CALLOC( Aig_GlaMan_t, 1 ); + p->pAig = pAig; + p->vAbstr = Vec_IntAlloc( 1000 ); + p->vUsed = Vec_IntStart( Aig_ManObjNumMax(pAig) ); + p->nFrames = 16; + + p->vPis = Vec_IntAlloc( 1000 ); + p->vPPis = Vec_IntAlloc( 1000 ); + p->vFlops = Vec_IntAlloc( 1000 ); + p->vNodes = Vec_IntAlloc( 1000 ); + + p->vObj2Vec = Vec_IntStart( Aig_ManObjNumMax(pAig) ); + p->vVec2Var = Vec_IntAlloc( 1 << 20 ); + p->vVar2Inf = Vec_IntAlloc( 1 << 20 ); + + // skip first vector ID + for ( i = 0; i < p->nFrames; i++ ) + Vec_IntPush( p->vVec2Var, -1 ); + // skip first SAT variable + Vec_IntPush( p->vVar2Inf, -1 ); + Vec_IntPush( p->vVar2Inf, -1 ); + + // start the SAT solver + p->pSat = sat_solver_new(); + sat_solver_setnvars( p->pSat, 1000 ); + return p; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_GlaManStop( Aig_GlaMan_t * p ) +{ + Vec_IntFreeP( &p->vAbstr ); + Vec_IntFreeP( &p->vUsed ); + + Vec_IntFreeP( &p->vPis ); + Vec_IntFreeP( &p->vPPis ); + Vec_IntFreeP( &p->vFlops ); + Vec_IntFreeP( &p->vNodes ); + + Vec_IntFreeP( &p->vObj2Vec ); + Vec_IntFreeP( &p->vVec2Var ); + Vec_IntFreeP( &p->vVar2Inf ); + + if ( p->pSat ) + sat_solver_delete( p->pSat ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_GlaCollectAbstr( Aig_GlaMan_t * p ) +{ + Aig_Obj_t * pObj, * pObjLi, * pObjLo; + int i; + Vec_IntClear( p->vPis ); + Vec_IntClear( p->vPPis ); + Vec_IntClear( p->vFlops ); + Vec_IntClear( p->vNodes ); + + Saig_ManForEachPi( p->pAig, pObj, i ) + if ( Vec_IntEntry(p->vUsed, Aig_ObjId(pObj)) ) + Vec_IntPush( p->vPis, Aig_ObjId(pObj) ); + + Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) + if ( Vec_IntEntry(p->vUsed, Aig_ObjId(pObjLo)) ) + { + if ( Vec_IntEntry(p->vUsed, Aig_ObjFaninId0(pObjLi)) ) + Vec_IntPush( p->vFlops, Aig_ObjId(pObjLo) ); + else + Vec_IntPush( p->vPPis, Aig_ObjId(pObjLo) ); + } + + Aig_ManForEachNode( p->pAig, pObj, i ) + if ( Vec_IntEntry(p->vUsed, Aig_ObjId(pObj)) ) + { + if ( Vec_IntEntry(p->vUsed, Aig_ObjFaninId0(pObj)) && Vec_IntEntry(p->vUsed, Aig_ObjFaninId1(pObj)) ) + Vec_IntPush( p->vNodes, Aig_ObjId(pObjLo) ); + else + Vec_IntPush( p->vPPis, Aig_ObjId(pObjLo) ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Cex_t * Aig_GlaDeriveCex( Aig_GlaMan_t * p ) +{ + return NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_GlaPrintAbstr( Aig_GlaMan_t * p, int f, int r ) +{ + printf( "Fra %3d : Ref %3d : PI =%6d PPI =%6d Flop =%6d Node =%6d\n", + f, r, Vec_IntSize(p->vPis), Vec_IntSize(p->vPPis), Vec_IntSize(p->vFlops), Vec_IntSize(p->vNodes) ); +} + +/**Function************************************************************* + + Synopsis [Perform variable frame abstraction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_GlaManTest( Aig_Man_t * pAig, int nFramesMax, int nConfLimit, int fVerbose ) +{ + Aig_GlaMan_t * p; + Aig_Man_t * pAbs; + Aig_Obj_t * pObj; + Abc_Cex_t * pCex; + Vec_Int_t * vPPisToRefine; + int f, g, r, i, iSatVar, Lit, Entry, RetValue; + assert( Saig_ManPoNum(pAig) == 1 ); + + // start the solver + p = Aig_GlaManStart( pAig ); + p->nFramesMax = nFramesMax; + p->nConfLimit = nConfLimit; + p->fVerbose = fVerbose; + + // iterate over the timeframes + for ( f = 0; f < nFramesMax; f++ ) + { + // initialize abstraction in this timeframe + Aig_ManForEachObjVec( p->vAbstr, pAig, pObj, i ) + Aig_GlaObjAddToSolver( p, pObj, f ); + + // create output literal to represent property failure + pObj = Aig_ManPo( pAig, 0 ); + iSatVar = Aig_GlaFetchVar( p, Aig_ObjFanin0(pObj), f ); + Lit = toLitCond( iSatVar, Aig_ObjFaninC0(pObj) ); + + // try solving the abstraction + Aig_GlaPrintAbstr( p, f, -1 ); + for ( r = 0; r < 1000000; r++ ) + { + RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1, + (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( RetValue != l_True ) + break; + // derive abstraction + Aig_GlaCollectAbstr( p ); + // derive counter-example + pCex = Aig_GlaDeriveCex( p ); + // derive abstraction + pAbs = Aig_GlaDeriveAbs( p ); + // perform refinement + vPPisToRefine = Saig_ManCbaFilterInputs( pAig, Vec_IntSize(p->vPis), pCex, 0 ); + // update + Vec_IntForEachEntry( vPPisToRefine, Entry, i ) + { + for ( g = 0; g <= f; g++ ) + Aig_GlaObjAddToSolver( p, Aig_ManObj(pAig, Vec_IntEntry(p->vPPis, Entry)), g ); + } + Vec_IntFree( vPPisToRefine ); + // print abstraction + Aig_GlaPrintAbstr( p, f, r ); + } + if ( RetValue != l_False ) + break; + } + Aig_GlaPrintAbstr( p, f, -1 ); + if ( f == nFramesMax ) + printf( "Finished %d frames without exceeding conflict limit (%d).\n", f, nConfLimit ); + else + printf( "Ran out of conflict limit (%d) at frame %d.\n", nConfLimit, f ); + + Aig_GlaManStop( p ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + |