ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Saves the input pattern with the given number.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Cec_ManTransformPattern( Gia_Man_t * p, int iOut, int * pValues ) { int i; assert( p->pCexComb == NULL ); p->pCexComb = Abc_CexAlloc( 0, Gia_ManCiNum(p), 1 ); p->pCexComb->iPo = iOut; for ( i = 0; i < Gia_ManCiNum(p); i++ ) if ( pValues && pValues[i] ) Abc_InfoSetBit( p->pCexComb->pData, i ); }
/**Function************************************************************* Synopsis [Makes sure the manager is normalized.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Gia_ManIsNormalized( Gia_Man_t * p ) { int i, nOffset; nOffset = 1; for ( i = 0; i < Gia_ManCiNum(p); i++ ) if ( !Gia_ObjIsCi( Gia_ManObj(p, nOffset+i) ) ) return 0; nOffset = 1 + Gia_ManCiNum(p) + Gia_ManAndNum(p); for ( i = 0; i < Gia_ManCoNum(p); i++ ) if ( !Gia_ObjIsCo( Gia_ManObj(p, nOffset+i) ) ) return 0; return 1; }
/**Function************************************************************* Synopsis [Tests the ECO miter.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Bmc_EcoMiterTest() { char * pFileGold = "eco_gold.aig"; char * pFileOld = "eco_old.aig"; Vec_Int_t * vFans; FILE * pFile; Gia_Man_t * pMiter; Gia_Obj_t * pObj; Gia_Man_t * pGold; Gia_Man_t * pOld; int i, RetValue; // check that the files exist pFile = fopen( pFileGold, "r" ); if ( pFile == NULL ) { printf( "File \"%s\" does not exist.\n", pFileGold ); return; } fclose( pFile ); pFile = fopen( pFileOld, "r" ); if ( pFile == NULL ) { printf( "File \"%s\" does not exist.\n", pFileOld ); return; } fclose( pFile ); // read files pGold = Gia_AigerRead( pFileGold, 0, 0 ); pOld = Gia_AigerRead( pFileOld, 0, 0 ); // create ECO miter vFans = Vec_IntAlloc( Gia_ManCiNum(pOld) ); Gia_ManForEachCi( pOld, pObj, i ) Vec_IntPush( vFans, Gia_ObjId(pOld, pObj) ); pMiter = Bmc_EcoMiter( pGold, pOld, vFans ); Vec_IntFree( vFans ); Gia_AigerWrite( pMiter, "eco_miter.aig", 0, 0 ); // find the patch RetValue = Bmc_EcoPatch( pMiter, Gia_ManCiNum(pGold), Gia_ManCoNum(pGold) ); if ( RetValue == 1 ) printf( "Patch is computed.\n" ); if ( RetValue == 0 ) printf( "Cannot be patched.\n" ); if ( RetValue == -1 ) printf( "Resource limit exceeded.\n" ); Gia_ManStop( pMiter ); }
Gia_Man_t * Ssc_PerformSweepingConstr( Gia_Man_t * p, Ssc_Pars_t * pPars ) { Gia_Man_t * pAig, * pCare, * pResult; int i; if ( pPars->fVerbose ) Abc_Print( 0, "SAT sweeping AIG with %d constraints.\n", p->nConstrs ); if ( p->nConstrs == 0 ) { pAig = Gia_ManDup( p ); pCare = Gia_ManStart( Gia_ManCiNum(p) + 2 ); pCare->pName = Abc_UtilStrsav( "care" ); for ( i = 0; i < Gia_ManCiNum(p); i++ ) Gia_ManAppendCi( pCare ); Gia_ManAppendCo( pCare, 0 ); } else { Vec_Int_t * vOuts = Vec_IntStartNatural( Gia_ManPoNum(p) ); pAig = Gia_ManDupCones( p, Vec_IntArray(vOuts), Gia_ManPoNum(p) - p->nConstrs, 0 ); pCare = Gia_ManDupCones( p, Vec_IntArray(vOuts) + Gia_ManPoNum(p) - p->nConstrs, p->nConstrs, 0 ); Vec_IntFree( vOuts ); } if ( pPars->fVerbose ) { printf( "User AIG: " ); Gia_ManPrintStats( pAig, NULL ); printf( "Care AIG: " ); Gia_ManPrintStats( pCare, NULL ); } pAig = Gia_ManDupLevelized( pResult = pAig ); Gia_ManStop( pResult ); pResult = Ssc_PerformSweeping( pAig, pCare, pPars ); if ( pPars->fAppend ) { Gia_ManDupAppendShare( pResult, pCare ); pResult->nConstrs = Gia_ManPoNum(pCare); } Gia_ManStop( pAig ); Gia_ManStop( pCare ); return pResult; }
/**Function************************************************************* Synopsis [Creates logic network isomorphic to the given AIG.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Cof_Man_t * Cof_ManCreateLogicSimple( Gia_Man_t * pGia ) { Cof_Man_t * p; Cof_Obj_t * pObjLog, * pFanLog; Gia_Obj_t * pObj; int * pMuxRefs; int i, iHandle = 0; p = ABC_CALLOC( Cof_Man_t, 1 ); p->pGia = pGia; p->vCis = Vec_IntAlloc( Gia_ManCiNum(pGia) ); p->vCos = Vec_IntAlloc( Gia_ManCoNum(pGia) ); p->nObjData = (sizeof(Cof_Obj_t) / 4) * Gia_ManObjNum(pGia) + 4 * Gia_ManAndNum(pGia) + 2 * Gia_ManCoNum(pGia); p->pObjData = ABC_CALLOC( int, p->nObjData ); ABC_FREE( pGia->pRefs ); Gia_ManCreateRefs( pGia ); Gia_ManForEachObj( pGia, pObj, i ) { pObj->Value = iHandle; pObjLog = Cof_ManObj( p, iHandle ); pObjLog->nFanins = 0; pObjLog->nFanouts = Gia_ObjRefNum( pGia, pObj ); pObjLog->Id = i; pObjLog->Value = 0; if ( Gia_ObjIsAnd(pObj) ) { pFanLog = Cof_ManObj( p, Gia_ObjHandle(Gia_ObjFanin0(pObj)) ); pFanLog->Fanios[pFanLog->nFanins + pFanLog->Value++].iFan = pObjLog->Fanios[pObjLog->nFanins].iFan = Cof_ObjHandleDiff( pObjLog, pFanLog ); pObjLog->Fanios[pObjLog->nFanins++].fCompl = Gia_ObjFaninC0(pObj); pFanLog = Cof_ManObj( p, Gia_ObjHandle(Gia_ObjFanin1(pObj)) ); pFanLog->Fanios[pFanLog->nFanins + pFanLog->Value++].iFan = pObjLog->Fanios[pObjLog->nFanins].iFan = Cof_ObjHandleDiff( pObjLog, pFanLog ); pObjLog->Fanios[pObjLog->nFanins++].fCompl = Gia_ObjFaninC1(pObj); p->nNodes++; } else if ( Gia_ObjIsCo(pObj) ) { pFanLog = Cof_ManObj( p, Gia_ObjHandle(Gia_ObjFanin0(pObj)) ); pFanLog->Fanios[pFanLog->nFanins + pFanLog->Value++].iFan = pObjLog->Fanios[pObjLog->nFanins].iFan = Cof_ObjHandleDiff( pObjLog, pFanLog ); pObjLog->Fanios[pObjLog->nFanins++].fCompl = Gia_ObjFaninC0(pObj); pObjLog->fTerm = 1; Vec_IntPush( p->vCos, iHandle ); } else if ( Gia_ObjIsCi(pObj) ) { pObjLog->fTerm = 1; Vec_IntPush( p->vCis, iHandle ); } iHandle += Cof_ObjSize( pObjLog ); p->nObjs++; }
/**Function************************************************************* Synopsis [Duplicates AIG in the DFS order while putting CIs first.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManDupNormalize( Gia_Man_t * p ) { int fHashMapping = 0; Gia_Man_t * pNew; Gia_Obj_t * pObj; int i; Gia_ManFillValue( p ); pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Gia_ManConst0(p)->Value = 0; if ( !Gia_ManIsSeqWithBoxes(p) ) { Gia_ManForEachCi( p, pObj, i ) pObj->Value = Gia_ManAppendCi(pNew); } else { // current CI order: PIs + FOs + NewCIs // desired reorder: PIs + NewCIs + FOs int nCIs = Tim_ManPiNum( (Tim_Man_t *)p->pManTime ); int nAll = Tim_ManCiNum( (Tim_Man_t *)p->pManTime ); int nPis = nCIs - Gia_ManRegNum(p); assert( nAll == Gia_ManCiNum(p) ); assert( nPis > 0 ); // copy PIs first for ( i = 0; i < nPis; i++ ) Gia_ManCi(p, i)->Value = Gia_ManAppendCi(pNew); // copy new CIs second for ( i = nCIs; i < nAll; i++ ) Gia_ManCi(p, i)->Value = Gia_ManAppendCi(pNew); // copy flops last for ( i = nCIs - Gia_ManRegNum(p); i < nCIs; i++ ) Gia_ManCi(p, i)->Value = Gia_ManAppendCi(pNew); printf( "Warning: Shuffled CI order to be correct sequential AIG.\n" ); } if ( fHashMapping ) Gia_ManHashAlloc( pNew ); Gia_ManForEachAnd( p, pObj, i ) if ( Gia_ObjIsBuf(pObj) ) pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) ); else if ( fHashMapping ) pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); else pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); if ( fHashMapping ) Gia_ManHashStop( pNew ); Gia_ManForEachCo( p, pObj, i ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); pNew->nConstrs = p->nConstrs; assert( Gia_ManIsNormalized(pNew) ); Gia_ManDupRemapEquiv( pNew, p ); return pNew; }
/**Function************************************************************* Synopsis [Computes CE-induced network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Bmc_CexBuildNetwork2( Gia_Man_t * p, Abc_Cex_t * pCex, int fStart ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj, * pObjRo, * pObjRi; int fCompl0, fCompl1; int i, k, iBit; assert( pCex->nRegs == 0 ); assert( pCex->nPis == Gia_ManCiNum(p) ); assert( fStart <= pCex->iFrame ); // start the manager pNew = Gia_ManStart( 1000 ); pNew->pName = Abc_UtilStrsav( "unate" ); // set const0 Gia_ManConst0(p)->fMark0 = 0; // value Gia_ManConst0(p)->fMark1 = 1; // care Gia_ManConst0(p)->Value = ~0; // set init state Gia_ManForEachRi( p, pObj, k ) { pObj->fMark0 = Abc_InfoHasBit( pCex->pData, pCex->nRegs + fStart * Gia_ManCiNum(p) + Gia_ManPiNum(p) + k ); pObj->fMark1 = 0; pObj->Value = Abc_LitNotCond( Gia_ManAppendCi(pNew), !pObj->fMark0 ); }
/**Function************************************************************* Synopsis [Reorders flops for sequential AIGs with boxes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManDupUnshuffleInputs( Gia_Man_t * p ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; int i, nCIs, nAll, nPis; // sanity checks assert( Gia_ManIsNormalized(p) ); assert( Gia_ManIsSeqWithBoxes(p) ); Gia_ManFillValue( p ); pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Gia_ManConst0(p)->Value = 0; // change input order // desired reorder: PIs + NewCIs + FOs // current CI order: PIs + FOs + NewCIs nCIs = Tim_ManPiNum( (Tim_Man_t *)p->pManTime ); nAll = Tim_ManCiNum( (Tim_Man_t *)p->pManTime ); nPis = nCIs - Gia_ManRegNum(p); assert( nAll == Gia_ManCiNum(p) ); assert( nPis > 0 ); // copy PIs first for ( i = 0; i < nPis; i++ ) Gia_ManCi(p, i)->Value = Gia_ManAppendCi(pNew); // copy flops second for ( i = nAll - Gia_ManRegNum(p); i < nAll; i++ ) Gia_ManCi(p, i)->Value = Gia_ManAppendCi(pNew); // copy new CIs last for ( i = nPis; i < nAll - Gia_ManRegNum(p); i++ ) Gia_ManCi(p, i)->Value = Gia_ManAppendCi(pNew); printf( "Warning: Unshuffled CI order to be correct AIG with boxes.\n" ); // other things Gia_ManForEachAnd( p, pObj, i ) pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( p, pObj, i ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); pNew->nConstrs = p->nConstrs; assert( Gia_ManIsNormalized(pNew) ); Gia_ManDupRemapEquiv( pNew, p ); return pNew; }
/**Function************************************************************* Synopsis [Creates AIG.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Cec_ManSim_t * Cec_ManSimStart( Gia_Man_t * pAig, Cec_ParSim_t * pPars ) { Cec_ManSim_t * p; p = ABC_ALLOC( Cec_ManSim_t, 1 ); memset( p, 0, sizeof(Cec_ManSim_t) ); p->pAig = pAig; p->pPars = pPars; p->nWords = pPars->nWords; p->pSimInfo = ABC_CALLOC( int, Gia_ManObjNum(pAig) ); p->vClassOld = Vec_IntAlloc( 1000 ); p->vClassNew = Vec_IntAlloc( 1000 ); p->vClassTemp = Vec_IntAlloc( 1000 ); p->vRefinedC = Vec_IntAlloc( 10000 ); p->vCiSimInfo = Vec_PtrAllocSimInfo( Gia_ManCiNum(p->pAig), pPars->nWords ); if ( pPars->fCheckMiter || Gia_ManRegNum(p->pAig) ) { p->vCoSimInfo = Vec_PtrAllocSimInfo( Gia_ManCoNum(p->pAig), pPars->nWords ); Vec_PtrCleanSimInfo( p->vCoSimInfo, 0, pPars->nWords ); } p->iOut = -1; return p; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Computes miter for ECO with given root node and fanins.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Bmc_EcoMiter( Gia_Man_t * pGold, Gia_Man_t * pOld, Vec_Int_t * vFans ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pRoot = Gia_ObjFanin0( Gia_ManPo(pOld, Gia_ManPoNum(pOld)-1) ); // fanin of the last PO Gia_Obj_t * pObj; int i, NewPi, Miter; assert( Gia_ManCiNum(pGold) == Gia_ManCiNum(pOld) ); assert( Gia_ManCoNum(pGold) == Gia_ManCoNum(pOld) - 1 ); assert( Gia_ObjIsAnd(pRoot) ); // create the miter pNew = Gia_ManStart( 3 * Gia_ManObjNum(pGold) ); pNew->pName = Abc_UtilStrsav( pGold->pName ); Gia_ManHashAlloc( pNew ); // copy gold Gia_ManConst0(pGold)->Value = 0; Gia_ManForEachCi( pGold, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); NewPi = Gia_ManAppendCi( pNew ); Gia_ManForEachAnd( pGold, pObj, i ) pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( pGold, pObj, i ) pObj->Value = Gia_ObjFanin0Copy( pObj ); // create onset Gia_ManConst0(pOld)->Value = 0; Gia_ManForEachCi( pOld, pObj, i ) pObj->Value = Gia_ManCi(pGold, i)->Value; Gia_ManForEachAnd( pOld, pObj, i ) if ( pObj == pRoot ) pObj->Value = NewPi; else pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( pOld, pObj, i ) pObj->Value = Gia_ObjFanin0Copy( pObj ); Gia_ManForEachCo( pGold, pObj, i ) Gia_ManAppendCo( pNew, Gia_ManHashXor(pNew, pObj->Value, Gia_ManCo(pOld, i)->Value) ); // create offset Gia_ManForEachAnd( pOld, pObj, i ) if ( pObj == pRoot ) pObj->Value = Abc_LitNot(NewPi); else pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( pOld, pObj, i ) pObj->Value = Gia_ObjFanin0Copy( pObj ); Miter = 0; Gia_ManForEachCo( pGold, pObj, i ) Miter = Gia_ManHashOr( pNew, Miter, Gia_ManHashXor(pNew, pObj->Value, Gia_ManCo(pOld, i)->Value) ); Gia_ManAppendCo( pNew, Miter ); // add outputs for the nodes Gia_ManForEachObjVec( vFans, pOld, pObj, i ) Gia_ManAppendCo( pNew, pObj->Value ); // cleanup pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); assert( Gia_ManPiNum(pNew) == Gia_ManCiNum(pGold) + 1 ); assert( Gia_ManPoNum(pNew) == Gia_ManCoNum(pGold) + 1 + Vec_IntSize(vFans) ); return pNew; }
// start the manager pNew = Gia_ManStart( 1000 ); pNew->pName = Abc_UtilStrsav( "unate" ); // set const0 Gia_ManConst0(p)->fMark0 = 0; // value Gia_ManConst0(p)->fMark1 = 1; // care Gia_ManConst0(p)->Value = ~0; // set init state Gia_ManForEachRi( p, pObj, k ) { pObj->fMark0 = Abc_InfoHasBit( pCex->pData, pCex->nRegs + fStart * Gia_ManCiNum(p) + Gia_ManPiNum(p) + k ); pObj->fMark1 = 0; pObj->Value = Abc_LitNotCond( Gia_ManAppendCi(pNew), !pObj->fMark0 ); } Gia_ManHashAlloc( pNew ); iBit = pCex->nRegs + fStart * Gia_ManCiNum(p); for ( i = fStart; i <= pCex->iFrame; i++ ) { // primary inputs Gia_ManForEachPi( p, pObj, k ) { pObj->fMark0 = Abc_InfoHasBit( pCex->pData, iBit++ ); pObj->fMark1 = 1; pObj->Value = ~0; } iBit += Gia_ManRegNum(p); // transfer Gia_ManForEachRiRo( p, pObjRi, pObjRo, k ) { pObjRo->fMark0 = pObjRi->fMark0; pObjRo->fMark1 = pObjRi->fMark1;
int Gia_ManBoxCiNum( Gia_Man_t * p ) { return p->pManTime ? Gia_ManCiNum(p) - Tim_ManPiNum((Tim_Man_t *)p->pManTime) : 0; }
Vec_Int_t * Gia_ManOrderWithBoxes( Gia_Man_t * p ) { Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime; Vec_Int_t * vNodes; Gia_Obj_t * pObj; int i, k, curCi, curCo; assert( pManTime != NULL ); assert( Gia_ManIsNormalized( p ) ); // start trav IDs Gia_ManIncrementTravId( p ); // start the array vNodes = Vec_IntAlloc( Gia_ManObjNum(p) ); // include constant Vec_IntPush( vNodes, 0 ); Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); // include primary inputs for ( i = 0; i < Tim_ManPiNum(pManTime); i++ ) { pObj = Gia_ManCi( p, i ); Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); Gia_ObjSetTravIdCurrent( p, pObj ); assert( Gia_ObjId(p, pObj) == i+1 ); } // for each box, include box nodes curCi = Tim_ManPiNum(pManTime); curCo = 0; for ( i = 0; i < Tim_ManBoxNum(pManTime); i++ ) { // add internal nodes for ( k = 0; k < Tim_ManBoxInputNum(pManTime, i); k++ ) { pObj = Gia_ManCo( p, curCo + k ); if ( Gia_ManOrderWithBoxes_rec( p, Gia_ObjFanin0(pObj), vNodes ) ) { int iCiNum = p->iData2; int iBoxNum = Tim_ManBoxFindFromCiNum( pManTime, iCiNum ); printf( "The command has to terminate. Boxes are not in a topological order.\n" ); printf( "The following information may help debugging (numbers are 0-based):\n" ); printf( "Input %d of BoxA %d (1stCI = %d; 1stCO = %d) has TFI with CI %d,\n", k, i, Tim_ManBoxOutputFirst(pManTime, i), Tim_ManBoxInputFirst(pManTime, i), iCiNum ); printf( "which corresponds to output %d of BoxB %d (1stCI = %d; 1stCO = %d).\n", iCiNum - Tim_ManBoxOutputFirst(pManTime, iBoxNum), iBoxNum, Tim_ManBoxOutputFirst(pManTime, iBoxNum), Tim_ManBoxInputFirst(pManTime, iBoxNum) ); printf( "In a correct topological order, BoxB should precede BoxA.\n" ); Vec_IntFree( vNodes ); p->iData2 = 0; return NULL; } } // add POs corresponding to box inputs for ( k = 0; k < Tim_ManBoxInputNum(pManTime, i); k++ ) { pObj = Gia_ManCo( p, curCo + k ); Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); } curCo += Tim_ManBoxInputNum(pManTime, i); // add PIs corresponding to box outputs for ( k = 0; k < Tim_ManBoxOutputNum(pManTime, i); k++ ) { pObj = Gia_ManCi( p, curCi + k ); Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); Gia_ObjSetTravIdCurrent( p, pObj ); } curCi += Tim_ManBoxOutputNum(pManTime, i); } // add remaining nodes for ( i = Tim_ManCoNum(pManTime) - Tim_ManPoNum(pManTime); i < Tim_ManCoNum(pManTime); i++ ) { pObj = Gia_ManCo( p, i ); Gia_ManOrderWithBoxes_rec( p, Gia_ObjFanin0(pObj), vNodes ); } // add POs for ( i = Tim_ManCoNum(pManTime) - Tim_ManPoNum(pManTime); i < Tim_ManCoNum(pManTime); i++ ) { pObj = Gia_ManCo( p, i ); Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); } curCo += Tim_ManPoNum(pManTime); // verify counts assert( curCi == Gia_ManCiNum(p) ); assert( curCo == Gia_ManCoNum(p) ); //assert( Vec_IntSize(vNodes) == Gia_ManObjNum(p) ); return vNodes; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Ssc_PerformSweeping( Gia_Man_t * pAig, Gia_Man_t * pCare, Ssc_Pars_t * pPars ) { Ssc_Man_t * p; Gia_Man_t * pResult, * pTemp; Gia_Obj_t * pObj, * pRepr; abctime clk, clkTotal = Abc_Clock(); int i, fCompl, nRefined, status; clk = Abc_Clock(); assert( Gia_ManRegNum(pCare) == 0 ); assert( Gia_ManCiNum(pAig) == Gia_ManCiNum(pCare) ); assert( Gia_ManIsNormalized(pAig) ); assert( Gia_ManIsNormalized(pCare) ); // reset random numbers Gia_ManRandom( 1 ); // sweeping manager p = Ssc_ManStart( pAig, pCare, pPars ); if ( p == NULL ) return Gia_ManDup( pAig ); if ( p->pPars->fVerbose ) printf( "Care set produced %d hits out of %d.\n", Ssc_GiaEstimateCare(p->pFraig, 5), 640 ); // perform simulation while ( 1 ) { // simulate care set Ssc_GiaRandomPiPattern( p->pFraig, 5, NULL ); Ssc_GiaSimRound( p->pFraig ); // transfer care patterns to user's AIG if ( !Ssc_GiaTransferPiPattern( pAig, p->pFraig, p->vPivot ) ) break; // simulate the main AIG Ssc_GiaSimRound( pAig ); nRefined = Ssc_GiaClassesRefine( pAig ); if ( pPars->fVerbose ) Gia_ManEquivPrintClasses( pAig, 0, 0 ); if ( nRefined <= Gia_ManCandNum(pAig) / 100 ) break; } p->timeSimInit += Abc_Clock() - clk; // prepare user's AIG Gia_ManFillValue(pAig); Gia_ManConst0(pAig)->Value = 0; Gia_ManForEachCi( pAig, pObj, i ) pObj->Value = Gia_Obj2Lit( p->pFraig, Gia_ManCi(p->pFraig, i) ); // Gia_ManLevelNum(pAig); // prepare swept AIG (should be done after starting SAT solver in Ssc_ManStart) Gia_ManHashStart( p->pFraig ); // perform sweeping Ssc_GiaResetPiPattern( pAig, pPars->nWords ); Ssc_GiaSavePiPattern( pAig, p->vPivot ); Gia_ManForEachCand( pAig, pObj, i ) { if ( pAig->iPatsPi == 64 * pPars->nWords ) { clk = Abc_Clock(); Ssc_GiaSimRound( pAig ); Ssc_GiaClassesRefine( pAig ); if ( pPars->fVerbose ) Gia_ManEquivPrintClasses( pAig, 0, 0 ); Ssc_GiaClassesCheckPairs( pAig, p->vDisPairs ); Vec_IntClear( p->vDisPairs ); // prepare next patterns Ssc_GiaResetPiPattern( pAig, pPars->nWords ); Ssc_GiaSavePiPattern( pAig, p->vPivot ); p->timeSimSat += Abc_Clock() - clk; //printf( "\n" ); } if ( Gia_ObjIsAnd(pObj) ) pObj->Value = Gia_ManHashAnd( p->pFraig, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); if ( !Gia_ObjHasRepr(pAig, i) ) continue; pRepr = Gia_ObjReprObj(pAig, i); if ( (int)pObj->Value == Abc_LitNotCond( pRepr->Value, pRepr->fPhase ^ pObj->fPhase ) ) { Gia_ObjSetProved( pAig, i ); continue; } assert( Abc_Lit2Var(pRepr->Value) != Abc_Lit2Var(pObj->Value) ); fCompl = pRepr->fPhase ^ pObj->fPhase ^ Abc_LitIsCompl(pRepr->Value) ^ Abc_LitIsCompl(pObj->Value); // perform SAT call clk = Abc_Clock(); p->nSatCalls++; status = Ssc_ManCheckEquivalence( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl ); if ( status == l_False ) { p->nSatCallsUnsat++; pObj->Value = Abc_LitNotCond( pRepr->Value, pRepr->fPhase ^ pObj->fPhase ); Gia_ObjSetProved( pAig, i ); } else if ( status == l_True ) { p->nSatCallsSat++; Ssc_GiaSavePiPattern( pAig, p->vPattern ); Vec_IntPush( p->vDisPairs, Gia_ObjRepr(p->pAig, i) ); Vec_IntPush( p->vDisPairs, i ); // printf( "Try %2d and %2d: ", Gia_ObjRepr(p->pAig, i), i ); // Vec_IntPrint( p->vPattern ); if ( Gia_ObjRepr(p->pAig, i) > 0 ) Ssc_GiaResimulateOneClass( p, Gia_ObjRepr(p->pAig, i), i ); } else if ( status == l_Undef ) p->nSatCallsUndec++; else assert( 0 ); p->timeSat += Abc_Clock() - clk; } if ( pAig->iPatsPi > 1 ) { clk = Abc_Clock(); while ( pAig->iPatsPi < 64 * pPars->nWords ) Ssc_GiaSavePiPattern( pAig, p->vPivot ); Ssc_GiaSimRound( pAig ); Ssc_GiaClassesRefine( pAig ); if ( pPars->fVerbose ) Gia_ManEquivPrintClasses( pAig, 0, 0 ); Ssc_GiaClassesCheckPairs( pAig, p->vDisPairs ); Vec_IntClear( p->vDisPairs ); p->timeSimSat += Abc_Clock() - clk; } // Gia_ManEquivPrintClasses( pAig, 1, 0 ); // Gia_ManPrint( pAig ); // generate the resulting AIG pResult = Gia_ManEquivReduce( pAig, 0, 0, 1, 0 ); if ( pResult == NULL ) { printf( "There is no equivalences.\n" ); ABC_FREE( pAig->pReprs ); ABC_FREE( pAig->pNexts ); pResult = Gia_ManDup( pAig ); } pResult = Gia_ManCleanup( pTemp = pResult ); Gia_ManStop( pTemp ); p->timeTotal = Abc_Clock() - clkTotal; if ( pPars->fVerbose ) Ssc_ManPrintStats( p ); Ssc_ManStop( p ); // count the number of representatives if ( pPars->fVerbose ) { Abc_Print( 1, "Reduction in AIG nodes:%8d ->%8d (%6.2f %%). ", Gia_ManAndNum(pAig), Gia_ManAndNum(pResult), 100.0 - 100.0 * Gia_ManAndNum(pResult) / Gia_ManAndNum(pAig) ); Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal ); } return pResult; }