| |
| int Saig_ManFilterUsingIndOne2( Aig_Man_t * p, Aig_Man_t * pFrame, sat_solver * pSat, Cnf_Dat_t * pCnf, int nConfs, int nProps, int Counter |
| , int type_ /* jlong -- */ |
| ) |
| { |
| Aig_Obj_t * pObj; |
| int Lit, status; |
| pObj = Aig_ManCo( pFrame, Counter*3+type_ ); /* which co */ |
| Lit = toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], 0 ); |
| status = sat_solver_solve( pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfs, 0, 0, 0 ); |
| if ( status == l_False ) /* unsat */ |
| return status; |
| if ( status == l_Undef ) |
| { |
| printf( "Solver returned undecided.\n" ); |
| return status; |
| } |
| assert( status == l_True ); |
| return status; |
| } |
| |
| Aig_Man_t * Saig_ManCreateIndMiter2( Aig_Man_t * pAig, Vec_Vec_t * vCands ) |
| { |
| int nFrames = 3; |
| Vec_Ptr_t * vNodes; |
| Aig_Man_t * pFrames; |
| Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjNew; |
| Aig_Obj_t ** pObjMap; |
| int i, f, k; |
| |
| // create mapping for the frames nodes |
| pObjMap = ABC_CALLOC( Aig_Obj_t *, nFrames * Aig_ManObjNumMax(pAig) ); |
| |
| // start the fraig package |
| pFrames = Aig_ManStart( Aig_ManObjNumMax(pAig) * nFrames ); |
| pFrames->pName = Abc_UtilStrsav( pAig->pName ); |
| pFrames->pSpec = Abc_UtilStrsav( pAig->pSpec ); |
| // map constant nodes |
| for ( f = 0; f < nFrames; f++ ) |
| Aig_ObjSetFrames( pObjMap, nFrames, Aig_ManConst1(pAig), f, Aig_ManConst1(pFrames) ); |
| // create PI nodes for the frames |
| for ( f = 0; f < nFrames; f++ ) |
| Aig_ManForEachPiSeq( pAig, pObj, i ) |
| Aig_ObjSetFrames( pObjMap, nFrames, pObj, f, Aig_ObjCreateCi(pFrames) ); |
| // set initial state for the latches |
| Aig_ManForEachLoSeq( pAig, pObj, i ) |
| Aig_ObjSetFrames( pObjMap, nFrames, pObj, 0, Aig_ObjCreateCi(pFrames) ); |
| |
| // add timeframes |
| for ( f = 0; f < nFrames; f++ ) |
| { |
| // add internal nodes of this frame |
| Aig_ManForEachNode( pAig, pObj, i ) |
| { |
| pObjNew = Aig_And( pFrames, Aig_ObjChild0Frames(pObjMap,nFrames,pObj,f), Aig_ObjChild1Frames(pObjMap,nFrames,pObj,f) ); |
| Aig_ObjSetFrames( pObjMap, nFrames, pObj, f, pObjNew ); |
| } |
| // set the latch inputs and copy them into the latch outputs of the next frame |
| Aig_ManForEachLiLoSeq( pAig, pObjLi, pObjLo, i ) |
| { |
| pObjNew = Aig_ObjChild0Frames(pObjMap,nFrames,pObjLi,f); |
| if ( f < nFrames - 1 ) |
| Aig_ObjSetFrames( pObjMap, nFrames, pObjLo, f+1, pObjNew ); |
| } |
| } |
| |
| // go through the candidates |
| Vec_VecForEachLevel( vCands, vNodes, i ) |
| { |
| Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, k ) |
| { |
| Aig_Obj_t * pObjR = Aig_Regular(pObj); |
| Aig_Obj_t * pNode0 = pObjMap[nFrames*Aig_ObjId(pObjR)+0]; |
| Aig_Obj_t * pNode1 = pObjMap[nFrames*Aig_ObjId(pObjR)+1]; |
| { |
| Aig_Obj_t * pFan0 = Aig_NotCond( pNode0, Aig_IsComplement(pObj) ); |
| Aig_Obj_t * pFan1 = Aig_NotCond( pNode1, !Aig_IsComplement(pObj) ); |
| Aig_Obj_t * pMiter = Aig_And( pFrames, pFan0, pFan1 ); |
| Aig_ObjCreateCo( pFrames, pMiter ); |
| |
| /* need to check p & Xp is satisfiable */ |
| /* jlong -- begin */ |
| { |
| Aig_Obj_t * pMiter2 = Aig_And( pFrames, pFan0, Aig_Not(pFan1)); |
| Aig_ObjCreateCo( pFrames, pMiter2 ); |
| } |
| /* jlong -- end */ |
| } |
| |
| { /* jlong -- begin */ |
| Aig_Obj_t * pNode2 = pObjMap[nFrames*Aig_ObjId(pObjR)+2]; |
| Aig_Obj_t * pFan0 = Aig_NotCond( pNode0, Aig_IsComplement(pObj) ); |
| Aig_Obj_t * pFan1 = Aig_NotCond( pNode1, Aig_IsComplement(pObj) ); |
| Aig_Obj_t * pFan2 = Aig_NotCond( pNode2, !Aig_IsComplement(pObj) ); |
| Aig_Obj_t * pMiter = Aig_And( pFrames, Aig_And(pFrames, pFan0, pFan1 ), pFan2); |
| Aig_ObjCreateCo( pFrames, pMiter ); /* jlong -- end */ |
| } |
| |
| } |
| } |
| Aig_ManCleanup( pFrames ); |
| ABC_FREE( pObjMap ); |
| |
| //Aig_ManShow( pAig, 0, NULL ); |
| //Aig_ManShow( pFrames, 0, NULL ); |
| return pFrames; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Detects constraints functionally.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Saig_ManFilterUsingInd2( Aig_Man_t * p, Vec_Vec_t * vCands, int nConfs, int nProps, int fVerbose ) |
| { |
| Vec_Ptr_t * vNodes; |
| Aig_Man_t * pFrames; |
| sat_solver * pSat; |
| Cnf_Dat_t * pCnf; |
| Aig_Obj_t * pObj; |
| int i, k, k2, Counter; |
| /* |
| Vec_VecForEachLevel( vCands, vNodes, i ) |
| Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, k ) |
| printf( "%d ", Aig_ObjId(Aig_Regular(pObj)) ); |
| printf( "\n" ); |
| */ |
| // create timeframes |
| // pFrames = Saig_ManUnrollInd( p ); |
| pFrames = Saig_ManCreateIndMiter2( p, vCands ); |
| assert( Aig_ManCoNum(pFrames) == Vec_VecSizeSize(vCands)*3 ); |
| // start the SAT solver |
| pCnf = Cnf_DeriveSimple( pFrames, Aig_ManCoNum(pFrames) ); |
| pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); |
| // check candidates |
| if ( fVerbose ) |
| printf( "Filtered cands: \n" ); |
| Counter = 0; |
| Vec_VecForEachLevel( vCands, vNodes, i ) |
| { |
| assert(i==0); /* only one item */ |
| k2 = 0; |
| Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, k ) |
| { |
| if ( Saig_ManFilterUsingIndOne2( p, pFrames, pSat, pCnf, nConfs, nProps, Counter++ , 0) == l_False) |
| // if ( Saig_ManFilterUsingIndOne_old( p, pSat, pCnf, nConfs, pObj ) ) |
| { |
| Vec_PtrWriteEntry( vNodes, k2++, pObj ); |
| if ( fVerbose ) |
| printf( "%d:%s%d \n", i, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); |
| printf( " type I : %d:%s%d \n", i, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); |
| Vec_PtrPush(p->unfold2_type_I, pObj); |
| } |
| /* jlong -- begin */ |
| else if ( Saig_ManFilterUsingIndOne2( p, pFrames, pSat, pCnf, nConfs, nProps, Counter-1 , 1) == l_True ) /* can be self-conflicting */ |
| { |
| if ( Saig_ManFilterUsingIndOne2( p, pFrames, pSat, pCnf, nConfs, nProps, Counter-1 , 2) == l_False ){ |
| //Vec_PtrWriteEntry( vNodes, k2++, pObj ); |
| if ( fVerbose ) |
| printf( "%d:%s%d \n", i, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); |
| printf( " type II: %d:%s%d \n", i, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); |
| Vec_PtrWriteEntry( vNodes, k2++, pObj ); /* add type II constraints */ |
| Vec_PtrPush(p->unfold2_type_II, pObj); |
| } |
| } |
| /* jlong -- end */ |
| } |
| Vec_PtrShrink( vNodes, k2 ); |
| } |
| |
| // clean up |
| Cnf_DataFree( pCnf ); |
| sat_solver_delete( pSat ); |
| if ( fVerbose ) |
| Aig_ManPrintStats( pFrames ); |
| Aig_ManStop( pFrames ); |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns the number of variables implied by the output.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Vec_Vec_t * Ssw_ManFindDirectImplications2( Aig_Man_t * p, int nFrames, int nConfs, int nProps, int fVerbose ) |
| { |
| Vec_Vec_t * vCands = NULL; |
| Vec_Ptr_t * vNodes; |
| Cnf_Dat_t * pCnf; |
| sat_solver * pSat; |
| Aig_Man_t * pFrames; |
| Aig_Obj_t * pObj, * pRepr, * pReprR; |
| int i, f, k, value; |
| assert(nFrames == 1); |
| vCands = Vec_VecAlloc( nFrames ); |
| assert(nFrames == 1); |
| // perform unrolling |
| pFrames = Saig_ManUnrollCOI( p, nFrames ); |
| assert( Aig_ManCoNum(pFrames) == 1 ); |
| // start the SAT solver |
| pCnf = Cnf_DeriveSimple( pFrames, 0 ); |
| pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); |
| if ( pSat != NULL ) |
| { |
| Aig_ManIncrementTravId( p ); |
| for ( f = 0; f < nFrames; f++ ) |
| { |
| Aig_ManForEachObj( p, pObj, i ) |
| { |
| if ( !Aig_ObjIsCand(pObj) ) |
| continue; |
| //--jlong : also use internal nodes as well |
| /* if ( !Aig_ObjIsCi(pObj) ) */ |
| /* continue; */ |
| if ( Aig_ObjIsTravIdCurrent(p, pObj) ) |
| continue; |
| // get the node from timeframes |
| pRepr = p->pObjCopies[nFrames*i + nFrames-1-f]; |
| pReprR = Aig_Regular(pRepr); |
| if ( pCnf->pVarNums[Aig_ObjId(pReprR)] < 0 ) |
| continue; |
| // value = pSat->assigns[ pCnf->pVarNums[Aig_ObjId(pReprR)] ]; |
| value = sat_solver_get_var_value( pSat, pCnf->pVarNums[Aig_ObjId(pReprR)] ); |
| if ( value == l_Undef ) |
| continue; |
| // label this node as taken |
| Aig_ObjSetTravIdCurrent(p, pObj); |
| if ( Saig_ObjIsLo(p, pObj) ) |
| Aig_ObjSetTravIdCurrent( p, Aig_ObjFanin0(Saig_ObjLoToLi(p, pObj)) ); |
| // remember the node |
| Vec_VecPush( vCands, f, Aig_NotCond( pObj, (value == l_True) ^ Aig_IsComplement(pRepr) ) ); |
| // printf( "%s%d ", (value == l_False)? "":"!", i ); |
| } |
| } |
| // printf( "\n" ); |
| sat_solver_delete( pSat ); |
| } |
| Aig_ManStop( pFrames ); |
| Cnf_DataFree( pCnf ); |
| |
| if ( fVerbose ) |
| { |
| printf( "Found %3d candidates.\n", Vec_VecSizeSize(vCands) ); |
| Vec_VecForEachLevel( vCands, vNodes, k ) |
| { |
| printf( "Level %d. Cands =%d ", k, Vec_PtrSize(vNodes) ); |
| // Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) |
| // printf( "%d:%s%d ", k, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); |
| printf( "\n" ); |
| } |
| } |
| |
| ABC_FREE( p->pObjCopies ); |
| /* -- jlong -- this does the SAT proof of the constraints */ |
| Saig_ManFilterUsingInd2( p, vCands, nConfs, nProps, fVerbose ); |
| if ( Vec_VecSizeSize(vCands) ) |
| printf( "Found %3d constraints after filtering.\n", Vec_VecSizeSize(vCands) ); |
| if ( fVerbose ) |
| { |
| Vec_VecForEachLevel( vCands, vNodes, k ) |
| { |
| printf( "Level %d. Constr =%d ", k, Vec_PtrSize(vNodes) ); |
| // Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) |
| // printf( "%d:%s%d ", k, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); |
| printf( "\n" ); |
| } |
| } |
| |
| return vCands; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Duplicates the AIG while unfolding constraints.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Aig_Man_t * Saig_ManDupUnfoldConstrsFunc2( Aig_Man_t * pAig, int nFrames, int nConfs, int nProps, int fOldAlgo, int fVerbose , int * typeII_cnt){ |
| Aig_Man_t * pNew; |
| Vec_Vec_t * vCands; |
| Vec_Ptr_t * vNewFlops; |
| Aig_Obj_t * pObj; |
| int i, k, nNewFlops; |
| const int fCompl = 0 ; |
| if ( fOldAlgo ) |
| vCands = Saig_ManDetectConstrFunc( pAig, nFrames, nConfs, nProps, fVerbose ); |
| else |
| vCands = Ssw_ManFindDirectImplications2( pAig, nFrames, nConfs, nProps, fVerbose ); |
| if ( vCands == NULL || Vec_VecSizeSize(vCands) == 0 ) |
| { |
| Vec_VecFreeP( &vCands ); |
| return Aig_ManDupDfs( pAig ); |
| } |
| // create new manager |
| pNew = Aig_ManDupWithoutPos( pAig ); /* good */ |
| pNew->nConstrs = pAig->nConstrs + Vec_VecSizeSize(vCands); |
| pNew->nConstrs = pAig->nConstrs + Vec_PtrSize(pAig->unfold2_type_II) |
| + Vec_PtrSize(pAig->unfold2_type_I); |
| // pNew->nConstrsTypeII = Vec_PtrSize(pAig->unfold2_type_II); |
| *typeII_cnt = Vec_PtrSize(pAig->unfold2_type_II); |
| |
| /* new set of registers */ |
| |
| // add normal POs |
| Saig_ManForEachPo( pAig, pObj, i ) |
| Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) ); |
| // create constraint outputs |
| vNewFlops = Vec_PtrAlloc( 100 ); |
| |
| |
| Vec_PtrForEachEntry(Aig_Obj_t * , pAig->unfold2_type_I, pObj, k){ |
| Aig_Obj_t * x = Aig_ObjRealCopy(pObj); |
| Aig_ObjCreateCo(pNew, x); |
| } |
| |
| Vec_PtrForEachEntry(Aig_Obj_t * , pAig->unfold2_type_II, pObj, k){ |
| Aig_Obj_t * type_II_latch |
| = Aig_ObjCreateCi(pNew); /* will get connected later; */ |
| Aig_Obj_t * x = Aig_ObjRealCopy(pObj); |
| |
| Aig_Obj_t * n = Aig_And(pNew, |
| Aig_NotCond(type_II_latch, fCompl), |
| Aig_NotCond(x, fCompl)); |
| Aig_ObjCreateCo(pNew, n);//Aig_Not(n)); |
| } |
| |
| // add latch outputs |
| Saig_ManForEachLi( pAig, pObj, i ) |
| Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) ); |
| |
| Vec_PtrForEachEntry(Aig_Obj_t * , pAig->unfold2_type_II, pObj, k){ |
| Aig_Obj_t * x = Aig_ObjRealCopy(pObj); |
| Aig_ObjCreateCo(pNew, x); |
| } |
| |
| // add new latch outputs |
| nNewFlops = Vec_PtrSize(pAig->unfold2_type_II); |
| //assert( nNewFlops == Vec_PtrSize(vNewFlops) ); |
| Aig_ManSetRegNum( pNew, Aig_ManRegNum(pAig) + nNewFlops ); |
| printf("#reg after unfold2: %d\n", Aig_ManRegNum(pAig) + nNewFlops ); |
| Vec_VecFreeP( &vCands ); |
| Vec_PtrFree( vNewFlops ); |
| return pNew; |
| |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Duplicates the AIG while unfolding constraints.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Aig_Man_t * Saig_ManDupFoldConstrsFunc2( Aig_Man_t * pAig, int fCompl, int fVerbose , |
| int typeII_cnt) |
| { |
| Aig_Man_t * pAigNew; |
| Aig_Obj_t * pMiter, * pFlopOut, * pFlopIn, * pObj; |
| int i, typeII_cc, type_II; |
| if ( Aig_ManConstrNum(pAig) == 0 ) |
| return Aig_ManDupDfs( pAig ); |
| assert( Aig_ManConstrNum(pAig) < Saig_ManPoNum(pAig) ); |
| // start the new manager |
| pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) ); |
| pAigNew->pName = Abc_UtilStrsav( pAig->pName ); |
| pAigNew->pSpec = Abc_UtilStrsav( pAig->pSpec ); |
| // map the constant node |
| Aig_ManConst1(pAig)->pData = Aig_ManConst1( pAigNew ); |
| // create variables for PIs |
| Aig_ManForEachCi( pAig, pObj, i ) |
| pObj->pData = Aig_ObjCreateCi( pAigNew ); |
| // add internal nodes of this frame |
| Aig_ManForEachNode( pAig, pObj, i ) |
| pObj->pData = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); |
| |
| // OR the constraint outputs |
| pMiter = Aig_ManConst0( pAigNew ); |
| typeII_cc = 0;//typeII_cnt; |
| typeII_cnt = 0; |
| type_II = 0; |
| |
| Saig_ManForEachPo( pAig, pObj, i ) |
| { |
| |
| if ( i < Saig_ManPoNum(pAig)-Aig_ManConstrNum(pAig) ) |
| continue; |
| if (i + typeII_cnt >= Saig_ManPoNum(pAig) ) { |
| type_II = 1; |
| } |
| /* now we got the constraint */ |
| if (type_II) { |
| |
| Aig_Obj_t * type_II_latch |
| = Aig_ObjCreateCi(pAigNew); /* will get connected later; */ |
| pMiter = Aig_Or(pAigNew, pMiter, |
| Aig_And(pAigNew, |
| Aig_NotCond(type_II_latch, fCompl), |
| Aig_NotCond( Aig_ObjChild0Copy(pObj), fCompl ) ) |
| ); |
| printf( "modeling typeII : %d:%s%d \n", i, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); |
| } else |
| pMiter = Aig_Or( pAigNew, pMiter, Aig_NotCond( Aig_ObjChild0Copy(pObj), fCompl ) ); |
| } |
| |
| // create additional flop |
| if ( Saig_ManRegNum(pAig) > 0 ) |
| { |
| pFlopOut = Aig_ObjCreateCi( pAigNew ); |
| pFlopIn = Aig_Or( pAigNew, pMiter, pFlopOut ); |
| } |
| else |
| pFlopIn = pMiter; |
| |
| // create primary output |
| Saig_ManForEachPo( pAig, pObj, i ) |
| { |
| if ( i >= Saig_ManPoNum(pAig)-Aig_ManConstrNum(pAig) ) |
| continue; |
| pMiter = Aig_And( pAigNew, Aig_ObjChild0Copy(pObj), Aig_Not(pFlopIn) ); |
| Aig_ObjCreateCo( pAigNew, pMiter ); |
| } |
| |
| // transfer to register outputs |
| { |
| /* the same for type I and type II */ |
| Aig_Obj_t * pObjLi, *pObjLo; |
| |
| Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) { |
| if( i + typeII_cc < Aig_ManRegNum(pAig)) { |
| Aig_Obj_t *c = Aig_Mux(pAigNew, Aig_Not(pFlopIn), |
| Aig_ObjChild0Copy(pObjLi) , |
| (Aig_Obj_t*)pObjLo->pData); |
| Aig_ObjCreateCo( pAigNew, c); |
| } else { |
| printf ( "skipping: reg%d\n", i); |
| Aig_ObjCreateCo( pAigNew,Aig_ObjChild0Copy(pObjLi)); |
| } |
| } |
| |
| } |
| if(0)Saig_ManForEachLi( pAig, pObj, i ) { |
| Aig_ObjCreateCo( pAigNew, Aig_ObjChild0Copy(pObj) ); |
| } |
| Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAig) ); |
| |
| type_II = 0; |
| Saig_ManForEachPo( pAig, pObj, i ) |
| { |
| |
| if ( i < Saig_ManPoNum(pAig)-Aig_ManConstrNum(pAig) ) |
| continue; |
| if (i + typeII_cnt >= Saig_ManPoNum(pAig) ) { |
| type_II = 1; |
| } |
| /* now we got the constraint */ |
| if (type_II) { |
| Aig_ObjCreateCo( pAigNew, Aig_ObjChild0Copy(pObj)); |
| Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAigNew)+1 ); |
| printf( "Latch for typeII : %d:%s%d \n", i, Aig_IsComplement(pObj)? "!":"", Aig_ObjId(Aig_Regular(pObj)) ); |
| } |
| } |
| |
| |
| // create additional flop |
| |
| if ( Saig_ManRegNum(pAig) > 0 ) |
| { |
| Aig_ObjCreateCo( pAigNew, pFlopIn ); |
| Aig_ManSetRegNum( pAigNew, Aig_ManRegNum(pAigNew)+1 ); |
| } |
| printf("#reg after fold2: %d\n", Aig_ManRegNum(pAigNew)); |
| // perform cleanup |
| Aig_ManCleanup( pAigNew ); |
| Aig_ManSeqCleanup( pAigNew ); |
| return pAigNew; |
| } |