/**Function************************************************************* Synopsis [Duplicates AIG according to the timing manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManDupUnnormalize( Gia_Man_t * p ) { Vec_Int_t * vNodes; Gia_Man_t * pNew; Gia_Obj_t * pObj; int i; vNodes = Gia_ManOrderWithBoxes( p ); if ( vNodes == NULL ) return NULL; Gia_ManFillValue( p ); pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); if ( p->pSibls ) pNew->pSibls = ABC_CALLOC( int, Gia_ManObjNum(p) ); Gia_ManForEachObjVec( vNodes, p, pObj, i ) { if ( Gia_ObjIsAnd(pObj) ) { pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); if ( Gia_ObjSibl(p, Gia_ObjId(p, pObj)) ) pNew->pSibls[Abc_Lit2Var(pObj->Value)] = Abc_Lit2Var(Gia_ObjSiblObj(p, Gia_ObjId(p, pObj))->Value); } else if ( Gia_ObjIsCi(pObj) ) pObj->Value = Gia_ManAppendCi( pNew ); else if ( Gia_ObjIsCo(pObj) ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); else if ( Gia_ObjIsConst0(pObj) ) pObj->Value = 0; else assert( 0 ); } Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); Vec_IntFree( vNodes ); return pNew; }
/**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; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Specialized duplication.] Description [Replaces registers by PIs/POs and PIs by registers.] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManDupIn2Ff( Gia_Man_t * p ) { Vec_Int_t * vPiOuts; Gia_Man_t * pNew; Gia_Obj_t * pObj; int i; vPiOuts = Vec_IntAlloc( Gia_ManPiNum(p) ); pNew = Gia_ManStart( Gia_ManObjNum(p) + 2 * Gia_ManPiNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Gia_ManFillValue( p ); Gia_ManConst0(p)->Value = 0; Gia_ManForEachPi( p, pObj, i ) Vec_IntPush( vPiOuts, Gia_ManAppendCi(pNew) ); Gia_ManForEachRo( p, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); Gia_ManForEachPi( p, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); Gia_ManForEachAnd( p, pObj, i ) pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachPo( p, pObj, i ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManForEachRi( p, pObj, i ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManForEachPi( p, pObj, i ) Gia_ManAppendCo( pNew, Vec_IntEntry(vPiOuts, i) ); Gia_ManSetRegNum( pNew, Gia_ManPiNum(p) ); Vec_IntFree( vPiOuts ); return pNew; }
/**Function************************************************************* Synopsis [Computes partitioning of registers.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManRegCreatePart( Gia_Man_t * p, Vec_Int_t * vPart, int * pnCountPis, int * pnCountRegs, int ** ppMapBack ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; Vec_Int_t * vNodes, * vRoots; int i, iOut, nCountPis, nCountRegs; int * pMapBack; // collect/mark nodes/PIs in the DFS order from the roots Gia_ManIncrementTravId( p ); vRoots = Vec_IntAlloc( Vec_IntSize(vPart) ); Vec_IntForEachEntry( vPart, iOut, i ) Vec_IntPush( vRoots, Gia_ObjId(p, Gia_ManCo(p, Gia_ManPoNum(p)+iOut)) ); vNodes = Gia_ManCollectNodesCis( p, Vec_IntArray(vRoots), Vec_IntSize(vRoots) ); Vec_IntFree( vRoots ); // unmark register outputs Vec_IntForEachEntry( vPart, iOut, i ) Gia_ObjSetTravIdPrevious( p, Gia_ManCi(p, Gia_ManPiNum(p)+iOut) ); // count pure PIs nCountPis = nCountRegs = 0; Gia_ManForEachPi( p, pObj, i ) nCountPis += Gia_ObjIsTravIdCurrent(p, pObj); // count outputs of other registers Gia_ManForEachRo( p, pObj, i ) nCountRegs += Gia_ObjIsTravIdCurrent(p, pObj); // should be !Gia_... ??? if ( pnCountPis ) *pnCountPis = nCountPis; if ( pnCountRegs ) *pnCountRegs = nCountRegs; // clean old manager Gia_ManFillValue(p); Gia_ManConst0(p)->Value = 0; // create the new manager pNew = Gia_ManStart( Vec_IntSize(vNodes) ); // create the PIs Gia_ManForEachCi( p, pObj, i ) if ( Gia_ObjIsTravIdCurrent(p, pObj) ) pObj->Value = Gia_ManAppendCi(pNew); // add variables for the register outputs // create fake POs to hold the register outputs Vec_IntForEachEntry( vPart, iOut, i ) { pObj = Gia_ManCi(p, Gia_ManPiNum(p)+iOut); pObj->Value = Gia_ManAppendCi(pNew); Gia_ManAppendCo( pNew, pObj->Value ); Gia_ObjSetTravIdCurrent( p, pObj ); // added }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Duplicates AIG in the DFS order while putting CIs first.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManDupNormalize( Gia_Man_t * p ) { 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; Gia_ManForEachCi( p, pObj, i ) pObj->Value = Gia_ManAppendCi(pNew); 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 [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 [Reverses the above step.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManDupFf2In( Gia_Man_t * p, int nFlopsOld ) { Gia_Man_t * pNew; Gia_Obj_t * pObj; int i; pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Gia_ManFillValue( p ); Gia_ManConst0(p)->Value = 0; Gia_ManForEachRo( p, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); for ( i = Gia_ManPiNum(p) - nFlopsOld; i < Gia_ManPiNum(p); i++ ) Gia_ManPi(p, i)->Value = Gia_ManAppendCi( pNew ); Gia_ManForEachPo( p, pObj, i ) Gia_ManDupFf2In_rec( pNew, Gia_ObjFanin0(pObj) ); Gia_ManForEachPo( p, pObj, i ) Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManSetRegNum( pNew, nFlopsOld ); return pNew; }
/**Function************************************************************* Synopsis [Duplicates the AIG while retiming the registers to the cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManRetimeDupForward( Gia_Man_t * p, Vec_Ptr_t * vCut ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj, * pObjRi, * pObjRo; int i; // create the new manager pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Gia_UtilStrsav( p->pName ); Gia_ManHashAlloc( pNew ); // create the true PIs Gia_ManFillValue( p ); Gia_ManSetPhase( p ); Gia_ManConst0(p)->Value = 0; Gia_ManForEachPi( p, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); // create the registers Vec_PtrForEachEntry( Gia_Obj_t *, vCut, pObj, i ) pObj->Value = Gia_LitNotCond( Gia_ManAppendCi(pNew), pObj->fPhase ); // duplicate logic above the cut Gia_ManForEachCo( p, pObj, i ) Gia_ManRetimeDup_rec( pNew, Gia_ObjFanin0(pObj) ); // create the true POs Gia_ManForEachPo( p, pObj, i ) Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); // remember value in LI Gia_ManForEachRi( p, pObj, i ) pObj->Value = Gia_ObjFanin0Copy(pObj); // transfer values from the LIs to the LOs Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) pObjRo->Value = pObjRi->Value; // erase the data values on the internal nodes of the cut Vec_PtrForEachEntry( Gia_Obj_t *, vCut, pObj, i ) if ( Gia_ObjIsAnd(pObj) ) pObj->Value = ~0; // duplicate logic below the cut Vec_PtrForEachEntry( Gia_Obj_t *, vCut, pObj, i ) { Gia_ManRetimeDup_rec( pNew, pObj ); Gia_ManAppendCo( pNew, Gia_LitNotCond( pObj->Value, pObj->fPhase ) ); }
/**Function************************************************************* Synopsis [Performs structural hashing on the LUT functions.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void * Dsm_ManDeriveGia( void * pGia, int fUseMuxes ) { Gia_Man_t * p = (Gia_Man_t *)pGia; Gia_Man_t * pNew, * pTemp; Vec_Int_t * vCover, * vLeaves; Gia_Obj_t * pObj; int k, i, iLut, iVar; word * pTruth; assert( Gia_ManHasMapping(p) ); // create new manager pNew = Gia_ManStart( 6*Gia_ManObjNum(p)/5 + 100 ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); pNew->vLevels = Vec_IntStart( 6*Gia_ManObjNum(p)/5 + 100 ); if ( fUseMuxes ) pNew->pMuxes = ABC_CALLOC( unsigned, pNew->nObjsAlloc ); // map primary inputs Gia_ManFillValue(p); Gia_ManConst0(p)->Value = 0; Gia_ManForEachCi( p, pObj, i ) pObj->Value = Gia_ManAppendCi(pNew); // iterate through nodes used in the mapping vLeaves = Vec_IntAlloc( 16 ); vCover = Vec_IntAlloc( 1 << 16 ); Gia_ManHashStart( pNew ); Gia_ObjComputeTruthTableStart( p, Gia_ManLutSizeMax(p) ); Gia_ManForEachAnd( p, pObj, iLut ) { if ( Gia_ObjIsBuf(pObj) ) { pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) ); continue; } if ( !Gia_ObjIsLut(p, iLut) ) continue; // collect leaves Vec_IntClear( vLeaves ); Gia_LutForEachFanin( p, iLut, iVar, k ) Vec_IntPush( vLeaves, iVar ); pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ManObj(p, iLut), vLeaves ); // collect incoming literals Vec_IntClear( vLeaves ); Gia_LutForEachFanin( p, iLut, iVar, k ) Vec_IntPush( vLeaves, Gia_ManObj(p, iVar)->Value ); Gia_ManObj(p, iLut)->Value = Dsm_ManTruthToGia( pNew, pTruth, vLeaves, vCover ); } Gia_ObjComputeTruthTableStop( p ); Gia_ManForEachCo( p, pObj, i ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManHashStop( pNew ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); Vec_IntFree( vLeaves ); Vec_IntFree( vCover ); /* Gia_ManForEachAnd( pNew, pObj, i ) { int iLev = Gia_ObjLevelId(pNew, i); int iLev0 = Gia_ObjLevelId(pNew, Gia_ObjFaninId0(pObj, i)); int iLev1 = Gia_ObjLevelId(pNew, Gia_ObjFaninId1(pObj, i)); assert( iLev == 1 + Abc_MaxInt(iLev0, iLev1) ); } */ // perform cleanup pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); return pNew; }
/**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; }
/**Function************************************************************* Synopsis [Performs AIG shrinking using the current mapping.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManMapShrink4( Gia_Man_t * p, int fKeepLevel, int fVerbose ) { Vec_Int_t * vLeaves, * vTruth, * vVisited, * vLeavesBest; Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj, * pFanin; unsigned * pTruth; int i, k, iFan; abctime clk = Abc_Clock(); // int ClassCounts[222] = {0}; int * pLutClass, Counter = 0; assert( p->pMapping != NULL ); if ( Gia_ManLutSizeMax( p ) > 4 ) { printf( "Resynthesis is not performed when nodes have more than 4 inputs.\n" ); return NULL; } pLutClass = ABC_CALLOC( int, Gia_ManObjNum(p) ); vLeaves = Vec_IntAlloc( 0 ); vTruth = Vec_IntAlloc( (1<<16) ); vVisited = Vec_IntAlloc( 0 ); vLeavesBest = Vec_IntAlloc( 4 ); // prepare the library Dar_LibPrepare( 5 ); // clean the old manager Gia_ManCleanTruth( p ); Gia_ManSetPhase( p ); Gia_ManFillValue( p ); Gia_ManConst0(p)->Value = 0; // start the new manager pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Gia_ManHashAlloc( pNew ); Gia_ManCleanLevels( pNew, Gia_ManObjNum(p) ); Gia_ManForEachObj1( p, pObj, i ) { if ( Gia_ObjIsCi(pObj) ) { pObj->Value = Gia_ManAppendCi( pNew ); if ( p->vLevels ) Gia_ObjSetLevel( pNew, Gia_ObjFromLit(pNew, Gia_ObjValue(pObj)), Gia_ObjLevel(p, pObj) ); } else if ( Gia_ObjIsCo(pObj) ) { pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); } else if ( Gia_ObjIsLut(p, i) ) { Counter++; // collect leaves of this gate Vec_IntClear( vLeaves ); Gia_LutForEachFanin( p, i, iFan, k ) Vec_IntPush( vLeaves, iFan ); for ( ; k < 4; k++ ) Vec_IntPush( vLeaves, 0 ); //.compute the truth table pTruth = Gia_ManConvertAigToTruth( p, pObj, vLeaves, vTruth, vVisited ); // change from node IDs to their literals Gia_ManForEachObjVec( vLeaves, p, pFanin, k ) { assert( Gia_ObjValue(pFanin) != ~0 ); Vec_IntWriteEntry( vLeaves, k, Gia_ObjValue(pFanin) ); } // derive new structre if ( Gia_ManTruthIsConst0(pTruth, Vec_IntSize(vLeaves)) ) pObj->Value = 0; else if ( Gia_ManTruthIsConst1(pTruth, Vec_IntSize(vLeaves)) ) pObj->Value = 1; else { pObj->Value = Dar_LibEvalBuild( pNew, vLeaves, 0xffff & *pTruth, fKeepLevel, vLeavesBest ); pObj->Value = Abc_LitNotCond( pObj->Value, Gia_ObjPhaseRealLit(pNew, pObj->Value) ^ pObj->fPhase ); } } }